Install eslint and fix errors

- argparse
- scripts
- tasq
- validator
This commit is contained in:
Jerko Steiner 2019-09-15 15:57:10 +07:00
parent fb41c2ce69
commit 8c732ba91e
34 changed files with 730 additions and 302 deletions

3
.eslintignore Normal file
View File

@ -0,0 +1,3 @@
packages/*/lib
packages/*/esm
build/

32
.eslintrc.yaml Normal file
View File

@ -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

524
package-lock.json generated
View File

@ -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",

View File

@ -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",

View File

@ -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/)
})

View File

@ -18,7 +18,7 @@ export const N_DEFAULT_VALUE = 1
export type TNumberOfArgs = number | '+' | '*'
export interface IArgParam<T extends TArgTypeName> {
export interface ArgParam<T extends TArgTypeName> {
alias?: string
description?: string
default?: TArgType<T>
@ -28,26 +28,26 @@ export interface IArgParam<T extends TArgTypeName> {
n?: TNumberOfArgs
}
export interface IArgument<T extends TArgTypeName> extends IArgParam<T> {
export interface Argument<T extends TArgTypeName> extends ArgParam<T> {
type: T
}
export interface IArgsConfig {
[arg: string]: IArgument<TArgTypeName>
export interface ArgsConfig {
[arg: string]: Argument<TArgTypeName>
}
export type TArgs<T extends IArgsConfig> = {
[k in keyof T]: T[k] extends IArgument<infer A> ?
export type TArgs<T extends ArgsConfig> = {
[k in keyof T]: T[k] extends Argument<infer A> ?
TArgType<A> : never
}
interface IIterator<T> {
interface Iterator<T> {
hasNext(): boolean
next(): T
peek(): T
}
const iterate = <T>(arr: T[]): IIterator<T> => {
const iterate = <T>(arr: T[]): Iterator<T> => {
let i = -1
return {
hasNext() {
@ -86,7 +86,7 @@ function getDefaultValue(type: TArgTypeName) {
}
function getBooleanValue(
it: IIterator<string>,
it: Iterator<string>,
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<string>,
it: Iterator<string>,
argument: string,
isPositional: boolean,
): string {
return isPositional ? argument : it.next()
}
function getNumberValue(
it: Iterator<string>,
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<string>,
it: Iterator<string>,
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<TArgTypeName>): string {
function getDescription(argConfig: Argument<TArgTypeName>): 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<T extends TArgTypeName>(
type: T,
config: IArgParam<T> = {},
): IArgument<T> {
config: ArgParam<T> = {},
): Argument<T> {
return {
...config,
type,
}
}
export function argparse<T extends IArgsConfig>(
export function argparse<T extends ArgsConfig>(
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<T extends IArgsConfig>(
parse(args: string[]): TArgs<T> {
const command = args[0]
args = args.slice(1)
const result: any = {}
const result: any = {} // eslint-disable-line
const it = iterate(args)
const aliases: Record<string, string> = {}
@ -341,8 +351,10 @@ export function argparse<T extends IArgsConfig>(
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<T extends IArgsConfig>(
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<T extends IArgsConfig>(
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)

View File

@ -1 +1 @@
export type TCommand = (...argv: string[]) => Promise<void>
export type TCommand = (...argv: string[]) => unknown

View File

@ -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<string, TCommand>,
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<typeof parse> | 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)

View File

@ -1,9 +1,9 @@
import {format} from 'util'
export function error(message: string, ...values: any[]) {
export function error(message: string, ...values: Array<unknown>) {
process.stderr.write(format(message, ...values) + '\n')
}
export function info(message: string, ...values: any[]) {
export function info(message: string, ...values: Array<unknown>) {
process.stdout.write(format(message, ...values) + '\n')
}

View File

@ -1,5 +1,4 @@
import {getPathVariable, getPathSeparator, findNodeModules} from './modules'
import {resolve} from 'path'
import {platform} from 'os'
describe('modules', () => {

View File

@ -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<string, TCommand>
export async function resolve(cwd = process.cwd()): Promise<AvailableCommands> {
let extraScripts: Record<string, TCommand> = {}
try {
extraScripts = await import(join(cwd, './src/scripts'))
} catch (err) {

View File

@ -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<string[]> {
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<string[]> {
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
}

View File

@ -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)
}

View File

@ -17,18 +17,18 @@ export class Name {
lastName!: string
}
export interface IYear {
export interface Year {
year: number
}
export interface ITyped<T> {
export interface TypedValue<T> {
value: T
}
type AorB = 'A' | 'B'
interface IB { a: number }
interface B { a: number }
/* tslint:disable-next-line */
type Param<T> = {t: T, b: IB}
type Param<T> = {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, B extends 'singleVal', C = 'defVal'> {
a!: ITyped<A>
b!: ITyped<B>
c!: ITyped<C>
d!: ITyped<A> | ITyped<B>
a!: TypedValue<A>
b!: TypedValue<B>
c!: TypedValue<C>
d!: TypedValue<A> | TypedValue<B>
e!: Param<Company>
}

View File

@ -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<unknown>) {
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<ts.Type, IClassDefinition> = new Map()
const typeDefinitions: Map<ts.Type, ClassDefinition> = 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 => {

View File

@ -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),

View File

@ -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<typeof fs.writeFileSync>
const cpMock = cp.execFileSync as unknown as jest.Mock<typeof cp.execFileSync>
let outdated: Record<string, IOutdated> = {}
let outdated: Record<string, Outdated> = {}
beforeEach(() => {
outdated = {}

View File

@ -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<string, string>
devDependencies?: Record<string, string>
}
function findOutdated(cwd: string): Record<string, IOutdated> {
function findOutdated(cwd: string): Record<string, Outdated> {
try {
const result = cp.execFileSync('npm', ['outdated', '--json'], {
cwd,
@ -28,6 +28,27 @@ function findOutdated(cwd: string): Record<string, IOutdated> {
}
}
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,
},
}
}

View File

@ -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<number>()
const d = new DeferredPromise<number>()
d.resolve(3)
const result = await d.promise
expect(result).toBe(3)

View File

@ -1,23 +1,23 @@
export interface IDeferred<T> {
export interface Deferred<T> {
resolve(result: T | PromiseLike<T> | undefined): void
reject(err: Error): void
}
export class Deferred<T> implements IDeferred<T> {
export class DeferredPromise<T> implements Deferred<T> {
readonly resolve: (result: T | PromiseLike<T> | undefined) => void
readonly reject: (err: Error) => void
readonly promise: Promise<T>
readonly reject!: (err: Error) => void
readonly promise!: Promise<T>
constructor() {
let res: any
let rej: any
let res: (result: T | PromiseLike<T> | undefined) => void
let rej: (err: Error) => void
this.promise = new Promise<T>((resolve, reject) => {
res = resolve
rej = reject
})
this.resolve = res
this.reject = rej
this.resolve = res!
this.reject = rej!
}
}

View File

@ -1,25 +1,24 @@
import { IRequest } from './ITask'
import cp from 'child_process'
import { LinkedList } from './LinkedList'
import { Request } from './Task'
export interface IExecutor<T, R> {
execute(task: IRequest<T>): Promise<R>
export interface Executor<T, R> {
execute(task: Request<T>): Promise<R>
}
export type ExecutorFactory<T, R> = () => IExecutor<T, R>
export type ExecutorFactory<T, R> = () => Executor<T, R>
export class PromiseExecutor<T, R> implements IExecutor<T, R> {
constructor(readonly execute: (task: IRequest<T>) => Promise<R>) {}
export class PromiseExecutor<T, R> implements Executor<T, R> {
constructor(readonly execute: (task: Request<T>) => Promise<R>) {}
}
export class SubprocessExecutor<T, R> implements IExecutor<T, R> {
export class SubprocessExecutor<T, R> implements Executor<T, R> {
process: cp.ChildProcess
constructor(protected sourceFile: string) {
this.process = cp.fork(sourceFile)
}
async execute(task: IRequest<T>): Promise<R> {
async execute(task: Request<T>): Promise<R> {
return new Promise((resolve, reject) => {
this.process.once('response_' + task.id, message => {
if (message.error) {

View File

@ -1,18 +0,0 @@
export interface IRequest<T> {
id: number
params: T
}
export interface ISuccessMessage<T> {
id: number
result: T
type: 'success'
}
export interface IErrorMessage {
id: number
error: Error
type: 'error'
}
export type TResponse<T> = ISuccessMessage<T> | IErrorMessage

View File

@ -1,22 +1,22 @@
export interface IQueue<T> {
export interface Queue<T> {
push(...t: T[]): void
shift(): T | undefined
peek(): T | undefined
toArray(): T[]
}
interface INode<T> {
interface Node<T> {
value: T
next?: INode<T>
next?: Node<T>
}
export interface IIterator<T> {
export interface Iterator<T> {
hasNext(): boolean
next(): T | undefined
}
export class LinkedListIterator<T> implements IIterator<T> {
constructor(protected node: INode<T> | undefined) {
export class LinkedListIterator<T> implements Iterator<T> {
constructor(protected node: Node<T> | undefined) {
}
hasNext() {
return this.node !== undefined
@ -32,15 +32,15 @@ export class LinkedListIterator<T> implements IIterator<T> {
}
}
export class LinkedList<T> implements IQueue<T> {
export class LinkedList<T> implements Queue<T> {
length = 0
protected head: INode<T> | undefined
protected tail: INode<T> | undefined
protected head: Node<T> | undefined
protected tail: Node<T> | undefined
push(...t: T[]) {
t.forEach(value => {
const node: INode<T> = {value}
const node: Node<T> = {value}
if (!this.length) {
this.head = this.tail = node
this.length = 1

View File

@ -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<T, R> {
constructor(readonly executor: IExecutor<T, R>) {
constructor(readonly executor: Executor<T, R>) {
if (!process.send) {
throw new Error('Messenger can only be used from a forked subprocess')
}
process.on('message', async (request: IRequest<T>) => {
process.on('message', async (request: Request<T>) => {
try {
const result: R = await this.executor.execute(request)
const response: TResponse<R> = {id: request.id, result, type: 'success'}
const response: Response<R> = {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)
}
})

18
packages/tasq/src/Task.ts Normal file
View File

@ -0,0 +1,18 @@
export interface Request<T> {
id: number
params: T
}
export interface SuccessMessage<T> {
id: number
result: T
type: 'success'
}
export interface ErrorMessage {
id: number
error: Error
type: 'error'
}
export type Response<T> = SuccessMessage<T> | ErrorMessage

View File

@ -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<number, void>(
const te = new QueuedTaskManager<number, void>(
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<number, void>(
const te = new QueuedTaskManager<number, void>(
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<number, void>(
const te = new QueuedTaskManager<number, void>(
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<IParams, number>(
const te = new QueuedTaskManager<Params, number>(
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<number, void>(2,
const tm = new QueuedTaskManager<number, void>(2,
() => new PromiseExecutor(async task => {
await delay(task.params)
if (task.params % 2 === 0) {

View File

@ -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<T> {
export interface TaskManager<T> {
post(task: T): void
wait(): Promise<void>
}
export class TaskManager<T, R> implements ITaskManager<T> {
protected taskQueue = new LinkedList<IRequest<T>>()
export class QueuedTaskManager<T, R> implements TaskManager<T> {
protected taskQueue = new LinkedList<Request<T>>()
protected workers: Set<Promise<void>> = new Set()
protected deferredTasks = new Map<number, Deferred<R>>()
protected deferredTasks = new Map<number, DeferredPromise<R>>()
protected taskCount = 0
@ -35,12 +34,12 @@ export class TaskManager<T, R> implements ITaskManager<T> {
params,
})
const deferred = new Deferred<R>()
const deferred = new DeferredPromise<R>()
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<T, R> implements ITaskManager<T> {
}
protected async startWorker() {
const promise = new Worker(
const promise = new QueuedWorker(
this.createExecutor(),
this.taskQueue,
response => {

View File

@ -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<T> {
export interface Worker<T> {
start(): Promise<void>
}
export type ICallback<R> = (result: TResponse<R>) => void
export type Callback<R> = (result: Response<R>) => void
export class Worker<T, R> implements IWorker<T> {
export class QueuedWorker<T, R> implements Worker<T> {
constructor(
protected executor: IExecutor<T, R>,
protected taskQueue: LinkedList<IRequest<T>>,
protected callback: ICallback<R>,
protected executor: Executor<T, R>,
protected taskQueue: LinkedList<Request<T>>,
protected callback: Callback<R>,
) {
}

View File

@ -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)
})

View File

@ -18,9 +18,6 @@
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"plugins": [{
"name": "typescript-tslint-plugin",
"suppressWhileTypeErrorsPresent": true
}, {
"transform": "ts-transformer-keys/transformer"
}]
}

View File

@ -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)
}
}

View File

@ -1,4 +1,4 @@
export interface IValidationMessage {
export interface ValidationMessage {
readonly property: string | number | symbol
readonly message: string
}

View File

@ -1,9 +1,9 @@
import {IValidationMessage} from './IValidationMessage'
import {ValidationMessage} from './ValidationMessage'
import {ValidationError} from './ValidationError'
export class Validator<T> {
readonly errors: IValidationMessage[] = []
readonly errors: ValidationMessage[] = []
readonly entity: T
constructor(entity: T | undefined) {
@ -13,7 +13,7 @@ export class Validator<T> {
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`)

View File

@ -1,4 +1,4 @@
export * from './IValidationMessage'
export * from './ValidationMessage'
export * from './ValidationError'
export * from './Validator'