1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-03-29 21:21:15 +02:00

Chore: Apply eslint no-unused-vars eslint config and add TypeScript config

This commit is contained in:
Laurent Cozic 2019-09-12 22:16:42 +00:00
parent 0b9e007b46
commit 15a42a3729
90 changed files with 339 additions and 187 deletions
.eslintignore.eslintrc.js
CliClient
Clipper/joplin-webclipper
ElectronClient/app
ReactNativeClient
Tools
joplin.code-workspacepackage-lock.jsonpackage.json

@ -39,3 +39,9 @@ ReactNativeClient/node_modules
readme/
Tools/node_modules
Tools/PortableAppsLauncher
Server/.git/
Server/.github/
Server/docs/
Server/dist/
Server/bin/
Server/node_modules/

@ -4,6 +4,7 @@ module.exports = {
'es6': true,
'node': true,
},
"parser": "@typescript-eslint/parser",
'extends': ['eslint:recommended'],
'globals': {
'Atomics': 'readonly',
@ -36,7 +37,8 @@ module.exports = {
"react/jsx-uses-vars": "error",
// Ignore all unused function arguments, because in some
// case they are kept to indicate the function signature.
"no-unused-vars": ["error", { "argsIgnorePattern": ".*" }],
//"no-unused-vars": ["error", { "argsIgnorePattern": ".*" }],
"@typescript-eslint/no-unused-vars": ["error"],
"no-constant-condition": 0,
"no-prototype-builtins": 0,
"space-in-parens": ["error", "never"],
@ -49,5 +51,6 @@ module.exports = {
},
"plugins": [
"react",
"@typescript-eslint",
],
};

13
CliClient/.eslintrc.js Normal file

@ -0,0 +1,13 @@
module.exports = {
"overrides": [
{
"files": ["tests/**/*.js"],
'rules': {
// Ignore all unused function arguments, because in some
// case they are kept to indicate the function signature.
"no-unused-vars": ["error", { "argsIgnorePattern": ".*" }],
"@typescript-eslint/no-unused-vars": 0,
}
},
],
};

@ -695,7 +695,7 @@ class AppGui {
term.grabInput();
term.on('key', async (name, matches, data) => {
term.on('key', async (name) => {
// -------------------------------------------------------------------------
// Handle special shortcuts
// -------------------------------------------------------------------------

@ -125,7 +125,7 @@ class Application extends BaseApplication {
if (this.store()) {
return this.store().dispatch(action);
} else {
return action => {};
return () => {};
}
});
@ -278,16 +278,16 @@ class Application extends BaseApplication {
stdout: text => {
console.info(text);
},
fullScreen: (b = true) => {},
fullScreen: () => {},
exit: () => {},
showModalOverlay: text => {},
showModalOverlay: () => {},
hideModalOverlay: () => {},
stdoutMaxWidth: () => {
return 100;
},
forceRender: () => {},
termSaveState: () => {},
termRestoreState: state => {},
termRestoreState: () => {},
};
}

@ -19,7 +19,7 @@ class BaseCommand {
throw new Error('Description not defined');
}
async action(args) {
async action() {
throw new Error('Action not defined');
}

@ -39,7 +39,7 @@ function createClient(id) {
const client = createClient(1);
function execCommand(client, command, options = {}) {
function execCommand(client, command) {
let exePath = 'node ' + joplinAppPath;
let cmd = exePath + ' --update-geolocation-disabled --env dev --profile ' + client.profileDir + ' ' + command;
logger.info(client.id + ': ' + command);
@ -212,7 +212,7 @@ testUnits.testMv = async () => {
assertEquals(4, notes2.length);
};
async function main(argv) {
async function main() {
await fs.remove(baseDir);
logger.info(await execCommand(client, 'version'));

@ -5,7 +5,7 @@ const stringPadding = require('string-padding');
const cliUtils = {};
cliUtils.printArray = function(logFunction, rows, headers = null) {
cliUtils.printArray = function(logFunction, rows) {
if (!rows.length) return '';
const ALIGN_LEFT = 0;
@ -167,7 +167,7 @@ cliUtils.promptConfirm = function(message, answers = null) {
message += ' (' + answers.join('/') + ')';
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
rl.question(message + ' ', answer => {
const ok = !answer || answer.toLowerCase() == answers[0].toLowerCase();
rl.close();
@ -179,6 +179,7 @@ cliUtils.promptConfirm = function(message, answers = null) {
// Note: initialText is there to have the same signature as statusBar.prompt() so that
// it can be a drop-in replacement, however initialText is not used (and cannot be
// with readline.question?).
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
cliUtils.prompt = function(initialText = '', promptString = ':', options = null) {
if (!options) options = {};
@ -198,7 +199,7 @@ cliUtils.prompt = function(initialText = '', promptString = ':', options = null)
terminal: true,
});
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
mutableStdout.muted = false;
rl.question(promptString, answer => {

@ -31,7 +31,7 @@ class Command extends BaseCommand {
return markdownUtils.createMarkdownTable(headers, tableFields);
}
async action(args) {
async action() {
const models = [
{
type: BaseModel.TYPE_NOTE,

@ -16,7 +16,7 @@ class Command extends BaseCommand {
return true;
}
async action(args) {
async action() {
let items = [];
let folders = await Folder.all();
for (let i = 0; i < folders.length; i++) {

@ -15,7 +15,7 @@ class Command extends BaseCommand {
return ['gui'];
}
async action(args) {
async action() {
await app().exit();
}
}

@ -17,7 +17,7 @@ class Command extends BaseCommand {
return true;
}
async action(args) {
async action() {
const service = new ReportService();
const csv = await service.basicItemList({ format: 'csv' });
const filePath = Setting.value('profileDir') + '/syncReport-' + new Date().getTime() + '.csv';

@ -26,7 +26,7 @@ class Command extends BaseCommand {
warn: stdoutFn,
error: stdoutFn,
}});
ClipperServer.instance().setDispatch(action => {});
ClipperServer.instance().setDispatch(() => {});
ClipperServer.instance().setLogger(clipperLogger);
const pidPath = Setting.value('profileDir') + '/clipper-pid.txt';

@ -13,7 +13,7 @@ class Command extends BaseCommand {
return _('Displays summary about the notes and notebooks.');
}
async action(args) {
async action() {
let service = new ReportService();
let report = await service.status(Setting.value('sync.target'));

@ -11,7 +11,7 @@ class Command extends BaseCommand {
return _('Displays version information');
}
async action(args) {
async action() {
const p = require('./package.json');
this.stdout(_('%s %s (%s)', p.name, p.version, Setting.value('env')));
}

@ -2312,7 +2312,7 @@ async function compareClientItems(clientItems) {
}
}
async function main(argv) {
async function main() {
await fs.remove(syncDir);
let clients = await createClients();

@ -24,7 +24,7 @@ async function browserCaptureVisibleTabs(windowId) {
const options = { format: 'jpeg' };
if (browserSupportsPromises_) return browser_.tabs.captureVisibleTab(windowId, options);
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
browser_.tabs.captureVisibleTab(windowId, options, (image) => {
resolve(image);
});
@ -34,14 +34,14 @@ async function browserCaptureVisibleTabs(windowId) {
async function browserGetZoom(tabId) {
if (browserSupportsPromises_) return browser_.tabs.getZoom(tabId);
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
browser_.tabs.getZoom(tabId, (zoom) => {
resolve(zoom);
});
});
}
browser_.runtime.onInstalled.addListener(function(details) {
browser_.runtime.onInstalled.addListener(function() {
if (window.joplinEnv() === 'dev') {
browser_.browserAction.setIcon({
path: 'icons/32-dev.png',

@ -1,4 +1,4 @@
/* eslint-disable no-unused-vars */
/* eslint-disable no-unused-vars, @typescript-eslint/no-unused-vars */
// Add here all the external scripts that the content script might need
// and run browserify on it to create vendor.bundle.js

@ -155,7 +155,7 @@ class AppComponent extends Component {
this.onClearTagButtonClick = this.onClearTagButtonClick.bind(this);
}
onAddTagClick(event) {
onAddTagClick() {
const newTags = this.state.selectedTags.slice();
newTags.push('');
this.setState({ selectedTags: newTags });

@ -71,7 +71,7 @@ class Bridge {
const bgp = browser.extension.getBackgroundPage();
if (bgp) return bgp;
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
browser.runtime.getBackgroundPage((bgp) => {
resolve(bgp);
});
@ -204,7 +204,7 @@ class Bridge {
async tabsQuery(options) {
if (this.browserSupportsPromises_) return this.browser().tabs.query(options);
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
this.browser().tabs.query(options, (tabs) => {
resolve(tabs);
});
@ -214,7 +214,7 @@ class Bridge {
async tabsSendMessage(tabId, command) {
if (this.browserSupportsPromises_) return this.browser().tabs.sendMessage(tabId, command);
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
this.browser().tabs.sendMessage(tabId, command, (result) => {
resolve(result);
});
@ -224,7 +224,7 @@ class Bridge {
async tabsCreate(options) {
if (this.browserSupportsPromises_) return this.browser().tabs.create(options);
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
this.browser().tabs.create(options, () => {
resolve();
});
@ -238,7 +238,7 @@ class Bridge {
async storageSet(keys) {
if (this.browserSupportsPromises_) return this.browser().storage.local.set(keys);
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
this.browser().storage.local.set(keys, () => {
resolve();
});
@ -254,7 +254,7 @@ class Bridge {
return defaultValue;
}
} else {
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
this.browser().storage.local.get(keys, (result) => {
resolve(result);
});

@ -115,7 +115,7 @@ class ElectronAppWrapper {
async waitForElectronAppReady() {
if (this.electronApp().isReady()) return Promise.resolve();
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
const iid = setInterval(() => {
if (this.electronApp().isReady()) {
clearInterval(iid);
@ -202,7 +202,7 @@ class ElectronAppWrapper {
}
// Someone tried to open a second instance - focus our window instead
this.electronApp_.on('second-instance', (event, commandLine, workingDirectory) => {
this.electronApp_.on('second-instance', () => {
const win = this.window();
if (!win) return;
if (win.isMinimized()) win.restore();

@ -4,7 +4,7 @@ const execCommand = function(command) {
console.info('Running: ' + command);
return new Promise((resolve, reject) => {
exec(command, (error, stdout, stderr) => {
exec(command, (error, stdout) => {
if (error) {
if (error.signal == 'SIGTERM') {
resolve('Process was killed');

@ -238,7 +238,7 @@ class ConfigScreenComponent extends React.Component {
</div>
);
} else if (md.type === Setting.TYPE_BOOL) {
const onCheckboxClick = event => {
const onCheckboxClick = () => {
updateSettingValue(key, !value);
};

@ -32,12 +32,12 @@ class HeaderComponent extends React.Component {
}, 500);
};
this.search_onClear = event => {
this.search_onClear = () => {
this.resetSearch();
if (this.searchElement_) this.searchElement_.focus();
};
this.search_onFocus = event => {
this.search_onFocus = () => {
if (this.hideSearchUsageLinkIID_) {
clearTimeout(this.hideSearchUsageLinkIID_);
this.hideSearchUsageLinkIID_ = null;
@ -46,7 +46,7 @@ class HeaderComponent extends React.Component {
this.setState({ showSearchUsageLink: true });
};
this.search_onBlur = event => {
this.search_onBlur = () => {
if (this.hideSearchUsageLinkIID_) return;
this.hideSearchUsageLinkIID_ = setTimeout(() => {
@ -66,7 +66,7 @@ class HeaderComponent extends React.Component {
triggerOnQuery('');
};
this.searchUsageLink_click = event => {
this.searchUsageLink_click = () => {
bridge().openExternal('https://joplinapp.org/#searching');
};
}

@ -271,7 +271,7 @@ class NoteListComponent extends React.Component {
}
}
componentDidUpdate(prevProps, prevState, snapshot) {
componentDidUpdate(prevProps) {
if (prevProps.windowCommand !== this.props.windowCommand) {
this.doCommand(this.props.windowCommand);
}

@ -192,7 +192,7 @@ class NotePropertiesDialog extends React.Component {
async saveProperty() {
if (!this.state.editedKey) return;
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
const newFormNote = Object.assign({}, this.state.formNote);
if (this.state.editedKey.indexOf('_time') >= 0) {
@ -216,7 +216,7 @@ class NotePropertiesDialog extends React.Component {
}
async cancelProperty() {
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
this.okButton.current.focus();
this.setState(
{

@ -88,15 +88,15 @@ class NoteSearchBarComponent extends React.Component {
}
}
previousButton_click(event) {
previousButton_click() {
if (this.props.onPrevious) this.props.onPrevious();
}
nextButton_click(event) {
nextButton_click() {
if (this.props.onNext) this.props.onNext();
}
closeButton_click(event) {
closeButton_click() {
if (this.props.onClose) this.props.onClose();
}

@ -151,7 +151,7 @@ class NoteTextComponent extends React.Component {
this.setState({ lastKeys: lastKeys });
};
this.onEditorContextMenu_ = event => {
this.onEditorContextMenu_ = () => {
const menu = new Menu();
const selectedText = this.selectedText();
@ -244,7 +244,7 @@ class NoteTextComponent extends React.Component {
updateSelectionRange();
};
this.aceEditor_focus = event => {
this.aceEditor_focus = () => {
updateSelectionRange();
};
@ -1486,7 +1486,7 @@ class NoteTextComponent extends React.Component {
this.wrapSelectionWithStrings('[', '](' + url + ')');
}
itemContextMenu(event) {
itemContextMenu() {
const note = this.state.note;
if (!note) return;
@ -2016,7 +2016,7 @@ class NoteTextComponent extends React.Component {
showGutter={false}
name="note-editor"
wrapEnabled={true}
onScroll={event => {
onScroll={() => {
this.editor_scroll();
}}
ref={elem => {

@ -44,7 +44,7 @@ class VerticalResizer extends React.PureComponent {
if (this.props.onDragStart) this.props.onDragStart({});
}
onDrag(event) {
onDrag() {
// If we got a drag event with no buttons pressed, it's the last drag event
// that we should ignore, because it's sometimes use to put the dragged element
// back to its original position (if there was no valid drop target), which we don't want.
@ -67,7 +67,7 @@ class VerticalResizer extends React.PureComponent {
);
}
onDragEnd(event) {
onDragEnd() {
document.removeEventListener('dragover', this.document_onDragOver);
}

@ -15,7 +15,7 @@ const itemHeight = 60;
class GotoAnything {
onTrigger(event) {
onTrigger() {
this.dispatch({
type: 'PLUGIN_DIALOG_SET',
open: true,
@ -106,7 +106,7 @@ class Dialog extends React.PureComponent {
}
}
helpButton_onClick(event) {
helpButton_onClick() {
this.setState({ showHelp: !this.state.showHelp });
}

@ -285,7 +285,7 @@ class BaseApplication {
}
}
async decryptionWorker_resourceMetadataButNotBlobDecrypted(event) {
async decryptionWorker_resourceMetadataButNotBlobDecrypted() {
this.scheduleAutoAddResources();
}
@ -575,7 +575,7 @@ class BaseApplication {
this.logger_.setLevel(initArgs.logLevel);
reg.setLogger(this.logger_);
reg.dispatch = o => {};
reg.dispatch = () => {};
this.dbLogger_.addTarget('file', { path: profileDir + '/log-database.txt' });
this.dbLogger_.setLevel(initArgs.logLevel);

@ -512,9 +512,8 @@ class BaseModel {
return output;
}
static delete(id, options = null) {
static delete(id) {
if (!id) throw new Error('Cannot delete object without an ID');
options = this.modOptions(options);
return this.db().exec('DELETE FROM ' + this.tableName() + ' WHERE id = ?', [id]);
}
@ -544,7 +543,7 @@ for (let i = 0; i < BaseModel.typeEnum_.length; i++) {
}
BaseModel.db_ = null;
BaseModel.dispatch = function(o) {};
BaseModel.dispatch = function() {};
BaseModel.saveMutexes_ = {};
module.exports = BaseModel;

@ -122,6 +122,6 @@ class BaseSyncTarget {
}
}
BaseSyncTarget.dispatch = action => {};
BaseSyncTarget.dispatch = () => {};
module.exports = BaseSyncTarget;

@ -79,7 +79,7 @@ class WebDavApi {
attrValueProcessors: [attrValueProcessor],
};
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
parseXmlString(xml, options, (error, result) => {
if (error) {
resolve(null); // Error handled by caller which will display the XML text (or plain text) if null is returned from this function

@ -63,7 +63,7 @@ class NoteTagsDialogComponent extends React.Component {
);
};
this.tagKeyExtractor = (tag, index) => tag.id;
this.tagKeyExtractor = (tag) => tag.id;
this.okButton_press = async () => {
this.setState({ savingTags: true });

@ -21,7 +21,7 @@ import { PermissionsAndroid } from 'react-native';
import Slider from '@react-native-community/slider';
class ConfigScreenComponent extends BaseScreenComponent {
static navigationOptions(options) {
static navigationOptions() {
return { header: null };
}
@ -324,7 +324,7 @@ class ConfigScreenComponent extends BaseScreenComponent {
color: theme.color,
fontSize: theme.fontSize,
}}
onValueChange={(itemValue, itemIndex) => {
onValueChange={(itemValue) => {
updateSettingValue(key, itemValue);
}}
/>

@ -13,7 +13,7 @@ const { dialogs } = require('lib/dialogs.js');
const DialogBox = require('react-native-dialogbox').default;
class EncryptionConfigScreenComponent extends BaseScreenComponent {
static navigationOptions(options) {
static navigationOptions() {
return { header: null };
}

@ -11,7 +11,7 @@ const { themeStyle } = require('lib/components/global-style.js');
const { _ } = require('lib/locale.js');
class FolderScreenComponent extends BaseScreenComponent {
static navigationOptions(options) {
static navigationOptions() {
return { header: null };
}
@ -67,7 +67,7 @@ class FolderScreenComponent extends BaseScreenComponent {
}
folderComponent_change(propName, propValue) {
this.setState((prevState, props) => {
this.setState((prevState) => {
let folder = Object.assign({}, prevState.folder);
folder[propName] = propValue;
return { folder: folder };

@ -11,7 +11,7 @@ const { BaseScreenComponent } = require('lib/components/base-screen.js');
const { _ } = require('lib/locale.js');
class LogScreenComponent extends BaseScreenComponent {
static navigationOptions(options) {
static navigationOptions() {
return { header: null };
}

@ -41,7 +41,7 @@ const urlUtils = require('lib/urlUtils');
import FileViewer from 'react-native-file-viewer';
class NoteScreenComponent extends BaseScreenComponent {
static navigationOptions(options) {
static navigationOptions() {
return { header: null };
}
@ -358,7 +358,7 @@ class NoteScreenComponent extends BaseScreenComponent {
}
async pickDocument() {
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
DocumentPicker.show({ filetype: [DocumentPickerUtil.allFiles()] }, (error, res) => {
if (error) {
// Also returns an error if the user doesn't pick a file
@ -388,7 +388,7 @@ class NoteScreenComponent extends BaseScreenComponent {
}
showImagePicker(options) {
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
ImagePicker.launchImageLibrary(options, response => {
resolve(response);
});
@ -750,7 +750,7 @@ class NoteScreenComponent extends BaseScreenComponent {
if (fieldToFocus === 'body') this.refs.noteBodyTextField.focus();
}
async folderPickerOptions_valueChanged(itemValue, itemIndex) {
async folderPickerOptions_valueChanged(itemValue) {
const note = this.state.note;
if (!note.id) {

@ -17,7 +17,7 @@ const DialogBox = require('react-native-dialogbox').default;
const { BaseScreenComponent } = require('lib/components/base-screen.js');
class NotesScreenComponent extends BaseScreenComponent {
static navigationOptions(options) {
static navigationOptions() {
return { header: null };
}

@ -11,7 +11,7 @@ const { BaseScreenComponent } = require('lib/components/base-screen.js');
const parseUri = require('lib/parseUri');
class OneDriveLoginScreenComponent extends BaseScreenComponent {
static navigationOptions(options) {
static navigationOptions() {
return { header: null };
}
@ -116,7 +116,7 @@ class OneDriveLoginScreenComponent extends BaseScreenComponent {
}
}
const OneDriveLoginScreen = connect(state => {
const OneDriveLoginScreen = connect(() => {
return {};
})(OneDriveLoginScreenComponent);

@ -13,7 +13,7 @@ const SearchEngineUtils = require('lib/services/SearchEngineUtils');
const DialogBox = require('react-native-dialogbox').default;
class SearchScreenComponent extends BaseScreenComponent {
static navigationOptions(options) {
static navigationOptions() {
return { header: null };
}
@ -185,7 +185,7 @@ class SearchScreenComponent extends BaseScreenComponent {
</TouchableHighlight>
</View>
<FlatList data={this.state.notes} keyExtractor={(item, index) => item.id} renderItem={event => <NoteItem note={event.item} />} />
<FlatList data={this.state.notes} keyExtractor={(item) => item.id} renderItem={event => <NoteItem note={event.item} />} />
</View>
<DialogBox
ref={dialogbox => {

@ -17,7 +17,7 @@ const styles = StyleSheet.create({
});
class StatusScreenComponent extends BaseScreenComponent {
static navigationOptions(options) {
static navigationOptions() {
return { header: null };
}

@ -9,7 +9,7 @@ const { _ } = require('lib/locale.js');
const { BaseScreenComponent } = require('lib/components/base-screen.js');
class TagsScreenComponent extends BaseScreenComponent {
static navigationOptions(options) {
static navigationOptions() {
return { header: null };
}
@ -76,7 +76,7 @@ class TagsScreenComponent extends BaseScreenComponent {
);
}
tagList_keyExtractor(item, index) {
tagList_keyExtractor(item) {
return item.id;
}

@ -23,10 +23,6 @@ class DatabaseDriverNode {
return output;
}
setDebugMode(v) {
// ??
}
selectOne(sql, params = null) {
if (!params) params = {};
return new Promise((resolve, reject) => {

@ -21,14 +21,10 @@ class DatabaseDriverReactNative {
});
}
sqliteErrorToJsError(error, sql = null, params = null) {
sqliteErrorToJsError(error) {
return error;
}
setDebugMode(v) {
//SQLite.DEBUG(v);
}
selectOne(sql, params = null) {
return new Promise((resolve, reject) => {
this.db_.executeSql(

@ -11,7 +11,7 @@ dialogs.confirm = (parentComponent, message) => {
if (!parentComponent) throw new Error('parentComponent is required');
if (!('dialogbox' in parentComponent)) throw new Error('A "dialogbox" component must be defined on the parent component!');
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
Keyboard.dismiss();
parentComponent.dialogbox.confirm({
@ -39,7 +39,7 @@ dialogs.pop = (parentComponent, message, buttons, options = null) => {
if (!options) options = {};
if (!('buttonFlow' in options)) options.buttonFlow = 'auto';
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
Keyboard.dismiss();
let btns = [];

@ -61,7 +61,7 @@ class FileApiDriverDropbox {
return output;
}
async setTimestamp(path, timestampMs) {
async setTimestamp() {
throw new Error('Not implemented'); // Not needed anymore
}
@ -97,7 +97,7 @@ class FileApiDriverDropbox {
}
}
async list(path, options) {
async list(path) {
let response = await this.api().exec('POST', 'files/list_folder', {
path: this.makePath_(path),
});
@ -200,7 +200,7 @@ class FileApiDriverDropbox {
}
}
async move(oldPath, newPath) {
async move() {
throw new Error('Not supported');
}

@ -77,7 +77,7 @@ class FileApiDriverLocal {
}
}
async list(path, options) {
async list(path) {
try {
const stats = await this.fsDriver().readDirStats(path);
const output = this.metadataFromStats_(stats);

@ -54,7 +54,7 @@ class FileApiDriverMemory {
item.updated_time = timestampMs;
}
async list(path, options) {
async list(path) {
let output = [];
for (let i = 0; i < this.items_.length; i++) {

@ -151,7 +151,7 @@ class FileApiDriverOneDrive {
return this.api_.exec('DELETE', this.makePath_(path));
}
async move(oldPath, newPath) {
async move() {
// Cannot work in an atomic way because if newPath already exist, the OneDrive API throw an error
// "An item with the same name already exists under the parent". Some posts suggest to use
// @name.conflictBehavior [0]but that doesn't seem to work. So until Microsoft fixes this

@ -65,7 +65,7 @@ class FileApiDriverWebDav {
};
}
async setTimestamp(path, timestampMs) {
async setTimestamp() {
throw new Error('Not implemented'); // Not needed anymore
}
@ -111,7 +111,7 @@ class FileApiDriverWebDav {
return output;
}
async list(path, options) {
async list(path) {
// const relativeBaseUrl = this.api().relativeBaseUrl();
// function parsePropFindXml(xmlString) {

@ -107,6 +107,7 @@ class FileApi {
}
// DRIVER MUST RETURN PATHS RELATIVE TO `path`
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
async list(path = '', options = null) {
if (!options) options = {};
if (!('includeHidden' in options)) options.includeHidden = false;

@ -1,8 +1,8 @@
class FsDriverDummy {
constructor() {}
appendFileSync(path, string) {}
writeBinaryFile(path, content) {}
readFile(path) {}
appendFileSync() {}
writeBinaryFile() {}
readFile() {}
}
module.exports = { FsDriverDummy };

@ -2,7 +2,7 @@ const RNFS = require('react-native-fs');
const FsDriverBase = require('lib/fs-driver-base');
class FsDriverRN extends FsDriverBase {
appendFileSync(path, string) {
appendFileSync() {
throw new Error('Not implemented');
}
@ -19,7 +19,7 @@ class FsDriverRN extends FsDriverBase {
return await this.unlink(path);
}
writeBinaryFile(path, content) {
writeBinaryFile() {
throw new Error('Not implemented');
}
@ -81,7 +81,7 @@ class FsDriverRN extends FsDriverBase {
// arguments but the function returns `false` and the timestamp is not set.
// Current setTimestamp is not really used so keep it that way, but careful if it
// becomes needed.
async setTimestamp(path, timestampDate) {
async setTimestamp() {
// return RNFS.touch(path, timestampDate, timestampDate);
}
@ -98,7 +98,7 @@ class FsDriverRN extends FsDriverBase {
};
}
close(handle) {
close() {
return null;
}

@ -382,7 +382,7 @@ function attributeToLowerCase(node) {
return output;
}
function isSpanWithStyle(attributes, state) {
function isSpanWithStyle(attributes) {
if (attributes != undefined) {
if ('style' in attributes) {
return true;
@ -417,7 +417,7 @@ function enexXmlToMdArray(stream, resources) {
}
};
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
let state = {
inCode: [],
inPre: false,
@ -439,7 +439,6 @@ function enexXmlToMdArray(stream, resources) {
saxStream.on('error', function(e) {
console.warn(e);
//reject(e);
});
const unwrapInnerText = text => {
@ -901,7 +900,7 @@ function enexXmlToMdArray(stream, resources) {
}
});
saxStream.on('attribute', function(attr) {});
saxStream.on('attribute', function() {});
saxStream.on('end', function() {
resolve({

@ -165,8 +165,8 @@ async function saveNoteToStorage(note, fuzzyMatching = false) {
function importEnex(parentFolderId, filePath, importOptions = null) {
if (!importOptions) importOptions = {};
if (!('fuzzyMatching' in importOptions)) importOptions.fuzzyMatching = false;
if (!('onProgress' in importOptions)) importOptions.onProgress = function(state) {};
if (!('onError' in importOptions)) importOptions.onError = function(error) {};
if (!('onProgress' in importOptions)) importOptions.onProgress = function() {};
if (!('onError' in importOptions)) importOptions.onError = function() {};
return new Promise((resolve, reject) => {
let progressState = {

@ -199,7 +199,7 @@ class JoplinDatabase extends Database {
await this.transactionExecBatch(queries);
}
createDefaultRow(tableName) {
createDefaultRow() {
const row = {};
const fields = this.tableFields('resource_local_states');
for (let i = 0; i < fields.length; i++) {

@ -36,7 +36,7 @@ class ItemChange extends BaseModel {
// Because item changes are recorded in the background, this function
// can be used for synchronous code, in particular when unit testing.
static async waitForAllSaved() {
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
const iid = setInterval(() => {
if (!ItemChange.saveCalls_.length) {
clearInterval(iid);

@ -816,7 +816,7 @@ class Setting extends BaseModel {
return name;
}
static sectionNameToIcon(name, platform) {
static sectionNameToIcon(name) {
if (name === 'general') return 'fa-sliders';
if (name === 'sync') return 'fa-refresh';
if (name === 'appearance') return 'fa-pencil';

@ -1,5 +1,5 @@
function promiseChain(chain, defaultValue = null) {
let output = new Promise((resolve, reject) => {
let output = new Promise((resolve) => {
resolve(defaultValue);
});
for (let i = 0; i < chain.length; i++) {

@ -53,7 +53,7 @@ reg.scheduleSync = async (delay = null, syncOptions = null) => {
if (syncOptions === null) syncOptions = {};
let promiseResolve = null;
const promise = new Promise((resolve, reject) => {
const promise = new Promise((resolve) => {
promiseResolve = resolve;
});

@ -1,4 +1,4 @@
function installRule(markdownIt, mdOptions, ruleOptions) {
function installRule(markdownIt) {
const defaultRender =
markdownIt.renderer.rules.code_inline ||
function(tokens, idx, options, env, self) {

@ -194,7 +194,7 @@ function math_block(state, start, end, silent) {
let assetsLoaded_ = false;
let cache_ = {};
module.exports = function(context, ruleOptions) {
module.exports = function(context) {
// Keep macros that persist across Katex blocks to allow defining a macro
// in one block and re-using it later in other blocks.
// https://github.com/laurent22/joplin/issues/1105

@ -4,7 +4,7 @@ const utils = require('../../utils');
const urlUtils = require('lib/urlUtils.js');
function installRule(markdownIt, mdOptions, ruleOptions) {
markdownIt.renderer.rules.link_open = function(tokens, idx, options, env, self) {
markdownIt.renderer.rules.link_open = function(tokens, idx) {
const token = tokens[idx];
let href = utils.getAttr(token.attrs, 'href');
const resourceHrefInfo = urlUtils.parseResourceUrl(href);

@ -23,7 +23,7 @@ class AlarmServiceDriver {
return true;
}
notificationIsSet(alarmId) {
notificationIsSet() {
throw new Error('Available only for non-persistent alarms');
}

@ -22,7 +22,7 @@ class AlarmServiceDriver {
return true;
}
notificationIsSet(alarmId) {
notificationIsSet() {
throw new Error('Available only for non-persistent alarms');
}
@ -35,7 +35,7 @@ class AlarmServiceDriver {
if (this.hasPermission_ !== null) return this.hasPermission_;
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
PushNotificationIOS.checkPermissions(async perm => {
const ok = await this.hasPermissions(perm);
this.hasPermission_ = ok;

@ -10,9 +10,7 @@ class DecryptionWorker {
this.state_ = 'idle';
this.logger_ = new Logger();
this.dispatch = action => {
//console.warn('DecryptionWorker.dispatch is not defined');
};
this.dispatch = () => {};
this.scheduleId_ = null;
this.eventEmitter_ = new EventEmitter();

@ -530,8 +530,7 @@ class EncryptionService {
if (identifier !== 'JED') throw new Error('Invalid header (missing identifier): ' + headerHexaBytes.substr(0, 64));
const template = this.headerTemplate(version);
// eslint-disable-next-line no-unused-vars
const size = parseInt(reader.read(6), 16); // Read the size and move the reader pointer forward
parseInt(reader.read(6), 16); // Read the size and move the reader pointer forward
let output = {};

@ -1,5 +0,0 @@
class EncryptionServiceDriverRN {
encryptFile(srcPath, destPath) {}
}
module.exports = EncryptionServiceDriverRN;

@ -12,7 +12,7 @@ const { bridge } = require('electron').remote.require('./bridge');
class ExternalEditWatcher {
constructor() {
this.logger_ = new Logger();
this.dispatch = action => {};
this.dispatch = () => {};
this.watcher_ = null;
this.eventEmitter_ = new EventEmitter();
this.skipNextChangeEvent_ = {};

@ -1,3 +1,5 @@
/* eslint @typescript-eslint/no-unused-vars: 0, no-unused-vars: ["error", { "argsIgnorePattern": ".*" }], */
class InteropService_Exporter_Base {
async init(destDir) {}
async processItem(ItemClass, item) {}

@ -12,7 +12,7 @@ class InteropService_Importer_Base {
this.options_ = options;
}
async exec(result) {}
async exec() {}
async temporaryDirectory_(createIt) {
const md5 = require('md5');

@ -11,7 +11,7 @@ class ResourceFetcher extends BaseService {
constructor(fileApi = null) {
super();
this.dispatch = action => {};
this.dispatch = () => {};
this.setFileApi(fileApi);
this.logger_ = new Logger();
@ -194,7 +194,7 @@ class ResourceFetcher extends BaseService {
}
async waitForAllFinished() {
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
const iid = setInterval(() => {
if (!this.updateReportIID_ && !this.scheduleQueueProcessIID_ && !this.addingResources_ && !this.queue_.length && !Object.getOwnPropertyNames(this.fetchingItems_).length) {
clearInterval(iid);

@ -10,7 +10,7 @@ const { sprintf } = require('sprintf-js');
class SearchEngine {
constructor() {
this.dispatch = action => {};
this.dispatch = () => {};
this.logger_ = new Logger();
this.db_ = null;
this.isIndexing_ = false;

@ -229,7 +229,7 @@ class Api {
throw new ErrorMethodNotAllowed();
}
async action_ping(request, id = null, link = null) {
async action_ping(request) {
if (request.method === 'GET') {
return 'JoplinClipperServer';
}
@ -552,7 +552,7 @@ class Api {
return output;
}
async downloadImage_(url, allowFileProtocolImages) {
async downloadImage_(url /*, allowFileProtocolImages */) {
const tempDir = Setting.value('tempDir');
const isDataUrl = url && url.toLowerCase().indexOf('data:') === 0;

@ -138,7 +138,7 @@ function shimInit() {
};
shim.waitForFrame = () => {
return new Promise(function(resolve, reject) {
return new Promise(function(resolve) {
requestAnimationFrame(function() {
resolve();
});

@ -1,3 +1,5 @@
/* eslint @typescript-eslint/no-unused-vars: 0, no-unused-vars: ["error", { "argsIgnorePattern": ".*" }], */
let shim = {};
shim.isNode = () => {

@ -158,7 +158,7 @@ class Synchronizer {
this.logSyncOperation('cancelling', null, null, '');
this.cancelling_ = true;
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
const iid = setInterval(() => {
if (this.state() == 'idle') {
clearInterval(iid);

@ -97,7 +97,7 @@ class Time {
}
msleep(ms) {
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, ms);

@ -79,7 +79,7 @@ const DecryptionWorker = require('lib/services/DecryptionWorker');
const EncryptionService = require('lib/services/EncryptionService');
const MigrationService = require('lib/services/MigrationService');
let storeDispatch = function(action) {};
let storeDispatch = function() {};
const logReducerAction = function(action) {
if (['SIDE_MENU_OPEN_PERCENT', 'SYNC_REPORT_UPDATE'].indexOf(action.type) >= 0) return;
@ -155,7 +155,7 @@ const generalMiddleware = store => next => async (action) => {
let navHistory = [];
function historyCanGoBackTo(route, nextRoute) {
function historyCanGoBackTo(route) {
if (route.routeName === 'Note') return false;
if (route.routeName === 'Folder') return false;

@ -16,7 +16,7 @@ async function copyJs(name, filePath) {
await fs.writeFile(outputPath, json);
}
async function main(argv) {
async function main() {
await fs.mkdirp(outputDir);
await copyJs('webviewLib', rnDir + '/lib/renderers/webviewLib.js');
}

@ -21,7 +21,7 @@ function wslToWinPath(wslPath) {
}
function increaseGradleVersionCode(content) {
const newContent = content.replace(/versionCode\s+(\d+)/, function(a, versionCode, c) {
const newContent = content.replace(/versionCode\s+(\d+)/, function(a, versionCode) {
const n = Number(versionCode);
if (isNaN(n) || !n) throw new Error('Invalid version code: ' + versionCode);
return 'versionCode ' + (n + 1);

@ -4,7 +4,7 @@ toolUtils.execCommand = function(command) {
const exec = require('child_process').exec;
return new Promise((resolve, reject) => {
exec(command, (error, stdout, stderr) => {
exec(command, (error, stdout) => {
if (error) {
if (error.signal == 'SIGTERM') {
resolve('Process was killed');
@ -71,7 +71,7 @@ toolUtils.fileExists = async function(filePath) {
const fs = require('fs-extra');
return new Promise((resolve, reject) => {
fs.stat(filePath, function(err, stat) {
fs.stat(filePath, function(err) {
if (err == null) {
resolve(true);
} else if(err.code == 'ENOENT') {
@ -124,7 +124,7 @@ toolUtils.githubRelease = async function(project, tagName, options = null) {
};
toolUtils.readline = question => {
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
const readline = require('readline');
const rl = readline.createInterface({

@ -66,7 +66,7 @@ function contributorTable(contributors) {
return lines.join('\n');
}
async function main(argv) {
async function main() {
let contributors = [];
let pageIndex = 0;
const doneNames = [];

@ -10,7 +10,7 @@ const url = 'https://api.github.com/repos/laurent22/joplin/releases/latest';
const readmePath = __dirname + '/../README.md';
async function msleep(ms) {
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, ms);

69
joplin.code-workspace Normal file

@ -0,0 +1,69 @@
{
"folders": [
{
"path": ".",
},
],
"settings": {
"files.exclude": {
"**/node_modules/": true,
"_mydocs/mdtest/": true,
"_vieux/": true,
"ElectronClient/app/fonts/": true,
"CliClient/app/lib/": true,
"CliClient/app/src/": true,
"CliClient/build/": true,
"CliClient/node_modules/": true,
"CliClient/tests-build/": true,
"CliClient/tests-build/lib/": true,
"CliClient/tests/fuzzing -*/": true,
"CliClient/tests/fuzzing/": true,
"CliClient/tests/src/": true,
"CliClient/tests/sync/": true,
"ElectronClient/dist/": true,
"ElectronClient/build/": true,
"ElectronClient/app/lib/": true,
"ElectronClient/app/locale/": true,
"node_modules/": true,
"ReactNativeClient/android/.gradle/": true,
"ReactNativeClient/android/.idea/": true,
"ReactNativeClient/android/app/build/": true,
"ReactNativeClient/android/build/": true,
"ReactNativeClient/android/local.properties/": true,
"ReactNativeClient/node_modules/": true,
"ElectronClient/app/gui/note-viewer/highlight/styles/": true,
"tests/logs/": true,
"ReactNativeClient/ios/build/": true,
"ElectronClient/app/dist/": true,
"_releases/": true,
"ReactNativeClient/lib/csstojs/": true,
"Clipper/joplin-webclipper/popup/build/": true,
"Clipper/joplin-webclipper/dist/": true,
"ReactNativeClient/lib/rnInjectedJs/": true,
"**/*.jar": true,
"**/*.map": true,
"**/*.po": true,
"**/*.po~": true,
"**/*.pot": true,
"**/CliClient/app/lib": true,
"**/CliClient/app/src": true,
"**/locales/*.json": true,
"**/log.txt": true,
"**/package-lock.json": true,
"**/ReactNativeClient/locales/*": true,
"**/src/log.txt": true,
"**/ElectronClient/app/gui/note-viewer/highlight/*.pack.js": true,
"**/ElectronClient/app/css/font-awesome.min.css": true,
"**/docs/*.html": true,
"**/docs/*.svg": true,
"**/ReactNativeClient/lib/mime-utils.js": true,
"**/_mydocs/EnexSamples/*.enex": true,
"**/*.min.css": true,
"**/*.min.js": true,
"**/*.bundle.js": true,
"**/yarn.lock": true,
"**/*.icns": true,
"**/*.base64": true,
}
},
}

137
package-lock.json generated

@ -59,6 +59,11 @@
"any-observable": "^0.3.0"
}
},
"@types/eslint-visitor-keys": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
"integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag=="
},
"@types/events": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
@ -76,6 +81,11 @@
"@types/node": "*"
}
},
"@types/json-schema": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.3.tgz",
"integrity": "sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A=="
},
"@types/minimatch": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
@ -94,6 +104,67 @@
"integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==",
"dev": true
},
"@typescript-eslint/eslint-plugin": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.2.0.tgz",
"integrity": "sha512-rOodtI+IvaO8USa6ValYOrdWm9eQBgqwsY+B0PPiB+aSiK6p6Z4l9jLn/jI3z3WM4mkABAhKIqvGIBl0AFRaLQ==",
"requires": {
"@typescript-eslint/experimental-utils": "2.2.0",
"eslint-utils": "^1.4.2",
"functional-red-black-tree": "^1.0.1",
"regexpp": "^2.0.1",
"tsutils": "^3.17.1"
},
"dependencies": {
"eslint-utils": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz",
"integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==",
"requires": {
"eslint-visitor-keys": "^1.0.0"
}
}
}
},
"@typescript-eslint/experimental-utils": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.2.0.tgz",
"integrity": "sha512-IMhbewFs27Frd/ICHBRfIcsUCK213B8MsEUqvKFK14SDPjPR5JF6jgOGPlroybFTrGWpMvN5tMZdXAf+xcmxsA==",
"requires": {
"@types/json-schema": "^7.0.3",
"@typescript-eslint/typescript-estree": "2.2.0",
"eslint-scope": "^5.0.0"
}
},
"@typescript-eslint/parser": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.2.0.tgz",
"integrity": "sha512-0mf893kj9L65O5sA7wP6EoYvTybefuRFavUNhT7w9kjhkdZodoViwVS+k3D+ZxKhvtL7xGtP/y/cNMJX9S8W4A==",
"requires": {
"@types/eslint-visitor-keys": "^1.0.0",
"@typescript-eslint/experimental-utils": "2.2.0",
"@typescript-eslint/typescript-estree": "2.2.0",
"eslint-visitor-keys": "^1.1.0"
},
"dependencies": {
"eslint-visitor-keys": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz",
"integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A=="
}
}
},
"@typescript-eslint/typescript-estree": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.2.0.tgz",
"integrity": "sha512-9/6x23A3HwWWRjEQbuR24on5XIfVmV96cDpGR9671eJv1ebFKHj2sGVVAwkAVXR2UNuhY1NeKS2QMv5P8kQb2Q==",
"requires": {
"glob": "^7.1.4",
"is-glob": "^4.0.1",
"lodash.unescape": "4.0.1",
"semver": "^6.3.0"
}
},
"acorn": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.1.tgz",
@ -179,14 +250,12 @@
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"dev": true
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -354,8 +423,7 @@
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"cosmiconfig": {
"version": "5.2.1",
@ -613,7 +681,6 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz",
"integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==",
"dev": true,
"requires": {
"esrecurse": "^4.1.0",
"estraverse": "^4.1.1"
@ -631,8 +698,7 @@
"eslint-visitor-keys": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
"integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==",
"dev": true
"integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ=="
},
"espree": {
"version": "6.0.0",
@ -664,7 +730,6 @@
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
"integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
"dev": true,
"requires": {
"estraverse": "^4.1.0"
}
@ -672,8 +737,7 @@
"estraverse": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
"integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
"dev": true
"integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM="
},
"esutils": {
"version": "2.0.2",
@ -805,8 +869,7 @@
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"function-bind": {
"version": "1.1.1",
@ -817,8 +880,7 @@
"functional-red-black-tree": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
"integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
"dev": true
"integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc="
},
"get-own-enumerable-property-symbols": {
"version": "3.0.0",
@ -839,7 +901,6 @@
"version": "7.1.4",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
"integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@ -1000,7 +1061,6 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"dev": true,
"requires": {
"once": "^1.3.0",
"wrappy": "1"
@ -1009,8 +1069,7 @@
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"inquirer": {
"version": "6.5.0",
@ -1069,8 +1128,7 @@
"is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
"dev": true
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
},
"is-fullwidth-code-point": {
"version": "2.0.0",
@ -1082,7 +1140,6 @@
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
"integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
"dev": true,
"requires": {
"is-extglob": "^2.1.1"
}
@ -1452,6 +1509,11 @@
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
"dev": true
},
"lodash.unescape": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz",
"integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw="
},
"log-symbols": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
@ -1513,7 +1575,6 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@ -1656,7 +1717,6 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"requires": {
"wrappy": "1"
}
@ -1760,8 +1820,7 @@
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
},
"path-is-inside": {
"version": "1.0.2",
@ -1885,8 +1944,7 @@
"regexpp": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz",
"integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==",
"dev": true
"integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw=="
},
"resolve": {
"version": "1.11.1",
@ -1967,8 +2025,7 @@
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
},
"semver-compare": {
"version": "1.0.0",
@ -2198,8 +2255,15 @@
"tslib": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
"integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==",
"dev": true
"integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ=="
},
"tsutils": {
"version": "3.17.1",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz",
"integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==",
"requires": {
"tslib": "^1.8.1"
}
},
"type-check": {
"version": "0.3.2",
@ -2216,6 +2280,12 @@
"integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
"dev": true
},
"typescript": {
"version": "3.6.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.3.tgz",
"integrity": "sha512-N7bceJL1CtRQ2RiG0AQME13ksR7DiuQh/QehubYcghzv20tnh+MQnQIuJddTmsbqYj+dztchykemz0zFzlvdQw==",
"dev": true
},
"uri-js": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
@ -2280,8 +2350,7 @@
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"write": {
"version": "1.0.3",

@ -25,7 +25,11 @@
"eslint": "^6.1.0",
"eslint-plugin-react": "^7.14.3",
"husky": "^3.0.2",
"lint-staged": "^9.2.1"
"lint-staged": "^9.2.1",
"typescript": "^3.6.3"
},
"dependencies": {}
"dependencies": {
"@typescript-eslint/eslint-plugin": "^2.2.0",
"@typescript-eslint/parser": "^2.2.0"
}
}