lint: replace tslint with eslint and fix new warnings and errors.

master
Tom Hacohen 5 years ago
parent f29edf1563
commit 11dd883f5f

@ -0,0 +1 @@
EXTEND_ESLINT=true

@ -0,0 +1,98 @@
module.exports = {
"env": {
"browser": true,
"es6": true,
"node": true
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"settings": {
"react": {
"version": "detect",
},
},
"plugins": [
"@typescript-eslint",
],
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended"
],
"rules": {
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-use-before-define": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/member-delimiter-style": ["error", {
"multiline": {
"delimiter": "semi",
"requireLast": true
},
"singleline": {
"delimiter": "comma",
"requireLast": false
}
}],
"@typescript-eslint/no-unused-vars": ["warn", {
"vars": "all",
"args": "after-used",
"ignoreRestSiblings": true,
"argsIgnorePattern": "^_",
}],
"react/display-name": "off",
"react/no-unescaped-entities": "off",
"react/jsx-tag-spacing": ["error", {
"closingSlash": "never",
"beforeSelfClosing": "always",
"afterOpening": "never",
"beforeClosing": "never"
}],
"react/jsx-boolean-value": ["error", "never"],
"react/jsx-curly-spacing": ["error", "never"],
"react/jsx-key": ["error", { "checkFragmentShorthand": true }],
"quotes": "off",
"@typescript-eslint/quotes": ["error", "single", { "allowTemplateLiterals": true }],
"semi": ["error", "always", { "omitLastInOneLineBlock": true }],
"camelcase": ["error"],
"comma-dangle": ["error", {
"arrays": "always-multiline",
"objects": "always-multiline",
"imports": "always-multiline",
"exports": "always-multiline",
"functions": "never"
}],
"eqeqeq": ["error", "smart"],
"indent": ["error", 2, {
"SwitchCase": 1,
}],
"no-multi-spaces": "error",
"object-curly-spacing": ["error", "always"],
"arrow-parens": "error",
"arrow-spacing": "error",
"key-spacing": "error",
"keyword-spacing": "error",
"func-call-spacing": "off",
"@typescript-eslint/func-call-spacing": ["error"],
"space-before-function-paren": ["error", {
"anonymous": "always",
"named": "never",
"asyncArrow": "always"
}],
"space-in-parens": ["error", "never"],
"space-before-blocks": "error",
"curly": ["error", "all"],
"space-infix-ops": "error",
"consistent-return": "error",
"brace-style": ["error", "1tbs", { "allowSingleLine": true }],
"jsx-quotes": ["error"],
}
};

2
.gitignore vendored

@ -21,5 +21,3 @@ Session.vim
npm-debug.log* npm-debug.log*
yarn-debug.log* yarn-debug.log*
yarn-error.log* yarn-error.log*
/.env

@ -51,8 +51,6 @@
"@types/sjcl": "^1.0.28", "@types/sjcl": "^1.0.28",
"@types/urijs": "^1.15.38", "@types/urijs": "^1.15.38",
"@types/uuid": "^3.4.3", "@types/uuid": "^3.4.3",
"tslint": "^5.12.1",
"tslint-react": "^3.6.0",
"typescript": "^3.3.3" "typescript": "^3.3.3"
}, },
"browserslist": [ "browserslist": [

@ -11,5 +11,5 @@ it('renders without crashing', () => {
<Provider store={store}> <Provider store={store}>
<App /> <App />
</Provider> </Provider>
, div); , div);
}); });

@ -97,11 +97,11 @@ export const routeResolver = new RouteResolver({
const AppBarWitHistory = withRouter( const AppBarWitHistory = withRouter(
class extends React.PureComponent { class extends React.PureComponent {
public props: { public props: {
title: string, title: string;
toggleDrawerIcon: any, toggleDrawerIcon: any;
history?: History; history?: History;
staticContext?: any; staticContext?: any;
iconElementRight: any, iconElementRight: any;
}; };
constructor(props: any) { constructor(props: any) {
@ -159,7 +159,7 @@ const IconRefreshWithSpin = withSpin(NavigationRefresh);
class App extends React.PureComponent { class App extends React.PureComponent {
public state: { public state: {
drawerOpen: boolean, drawerOpen: boolean;
}; };
public props: { public props: {
@ -193,37 +193,37 @@ class App extends React.PureComponent {
return ( return (
<ThemeProvider theme={muiTheme}> <ThemeProvider theme={muiTheme}>
<BrowserRouter> <BrowserRouter>
<div style={styles.main}> <div style={styles.main}>
<AppBarWitHistory <AppBarWitHistory
toggleDrawerIcon={<IconButton onClick={this.toggleDrawer}><NavigationMenu /></IconButton>} toggleDrawerIcon={<IconButton onClick={this.toggleDrawer}><NavigationMenu /></IconButton>}
iconElementRight={ iconElementRight={
<IconButton disabled={!credentials || fetching} onClick={this.refresh} title="Refresh"> <IconButton disabled={!credentials || fetching} onClick={this.refresh} title="Refresh">
<IconRefreshWithSpin spin={fetching} /> <IconRefreshWithSpin spin={fetching} />
</IconButton>} </IconButton>}
/> />
<Drawer <Drawer
open={this.state.drawerOpen} open={this.state.drawerOpen}
onClose={this.toggleDrawer} onClose={this.toggleDrawer}
> >
<SideMenu etesync={credentials} onCloseDrawerRequest={this.closeDrawer} /> <SideMenu etesync={credentials} onCloseDrawerRequest={this.closeDrawer} />
</Drawer> </Drawer>
<ErrorBoundary> <ErrorBoundary>
<LoginGate credentials={this.props.credentials} /> <LoginGate credentials={this.props.credentials} />
</ErrorBoundary> </ErrorBoundary>
</div> </div>
</BrowserRouter> </BrowserRouter>
</ThemeProvider> </ThemeProvider>
); );
} }
private toggleDrawer() { private toggleDrawer() {
this.setState({drawerOpen: !this.state.drawerOpen}); this.setState({ drawerOpen: !this.state.drawerOpen });
} }
private closeDrawer() { private closeDrawer() {
this.setState({drawerOpen: false}); this.setState({ drawerOpen: false });
} }
private refresh() { private refresh() {
@ -238,7 +238,7 @@ const credentialsSelector = createSelector(
(state: store.StoreState) => state.encryptionKey.key, (state: store.StoreState) => state.encryptionKey.key,
(value, error, fetching, encryptionKey) => { (value, error, fetching, encryptionKey) => {
if (value === null) { if (value === null) {
return {value, error, fetching}; return { value, error, fetching };
} }
return { return {

@ -71,14 +71,14 @@ class ImportDialog extends React.Component<PropsType> {
<DialogTitle>Import entries from file?</DialogTitle> <DialogTitle>Import entries from file?</DialogTitle>
<DialogContent> <DialogContent>
{ loading ? { loading ?
<LoadingIndicator style={{display: 'block', margin: 'auto'}} /> <LoadingIndicator style={{ display: 'block', margin: 'auto' }} />
: :
<Dropzone <Dropzone
onDrop={dropFunction} onDrop={dropFunction}
multiple={false} multiple={false}
accept={acceptTypes} accept={acceptTypes}
> >
{({getRootProps, getInputProps}) => ( {({ getRootProps, getInputProps }) => (
<section> <section>
<div {...getRootProps()}> <div {...getRootProps()}>
<input {...getInputProps()} /> <input {...getInputProps()} />
@ -87,7 +87,7 @@ class ImportDialog extends React.Component<PropsType> {
</DialogContentText> </DialogContentText>
</div> </div>
</section> </section>
)} )}
</Dropzone> </Dropzone>
} }
</DialogContent> </DialogContent>

@ -51,8 +51,8 @@ const JournalTaskList = journalView(TaskList, Task);
class Journal extends React.Component<PropsTypeInner> { class Journal extends React.Component<PropsTypeInner> {
public state: { public state: {
tab: number, tab: number;
importDialogOpen: boolean, importDialogOpen: boolean;
}; };
constructor(props: PropsTypeInner) { constructor(props: PropsTypeInner) {
@ -87,7 +87,7 @@ class Journal extends React.Component<PropsTypeInner> {
itemsView = itemsView =
<JournalAddressBook journal={journal} entries={syncEntriesToItemMap(collectionInfo, syncEntries)} />; <JournalAddressBook journal={journal} entries={syncEntriesToItemMap(collectionInfo, syncEntries)} />;
itemsTitle = 'Contacts'; itemsTitle = 'Contacts';
} else if (collectionInfo.type === 'TASKS') { } else if (collectionInfo.type === 'TASKS') {
itemsView = ( itemsView = (
<JournalTaskList <JournalTaskList
journal={journal} journal={journal}
@ -110,14 +110,14 @@ class Journal extends React.Component<PropsTypeInner> {
<IconButton <IconButton
component={Link} component={Link}
title="Edit" title="Edit"
{...{to: routeResolver.getRoute('journals._id.edit', { journalUid: journal.uid })}} {...{ to: routeResolver.getRoute('journals._id.edit', { journalUid: journal.uid }) }}
> >
<IconEdit /> <IconEdit />
</IconButton> </IconButton>
<IconButton <IconButton
component={Link} component={Link}
title="Members" title="Members"
{...{to: routeResolver.getRoute('journals._id.members', { journalUid: journal.uid })}} {...{ to: routeResolver.getRoute('journals._id.members', { journalUid: journal.uid }) }}
> >
<IconMembers /> <IconMembers />
</IconButton> </IconButton>

@ -54,7 +54,7 @@ class JournalEdit extends React.PureComponent<PropsTypeInner> {
if (this.props.item !== undefined) { if (this.props.item !== undefined) {
const collection = this.props.item; const collection = this.props.item;
this.state.info = {...collection}; this.state.info = { ...collection };
} else { } else {
this.state.info.uid = EteSync.genUid(); this.state.info.uid = EteSync.genUid();
this.state.info.type = 'ADDRESS_BOOK'; this.state.info.type = 'ADDRESS_BOOK';
@ -86,9 +86,9 @@ class JournalEdit extends React.PureComponent<PropsTypeInner> {
return ( return (
<> <>
<AppBarOverride title={pageTitle} /> <AppBarOverride title={pageTitle} />
<Container style={{maxWidth: '30rem'}}> <Container style={{ maxWidth: '30rem' }}>
<form onSubmit={this.onSubmit}> <form onSubmit={this.onSubmit}>
<FormControl disabled={this.props.item !== undefined} style={styles.fullWidth} > <FormControl disabled={this.props.item !== undefined} style={styles.fullWidth}>
<InputLabel> <InputLabel>
Collection type Collection type
</InputLabel> </InputLabel>
@ -126,17 +126,17 @@ class JournalEdit extends React.PureComponent<PropsTypeInner> {
variant="contained" variant="contained"
onClick={onCancel} onClick={onCancel}
> >
<IconCancel style={{marginRight: 8}} /> <IconCancel style={{ marginRight: 8 }} />
Cancel Cancel
</Button> </Button>
{this.props.item && {this.props.item &&
<Button <Button
variant="contained" variant="contained"
style={{marginLeft: 15, backgroundColor: colors.red[500], color: 'white'}} style={{ marginLeft: 15, backgroundColor: colors.red[500], color: 'white' }}
onClick={this.onDeleteRequest} onClick={this.onDeleteRequest}
> >
<IconDelete style={{marginRight: 8}} /> <IconDelete style={{ marginRight: 8 }} />
Delete Delete
</Button> </Button>
} }
@ -145,9 +145,9 @@ class JournalEdit extends React.PureComponent<PropsTypeInner> {
type="submit" type="submit"
variant="contained" variant="contained"
color="secondary" color="secondary"
style={{marginLeft: 15}} style={{ marginLeft: 15 }}
> >
<IconSave style={{marginRight: 8}} /> <IconSave style={{ marginRight: 8 }} />
Save Save
</Button> </Button>
</div> </div>
@ -158,7 +158,7 @@ class JournalEdit extends React.PureComponent<PropsTypeInner> {
labelOk="Delete" labelOk="Delete"
open={this.state.showDeleteDialog} open={this.state.showDeleteDialog}
onOk={() => onDelete(this.props.item!)} onOk={() => onDelete(this.props.item!)}
onCancel={() => this.setState({showDeleteDialog: false})} onCancel={() => this.setState({ showDeleteDialog: false })}
> >
Are you sure you would like to delete this journal? Are you sure you would like to delete this journal?
</ConfirmationDialog> </ConfirmationDialog>

@ -119,7 +119,7 @@ class JournalMemberAddDialog extends React.PureComponent<PropsType> {
publicKey: userInfo.publicKey, publicKey: userInfo.publicKey,
}); });
}).catch((error) => { }).catch((error) => {
this.setState({error}); this.setState({ error });
}); });
} }

@ -53,26 +53,26 @@ class JournalMembers extends React.PureComponent<PropsTypeInner> {
return ( return (
<> <>
<AppBarOverride title={`${info.displayName} - Members`} /> <AppBarOverride title={`${info.displayName} - Members`} />
<Container style={{maxWidth: '30rem'}}> <Container style={{ maxWidth: '30rem' }}>
{ members ? { members ?
<List> <List>
<ListItem rightIcon={<IconMemberAdd />} onClick={() => this.setState({ addMemberOpen: true })}> <ListItem rightIcon={<IconMemberAdd />} onClick={() => this.setState({ addMemberOpen: true })}>
Add member Add member
</ListItem> </ListItem>
{(members.length > 0 ? {(members.length > 0 ?
members.map((member) => ( members.map((member) => (
<ListItem key={member.user} onClick={() => this.onRevokeRequest(member.user)}> <ListItem key={member.user} onClick={() => this.onRevokeRequest(member.user)}>
{member.user} {member.user}
</ListItem> </ListItem>
)) ))
: :
<ListItem> <ListItem>
No members No members
</ListItem> </ListItem>
)} )}
</List> </List>
: :
<LoadingIndicator /> <LoadingIndicator />
} }
</Container> </Container>
<ConfirmationDialog <ConfirmationDialog
@ -80,7 +80,7 @@ class JournalMembers extends React.PureComponent<PropsTypeInner> {
labelOk="OK" labelOk="OK"
open={revokeUser !== null} open={revokeUser !== null}
onOk={this.onRevokeDo} onOk={this.onRevokeDo}
onCancel={() => this.setState({revokeUser: null})} onCancel={() => this.setState({ revokeUser: null })}
> >
Would you like to revoke {revokeUser}'s access?<br /> Would you like to revoke {revokeUser}'s access?<br />
Please be advised that a malicious user would potentially be able to retain access to encryption keys. Please refer to the FAQ for more information. Please be advised that a malicious user would potentially be able to retain access to encryption keys. Please refer to the FAQ for more information.
@ -94,7 +94,7 @@ class JournalMembers extends React.PureComponent<PropsTypeInner> {
onOk={this.onMemberAdd} onOk={this.onMemberAdd}
onClose={() => this.setState({ addMemberOpen: false })} onClose={() => this.setState({ addMemberOpen: false })}
/> />
: :
<ConfirmationDialog <ConfirmationDialog
title="Now Allowed" title="Now Allowed"
labelOk="OK" labelOk="OK"

@ -56,7 +56,7 @@ class JournalsList extends React.PureComponent {
<IconButton <IconButton
component={Link} component={Link}
title="New" title="New"
{...{to: routeResolver.getRoute('journals.new')}} {...{ to: routeResolver.getRoute('journals.new') }}
> >
<IconAdd /> <IconAdd />
</IconButton> </IconButton>

@ -62,7 +62,7 @@ class Journals extends React.PureComponent {
/> />
<Route <Route
path={routeResolver.getRoute('journals._id')} path={routeResolver.getRoute('journals._id')}
render={({match}) => { render={({ match }) => {
const journalUid = match.params.journalUid; const journalUid = match.params.journalUid;
const syncJournal = this.props.syncInfo.get(journalUid); const syncJournal = this.props.syncInfo.get(journalUid);

@ -14,9 +14,9 @@ function objValues(obj: any) {
export function journalView(JournalList: any, JournalItem: any) { export function journalView(JournalList: any, JournalItem: any) {
return withRouter(class extends React.PureComponent { return withRouter(class extends React.PureComponent {
public props: { public props: {
journal: EteSync.Journal, journal: EteSync.Journal;
entries: {[key: string]: any}, entries: {[key: string]: any};
history?: History, history?: History;
}; };
constructor(props: any) { constructor(props: any) {
@ -41,13 +41,13 @@ export function journalView(JournalList: any, JournalItem: any) {
exact exact
render={() => ( render={() => (
<JournalList entries={objValues(items)} onItemClick={this.itemClicked} /> <JournalList entries={objValues(items)} onItemClick={this.itemClicked} />
) )
} }
/> />
<Route <Route
path={routeResolver.getRoute('journals._id.items._id')} path={routeResolver.getRoute('journals._id.items._id')}
exact exact
render={({match}) => { render={({ match }) => {
return ( return (
<JournalItem item={items[`${match.params.journalUid}|${match.params.itemUid}`]} /> <JournalItem item={items[`${match.params.journalUid}|${match.params.itemUid}`]} />

@ -35,7 +35,7 @@ function EncryptionPart(props: { credentials: CredentialsType, onEncryptionFormS
return ( return (
<Container style={{maxWidth: '30rem'}}> <Container style={{ maxWidth: '30rem' }}>
<h2>Encryption Password</h2> <h2>Encryption Password</h2>
{ (isNewUser) ? { (isNewUser) ?
<div> <div>
@ -93,7 +93,7 @@ class LoginGate extends React.Component {
}; };
return ( return (
<Container style={{maxWidth: '30rem'}}> <Container style={{ maxWidth: '30rem' }}>
<h2>Please Log In</h2> <h2>Please Log In</h2>
<LoginForm <LoginForm
onSubmit={this.onFormSubmit} onSubmit={this.onFormSubmit}

@ -43,7 +43,7 @@ class PimMain extends React.PureComponent<PropsType> {
constructor(props: any) { constructor(props: any) {
super(props); super(props);
this.state = {tab: 1}; this.state = { tab: 1 };
this.eventClicked = this.eventClicked.bind(this); this.eventClicked = this.eventClicked.bind(this);
this.taskClicked = this.taskClicked.bind(this); this.taskClicked = this.taskClicked.bind(this);
this.contactClicked = this.contactClicked.bind(this); this.contactClicked = this.contactClicked.bind(this);
@ -78,7 +78,7 @@ class PimMain extends React.PureComponent<PropsType> {
public newEvent(start?: Date, end?: Date) { public newEvent(start?: Date, end?: Date) {
this.props.history!.push( this.props.history!.push(
routeResolver.getRoute('pim.events.new'), routeResolver.getRoute('pim.events.new'),
{start, end} { start, end }
); );
} }
@ -116,7 +116,7 @@ class PimMain extends React.PureComponent<PropsType> {
variant="fullWidth" variant="fullWidth"
style={{ backgroundColor: theme.palette.primary.main }} style={{ backgroundColor: theme.palette.primary.main }}
value={tab} value={tab}
onChange={(event, value) => this.setState({tab: value})} onChange={(event, value) => this.setState({ tab: value })}
> >
<Tab <Tab
label={addressBookTitle} label={addressBookTitle}

@ -101,12 +101,12 @@ const ItemChangeLog = React.memo((props: any) => {
}); });
type CollectionRoutesPropsType = RouteComponentProps<{}> & { type CollectionRoutesPropsType = RouteComponentProps<{}> & {
syncInfo: SyncInfo, syncInfo: SyncInfo;
routePrefix: string, routePrefix: string;
collections: EteSync.CollectionInfo[], collections: EteSync.CollectionInfo[];
componentEdit: any, componentEdit: any;
componentView: any, componentView: any;
items: {[key: string]: PimType}, items: {[key: string]: PimType};
onItemSave: (item: PimType, journalUid: string, originalContact?: PimType) => void; onItemSave: (item: PimType, journalUid: string, originalContact?: PimType) => void;
onItemDelete: (item: PimType, journalUid: string) => void; onItemDelete: (item: PimType, journalUid: string) => void;
onItemCancel: () => void; onItemCancel: () => void;
@ -135,8 +135,8 @@ const CollectionRoutes = withStyles(styles)(withRouter(
<Route <Route
path={routeResolver.getRoute(props.routePrefix + '.new')} path={routeResolver.getRoute(props.routePrefix + '.new')}
exact exact
render={({match}) => ( render={({ match }) => (
<Container style={{maxWidth: '30rem'}}> <Container style={{ maxWidth: '30rem' }}>
<ComponentEdit <ComponentEdit
collections={props.collections} collections={props.collections}
onSave={props.onItemSave} onSave={props.onItemSave}
@ -148,8 +148,8 @@ const CollectionRoutes = withStyles(styles)(withRouter(
<Route <Route
path={routeResolver.getRoute(props.routePrefix + '._id.edit')} path={routeResolver.getRoute(props.routePrefix + '._id.edit')}
exact exact
render={({match}) => ( render={({ match }) => (
<Container style={{maxWidth: '30rem'}}> <Container style={{ maxWidth: '30rem' }}>
{(match.params.itemUid in props.items) && {(match.params.itemUid in props.items) &&
<ComponentEdit <ComponentEdit
initialCollection={(props.items[match.params.itemUid] as any).journalUid} initialCollection={(props.items[match.params.itemUid] as any).journalUid}
@ -166,7 +166,7 @@ const CollectionRoutes = withStyles(styles)(withRouter(
<Route <Route
path={routeResolver.getRoute(props.routePrefix + '._id.log')} path={routeResolver.getRoute(props.routePrefix + '._id.log')}
exact exact
render={({match}) => ( render={({ match }) => (
<Container> <Container>
<ItemChangeLog <ItemChangeLog
syncInfo={props.syncInfo} syncInfo={props.syncInfo}
@ -178,19 +178,19 @@ const CollectionRoutes = withStyles(styles)(withRouter(
<Route <Route
path={routeResolver.getRoute(props.routePrefix + '._id')} path={routeResolver.getRoute(props.routePrefix + '._id')}
exact exact
render={({match, history}) => ( render={({ match, history }) => (
<Container> <Container>
<div style={{textAlign: 'right', marginBottom: 15}}> <div style={{ textAlign: 'right', marginBottom: 15 }}>
<Button <Button
variant="contained" variant="contained"
className={classes.button} className={classes.button}
onClick={() => onClick={() =>
history.push(routeResolver.getRoute( history.push(routeResolver.getRoute(
props.routePrefix + '._id.log', props.routePrefix + '._id.log',
{itemUid: match.params.itemUid})) { itemUid: match.params.itemUid }))
} }
> >
<IconChangeHistory className={classes.leftIcon} /> <IconChangeHistory className={classes.leftIcon} />
Change History Change History
</Button> </Button>
@ -199,11 +199,11 @@ const CollectionRoutes = withStyles(styles)(withRouter(
variant="contained" variant="contained"
disabled={!props.componentEdit} disabled={!props.componentEdit}
className={classes.button} className={classes.button}
style={{marginLeft: 15}} style={{ marginLeft: 15 }}
onClick={() => onClick={() =>
history.push(routeResolver.getRoute( history.push(routeResolver.getRoute(
props.routePrefix + '._id.edit', props.routePrefix + '._id.edit',
{itemUid: match.params.itemUid})) { itemUid: match.params.itemUid }))
} }
> >
<IconEdit className={classes.leftIcon} /> <IconEdit className={classes.leftIcon} />
@ -254,20 +254,20 @@ class Pim extends React.PureComponent {
store.dispatch<any>(fetchEntries(this.props.etesync, journal.uid, prevUid)) store.dispatch<any>(fetchEntries(this.props.etesync, journal.uid, prevUid))
.then((entriesAction: Action<EteSync.Entry[]>) => { .then((entriesAction: Action<EteSync.Entry[]>) => {
last = entriesAction.payload!.slice(-1).pop() as EteSync.Entry; last = entriesAction.payload!.slice(-1).pop() as EteSync.Entry;
if (last) { if (last) {
prevUid = last.uid; prevUid = last.uid;
} }
const saveEvent = store.dispatch( const saveEvent = store.dispatch(
addJournalEntry( addJournalEntry(
this.props.etesync, this.props.userInfo, journal, this.props.etesync, this.props.userInfo, journal,
prevUid, action, item.toIcal())); prevUid, action, item.toIcal()));
(saveEvent as any).then(() => { (saveEvent as any).then(() => {
this.props.history.goBack(); this.props.history.goBack();
});
}); });
});
} }
public onItemDelete(item: PimType, journalUid: string) { public onItemDelete(item: PimType, journalUid: string) {
@ -289,20 +289,20 @@ class Pim extends React.PureComponent {
store.dispatch<any>(fetchEntries(this.props.etesync, journal.uid, prevUid)) store.dispatch<any>(fetchEntries(this.props.etesync, journal.uid, prevUid))
.then((entriesAction: Action<EteSync.Entry[]>) => { .then((entriesAction: Action<EteSync.Entry[]>) => {
last = entriesAction.payload!.slice(-1).pop() as EteSync.Entry; last = entriesAction.payload!.slice(-1).pop() as EteSync.Entry;
if (last) { if (last) {
prevUid = last.uid; prevUid = last.uid;
} }
const deleteItem = store.dispatch( const deleteItem = store.dispatch(
addJournalEntry( addJournalEntry(
this.props.etesync, this.props.userInfo, journal, this.props.etesync, this.props.userInfo, journal,
prevUid, action, item.toIcal())); prevUid, action, item.toIcal()));
(deleteItem as any).then(() => { (deleteItem as any).then(() => {
this.props.history.push(routeResolver.getRoute('pim')); this.props.history.push(routeResolver.getRoute('pim'));
});
}); });
});
} }
public onCancel() { public onCancel() {
@ -317,7 +317,7 @@ class Pim extends React.PureComponent {
<Route <Route
path={routeResolver.getRoute('pim')} path={routeResolver.getRoute('pim')}
exact exact
render={({history}) => ( render={({ history }) => (
<PimMain <PimMain
contacts={objValues(addressBookItems)} contacts={objValues(addressBookItems)}
events={objValues(calendarItems)} events={objValues(calendarItems)}

@ -35,7 +35,7 @@ class Settings extends React.PureComponent<PropsTypeInner> {
<AppBarOverride title="Settings" /> <AppBarOverride title="Settings" />
<Container> <Container>
<h1>Date & Time</h1> <h1>Date & Time</h1>
<FormControl style={{width: '15em'}}> <FormControl style={{ width: '15em' }}>
<InputLabel> <InputLabel>
Locale Locale
</InputLabel> </InputLabel>
@ -62,7 +62,7 @@ class Settings extends React.PureComponent<PropsTypeInner> {
const value = event.target.value; const value = event.target.value;
const { settings } = this.props; const { settings } = this.props;
store.dispatch(setSettings({ ...settings, [name]: value})); store.dispatch(setSettings({ ...settings, [name]: value }));
} }
} }

@ -68,16 +68,16 @@ class SideMenu extends React.PureComponent<PropsTypeInner> {
this.props.history.push(routeResolver.getRoute('settings')); this.props.history.push(routeResolver.getRoute('settings'));
}} }}
/> />
<ListItem primaryText="Log Out" leftIcon={<LogoutIcon />} onClick={this.logout} /> <ListItem primaryText="Log Out" leftIcon={<LogoutIcon />} onClick={this.logout} />
</React.Fragment> </React.Fragment>
); );
} }
return ( return (
<div style={{ overflowX: 'hidden', width: 250}}> <div style={{ overflowX: 'hidden', width: 250 }}>
<div className="App-drawer-header"> <div className="App-drawer-header">
<img alt="App logo" className="App-drawer-logo" src={logo} /> <img alt="App logo" className="App-drawer-logo" src={logo} />
<div style={{ color: theme.palette.secondary.contrastText }} > <div style={{ color: theme.palette.secondary.contrastText }}>
{username} {username}
</div> </div>
</div> </div>

@ -123,7 +123,7 @@ class SyncGate extends React.PureComponent<PropsTypeInner> {
if (!journalAction.error) { if (!journalAction.error) {
store.dispatch(fetchEntries(this.props.etesync, collection.uid)); store.dispatch(fetchEntries(this.props.etesync, collection.uid));
} }
}); });
}); });
}); });
}; };
@ -162,14 +162,14 @@ class SyncGate extends React.PureComponent<PropsTypeInner> {
const errors: Array<{journal: string, error: Error}> = []; const errors: Array<{journal: string, error: Error}> = [];
this.props.entries.forEach((entry, journal) => { this.props.entries.forEach((entry, journal) => {
if (entry.error) { if (entry.error) {
errors.push({journal, error: entry.error}); errors.push({ journal, error: entry.error });
} }
}); });
if (errors.length > 0) { if (errors.length > 0) {
return ( return (
<ul> <ul>
{errors.map((error) => (<li>{error.journal}: {error.error.toString()}</li>))} {errors.map((error, idx) => (<li key={idx}>{error.journal}: {error.error.toString()}</li>))}
</ul> </ul>
); );
} }
@ -178,8 +178,8 @@ class SyncGate extends React.PureComponent<PropsTypeInner> {
if ((this.props.userInfo.value === null) || (journals === null) || if ((this.props.userInfo.value === null) || (journals === null) ||
((this.props.fetchCount > 0) && ((this.props.fetchCount > 0) &&
((entryArrays.size === 0) || !entryArrays.every((x: any) => (x.value !== null)))) ((entryArrays.size === 0) || !entryArrays.every((x: any) => (x.value !== null))))
) { ) {
return (<LoadingIndicator style={{display: 'block', margin: '40px auto'}} />); return (<LoadingIndicator style={{ display: 'block', margin: '40px auto' }} />);
} }
// FIXME: Shouldn't be here // FIXME: Shouldn't be here
@ -193,13 +193,13 @@ class SyncGate extends React.PureComponent<PropsTypeInner> {
<Route <Route
path={routeResolver.getRoute('home')} path={routeResolver.getRoute('home')}
exact exact
render={({match}) => ( render={() => (
<Redirect to={routeResolver.getRoute('pim')} /> <Redirect to={routeResolver.getRoute('pim')} />
)} )}
/> />
<Route <Route
path={routeResolver.getRoute('pim')} path={routeResolver.getRoute('pim')}
render={({match, history}) => ( render={({ history }) => (
<> <>
<AppBarOverride title="EteSync" /> <AppBarOverride title="EteSync" />
<PimRouter <PimRouter
@ -227,7 +227,7 @@ class SyncGate extends React.PureComponent<PropsTypeInner> {
<Route <Route
path={routeResolver.getRoute('settings')} path={routeResolver.getRoute('settings')}
exact exact
render={({history}) => ( render={({ history }) => (
<Settings <Settings
history={history} history={history}
/> />
@ -238,7 +238,7 @@ class SyncGate extends React.PureComponent<PropsTypeInner> {
} }
} }
const mapStateToProps = (state: StoreState, props: PropsType) => { const mapStateToProps = (state: StoreState, _props: PropsType) => {
return { return {
settings: state.settings, settings: state.settings,
journals: state.cache.journals, journals: state.cache.journals,

@ -30,7 +30,7 @@ it('Simple sync', async () => {
const uid1 = sjcl.codec.hex.fromBits(sjcl.hash.sha256.hash('id1')); const uid1 = sjcl.codec.hex.fromBits(sjcl.hash.sha256.hash('id1'));
const cryptoManager = new EteSync.CryptoManager(keyBase64, USER); const cryptoManager = new EteSync.CryptoManager(keyBase64, USER);
const info1 = new EteSync.CollectionInfo({uid: uid1, content: 'test', displayName: 'Dislpay 1'}); const info1 = new EteSync.CollectionInfo({ uid: uid1, content: 'test', displayName: 'Dislpay 1' });
const journal = new EteSync.Journal(); const journal = new EteSync.Journal();
journal.setInfo(cryptoManager, info1); journal.setInfo(cryptoManager, info1);
@ -66,7 +66,7 @@ it('Journal Entry sync', async () => {
const uid1 = sjcl.codec.hex.fromBits(sjcl.hash.sha256.hash('id1')); const uid1 = sjcl.codec.hex.fromBits(sjcl.hash.sha256.hash('id1'));
const cryptoManager = new EteSync.CryptoManager(keyBase64, USER); const cryptoManager = new EteSync.CryptoManager(keyBase64, USER);
const info1 = new EteSync.CollectionInfo({uid: uid1, content: 'test', displayName: 'Dislpay 1'}); const info1 = new EteSync.CollectionInfo({ uid: uid1, content: 'test', displayName: 'Dislpay 1' });
const journal = new EteSync.Journal(); const journal = new EteSync.Journal();
journal.setInfo(cryptoManager, info1); journal.setInfo(cryptoManager, info1);
@ -77,7 +77,7 @@ it('Journal Entry sync', async () => {
let entries = await entryManager.list(null); let entries = await entryManager.list(null);
expect(entries.length).toBe(0); expect(entries.length).toBe(0);
const syncEntry = new EteSync.SyncEntry({action: 'ADD', content: 'bla'}); const syncEntry = new EteSync.SyncEntry({ action: 'ADD', content: 'bla' });
let prevUid = null; let prevUid = null;
const entry = new EteSync.Entry(); const entry = new EteSync.Entry();
entry.setSyncEntry(cryptoManager, syncEntry, prevUid); entry.setSyncEntry(cryptoManager, syncEntry, prevUid);

@ -48,7 +48,7 @@ function CastJson(json: any, to: any) {
} }
function hmacToHex(hmac: byte[]): string { function hmacToHex(hmac: byte[]): string {
return sjcl.codec.hex.fromBits(sjcl.codec.bytes.toBits(hmac)); return sjcl.codec.hex.fromBits(sjcl.codec.bytes.toBits(hmac));
} }
export class Credentials { export class Credentials {
@ -497,7 +497,7 @@ export class EntryManager extends BaseManager {
super(credentials, apiBase, ['journals', journalId, 'entries', '']); super(credentials, apiBase, ['journals', journalId, 'entries', '']);
} }
public list(lastUid: string | null, limit: number = 0): Promise<Entry[]> { public list(lastUid: string | null, limit = 0): Promise<Entry[]> {
let apiBase = this.apiBase.clone(); let apiBase = this.apiBase.clone();
apiBase = apiBase.search({ apiBase = apiBase.search({
last: (lastUid !== null) ? lastUid : undefined, last: (lastUid !== null) ? lastUid : undefined,

@ -48,7 +48,7 @@ const AddressBookItem = React.memo((_props: any) => {
return ( return (
<ListItem <ListItem
leftIcon={ leftIcon={
<Avatar style={{backgroundColor: getContactColor(entry)}}> <Avatar style={{ backgroundColor: getContactColor(entry) }}>
{name && name[0].toUpperCase()} {name && name[0].toUpperCase()}
</Avatar>} </Avatar>}
primaryText={name} primaryText={name}
@ -64,7 +64,7 @@ const sortSelector = createSelector(
const a = _a.fn; const a = _a.fn;
const b = _b.fn; const b = _b.fn;
return a.localeCompare(b, undefined, {sensitivity: 'base'}); return a.localeCompare(b, undefined, { sensitivity: 'base' });
}); });
} }
); );

@ -72,7 +72,7 @@ class Calendar extends React.PureComponent<PropsType> {
}); });
return ( return (
<div style={{width: '100%', height: 'calc(100vh - 230px)', minHeight: 500}}> <div style={{ width: '100%', height: 'calc(100vh - 230px)', minHeight: 500 }}>
<BigCalendar <BigCalendar
defaultDate={new Date()} defaultDate={new Date()}
scrollToTime={new Date(1970, 1, 1, 8)} scrollToTime={new Date(1970, 1, 1, 8)}
@ -81,7 +81,7 @@ class Calendar extends React.PureComponent<PropsType> {
selectable selectable
onSelectEvent={this.props.onItemClick as any} onSelectEvent={this.props.onItemClick as any}
onSelectSlot={this.slotClicked as any} onSelectSlot={this.slotClicked as any}
formats={{agendaHeaderFormat: agendaHeaderFormat as any}} formats={{ agendaHeaderFormat: agendaHeaderFormat as any }}
eventPropGetter={eventPropGetter} eventPropGetter={eventPropGetter}
date={this.state.currentDate} date={this.state.currentDate}
onNavigate={this.onNavigate} onNavigate={this.onNavigate}
@ -93,11 +93,11 @@ class Calendar extends React.PureComponent<PropsType> {
} }
private onNavigate(currentDate: Date) { private onNavigate(currentDate: Date) {
this.setState({currentDate}); this.setState({ currentDate });
} }
private onView(view: string) { private onView(view: string) {
this.setState({view}); this.setState({ view });
} }
private slotClicked(slotInfo: {start: Date, end: Date}) { private slotClicked(slotInfo: {start: Date, end: Date}) {

@ -16,7 +16,7 @@ import { IconButton } from '@material-ui/core';
class Contact extends React.PureComponent { class Contact extends React.PureComponent {
public props: { public props: {
item?: ContactType, item?: ContactType;
}; };
public render() { public render() {

@ -24,24 +24,24 @@ import * as EteSync from '../api/EteSync';
import { ContactType } from '../pim-types'; import { ContactType } from '../pim-types';
const telTypes = [ const telTypes = [
{type: 'Home'}, { type: 'Home' },
{type: 'Work'}, { type: 'Work' },
{type: 'Cell'}, { type: 'Cell' },
{type: 'Other'}, { type: 'Other' },
]; ];
const emailTypes = telTypes; const emailTypes = telTypes;
const addressTypes = [ const addressTypes = [
{type: 'Home'}, { type: 'Home' },
{type: 'Work'}, { type: 'Work' },
{type: 'Other'}, { type: 'Other' },
]; ];
const imppTypes = [ const imppTypes = [
{type: 'Jabber'}, { type: 'Jabber' },
{type: 'Hangouts'}, { type: 'Hangouts' },
{type: 'Other'}, { type: 'Other' },
]; ];
const TypeSelector = (props: any) => { const TypeSelector = (props: any) => {
@ -122,7 +122,7 @@ interface PropsType {
class ContactEdit extends React.PureComponent<PropsType> { class ContactEdit extends React.PureComponent<PropsType> {
public state: { public state: {
uid: string, uid: string;
fn: string; fn: string;
phone: ValueType[]; phone: ValueType[];
email: ValueType[]; email: ValueType[];
@ -297,7 +297,7 @@ class ContactEdit extends React.PureComponent<PropsType> {
setProperties('email', this.state.email); setProperties('email', this.state.email);
setProperties('adr', this.state.address); setProperties('adr', this.state.address);
setProperties('impp', this.state.impp.map((x) => ( setProperties('impp', this.state.impp.map((x) => (
{type: x.type, value: x.type + ':' + x.value} { type: x.type, value: x.type + ':' + x.value }
))); )));
function setProperty(name: string, value: string) { function setProperty(name: string, value: string) {
@ -341,7 +341,7 @@ class ContactEdit extends React.PureComponent<PropsType> {
{this.props.item ? 'Edit Contact' : 'New Contact'} {this.props.item ? 'Edit Contact' : 'New Contact'}
</h2> </h2>
<form style={styles.form} onSubmit={this.onSubmit}> <form style={styles.form} onSubmit={this.onSubmit}>
<FormControl disabled={this.props.item !== undefined} style={styles.fullWidth} > <FormControl disabled={this.props.item !== undefined} style={styles.fullWidth}>
<InputLabel> <InputLabel>
Saving to Saving to
</InputLabel> </InputLabel>
@ -382,7 +382,7 @@ class ContactEdit extends React.PureComponent<PropsType> {
value={this.state.phone[idx]} value={this.state.phone[idx]}
onClearRequest={(name: string) => this.removeValueType(name, idx)} onClearRequest={(name: string) => this.removeValueType(name, idx)}
onChange={(name: string, type: string, value: string) => ( onChange={(name: string, type: string, value: string) => (
this.handleValueTypeChange(name, idx, {type, value}) this.handleValueTypeChange(name, idx, { type, value })
)} )}
/> />
))} ))}
@ -405,7 +405,7 @@ class ContactEdit extends React.PureComponent<PropsType> {
value={this.state.email[idx]} value={this.state.email[idx]}
onClearRequest={(name: string) => this.removeValueType(name, idx)} onClearRequest={(name: string) => this.removeValueType(name, idx)}
onChange={(name: string, type: string, value: string) => ( onChange={(name: string, type: string, value: string) => (
this.handleValueTypeChange(name, idx, {type, value}) this.handleValueTypeChange(name, idx, { type, value })
)} )}
/> />
))} ))}
@ -428,7 +428,7 @@ class ContactEdit extends React.PureComponent<PropsType> {
value={this.state.impp[idx]} value={this.state.impp[idx]}
onClearRequest={(name: string) => this.removeValueType(name, idx)} onClearRequest={(name: string) => this.removeValueType(name, idx)}
onChange={(name: string, type: string, value: string) => ( onChange={(name: string, type: string, value: string) => (
this.handleValueTypeChange(name, idx, {type, value}) this.handleValueTypeChange(name, idx, { type, value })
)} )}
/> />
))} ))}
@ -451,7 +451,7 @@ class ContactEdit extends React.PureComponent<PropsType> {
value={this.state.address[idx]} value={this.state.address[idx]}
onClearRequest={(name: string) => this.removeValueType(name, idx)} onClearRequest={(name: string) => this.removeValueType(name, idx)}
onChange={(name: string, type: string, value: string) => ( onChange={(name: string, type: string, value: string) => (
this.handleValueTypeChange(name, idx, {type, value}) this.handleValueTypeChange(name, idx, { type, value })
)} )}
/> />
))} ))}
@ -486,17 +486,17 @@ class ContactEdit extends React.PureComponent<PropsType> {
variant="contained" variant="contained"
onClick={this.props.onCancel} onClick={this.props.onCancel}
> >
<IconCancel style={{marginRight: 8}} /> <IconCancel style={{ marginRight: 8 }} />
Cancel Cancel
</Button> </Button>
{this.props.item && {this.props.item &&
<Button <Button
variant="contained" variant="contained"
style={{marginLeft: 15, backgroundColor: colors.red[500], color: 'white'}} style={{ marginLeft: 15, backgroundColor: colors.red[500], color: 'white' }}
onClick={this.onDeleteRequest} onClick={this.onDeleteRequest}
> >
<IconDelete style={{marginRight: 8}} /> <IconDelete style={{ marginRight: 8 }} />
Delete Delete
</Button> </Button>
} }
@ -505,9 +505,9 @@ class ContactEdit extends React.PureComponent<PropsType> {
type="submit" type="submit"
variant="contained" variant="contained"
color="secondary" color="secondary"
style={{marginLeft: 15}} style={{ marginLeft: 15 }}
> >
<IconSave style={{marginRight: 8}} /> <IconSave style={{ marginRight: 8 }} />
Save Save
</Button> </Button>
</div> </div>
@ -518,15 +518,15 @@ class ContactEdit extends React.PureComponent<PropsType> {
</div> </div>
</form> </form>
<ConfirmationDialog <ConfirmationDialog
title="Delete Confirmation" title="Delete Confirmation"
labelOk="Delete" labelOk="Delete"
open={this.state.showDeleteDialog} open={this.state.showDeleteDialog}
onOk={() => this.props.onDelete(this.props.item!, this.props.initialCollection!)} onOk={() => this.props.onDelete(this.props.item!, this.props.initialCollection!)}
onCancel={() => this.setState({showDeleteDialog: false})} onCancel={() => this.setState({ showDeleteDialog: false })}
> >
Are you sure you would like to delete this contact? Are you sure you would like to delete this contact?
</ConfirmationDialog> </ConfirmationDialog>
</React.Fragment> </React.Fragment>
); );
} }

@ -8,7 +8,7 @@ interface FormErrors {
class EncryptionLoginForm extends React.PureComponent { class EncryptionLoginForm extends React.PureComponent {
public state: { public state: {
errors: FormErrors, errors: FormErrors;
encryptionPassword: string; encryptionPassword: string;
}; };
@ -48,10 +48,10 @@ class EncryptionLoginForm extends React.PureComponent {
} }
if (Object.keys(errors).length) { if (Object.keys(errors).length) {
this.setState({errors}); this.setState({ errors });
return; return;
} else { } else {
this.setState({errors: {}}); this.setState({ errors: {} });
} }
this.props.onSubmit(encryptionPassword); this.props.onSubmit(encryptionPassword);

@ -6,17 +6,21 @@ import { resetKey } from '../store/actions';
import { EncryptionPasswordError, IntegrityError } from '../api/EteSync'; import { EncryptionPasswordError, IntegrityError } from '../api/EteSync';
import PrettyError from '../widgets/PrettyError'; import PrettyError from '../widgets/PrettyError';
class ErrorBoundary extends React.Component { interface PropsType {
children: React.ReactNode | React.ReactNode[];
}
class ErrorBoundary extends React.Component<PropsType> {
public state: { public state: {
error?: Error; error?: Error;
}; };
constructor(props: any) { constructor(props: PropsType) {
super(props); super(props);
this.state = { }; this.state = { };
} }
public componentDidCatch(error: Error, info: any) { public componentDidCatch(error: Error, _info: any) {
if (error instanceof EncryptionPasswordError) { if (error instanceof EncryptionPasswordError) {
store.dispatch(resetKey()); store.dispatch(resetKey());
} else if (error instanceof IntegrityError) { } else if (error instanceof IntegrityError) {
@ -46,7 +50,7 @@ class ErrorBoundary extends React.Component {
Please log out from the menu, refresh the page and try again, and if the problem persists, contact support. Please log out from the menu, refresh the page and try again, and if the problem persists, contact support.
</p> </p>
<pre> <pre>
{error.message} {error.message}
</pre> </pre>
</div> </div>
); );

@ -8,7 +8,7 @@ import { EventType } from '../pim-types';
class Event extends React.PureComponent { class Event extends React.PureComponent {
public props: { public props: {
item?: EventType, item?: EventType;
}; };
public render() { public render() {

@ -42,7 +42,7 @@ interface PropsType {
class EventEdit extends React.PureComponent<PropsType> { class EventEdit extends React.PureComponent<PropsType> {
public state: { public state: {
uid: string, uid: string;
title: string; title: string;
allDay: boolean; allDay: boolean;
start?: Date; start?: Date;
@ -143,14 +143,14 @@ class EventEdit extends React.PureComponent<PropsType> {
} }
public toggleAllDay() { public toggleAllDay() {
this.setState({allDay: !this.state.allDay}); this.setState({ allDay: !this.state.allDay });
} }
public onSubmit(e: React.FormEvent<any>) { public onSubmit(e: React.FormEvent<any>) {
e.preventDefault(); e.preventDefault();
if ((!this.state.start) || (!this.state.end)) { if ((!this.state.start) || (!this.state.end)) {
this.setState({error: 'Both start and end time must be set!'}); this.setState({ error: 'Both start and end time must be set!' });
return; return;
} }
@ -173,7 +173,7 @@ class EventEdit extends React.PureComponent<PropsType> {
} }
if (startDate.compare(endDate) >= 0) { if (startDate.compare(endDate) >= 0) {
this.setState({error: 'End time must be later than start time!'}); this.setState({ error: 'End time must be later than start time!' });
return; return;
} }
@ -242,7 +242,7 @@ class EventEdit extends React.PureComponent<PropsType> {
onChange={this.handleInputChange} onChange={this.handleInputChange}
/> />
<FormControl disabled={this.props.item !== undefined} style={styles.fullWidth} > <FormControl disabled={this.props.item !== undefined} style={styles.fullWidth}>
<InputLabel> <InputLabel>
Saving to Saving to
</InputLabel> </InputLabel>
@ -277,7 +277,7 @@ class EventEdit extends React.PureComponent<PropsType> {
dateOnly={this.state.allDay} dateOnly={this.state.allDay}
placeholder="Start" placeholder="Start"
value={this.state.start} value={this.state.start}
onChange={(date?: Date) => this.setState({start: date})} onChange={(date?: Date) => this.setState({ start: date })}
/> />
</div> </div>
@ -286,7 +286,7 @@ class EventEdit extends React.PureComponent<PropsType> {
dateOnly={this.state.allDay} dateOnly={this.state.allDay}
placeholder="End" placeholder="End"
value={this.state.end} value={this.state.end}
onChange={(date?: Date) => this.setState({end: date})} onChange={(date?: Date) => this.setState({ end: date })}
/> />
</div> </div>
@ -312,17 +312,17 @@ class EventEdit extends React.PureComponent<PropsType> {
variant="contained" variant="contained"
onClick={this.props.onCancel} onClick={this.props.onCancel}
> >
<IconCancel style={{marginRight: 8}} /> <IconCancel style={{ marginRight: 8 }} />
Cancel Cancel
</Button> </Button>
{this.props.item && {this.props.item &&
<Button <Button
variant="contained" variant="contained"
style={{marginLeft: 15, backgroundColor: colors.red[500], color: 'white'}} style={{ marginLeft: 15, backgroundColor: colors.red[500], color: 'white' }}
onClick={this.onDeleteRequest} onClick={this.onDeleteRequest}
> >
<IconDelete style={{marginRight: 8}} /> <IconDelete style={{ marginRight: 8 }} />
Delete Delete
</Button> </Button>
} }
@ -331,9 +331,9 @@ class EventEdit extends React.PureComponent<PropsType> {
type="submit" type="submit"
variant="contained" variant="contained"
color="secondary" color="secondary"
style={{marginLeft: 15}} style={{ marginLeft: 15 }}
> >
<IconSave style={{marginRight: 8}} /> <IconSave style={{ marginRight: 8 }} />
Save Save
</Button> </Button>
</div> </div>
@ -344,15 +344,15 @@ class EventEdit extends React.PureComponent<PropsType> {
</div> </div>
</form> </form>
<ConfirmationDialog <ConfirmationDialog
title="Delete Confirmation" title="Delete Confirmation"
labelOk="Delete" labelOk="Delete"
open={this.state.showDeleteDialog} open={this.state.showDeleteDialog}
onOk={() => this.props.onDelete(this.props.item!, this.props.initialCollection!)} onOk={() => this.props.onDelete(this.props.item!, this.props.initialCollection!)}
onCancel={() => this.setState({showDeleteDialog: false})} onCancel={() => this.setState({ showDeleteDialog: false })}
> >
Are you sure you would like to delete this event? Are you sure you would like to delete this event?
</ConfirmationDialog> </ConfirmationDialog>
</React.Fragment> </React.Fragment>
); );
} }

@ -27,9 +27,9 @@ class JournalEntries extends React.PureComponent {
}; };
public props: { public props: {
journal: EteSync.Journal, journal: EteSync.Journal;
entries: Immutable.List<EteSync.SyncEntry>, entries: Immutable.List<EteSync.SyncEntry>;
uid?: string, uid?: string;
}; };
constructor(props: any) { constructor(props: any) {
@ -47,11 +47,11 @@ class JournalEntries extends React.PureComponent {
let icon; let icon;
if (syncEntry.action === EteSync.SyncEntryAction.Add) { if (syncEntry.action === EteSync.SyncEntryAction.Add) {
icon = (<IconAdd style={{color: '#16B14B'}} />); icon = (<IconAdd style={{ color: '#16B14B' }} />);
} else if (syncEntry.action === EteSync.SyncEntryAction.Change) { } else if (syncEntry.action === EteSync.SyncEntryAction.Change) {
icon = (<IconEdit style={{color: '#FEB115'}} />); icon = (<IconEdit style={{ color: '#FEB115' }} />);
} else if (syncEntry.action === EteSync.SyncEntryAction.Delete) { } else if (syncEntry.action === EteSync.SyncEntryAction.Delete) {
icon = (<IconDelete style={{color: '#F20C0C'}} />); icon = (<IconDelete style={{ color: '#F20C0C' }} />);
} }
let name; let name;
@ -91,7 +91,7 @@ class JournalEntries extends React.PureComponent {
}); });
}} }}
/> />
); );
}).reverse(); }).reverse();
return ( return (
@ -99,7 +99,7 @@ class JournalEntries extends React.PureComponent {
<Dialog <Dialog
open={this.state.dialog !== undefined} open={this.state.dialog !== undefined}
onClose={() => { onClose={() => {
this.setState({dialog: undefined}); this.setState({ dialog: undefined });
}} }}
> >
<DialogTitle> <DialogTitle>
@ -112,7 +112,7 @@ class JournalEntries extends React.PureComponent {
<Button <Button
color="primary" color="primary"
onClick={() => { onClick={() => {
this.setState({dialog: undefined}); this.setState({ dialog: undefined });
}} }}
> >
Close Close

@ -77,17 +77,17 @@ class LoginForm extends React.PureComponent {
} }
if (Object.keys(errors).length) { if (Object.keys(errors).length) {
this.setState({errors}); this.setState({ errors });
return; return;
} else { } else {
this.setState({errors: {}}); this.setState({ errors: {} });
} }
this.props.onSubmit(username, password, server); this.props.onSubmit(username, password, server);
} }
public toggleAdvancedSettings() { public toggleAdvancedSettings() {
this.setState({showAdvanced: !this.state.showAdvanced}); this.setState({ showAdvanced: !this.state.showAdvanced });
} }
public render() { public render() {
@ -109,19 +109,19 @@ class LoginForm extends React.PureComponent {
let advancedSettings = null; let advancedSettings = null;
if (this.state.showAdvanced) { if (this.state.showAdvanced) {
advancedSettings = ( advancedSettings = (
<React.Fragment> <React.Fragment>
<TextField <TextField
type="url" type="url"
style={styles.textField} style={styles.textField}
error={!!this.state.errors.errorServer} error={!!this.state.errors.errorServer}
helperText={this.state.errors.errorServer} helperText={this.state.errors.errorServer}
label="Server" label="Server"
name="server" name="server"
value={this.state.server} value={this.state.server}
onChange={this.handleInputChange} onChange={this.handleInputChange}
/> />
<br /> <br />
</React.Fragment> </React.Fragment>
); );
} }

@ -3,23 +3,23 @@ import * as React from 'react';
import { Theme, withTheme } from '@material-ui/core/styles'; import { Theme, withTheme } from '@material-ui/core/styles';
export default withTheme()((props: {text: string, backgroundColor?: string, children?: any, theme: Theme}) => { export default withTheme()((props: {text: string, backgroundColor?: string, children?: any, theme: Theme}) => {
const style = { const style = {
header: { header: {
backgroundColor: (props.backgroundColor !== undefined) ? backgroundColor: (props.backgroundColor !== undefined) ?
props.backgroundColor : props.theme.palette.secondary.main, props.backgroundColor : props.theme.palette.secondary.main,
color: props.theme.palette.secondary.contrastText, color: props.theme.palette.secondary.contrastText,
padding: 15, padding: 15,
}, },
headerText: { headerText: {
marginTop: 10, marginTop: 10,
marginBottom: 10, marginBottom: 10,
}, },
}; };
return ( return (
<div style={style.header}> <div style={style.header}>
<h2 style={style.headerText}>{props.text}</h2> <h2 style={style.headerText}>{props.text}</h2>
{props.children} {props.children}
</div> </div>
); );
}); });

@ -12,8 +12,8 @@ import AddressBook from '../components/AddressBook';
class SearchableAddressBook extends React.PureComponent { class SearchableAddressBook extends React.PureComponent {
public props: { public props: {
entries: ContactType[], entries: ContactType[];
onItemClick: (contact: ContactType) => void, onItemClick: (contact: ContactType) => void;
}; };
public state: { public state: {
@ -22,7 +22,7 @@ class SearchableAddressBook extends React.PureComponent {
constructor(props: any) { constructor(props: any) {
super(props); super(props);
this.state = {searchQuery: ''}; this.state = { searchQuery: '' };
this.handleInputChange = this.handleInputChange.bind(this); this.handleInputChange = this.handleInputChange.bind(this);
} }
@ -47,12 +47,12 @@ class SearchableAddressBook extends React.PureComponent {
<TextField <TextField
name="searchQuery" name="searchQuery"
value={this.state.searchQuery} value={this.state.searchQuery}
style={{fontSize: '120%', marginLeft: 20}} style={{ fontSize: '120%', marginLeft: 20 }}
placeholder="Find Contacts" placeholder="Find Contacts"
onChange={this.handleInputChange} onChange={this.handleInputChange}
/> />
{this.state.searchQuery && {this.state.searchQuery &&
<IconButton onClick={() => this.setState({searchQuery: ''})}> <IconButton onClick={() => this.setState({ searchQuery: '' })}>
<IconClear /> <IconClear />
</IconButton> </IconButton>
} }

@ -8,7 +8,7 @@ import { TaskType } from '../pim-types';
class Task extends React.PureComponent { class Task extends React.PureComponent {
public props: { public props: {
item?: TaskType, item?: TaskType;
}; };
public render() { public render() {

@ -42,7 +42,7 @@ interface PropsType {
class TaskEdit extends React.PureComponent<PropsType> { class TaskEdit extends React.PureComponent<PropsType> {
public state: { public state: {
uid: string, uid: string;
title: string; title: string;
status: TaskStatusType; status: TaskStatusType;
allDay: boolean; allDay: boolean;
@ -131,7 +131,7 @@ class TaskEdit extends React.PureComponent<PropsType> {
} }
public toggleAllDay() { public toggleAllDay() {
this.setState({allDay: !this.state.allDay}); this.setState({ allDay: !this.state.allDay });
} }
public onSubmit(e: React.FormEvent<any>) { public onSubmit(e: React.FormEvent<any>) {
@ -156,7 +156,7 @@ class TaskEdit extends React.PureComponent<PropsType> {
if (startDate && dueDate) { if (startDate && dueDate) {
if (startDate.compare(dueDate) >= 0) { if (startDate.compare(dueDate) >= 0) {
this.setState({error: 'End time must be later than start time!'}); this.setState({ error: 'End time must be later than start time!' });
return; return;
} }
} }
@ -230,7 +230,7 @@ class TaskEdit extends React.PureComponent<PropsType> {
onChange={this.handleInputChange} onChange={this.handleInputChange}
/> />
<FormControl disabled={this.props.item !== undefined} style={styles.fullWidth} > <FormControl disabled={this.props.item !== undefined} style={styles.fullWidth}>
<InputLabel> <InputLabel>
Saving to Saving to
</InputLabel> </InputLabel>
@ -246,7 +246,7 @@ class TaskEdit extends React.PureComponent<PropsType> {
</Select> </Select>
</FormControl> </FormControl>
<FormControl style={styles.fullWidth} > <FormControl style={styles.fullWidth}>
<InputLabel> <InputLabel>
Status Status
</InputLabel> </InputLabel>
@ -281,16 +281,16 @@ class TaskEdit extends React.PureComponent<PropsType> {
dateOnly={this.state.allDay} dateOnly={this.state.allDay}
placeholder="Start" placeholder="Start"
value={this.state.start} value={this.state.start}
onChange={(date?: Date) => this.setState({start: date})} onChange={(date?: Date) => this.setState({ start: date })}
/> />
</div> </div>
<div> <div>
<DateTimePicker <DateTimePicker
dateOnly={this.state.allDay} dateOnly={this.state.allDay}
placeholder="End" placeholder="End"
value={this.state.due} value={this.state.due}
onChange={(date?: Date) => this.setState({due: date})} onChange={(date?: Date) => this.setState({ due: date })}
/> />
</div> </div>
@ -316,17 +316,17 @@ class TaskEdit extends React.PureComponent<PropsType> {
variant="contained" variant="contained"
onClick={this.props.onCancel} onClick={this.props.onCancel}
> >
<IconCancel style={{marginRight: 8}} /> <IconCancel style={{ marginRight: 8 }} />
Cancel Cancel
</Button> </Button>
{this.props.item && {this.props.item &&
<Button <Button
variant="contained" variant="contained"
style={{marginLeft: 15, backgroundColor: colors.red[500], color: 'white'}} style={{ marginLeft: 15, backgroundColor: colors.red[500], color: 'white' }}
onClick={this.onDeleteRequest} onClick={this.onDeleteRequest}
> >
<IconDelete style={{marginRight: 8}} /> <IconDelete style={{ marginRight: 8 }} />
Delete Delete
</Button> </Button>
} }
@ -335,9 +335,9 @@ class TaskEdit extends React.PureComponent<PropsType> {
type="submit" type="submit"
variant="contained" variant="contained"
color="secondary" color="secondary"
style={{marginLeft: 15}} style={{ marginLeft: 15 }}
> >
<IconSave style={{marginRight: 8}} /> <IconSave style={{ marginRight: 8 }} />
Save Save
</Button> </Button>
</div> </div>
@ -348,15 +348,15 @@ class TaskEdit extends React.PureComponent<PropsType> {
</div> </div>
</form> </form>
<ConfirmationDialog <ConfirmationDialog
title="Delete Confirmation" title="Delete Confirmation"
labelOk="Delete" labelOk="Delete"
open={this.state.showDeleteDialog} open={this.state.showDeleteDialog}
onOk={() => this.props.onDelete(this.props.item!, this.props.initialCollection!)} onOk={() => this.props.onDelete(this.props.item!, this.props.initialCollection!)}
onCancel={() => this.setState({showDeleteDialog: false})} onCancel={() => this.setState({ showDeleteDialog: false })}
> >
Are you sure you would like to delete this event? Are you sure you would like to delete this event?
</ConfirmationDialog> </ConfirmationDialog>
</React.Fragment> </React.Fragment>
); );
} }

@ -41,8 +41,8 @@ const sortSelector = createSelector(
class TaskList extends React.PureComponent { class TaskList extends React.PureComponent {
public props: { public props: {
entries: TaskType[], entries: TaskType[];
onItemClick: (contact: TaskType) => void, onItemClick: (contact: TaskType) => void;
}; };
public render() { public render() {

@ -91,7 +91,7 @@ export class TaskType extends EventType {
} }
set status(status: TaskStatusType) { set status(status: TaskStatusType) {
this.component.updatePropertyWithValue('status', status); this.component.updatePropertyWithValue('status', status);
} }
get status(): TaskStatusType { get status(): TaskStatusType {

@ -26,9 +26,9 @@ it('translating routes', () => {
expect(routeResolver.getRoute('post')).toBe('/post'); expect(routeResolver.getRoute('post')).toBe('/post');
expect(routeResolver.getRoute('post._id', { postId: 3 })).toBe('/post/3'); expect(routeResolver.getRoute('post._id', { postId: 3 })).toBe('/post/3');
expect(routeResolver.getRoute('post._id.comment', expect(routeResolver.getRoute('post._id.comment',
{ postId: 3, commentId: 5 })).toBe('/post/3/comment/5'); { postId: 3, commentId: 5 })).toBe('/post/3/comment/5');
expect(routeResolver.getRoute('post._id.revision', expect(routeResolver.getRoute('post._id.revision',
{ postId: 3, revisionId: 5, someOtherVar: 'a' })).toBe('/post/3/history/5/a/test'); { postId: 3, revisionId: 5, someOtherVar: 'a' })).toBe('/post/3/history/5/a/test');
// Failing basic resolves // Failing basic resolves
expect(() => { expect(() => {

@ -189,6 +189,6 @@ export function fetchAll(etesync: CredentialsData, currentEntries: EntriesType)
export const setSettings = createAction( export const setSettings = createAction(
'SET_SETTINGS', 'SET_SETTINGS',
(settings: SettingsType) => { (settings: SettingsType) => {
return {...settings}; return { ...settings };
} }
); );

@ -73,14 +73,14 @@ const entriesSerialize = (state: FetchType<EntriesData>) => {
const entriesDeserialize = (state: EteSync.EntryJson[]): FetchType<EntriesData> => { const entriesDeserialize = (state: EteSync.EntryJson[]): FetchType<EntriesData> => {
if (state === null) { if (state === null) {
return new EntriesFetchRecord({value: null}); return new EntriesFetchRecord({ value: null });
} }
return new EntriesFetchRecord({value: List(state.map((x: any) => { return new EntriesFetchRecord({ value: List(state.map((x: any) => {
const ret = new EteSync.Entry(); const ret = new EteSync.Entry();
ret.deserialize(x); ret.deserialize(x);
return ret; return ret;
}))}); })) });
}; };
const userInfoSerialize = (state: FetchType<UserInfoData>) => { const userInfoSerialize = (state: FetchType<UserInfoData>) => {
@ -125,9 +125,9 @@ const cacheDeserialize = (state: any, key: string) => {
}); });
return ImmutableMap(ret); return ImmutableMap(ret);
} else if (key === 'journals') { } else if (key === 'journals') {
return new JournalsFetchRecord({value: journalsDeserialize(state)}); return new JournalsFetchRecord({ value: journalsDeserialize(state) });
} else if (key === 'userInfo') { } else if (key === 'userInfo') {
return new UserInfoFetchRecord({value: userInfoDeserialize(state)}); return new UserInfoFetchRecord({ value: userInfoDeserialize(state) });
} }
return state; return state;
@ -147,7 +147,7 @@ const cachePersistConfig = {
version: 1, version: 1,
storage: localforage, storage: localforage,
transforms: [createTransform(cacheSerialize, cacheDeserialize)], transforms: [createTransform(cacheSerialize, cacheDeserialize)],
migrate: createMigrate(cacheMigrations, { debug: false}), migrate: createMigrate(cacheMigrations, { debug: false }),
}; };
const reducers = combineReducers({ const reducers = combineReducers({

@ -17,7 +17,7 @@ it('Entries reducer', () => {
const action = { const action = {
type: fetchEntries.toString(), type: fetchEntries.toString(),
meta: {journal: jId, prevUid: null as string | null}, meta: { journal: jId, prevUid: null as string | null },
payload: [entry], payload: [entry],
}; };

@ -7,7 +7,7 @@ function isPromise(val: any) {
export default function promiseMiddleware({ dispatch }: any) { export default function promiseMiddleware({ dispatch }: any) {
return (next: any) => (action: any) => { return (next: any) => (action: any) => {
if (isPromise(action.payload)) { if (isPromise(action.payload)) {
dispatch({...action, payload: undefined}); dispatch({ ...action, payload: undefined });
return action.payload.then( return action.payload.then(
(result: any) => dispatch({ ...action, payload: result }), (result: any) => dispatch({ ...action, payload: result }),

@ -53,7 +53,7 @@ export type UserInfoType = FetchType<UserInfoData>;
export type UserInfoTypeImmutable = Record<UserInfoType>; export type UserInfoTypeImmutable = Record<UserInfoType>;
function fetchTypeIdentityReducer( function fetchTypeIdentityReducer(
state: Record<FetchType<any>> = fetchTypeRecord<any>()(), action: any, extend: boolean = false) { state: Record<FetchType<any>> = fetchTypeRecord<any>()(), action: any, extend = false) {
if (action.error) { if (action.error) {
return state.set('error', action.payload); return state.set('error', action.payload);
} else { } else {
@ -82,22 +82,22 @@ function fetchTypeIdentityReducer(
export const encryptionKeyReducer = handleActions( export const encryptionKeyReducer = handleActions(
{ {
[actions.deriveKey.toString()]: (state: {key: string | null}, action: any) => ( [actions.deriveKey.toString()]: (state: {key: string | null}, action: any) => (
{key: action.payload} { key: action.payload }
), ),
[actions.resetKey.toString()]: (state: {key: string | null}, action: any) => ( [actions.resetKey.toString()]: (state: {key: string | null}, action: any) => (
{key: null} { key: null }
), ),
[actions.logout.toString()]: (state: {key: string | null}, action: any) => { [actions.logout.toString()]: (state: {key: string | null}, action: any) => {
return {out: true, key: null}; return { out: true, key: null };
}, },
}, },
{key: null} { key: null }
); );
export const credentials = handleActions( export const credentials = handleActions(
{ {
[actions.fetchCredentials.toString()]: ( [actions.fetchCredentials.toString()]: (
state: CredentialsTypeRemote, action: any, extend: boolean = false) => { state: CredentialsTypeRemote, action: any, extend = false) => {
if (action.error) { if (action.error) {
return { return {
value: null, value: null,
@ -119,10 +119,10 @@ export const credentials = handleActions(
} }
}, },
[actions.logout.toString()]: (state: CredentialsTypeRemote, action: any) => { [actions.logout.toString()]: (state: CredentialsTypeRemote, action: any) => {
return {out: true, value: null}; return { out: true, value: null };
}, },
}, },
{value: null} { value: null }
); );
const setMapModelReducer = <T extends Record<any>, V extends BaseModel>(state: T, action: any) => { const setMapModelReducer = <T extends Record<any>, V extends BaseModel>(state: T, action: any) => {
@ -200,7 +200,7 @@ function fetchCreateEntriesReducer(state: EntriesTypeImmutable, action: any) {
const prevState = state.get(action.meta.journal); const prevState = state.get(action.meta.journal);
const extend = action.meta.prevUid != null; const extend = action.meta.prevUid != null;
return state.set(action.meta.journal, return state.set(action.meta.journal,
fetchTypeIdentityReducer(prevState, action, extend)); fetchTypeIdentityReducer(prevState, action, extend));
} }
export const entries = handleActions( export const entries = handleActions(
@ -229,7 +229,7 @@ export const userInfo = handleAction(
actions.fetchUserInfo, actions.fetchUserInfo,
actions.createUserInfo actions.createUserInfo
), ),
(state: Record<FetchType<any>> = fetchTypeRecord<any>()(), action: any, extend: boolean = false) => { (state: Record<FetchType<any>> = fetchTypeRecord<any>()(), action: any, extend = false) => {
if (action.error) { if (action.error) {
return state.set('error', action.payload); return state.set('error', action.payload);
} else { } else {
@ -285,7 +285,7 @@ export interface SettingsType {
export const settingsReducer = handleActions( export const settingsReducer = handleActions(
{ {
[actions.setSettings.toString()]: (state: {key: string | null}, action: any) => ( [actions.setSettings.toString()]: (state: {key: string | null}, action: any) => (
{...action.payload} { ...action.payload }
), ),
}, },
{ locale: 'en-gb' } { locale: 'en-gb' }

@ -1,6 +1,6 @@
import * as React from 'react'; import * as React from 'react';
export const ExternalLink = React.memo(({children, ...props}: any) => ( export const ExternalLink = React.memo(({ children, ...props }: any) => (
<a target="_blank" rel="noopener" {...props}> <a target="_blank" rel="noopener" {...props}>
{children} {children}
</a> </a>

@ -8,7 +8,7 @@ function byteArray4ToNumber(bytes: byte[], offset: number) {
return ( return (
((bytes[offset + 0] & 0xff) * (1 << 24)) + ((bytes[offset + 0] & 0xff) * (1 << 24)) +
((bytes[offset + 1] & 0xff) * (1 << 16)) + ((bytes[offset + 1] & 0xff) * (1 << 16)) +
((bytes[offset + 2] & 0xff) * (1 << 8)) + ((bytes[offset + 2] & 0xff) * (1 << 8)) +
((bytes[offset + 3] & 0xff)) ((bytes[offset + 3] & 0xff))
); );
} }

@ -1,42 +0,0 @@
{
"extends": ["tslint:recommended", "tslint-react"],
"rules": {
"no-console": [true, "error"],
"interface-name": [true, "never-prefix"],
"ordered-imports": false,
"jsx-boolean-value": [true, "never"],
"jsx-curly-spacing": [true, "never"],
"jsx-no-bind": [true, "allowArrowFunctions"],
"jsx-no-lambda": [false],
"jsx-no-multiline-js": false,
"jsx-space-before-trailing-slash": true,
"jsx-key": true,
"max-classes-per-file": [false, 0],
"max-line-length": false,
"no-consecutive-blank-lines": false,
"no-conditional-assignment": false,
"object-literal-sort-keys": false,
"quotemark": [true, "single", "jsx-double", "avoid-escape", "avoid-template"],
"semicolon": [true, "always", "ignore-bound-class-methods"],
"variable-name": [true, "ban-keywords", "check-format", "allow-pascal-case", "allow-leading-underscore"],
"trailing-comma": [
true,
{
"multiline": {
"objects": "always",
"arrays": "always",
"functions": "never",
"typeLiterals": "ignore"
},
"esSpecCompliant": true
}
],
"whitespace": [true,"check-branch", "check-decl", "check-operator", "check-module", "check-separator", "check-rest-spread", "check-type", "check-typecast", "check-type-operator", "check-preblock"]
},
"linterOptions": {
"exclude": [
"config/**/*.js",
"node_modules/**/*.ts"
]
}
}

@ -2461,11 +2461,6 @@ buffer@^4.3.0:
ieee754 "^1.1.4" ieee754 "^1.1.4"
isarray "^1.0.0" isarray "^1.0.0"
builtin-modules@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=
builtin-status-codes@^3.0.0: builtin-status-codes@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
@ -2601,7 +2596,7 @@ caseless@~0.12.0:
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2:
version "2.4.2" version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
@ -2824,7 +2819,7 @@ commander@^2.11.0, commander@^2.20.0, commander@~2.20.3:
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
commander@^2.12.1, commander@~2.19.0: commander@~2.19.0:
version "2.19.0" version "2.19.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==
@ -3531,11 +3526,6 @@ diff-sequences@^24.9.0:
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5"
integrity sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew== integrity sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==
diff@^3.2.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==
diffie-hellman@^5.0.0: diffie-hellman@^5.0.0:
version "5.0.3" version "5.0.3"
resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
@ -6010,7 +6000,7 @@ js-tokens@^3.0.2:
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls=
js-yaml@^3.13.1, js-yaml@^3.7.0: js-yaml@^3.13.1:
version "3.13.1" version "3.13.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
@ -10182,48 +10172,11 @@ ts-pnp@1.1.4, ts-pnp@^1.1.2:
resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.1.4.tgz#ae27126960ebaefb874c6d7fa4729729ab200d90" resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.1.4.tgz#ae27126960ebaefb874c6d7fa4729729ab200d90"
integrity sha512-1J/vefLC+BWSo+qe8OnJQfWTYRS6ingxjwqmHMqaMxXMj7kFtKLgAaYW3JeX3mktjgUL+etlU8/B4VUAUI9QGw== integrity sha512-1J/vefLC+BWSo+qe8OnJQfWTYRS6ingxjwqmHMqaMxXMj7kFtKLgAaYW3JeX3mktjgUL+etlU8/B4VUAUI9QGw==
tslib@^1.8.0:
version "1.9.3"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==
tslib@^1.8.1, tslib@^1.9.0: tslib@^1.8.1, tslib@^1.9.0:
version "1.10.0" version "1.10.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"
integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==
tslint-react@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/tslint-react/-/tslint-react-3.6.0.tgz#7f462c95c4a0afaae82507f06517ff02942196a1"
integrity sha512-AIv1QcsSnj7e9pFir6cJ6vIncTqxfqeFF3Lzh8SuuBljueYzEAtByuB6zMaD27BL0xhMEqsZ9s5eHuCONydjBw==
dependencies:
tsutils "^2.13.1"
tslint@^5.12.1:
version "5.12.1"
resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.12.1.tgz#8cec9d454cf8a1de9b0a26d7bdbad6de362e52c1"
integrity sha512-sfodBHOucFg6egff8d1BvuofoOQ/nOeYNfbp7LDlKBcLNrL3lmS5zoiDGyOMdT7YsEXAwWpTdAHwOGOc8eRZAw==
dependencies:
babel-code-frame "^6.22.0"
builtin-modules "^1.1.1"
chalk "^2.3.0"
commander "^2.12.1"
diff "^3.2.0"
glob "^7.1.1"
js-yaml "^3.7.0"
minimatch "^3.0.4"
resolve "^1.3.2"
semver "^5.3.0"
tslib "^1.8.0"
tsutils "^2.27.2"
tsutils@^2.13.1, tsutils@^2.27.2:
version "2.29.0"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99"
integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==
dependencies:
tslib "^1.8.1"
tsutils@^3.17.1: tsutils@^3.17.1:
version "3.17.1" version "3.17.1"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759"

Loading…
Cancel
Save