diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 794a450d..8006381d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: Run Jest Tests +name: Run Jest Tests on Node.js on: push: diff --git a/.github/workflows/test_bun.yml b/.github/workflows/test_bun.yml new file mode 100644 index 00000000..393aba6d --- /dev/null +++ b/.github/workflows/test_bun.yml @@ -0,0 +1,42 @@ +name: Run Jest Tests on Bun.js + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + test-bun: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Set up Apache Pulsar + uses: reugn/github-action-pulsar@v1 + + - name: Install Bun + run: | + curl https://bun.sh/install | bash + echo "$HOME/.bun/bin" >> $GITHUB_PATH + + - name: Verify Bun Installation + run: bun --version + + - name: Install dependencies with Bun + run: bun install + + - name: Run Bun tests + run: bun run test:bun + + - name: Upload Bun test logs on failure + if: failure() + uses: actions/upload-artifact@v3 + with: + name: bun-test-logs + path: ./bun-test-logs/* + diff --git a/package-lock.json b/package-lock.json index b2a6c298..736ce7e9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,23 +1,27 @@ { "name": "stated-js", - "version": "0.1.28", + "version": "0.1.34", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "stated-js", - "version": "0.1.28", + "version": "0.1.34", "license": "Apache-2.0", "dependencies": { + "@types/js-yaml": "^4.0.9", + "@types/lodash": "^4.14.195", + "@types/lodash-es": "^4.17.12", + "@types/minimist": "^1.2.5", "chalk": "^5.3.0", "flatbuffers": "^23.5.26", "js-yaml": "^4.1.0", "json-colorizer": "^2.2.2", - "jsonata": "^2.0.3", + "jsonata": "2.0.4", "lodash": "^4.17.21", "lodash-es": "^4.17.21", "minimist": "^1.2.8", - "pulsar-client": "^1.12.0", + "pulsar-flex": "^1.1.1", "readline": "^1.3.0", "repl": "^0.1.3", "string-argv": "^0.3.2", @@ -31,9 +35,7 @@ "@babel/core": "^7.22.20", "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", "@babel/preset-env": "^7.22.20", - "@types/js-yaml": "^4.0.9", - "@types/lodash-es": "^4.17.12", - "@types/minimist": "^1.2.5", + "@jest/globals": "latest", "babel-loader": "^9.1.3", "copy-webpack-plugin": "^11.0.0", "jest": "^29.7.0", @@ -2864,78 +2866,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@mapbox/node-pre-gyp": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", - "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", - "license": "BSD-3-Clause", - "dependencies": { - "detect-libc": "^2.0.0", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.7", - "nopt": "^5.0.0", - "npmlog": "^5.0.1", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.11" - }, - "bin": { - "node-pre-gyp": "bin/node-pre-gyp" - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "license": "MIT", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -3127,7 +3057,6 @@ "version": "4.0.9", "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", - "dev": true, "license": "MIT" }, "node_modules/@types/json-schema": { @@ -3141,14 +3070,12 @@ "version": "4.17.0", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.0.tgz", "integrity": "sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==", - "dev": true, "license": "MIT" }, "node_modules/@types/lodash-es": { "version": "4.17.12", "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz", "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==", - "dev": true, "license": "MIT", "dependencies": { "@types/lodash": "*" @@ -3158,7 +3085,6 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", - "dev": true, "license": "MIT" }, "node_modules/@types/node": { @@ -3420,12 +3346,6 @@ "dev": true, "license": "Apache-2.0" }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "license": "ISC" - }, "node_modules/acorn": { "version": "8.10.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", @@ -3449,18 +3369,6 @@ "acorn": "^8" } }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "license": "MIT", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, "node_modules/ajv": { "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", @@ -3529,6 +3437,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -3568,26 +3477,6 @@ "node": ">= 8" } }, - "node_modules/aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", - "license": "ISC" - }, - "node_modules/are-we-there-yet": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", - "deprecated": "This package is no longer supported.", - "license": "ISC", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -3840,21 +3729,14 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, "license": "MIT" }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "license": "MIT", - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -3987,15 +3869,6 @@ "node": ">=10" } }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "license": "ISC", - "engines": { - "node": ">=10" - } - }, "node_modules/chrome-trace-event": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", @@ -4112,15 +3985,6 @@ "simple-swizzle": "^0.2.2" } }, - "node_modules/color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "license": "ISC", - "bin": { - "color-support": "bin.js" - } - }, "node_modules/colorette": { "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", @@ -4156,14 +4020,9 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, "license": "MIT" }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", - "license": "ISC" - }, "node_modules/convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", @@ -4210,6 +4069,12 @@ "url": "https://opencollective.com/core-js" } }, + "node_modules/crc-full": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/crc-full/-/crc-full-1.1.0.tgz", + "integrity": "sha512-7YK4t8C9PiekOSnBotYjU2roaaorUXHyT+Xzb12Zgg4DsfG58AxmPk2/wx7XnC9UXyriqRvl3c+U0zFsZkdVYg==", + "license": "MIT" + }, "node_modules/create-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", @@ -4304,6 +4169,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, "license": "MIT", "dependencies": { "ms": "2.1.2" @@ -4342,21 +4208,6 @@ "node": ">=0.10.0" } }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", - "license": "MIT" - }, - "node_modules/detect-libc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", - "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -4421,6 +4272,7 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, "license": "MIT" }, "node_modules/enabled": { @@ -4704,12 +4556,6 @@ "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==", "license": "MIT" }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "license": "MIT" - }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -4796,40 +4642,11 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fs-minipass/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, "license": "ISC" }, "node_modules/fsevents": { @@ -4854,27 +4671,6 @@ "dev": true, "license": "MIT" }, - "node_modules/gauge": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", - "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", - "deprecated": "This package is no longer supported.", - "license": "ISC", - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.2", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.1", - "object-assign": "^4.1.1", - "signal-exit": "^3.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.2" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -4923,6 +4719,7 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -4989,6 +4786,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/google-protobuf": { + "version": "3.21.4", + "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.21.4.tgz", + "integrity": "sha512-MnG7N936zcKTco4Jd2PX2U96Kf9PxygAPKBug+74LHzmHXmceN16MmRcdgZv+DGef/S9YvQAfRsNCn4cjf9yyQ==", + "license": "(BSD-3-Clause AND Apache-2.0)" + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -5019,12 +4822,6 @@ "node": ">=8" } }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "license": "ISC" - }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -5032,19 +4829,6 @@ "dev": true, "license": "MIT" }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "license": "MIT", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -5113,6 +4897,7 @@ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -5169,6 +4954,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -6912,9 +6698,9 @@ } }, "node_modules/jsonata": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/jsonata/-/jsonata-2.0.3.tgz", - "integrity": "sha512-Up2H81MUtjqI/dWwWX7p4+bUMfMrQJVMN/jW6clFMTiYP528fBOBNtRu944QhKTs3+IsVWbgMeUTny5fw2VMUA==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/jsonata/-/jsonata-2.0.4.tgz", + "integrity": "sha512-vfavX4/G/yrYxE+UrmT/oUJ3ph7KqUrb0R7b0LVRcntQwxw+Z5kA1pNUIQzX5hF04Oe1eKxyoIPsmXtc2LgJTQ==", "license": "MIT", "engines": { "node": ">= 8" @@ -7192,6 +6978,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -7213,54 +7000,12 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, "license": "ISC", "engines": { "node": ">=8" } }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "license": "MIT", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -7281,32 +7026,6 @@ "dev": true, "license": "MIT" }, - "node_modules/node-addon-api": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", - "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==", - "license": "MIT" - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -7321,21 +7040,6 @@ "dev": true, "license": "MIT" }, - "node_modules/nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "license": "ISC", - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -7359,32 +7063,11 @@ "node": ">=8" } }, - "node_modules/npmlog": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", - "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", - "deprecated": "This package is no longer supported.", - "license": "ISC", - "dependencies": { - "are-we-there-yet": "^2.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^3.0.0", - "set-blocking": "^2.0.0" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, "license": "ISC", "dependencies": { "wrappy": "1" @@ -7510,6 +7193,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -7732,19 +7416,17 @@ "node": ">= 6" } }, - "node_modules/pulsar-client": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/pulsar-client/-/pulsar-client-1.12.0.tgz", - "integrity": "sha512-6xzL7ACXW6vf5J6ilsXB0Zvn1SjtLnuSP8AX+M1xtaVrR/F04BCMifOhxywpPWJpW7yaGJR1zYZjfimGxS8wiw==", - "hasInstallScript": true, - "license": "Apache-2.0", + "node_modules/pulsar-flex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pulsar-flex/-/pulsar-flex-1.1.1.tgz", + "integrity": "sha512-R6jNg4E326uItcG/QcNYLSOnZxMvVo4ZzxB2scEZDN3mp2VHKzPr/iiC07sXthrtdAVXlFTUt8+QyujoKc54ZA==", + "license": "MIT", "dependencies": { - "@mapbox/node-pre-gyp": "^1.0.11", - "bindings": "^1.5.0", - "node-addon-api": "^4.3.0" + "crc-full": "^1.1.0", + "google-protobuf": "^3.17.3" }, "engines": { - "node": ">=12.3.0" + "node": ">=10.6.0" } }, "node_modules/punycode": { @@ -8183,12 +7865,6 @@ "randombytes": "^2.1.0" } }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "license": "ISC" - }, "node_modules/shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", @@ -8242,6 +7918,7 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, "license": "ISC" }, "node_modules/simple-swizzle": { @@ -8365,6 +8042,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -8395,6 +8073,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -8486,29 +8165,6 @@ "node": ">=6" } }, - "node_modules/tar": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", - "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", - "license": "ISC", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/tar/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" - }, "node_modules/terser": { "version": "5.19.4", "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.4.tgz", @@ -8709,12 +8365,6 @@ "node": ">=8.0" } }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" - }, "node_modules/triple-beam": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", @@ -8953,12 +8603,6 @@ "node": ">=10.13.0" } }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause" - }, "node_modules/webpack": { "version": "5.88.2", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz", @@ -9149,16 +8793,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -9175,15 +8809,6 @@ "node": ">= 8" } }, - "node_modules/wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "license": "ISC", - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, "node_modules/wildcard": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", @@ -9340,6 +8965,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, "license": "ISC" }, "node_modules/write-file-atomic": { diff --git a/package.json b/package.json index f4c780f5..88fb1764 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "build": "tsc && npm run webpack && npm run docs", "webpack": "webpack && webpack --config webpack.config.cjs.js && webpack --config webpack.nodeSingleBin.cjs.js", "test": "npm run clean && npm run build && node --experimental-vm-modules node_modules/jest/bin/jest.js --detectOpenHandles", + "test:bun": "npm run clean && npm run build && bun test", "test-fast": "node --experimental-vm-modules node_modules/jest/bin/jest.js", "stated": "node --experimental-vm-modules dist/stated.js", "docs": "typedoc --out docs src/*" @@ -54,11 +55,11 @@ "flatbuffers": "^23.5.26", "js-yaml": "^4.1.0", "json-colorizer": "^2.2.2", - "jsonata": "^2.0.3", + "jsonata": "2.0.4", "lodash": "^4.17.21", "lodash-es": "^4.17.21", "minimist": "^1.2.8", - "pulsar-client": "^1.12.0", + "pulsar-flex": "^1.1.1", "readline": "^1.3.0", "repl": "^0.1.3", "string-argv": "^0.3.2", @@ -69,6 +70,7 @@ "@babel/core": "^7.22.20", "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", "@babel/preset-env": "^7.22.20", + "@jest/globals": "latest", "babel-loader": "^9.1.3", "copy-webpack-plugin": "^11.0.0", "jest": "^29.7.0", diff --git a/src/CliCore.ts b/src/CliCore.ts index 3e1b18e9..17079df8 100644 --- a/src/CliCore.ts +++ b/src/CliCore.ts @@ -11,354 +11,22 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -import fs from 'fs'; -import path from 'path'; + import TemplateProcessor from './TemplateProcessor.js'; -import yaml from 'js-yaml'; -import minimist from "minimist"; -import parseArgsStringToArgv from 'string-argv'; -import {Levels, LOG_LEVELS} from "./ConsoleLogger.js"; import * as repl from 'repl'; import {stringifyTemplateJSON} from "./utils/stringify.js"; import jsonata from "jsonata"; -import VizGraph from "./VizGraph.js"; -import { exec } from 'child_process'; -import http from 'http'; -import * as child_process from "child_process"; -import os from "os"; +import {CliCoreBase} from "./CliCoreBase.js"; -export default class CliCore { - private templateProcessor: TemplateProcessor; - private logLevel: keyof typeof LOG_LEVELS; - private currentDirectory:string; - //@ts-ignore - private server: http.Server; //http server to serve SVG images +export default class CliCore extends CliCoreBase{ //@ts-ignore public replServer:repl.REPLServer; - public onInit: () => Promise|void; constructor(templateProcessor: TemplateProcessor) { - this.templateProcessor = templateProcessor; - this.logLevel = "info"; - this.currentDirectory = process.cwd(); - this.onInit = ()=>{}; - } - public async close(){ - if(this.templateProcessor){ - await this.templateProcessor.close(); - } - if(this.server){ - this.server.close(); - } - } - - - static minimistArgs(replCmdInputStr:string) { - const args = parseArgsStringToArgv(replCmdInputStr); - return minimist(args); - - } - static parseInitArgs(replCmdInputStr:string){ - - const parsed = CliCore.minimistArgs(replCmdInputStr); - let {_:bareArgs ,f:filepath, o:oneshot,options="{}", ctx={}} = parsed; - let tags:any = parsed.tags ||""; - if(tags === true){ //weird case of --tags with no arguments - tags = ""; - } - if(tags===""){ - tags=[]; - }else { - tags = tags.split(',').map((s:string) => s.trim()); //tags are provided as JSON array - } - try { - options = JSON.parse(options); - }catch(e:any){ - console.error("failed to parse --options json: " + e.message); - throw e; - } - - filepath = filepath?filepath:bareArgs[0]; - oneshot = oneshot===true?oneshot:bareArgs.length > 0; - const processedArgs = {filepath, tags, oneshot, options, ctx}; - return {...parsed, ...processedArgs}; //spread the processedArgs back into what was parsed - } - - async readFileAndParse(filepath:string, importPath?:string) { - const fileExtension = path.extname(filepath).toLowerCase().replace(/\W/g, ''); - if (fileExtension === 'js' || fileExtension === 'mjs') { - return await import(CliCore.resolveImportPath(filepath, importPath)); - } - - const fileContent = await fs.promises.readFile(filepath, 'utf8'); - - if (fileExtension === 'yaml' || fileExtension === 'yml') { - return yaml.load(fileContent); - } else { - return JSON.parse(fileContent); - } - } - - static isNodeEnvironment() { - return typeof process !== 'undefined' && process.versions != null && process.versions.node != null; - } - - - static resolveImportPath(filepath: any, importPath: any): string { - if (!filepath) throw new Error("filepath is required"); - - // can't do any path resolution in browser - if (!CliCore.isNodeEnvironment()) return filepath; - - if (importPath) { - if (filepath && filepath.startsWith("~")) throw new Error("Cannot use file path starting with '~' with importPath"); - if (filepath && filepath.startsWith("/")) throw new Error("Cannot use file path starting with '/' with importPath"); - if (importPath.startsWith("/")) return path.resolve(path.join(importPath, filepath)) - - if (importPath.startsWith("~")) return path.resolve(path.join(importPath.replace("~", os.homedir()), filepath)); - - //relative path - return path.resolve(path.join(importPath, filepath)); - } - - if (filepath && filepath.includes("~")) return path.normalize(path.resolve(filepath.replace("~", os.homedir()))); - if (filepath && filepath.startsWith("/")) return path.normalize(filepath); - return path.join(process.cwd(), filepath); - } - - //replCmdInoutStr like: -f "defaultSnapshot.json" - - /** - * replCmdInoutStr example: -f "example/restoreSnapshot.json" --tags=["PEACE"] --xf=example/myEnv.json - * @param replCmdInputStr - the command line string that will be parsed into arguments - */ - async restore(replCmdInputStr: string) { - return this.init(replCmdInputStr, true); - - } - - /** - * This Cli core command may be invoked directly from the REPL init command or from restore command - * - * - fromSnapshot=false, replCmdInoutStr example: -f "example/ex23.json" --tags=["PEACE"] --xf=example/myEnv.json - * - fromSnapshot=true, replCmdInoutStr example: -f "example/restoreSnapshot.json" --tags=["PEACE"] --xf=example/myEnv.json - * - * @param replCmdInputStr - * @param fromSnapshot - when set to true, template processor will treat input as a snapshot of a previous - * templateProcessor state - */ - async init(replCmdInputStr:string, fromSnapshot: boolean=false) { - if(this.templateProcessor){ - this.templateProcessor.close(); - } - const parsed:any = CliCore.parseInitArgs(replCmdInputStr); - const {filepath, tags,oneshot, options, xf:contextFilePath, importPath=this.currentDirectory, tail, ctx={}} = parsed; - if(filepath===undefined){ - return undefined; - } - const input = await this.openFile(filepath); - let contextData = contextFilePath ? await this.readFileAndParse(contextFilePath, importPath) : {}; - contextData = {...contextData, ...ctx} //--ctx.foo=bar creates ctx={foo:bar}. The dot argument syntax is built into minimist - options.importPath = importPath; //path is where local imports will be sourced from. We sneak path in with the options - // if we initialize for the first time, we need to create a new instance of TemplateProcessor - if (!this.templateProcessor && !fromSnapshot) { - this.templateProcessor = new TemplateProcessor(input, contextData, options); - } else if (!this.templateProcessor && fromSnapshot) { - this.templateProcessor = TemplateProcessor.constructFromSnapshotObject(input, contextData); - } else { // if we are re-initializing, we need to reset the tagSet and options, if provided - this.templateProcessor.tagSet = new Set(); - this.templateProcessor.options = options; - if (contextData && Object.keys(contextData).length > 0) { - this.templateProcessor.setupContext(contextData); - } - } - if(this.replServer){ - //make variable called 'template' accessible in REPL - this.replServer.context.template = this.templateProcessor; - } - this.templateProcessor.onInitialize.set("CLI",this.onInit); - tags.forEach((a:string) => this.templateProcessor.tagSet.add(a)); - // set options - this.templateProcessor.logger.level = this.logLevel; - this.templateProcessor.logger.debug(`arguments: ${JSON.stringify(parsed)}`); - this.templateProcessor.context["open"] = this.openFile.bind(this); //$open('foo.json') is supported by the CLI adding $open function. It is not part of core TemplateProcessor as that would be security hole - try { - let tailPromise; - if(tail !== undefined){ - tailPromise = this.tail(tail); - } - if (fromSnapshot) { // restore from a snapshot - await this.templateProcessor.initialize(undefined, "/", input); - } else { - await this.templateProcessor.initialize(input); - } - const {__init} = contextData; - __init && __init(this.templateProcessor); //if a function named __init is found in the --xf, said context function is run - if(tail !== undefined){ - return tailPromise; - } - if (oneshot === true) { - return this.templateProcessor.output; - } - return this.templateProcessor.input; - - } catch (error:any) { - return { - name: error.name, - message: error.message - }; - } - - } - - private async openFile(fname:string){ - let _filepath = fname; - if(this.currentDirectory){ - _filepath = path.join(this.currentDirectory, _filepath); - } - return await this.readFileAndParse(_filepath); - } - - - async set(args:string) { - const options:any = args.match(/(?:[^\s"]+|"[^"]*")+/g); - let [path, data] = options; - let jsonPtr = path; - if (path === '-f') { - try { - // Read file - const fileContent = await fs.promises.readFile(data, 'utf8'); - const tmp = JSON.parse(fileContent); - jsonPtr = tmp.path; // Assumes the file contains an object with 'path' and 'data' properties - data = tmp.data; - } catch (err) { - console.error('Error reading file:', err); - throw err; - } - } - - if (!this.templateProcessor) { - throw new Error('Initialize the template first.'); - } - try { - data = JSON.parse(data); - } catch (err) { - console.error('Error parsing JSON data:', err); - throw err; - } - - await this.templateProcessor.setData(jsonPtr, data); - return this.templateProcessor.output; - } - - in() { - if (!this.templateProcessor) { - throw new Error('Initialize the template first.'); - } - return this.templateProcessor.input; - } - - out(replCmdInputStr:string) { - if (!this.templateProcessor) { - throw new Error('Initialize the template first.'); - } - const parsed = CliCore.minimistArgs(replCmdInputStr === undefined ? "" : replCmdInputStr) - let {_:jsonPointer=""} = parsed; - if(Array.isArray(jsonPointer)){ - jsonPointer = jsonPointer[0]; - if(jsonPointer===undefined){ - jsonPointer = ""; - } - } - return this.templateProcessor.out(jsonPointer); - } - - state() { - if (!this.templateProcessor) { - throw new Error('Initialize the template first.'); - } - return this.templateProcessor.templateMeta; - } - - from(args:string) { - if (!this.templateProcessor) { - throw new Error('Initialize the template first.'); - } - const [jsonPtr, option] = args.split(' '); - return option === '--shallow' ? this.templateProcessor.getDependents(jsonPtr) : this.templateProcessor.from(jsonPtr); - } - - to(args:string) { - if (!this.templateProcessor) { - throw new Error('Initialize the template first.'); - } - const [jsonPtr, option] = args.split(' '); - return option === '--shallow' ? this.templateProcessor.getDependencies(jsonPtr) : this.templateProcessor.to(jsonPtr); + super(templateProcessor); } - async plan() { - if (!this.templateProcessor) { - throw new Error('Initialize the template first.'); - } - return await this.templateProcessor.getEvaluationPlan(); - } - - log(level:Levels) { - this.logLevel = level; - if(this.templateProcessor){ - this.templateProcessor.logger.level = level; - } - return {"log level":level}; - } - - note(){ - return "============================================================="; - } - - async debug(replCmdInputStr:string) { - if (!this.templateProcessor) { - throw new Error('Initialize the template first.'); - } - const parsed = CliCore.minimistArgs(replCmdInputStr) - return this.templateProcessor.debugger.processCommands(parsed); - } - - async errors() { - if (!this.templateProcessor) { - throw new Error('Initialize the template first.'); - } - return this.templateProcessor.errorReport; - } - - private extractArgsInfo(args:string) { - // Define the regex patterns - const jsonPointerNumberPattern = /^(?\/[^\s]*)(?:\s+(?\d+))?$/; - const untilJsonataPattern = /^(?\/[^\s]*)\s+until\s+(?[^\n]+)$/; - - // Try to match the args string against both patterns - const matchNumberFormat = args.match(jsonPointerNumberPattern); - const matchUntilJsonataFormat = args.match(untilJsonataPattern); - - // Check which format was matched - if (matchNumberFormat) { - // Extracted information for format - const { jsonPointer, number } = matchNumberFormat.groups || {}; - if (jsonPointer) { - return { format: "Number", jsonPointer, number: parseInt(number, 10) }; - } - } else if (matchUntilJsonataFormat) { - // Extracted information for format - const { jsonPointer, jsonataExpression } = matchUntilJsonataFormat.groups || {}; - if (jsonPointer) { - return { format: "UntilJsonata", jsonPointer, jsonataExpression }; - } - } - - throw new Error(`invalid --tail args: ${args}`); - } - - public async tail(args: string): Promise { console.log("Started tailing... Press Ctrl+C to stop.") @@ -445,149 +113,5 @@ export default class CliCore { }; //the last result tailed to the screen is what this command returns } - - - public async open(directory: string = this.currentDirectory) { - if(directory === ""){ - directory = this.currentDirectory; - } - - let files: string[]|undefined = undefined; - try { - // Read all files from the directory - files = await fs.promises.readdir(directory); - } catch (error) { - console.log(`Error reading directory ${directory}: ${error}`); - console.log('Changed directory with .cd or .open an/existing/directory'); - this.replServer.displayPrompt(); - return {error: `Error reading directory ${directory}: ${error}`}; - } - // Filter out only .json and .yaml files - const templateFiles: string[] = files.filter(file => file.endsWith('.json') || file.endsWith('.yaml')); - - // Display the list of files to the user - templateFiles.forEach((file, index) => { - console.log(`${index + 1}: ${file}`); - }); - - // Create an instance of AbortController - const ac = new AbortController(); - const {signal} = ac; // Get the AbortSignal from the controller - - // Ask the user to choose a file - this.replServer.question('Enter the number of the file to open (or type "abort" to cancel): ', {signal}, async (answer) => { - // Check if the operation was aborted - if (signal.aborted) { - console.log('File open operation was aborted.'); - this.replServer.displayPrompt(); - return; - } - - const fileIndex = parseInt(answer, 10) - 1; // Convert to zero-based index - if (fileIndex >= 0 && fileIndex < templateFiles.length) { - // User has entered a valid file number; initialize with this file - const filepath = templateFiles[fileIndex]; - try { - const result = await this.init(`-f "${filepath}"`); // Adjust this call as per your init method's expected format - console.log(stringifyTemplateJSON(result)); - console.log("...try '.out' or 'template.output' to see evaluated template") - } catch (error) { - console.log('Error loading file:', error); - } - } else { - console.log('Invalid file number.'); - } - this.replServer.displayPrompt(); - }); - - // Allow the user to type "abort" to cancel the file open operation - this.replServer.once('SIGINT', () => { - ac.abort(); - }); - - return "open... (type 'abort' to cancel)"; - } - - - public cd(newDirectory: string) { - // Resolve the new path against the current directory to support relative paths - const resolvedNewDirectory = path.resolve(this.currentDirectory, newDirectory); - - // Check if the resolved new directory path is valid - if (fs.existsSync(resolvedNewDirectory) && fs.lstatSync(resolvedNewDirectory).isDirectory()) { - this.currentDirectory = resolvedNewDirectory; - return `Current directory changed to: ${this.currentDirectory}`; - } else { - return `Invalid directory: ${newDirectory}`; - } - } - - public svg(replCmdInputStr:string):string { - const {port=3000} = CliCore.minimistArgs(replCmdInputStr); - - const startServer = () => { - this.server = http.createServer((req, res) => { - // Check for a specific URL path or request method if needed - - // Execute 'dot' to convert the DOT code to SVG - const dotProcess:child_process.ChildProcess = exec(`dot -Tsvg`, (error, stdout, stderr) => { - if (error) { - console.error(`Error converting DOT to SVG: ${error.message}`); - res.writeHead(500, { 'Content-Type': 'text/plain' }); - res.end('Internal Server Error'); - return; - } - - if (stderr) { - console.error(`dot stderr: ${stderr}`); - } - - // Set the response headers for SVG content - res.writeHead(200, { - 'Content-Type': 'image/svg+xml', - }); - - // Send the SVG data as the HTTP response - res.end(stdout); - }); - if(this.templateProcessor && dotProcess) { - const dot = VizGraph.dot(this.templateProcessor); - // Pipe the DOT code string to the 'dot' process - dotProcess.stdin?.write(dot); - dotProcess.stdin?.end(); - } - }); - - this.server.on('error', (error:any) => { - if (error.code === 'EADDRINUSE') { - console.error(`Port ${port} is already in use.`); - } else { - console.error(`Server error: ${error.message}`); - } - }); - - this.server.listen(port, () => { - console.log(`Server is running on port ${port}`); - }); - }; - - if (this.server) { - // Server is already running, return its URL - return `http://localhost:${port}`; - } else { - // Start the server and return its URL - startServer(); - return `http://localhost:${port}`; - } - } - - /** - * this method is just here as a stub to allow tests to pass. Color is in reality handled only by StatedRepl, - * it is not something that is possible to 'see' from the CLI since CLI returns pure JSON which has no concept - * of terminal colors. - */ - color(){ - ""; - } } diff --git a/src/CliCoreBase.ts b/src/CliCoreBase.ts new file mode 100644 index 00000000..c8c46177 --- /dev/null +++ b/src/CliCoreBase.ts @@ -0,0 +1,445 @@ +// Copyright 2023 Cisco Systems, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +import fs from 'fs'; +import path from 'path'; +import TemplateProcessor from './TemplateProcessor.js'; +import yaml from 'js-yaml'; +import minimist from "minimist"; +import parseArgsStringToArgv from 'string-argv'; +import {Levels, LOG_LEVELS} from "./ConsoleLogger.js"; +import VizGraph from "./VizGraph.js"; +import { exec } from 'child_process'; +import http from 'http'; +import * as child_process from "child_process"; +import os from "os"; + +/** + * Base class for building CLIs. By itself can be used for a CLI that does not support the tail command. Tail command + * uses Node repl class that is not implemented in other JS runtimes such as Bun. CliCoreBase should run in Bun. + */ +export class CliCoreBase { + protected templateProcessor: TemplateProcessor; + private logLevel: keyof typeof LOG_LEVELS; + protected currentDirectory:string; + //@ts-ignore + private server: http.Server; //http server to serve SVG images + public onInit: () => Promise|void; + + constructor(templateProcessor: TemplateProcessor) { + this.templateProcessor = templateProcessor; + this.logLevel = "info"; + this.currentDirectory = process.cwd(); + this.onInit = ()=>{}; + } + public async close(){ + if(this.templateProcessor){ + await this.templateProcessor.close(); + } + if(this.server){ + this.server.close(); + } + } + + + static minimistArgs(replCmdInputStr:string) { + const args = parseArgsStringToArgv(replCmdInputStr); + return minimist(args); + + } + static parseInitArgs(replCmdInputStr:string){ + + const parsed = CliCoreBase.minimistArgs(replCmdInputStr); + let {_:bareArgs ,f:filepath, o:oneshot,options="{}", ctx={}} = parsed; + let tags:any = parsed.tags ||""; + if(tags === true){ //weird case of --tags with no arguments + tags = ""; + } + if(tags===""){ + tags=[]; + }else { + tags = tags.split(',').map((s:string) => s.trim()); //tags are provided as JSON array + } + try { + options = JSON.parse(options); + }catch(e:any){ + console.error("failed to parse --options json: " + e.message); + throw e; + } + + filepath = filepath?filepath:bareArgs[0]; + oneshot = oneshot===true?oneshot:bareArgs.length > 0; + const processedArgs = {filepath, tags, oneshot, options, ctx}; + return {...parsed, ...processedArgs}; //spread the processedArgs back into what was parsed + } + + async readFileAndParse(filepath:string, importPath?:string) { + const fileExtension = path.extname(filepath).toLowerCase().replace(/\W/g, ''); + if (fileExtension === 'js' || fileExtension === 'mjs') { + return await import(CliCoreBase.resolveImportPath(filepath, importPath)); + } + + const fileContent = await fs.promises.readFile(filepath, 'utf8'); + + if (fileExtension === 'yaml' || fileExtension === 'yml') { + return yaml.load(fileContent); + } else { + return JSON.parse(fileContent); + } + } + + static isNodeEnvironment() { + return typeof process !== 'undefined' && process.versions != null && process.versions.node != null; + } + + + static resolveImportPath(filepath: any, importPath: any): string { + if (!filepath) throw new Error("filepath is required"); + + // can't do any path resolution in browser + if (!CliCoreBase.isNodeEnvironment()) return filepath; + + if (importPath) { + if (filepath && filepath.startsWith("~")) throw new Error("Cannot use file path starting with '~' with importPath"); + if (filepath && filepath.startsWith("/")) throw new Error("Cannot use file path starting with '/' with importPath"); + if (importPath.startsWith("/")) return path.resolve(path.join(importPath, filepath)) + + if (importPath.startsWith("~")) return path.resolve(path.join(importPath.replace("~", os.homedir()), filepath)); + + //relative path + return path.resolve(path.join(importPath, filepath)); + } + + if (filepath && filepath.includes("~")) return path.normalize(path.resolve(filepath.replace("~", os.homedir()))); + if (filepath && filepath.startsWith("/")) return path.normalize(filepath); + return path.join(process.cwd(), filepath); + } + + //replCmdInoutStr like: -f "defaultSnapshot.json" + + /** + * replCmdInoutStr example: -f "example/restoreSnapshot.json" --tags=["PEACE"] --xf=example/myEnv.json + * @param replCmdInputStr - the command line string that will be parsed into arguments + */ + async restore(replCmdInputStr: string) { + return this.init(replCmdInputStr, true); + + } + + /** + * This Cli core command may be invoked directly from the REPL init command or from restore command + * + * - fromSnapshot=false, replCmdInoutStr example: -f "example/ex23.json" --tags=["PEACE"] --xf=example/myEnv.json + * - fromSnapshot=true, replCmdInoutStr example: -f "example/restoreSnapshot.json" --tags=["PEACE"] --xf=example/myEnv.json + * + * @param replCmdInputStr + * @param fromSnapshot - when set to true, template processor will treat input as a snapshot of a previous + * templateProcessor state + */ + async init(replCmdInputStr:string, fromSnapshot: boolean=false) { + if(this.templateProcessor){ + this.templateProcessor.close(); + } + const parsed:any = CliCoreBase.parseInitArgs(replCmdInputStr); + const {filepath, tags,oneshot, options, xf:contextFilePath, importPath=this.currentDirectory, tail, ctx={}} = parsed; + if(filepath===undefined){ + return undefined; + } + const input = await this.openFile(filepath); + let contextData = contextFilePath ? await this.readFileAndParse(contextFilePath, importPath) : {}; + contextData = {...contextData, ...ctx} //--ctx.foo=bar creates ctx={foo:bar}. The dot argument syntax is built into minimist + options.importPath = importPath; //path is where local imports will be sourced from. We sneak path in with the options + // if we initialize for the first time, we need to create a new instance of TemplateProcessor + if (!this.templateProcessor && !fromSnapshot) { + this.templateProcessor = new TemplateProcessor(input, contextData, options); + } else if (!this.templateProcessor && fromSnapshot) { + this.templateProcessor = TemplateProcessor.constructFromSnapshotObject(input, contextData); + } else { // if we are re-initializing, we need to reset the tagSet and options, if provided + this.templateProcessor.tagSet = new Set(); + this.templateProcessor.options = options; + if (contextData && Object.keys(contextData).length > 0) { + this.templateProcessor.setupContext(contextData); + } + } + this.templateProcessor.onInitialize.set("CLI",this.onInit); + tags.forEach((a:string) => this.templateProcessor.tagSet.add(a)); + // set options + this.templateProcessor.logger.level = this.logLevel; + this.templateProcessor.logger.debug(`arguments: ${JSON.stringify(parsed)}`); + this.templateProcessor.context["open"] = this.openFile.bind(this); //$open('foo.json') is supported by the CLI adding $open function. It is not part of core TemplateProcessor as that would be security hole + try { + let tailPromise; + if(tail !== undefined){ + tailPromise = this.tail(tail); + } + if (fromSnapshot) { // restore from a snapshot + await this.templateProcessor.initialize(undefined, "/", input); + } else { + await this.templateProcessor.initialize(input); + } + const {__init} = contextData; + __init && __init(this.templateProcessor); //if a function named __init is found in the --xf, said context function is run + if(tail !== undefined){ + return tailPromise; + } + if (oneshot === true) { + return this.templateProcessor.output; + } + return this.templateProcessor.input; + + } catch (error:any) { + return { + name: error.name, + message: error.message + }; + } + + } + + private async openFile(fname:string){ + let _filepath = fname; + if(this.currentDirectory){ + _filepath = path.join(this.currentDirectory, _filepath); + } + return await this.readFileAndParse(_filepath); + } + + + async set(args:string) { + const options:any = args.match(/(?:[^\s"]+|"[^"]*")+/g); + let [path, data] = options; + let jsonPtr = path; + if (path === '-f') { + try { + // Read file + const fileContent = await fs.promises.readFile(data, 'utf8'); + const tmp = JSON.parse(fileContent); + jsonPtr = tmp.path; // Assumes the file contains an object with 'path' and 'data' properties + data = tmp.data; + } catch (err) { + console.error('Error reading file:', err); + throw err; + } + } + + if (!this.templateProcessor) { + throw new Error('Initialize the template first.'); + } + try { + data = JSON.parse(data); + } catch (err) { + console.error('Error parsing JSON data:', err); + throw err; + } + + await this.templateProcessor.setData(jsonPtr, data); + return this.templateProcessor.output; + } + + in() { + if (!this.templateProcessor) { + throw new Error('Initialize the template first.'); + } + return this.templateProcessor.input; + } + + out(replCmdInputStr:string) { + if (!this.templateProcessor) { + throw new Error('Initialize the template first.'); + } + const parsed = CliCoreBase.minimistArgs(replCmdInputStr === undefined ? "" : replCmdInputStr) + let {_:jsonPointer=""} = parsed; + if(Array.isArray(jsonPointer)){ + jsonPointer = jsonPointer[0]; + if(jsonPointer===undefined){ + jsonPointer = ""; + } + } + return this.templateProcessor.out(jsonPointer); + } + + state() { + if (!this.templateProcessor) { + throw new Error('Initialize the template first.'); + } + return this.templateProcessor.templateMeta; + } + + from(args:string) { + if (!this.templateProcessor) { + throw new Error('Initialize the template first.'); + } + const [jsonPtr, option] = args.split(' '); + return option === '--shallow' ? this.templateProcessor.getDependents(jsonPtr) : this.templateProcessor.from(jsonPtr); + } + + to(args:string) { + if (!this.templateProcessor) { + throw new Error('Initialize the template first.'); + } + const [jsonPtr, option] = args.split(' '); + return option === '--shallow' ? this.templateProcessor.getDependencies(jsonPtr) : this.templateProcessor.to(jsonPtr); + } + + async plan() { + if (!this.templateProcessor) { + throw new Error('Initialize the template first.'); + } + return await this.templateProcessor.getEvaluationPlan(); + } + + log(level:Levels) { + this.logLevel = level; + if(this.templateProcessor){ + this.templateProcessor.logger.level = level; + } + return {"log level":level}; + } + + note(){ + return "============================================================="; + } + + async debug(replCmdInputStr:string) { + if (!this.templateProcessor) { + throw new Error('Initialize the template first.'); + } + const parsed = CliCoreBase.minimistArgs(replCmdInputStr) + return this.templateProcessor.debugger.processCommands(parsed); + } + + async errors() { + if (!this.templateProcessor) { + throw new Error('Initialize the template first.'); + } + return this.templateProcessor.errorReport; + } + + protected extractArgsInfo(args:string) { + // Define the regex patterns + const jsonPointerNumberPattern = /^(?\/[^\s]*)(?:\s+(?\d+))?$/; + const untilJsonataPattern = /^(?\/[^\s]*)\s+until\s+(?[^\n]+)$/; + + // Try to match the args string against both patterns + const matchNumberFormat = args.match(jsonPointerNumberPattern); + const matchUntilJsonataFormat = args.match(untilJsonataPattern); + + // Check which format was matched + if (matchNumberFormat) { + // Extracted information for format + const { jsonPointer, number } = matchNumberFormat.groups || {}; + if (jsonPointer) { + return { format: "Number", jsonPointer, number: parseInt(number, 10) }; + } + } else if (matchUntilJsonataFormat) { + // Extracted information for format + const { jsonPointer, jsonataExpression } = matchUntilJsonataFormat.groups || {}; + if (jsonPointer) { + return { format: "UntilJsonata", jsonPointer, jsonataExpression }; + } + } + + throw new Error(`invalid --tail args: ${args}`); + } + + + public cd(newDirectory: string) { + // Resolve the new path against the current directory to support relative paths + const resolvedNewDirectory = path.resolve(this.currentDirectory, newDirectory); + + // Check if the resolved new directory path is valid + if (fs.existsSync(resolvedNewDirectory) && fs.lstatSync(resolvedNewDirectory).isDirectory()) { + this.currentDirectory = resolvedNewDirectory; + return `Current directory changed to: ${this.currentDirectory}`; + } else { + return `Invalid directory: ${newDirectory}`; + } + } + + public svg(replCmdInputStr:string):string { + const {port=3000} = CliCoreBase.minimistArgs(replCmdInputStr); + + const startServer = () => { + this.server = http.createServer((req, res) => { + // Check for a specific URL path or request method if needed + + // Execute 'dot' to convert the DOT code to SVG + const dotProcess:child_process.ChildProcess = exec(`dot -Tsvg`, (error, stdout, stderr) => { + if (error) { + console.error(`Error converting DOT to SVG: ${error.message}`); + res.writeHead(500, { 'Content-Type': 'text/plain' }); + res.end('Internal Server Error'); + return; + } + + if (stderr) { + console.error(`dot stderr: ${stderr}`); + } + + // Set the response headers for SVG content + res.writeHead(200, { + 'Content-Type': 'image/svg+xml', + }); + + // Send the SVG data as the HTTP response + res.end(stdout); + }); + if(this.templateProcessor && dotProcess) { + const dot = VizGraph.dot(this.templateProcessor); + // Pipe the DOT code string to the 'dot' process + dotProcess.stdin?.write(dot); + dotProcess.stdin?.end(); + } + }); + + this.server.on('error', (error:any) => { + if (error.code === 'EADDRINUSE') { + console.error(`Port ${port} is already in use.`); + } else { + console.error(`Server error: ${error.message}`); + } + }); + + this.server.listen(port, () => { + console.log(`Server is running on port ${port}`); + }); + }; + + if (this.server) { + // Server is already running, return its URL + return `http://localhost:${port}`; + } else { + // Start the server and return its URL + startServer(); + return `http://localhost:${port}`; + } + } + + /** + * this method is just here as a stub to allow tests to pass. Color is in reality handled only by StatedRepl, + * it is not something that is possible to 'see' from the CLI since CLI returns pure JSON which has no concept + * of terminal colors. + */ + color(){ + return; + } + + getTemplateProcessor() { + return this.templateProcessor; + } + + public async tail(args: string): Promise { + throw new Error('tail command is not implemented in CliCoreBase'); + } +} + diff --git a/src/StatedREPL.ts b/src/StatedREPL.ts index 70243a6c..e3d764fd 100755 --- a/src/StatedREPL.ts +++ b/src/StatedREPL.ts @@ -22,7 +22,7 @@ import TemplateProcessor from "./TemplateProcessor.js"; export default class StatedREPL { private readonly cliCore: CliCore; //@ts-ignore - r: repl.REPLServer; + replServer: repl.REPLServer; private isColorized:boolean=false; constructor(templateProcessor: TemplateProcessor) { this.cliCore = new CliCore(templateProcessor); @@ -67,31 +67,33 @@ export default class StatedREPL { return; //do not start REPL. We produced oneshot output, now bail } //crank up the interactive REPL - this.r = repl.start({ + this.replServer = repl.start({ prompt: '> ', useColors:true, useGlobal:true }); - this.cliCore.replServer = this.r; + //make variable called 'template' accessible in REPL + this.replServer.context.template = this.cliCore.getTemplateProcessor(); + this.cliCore.replServer = this.replServer; this.registerCommands(); } close(){ this.cliCore.close(); - this.r.close(); + this.replServer.close(); } registerCommands() { StatedREPL.CLICORE_COMMANDS.map(c=>{ const [cmdName, helpMsg] = c; - this.r.defineCommand(cmdName, { + this.replServer.defineCommand(cmdName, { help: helpMsg, action: async (args) => { await this.cli(cmdName, args); }, }); }); - this.r.defineCommand("color", { + this.replServer.defineCommand("color", { help: "[on|off] colorize JSON", action: async (args) => { if(args.trim()==="on"){ @@ -99,25 +101,25 @@ export default class StatedREPL { }else if(args.trim()==="off"){ this.isColorized = false; } - this.r.displayPrompt(); + this.replServer.displayPrompt(); }, }); //these other commands are REPL-only commands and are not part of the CLiCore that does //template processing - this.r.defineCommand('help', { + this.replServer.defineCommand('help', { help: 'Display available commands and their descriptions', action: () => { try { console.log('Available commands:'); - Object.entries(this.r.commands).forEach(([name, command]) => { + Object.entries(this.replServer.commands).forEach(([name, command]) => { //@ts-ignore console.log(` .${name} - ${command.help}`); }); } catch (e) { console.error(e); } - this.r.displayPrompt(); + this.replServer.displayPrompt(); }, }); } @@ -137,7 +139,7 @@ export default class StatedREPL { } catch (e:any) { console.error(stringify(e.message)); } - this.r.displayPrompt(); + this.replServer.displayPrompt(); } static colorize(s:string):string{ diff --git a/src/index.ts b/src/index.ts index c459c20d..79009c01 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,4 +5,5 @@ export * from './TemplateProcessor.js'; export * as MetaInfoProducer from './MetaInfoProducer.js'; export {default as JsonPointer} from './JsonPointer.js' export {stringifyTemplateJSON} from './utils/stringify.js' +export {CliCoreBase} from './CliCoreBase.js'; diff --git a/src/test/Pulsar.test.js b/src/test/Pulsar.test.js index 3c523734..a3411b8f 100644 --- a/src/test/Pulsar.test.js +++ b/src/test/Pulsar.test.js @@ -1,47 +1,106 @@ -// pulsar.test.js -import Pulsar from 'pulsar-client'; +import pulsar from 'pulsar-flex'; +import {jest, describe, beforeAll, afterAll, test, expect} from "@jest/globals"; -describe('Pulsar Standalone Mode', () => { - let client; +describe('pulsar-flex Integration Test', () => { + //jest.useFakeTimers() let producer; let consumer; + const topic = "persistent://public/default/yyy"; + const subscription = "test-subscription-xxx"; + + const messagesToSend = [ + { properties: { pulsar: "flex" }, payload: 'Ayeo' } + ]; + + let receivedMessages = []; + + // Increase Jest's default timeout since Pulsar operations might take longer + jest.setTimeout(1000000000); // 20 seconds + beforeAll(async () => { - // Create a Pulsar client connected to the local standalone broker - client = new Pulsar.Client({ - serviceUrl: 'pulsar://localhost:6650', + // Initialize Producer + producer = new pulsar.Producer({ + topic: topic, + discoveryServers: ['localhost:6650'], + // If your Pulsar setup requires JWT, ensure it's set in the environment variables + jwt: process.env.JWT_TOKEN, + producerAccessMode: pulsar.Producer.ACCESS_MODES.SHARED, + logLevel: pulsar.logLevel.TRACE + // Optionally, provide a logCreator function for custom logging + }); + + // Initialize Consumer + consumer = new pulsar.Consumer({ + topic: topic, + subscription: subscription, + discoveryServers: ['localhost:6650'], + jwt: process.env.JWT_TOKEN, + subType: pulsar.Consumer.SUB_TYPES.EXCLUSIVE, + consumerName: 'Test Consumer xxx', + receiveQueueSize: 1, + logLevel: pulsar.logLevel.TRACE, + // Optionally, provide a logCreator function for custom logging }); - // Create a producer on a test topic - producer = await client.createProducer({ - topic: 'persistent://public/default/test-topic', + // Create Producer + await producer.create(); + + + // Optional: Listen to Consumer state changes + consumer.onStateChange(({ previousState, newState }) => { + //console.log(`Consumer state changed from ${previousState} to ${newState}.`); }); - // Create a consumer to verify message delivery - consumer = await client.subscribe({ - topic: 'persistent://public/default/test-topic', - subscription: 'test-subscription', - subscriptionType: 'Exclusive', + // Subscribe Consumer + await consumer.subscribe(); + + // Run Consumer + await consumer.run({ + onMessage: async ({ ack, message, properties, redeliveryCount }) => { + await ack(); // Acknowledge the message + receivedMessages.push({ + message: message, // Contains the payload + properties: properties, // Message properties + redeliveryCount: redeliveryCount, // Number of times the message was redelivered + }); + }, + autoAck: false, // Manual acknowledgment }); }); - afterAll(async () => { - // Clean up: close the producer, consumer, and client + test('should produce and consume messages successfully', async () => { + // Send a batch of messages + await producer.sendMessage({ properties: { pulsar: "flex" }, payload: 'Ayeo' }); await producer.close(); - await consumer.close(); - await client.close(); - }); + // Wait for messages to be received + const maxWaitTime = 10000; // 10 seconds + const pollInterval = 100; // 100ms + let waited = 0; + + while (receivedMessages.length < 1 && waited < maxWaitTime) { + await new Promise(resolve => setTimeout(resolve, pollInterval)); + waited += pollInterval; + } - test('should produce and consume a message', async () => { - // Send a test message - const message = Buffer.from('Hello, Pulsar!'); - await producer.send({ data: message }); + // Assertions + expect(receivedMessages.length).toBe(messagesToSend.length); - // Receive the message - const msg = await consumer.receive(); - expect(msg.getData().toString()).toBe('Hello, Pulsar!'); + receivedMessages.forEach((received, index) => { + expect(received.message.toString()).toBe(messagesToSend[index].payload); + expect(received.properties).toEqual(messagesToSend[index].properties); + expect(received.redeliveryCount).toBe(0); // Assuming no redeliveries + }); - // Acknowledge the message - consumer.acknowledge(msg); + try { + await consumer.unsubscribe(); + } catch (error) { + console.error('Error during cleanup:', error); + } + /** uncomment these lines, and you will find that the test completes normally with no open handles + * detected. + */ + producer._client.getCnx().close(); + await new Promise(resolve => setTimeout(resolve, 11000)); }); }); diff --git a/src/test/StatedREPL.test.js b/src/test/StatedREPL.test.js index fa86b0ee..5491d0b2 100644 --- a/src/test/StatedREPL.test.js +++ b/src/test/StatedREPL.test.js @@ -33,34 +33,69 @@ test("test stringify custom print function", async () => { }`); }); -/** Test that the onInit function is called when the .init command is called */ -test("test onInit", async () => { - const repl1 = new StatedREPL(); - await repl1.initialize(); - - const repl2 = new StatedREPL(); - await repl2.initialize(); - - try { - let beenCalled1 = false; - repl1.cliCore.onInit = () => { - beenCalled1 = true; +if(typeof Bun === "undefined") { //run on node, not bun + /** Test that the onInit function is called when the .init command is called */ + test("test onInitxx", async () => { + const repl1 = new StatedREPL(); + await repl1.initialize(); + + const repl2 = new StatedREPL(); + await repl2.initialize(); + + try { + let beenCalled1 = false; + repl1.cliCore.onInit = () => { + beenCalled1 = true; + } + let beenCalled2 = false; + repl2.cliCore.onInit = () => { + beenCalled2 = true; + } + await repl1.cliCore.init('-f "example/ex01.yaml"'); + expect(beenCalled1).toBe(true); + expect(beenCalled2).toBe(false); + + await repl2.cliCore.init('-f "example/ex01.yaml"'); + expect(beenCalled2).toBe(true); + } finally { + await repl1.close(); + await repl2.close(); } - let beenCalled2 = false; - repl2.cliCore.onInit = () => { - beenCalled2 = true; + }); + // Validates restore command + test("Extend CliCore with restore command", async () => { + + // ensure jest argv does not interfere with the test + const originalCmdLineArgsStr = process.argv; + process.argv = ["node", "dist/stated.js"]; // this is an argv when running stated.js repl. + + // extend CliCore with restore command + const repl = new StatedREPL(); + + try { + await repl.initialize(); + + // we call restore on the repl, which will expect it to be defined in CliCore. + await repl.cli('restore', '-f example/restoreSnapshot.json'); + + console.log(stringify(repl.cliCore.templateProcessor.output)); + expect(repl.cliCore.templateProcessor.output).toBeDefined(); + expect(repl.cliCore.templateProcessor.output.count).toBeGreaterThanOrEqual(3); // should be 3 or more right after restoring from the snapshot + expect(repl.cliCore.templateProcessor.output.count).toBeLessThan(10); // ... but less than 10 + + + while (repl.cliCore.templateProcessor.output.count < 10) { // validates that templateProcessor picks up where it was left in the snapshot. + console.log("waiting for output.count to reach 10") + await new Promise(resolve => setTimeout(resolve, 50)); + } + expect(repl.cliCore.templateProcessor.output.count).toBe(10); + } finally { + process.argv = originalCmdLineArgsStr; + if (repl !== undefined) await repl.close(); } - await repl1.cliCore.init('-f "example/ex01.yaml"'); - expect(beenCalled1).toBe(true); - expect(beenCalled2).toBe(false); - - await repl2.cliCore.init('-f "example/ex01.yaml"'); - expect(beenCalled2).toBe(true); - }finally { - await repl1.close(); - await repl2.close(); - } -}); + }); + +} // This test validates a bug when running an init command in StatedREPL overwrites context of provided TemplateProcessor test("TemplateProcessor keeps context on init", async () => { @@ -78,35 +113,3 @@ test("TemplateProcessor keeps context on init", async () => { ); }); -// Validates restore command -test("Extend CliCore with restore command", async () => { - - // ensure jest argv does not interfere with the test - const originalCmdLineArgsStr = process.argv; - process.argv = ["node", "dist/stated.js"]; // this is an argv when running stated.js repl. - - // extend CliCore with restore command - const repl = new StatedREPL(); - - try { - await repl.initialize(); - - // we call restore on the repl, which will expect it to be defined in CliCore. - await repl.cli('restore', '-f example/restoreSnapshot.json'); - - console.log(stringify(repl.cliCore.templateProcessor.output)); - expect(repl.cliCore.templateProcessor.output).toBeDefined(); - expect(repl.cliCore.templateProcessor.output.count).toBeGreaterThanOrEqual(3); // should be 3 or more right after restoring from the snapshot - expect(repl.cliCore.templateProcessor.output.count).toBeLessThan(10); // ... but less than 10 - - - while (repl.cliCore.templateProcessor.output.count < 10) { // validates that templateProcessor picks up where it was left in the snapshot. - console.log("waiting for output.count to reach 10") - await new Promise(resolve => setTimeout(resolve, 50)); - } - expect(repl.cliCore.templateProcessor.output.count).toBe(10); - } finally { - process.argv = originalCmdLineArgsStr; - if (repl !== undefined) await repl.close(); - } -}); \ No newline at end of file diff --git a/src/test/TemplateProcessor.test.js b/src/test/TemplateProcessor.test.js index b7ce3525..6e666e8c 100644 --- a/src/test/TemplateProcessor.test.js +++ b/src/test/TemplateProcessor.test.js @@ -22,7 +22,7 @@ import {dirname} from 'path'; import DependencyFinder from "../../dist/src/DependencyFinder.js"; import jsonata from "jsonata"; import { default as jp } from "../../dist/src/JsonPointer.js"; -import {expect} from "@jest/globals"; +//import {expect} from "@jest/globals"; import StatedREPL from "../../dist/src/StatedREPL.js"; test("test 1", async () => { diff --git a/src/test/utils/rateLimit.test.js b/src/test/utils/rateLimit.test.js index 47e30538..3528c109 100644 --- a/src/test/utils/rateLimit.test.js +++ b/src/test/utils/rateLimit.test.js @@ -13,54 +13,64 @@ // limitations under the License. import { rateLimit } from "../../../dist/src/utils/rateLimit.js"; -import {expect, jest} from '@jest/globals' +import { jest, expect, describe, beforeEach, afterEach, test} from '@jest/globals'; -describe('rateLimit function', () => { - jest.useFakeTimers(); - /** - * Below test validates the following scenario - * rateLimitedFunction('First call'); // called at 0ms and Executed immediately - * rateLimitedFunction('Second call'); // called at 500ms, deferred till execution at 1000ms - * rateLimitedFunction('Third call'); // called at 700ms, deferred till execution at 1000ms, and replaces the Second call - * // at 1000ms 'Third call' gets executed. - * rateLimitedFunction('Forth call'); // called at 1100ms and gets executed in 2000ms - **/ - it('should rate limit function calls as specified', () => { - const mockFunction = jest.fn(); - const maxWait = 1000; - const rateLimitedFunction = rateLimit(mockFunction, maxWait); +if(typeof Bun === 'undefined'){ //advanceTimersByTime is not available in Bun + describe('rateLimit function', () => { + beforeEach(() => { + // Enable fake timers before each test + jest.useFakeTimers('modern'); + }); - // First call - executed immediately - rateLimitedFunction('First call'); - expect(mockFunction).toHaveBeenCalledTimes(1); - expect(mockFunction).toHaveBeenCalledWith('First call'); + afterEach(() => { + // Restore real timers after each test + jest.useRealTimers(); + }); - // Second call - deferred - jest.advanceTimersByTime(500); - rateLimitedFunction('Second call'); - expect(mockFunction).toHaveBeenCalledTimes(1); + /** + * Below test validates the following scenario + * rateLimitedFunction('First call'); // called at 0ms and Executed immediately + * rateLimitedFunction('Second call'); // called at 500ms, deferred till execution at 1000ms + * rateLimitedFunction('Third call'); // called at 700ms, deferred till execution at 1000ms, and replaces the Second call + * // at 1000ms 'Third call' gets executed. + * rateLimitedFunction('Forth call'); // called at 1100ms and gets executed in 2000ms + **/ + test('should rate limit function calls as specified', () => { + const mockFunction = jest.fn(); + const maxWait = 1000; + const rateLimitedFunction = rateLimit(mockFunction, maxWait); - // Third call - replaces second, also deferred - jest.advanceTimersByTime(200); - rateLimitedFunction('Third call'); - expect(mockFunction).toHaveBeenCalledTimes(1); + // First call - executed immediately + rateLimitedFunction('First call'); + expect(mockFunction).toHaveBeenCalledTimes(1); + expect(mockFunction).toHaveBeenCalledWith('First call'); - // Executing the deferred 'Third call' - jest.advanceTimersByTime(350); - expect(mockFunction).toHaveBeenCalledTimes(2); - expect(mockFunction).toHaveBeenCalledWith('Third call'); + // Second call - deferred + jest.advanceTimersByTime(500); + rateLimitedFunction('Second call'); + expect(mockFunction).toHaveBeenCalledTimes(1); - // Fourth call - at 1100ms from start gets defferred till 2000ms - jest.advanceTimersByTime(100); - rateLimitedFunction('Forth call'); - jest.advanceTimersByTime(900); - expect(mockFunction).toHaveBeenCalledTimes(3); - expect(mockFunction).toHaveBeenCalledWith('Forth call'); + // Third call - replaces second, also deferred + jest.advanceTimersByTime(200); + rateLimitedFunction('Third call'); + expect(mockFunction).toHaveBeenCalledTimes(1); - // no more calls expected - jest.advanceTimersByTime(1000); - expect(mockFunction).toHaveBeenCalledTimes(3); - }); -}); + // Executing the deferred 'Third call' + jest.advanceTimersByTime(350); + expect(mockFunction).toHaveBeenCalledTimes(2); + expect(mockFunction).toHaveBeenCalledWith('Third call'); + + // Fourth call - at 1100ms from start gets defferred till 2000ms + jest.advanceTimersByTime(100); + rateLimitedFunction('Forth call'); + jest.advanceTimersByTime(900); + expect(mockFunction).toHaveBeenCalledTimes(3); + expect(mockFunction).toHaveBeenCalledWith('Forth call'); + // no more calls expected + jest.advanceTimersByTime(1000); + expect(mockFunction).toHaveBeenCalledTimes(3); + }); + }); +} diff --git a/src/utils/stringify.ts b/src/utils/stringify.ts index 3da53839..515f0d9e 100644 --- a/src/utils/stringify.ts +++ b/src/utils/stringify.ts @@ -31,10 +31,12 @@ export const circularReplacer = (key: any, value: any) => { return "--compiled expression--"; } if (null !== value) { + const tag = Object.prototype.toString.call(value); const { _idleTimeout, _onTimeout } = value; - if (_idleTimeout !== undefined && _onTimeout !== undefined) { + if (tag === '[object Timeout]'|| (_idleTimeout !== undefined && _onTimeout !== undefined)) { //Node.js return "--interval/timeout--"; } + if (value instanceof Set) { return Array.from(value); } diff --git a/yarn.lock b/yarn.lock index 4bcaff8f..e51a77a8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23,7 +23,7 @@ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.20.tgz" integrity sha512-BQYjKbpXjoXwFW5jGqiizJQQT/aC7pFm9Ok1OWssonuguICi264lbgMzRp2ZMmRSlfkX6DsWDDcsrctK8Rwfiw== -"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.22.20": +"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.0.0-0 || ^8.0.0-0 <8.0.0", "@babel/core@^7.11.6", "@babel/core@^7.12.0", "@babel/core@^7.12.3", "@babel/core@^7.13.0", "@babel/core@^7.22.20", "@babel/core@^7.4.0 || ^8.0.0-0 <8.0.0", "@babel/core@^7.8.0": version "7.22.20" resolved "https://registry.npmjs.org/@babel/core/-/core-7.22.20.tgz" integrity sha512-Y6jd1ahLubuYweD/zJH+vvOY141v4f9igNQAQ+MBgq9JlHS2iTsZKn1aMsb3vGccZsXI16VzTBw52Xx0DWmtnA== @@ -1098,7 +1098,7 @@ jest-mock "^29.7.0" jest-util "^29.7.0" -"@jest/globals@^29.7.0": +"@jest/globals@^29.7.0", "@jest/globals@latest": version "29.7.0" resolved "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz" integrity sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ== @@ -1234,16 +1234,16 @@ "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/sourcemap-codec@1.4.14": - version "1.4.14" - resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz" - integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== - "@jridgewell/sourcemap-codec@^1.4.10": version "1.4.15" resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== +"@jridgewell/sourcemap-codec@1.4.14": + version "1.4.14" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + "@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.9": version "0.3.18" resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz" @@ -1252,21 +1252,6 @@ "@jridgewell/resolve-uri" "3.1.0" "@jridgewell/sourcemap-codec" "1.4.14" -"@mapbox/node-pre-gyp@^1.0.11": - version "1.0.11" - resolved "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz" - integrity sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ== - dependencies: - detect-libc "^2.0.0" - https-proxy-agent "^5.0.0" - make-dir "^3.1.0" - node-fetch "^2.6.7" - nopt "^5.0.0" - npmlog "^5.0.1" - rimraf "^3.0.2" - semver "^7.3.5" - tar "^6.1.11" - "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" @@ -1275,7 +1260,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": +"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -1409,19 +1394,14 @@ dependencies: "@types/lodash" "*" -"@types/lodash@*": +"@types/lodash@*", "@types/lodash@^4.14.195": version "4.17.0" resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.0.tgz" integrity sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA== -"@types/lodash@^4.14.195": - version "4.17.9" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.9.tgz#0dc4902c229f6b8e2ac5456522104d7b1a230290" - integrity sha512-w9iWudx1XWOHW5lQRS9iKpK/XuRhnN+0T7HvdCCd802FYkT1AMTnxndJHGrNJwRoRHkslGr4S29tjm1cT7x/7w== - "@types/minimist@^1.2.5": version "1.2.5" - resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.5.tgz#ec10755e871497bcd83efe927e43ec46e8c0747e" + resolved "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz" integrity sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag== "@types/node@*": @@ -1451,7 +1431,7 @@ dependencies: "@types/yargs-parser" "*" -"@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5": +"@webassemblyjs/ast@^1.11.5", "@webassemblyjs/ast@1.11.6": version "1.11.6" resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz" integrity sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q== @@ -1552,7 +1532,7 @@ "@webassemblyjs/wasm-gen" "1.11.6" "@webassemblyjs/wasm-parser" "1.11.6" -"@webassemblyjs/wasm-parser@1.11.6", "@webassemblyjs/wasm-parser@^1.11.5": +"@webassemblyjs/wasm-parser@^1.11.5", "@webassemblyjs/wasm-parser@1.11.6": version "1.11.6" resolved "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz" integrity sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ== @@ -1597,28 +1577,16 @@ resolved "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== -abbrev@1: - version "1.1.1" - resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - acorn-import-assertions@^1.9.0: version "1.9.0" resolved "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz" integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== -acorn@^8.7.1, acorn@^8.8.2: +acorn@^8, acorn@^8.7.1, acorn@^8.8.2: version "8.10.0" resolved "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz" integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== -agent-base@6: - version "6.0.2" - resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - ajv-formats@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz" @@ -1638,7 +1606,7 @@ ajv-keywords@^5.1.0: dependencies: fast-deep-equal "^3.1.3" -ajv@^6.12.5: +ajv@^6.12.5, ajv@^6.9.1: version "6.12.6" resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -1648,7 +1616,7 @@ ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.0, ajv@^8.9.0: +ajv@^8.0.0, ajv@^8.8.2, ajv@^8.9.0: version "8.12.0" resolved "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz" integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== @@ -1687,7 +1655,14 @@ ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" -ansi-styles@^4.0.0, ansi-styles@^4.1.0: +ansi-styles@^4.0.0: + version "4.3.0" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== @@ -1712,19 +1687,6 @@ anymatch@^3.0.3: normalize-path "^3.0.0" picomatch "^2.0.4" -"aproba@^1.0.3 || ^2.0.0": - version "2.0.0" - resolved "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz" - integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== - -are-we-there-yet@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz" - integrity sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw== - dependencies: - delegates "^1.0.0" - readable-stream "^3.6.0" - argparse@^1.0.7: version "1.0.10" resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" @@ -1839,13 +1801,6 @@ balanced-match@^1.0.0: resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -bindings@^1.5.0: - version "1.5.0" - resolved "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz" - integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== - dependencies: - file-uri-to-path "1.0.0" - brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" @@ -1868,7 +1823,7 @@ braces@^3.0.2: dependencies: fill-range "^7.0.1" -browserslist@^4.14.5, browserslist@^4.21.10, browserslist@^4.21.9: +browserslist@^4.14.5, browserslist@^4.21.10, browserslist@^4.21.9, "browserslist@>= 4.21.0": version "4.21.10" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz" integrity sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ== @@ -1910,7 +1865,16 @@ caniuse-lite@^1.0.30001517: resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001535.tgz" integrity sha512-48jLyUkiWFfhm/afF7cQPqPjaUmSraEhK4j+FCTJpgnGGEZHqyLe3hmWH7lIooZdSzXL0ReMvHz0vKDoTBsrwg== -chalk@^2.4.1, chalk@^2.4.2: +chalk@^2.4.1: + version "2.4.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^2.4.2: version "2.4.2" resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -1937,11 +1901,6 @@ char-regex@^1.0.2: resolved "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz" integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== -chownr@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz" - integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== - chrome-trace-event@^1.0.2: version "1.0.3" resolved "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz" @@ -1999,7 +1958,7 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@1.1.3, color-name@^1.0.0: +color-name@^1.0.0, color-name@1.1.3: version "1.1.3" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== @@ -2017,11 +1976,6 @@ color-string@^1.6.0: color-name "^1.0.0" simple-swizzle "^0.2.2" -color-support@^1.1.2: - version "1.1.3" - resolved "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz" - integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== - color@^3.1.3: version "3.2.1" resolved "https://registry.npmjs.org/color/-/color-3.2.1.tgz" @@ -2063,11 +2017,6 @@ concat-map@0.0.1: resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -console-control-strings@^1.0.0, console-control-strings@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz" - integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== - convert-source-map@^1.6.0, convert-source-map@^1.7.0: version "1.9.0" resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz" @@ -2097,6 +2046,11 @@ core-js-compat@^3.31.0: dependencies: browserslist "^4.21.10" +crc-full@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/crc-full/-/crc-full-1.1.0.tgz" + integrity sha512-7YK4t8C9PiekOSnBotYjU2roaaorUXHyT+Xzb12Zgg4DsfG58AxmPk2/wx7XnC9UXyriqRvl3c+U0zFsZkdVYg== + create-jest@^29.7.0: version "29.7.0" resolved "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz" @@ -2119,7 +2073,7 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" -debug@4, debug@^4.1.0, debug@^4.1.1: +debug@^4.1.0, debug@^4.1.1: version "4.3.4" resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -2136,16 +2090,6 @@ deepmerge@^4.2.2: resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz" integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz" - integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== - -detect-libc@^2.0.0: - version "2.0.3" - resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz" - integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw== - detect-newline@^3.0.0: version "3.1.0" resolved "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz" @@ -2349,11 +2293,6 @@ fecha@^4.2.0: resolved "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz" integrity sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw== -file-uri-to-path@1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz" - integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== - fill-range@^7.0.1: version "7.0.1" resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" @@ -2403,13 +2342,6 @@ foreground-child@^3.1.0: cross-spawn "^7.0.0" signal-exit "^4.0.1" -fs-minipass@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz" - integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== - dependencies: - minipass "^3.0.0" - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" @@ -2417,7 +2349,7 @@ fs.realpath@^1.0.0: fsevents@^2.3.2: version "2.3.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== function-bind@^1.1.1: @@ -2425,21 +2357,6 @@ function-bind@^1.1.1: resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -gauge@^3.0.0: - version "3.0.2" - resolved "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz" - integrity sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q== - dependencies: - aproba "^1.0.3 || ^2.0.0" - color-support "^1.1.2" - console-control-strings "^1.0.0" - has-unicode "^2.0.1" - object-assign "^4.1.1" - signal-exit "^3.0.0" - string-width "^4.2.3" - strip-ansi "^6.0.1" - wide-align "^1.1.2" - gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz" @@ -2518,6 +2435,11 @@ globby@^13.1.1: merge2 "^1.4.1" slash "^4.0.0" +google-protobuf@^3.17.3: + version "3.21.4" + resolved "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.21.4.tgz" + integrity sha512-MnG7N936zcKTco4Jd2PX2U96Kf9PxygAPKBug+74LHzmHXmceN16MmRcdgZv+DGef/S9YvQAfRsNCn4cjf9yyQ== + graceful-fs@^4.1.2, graceful-fs@^4.2.4, graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" @@ -2533,11 +2455,6 @@ has-flag@^4.0.0: resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-unicode@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz" - integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== - has@^1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" @@ -2550,14 +2467,6 @@ html-escaper@^2.0.0: resolved "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== -https-proxy-agent@^5.0.0: - version "5.0.1" - resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz" - integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== - dependencies: - agent-base "6" - debug "4" - human-signals@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" @@ -2589,7 +2498,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.3: +inherits@^2.0.3, inherits@2: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -2931,7 +2840,7 @@ jest-resolve-dependencies@^29.7.0: jest-regex-util "^29.6.3" jest-snapshot "^29.7.0" -jest-resolve@^29.7.0: +jest-resolve@*, jest-resolve@^29.7.0: version "29.7.0" resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz" integrity sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA== @@ -3152,10 +3061,10 @@ json5@^2.2.3: resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== -jsonata@^2.0.3: - version "2.0.3" - resolved "https://registry.npmjs.org/jsonata/-/jsonata-2.0.3.tgz" - integrity sha512-Up2H81MUtjqI/dWwWX7p4+bUMfMrQJVMN/jW6clFMTiYP528fBOBNtRu944QhKTs3+IsVWbgMeUTny5fw2VMUA== +jsonata@2.0.4: + version "2.0.4" + resolved "https://registry.npmjs.org/jsonata/-/jsonata-2.0.4.tgz" + integrity sha512-vfavX4/G/yrYxE+UrmT/oUJ3ph7KqUrb0R7b0LVRcntQwxw+Z5kA1pNUIQzX5hF04Oe1eKxyoIPsmXtc2LgJTQ== jsonc-parser@^3.2.0: version "3.2.1" @@ -3262,13 +3171,6 @@ lunr@^2.3.9: resolved "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz" integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow== -make-dir@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - make-dir@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz" @@ -3349,14 +3251,7 @@ minimist@^1.2.8: resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== -minipass@^3.0.0: - version "3.3.6" - resolved "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz" - integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== - dependencies: - yallist "^4.0.0" - -minipass@^5.0.0, "minipass@^5.0.0 || ^6.0.2 || ^7.0.0": +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": version "5.0.0" resolved "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz" integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== @@ -3366,20 +3261,7 @@ minipass@^7.0.4: resolved "https://registry.npmjs.org/minipass/-/minipass-7.1.1.tgz" integrity sha512-UZ7eQ+h8ywIRAW1hIEl2AqdwzJucU/Kp59+8kkZeSvafXhZjul247BvIJjEVFVeON6d7lM46XX1HXCduKAS8VA== -minizlib@^2.1.1: - version "2.1.2" - resolved "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz" - integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== - dependencies: - minipass "^3.0.0" - yallist "^4.0.0" - -mkdirp@^1.0.3: - version "1.0.4" - resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - -ms@2.1.2, ms@^2.1.1: +ms@^2.1.1, ms@2.1.2: version "2.1.2" resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== @@ -3394,18 +3276,6 @@ neo-async@^2.6.2: resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -node-addon-api@^4.3.0: - version "4.3.0" - resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz" - integrity sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ== - -node-fetch@^2.6.7: - version "2.7.0" - resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz" - integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== - dependencies: - whatwg-url "^5.0.0" - node-int64@^0.4.0: version "0.4.0" resolved "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz" @@ -3416,13 +3286,6 @@ node-releases@^2.0.13: resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz" integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== -nopt@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz" - integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== - dependencies: - abbrev "1" - normalize-path@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" @@ -3435,21 +3298,6 @@ npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" -npmlog@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz" - integrity sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw== - dependencies: - are-we-there-yet "^2.0.0" - console-control-strings "^1.1.0" - gauge "^3.0.0" - set-blocking "^2.0.0" - -object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" - integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== - once@^1.3.0: version "1.4.0" resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" @@ -3610,14 +3458,13 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.5" -pulsar-client@^1.12.0: - version "1.12.0" - resolved "https://registry.npmjs.org/pulsar-client/-/pulsar-client-1.12.0.tgz" - integrity sha512-6xzL7ACXW6vf5J6ilsXB0Zvn1SjtLnuSP8AX+M1xtaVrR/F04BCMifOhxywpPWJpW7yaGJR1zYZjfimGxS8wiw== +pulsar-flex@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/pulsar-flex/-/pulsar-flex-1.1.1.tgz" + integrity sha512-R6jNg4E326uItcG/QcNYLSOnZxMvVo4ZzxB2scEZDN3mp2VHKzPr/iiC07sXthrtdAVXlFTUt8+QyujoKc54ZA== dependencies: - "@mapbox/node-pre-gyp" "^1.0.11" - bindings "^1.5.0" - node-addon-api "^4.3.0" + crc-full "^1.1.0" + google-protobuf "^3.17.3" punycode@^2.1.0: version "2.3.0" @@ -3756,13 +3603,6 @@ reusify@^1.0.4: resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - rimraf@^5.0.7: version "5.0.7" resolved "https://registry.npmjs.org/rimraf/-/rimraf-5.0.7.tgz" @@ -3787,7 +3627,16 @@ safe-stable-stringify@^2.3.1: resolved "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz" integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g== -schema-utils@^3.1.1, schema-utils@^3.2.0: +schema-utils@^3.1.1: + version "3.3.0" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz" + integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +schema-utils@^3.2.0: version "3.3.0" resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz" integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== @@ -3806,17 +3655,19 @@ schema-utils@^4.0.0: ajv-formats "^2.1.1" ajv-keywords "^5.1.0" -semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: +semver@^6.3.0, semver@^6.3.1: version "6.3.1" resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.5: - version "7.6.3" - resolved "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz" - integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== +semver@^7.5.3: + version "7.5.4" + resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" -semver@^7.5.3, semver@^7.5.4: +semver@^7.5.4: version "7.5.4" resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== @@ -3830,11 +3681,6 @@ serialize-javascript@^6.0.0, serialize-javascript@^6.0.1: dependencies: randombytes "^2.1.0" -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz" - integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== - shallow-clone@^3.0.0: version "3.0.1" resolved "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz" @@ -3864,7 +3710,7 @@ shiki@^0.14.7: vscode-oniguruma "^1.7.0" vscode-textmate "^8.0.0" -signal-exit@^3.0.0, signal-exit@^3.0.3, signal-exit@^3.0.7: +signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== @@ -3896,14 +3742,6 @@ slash@^4.0.0: resolved "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz" integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== -source-map-support@0.5.13: - version "0.5.13" - resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz" - integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - source-map-support@~0.5.20: version "0.5.21" resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" @@ -3912,6 +3750,14 @@ source-map-support@~0.5.20: buffer-from "^1.0.0" source-map "^0.6.0" +source-map-support@0.5.13: + version "0.5.13" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map@^0.6.0, source-map@^0.6.1: version "0.6.1" resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" @@ -3934,6 +3780,13 @@ stack-utils@^2.0.3: dependencies: escape-string-regexp "^2.0.0" +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + string-argv@^0.3.2: version "0.3.2" resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz" @@ -3956,7 +3809,7 @@ string-length@^4.0.1: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -3974,13 +3827,6 @@ string-width@^5.0.1, string-width@^5.1.2: emoji-regex "^9.2.2" strip-ansi "^7.0.1" -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - "strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" @@ -4048,18 +3894,6 @@ tapable@^2.1.1, tapable@^2.2.0: resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== -tar@^6.1.11: - version "6.2.1" - resolved "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz" - integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A== - dependencies: - chownr "^2.0.0" - fs-minipass "^2.0.0" - minipass "^5.0.0" - minizlib "^2.1.1" - mkdirp "^1.0.3" - yallist "^4.0.0" - terser-webpack-plugin@^5.3.7: version "5.3.9" resolved "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz" @@ -4112,11 +3946,6 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - triple-beam@^1.3.0: version "1.4.1" resolved "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz" @@ -4142,7 +3971,7 @@ typedoc@^0.25.7: minimatch "^9.0.3" shiki "^0.14.7" -typescript@^5.3.3: +typescript@^5.3.3, "typescript@4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x": version "5.3.3" resolved "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz" integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== @@ -4224,12 +4053,7 @@ watchpack@^2.4.0: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -webpack-cli@^5.1.4: +webpack-cli@^5.1.4, webpack-cli@5.x.x: version "5.1.4" resolved "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz" integrity sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg== @@ -4266,7 +4090,7 @@ webpack-sources@^3.2.3: resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack@^5.88.2: +webpack@^5.1.0, webpack@^5.88.2, webpack@>=5, webpack@5.x.x: version "5.88.2" resolved "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz" integrity sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ== @@ -4296,14 +4120,6 @@ webpack@^5.88.2: watchpack "^2.4.0" webpack-sources "^3.2.3" -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - which@^2.0.1: version "2.0.2" resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" @@ -4311,13 +4127,6 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -wide-align@^1.1.2: - version "1.1.5" - resolved "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz" - integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== - dependencies: - string-width "^1.0.2 || 2 || 3 || 4" - wildcard@^2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz"