From 7a81f677b121ecc89559d2aeaec5c715f07d600c Mon Sep 17 00:00:00 2001 From: Andreas Gassmann Date: Wed, 18 Dec 2019 13:59:21 +0000 Subject: [PATCH] feat(eslint): replace tslint with eslint --- .eslintrc.js | 260 +++++ .prettierrc | 2 +- examples/example.ts | 6 + package-lock.json | 1297 +++++++++++++++++++++++ package.json | 11 +- src/client/Client.ts | 78 -- src/client/DappClient.ts | 28 +- src/client/MockWindow.ts | 37 +- src/client/Serializer.ts | 4 +- src/client/WalletCommunicationClient.ts | 300 +++--- src/client/interfaces.ts | 41 + src/client/storage/FileStorage.ts | 30 +- src/client/storage/LocalStorage.ts | 2 +- src/client/storage/Storage.ts | 2 +- src/client/storage/StorageProvider.ts | 28 +- src/client/utils/assert-never.ts | 8 +- src/client/utils/crypto.ts | 65 ++ src/client/utils/exposed-promise.ts | 24 +- tslint.json | 38 - 19 files changed, 1925 insertions(+), 336 deletions(-) create mode 100644 .eslintrc.js delete mode 100644 src/client/Client.ts create mode 100644 src/client/interfaces.ts create mode 100644 src/client/utils/crypto.ts delete mode 100644 tslint.json diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 000000000..4083b1434 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,260 @@ +module.exports = { + "env": { + "browser": true, + "es6": true, + "node": true + }, + "parser": "@typescript-eslint/parser", + "parserOptions": { + "project": "tsconfig.json", + "sourceType": "module" + }, + "plugins": [ + "@typescript-eslint", + "@typescript-eslint/tslint", + "prefer-arrow", + "import" + ], + "extends": [ + "plugin:@typescript-eslint/recommended", + "prettier", + "prettier/@typescript-eslint" + ], + "rules": { + "@typescript-eslint/adjacent-overload-signatures": "error", + "@typescript-eslint/array-type": "error", + "@typescript-eslint/await-thenable": "error", + "@typescript-eslint/ban-types": "error", + "@typescript-eslint/class-name-casing": "error", + "@typescript-eslint/consistent-type-assertions": "error", + "@typescript-eslint/consistent-type-definitions": "error", + "@typescript-eslint/explicit-member-accessibility": [ + "error", + { + "accessibility": "explicit", + overrides: { + constructors: 'no-public', + } + } + ], + "@typescript-eslint/indent": "off", + "@typescript-eslint/interface-name-prefix": "error", + "@typescript-eslint/member-delimiter-style": [ + "error", + { + "multiline": { + "delimiter": "none", + "requireLast": true + }, + "singleline": { + "delimiter": "semi", + "requireLast": false + } + } + ], + "@typescript-eslint/member-ordering": "error", + "@typescript-eslint/no-empty-function": "error", + "@typescript-eslint/no-empty-interface": "error", + "@typescript-eslint/no-explicit-any": "error", + "@typescript-eslint/no-extraneous-class": "off", + "@typescript-eslint/no-floating-promises": "error", + "@typescript-eslint/no-for-in-array": "error", + "@typescript-eslint/no-inferrable-types": "off", + "@typescript-eslint/no-misused-new": "error", + "@typescript-eslint/no-namespace": "error", + "@typescript-eslint/no-non-null-assertion": "error", + "no-param-reassign": "error", + "@typescript-eslint/no-parameter-properties": "off", + "@typescript-eslint/no-require-imports": "off", + "@typescript-eslint/no-this-alias": "error", + "@typescript-eslint/no-unnecessary-qualifier": "error", + "@typescript-eslint/no-unnecessary-type-arguments": "error", + "@typescript-eslint/no-unnecessary-type-assertion": "error", + "@typescript-eslint/no-use-before-define": "error", + "@typescript-eslint/no-var-requires": "error", + "@typescript-eslint/prefer-for-of": "off", + "@typescript-eslint/prefer-function-type": "error", + "@typescript-eslint/prefer-namespace-keyword": "error", + "@typescript-eslint/promise-function-async": "off", + "@typescript-eslint/quotes": "off", + "@typescript-eslint/restrict-plus-operands": "error", + "@typescript-eslint/semi": [ + "error", + "never" + ], + "@typescript-eslint/space-within-parens": [ + "off", + "never" + ], + "@typescript-eslint/strict-boolean-expressions": "off", + "@typescript-eslint/triple-slash-reference": "error", + "@typescript-eslint/type-annotation-spacing": "off", + "@typescript-eslint/unbound-method": "error", + "@typescript-eslint/unified-signatures": "error", + "arrow-body-style": ["error", "as-needed"], + "arrow-parens": [ + "off", + "as-needed" + ], + "@typescript-eslint/camelcase": "warn", + "capitalized-comments": "error", + "class-methods-use-this": "off", + "comma-dangle": "off", + "complexity": "error", + "constructor-super": "error", + "curly": "error", + "default-case": "error", + "dot-notation": "error", + "eol-last": "off", + "eqeqeq": [ + "error", + "smart" + ], + "guard-for-in": "error", + "id-blacklist": [ + "warn", "err", "e", "cb", "callback", "result", "res", + "any", + "Number", + "number", + "String", + "string", + "Boolean", + "boolean", + "Undefined" + ], + "id-match": "error", + "import/no-default-export": "error", + "import/no-deprecated": "error", + "import/no-extraneous-dependencies": [ + "error", + { + "devDependencies": false + } + ], + "import/no-internal-modules": "off", + "import/no-unassigned-import": "off", + "import/order": "error", + "linebreak-style": "off", + "max-classes-per-file": [ + "error", + 1 + ], + "max-len": "off", + "max-lines": [ + "error", + 400 + ], + "new-parens": "off", + "newline-per-chained-call": "off", + "no-bitwise": "error", + "no-caller": "error", + "no-cond-assign": "error", + "no-console": "warn", + "no-debugger": "error", + "no-duplicate-case": "error", + "no-duplicate-imports": "error", + "no-empty": "error", + "no-eval": "error", + "no-extra-semi": "off", + "no-fallthrough": "error", + "no-invalid-this": "error", + "no-irregular-whitespace": "off", + "no-magic-numbers": "off", + "no-multiple-empty-lines": "off", + "no-new-wrappers": "error", + "no-null/no-null": "off", + "no-redeclare": "error", + "no-return-await": "error", + "no-sequences": "error", + "no-shadow": [ + "error", + { + "hoist": "all" + } + ], + "no-sparse-arrays": "error", + "no-template-curly-in-string": "error", + "no-throw-literal": "error", + "no-trailing-spaces": "off", + "no-undef-init": "error", + "no-underscore-dangle": "error", + "no-unsafe-finally": "error", + "no-unused-expressions": "error", + "no-unused-labels": "error", + "no-var": "error", + "no-void": "error", + "object-shorthand": "error", + "one-var": [ + "error", + "never" + ], + "padding-line-between-statements": [ + "error", + { + "blankLine": "always", + "prev": "*", + "next": "return" + } + ], + "prefer-arrow/prefer-arrow-functions": "error", + "prefer-const": "error", + "prefer-object-spread": "off", + "@typescript-eslint/prefer-readonly": "error", + "prefer-template": "error", + "quote-props": "off", + "radix": "error", + "space-before-function-paren": "off", + "spaced-comment": "error", + "use-isnan": "error", + "valid-typeof": "off", + "yoda": "error", + "@typescript-eslint/tslint/config": [ + "error", + { + "rules": { + "ban": [ + true, + "fit", + "fdescribe", + "xit", + "xdescribe" + ], + "encoding": true, + "import-blacklist": [ + true, + "rxjs", + "rxjs/Rx", + "lodash" + ], + "jsdoc-format": true, + "match-default-export-name": true, + "no-boolean-literal-compare": true, + "no-dynamic-delete": true, + "no-inferred-empty-object-type": true, + "no-mergeable-namespace": true, + "no-reference-import": true, + "no-unnecessary-callback-wrapper": true, + "no-unused-variable": true, + "prefer-conditional-expression": true, + "prefer-method-signature": true, + "prefer-switch": true, + "prefer-while": true, + "return-undefined": true, + "switch-final-break": true, + "typedef": [ + false, + "call-signature", + "arrow-call-signature", + "parameter", + "arrow-parameter", + "property-declaration", + "variable-declaration", + "member-variable-declaration", + "object-destructuring", + "array-destructuring" + ] + } + } + ] + } +}; diff --git a/.prettierrc b/.prettierrc index 2ad4d93a5..4d182dec3 100644 --- a/.prettierrc +++ b/.prettierrc @@ -2,5 +2,5 @@ "trailingComma": "none", "singleQuote": true, "semi": false, - "printWidth": 140 + "printWidth": 100 } \ No newline at end of file diff --git a/examples/example.ts b/examples/example.ts index f4e8a6186..e59e34511 100644 --- a/examples/example.ts +++ b/examples/example.ts @@ -1,5 +1,11 @@ import { WalletCommunicationClient } from '../src/index' +import { getStorage} from '../src/client/storage/StorageProvider' + +console.log(getStorage().then(storage => { + console.log(storage) +})) + let QR: | { pubKey: string diff --git a/package-lock.json b/package-lock.json index 30db3ea27..91fe40a8c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -136,6 +136,18 @@ "@types/chai": "*" } }, + "@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==", + "dev": true + }, + "@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==", + "dev": true + }, "@types/libsodium-wrappers": { "version": "0.7.7", "resolved": "https://registry.npmjs.org/@types/libsodium-wrappers/-/libsodium-wrappers-0.7.7.tgz", @@ -154,6 +166,130 @@ "integrity": "sha512-FjsYUPzEJdGXjwKqSpE0/9QEh6kzhTAeObA54rn6j3rR4C/mzpI9L0KNfoeASSPMMdxIsoJuCLDWcM/rVjIsSA==", "dev": true }, + "@typescript-eslint/eslint-plugin": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.12.0.tgz", + "integrity": "sha512-1t4r9rpLuEwl3hgt90jY18wJHSyb0E3orVL3DaqwmpiSDHmHiSspVsvsFF78BJ/3NNG3qmeso836jpuBWYziAA==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "2.12.0", + "eslint-utils": "^1.4.3", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.0.0", + "tsutils": "^3.17.1" + }, + "dependencies": { + "tsutils": { + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", + "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + } + } + }, + "@typescript-eslint/eslint-plugin-tslint": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin-tslint/-/eslint-plugin-tslint-2.12.0.tgz", + "integrity": "sha512-KBdoDJdXDJbJbz6gAqFPVOke7rguDfX54gMqXrNOHqEJB1VJRfdRmFCWafOeaBSiCZw52vmm0Jh+Ga2EEeYrIw==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "2.12.0", + "lodash.memoize": "^4.1.2" + } + }, + "@typescript-eslint/experimental-utils": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.12.0.tgz", + "integrity": "sha512-jv4gYpw5N5BrWF3ntROvCuLe1IjRenLy5+U57J24NbPGwZFAjhnM45qpq0nDH1y/AZMb3Br25YiNVwyPbz6RkA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "2.12.0", + "eslint-scope": "^5.0.0" + } + }, + "@typescript-eslint/parser": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.12.0.tgz", + "integrity": "sha512-lPdkwpdzxEfjI8TyTzZqPatkrswLSVu4bqUgnB03fHSOwpC7KSerPgJRgIAf11UGNf7HKjJV6oaPZI4AghLU6g==", + "dev": true, + "requires": { + "@types/eslint-visitor-keys": "^1.0.0", + "@typescript-eslint/experimental-utils": "2.12.0", + "@typescript-eslint/typescript-estree": "2.12.0", + "eslint-visitor-keys": "^1.1.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.12.0.tgz", + "integrity": "sha512-rGehVfjHEn8Frh9UW02ZZIfJs6SIIxIu/K1bbci8rFfDE/1lQ8krIJy5OXOV3DVnNdDPtoiPOdEANkLMrwXbiQ==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash.unescape": "4.0.1", + "semver": "^6.3.0", + "tsutils": "^3.17.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "tsutils": { + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", + "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + } + } + }, + "acorn": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", + "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==", + "dev": true + }, + "acorn-jsx": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", + "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", + "dev": true + }, "ajv": { "version": "6.10.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", @@ -176,6 +312,15 @@ "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", "dev": true }, + "ansi-escapes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz", + "integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", @@ -221,6 +366,114 @@ "sprintf-js": "~1.0.2" } }, + "array-includes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.0.tgz", + "integrity": "sha512-ONOEQoKrvXPKk7Su92Co0YMqYO32FfqJTzkKU9u2UpIXyYZIzLSvpdg4AwvSw4mSUW0czu6inK+zby6Oj6gDjQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.0" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.0-next.1.tgz", + "integrity": "sha512-7MmGr03N7Rnuid6+wyhD9sHNE2n4tFSwExnU2lQl3lIo2ShXWGePY80zYaoMOmILWv57H0amMjZGHNzzGG70Rw==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.0", + "string.prototype.trimright": "^2.1.0" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + } + } + }, + "array.prototype.flat": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", + "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.0-next.1.tgz", + "integrity": "sha512-7MmGr03N7Rnuid6+wyhD9sHNE2n4tFSwExnU2lQl3lIo2ShXWGePY80zYaoMOmILWv57H0amMjZGHNzzGG70Rw==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.0", + "string.prototype.trimright": "^2.1.0" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + } + } + }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -240,6 +493,12 @@ "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -344,6 +603,12 @@ "write-file-atomic": "^2.4.2" } }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -400,12 +665,33 @@ } } }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", "dev": true }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, "cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", @@ -486,6 +772,12 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, "content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", @@ -573,6 +865,12 @@ "type-detect": "^4.0.0" } }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, "default-require-extensions": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", @@ -602,6 +900,15 @@ "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -667,12 +974,465 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, + "eslint": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.7.2.tgz", + "integrity": "sha512-qMlSWJaCSxDFr8fBPvJM9kJwbazrhNcBU3+DszDW1OlEwKBBRWsJc7NJFelvwQpanHCR14cOLD41x8Eqvo3Nng==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^1.4.3", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.1.2", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^7.0.0", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.3", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^6.1.2", + "strip-ansi": "^5.2.0", + "strip-json-comments": "^3.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "globals": { + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.3.0.tgz", + "integrity": "sha512-wAfjdLgFsPZsklLJvOBUBmzYE8/CwhEqSBEMRXA3qxIiNtyqvjYurAtIfDh6chlEPUfmTY3MnZh5Hfh4q0UlIw==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "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 + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "strip-json-comments": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "dev": true + } + } + }, + "eslint-config-prettier": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.7.0.tgz", + "integrity": "sha512-FamQVKM3jjUVwhG4hEMnbtsq7xOIDm+SY5iBPfR8gKsJoAB2IQnNF+bk1+8Fy44Nq7PPJaLvkRxILYdJWoguKQ==", + "dev": true, + "requires": { + "get-stdin": "^6.0.0" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", + "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-module-utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.5.0.tgz", + "integrity": "sha512-kCo8pZaNz2dsAW7nCUjuVoI11EBXXpIzfNxmaoLhXoRDOnqXLC4iSGVRdZPhOitfbdEfMEfKOiENaK6wDPZEGw==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + } + } + }, + "eslint-plugin-import": { + "version": "2.19.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.19.1.tgz", + "integrity": "sha512-x68131aKoCZlCae7rDXKSAQmbT5DQuManyXo2sK6fJJ0aK5CWAkv6A6HJZGgqC8IhjQxYPgo6/IY4Oz8AFsbBw==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "array.prototype.flat": "^1.2.1", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.4.1", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.0", + "read-pkg-up": "^2.0.0", + "resolve": "^1.12.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + } + } + }, + "eslint-plugin-no-null": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-no-null/-/eslint-plugin-no-null-1.0.2.tgz", + "integrity": "sha1-EjaoEjkTkKGHetQAfCbnRTQclR8=", + "dev": true + }, + "eslint-plugin-prefer-arrow": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/eslint-plugin-prefer-arrow/-/eslint-plugin-prefer-arrow-1.1.7.tgz", + "integrity": "sha512-epsA4g804mRovlOHSbeO1xxW7REGeUjULRME9MJTJDOVscNIA01AkR66TP4cmHDfD+w72EQ9cPhf37MbZiFI2w==", + "dev": true + }, + "eslint-scope": { + "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" + } + }, + "eslint-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "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==", + "dev": true + }, + "espree": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz", + "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==", + "dev": true, + "requires": { + "acorn": "^7.1.0", + "acorn-jsx": "^5.1.0", + "eslint-visitor-keys": "^1.1.0" + } + }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "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" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -684,6 +1444,17 @@ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -699,6 +1470,30 @@ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "figures": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.1.0.tgz", + "integrity": "sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, "find-cache-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", @@ -728,6 +1523,34 @@ "is-buffer": "~2.0.3" } }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "dependencies": { + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "flatted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "dev": true + }, "foreground-child": { "version": "1.5.6", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", @@ -765,6 +1588,12 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, + "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 + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -777,6 +1606,12 @@ "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true + }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -799,6 +1634,15 @@ "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -902,6 +1746,31 @@ "sshpk": "^1.7.0" } }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", + "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -923,6 +1792,86 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "inquirer": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.1.tgz", + "integrity": "sha512-V1FFQ3TIO15det8PijPLFR9M9baSlnRs9nL7zWu1MNVA2T9YVl9ZbrHJhYs7e9X8jeMZ3lr2JH/rdHFgNCBdYw==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^2.4.2", + "cli-cursor": "^3.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", + "run-async": "^2.2.0", + "rxjs": "^6.5.3", + "string-width": "^4.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + } + } + } + } + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -947,12 +1896,33 @@ "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", "dev": true }, + "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 + }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, + "is-glob": { + "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" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, "is-regex": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", @@ -982,6 +1952,12 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -1135,6 +2111,12 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -1151,6 +2133,16 @@ "verror": "1.10.0" } }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, "libsodium": { "version": "0.7.6", "resolved": "https://registry.npmjs.org/libsodium/-/libsodium-0.7.6.tgz", @@ -1206,6 +2198,18 @@ "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "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=", + "dev": true + }, "log-symbols": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", @@ -1293,6 +2297,12 @@ "mime-db": "1.40.0" } }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -1354,6 +2364,18 @@ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, "neo-async": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", @@ -1366,6 +2388,12 @@ "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==", "dev": true }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, "node-environment-flags": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", @@ -1480,6 +2508,62 @@ "es-abstract": "^1.5.1" } }, + "object.values": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", + "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.0-next.1.tgz", + "integrity": "sha512-7MmGr03N7Rnuid6+wyhD9sHNE2n4tFSwExnU2lQl3lIo2ShXWGePY80zYaoMOmILWv57H0amMjZGHNzzGG70Rw==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.0", + "string.prototype.trimright": "^2.1.0" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + } + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -1489,6 +2573,15 @@ "wrappy": "1" } }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, "optimist": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", @@ -1499,12 +2592,32 @@ "wordwrap": "~0.0.2" } }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, "p-limit": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", @@ -1541,6 +2654,15 @@ "release-zalgo": "^1.0.0" } }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -1563,6 +2685,12 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", @@ -1612,12 +2740,24 @@ "find-up": "^3.0.0" } }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, "prettier": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", "dev": true }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", @@ -1670,6 +2810,12 @@ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" }, + "regexpp": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.0.0.tgz", + "integrity": "sha512-Z+hNr7RAVWxznLPuA7DIh8UNX1j9CDrUQxskw9IrBE1Dxue2lyXT+shqEIeLUjrokxIP8CMy1WkjgG3rTsd5/g==", + "dev": true + }, "release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", @@ -1740,6 +2886,16 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -1749,6 +2905,24 @@ "glob": "^7.1.3" } }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "rxjs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", + "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, "safe-buffer": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", @@ -1771,12 +2945,38 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, "slide": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", @@ -1934,6 +3134,46 @@ "has-flag": "^3.0.0" } }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, "test-exclude": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", @@ -1946,6 +3186,27 @@ "require-main-filename": "^2.0.0" } }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -2058,12 +3319,27 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, "typescript": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.2.tgz", @@ -2108,6 +3384,12 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" }, + "v8-compile-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", + "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "dev": true + }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -2152,6 +3434,12 @@ "string-width": "^1.0.2 || 2" } }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, "wordwrap": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", @@ -2203,6 +3491,15 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, "write-file-atomic": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", diff --git a/package.json b/package.json index a61e4a259..c9f1ff744 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "beacon-sdk", - "version": "0.0.1", + "version": "0.0.1-beta.0", "description": "The beacon-sdk is setup in a way to allow for p2p communication between wallets and dapps", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -24,6 +24,7 @@ "build": "tsc", "prettier": "npx prettier --write 'src/**/*'", "tslint": "tslint -c ./tslint.json --project ./tsconfig.json --format stylish --fix", + "eslint": "eslint 'src/**/*.ts' --fix", "lint-ci": "tslint -t json -o lintReport.json --project . || true", "test": "nyc mocha --require ts-node/register --require source-map-support/register --full-trace --timeout 40000 ./test/**/**.spec.ts", "test-ci": "nyc --reporter=lcov npm test", @@ -43,8 +44,16 @@ "@types/libsodium-wrappers": "^0.7.7", "@types/mocha": "^5.2.7", "@types/node": "^12.12.6", + "@typescript-eslint/eslint-plugin": "^2.12.0", + "@typescript-eslint/eslint-plugin-tslint": "^2.12.0", + "@typescript-eslint/parser": "^2.12.0", "chai": "^4.2.0", "chai-as-promised": "^7.1.1", + "eslint": "^6.7.2", + "eslint-config-prettier": "^6.7.0", + "eslint-plugin-import": "^2.19.1", + "eslint-plugin-no-null": "^1.0.2", + "eslint-plugin-prefer-arrow": "^1.1.7", "mocha": "^6.2.2", "nyc": "^14.1.1", "prettier": "^1.19.1", diff --git a/src/client/Client.ts b/src/client/Client.ts deleted file mode 100644 index b769de6f6..000000000 --- a/src/client/Client.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { Messages, MessageTypes, PermissionRequest, PermissionResponse } from './Messages' -import myWindow from './MockWindow' -import { Serializer } from './Serializer' -import { ExposedPromise, exposedPromise } from './utils/exposed-promise' - -interface Request { - id: string - promise: ExposedPromise -} - -export class Client { - private readonly name: string = '' - private readonly serializer = new Serializer() - private readonly listeners = new Map void)[]>() - private readonly openRequests = new Map() - - constructor(name: string) { - this.name = name - myWindow.addEventListener('message', event => { - const deserialized: { type: MessageTypes } = this.serializer.deserialize(event.data) - const listeners = this.listeners.get(deserialized.type) - if (listeners) { - listeners.forEach(listener => { - listener(deserialized, newPayload => { - myWindow.postMessage(this.serializer.serialize(newPayload)) - }) - }) - } else { - // throw new Error(`No listener defined for message type ${deserialized.type}`) - } - }) - - const openRequestsHandler = (event: { id: string; type: MessageTypes }) => { - const openRequests = this.openRequests.get(event.type) || [] - const openRequest = openRequests.find(openRequest => openRequest.id === event.id) - if (openRequest) { - console.log('found openRequest') - openRequest.promise.resolve(event as any) - } else { - console.log(this.openRequests) - // throw new Error('No matching request found') - } - } - this.addListener(MessageTypes.PermissionResponse, openRequestsHandler) - this.addListener(MessageTypes.SignPayloadResponse, openRequestsHandler) - this.addListener(MessageTypes.OperationResponse, openRequestsHandler) - this.addListener(MessageTypes.BroadcastResponse, openRequestsHandler) - } - - public addListener(type: MessageTypes, listener: (payload: any, callback: any) => void) { - const listeners = this.listeners.get(type) || [] - listeners.push(listener) - this.listeners.set(type, listeners) - } - - public addOpenRequest(type: MessageTypes, id: string, promise: ExposedPromise) { - console.log(this.name, 'adding request') - const openRequests = this.openRequests.get(type) || [] - openRequests.push({ id, promise }) - this.openRequests.set(type, openRequests) - } - - public async requestPermissions(request: PermissionRequest): Promise { - const payload = this.serializer.serialize(request) - myWindow.postMessage(payload, '*') - - const exposed = exposedPromise() - this.addOpenRequest(MessageTypes.PermissionResponse, request.id, exposed) - - return exposed.promise - } - - // public async signPayloads(request: SignPayloadRequest): Promise {} - - // public async requestOperation(request: OperationRequest): Promise {} - - // public async requestBroadcast(request: BroadcastRequest): Promise {} -} diff --git a/src/client/DappClient.ts b/src/client/DappClient.ts index 69c146a75..dc828665f 100644 --- a/src/client/DappClient.ts +++ b/src/client/DappClient.ts @@ -10,10 +10,12 @@ import { SignPayloadRequest, SignPayloadResponse } from './Messages' -import myWindow from './MockWindow' +import { myWindow } from './MockWindow' import { Serializer } from './Serializer' import { ExposedPromise, exposedPromise } from './utils/exposed-promise' +interface BeaconEvent { id: string; type: MessageTypes } + interface Request { id: string promise: ExposedPromise @@ -22,13 +24,16 @@ interface Request { export class DAppClient { private readonly name: string = '' private readonly serializer = new Serializer() + // eslint-disable-next-line @typescript-eslint/no-explicit-any private readonly listeners = new Map void)[]>() private readonly openRequests = new Map() constructor(name: string) { this.name = name - myWindow.addEventListener('message', event => { - const deserialized: { type: MessageTypes } = this.serializer.deserialize(event.data) + // eslint-disable-next-line @typescript-eslint/no-explicit-any + myWindow.addEventListener('message', (event: any) => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const deserialized: { type: MessageTypes } = this.serializer.deserialize(event.data) as any const listeners = this.listeners.get(deserialized.type) if (listeners) { listeners.forEach(listener => { @@ -37,19 +42,20 @@ export class DAppClient { }) }) } else { - // throw new Error(`No listener defined for message type ${deserialized.type}`) + // Throw new Error(`No listener defined for message type ${deserialized.type}`) } }) - const openRequestsHandler = (event: { id: string; type: MessageTypes }) => { + const openRequestsHandler = (event: BeaconEvent): void => { const openRequests = this.openRequests.get(event.type) || [] - const openRequest = openRequests.find(openRequest => openRequest.id === event.id) + const openRequest = openRequests.find(openRequestElement => openRequestElement.id === event.id) if (openRequest) { console.log('found openRequest') + // eslint-disable-next-line @typescript-eslint/no-explicit-any openRequest.promise.resolve(event as any) } else { console.log(this.openRequests) - // throw new Error('No matching request found') + // Throw new Error('No matching request found') } } this.addListener(MessageTypes.PermissionResponse, openRequestsHandler) @@ -58,24 +64,26 @@ export class DAppClient { this.addListener(MessageTypes.BroadcastResponse, openRequestsHandler) } - public addListener(type: MessageTypes, listener: (payload: any, callback: any) => void) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + public addListener(type: MessageTypes, listener: (payload: any, callback: any) => void): void { const listeners = this.listeners.get(type) || [] listeners.push(listener) this.listeners.set(type, listeners) } - public addOpenRequest(type: MessageTypes, id: string, promise: ExposedPromise) { + public addOpenRequest(type: MessageTypes, id: string, promise: ExposedPromise): void { console.log(this.name, 'adding request') const openRequests = this.openRequests.get(type) || [] openRequests.push({ id, promise }) this.openRequests.set(type, openRequests) } - public async makeRequest(type: MessageTypes, request: Messages) { + public async makeRequest(type: MessageTypes, request: Messages): Promise { const payload = this.serializer.serialize(request) myWindow.postMessage(payload, '*') const exposed = exposedPromise() + // eslint-disable-next-line @typescript-eslint/no-explicit-any this.addOpenRequest(type, (request as any).id, exposed) return exposed.promise diff --git a/src/client/MockWindow.ts b/src/client/MockWindow.ts index 64dda4540..3f9dfd851 100644 --- a/src/client/MockWindow.ts +++ b/src/client/MockWindow.ts @@ -1,25 +1,28 @@ -let myWindow: any = {} -const cbs = [(_message: any) => {}] -myWindow.postMessage = message => { - console.log('GOT POST MESSAGE', message) - cbs.forEach(cb => { - cb({ data: message }) - }) -} +type Callback = (message: unknown) => void + +const cbs: Callback[] = [(_: unknown): void => undefined] -myWindow.addEventListener = (name, callback) => { - console.log('addEventListener', name) - cbs.push(callback) +let myWindow = { + postMessage: (message: string, _target?: string): void => { + console.log('GOT POST MESSAGE', message) + cbs.forEach((callbackElement: Callback) => { + callbackElement({ data: message }) + }) + }, + addEventListener: (name: string, eventCallback: Callback): void => { + console.log('addEventListener', name) + cbs.push(eventCallback) + } } -console.log('before') try { if (typeof window !== 'undefined') { - myWindow = window + // eslint-disable-next-line @typescript-eslint/no-explicit-any + myWindow = (window as any) } -} catch (e) {} - -export default myWindow +} catch (windowError) { + console.log(`not defined: ${windowError}`) +} -console.log('after') +export { myWindow } diff --git a/src/client/Serializer.ts b/src/client/Serializer.ts index 170a37825..d8fa14304 100644 --- a/src/client/Serializer.ts +++ b/src/client/Serializer.ts @@ -1,8 +1,8 @@ export class Serializer { - public serialize(message: any): string { + public serialize(message: unknown): string { return JSON.stringify(message) } - public deserialize(encoded: string): any { + public deserialize(encoded: string): unknown { return JSON.parse(encoded) } } diff --git a/src/client/WalletCommunicationClient.ts b/src/client/WalletCommunicationClient.ts index 1a66d9d7b..ff0c48188 100644 --- a/src/client/WalletCommunicationClient.ts +++ b/src/client/WalletCommunicationClient.ts @@ -1,68 +1,21 @@ import * as sodium from 'libsodium-wrappers' import * as matrixsdk from 'matrix-js-sdk' import * as qrcode from 'qrcode-generator' - -interface Member { - membership: string - roomId: string - userId: string -} - -interface Room { - roomId: string - room_id: string - currentState: any -} - -function toHex(value: any): string { - return Buffer.from(value).toString('hex') -} - -function getHexHash(key: string | Buffer | Uint8Array): string { - return toHex(sodium.crypto_generichash(32, key)) -} - -function getKeypairFromSeed(seed: string): sodium.KeyPair { - return sodium.crypto_sign_seed_keypair(sodium.crypto_generichash(32, sodium.from_string(seed))) -} - -function encryptCryptoboxPayload(message: string, sharedKey: Uint8Array): string { - const nonce = Buffer.from(sodium.randombytes_buf(sodium.crypto_secretbox_NONCEBYTES)) - const combinedPayload = Buffer.concat([nonce, Buffer.from(sodium.crypto_secretbox_easy(Buffer.from(message, 'utf8'), nonce, sharedKey))]) - - return toHex(combinedPayload) -} - -function decryptCryptoboxPayload(payload: Uint8Array, sharedKey: Uint8Array): string { - const nonce = payload.slice(0, sodium.crypto_secretbox_NONCEBYTES) - const ciphertext = payload.slice(sodium.crypto_secretbox_NONCEBYTES) - - return Buffer.from(sodium.crypto_secretbox_open_easy(ciphertext, nonce, sharedKey)).toString('utf8') -} - -function sealCryptobox(payload: string | Buffer, publicKey: Uint8Array): string { - const kxSelfPublicKey = sodium.crypto_sign_ed25519_pk_to_curve25519(Buffer.from(publicKey)) //secret bytes to scalar bytes - const encryptedMessage = sodium.crypto_box_seal(payload, kxSelfPublicKey) - - return toHex(encryptedMessage) -} - -function openCryptobox(encryptedPayload: string | Buffer, publicKey: Uint8Array, privateKey: Uint8Array): string { - const kxSelfPrivateKey = sodium.crypto_sign_ed25519_sk_to_curve25519(Buffer.from(privateKey)) //secret bytes to scalar bytes - const kxSelfPublicKey = sodium.crypto_sign_ed25519_pk_to_curve25519(Buffer.from(publicKey)) //secret bytes to scalar bytes - - const decryptedMessage = sodium.crypto_box_seal_open(encryptedPayload, kxSelfPublicKey, kxSelfPrivateKey) - - return Buffer.from(decryptedMessage).toString() -} - -function recipientString(recipientHash: string, relayServer: string): string { - return '@' + recipientHash + ':' + relayServer -} +import { + getHexHash, + getKeypairFromSeed, + toHex, + sealCryptobox, + recipientString, + openCryptobox, + encryptCryptoboxPayload, + decryptCryptoboxPayload +} from './utils/crypto' +import { MatrixClient, Member, MatrixEvent, Room } from './interfaces' export class WalletCommunicationClient { private keyPair: sodium.KeyPair | undefined - private readonly clients: any[] = [] + private readonly clients: MatrixClient[] = [] private readonly KNOWN_RELAY_SERVERS = [ // 'matrix.papers.tech', @@ -79,20 +32,6 @@ export class WalletCommunicationClient { private readonly debug: boolean = false ) {} - private bigIntAbsolute(inputBigInt: any): BigInt { - if (inputBigInt < BigInt(0)) { - return inputBigInt * BigInt(-1) - } else { - return inputBigInt - } - } - - private getAbsoluteBigIntDifference(firstHash: string, secondHash: string): BigInt { - const difference = BigInt('0x' + firstHash) - BigInt('0x' + secondHash) - - return this.bigIntAbsolute(difference) - } - public getHandshakeInfo(): { pubKey: string; relayServer: string } { return { pubKey: this.getPublicKey(), @@ -100,7 +39,7 @@ export class WalletCommunicationClient { } } - public getHandshakeQR(type?: 'data' | 'svg') { + public getHandshakeQR(type?: 'data' | 'svg'): string { const typeNumber: TypeNumber = 4 const errorCorrectionLevel: ErrorCorrectionLevel = 'L' const qr = qrcode(typeNumber, errorCorrectionLevel) @@ -123,36 +62,45 @@ export class WalletCommunicationClient { const prevRelayServerHash = getHexHash(prev + nonce) const currRelayServerHash = getHexHash(curr + nonce) - return this.getAbsoluteBigIntDifference(hash, prevRelayServerHash) < this.getAbsoluteBigIntDifference(hash, currRelayServerHash) + return this.getAbsoluteBigIntDifference(hash, prevRelayServerHash) < + this.getAbsoluteBigIntDifference(hash, currRelayServerHash) ? prev : curr }) } - public async start() { + public async start(): Promise { this.log('starting client') await sodium.ready const keyPair: sodium.KeyPair = getKeypairFromSeed(this.privateSeed) this.keyPair = keyPair - const loginRawDigest = sodium.crypto_generichash(32, sodium.from_string('login:' + Math.floor(Date.now() / 1000 / (5 * 60)))) + const loginRawDigest = sodium.crypto_generichash( + 32, + sodium.from_string(`login:${Math.floor(Date.now() / 1000 / (5 * 60))}`) + ) const rawSignature = sodium.crypto_sign_detached(loginRawDigest, this.keyPair.privateKey) this.log(`connecting to ${this.replicationCount} servers`) for (let i = 0; i < this.replicationCount; i++) { const client = matrixsdk.createClient({ - baseUrl: 'https://' + this.getRelayServer(this.getPublicKeyHash(), i.toString()), + baseUrl: `https://${this.getRelayServer(this.getPublicKeyHash(), i.toString())}`, deviceId: toHex(this.keyPair.publicKey), timelineSupport: false }) - this.log('login', this.getPublicKeyHash(), 'on', this.getRelayServer(this.getPublicKeyHash(), i.toString())) + this.log( + 'login', + this.getPublicKeyHash(), + 'on', + this.getRelayServer(this.getPublicKeyHash(), i.toString()) + ) await client.login('m.login.password', { user: this.getPublicKeyHash(), - password: 'ed:' + toHex(rawSignature) + ':' + this.getPublicKey() + password: `ed:${toHex(rawSignature)}:${this.getPublicKey()}` }) - client.on('RoomMember.membership', async (_event: any, member: Member) => { + client.on('RoomMember.membership', async (_event: unknown, member: Member) => { if (member.membership === 'invite') { await client.joinRoom(member.roomId) } @@ -167,44 +115,10 @@ export class WalletCommunicationClient { } } - public getPublicKey(): string { - if (!this.keyPair) { - throw new Error('KeyPair not available') - } - - return toHex(this.keyPair.publicKey) - } - - public getPublicKeyHash(): string { - if (!this.keyPair) { - throw new Error('KeyPair not available') - } - - return getHexHash(this.keyPair.publicKey) - } - - private async createCryptoBox(otherPublicKey: string, selfPrivateKey: Uint8Array): Promise<[Uint8Array, Uint8Array, Uint8Array]> { - // TODO: Don't calculate it every time? - const kxSelfPrivateKey = sodium.crypto_sign_ed25519_sk_to_curve25519(Buffer.from(selfPrivateKey)) //secret bytes to scalar bytes - const kxSelfPublicKey = sodium.crypto_sign_ed25519_pk_to_curve25519(Buffer.from(selfPrivateKey).slice(32, 64)) //secret bytes to scalar bytes - const kxOtherPublicKey = sodium.crypto_sign_ed25519_pk_to_curve25519(Buffer.from(otherPublicKey, 'hex')) //secret bytes to scalar bytes - - return [Buffer.from(kxSelfPublicKey), Buffer.from(kxSelfPrivateKey), Buffer.from(kxOtherPublicKey)] - } - - private async createCryptoBoxServer(otherPublicKey: string, selfPrivateKey: Uint8Array): Promise { - const keys = await this.createCryptoBox(otherPublicKey, selfPrivateKey) - - return sodium.crypto_kx_server_session_keys(...keys) - } - - private async createCryptoBoxClient(otherPublicKey: string, selfPrivateKey: Uint8Array): Promise { - const keys = await this.createCryptoBox(otherPublicKey, selfPrivateKey) - - return sodium.crypto_kx_client_session_keys(...keys) - } - - public async listenForEncryptedMessage(senderPublicKey: string, messageCallback: (message: string) => void) { + public async listenForEncryptedMessage( + senderPublicKey: string, + messageCallback: (message: string) => void + ): Promise { if (!this.keyPair) { throw new Error('KeyPair not available') } @@ -212,10 +126,13 @@ export class WalletCommunicationClient { const { sharedRx } = await this.createCryptoBoxServer(senderPublicKey, this.keyPair.privateKey) for (const client of this.clients) { - client.on('event', (event: any) => { + client.on('event', (event: MatrixEvent) => { if (this.isRoomMessage(event) && this.isSender(event, senderPublicKey)) { const payload = Buffer.from(event.getContent().body, 'hex') - if (payload.length >= sodium.crypto_secretbox_NONCEBYTES + sodium.crypto_secretbox_MACBYTES) { + if ( + payload.length >= + sodium.crypto_secretbox_NONCEBYTES + sodium.crypto_secretbox_MACBYTES + ) { messageCallback(decryptCryptoboxPayload(payload, sharedRx)) } } @@ -223,15 +140,21 @@ export class WalletCommunicationClient { } } - public async sendMessage(recipientPublicKey: string, message: string) { + public async sendMessage(recipientPublicKey: string, message: string): Promise { if (!this.keyPair) { throw new Error('KeyPair not available') } - const { sharedTx } = await this.createCryptoBoxClient(recipientPublicKey, this.keyPair.privateKey) + const { sharedTx } = await this.createCryptoBoxClient( + recipientPublicKey, + this.keyPair.privateKey + ) for (let i = 0; i < this.replicationCount; i++) { const recipientHash = getHexHash(Buffer.from(recipientPublicKey, 'hex')) - const recipient = recipientString(recipientHash, this.getRelayServer(recipientHash, i.toString())) + const recipient = recipientString( + recipientHash, + this.getRelayServer(recipientHash, i.toString()) + ) for (const client of this.clients) { const room = await this.getRelevantRoom(client, recipient) @@ -244,9 +167,9 @@ export class WalletCommunicationClient { } } - public async listenForChannelOpening(messageCallback: (message: string) => void) { + public async listenForChannelOpening(messageCallback: (message: string) => void): Promise { for (const client of this.clients) { - client.on('event', (event: any) => { + client.on('event', (event: MatrixEvent) => { if (this.isRoomMessage(event) && this.isChannelOpenMessage(event)) { if (!this.keyPair) { throw new Error('KeyPair not available') @@ -256,7 +179,10 @@ export class WalletCommunicationClient { const splits = event.getContent().body.split(':') const payload = Buffer.from(splits[splits.length - 1], 'hex') - if (payload.length >= sodium.crypto_secretbox_NONCEBYTES + sodium.crypto_secretbox_MACBYTES) { + if ( + payload.length >= + sodium.crypto_secretbox_NONCEBYTES + sodium.crypto_secretbox_MACBYTES + ) { messageCallback(openCryptobox(payload, this.keyPair.publicKey, this.keyPair.privateKey)) } } @@ -264,16 +190,19 @@ export class WalletCommunicationClient { } } - public async openChannel(recipientPublicKey: string, relayServer: string) { + public async openChannel(recipientPublicKey: string, relayServer: string): Promise { this.log('open channel') const recipientHash = getHexHash(Buffer.from(recipientPublicKey, 'hex')) const recipient = recipientString(recipientHash, relayServer) - this.log('currently there are ' + this.clients.length + ' clients open') + this.log(`currently there are ${this.clients.length} clients open`) for (const client of this.clients) { const room = await this.getRelevantRoom(client, recipient) - const encryptedMessage = sealCryptobox(this.getPublicKey(), Buffer.from(recipientPublicKey, 'hex')) + const encryptedMessage = sealCryptobox( + this.getPublicKey(), + Buffer.from(recipientPublicKey, 'hex') + ) client.sendMessage(room.roomId, { msgtype: 'm.text', body: ['@channel-open', recipient, encryptedMessage].join(':') @@ -281,21 +210,104 @@ export class WalletCommunicationClient { } } - private async getRelevantRoom(client: any, recipient: string): Promise { + public isRoomMessage(event: MatrixEvent): boolean { + return event.getType() === 'm.room.message' + } + + public isChannelOpenMessage(event: MatrixEvent): boolean { + return event + .getContent() + .body.startsWith(`@channel-open:@${getHexHash(Buffer.from(this.getPublicKey(), 'hex'))}`) + } + + public isSender(event: MatrixEvent, senderPublicKey: string): boolean { + return event.getSender().startsWith(`@${getHexHash(Buffer.from(senderPublicKey, 'hex'))}`) + } + + public getPublicKey(): string { + if (!this.keyPair) { + throw new Error('KeyPair not available') + } + + return toHex(this.keyPair.publicKey) + } + + public getPublicKeyHash(): string { + if (!this.keyPair) { + throw new Error('KeyPair not available') + } + + return getHexHash(this.keyPair.publicKey) + } + + private bigIntAbsolute(inputBigInt: bigint): bigint { + if (inputBigInt < BigInt(0)) { + return inputBigInt * BigInt(-1) + } else { + return inputBigInt + } + } + + private getAbsoluteBigIntDifference(firstHash: string, secondHash: string): bigint { + const difference = BigInt(`0x${firstHash}`) - BigInt(`0x${secondHash}`) + + return this.bigIntAbsolute(difference) + } + + private async createCryptoBox( + otherPublicKey: string, + selfPrivateKey: Uint8Array + ): Promise<[Uint8Array, Uint8Array, Uint8Array]> { + // TODO: Don't calculate it every time? + const kxSelfPrivateKey = sodium.crypto_sign_ed25519_sk_to_curve25519( + Buffer.from(selfPrivateKey) + ) // Secret bytes to scalar bytes + const kxSelfPublicKey = sodium.crypto_sign_ed25519_pk_to_curve25519( + Buffer.from(selfPrivateKey).slice(32, 64) + ) // Secret bytes to scalar bytes + const kxOtherPublicKey = sodium.crypto_sign_ed25519_pk_to_curve25519( + Buffer.from(otherPublicKey, 'hex') + ) // Secret bytes to scalar bytes + + return [ + Buffer.from(kxSelfPublicKey), + Buffer.from(kxSelfPrivateKey), + Buffer.from(kxOtherPublicKey) + ] + } + + private async createCryptoBoxServer( + otherPublicKey: string, + selfPrivateKey: Uint8Array + ): Promise { + const keys = await this.createCryptoBox(otherPublicKey, selfPrivateKey) + + return sodium.crypto_kx_server_session_keys(...keys) + } + + private async createCryptoBoxClient( + otherPublicKey: string, + selfPrivateKey: Uint8Array + ): Promise { + const keys = await this.createCryptoBox(otherPublicKey, selfPrivateKey) + + return sodium.crypto_kx_client_session_keys(...keys) + } + + private async getRelevantRoom(client: MatrixClient, recipient: string): Promise { const rooms = client.getRooms() - const relevantRooms = rooms.filter((room: Room) => { - return room.currentState.getMembers().some((member: Member) => { - return member.userId === recipient - }) - }) + const relevantRooms = rooms.filter((roomElement: Room) => + roomElement.currentState.getMembers().some((member: Member) => member.userId === recipient) + ) let room: Room - if (relevantRooms.length == 0) { + if (relevantRooms.length === 0) { this.log(`no relevant rooms found`) room = await client.createRoom({ invite: [recipient], preset: 'trusted_private_chat', + // eslint-disable-next-line camelcase is_direct: true }) room = client.getRoom(room.room_id) @@ -307,19 +319,7 @@ export class WalletCommunicationClient { return room } - public isRoomMessage(event: any): boolean { - return event.getType() === 'm.room.message' - } - - public isChannelOpenMessage(event: any): boolean { - return event.getContent().body.startsWith('@channel-open:@' + getHexHash(Buffer.from(this.getPublicKey(), 'hex'))) - } - - public isSender(event: any, senderPublicKey: string): boolean { - return event.getSender().startsWith('@' + getHexHash(Buffer.from(senderPublicKey, 'hex'))) - } - - private log(...args: any[]): void { + private log(...args: unknown[]): void { if (this.debug) { console.log(`--- [WalletCommunicationClient]:${this.name}: `, ...args) } diff --git a/src/client/interfaces.ts b/src/client/interfaces.ts new file mode 100644 index 000000000..b07b953de --- /dev/null +++ b/src/client/interfaces.ts @@ -0,0 +1,41 @@ +export interface MatrixEvent { + getSender(): string + getContent(): { body: string } + getType(): string +} + +export interface MatrixCreateRoom { + invite: string[] + preset: string + // eslint-disable-next-line camelcase + is_direct: boolean +} + +export interface MatrixClient { + getRooms(): Room[] + createRoom(room: MatrixCreateRoom): Promise + getRoom(roomId: string): Room + sendMessage( + roomId: string, + message: { + msgtype: string + body: string + } + ): void + on(eventName: string, eventCallback: (event: MatrixEvent) => void): void +} + +export interface Member { + membership: string + roomId: string + userId: string +} + +export interface Room { + roomId: string + // eslint-disable-next-line camelcase + room_id: string + currentState: { + getMembers(): Member[] + } +} diff --git a/src/client/storage/FileStorage.ts b/src/client/storage/FileStorage.ts index f9bfeb169..9abdad922 100644 --- a/src/client/storage/FileStorage.ts +++ b/src/client/storage/FileStorage.ts @@ -5,34 +5,38 @@ import { Storage } from './Storage' const file: string = './storage.json' interface JsonObject { - [key: string]: any + [key: string]: unknown } +/* eslint-disable prefer-arrow/prefer-arrow-functions */ + function readLocalFile(): Promise { - return new Promise((resolve, reject) => { - readFile(file, { encoding: 'utf8' }, (err, result) => { - if (err) { - reject(err) + return new Promise((resolve: (_: JsonObject) => void, reject: (error: unknown) => void): void => { + readFile(file, { encoding: 'utf8' }, (fileReadError: unknown, fileContent: string) => { + if (fileReadError) { + reject(fileReadError) } try { - const json: JsonObject = JSON.parse(result) + const json: JsonObject = JSON.parse(fileContent) resolve(json) - } catch (e) { - reject(e) + } catch (jsonParseError) { + reject(jsonParseError) } }) }) } function writeLocalFile(json: JsonObject): Promise { - return new Promise(resolve => { - const data: string = JSON.stringify(json) - writeFile(data, { encoding: 'utf8' }, () => { + return new Promise((resolve: (_: void) => void): void => { + const fileContent: string = JSON.stringify(json) + writeFile(fileContent, { encoding: 'utf8' }, () => { resolve() }) }) } +/* eslint-enable prefer-arrow/prefer-arrow-functions */ + /** * This can be used for development in node. * @@ -43,7 +47,7 @@ export class FileStorage implements Storage { return Promise.resolve(typeof global !== 'undefined') } - public async get(key: string): Promise { + public async get(key: string): Promise { const json: JsonObject = await readLocalFile() return json[key] @@ -58,7 +62,7 @@ export class FileStorage implements Storage { public async delete(key: string): Promise { const json: JsonObject = await readLocalFile() - delete json[key] + json[key] = undefined return writeLocalFile(json) } diff --git a/src/client/storage/LocalStorage.ts b/src/client/storage/LocalStorage.ts index af0930881..5b31e8fdc 100644 --- a/src/client/storage/LocalStorage.ts +++ b/src/client/storage/LocalStorage.ts @@ -5,7 +5,7 @@ export class LocalStorage implements Storage { return Promise.resolve(typeof window !== 'undefined' && !!window.localStorage) } - public async get(key: string): Promise { + public async get(key: string): Promise { return localStorage.getItem(key) } diff --git a/src/client/storage/Storage.ts b/src/client/storage/Storage.ts index 38f0890b2..cb12c6f97 100644 --- a/src/client/storage/Storage.ts +++ b/src/client/storage/Storage.ts @@ -1,6 +1,6 @@ export interface Storage { isSupported(): Promise - get(key: string): Promise + get(key: string): Promise set(key: string, value: string): Promise delete(key: string): Promise } diff --git a/src/client/storage/StorageProvider.ts b/src/client/storage/StorageProvider.ts index 72003c796..68c204c7f 100644 --- a/src/client/storage/StorageProvider.ts +++ b/src/client/storage/StorageProvider.ts @@ -1,15 +1,15 @@ -import { FileStorage } from "./FileStorage" -import { LocalStorage } from "./LocalStorage" -import { Storage } from "./Storage" +import { FileStorage } from './FileStorage' +import { LocalStorage } from './LocalStorage' +import { Storage } from './Storage' -export async function getStorage(): Promise { - const local: LocalStorage = new LocalStorage() - const file: FileStorage = new FileStorage() - if (await local.isSupported()) { - return local - } else if (await file.isSupported()) { - return file - } else { - throw new Error('no storage type supported') - } -} \ No newline at end of file +export const getStorage: () => Promise = async (): Promise => { + const local: LocalStorage = new LocalStorage() + const file: FileStorage = new FileStorage() + if (await local.isSupported()) { + return local + } else if (await file.isSupported()) { + return file + } else { + throw new Error('no storage type supported') + } +} diff --git a/src/client/utils/assert-never.ts b/src/client/utils/assert-never.ts index 331b2ff8a..ef30af1e9 100644 --- a/src/client/utils/assert-never.ts +++ b/src/client/utils/assert-never.ts @@ -1 +1,7 @@ -export function assertNever(_: never) {} +/* eslint-disable prefer-arrow/prefer-arrow-functions */ + +export function assertNever(_: never): never { + return _ +} + +/* eslint-enable prefer-arrow/prefer-arrow-functions */ diff --git a/src/client/utils/crypto.ts b/src/client/utils/crypto.ts new file mode 100644 index 000000000..6fb3df169 --- /dev/null +++ b/src/client/utils/crypto.ts @@ -0,0 +1,65 @@ +import * as sodium from 'libsodium-wrappers' + +/* eslint-disable prefer-arrow/prefer-arrow-functions */ + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function toHex(value: any): string { + return Buffer.from(value).toString('hex') +} + +export function getHexHash(key: string | Buffer | Uint8Array): string { + return toHex(sodium.crypto_generichash(32, key)) +} + +export function getKeypairFromSeed(seed: string): sodium.KeyPair { + return sodium.crypto_sign_seed_keypair(sodium.crypto_generichash(32, sodium.from_string(seed))) +} + +export function encryptCryptoboxPayload(message: string, sharedKey: Uint8Array): string { + const nonce = Buffer.from(sodium.randombytes_buf(sodium.crypto_secretbox_NONCEBYTES)) + const combinedPayload = Buffer.concat([ + nonce, + Buffer.from(sodium.crypto_secretbox_easy(Buffer.from(message, 'utf8'), nonce, sharedKey)) + ]) + + return toHex(combinedPayload) +} + +export function decryptCryptoboxPayload(payload: Uint8Array, sharedKey: Uint8Array): string { + const nonce = payload.slice(0, sodium.crypto_secretbox_NONCEBYTES) + const ciphertext = payload.slice(sodium.crypto_secretbox_NONCEBYTES) + + return Buffer.from(sodium.crypto_secretbox_open_easy(ciphertext, nonce, sharedKey)).toString( + 'utf8' + ) +} + +export function sealCryptobox(payload: string | Buffer, publicKey: Uint8Array): string { + const kxSelfPublicKey = sodium.crypto_sign_ed25519_pk_to_curve25519(Buffer.from(publicKey)) // Secret bytes to scalar bytes + const encryptedMessage = sodium.crypto_box_seal(payload, kxSelfPublicKey) + + return toHex(encryptedMessage) +} + +export function openCryptobox( + encryptedPayload: string | Buffer, + publicKey: Uint8Array, + privateKey: Uint8Array +): string { + const kxSelfPrivateKey = sodium.crypto_sign_ed25519_sk_to_curve25519(Buffer.from(privateKey)) // Secret bytes to scalar bytes + const kxSelfPublicKey = sodium.crypto_sign_ed25519_pk_to_curve25519(Buffer.from(publicKey)) // Secret bytes to scalar bytes + + const decryptedMessage = sodium.crypto_box_seal_open( + encryptedPayload, + kxSelfPublicKey, + kxSelfPrivateKey + ) + + return Buffer.from(decryptedMessage).toString() +} + +export function recipientString(recipientHash: string, relayServer: string): string { + return `@${recipientHash}:${relayServer}` +} + +/* eslint-enable prefer-arrow/prefer-arrow-functions */ diff --git a/src/client/utils/exposed-promise.ts b/src/client/utils/exposed-promise.ts index c65427855..c6f44c03c 100644 --- a/src/client/utils/exposed-promise.ts +++ b/src/client/utils/exposed-promise.ts @@ -4,19 +4,25 @@ export interface ExposedPromise { reject(reason?: unknown): void } -function notInitialized() { +type Resolve = (value?: T | PromiseLike) => void +type Reject = (reason?: unknown) => void + +/* eslint-disable prefer-arrow/prefer-arrow-functions */ + +function notInitialized(): never { throw new Error('ExposedPromise not initialized yet.') } - export function exposedPromise(): ExposedPromise { - let resolve: (value?: T | PromiseLike) => void = notInitialized - let reject: (reason?: unknown) => void = notInitialized + let resolve: Resolve = notInitialized + let reject: Reject = notInitialized - // tslint:disable-next-line:promise-must-complete - const promise: Promise = new Promise((innerResolve, innerReject) => { - resolve = innerResolve - reject = innerReject - }) + const promise: Promise = new Promise( + (innerResolve: Resolve, innerReject: Reject): void => { + resolve = innerResolve + reject = innerReject + } + ) return { promise, resolve, reject } } +/* eslint-enable prefer-arrow/prefer-arrow-functions */ diff --git a/tslint.json b/tslint.json deleted file mode 100644 index c1f416d80..000000000 --- a/tslint.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "extends": ["tslint-config-valorsoft", "tslint-config-prettier"], - - "rules": { - "semicolon": [true, "never"], - "member-access": [true], - "member-ordering": [ - true, - { - "order": ["public-before-private", "static-before-instance", "variables-before-functions"], - "alphabetize": true - } - ], - "typedef": [ - true, - "call-signature", - "arrow-call-signature", - "parameter", - "arrow-parameter", - "property-declaration", - "variable-declaration", - "member-variable-declaration", - "object-destructuring", - "array-destructuring" - ], - "no-inferrable-types": false, - "ordered-imports": { - "options": { - "grouped-imports": true, - "import-sources-order": "case-insensitive", - "named-imports-order": "case-insensitive", - "module-source-path": "full" - } - }, - "no-implicit-dependencies": [true, "dev"], - "type-literal-delimiter": false - } -}