diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..c37dddc --- /dev/null +++ b/.eslintignore @@ -0,0 +1,3 @@ +packages/*/lib +packages/*/esm +build/ diff --git a/.eslintrc.yaml b/.eslintrc.yaml new file mode 100644 index 0000000..d96b427 --- /dev/null +++ b/.eslintrc.yaml @@ -0,0 +1,32 @@ +extends: + - eslint:recommended + - plugin:@typescript-eslint/eslint-recommended + - plugin:@typescript-eslint/recommended +rules: + max-len: + - warn + - code: 80 + ignorePattern: '^import .* from ' + # semi: + # - warn + # - never + # interface-name-prefix: + '@typescript-eslint/member-delimiter-style': + - error + - multiline: + delimiter: none + singleline: + delimiter: comma + '@typescript-eslint/explicit-function-return-type': off + '@typescript-eslint/no-non-null-assertion': off + '@typescript-eslint/no-use-before-define': off +overrides: + - files: + - '*.test.ts' + - '*.test.tsx' + rules: + '@typescript-eslint/no-explicit-any': off + - files: + - '*.js' + env: + node: true diff --git a/package-lock.json b/package-lock.json index fe8a26e..a16f842 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,7 +7,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", - "dev": true, "requires": { "@babel/highlight": "^7.0.0" } @@ -141,7 +140,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", - "dev": true, "requires": { "chalk": "^2.0.0", "esutils": "^2.0.2", @@ -2349,6 +2347,11 @@ "integrity": "sha512-z2JtmHE1wg75JTdT1qWGvW4eDOk6DUW1Exdzrs+8QTPFttkdTr4pKVzLLCCAOUC8i/KiG+QtkSEteQ5hDxwbpg==", "dev": true }, + "@types/eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==" + }, "@types/events": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", @@ -2459,6 +2462,11 @@ "integrity": "sha512-UGEe/6RsNAxgWdknhzFZbCxuYc5I7b/YEKlfKbo+76SM8CJzGs7XKCj7zyugXViRbKYpXhSXhCYVQZL5tmDbpQ==", "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==" + }, "@types/marked": { "version": "0.6.5", "resolved": "https://registry.npmjs.org/@types/marked/-/marked-0.6.5.tgz", @@ -2678,6 +2686,88 @@ "integrity": "sha512-sCZy4SxP9rN2w30Hlmg5dtdRwgYQfYRiLo9usw8X9cxlf+H4FqM1xX7+sNH7NNKVdbXMJWqva7iyy+fxh/V7fA==", "dev": true }, + "@typescript-eslint/eslint-plugin": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.2.0.tgz", + "integrity": "sha512-rOodtI+IvaO8USa6ValYOrdWm9eQBgqwsY+B0PPiB+aSiK6p6Z4l9jLn/jI3z3WM4mkABAhKIqvGIBl0AFRaLQ==", + "requires": { + "@typescript-eslint/experimental-utils": "2.2.0", + "eslint-utils": "^1.4.2", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^2.0.1", + "tsutils": "^3.17.1" + }, + "dependencies": { + "tsutils": { + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", + "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", + "requires": { + "tslib": "^1.8.1" + } + } + } + }, + "@typescript-eslint/experimental-utils": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.2.0.tgz", + "integrity": "sha512-IMhbewFs27Frd/ICHBRfIcsUCK213B8MsEUqvKFK14SDPjPR5JF6jgOGPlroybFTrGWpMvN5tMZdXAf+xcmxsA==", + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "2.2.0", + "eslint-scope": "^5.0.0" + } + }, + "@typescript-eslint/parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.2.0.tgz", + "integrity": "sha512-0mf893kj9L65O5sA7wP6EoYvTybefuRFavUNhT7w9kjhkdZodoViwVS+k3D+ZxKhvtL7xGtP/y/cNMJX9S8W4A==", + "requires": { + "@types/eslint-visitor-keys": "^1.0.0", + "@typescript-eslint/experimental-utils": "2.2.0", + "@typescript-eslint/typescript-estree": "2.2.0", + "eslint-visitor-keys": "^1.1.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.2.0.tgz", + "integrity": "sha512-9/6x23A3HwWWRjEQbuR24on5XIfVmV96cDpGR9671eJv1ebFKHj2sGVVAwkAVXR2UNuhY1NeKS2QMv5P8kQb2Q==", + "requires": { + "glob": "^7.1.4", + "is-glob": "^4.0.1", + "lodash.unescape": "4.0.1", + "semver": "^6.3.0" + }, + "dependencies": { + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "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" + } + }, + "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==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, "@zkochan/cmd-shim": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@zkochan/cmd-shim/-/cmd-shim-3.1.0.tgz", @@ -2741,6 +2831,11 @@ "acorn-walk": "^6.0.1" } }, + "acorn-jsx": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.2.tgz", + "integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==" + }, "acorn-node": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.6.2.tgz", @@ -2839,8 +2934,7 @@ "ansi-escapes": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" }, "ansi-regex": { "version": "2.1.1", @@ -3075,8 +3169,7 @@ "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 + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==" }, "async-each": { "version": "1.0.1", @@ -4530,8 +4623,7 @@ "chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" }, "check-error": { "version": "1.0.2", @@ -4645,7 +4737,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, "requires": { "restore-cursor": "^2.0.0" } @@ -4824,8 +4915,7 @@ "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 + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" }, "cliui": { "version": "4.1.0", @@ -5667,8 +5757,7 @@ "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 + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, "deep-object-diff": { "version": "1.1.0", @@ -5882,6 +5971,14 @@ "path-type": "^3.0.0" } }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "requires": { + "esutils": "^2.0.2" + } + }, "dom-serializer": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", @@ -6030,6 +6127,11 @@ "shimmer": "^1.2.0" } }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -6240,6 +6342,141 @@ "estraverse": "^4.1.1" } }, + "eslint": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.4.0.tgz", + "integrity": "sha512-WTVEzK3lSFoXUovDHEbkJqCVPEPwbhCq4trDktNI6ygs7aO41d4cDT0JFAT5MivzZeVLWlg7vHL+bgrQv/t3vA==", + "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.2", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.1.1", + "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": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.4.1", + "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.2", + "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": { + "ajv": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "glob-parent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", + "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "import-fresh": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", + "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "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==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "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==" + } + } + }, + "eslint-scope": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", + "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", + "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", + "requires": { + "eslint-visitor-keys": "^1.0.0" + } + }, + "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==" + }, "esmify": { "version": "git+https://github.com/jeremija/esmify.git#f98b2c83898283cb01346635ef457e33795d7060", "from": "git+https://github.com/jeremija/esmify.git", @@ -6257,16 +6494,40 @@ "through2": "^2.0.5" } }, + "espree": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.1.tgz", + "integrity": "sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ==", + "requires": { + "acorn": "^7.0.0", + "acorn-jsx": "^5.0.2", + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "acorn": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.0.0.tgz", + "integrity": "sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ==" + } + } + }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "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" } @@ -6274,14 +6535,12 @@ "estraverse": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" }, "esutils": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" }, "etag": { "version": "1.8.1", @@ -6542,7 +6801,6 @@ "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", @@ -6657,8 +6915,7 @@ "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 + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, "fb-watchman": { "version": "2.0.0", @@ -6699,11 +6956,18 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "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==", + "requires": { + "flat-cache": "^2.0.1" + } + }, "fileset": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", @@ -6788,6 +7052,31 @@ "locate-path": "^3.0.0" } }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "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==", + "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==" + }, "flush-write-stream": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", @@ -7481,6 +7770,11 @@ "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=" + }, "gauge": { "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", @@ -7863,8 +8157,7 @@ "globals": { "version": "11.11.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", - "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", - "dev": true + "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==" }, "globby": { "version": "9.2.0", @@ -8237,8 +8530,7 @@ "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 + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" }, "ignore-by-default": { "version": "1.0.1", @@ -8291,8 +8583,7 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" }, "in-publish": { "version": "2.0.0", @@ -8360,7 +8651,6 @@ "version": "6.5.2", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", - "dev": true, "requires": { "ansi-escapes": "^3.2.0", "chalk": "^2.4.2", @@ -8380,20 +8670,17 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" }, "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 + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" @@ -8403,7 +8690,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, "requires": { "ansi-regex": "^3.0.0" } @@ -8414,7 +8700,6 @@ "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" }, @@ -8422,8 +8707,7 @@ "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 + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" } } } @@ -8615,8 +8899,7 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" }, "is-finite": { "version": "1.0.2", @@ -8719,8 +9002,7 @@ "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 + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" }, "is-redirect": { "version": "1.0.0", @@ -9665,8 +9947,7 @@ "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "js-yaml": { "version": "3.13.1", @@ -9772,6 +10053,11 @@ "jsonify": "~0.0.0" } }, + "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=" + }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -9915,7 +10201,6 @@ "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" @@ -9945,8 +10230,7 @@ "lodash": { "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, "lodash-es": { "version": "4.17.15", @@ -10051,6 +10335,11 @@ "lodash._reinterpolate": "^3.0.0" } }, + "lodash.unescape": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", + "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=" + }, "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -10556,8 +10845,7 @@ "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" }, "multimatch": { "version": "3.0.0", @@ -10584,8 +10872,7 @@ "mute-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" }, "mutexify": { "version": "1.2.0", @@ -10686,8 +10973,7 @@ "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 + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" }, "needle": { "version": "2.2.4", @@ -11464,7 +11750,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, "requires": { "mimic-fn": "^1.0.0" } @@ -11509,7 +11794,6 @@ "version": "0.8.2", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, "requires": { "deep-is": "~0.1.3", "fast-levenshtein": "~2.0.4", @@ -11522,8 +11806,7 @@ "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" } } }, @@ -11700,6 +11983,21 @@ "readable-stream": "^2.1.5" } }, + "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==", + "requires": { + "callsites": "^3.0.0" + }, + "dependencies": { + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + } + } + }, "parent-require": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parent-require/-/parent-require-1.0.0.tgz", @@ -12168,8 +12466,7 @@ "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 + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" }, "prepend-http": { "version": "1.0.4", @@ -12223,8 +12520,7 @@ "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" }, "promise": { "version": "7.3.1", @@ -12846,6 +13142,11 @@ "safe-regex": "^1.1.0" } }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==" + }, "registry-auth-token": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", @@ -12987,8 +13288,7 @@ "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" }, "resolve-pathname": { "version": "2.2.0", @@ -13006,7 +13306,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, "requires": { "onetime": "^2.0.0", "signal-exit": "^3.0.2" @@ -13058,7 +13357,6 @@ "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" } @@ -13076,7 +13374,6 @@ "version": "6.5.2", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", - "dev": true, "requires": { "tslib": "^1.9.0" } @@ -13566,6 +13863,23 @@ "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", "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==", + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "dependencies": { + "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=" + } + } + }, "slide": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", @@ -14228,6 +14542,58 @@ "acorn-node": "^1.2.0" } }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "ajv": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "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=" + }, + "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==", + "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==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, "tar": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", @@ -14357,6 +14723,11 @@ "integrity": "sha512-F91ZqLgvi1E0PdvmxMgp+gcf6q8fMH7mhdwWfzXnl1k+GbpQDmi8l7DzLC5JTASKbwpY3TfxajAUzAXcv2NmsQ==", "dev": true }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + }, "thenify": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", @@ -14388,8 +14759,7 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, "through2": { "version": "2.0.5", @@ -14438,7 +14808,6 @@ "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" } @@ -14967,8 +15336,7 @@ "tslib": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", - "dev": true + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" }, "tslint": { "version": "5.12.1", @@ -15036,7 +15404,6 @@ "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" } @@ -15455,6 +15822,11 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" }, + "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==" + }, "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", @@ -15754,6 +16126,14 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "requires": { + "mkdirp": "^0.5.1" + } + }, "write-file-atomic": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", diff --git a/package.json b/package.json index cf9b6d1..98b5993 100644 --- a/package.json +++ b/package.json @@ -1,23 +1,26 @@ { "dependencies": { - "@rondo.dev/client": "file:packages/client", - "@rondo.dev/common": "file:packages/common", - "@rondo.dev/server": "file:packages/server", - "@rondo.dev/comments-server": "file:packages/comments-server", - "@rondo.dev/comments-common": "file:packages/comments-common", - "@rondo.dev/comments-client": "file:packages/comments-client", - "@rondo.dev/image-upload": "file:packages/image-upload", - "@rondo.dev/tasq": "file:packages/tasq", - "@rondo.dev/jsonrpc": "file:packages/jsonrpc", - "@rondo.dev/scripts": "file:packages/scripts", "@rondo.dev/argparse": "file:packages/argparse", - "@rondo.dev/logger": "file:packages/logger", + "@rondo.dev/client": "file:packages/client", + "@rondo.dev/comments-client": "file:packages/comments-client", + "@rondo.dev/comments-common": "file:packages/comments-common", + "@rondo.dev/comments-server": "file:packages/comments-server", + "@rondo.dev/common": "file:packages/common", "@rondo.dev/config": "file:packages/config", - "@rondo.dev/redux": "file:packages/redux", "@rondo.dev/http-client": "file:packages/http-client", - "@rondo.dev/test-utils": "file:packages/test-utils", "@rondo.dev/http-types": "file:packages/http-types", - "@rondo.dev/validator": "file:packages/validator" + "@rondo.dev/image-upload": "file:packages/image-upload", + "@rondo.dev/jsonrpc": "file:packages/jsonrpc", + "@rondo.dev/logger": "file:packages/logger", + "@rondo.dev/redux": "file:packages/redux", + "@rondo.dev/scripts": "file:packages/scripts", + "@rondo.dev/server": "file:packages/server", + "@rondo.dev/tasq": "file:packages/tasq", + "@rondo.dev/test-utils": "file:packages/test-utils", + "@rondo.dev/validator": "file:packages/validator", + "@typescript-eslint/eslint-plugin": "^2.2.0", + "@typescript-eslint/parser": "^2.2.0", + "eslint": "^6.4.0" }, "devDependencies": { "@types/bcrypt": "^3.0.0", diff --git a/packages/argparse/src/argparse.test.ts b/packages/argparse/src/argparse.test.ts index 2930cad..90a34b3 100644 --- a/packages/argparse/src/argparse.test.ts +++ b/packages/argparse/src/argparse.test.ts @@ -1,4 +1,4 @@ -import {argparse, arg, IArgsConfig} from './argparse' +import { arg, argparse } from './argparse' describe('argparse', () => { @@ -418,7 +418,7 @@ Positional arguments: expect(() => argparse({ a: { type: 'test', - } as any, + } as any, // eslint-disable-line }).parse([CMD, '-a'])).toThrowError(/Unknown type: test/) }) diff --git a/packages/argparse/src/argparse.ts b/packages/argparse/src/argparse.ts index 52d2bc8..f064f82 100644 --- a/packages/argparse/src/argparse.ts +++ b/packages/argparse/src/argparse.ts @@ -18,7 +18,7 @@ export const N_DEFAULT_VALUE = 1 export type TNumberOfArgs = number | '+' | '*' -export interface IArgParam { +export interface ArgParam { alias?: string description?: string default?: TArgType @@ -28,26 +28,26 @@ export interface IArgParam { n?: TNumberOfArgs } -export interface IArgument extends IArgParam { +export interface Argument extends ArgParam { type: T } -export interface IArgsConfig { - [arg: string]: IArgument +export interface ArgsConfig { + [arg: string]: Argument } -export type TArgs = { - [k in keyof T]: T[k] extends IArgument ? +export type TArgs = { + [k in keyof T]: T[k] extends Argument ? TArgType : never } -interface IIterator { +interface Iterator { hasNext(): boolean next(): T peek(): T } -const iterate = (arr: T[]): IIterator => { +const iterate = (arr: T[]): Iterator => { let i = -1 return { hasNext() { @@ -86,7 +86,7 @@ function getDefaultValue(type: TArgTypeName) { } function getBooleanValue( - it: IIterator, + it: Iterator, argument: string, isPositional: boolean, ): boolean { @@ -96,7 +96,7 @@ function getBooleanValue( } else if (argument === 'false') { return false } else { - throw new Error('Value of argument must be true or false: ' + arg) + throw new Error('Value of argument must be true or false: ' + argument) } } const peek = it.peek() @@ -112,15 +112,25 @@ function getBooleanValue( } function getValue( - it: IIterator, + it: Iterator, argument: string, isPositional: boolean, ): string { return isPositional ? argument : it.next() } +function getNumberValue( + it: Iterator, + argument: string, + isPositional: boolean, +): number { + const num = parseInt(getValue(it, argument, isPositional), 10) + assert(!isNaN(num), 'Value of argument must be a number: ' + argument) + return num +} + function extractArray( - it: IIterator, + it: Iterator, argument: string, isPositional: boolean, n: TNumberOfArgs = N_DEFAULT_VALUE, @@ -157,7 +167,7 @@ function padRight(str: string, chars: number) { return str } -function help(command: string, config: IArgsConfig, desc: string = '') { +function help(command: string, config: ArgsConfig, desc = '') { const keys = Object.keys(config) function getArrayHelp( @@ -184,7 +194,7 @@ function help(command: string, config: IArgsConfig, desc: string = '') { return required ? array.join(' ') : `[${array.join(' ')}]` } - function getDescription(argConfig: IArgument): string { + function getDescription(argConfig: Argument): string { const samples = [] if (argConfig.required) { samples.push('required') @@ -219,7 +229,7 @@ function help(command: string, config: IArgsConfig, desc: string = '') { .filter(k => config[k].positional) .map(argument => { const argConfig = config[argument] - const {type, required, n} = argConfig + const {type} = argConfig const nameAndType = ` ${argument.toUpperCase()} ${type}` const description = getDescription(argConfig) return getPaddedName(nameAndType, description) @@ -264,17 +274,17 @@ function help(command: string, config: IArgsConfig, desc: string = '') { export function arg( type: T, - config: IArgParam = {}, -): IArgument { + config: ArgParam = {}, +): Argument { return { ...config, type, } } -export function argparse( +export function argparse( config: T, - description: string = '', + description = '', exit: () => void = () => process.exit(), /* tslint:disable-next-line */ log: (message: string) => void = console.log.bind(console), @@ -283,7 +293,7 @@ export function argparse( parse(args: string[]): TArgs { const command = args[0] args = args.slice(1) - const result: any = {} + const result: any = {} // eslint-disable-line const it = iterate(args) const aliases: Record = {} @@ -341,8 +351,10 @@ export function argparse( function getNextPositional(argument: string): string { const p = positional.shift() - assert(!!p, 'Unknown positional argument: ' + argument) - return p! + if (!p) { + throw createError('Unknown positional argument: ' + argument) + } + return p } let onlyPositionals = false @@ -364,7 +376,7 @@ export function argparse( log(help(command, config, description)) exit() // should never reach this in real life - return null as any + return null as any // eslint-disable-line } assert(!!argConfig, 'Unknown argument: ' + argument) delete requiredArgs[argName] @@ -379,10 +391,7 @@ export function argparse( it, argument, isPositional, argConfig.n) break case 'number': - const num = parseInt(getValue(it, argument, isPositional), 10) - assert(!isNaN(num), - 'Value of argument must be a number: ' + argument) - result[argName] = num + result[argName] = getNumberValue(it, argument, isPositional) break case 'boolean': result[argName] = getBooleanValue(it, argument, isPositional) diff --git a/packages/scripts/src/TCommand.ts b/packages/scripts/src/TCommand.ts index 7381214..b5b4b13 100644 --- a/packages/scripts/src/TCommand.ts +++ b/packages/scripts/src/TCommand.ts @@ -1 +1 @@ -export type TCommand = (...argv: string[]) => Promise +export type TCommand = (...argv: string[]) => unknown diff --git a/packages/scripts/src/index.ts b/packages/scripts/src/index.ts index ae5ea12..3ff5b7c 100644 --- a/packages/scripts/src/index.ts +++ b/packages/scripts/src/index.ts @@ -5,19 +5,19 @@ import {argparse, arg} from '@rondo.dev/argparse' import {resolve} from './resolve' async function run( - args: any, commands: object, exit: (code: number) => void, + commandName: string, + commandArgs: string[], + commands: Record, + exit: (code: number) => void, ) { - const p = './scripts' - const module = await import(p) - const commandName = args.command if (!(commandName in commands)) { log.info( 'Invalid command! Use the --help argument to see a list of commands') exit(1) return } - const command = (commands as any)[commandName] as TCommand - await command(args.command, ...args.args) + const command = commands[commandName] + await command(commandName, ...commandArgs) } async function start( @@ -42,7 +42,7 @@ async function start( let args: ReturnType | null = null try { args = parse(argv) - await run(args, commands, exit) + await run(args.command, args.args, commands, exit) } catch (err) { log.error((args && args.debug ? err.stack : err.message)) exit(1) diff --git a/packages/scripts/src/log.ts b/packages/scripts/src/log.ts index bcb150d..915d428 100644 --- a/packages/scripts/src/log.ts +++ b/packages/scripts/src/log.ts @@ -1,9 +1,9 @@ import {format} from 'util' -export function error(message: string, ...values: any[]) { +export function error(message: string, ...values: Array) { process.stderr.write(format(message, ...values) + '\n') } -export function info(message: string, ...values: any[]) { +export function info(message: string, ...values: Array) { process.stdout.write(format(message, ...values) + '\n') } diff --git a/packages/scripts/src/modules.test.ts b/packages/scripts/src/modules.test.ts index 05cd18f..6c322a3 100644 --- a/packages/scripts/src/modules.test.ts +++ b/packages/scripts/src/modules.test.ts @@ -1,5 +1,4 @@ import {getPathVariable, getPathSeparator, findNodeModules} from './modules' -import {resolve} from 'path' import {platform} from 'os' describe('modules', () => { diff --git a/packages/scripts/src/resolve.ts b/packages/scripts/src/resolve.ts index c60774d..68c9ad4 100644 --- a/packages/scripts/src/resolve.ts +++ b/packages/scripts/src/resolve.ts @@ -1,8 +1,11 @@ import * as commands from './scripts' import {join} from 'path' +import { TCommand } from './TCommand' -export async function resolve(cwd = process.cwd()) { - let extraScripts: object = {} +export type AvailableCommands = typeof commands & Record + +export async function resolve(cwd = process.cwd()): Promise { + let extraScripts: Record = {} try { extraScripts = await import(join(cwd, './src/scripts')) } catch (err) { diff --git a/packages/scripts/src/scripts/add.ts b/packages/scripts/src/scripts/add.ts index bb75d5b..d2d77f8 100644 --- a/packages/scripts/src/scripts/add.ts +++ b/packages/scripts/src/scripts/add.ts @@ -2,7 +2,20 @@ import * as fs from 'fs' import * as log from '../log' import * as path from 'path' import {argparse, arg} from '@rondo.dev/argparse' -import {run} from '../run' + +async function walk( + file: string, + files: string[] = [], +): Promise { + files.push(file) + const stat = fs.statSync(file) + if (stat.isDirectory()) { + for (const f of fs.readdirSync(file)) { + walk(path.join(file, f), files) + } + } + return files +} export async function add(...argv: string[]) { const {parse} = argparse({ @@ -45,22 +58,8 @@ export async function add(...argv: string[]) { log.info('Update main package.json') const pkgFile = path.join(process.cwd(), 'package.json') - const pkg = require(pkgFile) + const pkg = require(pkgFile) // eslint-disable-line pkg.dependencies = pkg.dependencies || {} pkg.dependencies[libraryName] = `file:packages/${args.name}` fs.writeFileSync(pkgFile, JSON.stringify(pkg, null, ' ')) } - -export async function walk( - file: string, - files: string[] = [], -): Promise { - files.push(file) - const stat = fs.statSync(file) - if (stat.isDirectory()) { - for (const f of fs.readdirSync(file)) { - walk(path.join(file, f), files) - } - } - return files -} diff --git a/packages/scripts/src/scripts/build.ts b/packages/scripts/src/scripts/build.ts index 71ea0af..edeb3bc 100644 --- a/packages/scripts/src/scripts/build.ts +++ b/packages/scripts/src/scripts/build.ts @@ -1,5 +1,4 @@ import * as fs from 'fs' -import * as log from '../log' import * as p from 'path' import {argparse, arg} from '@rondo.dev/argparse' import {findNodeModules} from '../modules' @@ -100,7 +99,7 @@ function findTsConfig(file: string): string { return '' } -async function browserify(path: string = '.') { +async function browserify(path = '.') { // mkdirSync(join(path, 'build'), {recursive: true}) await run('browserify', [ join(path, 'esm', 'index.js'), @@ -112,7 +111,7 @@ async function browserify(path: string = '.') { ]) } -async function uglify(path: string = '.') { +async function uglify(path = '.') { await run('uglifyjs', [ '--compress', '--mangle', @@ -205,5 +204,5 @@ export async function frontend(...argv: string[]) { watchJs(path), watchCss(path), ] - return Promise.all(promises) + await Promise.all(promises) } diff --git a/packages/scripts/src/scripts/intergen.sample.ts b/packages/scripts/src/scripts/intergen.sample.ts index d10ccdb..c4dc67e 100644 --- a/packages/scripts/src/scripts/intergen.sample.ts +++ b/packages/scripts/src/scripts/intergen.sample.ts @@ -17,18 +17,18 @@ export class Name { lastName!: string } -export interface IYear { +export interface Year { year: number } -export interface ITyped { +export interface TypedValue { value: T } type AorB = 'A' | 'B' -interface IB { a: number } +interface B { a: number } /* tslint:disable-next-line */ -type Param = {t: T, b: IB} +type Param = {t: T, b: B} export class Person { readonly name!: Name @@ -40,7 +40,7 @@ export class Person { b: string } age?: number - birthyear: IYear | null = null + birthyear: Year | null = null stringAndNumberTuple!: [string, number] } @@ -53,9 +53,9 @@ export class Company { } export class Typed { - a!: ITyped - b!: ITyped - c!: ITyped - d!: ITyped | ITyped + a!: TypedValue + b!: TypedValue + c!: TypedValue + d!: TypedValue | TypedValue e!: Param } diff --git a/packages/scripts/src/scripts/intergen.ts b/packages/scripts/src/scripts/intergen.ts index f405615..130b438 100644 --- a/packages/scripts/src/scripts/intergen.ts +++ b/packages/scripts/src/scripts/intergen.ts @@ -21,7 +21,7 @@ function filterInvisibleProperties(type: ts.Symbol): boolean { return !(flags & ts.ModifierFlags.NonPublicAccessibilityModifier) } -interface IClassProperty { +interface ClassProperty { name: string type: ts.Type relevantTypes: ts.Type[] @@ -29,13 +29,13 @@ interface IClassProperty { optional: boolean } -interface IClassDefinition { +interface ClassDefinition { name: string type: ts.Type typeParameters: ts.TypeParameter[] relevantTypeParameters: ts.Type[] allRelevantTypes: ts.Type[] - properties: IClassProperty[] + properties: ClassProperty[] } /* @@ -64,7 +64,7 @@ export function intergen(...argv: string[]): string { output: arg('string', {alias: 'o', default: '-'}), }).parse(argv) - function debug(m: string, ...meta: any[]) { + function debug(m: string, ...meta: Array) { if (args.debug) { error(m, ...meta) } @@ -81,7 +81,7 @@ export function intergen(...argv: string[]): string { // Get the checker, we will use it to find more about classes const checker = program.getTypeChecker() - const classDefs: IClassDefinition[] = [] + const classDefs: ClassDefinition[] = [] function typeToString(type: ts.Type): string { return checker.typeToString(type) @@ -195,7 +195,7 @@ export function intergen(...argv: string[]): string { */ function isNodeExported(node: ts.Node): boolean { return ( - (ts.getCombinedModifierFlags(node as any) & + (ts.getCombinedModifierFlags(node as ts.Declaration) & ts.ModifierFlags.Export) !== 0 // (!!node.parent && node.parent.kind === ts.SyntaxKind.SourceFile) ) @@ -215,7 +215,7 @@ export function intergen(...argv: string[]): string { handleType(type) } - const typeDefinitions: Map = new Map() + const typeDefinitions: Map = new Map() function handleType(type: ts.Type) { if (typeDefinitions.has(type)) { return @@ -255,7 +255,7 @@ export function intergen(...argv: string[]): string { const filterClassTypeParameters = (t: ts.Type) => typeParameters.every(tp => tp !== t) - const classProperties: IClassProperty[] = properties + const classProperties: ClassProperty[] = properties .filter(filterInvisibleProperties) .map(p => { const vd = p.valueDeclaration @@ -289,7 +289,7 @@ export function intergen(...argv: string[]): string { allRelevantTypes.push(...relevantTypeParameters) - const classDef: IClassDefinition = { + const classDef: ClassDefinition = { name: typeToString(type), type, // name: symbol.getName(), @@ -345,11 +345,11 @@ export function intergen(...argv: string[]): string { for (const classDef of classDefs) { setTypeName(classDef.type, nameMappings) for (const t of classDef.allRelevantTypes) { - setTypeName(classDef.type, nameMappings) + setTypeName(t, nameMappings) } } - function createInterface(classDef: IClassDefinition): string { + function createInterface(classDef: ClassDefinition): string { const name = nameMappings.get(classDef.type)! const start = `export interface ${name} {` const properties = classDef.properties.map(p => { diff --git a/packages/scripts/src/scripts/syncEsmConfig.ts b/packages/scripts/src/scripts/syncEsmConfig.ts index 02ac378..c83990f 100644 --- a/packages/scripts/src/scripts/syncEsmConfig.ts +++ b/packages/scripts/src/scripts/syncEsmConfig.ts @@ -5,9 +5,8 @@ import {info} from '../log' const TSCONFIG_FILENAME = 'tsconfig.json' const TSCONFIG_ESM_FILENAME = 'tsconfig.esm.json' -const PKG_DIRNAME = 'packages' -interface IRef { +interface Ref { path: string } @@ -20,7 +19,7 @@ export async function syncEsmConfig(...argv: string[]) { const pkgDir = args.packages - const projects = fs.readdirSync(pkgDir) + fs.readdirSync(pkgDir) .filter(file => { const stat = fs.lstatSync(path.join(pkgDir, file)) return stat.isDirectory() @@ -29,7 +28,7 @@ export async function syncEsmConfig(...argv: string[]) { .filter(file => fs.existsSync(file)) .forEach(file => { const tsconfig = JSON.parse(fs.readFileSync(file, 'utf8')) - const references = ((tsconfig.references || []) as IRef[]) + const references = ((tsconfig.references || []) as Ref[]) .map(ref => ({ ...ref, path: path.join(ref.path, TSCONFIG_ESM_FILENAME), diff --git a/packages/scripts/src/scripts/update.test.ts b/packages/scripts/src/scripts/update.test.ts index d331bc0..0b900e2 100644 --- a/packages/scripts/src/scripts/update.test.ts +++ b/packages/scripts/src/scripts/update.test.ts @@ -4,7 +4,7 @@ jest.mock('../log') import cp from 'child_process' import * as fs from 'fs' -import {update, IOutdated} from './update' +import {update, Outdated} from './update' describe('update', () => { @@ -15,7 +15,7 @@ describe('update', () => { const writeMock = fs.writeFileSync as jest.Mock const cpMock = cp.execFileSync as unknown as jest.Mock - let outdated: Record = {} + let outdated: Record = {} beforeEach(() => { outdated = {} diff --git a/packages/scripts/src/scripts/update.ts b/packages/scripts/src/scripts/update.ts index 92cb77a..3fc45d8 100644 --- a/packages/scripts/src/scripts/update.ts +++ b/packages/scripts/src/scripts/update.ts @@ -4,18 +4,18 @@ import cp from 'child_process' import {argparse, arg} from '@rondo.dev/argparse' import {info} from '../log' -export interface IOutdated { +export interface Outdated { wanted: string latest: string location: string } -export interface IPackage { +export interface Package { dependencies?: Record devDependencies?: Record } -function findOutdated(cwd: string): Record { +function findOutdated(cwd: string): Record { try { const result = cp.execFileSync('npm', ['outdated', '--json'], { cwd, @@ -28,6 +28,27 @@ function findOutdated(cwd: string): Record { } } +function updateDependency( + pkg: Package, + key: 'dependencies' | 'devDependencies', + name: string, + prefix: string, + version: Outdated, +): Package { + const deps = pkg[key] + if (!deps || !deps[name] || version.wanted === version.latest) { + return pkg + } + info(' [%s] %s %s ==> %s', key, name, version.wanted, version.latest) + return { + ...pkg, + [key]: { + ...deps, + [name]: prefix + version.latest, + }, + } +} + export async function update(...argv: string[]) { const {parse} = argparse({ dirs: arg('string[]', {positional: true, default: ['.'], n: '+'}), @@ -41,8 +62,8 @@ export async function update(...argv: string[]) { const outdatedByName = findOutdated(dir) const pkgFile = path.join(dir, 'package.json') - const pkg: IPackage = JSON.parse(fs.readFileSync(pkgFile, 'utf8')) - let pkgUpdate: IPackage = pkg + const pkg: Package = JSON.parse(fs.readFileSync(pkgFile, 'utf8')) + let pkgUpdate: Package = pkg // tslint:disable-next-line for (const name in outdatedByName) { @@ -64,24 +85,3 @@ export async function update(...argv: string[]) { info('Done! Do not forget to run npm install!') } } - -function updateDependency( - pkg: IPackage, - key: 'dependencies' | 'devDependencies', - name: string, - prefix: string, - version: IOutdated, -): IPackage { - const deps = pkg[key] - if (!deps || !deps[name] || version.wanted === version.latest) { - return pkg - } - info(' [%s] %s %s ==> %s', key, name, version.wanted, version.latest) - return { - ...pkg, - [key]: { - ...deps, - [name]: prefix + version.latest, - }, - } -} diff --git a/packages/tasq/src/Deferred.test.ts b/packages/tasq/src/Deferred.test.ts index ff3b187..ab12027 100644 --- a/packages/tasq/src/Deferred.test.ts +++ b/packages/tasq/src/Deferred.test.ts @@ -1,9 +1,9 @@ -import {Deferred} from './Deferred' +import {DeferredPromise} from './Deferred' describe('Deferred', () => { it('allows promise to be resolved outside of the callback', async () => { - const d = new Deferred() + const d = new DeferredPromise() d.resolve(3) const result = await d.promise expect(result).toBe(3) diff --git a/packages/tasq/src/Deferred.ts b/packages/tasq/src/Deferred.ts index 59b52dc..c4acfe2 100644 --- a/packages/tasq/src/Deferred.ts +++ b/packages/tasq/src/Deferred.ts @@ -1,23 +1,23 @@ -export interface IDeferred { +export interface Deferred { resolve(result: T | PromiseLike | undefined): void reject(err: Error): void } -export class Deferred implements IDeferred { +export class DeferredPromise implements Deferred { readonly resolve: (result: T | PromiseLike | undefined) => void - readonly reject: (err: Error) => void - readonly promise: Promise + readonly reject!: (err: Error) => void + readonly promise!: Promise constructor() { - let res: any - let rej: any + let res: (result: T | PromiseLike | undefined) => void + let rej: (err: Error) => void this.promise = new Promise((resolve, reject) => { res = resolve rej = reject }) - this.resolve = res - this.reject = rej + this.resolve = res! + this.reject = rej! } } diff --git a/packages/tasq/src/Executor.ts b/packages/tasq/src/Executor.ts index 401fd13..faaa8fe 100644 --- a/packages/tasq/src/Executor.ts +++ b/packages/tasq/src/Executor.ts @@ -1,25 +1,24 @@ -import { IRequest } from './ITask' import cp from 'child_process' -import { LinkedList } from './LinkedList' +import { Request } from './Task' -export interface IExecutor { - execute(task: IRequest): Promise +export interface Executor { + execute(task: Request): Promise } -export type ExecutorFactory = () => IExecutor +export type ExecutorFactory = () => Executor -export class PromiseExecutor implements IExecutor { - constructor(readonly execute: (task: IRequest) => Promise) {} +export class PromiseExecutor implements Executor { + constructor(readonly execute: (task: Request) => Promise) {} } -export class SubprocessExecutor implements IExecutor { +export class SubprocessExecutor implements Executor { process: cp.ChildProcess constructor(protected sourceFile: string) { this.process = cp.fork(sourceFile) } - async execute(task: IRequest): Promise { + async execute(task: Request): Promise { return new Promise((resolve, reject) => { this.process.once('response_' + task.id, message => { if (message.error) { diff --git a/packages/tasq/src/ITask.ts b/packages/tasq/src/ITask.ts deleted file mode 100644 index d1e74be..0000000 --- a/packages/tasq/src/ITask.ts +++ /dev/null @@ -1,18 +0,0 @@ -export interface IRequest { - id: number - params: T -} - -export interface ISuccessMessage { - id: number - result: T - type: 'success' -} - -export interface IErrorMessage { - id: number - error: Error - type: 'error' -} - -export type TResponse = ISuccessMessage | IErrorMessage diff --git a/packages/tasq/src/LinkedList.ts b/packages/tasq/src/LinkedList.ts index 7bea504..f2110f6 100644 --- a/packages/tasq/src/LinkedList.ts +++ b/packages/tasq/src/LinkedList.ts @@ -1,22 +1,22 @@ -export interface IQueue { +export interface Queue { push(...t: T[]): void shift(): T | undefined peek(): T | undefined toArray(): T[] } -interface INode { +interface Node { value: T - next?: INode + next?: Node } -export interface IIterator { +export interface Iterator { hasNext(): boolean next(): T | undefined } -export class LinkedListIterator implements IIterator { - constructor(protected node: INode | undefined) { +export class LinkedListIterator implements Iterator { + constructor(protected node: Node | undefined) { } hasNext() { return this.node !== undefined @@ -32,15 +32,15 @@ export class LinkedListIterator implements IIterator { } } -export class LinkedList implements IQueue { +export class LinkedList implements Queue { length = 0 - protected head: INode | undefined - protected tail: INode | undefined + protected head: Node | undefined + protected tail: Node | undefined push(...t: T[]) { t.forEach(value => { - const node: INode = {value} + const node: Node = {value} if (!this.length) { this.head = this.tail = node this.length = 1 diff --git a/packages/tasq/src/Messenger.ts b/packages/tasq/src/Messenger.ts index 8b5c11e..0ceed58 100644 --- a/packages/tasq/src/Messenger.ts +++ b/packages/tasq/src/Messenger.ts @@ -1,19 +1,19 @@ -import {IExecutor} from './Executor' -import { IRequest, TResponse, IErrorMessage } from './ITask' +import {Executor} from './Executor' +import { Request, Response, ErrorMessage } from './Task' export class Messenger { - constructor(readonly executor: IExecutor) { + constructor(readonly executor: Executor) { if (!process.send) { throw new Error('Messenger can only be used from a forked subprocess') } - process.on('message', async (request: IRequest) => { + process.on('message', async (request: Request) => { try { const result: R = await this.executor.execute(request) - const response: TResponse = {id: request.id, result, type: 'success'} + const response: Response = {id: request.id, result, type: 'success'} process.send!('response_' + request.id, response) } catch (error) { - const response: IErrorMessage = {id: request.id, error, type: 'error'} + const response: ErrorMessage = {id: request.id, error, type: 'error'} process.send!('response_' + request.id, response) } }) diff --git a/packages/tasq/src/Task.ts b/packages/tasq/src/Task.ts new file mode 100644 index 0000000..0f9e5cc --- /dev/null +++ b/packages/tasq/src/Task.ts @@ -0,0 +1,18 @@ +export interface Request { + id: number + params: T +} + +export interface SuccessMessage { + id: number + result: T + type: 'success' +} + +export interface ErrorMessage { + id: number + error: Error + type: 'error' +} + +export type Response = SuccessMessage | ErrorMessage diff --git a/packages/tasq/src/TaskManager.test.ts b/packages/tasq/src/TaskManager.test.ts index 7baaf3c..ded8921 100644 --- a/packages/tasq/src/TaskManager.test.ts +++ b/packages/tasq/src/TaskManager.test.ts @@ -1,4 +1,4 @@ -import {TaskManager} from './TaskManager' +import {QueuedTaskManager} from './TaskManager' import { PromiseExecutor } from './Executor' import { getError } from '@rondo.dev/test-utils' @@ -11,7 +11,7 @@ describe('TaskManager', () => { describe('post', () => { it('posts new tasks and executes asynchronously', async () => { const results: number[] = [] - const te = new TaskManager( + const te = new QueuedTaskManager( 1, () => new PromiseExecutor(async task => { await delay(task.params) @@ -26,7 +26,7 @@ describe('TaskManager', () => { }) it('executes tasks in different order', async () => { const results: number[] = [] - const te = new TaskManager( + const te = new QueuedTaskManager( 2, () => new PromiseExecutor(async task => { await delay(task.params) @@ -43,7 +43,7 @@ describe('TaskManager', () => { it('returns promises when job posted', async () => { const results: number[] = [] - const te = new TaskManager( + const te = new QueuedTaskManager( 2, () => new PromiseExecutor(async task => { await delay(task.params) @@ -60,12 +60,12 @@ describe('TaskManager', () => { }) it('can return values from promises', async () => { - interface IParams { - a: number, - b: number, + interface Params { + a: number + b: number delay: number } - const te = new TaskManager( + const te = new QueuedTaskManager( 2, () => new PromiseExecutor(async task => { const {params} = task @@ -73,13 +73,19 @@ describe('TaskManager', () => { return params.a + params.b }), ) + const result = await te.post({ + a: 1, + b: 2, + delay: 1, + }) + expect(result).toBe(3) }) }) describe('error handling', () => { it('does not fail on error', async () => { - const tm = new TaskManager(2, + const tm = new QueuedTaskManager(2, () => new PromiseExecutor(async task => { await delay(task.params) if (task.params % 2 === 0) { diff --git a/packages/tasq/src/TaskManager.ts b/packages/tasq/src/TaskManager.ts index 3ca92bb..0b4966f 100644 --- a/packages/tasq/src/TaskManager.ts +++ b/packages/tasq/src/TaskManager.ts @@ -1,24 +1,23 @@ -import {EventEmitter} from 'events' -import {LinkedList} from './LinkedList' -import {Deferred} from './Deferred' -import { Worker } from './Worker' +import { DeferredPromise } from './Deferred' import { ExecutorFactory } from './Executor' -import { IRequest } from './ITask' +import { Request } from './Task' +import { LinkedList } from './LinkedList' +import { QueuedWorker } from './Worker' -interface ITaskEventHandler { +interface TaskEventHandler { success: () => void failure: (err: Error) => void } -export interface ITaskManager { +export interface TaskManager { post(task: T): void wait(): Promise } -export class TaskManager implements ITaskManager { - protected taskQueue = new LinkedList>() +export class QueuedTaskManager implements TaskManager { + protected taskQueue = new LinkedList>() protected workers: Set> = new Set() - protected deferredTasks = new Map>() + protected deferredTasks = new Map>() protected taskCount = 0 @@ -35,12 +34,12 @@ export class TaskManager implements ITaskManager { params, }) - const deferred = new Deferred() + const deferred = new DeferredPromise() this.deferredTasks.set(id, deferred) if (this.workers.size < this.n) { // deliberately do not use promise here - const worker = this.startWorker() + this.startWorker() } return deferred.promise @@ -52,7 +51,7 @@ export class TaskManager implements ITaskManager { } protected async startWorker() { - const promise = new Worker( + const promise = new QueuedWorker( this.createExecutor(), this.taskQueue, response => { diff --git a/packages/tasq/src/Worker.ts b/packages/tasq/src/Worker.ts index 83e7d9d..d6bf4f6 100644 --- a/packages/tasq/src/Worker.ts +++ b/packages/tasq/src/Worker.ts @@ -1,19 +1,18 @@ -import cp from 'child_process' +import { Executor } from './Executor' +import { Request, Response } from './Task' import { LinkedList } from './LinkedList' -import { IExecutor } from './Executor' -import { IRequest, TResponse } from './ITask' -export interface IWorker { +export interface Worker { start(): Promise } -export type ICallback = (result: TResponse) => void +export type Callback = (result: Response) => void -export class Worker implements IWorker { +export class QueuedWorker implements Worker { constructor( - protected executor: IExecutor, - protected taskQueue: LinkedList>, - protected callback: ICallback, + protected executor: Executor, + protected taskQueue: LinkedList>, + protected callback: Callback, ) { } diff --git a/packages/tasq/src/sample/fork-add.ts b/packages/tasq/src/sample/fork-add.ts index 222244c..201b823 100644 --- a/packages/tasq/src/sample/fork-add.ts +++ b/packages/tasq/src/sample/fork-add.ts @@ -1,9 +1,9 @@ import { Messenger } from '../Messenger' -import { IExecutor } from '../Executor' -import { IRequest } from '../ITask' +import { Executor } from '../Executor' +import { Request } from '../Task' -const executor = new (class implements IExecutor<[number, number], number> { - async execute(task: IRequest<[number, number]>) { +const executor = new (class implements Executor<[number, number], number> { + async execute(task: Request<[number, number]>) { await new Promise(resolve => { setTimeout(resolve, 1) }) diff --git a/packages/tsconfig.common.json b/packages/tsconfig.common.json index f19b9ca..5b55924 100644 --- a/packages/tsconfig.common.json +++ b/packages/tsconfig.common.json @@ -18,9 +18,6 @@ "emitDecoratorMetadata": true, "experimentalDecorators": true, "plugins": [{ - "name": "typescript-tslint-plugin", - "suppressWhileTypeErrorsPresent": true - }, { "transform": "ts-transformer-keys/transformer" }] } diff --git a/packages/validator/src/ValidationError.ts b/packages/validator/src/ValidationError.ts index debf4be..d25dc38 100644 --- a/packages/validator/src/ValidationError.ts +++ b/packages/validator/src/ValidationError.ts @@ -1,9 +1,9 @@ -import {IValidationMessage} from './IValidationMessage' +import {ValidationMessage} from './ValidationMessage' export class ValidationError extends Error { readonly name: string constructor( - readonly errors: IValidationMessage[], + readonly errors: ValidationMessage[], message?: string, readonly status: number = 400, ) { @@ -16,9 +16,11 @@ export class ValidationError extends Error { Error.captureStackTrace(this) } - static isInstanceOf(err: any): err is ValidationError { - return typeof err.status === 'number' - && typeof err.message === 'string' - && Array.isArray(err.errors) + static isInstanceOf(err: unknown): err is ValidationError { + const err2 = err as ValidationError + return err2 + && typeof err2.status === 'number' + && typeof err2.message === 'string' + && Array.isArray(err2.errors) } } diff --git a/packages/validator/src/IValidationMessage.ts b/packages/validator/src/ValidationMessage.ts similarity index 66% rename from packages/validator/src/IValidationMessage.ts rename to packages/validator/src/ValidationMessage.ts index 6beb9e4..07f71ac 100644 --- a/packages/validator/src/IValidationMessage.ts +++ b/packages/validator/src/ValidationMessage.ts @@ -1,4 +1,4 @@ -export interface IValidationMessage { +export interface ValidationMessage { readonly property: string | number | symbol readonly message: string } diff --git a/packages/validator/src/Validator.ts b/packages/validator/src/Validator.ts index afb106d..e3a2738 100644 --- a/packages/validator/src/Validator.ts +++ b/packages/validator/src/Validator.ts @@ -1,9 +1,9 @@ -import {IValidationMessage} from './IValidationMessage' +import {ValidationMessage} from './ValidationMessage' import {ValidationError} from './ValidationError' export class Validator { - readonly errors: IValidationMessage[] = [] + readonly errors: ValidationMessage[] = [] readonly entity: T constructor(entity: T | undefined) { @@ -13,7 +13,7 @@ export class Validator { this.entity = entity } - ensure(property: keyof T, value?: any): this { + ensure(property: keyof T, value?: unknown): this { if (arguments.length === 1) { if (!this.entity[property]) { this.addError(property, `The property "${property}" is invalid`) diff --git a/packages/validator/src/index.ts b/packages/validator/src/index.ts index ec3dde1..da926e3 100644 --- a/packages/validator/src/index.ts +++ b/packages/validator/src/index.ts @@ -1,4 +1,4 @@ -export * from './IValidationMessage' +export * from './ValidationMessage' export * from './ValidationError' export * from './Validator'