diff --git a/package-lock.json b/package-lock.json index 24d922cb..5dc42a76 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,26 @@ "typescript": "^5.0.4" } }, + "node_modules/@75lb/deep-merge": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@75lb/deep-merge/-/deep-merge-1.1.1.tgz", + "integrity": "sha512-xvgv6pkMGBA6GwdyJbNAnDmfAIR/DfWhrj9jgWh3TY7gRm3KO46x/GPjRg6wJ0nOepwqrNxFfojebh0Df4h4Tw==", + "dependencies": { + "lodash.assignwith": "^4.2.0", + "typical": "^7.1.1" + }, + "engines": { + "node": ">=12.17" + } + }, + "node_modules/@75lb/deep-merge/node_modules/typical": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz", + "integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==", + "engines": { + "node": ">=12.17" + } + }, "node_modules/@ampproject/remapping": { "version": "2.2.1", "dev": true, @@ -610,6 +630,10 @@ "resolved": "packages/browser", "link": true }, + "node_modules/@backtrace/javascript-cli": { + "resolved": "tools/cli", + "link": true + }, "node_modules/@backtrace/node": { "resolved": "packages/node", "link": true @@ -1334,9 +1358,8 @@ }, "node_modules/@types/archiver": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/@types/archiver/-/archiver-5.3.2.tgz", - "integrity": "sha512-IctHreBuWE5dvBDz/0WeKtyVKVRs4h75IblxOACL92wU66v+HGAfEYAOyXkOFphvRJMhuXdI9huDXpX0FC6lCw==", "dev": true, + "license": "MIT", "dependencies": { "@types/readdir-glob": "*" } @@ -1383,11 +1406,21 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/command-line-args": { + "version": "5.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/command-line-usage": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/command-line-usage/-/command-line-usage-5.0.2.tgz", + "integrity": "sha512-n7RlEEJ+4x4TS7ZQddTmNSxP+zziEG0TNsMfiRIxcIVXt71ENJ9ojeXmGO3wPoTdn7pJcU2xc3CJYMktNT6DPg==", + "dev": true + }, "node_modules/@types/decompress": { "version": "4.2.4", - "resolved": "https://registry.npmjs.org/@types/decompress/-/decompress-4.2.4.tgz", - "integrity": "sha512-/C8kTMRTNiNuWGl5nEyKbPiMv6HA+0RbEXzFhFBEzASM6+oa4tJro9b8nj7eRlOFfuLdzUU+DS/GPDlvvzMOhA==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -1503,9 +1536,8 @@ }, "node_modules/@types/readdir-glob": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/readdir-glob/-/readdir-glob-1.1.1.tgz", - "integrity": "sha512-ImM6TmoF8bgOwvehGviEj3tRdRBbQujr1N+0ypaln/GWjaerOB26jb93vsRHmdMtvVQZQebOlqt2HROark87mQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -2137,7 +2169,6 @@ }, "node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -2168,8 +2199,7 @@ }, "node_modules/archiver": { "version": "5.3.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.1.tgz", - "integrity": "sha512-8KyabkmbYrH+9ibcTScQ1xCJC/CGcugdVIwB+53f5sZziXgwUh3iXlAlANMxcZyDEfTHMe6+Z5FofV8nopXP7w==", + "license": "MIT", "dependencies": { "archiver-utils": "^2.1.0", "async": "^3.2.3", @@ -2185,8 +2215,7 @@ }, "node_modules/archiver-utils": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", + "license": "MIT", "dependencies": { "glob": "^7.1.4", "graceful-fs": "^4.2.0", @@ -2205,8 +2234,7 @@ }, "node_modules/archiver-utils/node_modules/glob": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -2224,8 +2252,7 @@ }, "node_modules/archiver/node_modules/readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -2272,6 +2299,13 @@ "node": ">=0.10.0" } }, + "node_modules/array-back": { + "version": "3.1.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/array-buffer-byte-length": { "version": "1.0.0", "dev": true, @@ -2400,8 +2434,7 @@ }, "node_modules/async": { "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + "license": "MIT" }, "node_modules/async-each": { "version": "1.0.6", @@ -2596,8 +2629,7 @@ }, "node_modules/bl": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -2606,8 +2638,6 @@ }, "node_modules/bl/node_modules/buffer": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "funding": [ { "type": "github", @@ -2622,6 +2652,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -2629,8 +2660,7 @@ }, "node_modules/bl/node_modules/readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -2811,9 +2841,8 @@ }, "node_modules/buffer-alloc": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", "dev": true, + "license": "MIT", "dependencies": { "buffer-alloc-unsafe": "^1.1.0", "buffer-fill": "^1.0.0" @@ -2821,23 +2850,20 @@ }, "node_modules/buffer-alloc-unsafe": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/buffer-crc32": { "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "license": "MIT", "engines": { "node": "*" } }, "node_modules/buffer-fill": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/buffer-from": { "version": "1.1.2", @@ -2990,7 +3016,6 @@ }, "node_modules/chalk": { "version": "4.1.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -3003,6 +3028,20 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chalk-template": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz", + "integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==", + "dependencies": { + "chalk": "^4.1.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/chalk-template?sponsor=1" + } + }, "node_modules/char-regex": { "version": "1.0.2", "dev": true, @@ -3268,7 +3307,6 @@ }, "node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -3279,7 +3317,6 @@ }, "node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, "node_modules/colorette": { @@ -3297,6 +3334,49 @@ "node": ">= 0.8" } }, + "node_modules/command-line-args": { + "version": "5.2.1", + "license": "MIT", + "dependencies": { + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/command-line-usage": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-7.0.1.tgz", + "integrity": "sha512-NCyznE//MuTjwi3y84QVUGEOT+P5oto1e1Pk/jFPVdPPfsG03qpTIl3yw6etR+v73d0lXsoojRpvbru2sqePxQ==", + "dependencies": { + "array-back": "^6.2.2", + "chalk-template": "^0.4.0", + "table-layout": "^3.0.0", + "typical": "^7.1.1" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/command-line-usage/node_modules/array-back": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", + "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", + "engines": { + "node": ">=12.17" + } + }, + "node_modules/command-line-usage/node_modules/typical": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz", + "integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==", + "engines": { + "node": ">=12.17" + } + }, "node_modules/commander": { "version": "2.20.3", "license": "MIT" @@ -3313,8 +3393,7 @@ }, "node_modules/compress-commons": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz", - "integrity": "sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==", + "license": "MIT", "dependencies": { "buffer-crc32": "^0.2.13", "crc32-stream": "^4.0.2", @@ -3327,8 +3406,7 @@ }, "node_modules/compress-commons/node_modules/readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -3427,8 +3505,7 @@ }, "node_modules/crc-32": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "license": "Apache-2.0", "bin": { "crc32": "bin/crc32.njs" }, @@ -3438,8 +3515,7 @@ }, "node_modules/crc32-stream": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.2.tgz", - "integrity": "sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==", + "license": "MIT", "dependencies": { "crc-32": "^1.2.0", "readable-stream": "^3.4.0" @@ -3450,8 +3526,7 @@ }, "node_modules/crc32-stream/node_modules/readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -3609,9 +3684,8 @@ }, "node_modules/decompress": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", - "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==", "dev": true, + "license": "MIT", "dependencies": { "decompress-tar": "^4.0.0", "decompress-tarbz2": "^4.0.0", @@ -3628,9 +3702,8 @@ }, "node_modules/decompress-tar": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", - "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", "dev": true, + "license": "MIT", "dependencies": { "file-type": "^5.2.0", "is-stream": "^1.1.0", @@ -3642,9 +3715,8 @@ }, "node_modules/decompress-tar/node_modules/bl": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", - "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", "dev": true, + "license": "MIT", "dependencies": { "readable-stream": "^2.3.5", "safe-buffer": "^5.1.1" @@ -3652,18 +3724,16 @@ }, "node_modules/decompress-tar/node_modules/is-stream": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/decompress-tar/node_modules/tar-stream": { "version": "1.6.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", - "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", "dev": true, + "license": "MIT", "dependencies": { "bl": "^1.0.0", "buffer-alloc": "^1.2.0", @@ -3679,9 +3749,8 @@ }, "node_modules/decompress-tarbz2": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", - "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", "dev": true, + "license": "MIT", "dependencies": { "decompress-tar": "^4.1.0", "file-type": "^6.1.0", @@ -3695,27 +3764,24 @@ }, "node_modules/decompress-tarbz2/node_modules/file-type": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", - "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/decompress-tarbz2/node_modules/is-stream": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/decompress-targz": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", - "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", "dev": true, + "license": "MIT", "dependencies": { "decompress-tar": "^4.1.1", "file-type": "^5.2.0", @@ -3727,18 +3793,16 @@ }, "node_modules/decompress-targz/node_modules/is-stream": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/decompress-unzip": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", - "integrity": "sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw==", "dev": true, + "license": "MIT", "dependencies": { "file-type": "^3.8.0", "get-stream": "^2.2.0", @@ -3751,18 +3815,16 @@ }, "node_modules/decompress-unzip/node_modules/file-type": { "version": "3.9.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/decompress-unzip/node_modules/get-stream": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", - "integrity": "sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==", "dev": true, + "license": "MIT", "dependencies": { "object-assign": "^4.0.1", "pinkie-promise": "^2.0.0" @@ -3773,18 +3835,16 @@ }, "node_modules/decompress-unzip/node_modules/pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/decompress/node_modules/make-dir": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", "dev": true, + "license": "MIT", "dependencies": { "pify": "^3.0.0" }, @@ -3794,18 +3854,16 @@ }, "node_modules/decompress/node_modules/make-dir/node_modules/pify": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/decompress/node_modules/pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -4916,9 +4974,8 @@ }, "node_modules/fd-slicer": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", "dev": true, + "license": "MIT", "dependencies": { "pend": "~1.2.0" } @@ -4941,9 +4998,8 @@ }, "node_modules/file-type": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", - "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -5059,6 +5115,16 @@ "semver": "bin/semver" } }, + "node_modules/find-replace": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "array-back": "^3.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/find-up": { "version": "5.0.0", "dev": true, @@ -5198,8 +5264,7 @@ }, "node_modules/fs-constants": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + "license": "MIT" }, "node_modules/fs-write-stream-atomic": { "version": "1.0.10", @@ -6002,9 +6067,8 @@ }, "node_modules/is-natural-number": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", - "integrity": "sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/is-negative-zero": { "version": "2.0.2", @@ -7028,8 +7092,7 @@ }, "node_modules/lazystream": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", - "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "license": "MIT", "dependencies": { "readable-stream": "^2.0.5" }, @@ -7112,25 +7175,30 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.assignwith": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz", + "integrity": "sha512-ZznplvbvtjK2gMvnQ1BR/zqPFZmS6jbK4p+6Up4xcRYA7yMIwxHCfbTcrYxXKzzqLsQ05eJPVznEW3tuwV7k1g==" + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "license": "MIT" + }, "node_modules/lodash.defaults": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==" + "license": "MIT" }, "node_modules/lodash.difference": { "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==" + "license": "MIT" }, "node_modules/lodash.flatten": { "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==" + "license": "MIT" }, "node_modules/lodash.isplainobject": { "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + "license": "MIT" }, "node_modules/lodash.memoize": { "version": "4.1.2", @@ -7144,8 +7212,7 @@ }, "node_modules/lodash.union": { "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==" + "license": "MIT" }, "node_modules/loose-envify": { "version": "1.4.0", @@ -7976,9 +8043,8 @@ }, "node_modules/pend": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/picocolors": { "version": "1.0.0", @@ -8005,18 +8071,16 @@ }, "node_modules/pinkie": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/pinkie-promise": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", "dev": true, + "license": "MIT", "dependencies": { "pinkie": "^2.0.0" }, @@ -8376,24 +8440,21 @@ }, "node_modules/readdir-glob": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", - "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", + "license": "Apache-2.0", "dependencies": { "minimatch": "^5.1.0" } }, "node_modules/readdir-glob/node_modules/brace-expansion": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/readdir-glob/node_modules/minimatch": { "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -8703,9 +8764,8 @@ }, "node_modules/seek-bzip": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz", - "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==", "dev": true, + "license": "MIT", "dependencies": { "commander": "^2.8.1" }, @@ -9253,6 +9313,14 @@ "xtend": "^4.0.0" } }, + "node_modules/stream-read-all": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/stream-read-all/-/stream-read-all-3.0.1.tgz", + "integrity": "sha512-EWZT9XOceBPlVJRrYcykW8jyRSZYbkb/0ZK36uLEmoWVO5gxBOnntNTseNzfREsqxqdfEGQrD8SXQ3QWbBmq8A==", + "engines": { + "node": ">=10" + } + }, "node_modules/stream-shift": { "version": "1.0.1", "dev": true, @@ -9412,9 +9480,8 @@ }, "node_modules/strip-dirs": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", - "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", "dev": true, + "license": "MIT", "dependencies": { "is-natural-number": "^4.0.1" } @@ -9440,7 +9507,6 @@ }, "node_modules/supports-color": { "version": "7.2.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -9465,6 +9531,42 @@ "dev": true, "license": "MIT" }, + "node_modules/table-layout": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-3.0.2.tgz", + "integrity": "sha512-rpyNZYRw+/C+dYkcQ3Pr+rLxW4CfHpXjPDnG7lYhdRoUcZTUt+KEsX+94RGp/aVp/MQU35JCITv2T/beY4m+hw==", + "dependencies": { + "@75lb/deep-merge": "^1.1.1", + "array-back": "^6.2.2", + "command-line-args": "^5.2.1", + "command-line-usage": "^7.0.0", + "stream-read-all": "^3.0.1", + "typical": "^7.1.1", + "wordwrapjs": "^5.1.0" + }, + "bin": { + "table-layout": "bin/cli.js" + }, + "engines": { + "node": ">=12.17" + } + }, + "node_modules/table-layout/node_modules/array-back": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", + "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", + "engines": { + "node": ">=12.17" + } + }, + "node_modules/table-layout/node_modules/typical": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz", + "integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==", + "engines": { + "node": ">=12.17" + } + }, "node_modules/tapable": { "version": "2.2.1", "license": "MIT", @@ -9474,8 +9576,7 @@ }, "node_modules/tar-stream": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "license": "MIT", "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", @@ -9489,8 +9590,7 @@ }, "node_modules/tar-stream/node_modules/readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -9620,9 +9720,8 @@ }, "node_modules/through": { "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/through2": { "version": "2.0.5", @@ -9656,9 +9755,8 @@ }, "node_modules/to-buffer": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", - "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/to-fast-properties": { "version": "2.0.0", @@ -9958,6 +10056,13 @@ "node": ">=12.20" } }, + "node_modules/typical": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/ua-parser-js": { "version": "1.0.35", "funding": [ @@ -9991,9 +10096,8 @@ }, "node_modules/unbzip2-stream": { "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", "dev": true, + "license": "MIT", "dependencies": { "buffer": "^5.2.1", "through": "^2.3.8" @@ -10001,8 +10105,6 @@ }, "node_modules/unbzip2-stream/node_modules/buffer": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "dev": true, "funding": [ { @@ -10018,6 +10120,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -11246,6 +11349,14 @@ "node": ">=0.10.0" } }, + "node_modules/wordwrapjs": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-5.1.0.tgz", + "integrity": "sha512-JNjcULU2e4KJwUNv6CHgI46UvDGitb6dGryHajXTDiLgg1/RiGoPSDw4kZfYnwGtEXf2ZMeIewDQgFGzkCB2Sg==", + "engines": { + "node": ">=12.17" + } + }, "node_modules/worker-farm": { "version": "1.7.0", "dev": true, @@ -11461,9 +11572,8 @@ }, "node_modules/yauzl": { "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", "dev": true, + "license": "MIT", "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" @@ -11482,8 +11592,7 @@ }, "node_modules/zip-stream": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz", - "integrity": "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==", + "license": "MIT", "dependencies": { "archiver-utils": "^2.1.0", "compress-commons": "^4.1.0", @@ -11495,8 +11604,7 @@ }, "node_modules/zip-stream/node_modules/readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -11581,6 +11689,23 @@ "typescript": "^5.0.4" } }, + "tools/cli": { + "name": "@backtrace/javascript-cli", + "version": "0.0.1", + "license": "MIT", + "dependencies": { + "@backtrace/sourcemap-tools": "^0.0.1", + "command-line-args": "^5.2.1", + "command-line-usage": "^7.0.1" + }, + "devDependencies": { + "@types/command-line-args": "^5.2.0", + "@types/command-line-usage": "^5.0.2" + }, + "engines": { + "node": ">=14" + } + }, "tools/sourcemap-tools": { "name": "@backtrace/sourcemap-tools", "version": "0.0.1", @@ -11605,8 +11730,7 @@ }, "tools/sourcemap-tools/node_modules/source-map": { "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "license": "BSD-3-Clause", "engines": { "node": ">= 8" } @@ -11640,6 +11764,22 @@ } }, "dependencies": { + "@75lb/deep-merge": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@75lb/deep-merge/-/deep-merge-1.1.1.tgz", + "integrity": "sha512-xvgv6pkMGBA6GwdyJbNAnDmfAIR/DfWhrj9jgWh3TY7gRm3KO46x/GPjRg6wJ0nOepwqrNxFfojebh0Df4h4Tw==", + "requires": { + "lodash.assignwith": "^4.2.0", + "typical": "^7.1.1" + }, + "dependencies": { + "typical": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz", + "integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==" + } + } + }, "@ampproject/remapping": { "version": "2.2.1", "dev": true, @@ -12029,6 +12169,16 @@ "webpack-cli": "^5.1.4" } }, + "@backtrace/javascript-cli": { + "version": "file:tools/cli", + "requires": { + "@backtrace/sourcemap-tools": "^0.0.1", + "@types/command-line-args": "^5.2.0", + "@types/command-line-usage": "^5.0.2", + "command-line-args": "^5.2.1", + "command-line-usage": "^7.0.1" + } + }, "@backtrace/node": { "version": "file:packages/node", "requires": { @@ -12087,9 +12237,7 @@ }, "dependencies": { "source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==" + "version": "0.7.4" } } }, @@ -12588,8 +12736,6 @@ }, "@types/archiver": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/@types/archiver/-/archiver-5.3.2.tgz", - "integrity": "sha512-IctHreBuWE5dvBDz/0WeKtyVKVRs4h75IblxOACL92wU66v+HGAfEYAOyXkOFphvRJMhuXdI9huDXpX0FC6lCw==", "dev": true, "requires": { "@types/readdir-glob": "*" @@ -12632,10 +12778,18 @@ "@babel/types": "^7.20.7" } }, + "@types/command-line-args": { + "version": "5.2.0", + "dev": true + }, + "@types/command-line-usage": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/command-line-usage/-/command-line-usage-5.0.2.tgz", + "integrity": "sha512-n7RlEEJ+4x4TS7ZQddTmNSxP+zziEG0TNsMfiRIxcIVXt71ENJ9ojeXmGO3wPoTdn7pJcU2xc3CJYMktNT6DPg==", + "dev": true + }, "@types/decompress": { "version": "4.2.4", - "resolved": "https://registry.npmjs.org/@types/decompress/-/decompress-4.2.4.tgz", - "integrity": "sha512-/C8kTMRTNiNuWGl5nEyKbPiMv6HA+0RbEXzFhFBEzASM6+oa4tJro9b8nj7eRlOFfuLdzUU+DS/GPDlvvzMOhA==", "dev": true, "requires": { "@types/node": "*" @@ -12736,8 +12890,6 @@ }, "@types/readdir-glob": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/readdir-glob/-/readdir-glob-1.1.1.tgz", - "integrity": "sha512-ImM6TmoF8bgOwvehGviEj3tRdRBbQujr1N+0ypaln/GWjaerOB26jb93vsRHmdMtvVQZQebOlqt2HROark87mQ==", "dev": true, "requires": { "@types/node": "*" @@ -13162,7 +13314,6 @@ }, "ansi-styles": { "version": "4.3.0", - "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -13181,8 +13332,6 @@ }, "archiver": { "version": "5.3.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.1.tgz", - "integrity": "sha512-8KyabkmbYrH+9ibcTScQ1xCJC/CGcugdVIwB+53f5sZziXgwUh3iXlAlANMxcZyDEfTHMe6+Z5FofV8nopXP7w==", "requires": { "archiver-utils": "^2.1.0", "async": "^3.2.3", @@ -13195,8 +13344,6 @@ "dependencies": { "readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -13207,8 +13354,6 @@ }, "archiver-utils": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", "requires": { "glob": "^7.1.4", "graceful-fs": "^4.2.0", @@ -13224,8 +13369,6 @@ "dependencies": { "glob": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -13260,6 +13403,9 @@ "version": "3.1.0", "dev": true }, + "array-back": { + "version": "3.1.0" + }, "array-buffer-byte-length": { "version": "1.0.0", "dev": true, @@ -13349,9 +13495,7 @@ "dev": true }, "async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + "version": "3.2.4" }, "async-each": { "version": "1.0.6", @@ -13468,8 +13612,6 @@ }, "bl": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "requires": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -13478,8 +13620,6 @@ "dependencies": { "buffer": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "requires": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -13487,8 +13627,6 @@ }, "readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -13629,8 +13767,6 @@ }, "buffer-alloc": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", "dev": true, "requires": { "buffer-alloc-unsafe": "^1.1.0", @@ -13639,19 +13775,13 @@ }, "buffer-alloc-unsafe": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", "dev": true }, "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==" + "version": "0.2.13" }, "buffer-fill": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==", "dev": true }, "buffer-from": { @@ -13758,12 +13888,19 @@ }, "chalk": { "version": "4.1.2", - "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, + "chalk-template": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz", + "integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==", + "requires": { + "chalk": "^4.1.2" + } + }, "char-regex": { "version": "1.0.2", "dev": true @@ -13940,14 +14077,12 @@ }, "color-convert": { "version": "2.0.1", - "dev": true, "requires": { "color-name": "~1.1.4" } }, "color-name": { - "version": "1.1.4", - "dev": true + "version": "1.1.4" }, "colorette": { "version": "2.0.20", @@ -13959,6 +14094,38 @@ "delayed-stream": "~1.0.0" } }, + "command-line-args": { + "version": "5.2.1", + "requires": { + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + } + }, + "command-line-usage": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-7.0.1.tgz", + "integrity": "sha512-NCyznE//MuTjwi3y84QVUGEOT+P5oto1e1Pk/jFPVdPPfsG03qpTIl3yw6etR+v73d0lXsoojRpvbru2sqePxQ==", + "requires": { + "array-back": "^6.2.2", + "chalk-template": "^0.4.0", + "table-layout": "^3.0.0", + "typical": "^7.1.1" + }, + "dependencies": { + "array-back": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", + "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==" + }, + "typical": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz", + "integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==" + } + } + }, "commander": { "version": "2.20.3" }, @@ -13972,8 +14139,6 @@ }, "compress-commons": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz", - "integrity": "sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==", "requires": { "buffer-crc32": "^0.2.13", "crc32-stream": "^4.0.2", @@ -13983,8 +14148,6 @@ "dependencies": { "readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -14059,14 +14222,10 @@ "version": "1.0.3" }, "crc-32": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==" + "version": "1.2.2" }, "crc32-stream": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.2.tgz", - "integrity": "sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==", "requires": { "crc-32": "^1.2.0", "readable-stream": "^3.4.0" @@ -14074,8 +14233,6 @@ "dependencies": { "readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -14198,8 +14355,6 @@ }, "decompress": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", - "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==", "dev": true, "requires": { "decompress-tar": "^4.0.0", @@ -14214,8 +14369,6 @@ "dependencies": { "make-dir": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", "dev": true, "requires": { "pify": "^3.0.0" @@ -14223,24 +14376,18 @@ "dependencies": { "pify": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", "dev": true } } }, "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true } } }, "decompress-tar": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", - "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", "dev": true, "requires": { "file-type": "^5.2.0", @@ -14250,8 +14397,6 @@ "dependencies": { "bl": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", - "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", "dev": true, "requires": { "readable-stream": "^2.3.5", @@ -14260,14 +14405,10 @@ }, "is-stream": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", "dev": true }, "tar-stream": { "version": "1.6.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", - "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", "dev": true, "requires": { "bl": "^1.0.0", @@ -14283,8 +14424,6 @@ }, "decompress-tarbz2": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", - "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", "dev": true, "requires": { "decompress-tar": "^4.1.0", @@ -14296,22 +14435,16 @@ "dependencies": { "file-type": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", - "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==", "dev": true }, "is-stream": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", "dev": true } } }, "decompress-targz": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", - "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", "dev": true, "requires": { "decompress-tar": "^4.1.1", @@ -14321,16 +14454,12 @@ "dependencies": { "is-stream": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", "dev": true } } }, "decompress-unzip": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", - "integrity": "sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw==", "dev": true, "requires": { "file-type": "^3.8.0", @@ -14341,14 +14470,10 @@ "dependencies": { "file-type": { "version": "3.9.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==", "dev": true }, "get-stream": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", - "integrity": "sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==", "dev": true, "requires": { "object-assign": "^4.0.1", @@ -14357,8 +14482,6 @@ }, "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true } } @@ -15137,8 +15260,6 @@ }, "fd-slicer": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", "dev": true, "requires": { "pend": "~1.2.0" @@ -15157,8 +15278,6 @@ }, "file-type": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", - "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", "dev": true }, "fill-range": { @@ -15231,6 +15350,12 @@ } } }, + "find-replace": { + "version": "3.0.0", + "requires": { + "array-back": "^3.0.1" + } + }, "find-up": { "version": "5.0.0", "dev": true, @@ -15323,9 +15448,7 @@ } }, "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + "version": "1.0.0" }, "fs-write-stream-atomic": { "version": "1.0.10", @@ -15814,8 +15937,6 @@ }, "is-natural-number": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", - "integrity": "sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ==", "dev": true }, "is-negative-zero": { @@ -16489,8 +16610,6 @@ }, "lazystream": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", - "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", "requires": { "readable-stream": "^2.0.5" } @@ -16540,25 +16659,25 @@ "version": "4.17.21", "dev": true }, - "lodash.defaults": { + "lodash.assignwith": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==" + "resolved": "https://registry.npmjs.org/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz", + "integrity": "sha512-ZznplvbvtjK2gMvnQ1BR/zqPFZmS6jbK4p+6Up4xcRYA7yMIwxHCfbTcrYxXKzzqLsQ05eJPVznEW3tuwV7k1g==" + }, + "lodash.camelcase": { + "version": "4.3.0" + }, + "lodash.defaults": { + "version": "4.2.0" }, "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==" + "version": "4.5.0" }, "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==" + "version": "4.4.0" }, "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + "version": "4.0.6" }, "lodash.memoize": { "version": "4.1.2", @@ -16569,9 +16688,7 @@ "dev": true }, "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==" + "version": "4.6.0" }, "loose-envify": { "version": "1.4.0", @@ -17130,8 +17247,6 @@ }, "pend": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", "dev": true }, "picocolors": { @@ -17147,14 +17262,10 @@ }, "pinkie": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", "dev": true }, "pinkie-promise": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", "dev": true, "requires": { "pinkie": "^2.0.0" @@ -17390,24 +17501,18 @@ }, "readdir-glob": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", - "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", "requires": { "minimatch": "^5.1.0" }, "dependencies": { "brace-expansion": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "requires": { "balanced-match": "^1.0.0" } }, "minimatch": { "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "requires": { "brace-expansion": "^2.0.1" } @@ -17590,8 +17695,6 @@ }, "seek-bzip": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz", - "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==", "dev": true, "requires": { "commander": "^2.8.1" @@ -17978,6 +18081,11 @@ "xtend": "^4.0.0" } }, + "stream-read-all": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/stream-read-all/-/stream-read-all-3.0.1.tgz", + "integrity": "sha512-EWZT9XOceBPlVJRrYcykW8jyRSZYbkb/0ZK36uLEmoWVO5gxBOnntNTseNzfREsqxqdfEGQrD8SXQ3QWbBmq8A==" + }, "stream-shift": { "version": "1.0.1", "dev": true @@ -18080,8 +18188,6 @@ }, "strip-dirs": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", - "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", "dev": true, "requires": { "is-natural-number": "^4.0.1" @@ -18097,7 +18203,6 @@ }, "supports-color": { "version": "7.2.0", - "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -18110,13 +18215,37 @@ "version": "3.2.4", "dev": true }, + "table-layout": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-3.0.2.tgz", + "integrity": "sha512-rpyNZYRw+/C+dYkcQ3Pr+rLxW4CfHpXjPDnG7lYhdRoUcZTUt+KEsX+94RGp/aVp/MQU35JCITv2T/beY4m+hw==", + "requires": { + "@75lb/deep-merge": "^1.1.1", + "array-back": "^6.2.2", + "command-line-args": "^5.2.1", + "command-line-usage": "^7.0.0", + "stream-read-all": "^3.0.1", + "typical": "^7.1.1", + "wordwrapjs": "^5.1.0" + }, + "dependencies": { + "array-back": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", + "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==" + }, + "typical": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz", + "integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==" + } + } + }, "tapable": { "version": "2.2.1" }, "tar-stream": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "requires": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", @@ -18127,8 +18256,6 @@ "dependencies": { "readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -18210,8 +18337,6 @@ }, "through": { "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, "through2": { @@ -18239,8 +18364,6 @@ }, "to-buffer": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", - "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", "dev": true }, "to-fast-properties": { @@ -18418,6 +18541,9 @@ "version": "5.0.4", "dev": true }, + "typical": { + "version": "4.0.0" + }, "ua-parser-js": { "version": "1.0.35" }, @@ -18433,8 +18559,6 @@ }, "unbzip2-stream": { "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", "dev": true, "requires": { "buffer": "^5.2.1", @@ -18443,8 +18567,6 @@ "dependencies": { "buffer": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "dev": true, "requires": { "base64-js": "^1.3.1", @@ -19324,6 +19446,11 @@ "version": "1.2.3", "dev": true }, + "wordwrapjs": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-5.1.0.tgz", + "integrity": "sha512-JNjcULU2e4KJwUNv6CHgI46UvDGitb6dGryHajXTDiLgg1/RiGoPSDw4kZfYnwGtEXf2ZMeIewDQgFGzkCB2Sg==" + }, "worker-farm": { "version": "1.7.0", "dev": true, @@ -19457,8 +19584,6 @@ }, "yauzl": { "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", "dev": true, "requires": { "buffer-crc32": "~0.2.3", @@ -19471,8 +19596,6 @@ }, "zip-stream": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz", - "integrity": "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==", "requires": { "archiver-utils": "^2.1.0", "compress-commons": "^4.1.0", @@ -19481,8 +19604,6 @@ "dependencies": { "readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", diff --git a/tools/cli/LICENSE b/tools/cli/LICENSE new file mode 100644 index 00000000..cf679f7e --- /dev/null +++ b/tools/cli/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Backtrace Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/tools/cli/package.json b/tools/cli/package.json new file mode 100644 index 00000000..1d5d903c --- /dev/null +++ b/tools/cli/package.json @@ -0,0 +1,48 @@ +{ + "name": "@backtrace/javascript-cli", + "version": "0.0.1", + "description": "Backtrace CLI for working with Javascript files.", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "engines": { + "node": ">=14" + }, + "scripts": { + "build": "tsc", + "clean": "tsc -b --clean && rimraf \"lib\"", + "format": "prettier --write '**/*.ts'", + "lint": "eslint . --ext .ts", + "watch": "tsc -w", + "start": "node lib/index.js" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/backtrace-labs/backtrace-javascript.git" + }, + "keywords": [ + "Error", + "Reporting", + "Diagnostic", + "Tool", + "Bug", + "Bugs", + "StackTrace", + "Source maps", + "Sourcemaps" + ], + "author": "Backtrace ", + "license": "MIT", + "bugs": { + "url": "https://github.com/backtrace-labs/backtrace-javascript/issues" + }, + "homepage": "https://github.com/backtrace-labs/backtrace-javascript#readme", + "dependencies": { + "@backtrace/sourcemap-tools": "^0.0.1", + "command-line-args": "^5.2.1", + "command-line-usage": "^7.0.1" + }, + "devDependencies": { + "@types/command-line-args": "^5.2.0", + "@types/command-line-usage": "^5.0.2" + } +} diff --git a/tools/cli/src/commands/Command.ts b/tools/cli/src/commands/Command.ts new file mode 100644 index 00000000..8f63b743 --- /dev/null +++ b/tools/cli/src/commands/Command.ts @@ -0,0 +1,168 @@ +import { Err, Ok, Result } from '@backtrace/sourcemap-tools'; +import commandLineArgs from 'command-line-args'; +import commandLineUsage, { Section } from 'command-line-usage'; +import { LoggerOptions, createLogger } from '../logger'; +import { CommandError } from '../models/CommandError'; +import { ExtendedOptionDefinition } from '../models/OptionDefinition'; + +const CLI_COMMAND = 'backtrace'; + +export class Command { + public readonly subcommands: Command[] = []; + public readonly options: ExtendedOptionDefinition[] = []; + public readonly helpSections: Section[] = []; + private _execute?: ( + this: this, + values: Partial, + stack?: Command[], + ) => Result | Promise>; + + constructor(public readonly definition: ExtendedOptionDefinition) {} + + public subcommand(command: Command): this { + this.subcommands.push(command); + return this; + } + + public option(option: ExtendedOptionDefinition): this { + this.options.push(option); + return this; + } + + public help(...sections: Section[]): this { + this.helpSections.push(...sections); + return this; + } + + public execute(fn: Command['_execute']): this { + this._execute = fn; + return this; + } + + public async run(argv: string[], stack?: Command[]): Promise> { + const stackOptions = stack?.flatMap((s) => s.options.filter((o) => o.global)) ?? []; + const localOptions = [...this.options, ...stackOptions]; + const subcommandOption = { + name: '_subcommand', + defaultOption: true, + }; + + const subCommandMode = !!this.subcommands.length; + if (subCommandMode) { + localOptions.push(subcommandOption); + } + + const values = commandLineArgs(localOptions, { + argv, + stopAtFirstUnknown: subCommandMode, + }); + + if (subCommandMode && values._subcommand) { + const subcommand = this.subcommands.find((s) => s.definition.name === values._subcommand); + if (subcommand) { + const subcommandValues = commandLineArgs([subcommandOption], { argv, stopAtFirstUnknown: true }); + return await subcommand.run(subcommandValues._unknown ?? [], [...(stack ?? []), this]); + } + } + + const logger = createLogger(values as LoggerOptions); + + if (values.help) { + logger.output(this.getHelpMessage(stack)); + return Ok(0); + } + + if (this._execute) { + return (await this._execute.call(this, values as T, stack)).mapErr((error) => ({ + command: this, + error, + stack, + })); + } + + logger.info(this.getHelpMessage(stack)); + + if (subCommandMode) { + return Err({ command: this, stack, error: 'Unknown command.' }); + } + + return Err({ command: this, stack, error: 'Unknown option.' }); + } + + public getHelpMessage(stack?: Command[]) { + const globalOptions = [ + ...this.options.filter((o) => o.global), + ...(stack?.flatMap((o) => o.options.filter((o) => o.global)) ?? []), + ]; + + const nonGlobalOptions = this.options.filter((o) => !o.global); + + let cmd = CLI_COMMAND; + const stackCmd = `${ + [...(stack ?? []), this] + .map((s) => s.definition.name) + .filter((s) => !!s) + .join(' ') ?? '' + }`; + + if (stackCmd) { + cmd += ` ${stackCmd}`; + } + + let usage = cmd; + if (this.subcommands.length) { + usage += ' '; + } + + const defaultOption = + nonGlobalOptions.find((s) => s.defaultOption) ?? globalOptions.find((s) => s.defaultOption); + if (defaultOption) { + usage += ` <${defaultOption.name}>`; + } + + if (globalOptions.length + nonGlobalOptions.length) { + usage += ' [options]'; + } + + const sections: Section[] = [ + { + header: cmd, + content: 'Backtrace utility for managing Javascript files.', + }, + ]; + + if (this.helpSections.length) { + sections.push(...this.helpSections); + } + + sections.push({ + content: `Usage: ${usage}`, + }); + + if (this.subcommands.length) { + sections.push({ + header: 'Available commands', + content: this.subcommands.map((s) => ({ + name: s.definition.name, + summary: s.definition.description, + })), + }); + } + + if (nonGlobalOptions.length) { + sections.push({ + header: 'Available options', + optionList: nonGlobalOptions, + }); + } + + if (globalOptions.length) { + sections.push({ + header: 'Global options', + optionList: globalOptions, + }); + } + + return commandLineUsage(sections); + } +} diff --git a/tools/cli/src/helpers/common.ts b/tools/cli/src/helpers/common.ts new file mode 100644 index 00000000..687da6c9 --- /dev/null +++ b/tools/cli/src/helpers/common.ts @@ -0,0 +1,69 @@ +import { Err, Ok, Result, ResultPromise } from '@backtrace/sourcemap-tools'; +import fs from 'fs'; +import { Readable } from 'stream'; + +export type ContentFile = readonly [content: string, path: string]; +export type StreamFile = readonly [stream: Readable, path: string]; + +export async function readFile(file: string): ResultPromise { + try { + return Ok(await fs.promises.readFile(file, 'utf-8')); + } catch (err) { + return Err(`failed to read file: ${err instanceof Error ? err.message : 'unknown error'}`); + } +} + +export async function writeFile(file: ContentFile) { + const [content, path] = file; + try { + await fs.promises.writeFile(path, content); + return Ok(file); + } catch (err) { + return Err(`failed to write file: ${err instanceof Error ? err.message : 'unknown error'}`); + } +} + +export async function writeStream(file: StreamFile) { + const [stream, path] = file; + try { + const output = fs.createWriteStream(path); + stream.pipe(output); + return new Promise>((resolve) => { + output.on('error', (err) => { + resolve(Err(`failed to write file: ${err.message}`)); + }); + + output.on('finish', () => resolve(Ok(file))); + }); + } catch (err) { + return Err(`failed to write file: ${err instanceof Error ? err.message : 'unknown error'}`); + } +} + +export function parseJSON(content: string): Result { + try { + return Ok(JSON.parse(content)); + } catch (err) { + return Err(`failed to parse content: ${err instanceof Error ? err.message : 'unknown error'}`); + } +} + +export function pass(t: T): T { + return t; +} + +export function passOk(t: T): Result { + return Ok(t); +} + +export function failIfEmpty(error: E) { + return function failIfEmpty(t: T[]): Result { + return t.length ? Ok(t) : Err(error); + }; +} + +export function map(fn: (t: T) => B) { + return function map(t: T[]) { + return t.map(fn); + }; +} diff --git a/tools/cli/src/helpers/find.ts b/tools/cli/src/helpers/find.ts new file mode 100644 index 00000000..02b25cc4 --- /dev/null +++ b/tools/cli/src/helpers/find.ts @@ -0,0 +1,41 @@ +import { Err, FileFinder, Ok, ResultPromise } from '@backtrace/sourcemap-tools'; +import fs from 'fs'; +import path from 'path'; + +/** + * Returns files found in directories matching `regex`. If path is a file, it is returned if it matches `regex`. + * @param regex Regular expression pattern to match. + * @param paths Paths to search in. + * @returns Result with file paths. + */ +export async function find(regex: RegExp, ...paths: string[]): ResultPromise { + const finder = new FileFinder(); + const results = new Map(); + for (const findPath of paths) { + const stat = await fs.promises.stat(findPath); + if (!stat.isDirectory()) { + if (!findPath.match(regex)) { + return Err(`${findPath} does not match regex: ${regex}`); + } + const fullPath = path.resolve(findPath); + if (!results.has(fullPath)) { + results.set(fullPath, findPath); + } + continue; + } + + const findResult = await finder.find(findPath, { match: regex, recursive: true }); + if (findResult.isErr()) { + return findResult; + } + + for (const result of findResult.data) { + const fullPath = path.resolve(result); + if (!results.has(fullPath)) { + results.set(fullPath, result); + } + } + } + + return Ok([...results.values()]); +} diff --git a/tools/cli/src/index.ts b/tools/cli/src/index.ts new file mode 100644 index 00000000..deaa2a52 --- /dev/null +++ b/tools/cli/src/index.ts @@ -0,0 +1,57 @@ +import commandLineArgs from 'command-line-args'; +import { Command } from './commands/Command'; +import { LoggerOptions, createLogger } from './logger'; +import { addSourcesCmd } from './sourcemaps/add-sources'; +import { processCmd } from './sourcemaps/process'; +import { uploadCmd } from './sourcemaps/upload'; + +export interface GlobalOptions extends LoggerOptions { + readonly help: boolean; +} + +const mainCommand = new Command({ + name: '', +}) + .subcommand(processCmd) + .subcommand(uploadCmd) + .subcommand(addSourcesCmd) + .option({ + name: 'help', + type: Boolean, + alias: 'h', + global: true, + description: 'Displays this help message.', + }) + .option({ + name: 'verbose', + type: Boolean, + alias: 'v', + global: true, + multiple: true, + description: 'Verbosity level. -v prints debug logs, -vv prints ALL logs.', + }) + .option({ + name: 'quiet', + type: Boolean, + alias: 'q', + global: true, + description: 'Disables ALL logging messages.', + }) + .option({ + name: 'log-level', + type: String, + global: true, + description: 'Sets the logging level. Can be one of: quiet, error, warn, info, debug, verbose. Default: info', + }); + +(async () => { + const result = await mainCommand.run(process.argv); + if (result.isOk()) { + process.exit(result.data); + } else { + const loggerOptions = commandLineArgs(mainCommand.options, { partial: true }) as Partial; + const logger = createLogger(loggerOptions); + logger.error(result.data.error); + process.exit(1); + } +})(); diff --git a/tools/cli/src/logger.ts b/tools/cli/src/logger.ts new file mode 100644 index 00000000..7b4ce5ca --- /dev/null +++ b/tools/cli/src/logger.ts @@ -0,0 +1,109 @@ +import { LogLevel, Logger } from '@backtrace/sourcemap-tools'; +import { format } from 'util'; + +export interface LoggerOptions { + readonly verbose?: boolean[]; + readonly quiet?: boolean; + readonly 'log-level'?: CliLogLevel; +} + +export type CliLogLevel = LogLevel | 'output'; + +export class CliLogger implements Logger { + private readonly _levelMap: Record; + + constructor(public readonly level: CliLogLevel, public readonly silent?: boolean) { + this._levelMap = this.createLevelMap(level); + } + + public output(value: unknown | Error, ...args: unknown[]) { + return this.log('output', value, ...args); + } + + public error(value: unknown | Error, ...args: unknown[]) { + return this.log('error', value, ...args); + } + + public warn(value: unknown | Error, ...args: unknown[]) { + return this.log('warn', value, ...args); + } + + public info(value: unknown | Error, ...args: unknown[]) { + return this.log('info', value, ...args); + } + + public debug(value: unknown | Error, ...args: unknown[]) { + return this.log('debug', value, ...args); + } + + public trace(value: unknown | Error, ...args: unknown[]) { + return this.log('trace', value, ...args); + } + + public log(level: CliLogLevel, value: unknown | Error, ...args: unknown[]) { + const isOutput = level === 'output'; + + if (this.silent && !isOutput) { + return; + } + + if (!this._levelMap[level]) { + return; + } + + const logger = isOutput + ? (...args: Parameters) => console.log(...args) + : (...args: Parameters) => console.error(...args); + + const message: unknown[] = []; + if (!isOutput) { + message.push(`${level}:`); + } + + if (value instanceof Error) { + message.push(...args, value); + } else { + message.push(value, ...args); + } + + logger(format(...message)); + } + + private createLevelMap(level: CliLogLevel): Record { + const levelMap: Record = { + output: 0, + error: 1, + warn: 2, + info: 3, + debug: 4, + trace: 5, + }; + + return { + output: levelMap[level] >= levelMap['output'], + error: levelMap[level] >= levelMap['error'], + warn: levelMap[level] >= levelMap['warn'], + info: levelMap[level] >= levelMap['info'], + debug: levelMap[level] >= levelMap['debug'], + trace: levelMap[level] >= levelMap['trace'], + }; + } +} + +export function createLogger(options?: LoggerOptions) { + let level: CliLogLevel | undefined; + if (options?.['log-level']) { + level = options?.['log-level']; + } else if (options?.verbose) { + switch (options.verbose.length) { + case 1: + level = 'debug'; + break; + case 2: + level = 'trace'; + break; + } + } + + return new CliLogger(level ?? 'info', options?.quiet); +} diff --git a/tools/cli/src/models/CommandError.ts b/tools/cli/src/models/CommandError.ts new file mode 100644 index 00000000..a7eaa49c --- /dev/null +++ b/tools/cli/src/models/CommandError.ts @@ -0,0 +1,7 @@ +import { Command } from '../commands/Command'; + +export interface CommandError { + readonly command: Command; + readonly stack?: Command[]; + readonly error: string | Error; +} diff --git a/tools/cli/src/models/OptionDefinition.ts b/tools/cli/src/models/OptionDefinition.ts new file mode 100644 index 00000000..9f9285de --- /dev/null +++ b/tools/cli/src/models/OptionDefinition.ts @@ -0,0 +1,6 @@ +import { OptionDefinition } from 'command-line-usage'; + +export interface ExtendedOptionDefinition extends OptionDefinition { + readonly name: N; + readonly global?: boolean; +} diff --git a/tools/cli/src/sourcemaps/add-sources.ts b/tools/cli/src/sourcemaps/add-sources.ts new file mode 100644 index 00000000..b560fc56 --- /dev/null +++ b/tools/cli/src/sourcemaps/add-sources.ts @@ -0,0 +1,118 @@ +import { AsyncResult, DebugIdGenerator, Err, SourceProcessor, flatMap } from '@backtrace/sourcemap-tools'; +import { GlobalOptions } from '..'; +import { Command } from '../commands/Command'; +import { ContentFile, failIfEmpty, map, parseJSON, pass, passOk, readFile, writeFile } from '../helpers/common'; +import { find } from '../helpers/find'; +import { CliLogger, createLogger } from '../logger'; + +interface AddSourcesOptions extends GlobalOptions { + readonly path: string[]; + readonly 'dry-run': boolean; + readonly force: boolean; + readonly skipFailing: boolean; + readonly 'pass-with-no-files': boolean; +} + +type ObjectFile = readonly [object, string]; + +export const addSourcesCmd = new Command({ + name: 'add-sources', + description: 'Adds sources to sourcemap files', +}) + .option({ + name: 'path', + description: 'Path to sourcemap files to append sources to.', + defaultOption: true, + defaultValue: process.cwd(), + multiple: true, + alias: 'p', + }) + .option({ + name: 'dry-run', + alias: 'n', + type: Boolean, + description: 'Does not modify the files at the end.', + defaultValue: false, + }) + .option({ + name: 'force', + alias: 'f', + type: Boolean, + description: 'Processes files even if sourcesContent is not empty. Will overwrite existing sources.', + defaultValue: false, + }) + .option({ + name: 'pass-with-no-files', + type: Boolean, + description: 'Exits with zero exit code if no sourcemaps are found.', + }) + .execute(function (opts, stack) { + const logger = createLogger(opts); + const sourceProcessor = new SourceProcessor(new DebugIdGenerator()); + logger.trace(`resolved options: \n${JSON.stringify(opts, null, ' ')}`); + + const searchPaths = opts.path; + if (!searchPaths) { + logger.info(this.getHelpMessage(stack)); + return Err('path must be specified'); + } + + return AsyncResult.equip(find(/\.(c|m)?jsx?\.map$/, ...searchPaths)) + .then(readFiles) + .then(loadFiles) + .then(opts.force ? pass : filterFiles(sourceProcessor)) + .then(opts['pass-with-no-files'] ? passOk : failIfEmpty('no valid sourcemaps found')) + .then(map(addSource(sourceProcessor))) + .then(opts['dry-run'] ? passOk : writeSourceMaps) + .then(output(logger)) + .then(() => 0).inner; + }); + +async function readFiles(paths: string[]) { + return Promise.all( + paths.map((f) => AsyncResult.equip(readFile(f)).then((content) => [content, f] as ContentFile).inner), + ); +} + +function loadFiles(files: ContentFile[]) { + return files.map(([content, path]) => parseJSON(content).map((c) => [c, path] as ObjectFile)); +} + +function filterFiles(sourceProcessor: SourceProcessor) { + return function filterFiles(files: ObjectFile[]) { + return files.filter(filterSourceMapWithoutSource(sourceProcessor)); + }; +} + +function filterSourceMapWithoutSource(sourceProcessor: SourceProcessor) { + return function filterSourceMapWithoutSource(sourceMap: ObjectFile): boolean { + return !sourceProcessor.doesSourceMapHaveSources(sourceMap[0] as never); + }; +} + +function addSource(sourceProcessor: SourceProcessor) { + return function addSource([sourceMapObj, sourceMapPath]: ObjectFile) { + return AsyncResult.equip(sourceProcessor.addSourcesToSourceMap(sourceMapObj as never, sourceMapPath)).then( + (newSourceMap) => [newSourceMap, sourceMapPath] as const, + ).inner; + }; +} + +async function writeSourceMaps(file: ObjectFile[]) { + return flatMap(await Promise.all(file.map(writeSourceMap))); +} + +function writeSourceMap(file: ObjectFile) { + const [sourceMapObj, sourceMapPath] = file; + return AsyncResult.equip(writeFile([JSON.stringify(sourceMapObj), sourceMapPath])).then(() => file).inner; +} + +function output(logger: CliLogger) { + return function output(files: ObjectFile[]) { + for (const [, file] of files) { + logger.output(file); + } + + return files; + }; +} diff --git a/tools/cli/src/sourcemaps/process.ts b/tools/cli/src/sourcemaps/process.ts new file mode 100644 index 00000000..207fc890 --- /dev/null +++ b/tools/cli/src/sourcemaps/process.ts @@ -0,0 +1,115 @@ +import { + AsyncResult, + DebugIdGenerator, + Err, + ProcessResultWithPaths, + Result, + SourceProcessor, + flatMap, +} from '@backtrace/sourcemap-tools'; +import { GlobalOptions } from '..'; +import { Command } from '../commands/Command'; +import { failIfEmpty, passOk, writeFile } from '../helpers/common'; +import { find } from '../helpers/find'; +import { CliLogger, createLogger } from '../logger'; + +interface ProcessOptions extends GlobalOptions { + readonly path: string[]; + readonly 'dry-run': boolean; + readonly force: boolean; + readonly 'pass-with-no-files': boolean; +} + +export const processCmd = new Command({ + name: 'process', + description: 'Processing source and sourcemap files', +}) + .option({ + name: 'path', + description: 'Path to sourcemap files or directories containing sourcemaps to upload.', + defaultOption: true, + defaultValue: process.cwd(), + multiple: true, + alias: 'p', + }) + .option({ + name: 'dry-run', + alias: 'n', + type: Boolean, + description: 'Does not modify the files at the end.', + defaultValue: false, + }) + .option({ + name: 'force', + alias: 'f', + type: Boolean, + description: 'Processes files even if already processed.', + defaultValue: false, + }) + .option({ + name: 'pass-with-no-files', + type: Boolean, + description: 'Exits with zero exit code if no files for processing are found.', + }) + .execute(function (opts, stack) { + const logger = createLogger(opts); + const sourceProcessor = new SourceProcessor(new DebugIdGenerator()); + logger.trace(`resolved options: \n${JSON.stringify(opts, null, ' ')}`); + + const searchPaths = opts.path; + if (!searchPaths) { + logger.info(this.getHelpMessage(stack)); + return Err('path must be specified'); + } + + return AsyncResult.equip(find(/\.(c|m)?jsx?$/, ...searchPaths)) + .then(opts.force ? passOk : filterUnprocessedFiles(sourceProcessor)) + .then(opts['pass-with-no-files'] ? passOk : failIfEmpty('no files for processing found')) + .then(processFiles(sourceProcessor)) + .then(opts['dry-run'] ? passOk : writeResults) + .then(output(logger)) + .then(() => 0).inner; + }); + +function filterUnprocessedFiles(sourceProcessor: SourceProcessor) { + return async function filterUnprocessedFiles(files: string[]): Promise> { + return flatMap( + await Promise.all( + files.map( + (file) => + AsyncResult.equip(sourceProcessor.isSourceFileProcessed(file)).then( + (result) => [file, result] as const, + ).inner, + ), + ), + ).map((results) => results.filter(([, result]) => !result).map(([file]) => file)); + }; +} + +function processFiles(sourceProcessor: SourceProcessor) { + return async function processFiles(pathsToProcess: string[]) { + return flatMap( + await Promise.all(pathsToProcess.map((file) => sourceProcessor.processSourceAndSourceMapFiles(file))), + ); + }; +} + +async function writeResults(results: ProcessResultWithPaths[]) { + return flatMap(await Promise.all(results.map(writeResult))); +} + +function writeResult(result: ProcessResultWithPaths) { + return AsyncResult.equip(writeFile([result.source, result.sourcePath])) + .then(() => writeFile([JSON.stringify(result.sourceMap), result.sourceMapPath])) + .then(() => result).inner; +} + +function output(logger: CliLogger) { + return function output(files: ProcessResultWithPaths[]) { + for (const { sourcePath } of files) { + logger.output(sourcePath); + } + + return files; + }; +} diff --git a/tools/cli/src/sourcemaps/upload.ts b/tools/cli/src/sourcemaps/upload.ts new file mode 100644 index 00000000..23a586e6 --- /dev/null +++ b/tools/cli/src/sourcemaps/upload.ts @@ -0,0 +1,192 @@ +import { + AsyncResult, + DebugIdGenerator, + Err, + Ok, + Result, + ResultPromise, + SourceProcessor, + SymbolUploader, + UploadResult, + ZipArchive, + flatMap, +} from '@backtrace/sourcemap-tools'; +import fs from 'fs'; +import path from 'path'; +import { Readable } from 'stream'; +import { GlobalOptions } from '..'; +import { Command } from '../commands/Command'; +import { failIfEmpty, passOk, writeStream } from '../helpers/common'; +import { find } from '../helpers/find'; +import { CliLogger, createLogger } from '../logger'; + +interface UploadOptions extends GlobalOptions { + readonly url: string; + readonly path: string[]; + readonly 'no-sources': string; + readonly insecure: boolean; + readonly 'dry-run': boolean; + readonly force: boolean; + readonly 'pass-with-no-files': boolean; + readonly output: string; +} + +export const uploadCmd = new Command({ + name: 'upload', + description: 'Uploading of sourcemaps to Backtrace', +}) + .option({ + name: 'url', + type: String, + description: 'URL to upload to. You can use also BACKTRACE_JS_UPLOAD_URL env variable.', + alias: 'u', + defaultValue: process.env.BACKTRACE_JS_UPLOAD_URL, + }) + .option({ + name: 'path', + type: String, + description: 'Path to sourcemap files or directories containing sourcemaps to upload.', + defaultOption: true, + defaultValue: process.cwd(), + multiple: true, + alias: 'p', + }) + .option({ + name: 'no-sources', + type: Boolean, + description: 'Uploads the sourcemaps without "sourcesContent" key.', + defaultValue: false, + }) + .option({ + name: 'insecure', + alias: 'k', + type: Boolean, + description: 'Disables HTTPS certificate checking.', + defaultValue: false, + }) + .option({ + name: 'dry-run', + alias: 'n', + type: Boolean, + description: 'Does not upload the files at the end.', + defaultValue: false, + }) + .option({ + name: 'force', + alias: 'f', + type: Boolean, + description: 'Upload files even if not processed.', + defaultValue: false, + }) + .option({ + name: 'pass-with-no-files', + type: Boolean, + description: 'Exits with zero exit code if no files for uploading are found.', + }) + .option({ + name: 'output', + alias: 'o', + description: 'If set, archive with sourcemaps will be outputted to this path instead of being uploaded.', + type: String, + }) + .execute(function (opts, stack) { + const logger = createLogger(opts); + const sourceProcessor = new SourceProcessor(new DebugIdGenerator()); + logger.trace(`resolved options: \n${JSON.stringify(opts, null, ' ')}`); + + const searchPaths = opts.path; + if (!searchPaths) { + logger.info(this.getHelpMessage(stack)); + return Err('path must be specified'); + } + + const outputPath = opts.output; + const uploadUrl = opts.url; + if (!outputPath && !uploadUrl) { + logger.info(this.getHelpMessage(stack)); + return Err('upload URL is required.'); + } + + const processArchive = outputPath + ? saveArchive(outputPath) + : uploadUrl + ? uploadArchive(new SymbolUploader(uploadUrl, { ignoreSsl: opts.insecure ?? false })) + : undefined; + + if (!processArchive) { + throw new Error('processArchive function should be defined'); + } + + return AsyncResult.equip(find(/\.(c|m)?jsx?\.map$/, ...searchPaths)) + .then(opts.force ? passOk : filterProcessedFiles(sourceProcessor)) + .then(readDebugIds(sourceProcessor)) + .then(opts['pass-with-no-files'] ? passOk : failIfEmpty('no files for uploading found')) + .then(createArchiveForUpload) + .then((archive) => (opts['dry-run'] ? Ok(null) : processArchive(archive))) + .then(output(logger)) + .then(() => 0).inner; + }); + +function filterProcessedFiles(sourceProcessor: SourceProcessor) { + return async function filterProcessedFiles(files: string[]): Promise> { + return flatMap( + await Promise.all( + files.map( + (file) => + AsyncResult.equip(sourceProcessor.isSourceMapFileProcessed(file)).then( + (result) => [file, result] as const, + ).inner, + ), + ), + ).map((results) => results.filter(([, result]) => result).map(([file]) => file)); + }; +} + +function readDebugIds(sourceProcessor: SourceProcessor) { + return async function readDebugIds(files: string[]): Promise> { + return flatMap( + await Promise.all( + files.map( + (file) => + AsyncResult.equip(sourceProcessor.getSourceMapFileDebugId(file)).then( + (result) => [file, result] as const, + ).inner, + ), + ), + ); + }; +} + +async function createArchiveForUpload( + pathsToArchive: (readonly [string, string])[], +): ResultPromise { + const archive = new ZipArchive(); + + for (const [filePath, debugId] of pathsToArchive) { + const fileName = path.basename(filePath); + const readStream = fs.createReadStream(filePath); + archive.append(`${debugId}-${fileName}`, readStream); + } + + await archive.finalize(); + return Ok(archive); +} + +function uploadArchive(symbolUploader: SymbolUploader) { + return async function uploadArchive(stream: Readable): ResultPromise { + return await symbolUploader.uploadSymbol(stream); + }; +} + +function saveArchive(filePath: string) { + return async function saveArchive(stream: Readable): ResultPromise { + return AsyncResult.equip(writeStream([stream, filePath])).then(([, rxid]) => ({ rxid })).inner; + }; +} + +function output(logger: CliLogger) { + return function output(result: UploadResult | null) { + logger.output(result?.rxid ?? ''); + return result; + }; +} diff --git a/tools/cli/tsconfig.json b/tools/cli/tsconfig.json new file mode 100644 index 00000000..32a5f6ba --- /dev/null +++ b/tools/cli/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + "composite": true + }, + "exclude": ["node_modules", "tests", "lib"] +} diff --git a/tools/sourcemap-tools/src/SourceProcessor.ts b/tools/sourcemap-tools/src/SourceProcessor.ts index 2d594fcc..b85183bd 100644 --- a/tools/sourcemap-tools/src/SourceProcessor.ts +++ b/tools/sourcemap-tools/src/SourceProcessor.ts @@ -4,7 +4,7 @@ import { BasicSourceMapConsumer, Position, RawSourceMap, SourceMapConsumer, Sour import { DebugIdGenerator } from './DebugIdGenerator'; import { stringToUuid } from './helpers/stringToUuid'; import { ResultPromise } from './models/AsyncResult'; -import { Err, Ok } from './models/Result'; +import { Err, Ok, Result } from './models/Result'; export interface ProcessResult { readonly debugId: string; @@ -53,6 +53,36 @@ export class SourceProcessor { return Ok(this.isSourceMapProcessed(sourcemap)); } + public getSourceMapDebugId(sourceMap: RawSourceMap): Result { + const debugId = this._debugIdGenerator.getSourceMapDebugId(sourceMap); + if (!debugId) { + return Err('sourcemap does not have a debug ID'); + } + + return Ok(debugId); + } + + public async getSourceMapFileDebugId(sourceMapPath: string): ResultPromise { + const readResult = await this.readFile(sourceMapPath); + if (readResult.isErr()) { + return readResult; + } + + let sourcemap: RawSourceMap; + try { + sourcemap = JSON.parse(readResult.data) as RawSourceMap; + } catch (err) { + return Err('failed to parse sourcemap JSON'); + } + + const debugId = this._debugIdGenerator.getSourceMapDebugId(sourcemap); + if (!debugId) { + return Err('sourcemap does not have a debug ID'); + } + + return Ok(debugId); + } + /** * Adds required snippets and comments to source, and modifies sourcemap to include debug ID. * @param source Source content.