diff --git a/.env.example b/.env.example index ec0691d11..06c46bcd7 100755 --- a/.env.example +++ b/.env.example @@ -2,9 +2,11 @@ NODE_ENV=dev PORT=5420 +# Kubo RPC endpoints IPFS_NODE_URL=http://host.docker.internal:5001 PUBLIC_IPFS_RESOLVER=http://host.docker.internal:5002 +# Kubo path gateway endpoint IPFS_RESOLVER_OVERRIDE=http://host.docker.internal:8089/ipfs ### Database - Postgres @@ -161,4 +163,4 @@ ES_DB_USER= ES_DB_PASSWORD= ### open Alex Database - Postgres -OPEN_ALEX_DATABASE_URL=postgresql://username:password@host/database?schema=openalex +OPEN_ALEX_DATABASE_URL=postgresql://username:password@host/database?schema=openalex \ No newline at end of file diff --git a/.github/workflows/build-and-test.yaml b/.github/workflows/build-and-test.yaml index f9047039a..0940f4a46 100644 --- a/.github/workflows/build-and-test.yaml +++ b/.github/workflows/build-and-test.yaml @@ -9,6 +9,7 @@ on: - desci-server/** - desci-repo/** - desci-contracts/** + - sync-server/** - Dockerfile name: Test desci-server @@ -32,6 +33,12 @@ jobs: # options: --user 1001 steps: + - name: Delete huge unnecessary tools folder + run: | + echo "DISK USE:"; find / -maxdepth 1 -mindepth 1 -type d -exec du -hs {} \; 2>/dev/null + rm -rf /opt/hostedtoolcache + echo "DISK USE:"; find / -maxdepth 1 -mindepth 1 -type d -exec du -hs {} \; 2>/dev/null + - name: Check out repository uses: actions/checkout@v4 @@ -49,12 +56,15 @@ jobs: desci-repo/yarn.lock - name: Install dependencies - run: cd desci-models && npm i -g yarn && yarn && yarn build && cd ../desci-server && yarn --ignore-engines && cd ../desci-repo && yarn + run: | + cd desci-models && npm i -g yarn && yarn && yarn build && cd ../desci-server && yarn --ignore-engines && cd ../desci-repo && yarn + echo "DISK USE:"; find / -maxdepth 1 -mindepth 1 -type d -exec du -hs {} \; 2>/dev/null - name: Stub contract run: | echo "{\"proxies\":[{\"address\":\"\"}]}" > desci-server/src/desci-contracts-config/unknown-research-object.json echo "{\"proxies\":[{\"address\":\"\"}]}" > desci-server/src/desci-contracts-config/unknown-dpid.json + echo "DISK USE:"; find / -maxdepth 1 -mindepth 1 -type d -exec du -hs {} \; 2>/dev/null - name: Set up Sentry CLI run: | @@ -65,9 +75,19 @@ jobs: echo -e "\nSENTRY_AUTH_TOKEN=$SENTRY_AUTH" >> desci-server/.env cd desci-server && yarn build + - name: Set up sync server + run: | + cd sync-server && yarn --ignore-engines && ./scripts/build.sh test + if [ $? -ne 0 ]; then + exit 1 + fi + echo "DISK USE:"; find / -maxdepth 1 -mindepth 1 -type d -exec du -hs {} \; 2>/dev/null + - name: Run tests run: | + echo "DISK USE:"; find / -maxdepth 1 -mindepth 1 -type d -exec du -hs {} \; 2>/dev/null cd desci-server && export DOCKER_BUILDKIT=1 && yarn --ignore-engines && yarn test if [ $? -ne 0 ]; then exit 1 fi + echo "DISK USE:"; find / -maxdepth 1 -mindepth 1 -type d -exec du -hs {} \; 2>/dev/null diff --git a/.github/workflows/deploy-sync-server.yaml b/.github/workflows/deploy-sync-server.yaml new file mode 100644 index 000000000..2036cb03b --- /dev/null +++ b/.github/workflows/deploy-sync-server.yaml @@ -0,0 +1,48 @@ +name: Deploy Worker +on: + pull_request: + paths: + - .github/workflows/deploy-sync-server.yaml + - sync-server/** + branches: # array of glob patterns matching against refs/heads. Optional; defaults to all + - main # triggers on pushes that contain changes + - develop + +jobs: + deploy: + runs-on: ubuntu-latest + timeout-minutes: 60 + steps: + - uses: actions/checkout@v4 + # - name: Show github ref + # run: | + # echo ${{ github.ref }} + # echo ${{ github.ref_name }} + # echo ${{ github.head_ref }} + # - name: Build & Deploy Worker (Dev) + # if: github.head_ref == 'tay/automerge-party-flagged' + # uses: cloudflare/wrangler-action@v3 + # with: + # apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + # accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + # environment: staging + # workingDirectory: sync-server + # wranglerVersion: 3.95.0 + - name: Build & Deploy Worker (Staging) + if: github.ref == 'refs/heads/develop' + uses: cloudflare/wrangler-action@v3 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + environment: staging + workingDirectory: sync-server + wranglerVersion: 3.95.0 + - name: Build & Deploy Worker (Production) + if: github.ref == 'refs/heads/main' + uses: cloudflare/wrangler-action@v3 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + environment: production + workingDirectory: sync-server + wranglerVersion: 3.95.0 diff --git a/.gitignore b/.gitignore index 8977d33b5..ba5b570b9 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,6 @@ ipfs-data/ local-data/ **/node_modules .idea +**/*.iml .composedbRuntimeDefinition.json openalex-importer -sync-server \ No newline at end of file diff --git a/.nvmrc b/.nvmrc index 5bacb9a1f..f812e4592 100755 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -20.8.1 \ No newline at end of file +20.18.1 \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index ec6e6899d..ad19d9e14 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -43,5 +43,14 @@ }, "[sql]": { "editor.defaultFormatter": "ms-mssql.mssql" + }, + "[dotenv]": { + "editor.defaultFormatter": "foxundermoon.shell-format" + }, + "[dockerfile]": { + "editor.defaultFormatter": "ms-azuretools.vscode-docker" + }, + "[shellscript]": { + "editor.defaultFormatter": "foxundermoon.shell-format" } } diff --git a/Dockerfile b/Dockerfile index 1c24d9a2c..b117de67c 100755 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,8 @@ -FROM node:20.8.1-bullseye-slim +FROM node:20.18.1-bullseye-slim VOLUME /root/.yarn -RUN apt-get -qy update && apt-get -qy install openssl curl - -RUN npm install -g npm@9.8.1 +RUN apt-get -qy update && apt-get -qy install openssl curl socat jq RUN mkdir /app RUN chown -R node:node /app diff --git a/Makefile b/Makefile index 958c0f944..053ccb72f 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,8 @@ build: .env desci-contracts/.env $(MAKE) -C desci-contracts build $(MAKE) -C desci-server install $(MAKE) -C desci-repo install + $(MAKE) -C sync-server install + $(MAKE) -C nodes-lib build .PHONY: sterile sterile: clean-rec diff --git a/desci-models/package-lock.json b/desci-models/package-lock.json deleted file mode 100644 index acb86cd8c..000000000 --- a/desci-models/package-lock.json +++ /dev/null @@ -1,3288 +0,0 @@ -{ - "name": "@desci-labs/desci-models", - "version": "0.2.13", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "@desci-labs/desci-models", - "version": "0.2.13", - "license": "MIT", - "dependencies": { - "jsonld": "^8.1.1", - "schema-dts": "^1.1.2" - }, - "devDependencies": { - "@types/chai": "^4.3.4", - "@types/jsonld": "^1.5.8", - "@types/mocha": "^10.0.1", - "@types/node": "^16.11.12", - "chai": "^4.3.7", - "mocha": "^10.2.0", - "nyc": "^15.1.0", - "ts-interface-builder": "^0.3.3", - "ts-interface-checker": "^1.0.2", - "ts-node": "^10.9.1", - "typescript": "^4.9.4" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/highlight": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.20.10", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.10.tgz", - "integrity": "sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.20.12", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", - "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.7", - "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-module-transforms": "^7.20.11", - "@babel/helpers": "^7.20.7", - "@babel/parser": "^7.20.7", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.12", - "@babel/types": "^7.20.7", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/generator": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz", - "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.20.7", - "@jridgewell/gen-mapping": "^0.3.2", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", - "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.20.5", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "lru-cache": "^5.1.1", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true, - "license": "ISC" - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.20.11", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", - "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.10", - "@babel/types": "^7.20.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.7.tgz", - "integrity": "sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.7", - "@babel/types": "^7.20.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.7.tgz", - "integrity": "sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==", - "dev": true, - "license": "MIT", - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/template": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", - "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.20.12", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.12.tgz", - "integrity": "sha512-MsIbFN0u+raeja38qboyF8TIT7K0BFzz/Yd/77ta4MsUsmP2RAnidIlwq7d5HFQrH/OZJecGV6B71C4zAgpoSQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.7", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", - "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@digitalbazaar/http-client": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@digitalbazaar/http-client/-/http-client-3.4.0.tgz", - "integrity": "sha512-B/T3Xlo5UjPkoAqX/DQOAF2D5khgNZJZhoQ1d1b3ykYd2XnwOQ6srz1T+SsWVfjbXyLajN7j/nfKy7QiUofN+A==", - "license": "BSD-3-Clause", - "dependencies": { - "ky": "^0.33.3", - "ky-universal": "^0.11.0", - "undici": "^5.21.2" - }, - "engines": { - "node": ">=14.0" - } - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - } - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/jsonld": { - "version": "1.5.8", - "resolved": "https://registry.npmjs.org/@types/jsonld/-/jsonld-1.5.8.tgz", - "integrity": "sha512-4l5t/jDnJpqZ+i7CLTTgPcT5BYXnAnwJupb07aAokPufCV0SjDHcwctUkSTuhIuSU9yHok+WOOngIGCtpL96gw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/mocha": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.1.tgz", - "integrity": "sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "16.18.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.23.tgz", - "integrity": "sha512-XAMpaw1s1+6zM+jn2tmw8MyaRDIJfXxqmIQIS0HfoGYPuf7dUWeiUKopwq13KFX9lEp1+THGtlaaYx39Nxr58g==", - "dev": true, - "license": "MIT" - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "license": "MIT", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-regex": { - "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" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/append-transform": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", - "dev": true, - "license": "MIT", - "dependencies": { - "default-require-extensions": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", - "dev": true, - "license": "MIT" - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true, - "license": "MIT" - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/balanced-match": { - "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/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "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", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true, - "license": "ISC" - }, - "node_modules/browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", - "dependencies": { - "streamsearch": "^1.1.0" - }, - "engines": { - "node": ">=10.16.0" - } - }, - "node_modules/caching-transform": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", - "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasha": "^5.0.0", - "make-dir": "^3.0.0", - "package-hash": "^4.0.0", - "write-file-atomic": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001442", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001442.tgz", - "integrity": "sha512-239m03Pqy0hwxYPYR5JwOIxRJfLTWtle9FV8zosfV5pHg+/51uD4nxcUlM8+mWWGfwKtt8lJNHnD3cWw9VZ6ow==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/canonicalize": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/canonicalize/-/canonicalize-1.0.8.tgz", - "integrity": "sha512-0CNTVCLZggSh7bc5VkX5WWPWO+cyZbNd07IHIsSXLia/eAq+r836hgk+8BKoEh7949Mda87VUOitx5OddVj64A==", - "license": "Apache-2.0" - }, - "node_modules/chai": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", - "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^4.1.2", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true, - "license": "MIT" - }, - "node_modules/concat-map": { - "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/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true, - "license": "MIT" - }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, - "node_modules/debug": { - "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" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/default-require-extensions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", - "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", - "dev": true, - "license": "MIT", - "dependencies": { - "strip-bom": "^4.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", - "dev": true, - "license": "ISC" - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true, - "license": "MIT" - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/fetch-blob": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "paypal", - "url": "https://paypal.me/jimmywarting" - } - ], - "license": "MIT", - "dependencies": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" - }, - "engines": { - "node": "^12.20 || >= 14.13" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dev": true, - "license": "MIT", - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "license": "BSD-3-Clause", - "bin": { - "flat": "cli.js" - } - }, - "node_modules/foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", - "dev": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/formdata-polyfill": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", - "license": "MIT", - "dependencies": { - "fetch-blob": "^3.1.2" - }, - "engines": { - "node": ">=12.20.0" - } - }, - "node_modules/fromentries": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "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": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true, - "license": "ISC" - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/hasha": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "license": "MIT", - "bin": { - "he": "bin/he" - } - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true, - "license": "MIT" - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC" - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-hook": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", - "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "append-transform": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-processinfo": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", - "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", - "dev": true, - "license": "ISC", - "dependencies": { - "archy": "^1.0.0", - "cross-spawn": "^7.0.3", - "istanbul-lib-coverage": "^3.2.0", - "p-map": "^3.0.0", - "rimraf": "^3.0.0", - "uuid": "^8.3.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "license": "MIT", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonld": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/jsonld/-/jsonld-8.1.1.tgz", - "integrity": "sha512-TbtV1hlnoDYxbscazbxcS7seDGV+pc0yktxpMySh0OBFvnLw/TIth0jiQtP/9r+ywuCbtj10XjDNBIkRgiyeUg==", - "license": "BSD-3-Clause", - "dependencies": { - "@digitalbazaar/http-client": "^3.2.0", - "canonicalize": "^1.0.1", - "lru-cache": "^6.0.0", - "rdf-canonize": "^3.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/ky": { - "version": "0.33.3", - "resolved": "https://registry.npmjs.org/ky/-/ky-0.33.3.tgz", - "integrity": "sha512-CasD9OCEQSFIam2U8efFK81Yeg8vNMTBUqtMOHlrcWQHqUX3HeCl9Dr31u4toV7emlH8Mymk5+9p0lL6mKb/Xw==", - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/ky?sponsor=1" - } - }, - "node_modules/ky-universal": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/ky-universal/-/ky-universal-0.11.0.tgz", - "integrity": "sha512-65KyweaWvk+uKKkCrfAf+xqN2/epw1IJDtlyCPxYffFCMR8u1sp2U65NtWpnozYfZxQ6IUzIlvUcw+hQ82U2Xw==", - "license": "MIT", - "dependencies": { - "abort-controller": "^3.0.0", - "node-fetch": "^3.2.10" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/ky-universal?sponsor=1" - }, - "peerDependencies": { - "ky": ">=0.31.4", - "web-streams-polyfill": ">=3.2.1" - }, - "peerDependenciesMeta": { - "web-streams-polyfill": { - "optional": true - } - } - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/loupe": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", - "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-func-name": "^2.0.0" - } - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true, - "license": "ISC" - }, - "node_modules/minimatch": { - "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" - }, - "engines": { - "node": "*" - } - }, - "node_modules/mocha": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", - "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "nanoid": "3.3.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha.js" - }, - "engines": { - "node": ">= 14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" - } - }, - "node_modules/mocha/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/mocha/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/mocha/node_modules/glob/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", - "concat-map": "0.0.1" - } - }, - "node_modules/mocha/node_modules/glob/node_modules/minimatch": { - "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" - }, - "engines": { - "node": "*" - } - }, - "node_modules/mocha/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", - "dev": true, - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/node-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "github", - "url": "https://paypal.me/jimmywarting" - } - ], - "license": "MIT", - "engines": { - "node": ">=10.5.0" - } - }, - "node_modules/node-fetch": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.1.tgz", - "integrity": "sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==", - "license": "MIT", - "dependencies": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/node-fetch" - } - }, - "node_modules/node-preload": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", - "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "process-on-spawn": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/node-releases": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", - "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==", - "dev": true, - "license": "MIT" - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nyc": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", - "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", - "dev": true, - "license": "ISC", - "dependencies": { - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "caching-transform": "^4.0.0", - "convert-source-map": "^1.7.0", - "decamelize": "^1.2.0", - "find-cache-dir": "^3.2.0", - "find-up": "^4.1.0", - "foreground-child": "^2.0.0", - "get-package-type": "^0.1.0", - "glob": "^7.1.6", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-processinfo": "^2.0.2", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "make-dir": "^3.0.0", - "node-preload": "^0.2.1", - "p-map": "^3.0.0", - "process-on-spawn": "^1.0.0", - "resolve-from": "^5.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "spawn-wrap": "^2.0.0", - "test-exclude": "^6.0.0", - "yargs": "^15.0.2" - }, - "bin": { - "nyc": "bin/nyc.js" - }, - "engines": { - "node": ">=8.9" - } - }, - "node_modules/nyc/node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "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" - } - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/package-hash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", - "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "graceful-fs": "^4.1.15", - "hasha": "^5.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "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" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/process-on-spawn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", - "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "fromentries": "^1.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/rdf-canonize": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/rdf-canonize/-/rdf-canonize-3.3.0.tgz", - "integrity": "sha512-gfSNkMua/VWC1eYbSkVaL/9LQhFeOh0QULwv7Or0f+po8pMgQ1blYQFe1r9Mv2GJZXw88Cz/drnAnB9UlNnHfQ==", - "license": "BSD-3-Clause", - "dependencies": { - "setimmediate": "^1.0.5" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", - "dev": true, - "license": "ISC", - "dependencies": { - "es6-error": "^4.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true, - "license": "ISC" - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/schema-dts": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/schema-dts/-/schema-dts-1.1.2.tgz", - "integrity": "sha512-MpNwH0dZJHinVxk9bT8XUdjKTxMYrA5bLtrrGmFA6PTLwlOKnhi67XoRd6/ty+Djt6ZC0slR57qFhZDNMI6DhQ==", - "license": "Apache-2.0", - "peerDependencies": { - "typescript": ">=4.1.0" - } - }, - "node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "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==", - "dev": true, - "license": "ISC" - }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "license": "MIT" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/signal-exit": { - "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/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/spawn-wrap": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", - "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^2.0.0", - "is-windows": "^1.0.2", - "make-dir": "^3.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "which": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/streamsearch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/string-width": { - "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", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "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" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "license": "ISC", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/ts-interface-builder": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/ts-interface-builder/-/ts-interface-builder-0.3.3.tgz", - "integrity": "sha512-WHQwVBy0+Sv/jcHhKlyFgTyEVTM0GEPEw+gLmOYlZiJC1/eh5ah2EHSw7o+RUrl2grjEAMU6MTOItCuQIVJvnQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "commander": "^2.12.2", - "fs-extra": "^4.0.3", - "glob": "^7.1.6", - "typescript": "^3.0.0" - }, - "bin": { - "ts-interface-builder": "bin/ts-interface-builder" - } - }, - "node_modules/ts-interface-builder/node_modules/typescript": { - "version": "3.9.10", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", - "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/ts-interface-checker": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-1.0.2.tgz", - "integrity": "sha512-4IKKvhZRXhvtYF/mtu+OCfBqJKV6LczUq4kQYcpT+iSB7++R9+giWnp2ecwWMIcnG16btVOkXFnoxLSYMN1Q1g==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/ts-node/node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typescript": { - "version": "4.9.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", - "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/undici": { - "version": "5.21.2", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.21.2.tgz", - "integrity": "sha512-f6pTQ9RF4DQtwoWSaC42P/NKlUjvezVvd9r155ohqkwFNRyBKM3f3pcty3ouusefNRyM25XhIQEbeQ46sZDJfQ==", - "license": "MIT", - "dependencies": { - "busboy": "^1.6.0" - }, - "engines": { - "node": ">=12.18" - } - }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "browserslist-lint": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true, - "license": "MIT" - }, - "node_modules/web-streams-polyfill": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", - "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", - "dev": true, - "license": "ISC" - }, - "node_modules/workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrappy": { - "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": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true, - "license": "ISC" - }, - "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/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs-unparser/node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/yargs/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/yargs/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs/node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/desci-models/package.json b/desci-models/package.json index ba34d9fa4..9a98cecb5 100644 --- a/desci-models/package.json +++ b/desci-models/package.json @@ -1,6 +1,6 @@ { "name": "@desci-labs/desci-models", - "version": "0.2.18", + "version": "0.2.19", "description": "Data models for DeSci Nodes", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -38,4 +38,4 @@ "ts-node": "^10.9.1", "typescript": "^4.9.4" } -} +} \ No newline at end of file diff --git a/desci-models/src/ResearchObject.ts b/desci-models/src/ResearchObject.ts index 594ac8b19..8c6e5594a 100644 --- a/desci-models/src/ResearchObject.ts +++ b/desci-models/src/ResearchObject.ts @@ -404,42 +404,43 @@ export type FileExtension = string; /** A semi-complete selection of license choices */ export type License = - | 'CC-BY-4.0' - | 'CC-BY' - | 'CC-BY-SA-4.0' - | 'CC-BY-SA' - | 'CC-BY-ND-4.0' - | 'CC-BY-ND' - | 'CC-BY-NC-4.0' - | 'CC-BY-NC' - | 'CC-BY-NC-SA-4.0' - | 'CC-BY-NC-SA' - | 'CC-BY-NC-ND-4.0' - | 'CC-BY-NC-ND' - | 'CC0-1.0' + | 'AGPL-3.0' + | 'Apache 2.0' + | 'Apache License 2.0' + | 'Apache-2.0' + | 'BSD-2-Clause' + | 'BSD-3-Clause' | 'CC BY' - | 'CC BY-SA' - | 'CC BY-ND' | 'CC BY-NC' - | 'CC BY-NC-SA' | 'CC BY-NC-ND' + | 'CC BY-NC-SA' + | 'CC BY-ND' + | 'CC BY-SA' + | 'CC-BY' + | 'CC-BY-3.0' + | 'CC-BY-4.0' + | 'CC-BY-NC' + | 'CC-BY-NC-4.0' + | 'CC-BY-NC-ND' + | 'CC-BY-NC-ND-4.0' + | 'CC-BY-NC-SA' + | 'CC-BY-NC-SA-4.0' + | 'CC-BY-ND' + | 'CC-BY-ND-4.0' + | 'CC-BY-SA' + | 'CC-BY-SA-4.0' | 'CC0' + | 'CC0-1.0' + | 'CDDL-1.0' + | 'EPL-2.0' | 'GPL-3.0' + | 'LGPL-2.1' + | 'LGPL-3.0' | 'MIT License' - | 'Apache License 2.0' - | 'Apache 2.0' - | 'Mozilla Public License 2.0' - | 'MPL 2.0' | 'MIT' - | 'BSD-3-Clause' - | 'BSD-2-Clause' - | 'Apache-2.0' - | 'LGPL-3.0' - | 'LGPL-2.1' + | 'MPL 2.0' | 'MPL-2.0' - | 'CDDL-1.0' - | 'EPL-2.0' - | 'AGPL-3.0' + | 'Mozilla Public License 2.0' | 'Unlicense'; /** diff --git a/desci-models/src/automerge.ts b/desci-models/src/automerge.ts index ce9bc3a0e..58021d9c1 100644 --- a/desci-models/src/automerge.ts +++ b/desci-models/src/automerge.ts @@ -60,6 +60,7 @@ export type ManifestActions = cid: string | undefined; } | { type: 'Add Reference'; reference: ResearchObjectReference } - | { type: 'Add References'; reference: ResearchObjectReference[] } + | { type: 'Add References'; references: ResearchObjectReference[] } + | { type: 'Set References'; references: ResearchObjectReference[] } | { type: 'Delete Reference'; referenceId: string } | { type: 'Set Contributors'; contributors: ResearchObjectV1Author[] }; diff --git a/desci-models/yarn.lock b/desci-models/yarn.lock index 61b6d705e..acad7d27c 100644 --- a/desci-models/yarn.lock +++ b/desci-models/yarn.lock @@ -22,7 +22,7 @@ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.10.tgz" integrity sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg== -"@babel/core@^7.0.0", "@babel/core@^7.7.5": +"@babel/core@^7.7.5": version "7.20.12" resolved "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz" integrity sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg== @@ -239,7 +239,7 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@3.1.0": +"@jridgewell/resolve-uri@3.1.0", "@jridgewell/resolve-uri@^3.0.3": version "3.1.0" resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz" integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== @@ -249,19 +249,11 @@ resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz" integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== -"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@1.4.14": +"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": 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.9": - version "0.3.17" - resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz" - integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== - dependencies: - "@jridgewell/resolve-uri" "3.1.0" - "@jridgewell/sourcemap-codec" "1.4.14" - "@jridgewell/trace-mapping@0.3.9": version "0.3.9" resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz" @@ -270,6 +262,14 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@jridgewell/trace-mapping@^0.3.9": + version "0.3.17" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz" + integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== + dependencies: + "@jridgewell/resolve-uri" "3.1.0" + "@jridgewell/sourcemap-codec" "1.4.14" + "@tsconfig/node10@^1.0.7": version "1.0.9" resolved "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz" @@ -305,7 +305,7 @@ resolved "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.1.tgz" integrity sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q== -"@types/node@*", "@types/node@^16.11.12": +"@types/node@^16.11.12": version "16.18.23" resolved "https://registry.npmjs.org/@types/node/-/node-16.18.23.tgz" integrity sha512-XAMpaw1s1+6zM+jn2tmw8MyaRDIJfXxqmIQIS0HfoGYPuf7dUWeiUKopwq13KFX9lEp1+THGtlaaYx39Nxr58g== @@ -438,7 +438,7 @@ browser-stdout@1.3.1: resolved "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz" integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== -browserslist@^4.21.3, "browserslist@>= 4.21.0": +browserslist@^4.21.3: version "4.21.4" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz" integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== @@ -572,16 +572,16 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - 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== +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + commander@^2.12.2: version "2.20.3" resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" @@ -621,7 +621,7 @@ data-uri-to-buffer@^4.0.0: resolved "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz" integrity sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A== -debug@^4.1.0, debug@^4.1.1, debug@4.3.4: +debug@4.3.4, 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== @@ -652,16 +652,16 @@ default-require-extensions@^3.0.0: dependencies: strip-bom "^4.0.0" -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - diff@5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz" integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + electron-to-chromium@^1.4.251: version "1.4.284" resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz" @@ -682,16 +682,16 @@ escalade@^3.1.1: resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== - escape-string-regexp@4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + esprima@^4.0.0: version "4.0.1" resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" @@ -726,14 +726,6 @@ find-cache-dir@^3.2.0: make-dir "^3.0.2" pkg-dir "^4.1.0" -find-up@^4.0.0, find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - find-up@5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" @@ -742,6 +734,14 @@ find-up@5.0.0: locate-path "^6.0.0" path-exists "^4.0.0" +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + flat@^5.0.2: version "5.0.2" resolved "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz" @@ -782,9 +782,9 @@ fs.realpath@^1.0.0: integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== gensync@^1.0.0-beta.2: version "1.0.0-beta.2" @@ -813,27 +813,27 @@ glob-parent@~5.1.2: dependencies: is-glob "^4.0.1" -glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: - version "7.2.3" - resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== +glob@7.2.0: + version "7.2.0" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" inherits "2" - minimatch "^3.1.1" + minimatch "^3.0.4" once "^1.3.0" path-is-absolute "^1.0.0" -glob@7.2.0: - version "7.2.0" - resolved "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== +glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: + version "7.2.3" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" inherits "2" - minimatch "^3.0.4" + minimatch "^3.1.1" once "^1.3.0" path-is-absolute "^1.0.0" @@ -1022,6 +1022,13 @@ js-tokens@^4.0.0: resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== +js-yaml@4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + js-yaml@^3.13.1: version "3.14.1" resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz" @@ -1030,13 +1037,6 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" -js-yaml@4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - jsesc@^2.5.1: version "2.5.2" resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz" @@ -1072,7 +1072,7 @@ ky-universal@^0.11.0: abort-controller "^3.0.0" node-fetch "^3.2.10" -ky@^0.33.3, ky@>=0.31.4: +ky@^0.33.3: version "0.33.3" resolved "https://registry.npmjs.org/ky/-/ky-0.33.3.tgz" integrity sha512-CasD9OCEQSFIam2U8efFK81Yeg8vNMTBUqtMOHlrcWQHqUX3HeCl9Dr31u4toV7emlH8Mymk5+9p0lL6mKb/Xw== @@ -1137,13 +1137,6 @@ make-error@^1.1.1: resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== -minimatch@^3.0.4, minimatch@^3.1.1: - version "3.1.2" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - minimatch@5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz" @@ -1151,6 +1144,13 @@ minimatch@5.0.1: dependencies: brace-expansion "^2.0.1" +minimatch@^3.0.4, minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + mocha@^10.2.0: version "10.2.0" resolved "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz" @@ -1510,6 +1510,13 @@ strip-json-comments@3.1.1: resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +supports-color@8.1.1: + version "8.1.1" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + supports-color@^5.3.0: version "5.5.0" resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" @@ -1524,13 +1531,6 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" -supports-color@8.1.1: - version "8.1.1" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - test-exclude@^6.0.0: version "6.0.0" resolved "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz" @@ -1608,7 +1608,7 @@ typescript@^3.0.0: resolved "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz" integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q== -typescript@^4.9.4, typescript@>=2.7, typescript@>=4.1.0: +typescript@^4.9.4: version "4.9.4" resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz" integrity sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg== @@ -1643,7 +1643,7 @@ v8-compile-cache-lib@^3.0.1: resolved "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz" integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== -web-streams-polyfill@^3.0.3, web-streams-polyfill@>=3.2.1: +web-streams-polyfill@^3.0.3: version "3.2.1" resolved "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz" integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q== @@ -1718,6 +1718,11 @@ yallist@^4.0.0: resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== +yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + yargs-parser@^18.1.2: version "18.1.3" resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz" @@ -1731,11 +1736,6 @@ yargs-parser@^20.2.2: resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - yargs-unparser@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz" @@ -1746,6 +1746,19 @@ yargs-unparser@2.0.0: flat "^5.0.2" is-plain-obj "^2.1.0" +yargs@16.2.0: + version "16.2.0" + resolved "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + yargs@^15.0.2: version "15.4.1" resolved "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz" @@ -1763,19 +1776,6 @@ yargs@^15.0.2: y18n "^4.0.0" yargs-parser "^18.1.2" -yargs@16.2.0: - version "16.2.0" - resolved "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - yn@3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz" diff --git a/desci-repo/.env.example b/desci-repo/.env.example index 2fea7a890..955d08ddb 100644 --- a/desci-repo/.env.example +++ b/desci-repo/.env.example @@ -3,4 +3,9 @@ NODE_ENV=dev JWT_SECRET=secretshhh DATABASE_URL=postgresql://walter:white@db_boilerplate:5432/boilerplate IPFS_RESOLVER_OVERRIDE=http://host.docker.internal:8089/ipfs -# DESCI_SERVER_URL= \ No newline at end of file +# DESCI_SERVER_URL= + +WRANGLER_HYPERDRIVE_LOCAL_CONNECTION_STRING_NODES_DB="postgresql://walter:white@host.docker.internal:5433/boilerplate" +PARTY_SERVER_HOST=ws://localhost:5445 +PARTY_SERVER_TOKEN=auth-token +ENABLE_PARTYKIT_FEATURE=true diff --git a/desci-repo/.env.test b/desci-repo/.env.test index 832a3f699..caff94696 100755 --- a/desci-repo/.env.test +++ b/desci-repo/.env.test @@ -1,7 +1,7 @@ NODE_ENV=test # these are mapped to different ports in docker-compose.test.yml -PORT=5484 # mapped to 5486 +PORT=5484 # mapped to 5486 WS_PORT=5445 # mapped to 5446 IPFS_NODE_URL=http://host.docker.internal:5003 @@ -21,4 +21,8 @@ JWT_EXPIRATION= # FOR Communicating with REPO SERVICE REPO_SERVICE_SECRET_KEY="m8sIy5BPygBcX3+ZmMVuAA10k6w59BSCZd+Z5+VLYm4=" -IPFS_RESOLVER_OVERRIDE=http://host.docker.internal:8089/ipfs \ No newline at end of file +IPFS_RESOLVER_OVERRIDE=http://host.docker.internal:8089/ipfs + +PARTY_SERVER_HOST=host.docker.internal:5446 +PARTY_SERVER_TOKEN=auth-token +ENABLE_PARTYKIT_FEATURE=true diff --git a/desci-repo/.eslintrc.cjs b/desci-repo/.eslintrc.cjs new file mode 100755 index 000000000..3f766f768 --- /dev/null +++ b/desci-repo/.eslintrc.cjs @@ -0,0 +1,44 @@ +module.exports = { + parser: '@typescript-eslint/parser', + + extends: ['plugin:@typescript-eslint/recommended', 'prettier', 'plugin:prettier/recommended'], + + plugins: ['@typescript-eslint', 'import'], + + rules: { + // General + '@typescript-eslint/no-unused-vars': 0, + '@typescript-eslint/explicit-module-boundary-types': 0, + '@typescript-eslint/no-explicit-any': 0, + '@typescript-eslint/no-non-null-assertion': 0, + '@typescript-eslint/ban-ts-comment': 0, + '@typescript-eslint/no-empty-interface': 0, + + // Import + 'import/order': [ + 'error', + { + groups: ['builtin', 'external', 'internal', 'parent', 'sibling'], + 'newlines-between': 'always', + alphabetize: { + order: 'asc', + caseInsensitive: true, + }, + }, + ], + }, + + parserOptions: { + ecmaVersion: 2018, + sourceType: 'module', + }, + + settings: { + 'import/resolver': { + node: { + extensions: ['.js', '.jsx', '.ts', '.tsx'], + moduleDirectory: ['node_modules', 'src/', '/test'], + }, + }, + }, +}; diff --git a/desci-repo/Dockerfile b/desci-repo/Dockerfile index c4739b9e7..0c7a20cf6 100644 --- a/desci-repo/Dockerfile +++ b/desci-repo/Dockerfile @@ -4,6 +4,8 @@ VOLUME /root/.yarn RUN npm install -g npm@9.8.1 +RUN apt-get update && apt-get install -y curl + RUN mkdir /app WORKDIR /app RUN mkdir /app/repo-tmp @@ -19,6 +21,6 @@ RUN yarn build EXPOSE 5484 # websocket -EXPOSE 5445 +# EXPOSE 5445 CMD [ "yarn", "start" ] diff --git a/desci-repo/kubernetes/deployment_dev.yaml b/desci-repo/kubernetes/deployment_dev.yaml index e106c0575..7a94fcd71 100644 --- a/desci-repo/kubernetes/deployment_dev.yaml +++ b/desci-repo/kubernetes/deployment_dev.yaml @@ -49,6 +49,9 @@ spec: export DATABASE_URL={{ .Data.DATABASE_URL }} export IPFS_RESOLVER_OVERRIDE={{ .Data.IPFS_RESOLVER_OVERRIDE }} export DESCI_SERVER_URL={{ .Data.DESCI_SERVER_URL }} + export PARTY_SERVER_HOST=nodes-dev-sync.desci.com + export PARTY_SERVER_TOKEN=auth-token + export ENABLE_PARTYKIT_FEATURE=true export PINO_LOG_LEVEL=info {{- end -}} labels: @@ -63,8 +66,8 @@ spec: ports: - containerPort: 5484 name: server-api - - containerPort: 5445 - name: ws-api + # - containerPort: 5445 + # name: ws-api resources: limits: cpu: '4.0' diff --git a/desci-repo/kubernetes/deployment_prod.yaml b/desci-repo/kubernetes/deployment_prod.yaml index a41ffe76d..9da98d20e 100755 --- a/desci-repo/kubernetes/deployment_prod.yaml +++ b/desci-repo/kubernetes/deployment_prod.yaml @@ -50,6 +50,9 @@ spec: export DATABASE_URL={{ .Data.DATABASE_URL }} export IPFS_RESOLVER_OVERRIDE={{ .Data.IPFS_RESOLVER_OVERRIDE }} export DESCI_SERVER_URL={{ .Data.DESCI_SERVER_URL }} + export PARTY_SERVER_HOST=nodes-sync.desci.com + export PARTY_SERVER_TOKEN=auth-token + export ENABLE_PARTYKIT_FEATURE=true export PINO_LOG_LEVEL=info {{- end -}} labels: @@ -64,8 +67,8 @@ spec: ports: - containerPort: 5484 name: server-api - - containerPort: 5445 - name: ws-api + # - containerPort: 5445 + # name: ws-api resources: limits: cpu: '4' diff --git a/desci-repo/kubernetes/deployment_staging.yaml b/desci-repo/kubernetes/deployment_staging.yaml index d8f6f5094..537474092 100644 --- a/desci-repo/kubernetes/deployment_staging.yaml +++ b/desci-repo/kubernetes/deployment_staging.yaml @@ -50,6 +50,9 @@ spec: export DATABASE_URL={{ .Data.DATABASE_URL }} export IPFS_RESOLVER_OVERRIDE={{ .Data.IPFS_RESOLVER_OVERRIDE }} export DESCI_SERVER_URL={{ .Data.DESCI_SERVER_URL }} + export PARTY_SERVER_HOST=nodes-sync.desci.com + export PARTY_SERVER_TOKEN=auth-token + export ENABLE_PARTYKIT_FEATURE=true export PINO_LOG_LEVEL=info {{- end -}} labels: @@ -64,8 +67,8 @@ spec: ports: - containerPort: 5484 name: server-api - - containerPort: 5445 - name: ws-api + # - containerPort: 5445 + # name: ws-api resources: limits: cpu: '2' diff --git a/desci-repo/package.json b/desci-repo/package.json index 740c5882e..8c9f58b90 100644 --- a/desci-repo/package.json +++ b/desci-repo/package.json @@ -4,12 +4,13 @@ "description": "", "type": "module", "engines": { - "node": ">=16.14" + "node": ">=16" }, "scripts": { "build": "rimraf dist && tsc", "start": "NODE_PATH=./dist node ./dist/index.js", "dev": "npm-run-all --parallel watch-compile watch-dev", + "partykit:dev": "wrangler dev --port 5446", "docker:dev": "docker compose --file docker-compose.repo.yml --compatibility up --build", "watch-dev": "debug=* nodemon --watch \"dist/**/*\" -e js ./dist/index.js", "watch-compile": "debug=* tsc -w --preserveWatchOutput", @@ -35,19 +36,18 @@ "cliui": "^8.0.1" }, "devDependencies": { - "@automerge/automerge": "^2.1.10", - "@automerge/automerge-repo": "^1.1.0", - "@automerge/automerge-repo-network-websocket": "^1.0.19", - "@automerge/automerge-repo-storage-nodefs": "^1.0.19", "@types/chai": "^4.3.11", "@types/cors": "^2.8.17", + "@types/deep-equal": "^1.0.4", "@types/express": "^4.17.21", "@types/jsonwebtoken": "^9.0.5", "@types/mocha": "^10.0.6", "@types/morgan": "^1.9.9", "@types/pg": "^8.10.9", + "@types/uuid": "^10.0.0", "@types/ws": "^8.5.10", "@typescript-eslint/eslint-plugin": "^6.13.1", + "@typescript-eslint/parser": "^8.14.0", "chai": "4.3.4", "dotenv-cli": "^7.3.0", "eslint": "^8.55.0", @@ -68,7 +68,11 @@ "typescript": "5.1.6" }, "dependencies": { - "@desci-labs/desci-models": "0.2.11", + "@automerge/automerge-repo": "^1.2.1", + "@automerge/automerge-repo-network-websocket": "^1.2.1", + "@automerge/automerge-repo-storage-indexeddb": "^1.2.1", + "@cloudflare/workers-types": "^4.20241022.0", + "@desci-labs/desci-models": "^0.2.19", "@sentry/node": "8.29.0", "@sentry/profiling-node": "8.32.0", "@sentry/tracing": "^7.84.0", @@ -77,14 +81,20 @@ "deep-equal": "^2.2.3", "dotenv": "^16.3.1", "express": "^4.18.2", + "isomorphic-ws": "^5.0.0", "jsonwebtoken": "^9.0.2", "morgan": "^1.10.0", - "pg": "^8.11.3", + "partykit": "^0.0.111", + "partyserver": "^0.0.57", + "partysocket": "^1.0.2", + "pg": "^8.13.1", "pino": "^8.16.2", "pino-http": "^8.5.1", "pino-pretty": "^10.2.3", + "postgres": "^3.4.5", "reflect-metadata": "^0.1.13", "uuid": "^9.0.1", + "wrangler": "^3.84.1", "ws": "^8.14.2", "zod": "^3.22.4" } diff --git a/desci-repo/src/config.ts b/desci-repo/src/config.ts index 20a668d30..12e65ef4b 100644 --- a/desci-repo/src/config.ts +++ b/desci-repo/src/config.ts @@ -3,4 +3,20 @@ export const PUBLIC_IPFS_PATH = ? `http://host.docker.internal:8089/ipfs` : process.env.NODE_ENV === 'test' ? 'http://host.docker.internal:8091/ipfs' - : 'https://ipfs.desci.com/ipfs'; \ No newline at end of file + : 'https://ipfs.desci.com/ipfs'; + +export const ENABLE_PARTYKIT_FEATURE = + process.env.ENABLE_PARTYKIT_FEATURE == '1' || process.env.ENABLE_PARTYKIT_FEATURE == 'true'; +export const PARTY_SERVER_HOST = process.env.PARTY_SERVER_HOST; +export const PARTY_SERVER_TOKEN = process.env.PARTY_SERVER_TOKEN; + +export const IS_DEV = process.env.NODE_ENV == 'dev'; +export const IS_TEST = process.env.NODE_ENV == 'test'; + +console.log({ + env: process.env.ENABLE_PARTYKIT_FEATURE, + ENABLE_PARTYKIT_FEATURE, + PARTY_SERVER_HOST, + IS_DEV, + IS_TEST, +}); diff --git a/desci-repo/src/controllers/nodes/documents.ts b/desci-repo/src/controllers/nodes/documents.ts index f4f8f271c..97ab229c5 100644 --- a/desci-repo/src/controllers/nodes/documents.ts +++ b/desci-repo/src/controllers/nodes/documents.ts @@ -1,20 +1,41 @@ +import { Doc } from '@automerge/automerge'; +import { AutomergeUrl, DocumentId } from '@automerge/automerge-repo'; +import { ManifestActions } from '@desci-labs/desci-models'; import { Request, Response } from 'express'; -import { ResearchObjectDocument } from '../../types.js'; +import { ZodError } from 'zod'; + +import { findNodeByUuid } from '../../db/index.js'; import { logger as parentLogger } from '../../logger.js'; -import { AutomergeUrl, DocumentId } from '@automerge/automerge-repo'; import { RequestWithNode } from '../../middleware/guard.js'; -import { backendRepo } from '../../repo.js'; +import { backendRepo, repoManager } from '../../repo.js'; import { getAutomergeUrl, getDocumentUpdater } from '../../services/manifestRepo.js'; -import { findNodeByUuid, query } from '../../db/index.js'; -import { Doc } from '@automerge/automerge'; -import { ZodError } from 'zod'; +import { ResearchObjectDocument } from '../../types.js'; import { actionsSchema } from '../../validators/schema.js'; + import { ensureUuidEndsWithDot } from './utils.js'; -import { ManifestActions } from '@desci-labs/desci-models'; +import { IS_DEV, IS_TEST, PARTY_SERVER_HOST, PARTY_SERVER_TOKEN } from '../../config.js'; + +const protocol = IS_TEST || IS_DEV ? 'http://' : 'https://'; + +const getDocument = async (documentId: DocumentId) => { + const logger = parentLogger.child({ module: 'getDocument', documentId }); + + if (!repoManager.isConnected(documentId)) { + repoManager.connect(documentId); + } + + const automergeUrl = getAutomergeUrl(documentId); + await backendRepo.networkSubsystem.whenReady(); + logger.trace({ documentId }, 'ready'); + const handle = backendRepo.find(automergeUrl as AutomergeUrl); + logger.trace({ handle: handle.url }, 'handle resolved'); + const document = await handle.doc(); + logger.trace({ automergeUrl, Retrieved: !!document, document }, 'DOCUMENT Retrieved'); + return document; +}; export const createNodeDocument = async function (req: Request, res: Response) { - const logger = parentLogger.child({ module: 'createNodeDocument', body: req.body, param: req.params }); - logger.trace('createNodeDocument'); + const logger = parentLogger.child({ module: 'createNodeDocument' }); try { if (!(req.body.uuid && req.body.manifest)) { @@ -23,68 +44,35 @@ export const createNodeDocument = async function (req: Request, res: Response) { } let { uuid, manifest } = req.body; - uuid = ensureUuidEndsWithDot(uuid); - logger.info({ peerId: backendRepo.networkSubsystem.peerId, uuid }, '[Backend REPO]:'); - const handle = backendRepo.create(); - handle.change( - (d) => { - d.manifest = manifest; - d.uuid = uuid; - d.driveClock = Date.now().toString(); - }, - { message: 'Init Document', time: Date.now() }, - ); - - logger.trace({ peerId: backendRepo.networkSubsystem.peerId, uuid }, 'Document Created'); - - const document = await handle.doc(); - - logger.trace({ handleReady: handle.isReady() }, 'Document Retrieved'); - - // const node = await findNodeByUuid(uuid); - // logger.trace({ node }, 'Node Retrieved'); - // await prisma.node.update({ where: { id: node.id }, data: { manifestDocumentId: handle.documentId } }); - // const result = await query('UPDATE "Node" SET "manifestDocumentId" = $1 WHERE uuid = $2', [ - // handle.documentId, - // uuid, - // ]); - - // logger.trace( - // { node, uuid, documentId: handle.documentId, url: handle.url, isReady: handle.isReady() }, - // 'Node Updated', - // ); - - // logger.info({ result }, 'UPDATE DOCUMENT ID'); - - res.status(200).send({ ok: true, documentId: handle.documentId, document }); - - logger.info({ documentId: handle.documentId, document }, 'END'); + logger.trace({ protocol, PARTY_SERVER_HOST, PARTY_SERVER_TOKEN }, 'ENV'); + const response = await fetch(`${protocol}${PARTY_SERVER_HOST}/api/documents`, { + method: 'POST', + body: JSON.stringify({ uuid, manifest }), + }); + const data = await response.json(); + + logger.trace({ uuid }, 'Document Created'); + res.status(200).send({ ok: true, ...data }); } catch (err) { - logger.error({ err }, 'Error'); + logger.error({ err }, '[Error]::createNodeDocument'); res.status(500).send({ ok: false, message: JSON.stringify(err) }); } }; export const getLatestNodeManifest = async function (req: Request, res: Response) { - const logger = parentLogger.child({ module: 'getLatestNodeManifest', params: req.params }); + const logger = parentLogger.child({ module: 'getLatestNodeManifest', query: req.query, params: req.params }); const { uuid } = req.params; const { documentId } = req.query; - const getDocument = async (documentId: DocumentId) => { - const automergeUrl = getAutomergeUrl(documentId); - const handle = backendRepo.find(automergeUrl as AutomergeUrl); - const document = await handle.doc(); - logger.trace({ uuid, automergeUrl }, 'DOCUMENT Retrieved'); - return document; - }; - try { // todo: add support for documentId params and skip querying node // fast track call if documentId is available if (documentId) { const document = await getDocument(documentId as DocumentId); - if (document) res.status(200).send({ ok: true, document }); - return; + if (document) { + res.status(200).send({ ok: true, document }); + return; + } } // calls might never reach this place again now that documentId is @@ -111,6 +99,7 @@ export const getLatestNodeManifest = async function (req: Request, res: Response const document = await getDocument(node.manifestDocumentId as DocumentId); + logger.trace({ document: !!document }, 'return DOCUMENT'); res.status(200).send({ ok: true, document }); } catch (err) { logger.error({ err }, 'Error'); @@ -136,7 +125,7 @@ export const dispatchDocumentChange = async function (req: RequestWithNode, res: let document: Doc | undefined; - const dispatchChange = getDocumentUpdater(documentId); + const dispatchChange = await getDocumentUpdater(documentId); for (const action of actions) { document = await dispatchChange(action); @@ -156,7 +145,6 @@ export const dispatchDocumentChange = async function (req: RequestWithNode, res: export const dispatchDocumentActions = async function (req: RequestWithNode, res: Response) { const logger = parentLogger.child({ module: 'dispatchDocumentActions' }); - // logger.info({ body: req.body }, 'START [dispatchDocumentActions]'); try { if (!(req.body.uuid && req.body.documentId && req.body.actions)) { logger.error({ body: req.body }, 'Invalid data'); @@ -178,7 +166,7 @@ export const dispatchDocumentActions = async function (req: RequestWithNode, res let document: Doc | undefined; - const dispatchChange = getDocumentUpdater(documentId); + const dispatchChange = await getDocumentUpdater(documentId); for (const action of actions) { document = await dispatchChange(action); diff --git a/desci-repo/src/controllers/nodes/utils.ts b/desci-repo/src/controllers/nodes/utils.ts index f3891315d..e73cf568d 100644 --- a/desci-repo/src/controllers/nodes/utils.ts +++ b/desci-repo/src/controllers/nodes/utils.ts @@ -1,9 +1,10 @@ -import axios from 'axios'; import { ResearchObjectV1 } from '@desci-labs/desci-models'; +import axios from 'axios'; + import { PUBLIC_IPFS_PATH } from '../../config.js'; -import { logger as parentLogger } from '../../logger.js'; -import { createIpfsUnresolvableError } from '../../lib/errors.js'; import { findNodeByUuid } from '../../db/index.js'; +import { createIpfsUnresolvableError } from '../../lib/errors.js'; +import { logger as parentLogger } from '../../logger.js'; import { Node } from '../../middleware/guard.js'; export async function getLatestManifest( diff --git a/desci-repo/src/db/index.ts b/desci-repo/src/db/index.ts index 0c6831430..fea805090 100644 --- a/desci-repo/src/db/index.ts +++ b/desci-repo/src/db/index.ts @@ -1,3 +1,5 @@ +import { logger } from '../logger.js'; + const pg = await import('pg').then((value) => value.default); const { Pool } = pg; @@ -25,10 +27,9 @@ export const query = async (query: string, values?: (string | number | object)[] try { // const client = await pool.connect(); const result = await pool.query(query, values ? values : undefined); - // console.log('QUERY RESULT', result.rowCount); return result.rows; } catch (err) { - console.error('[QUERY ERROR]::', err); + logger.error({ err }, '[QUERY ERROR]::'); return undefined; } }; diff --git a/desci-repo/src/index.ts b/desci-repo/src/index.ts index f27c2b6d9..b874cd6c9 100644 --- a/desci-repo/src/index.ts +++ b/desci-repo/src/index.ts @@ -1,3 +1,4 @@ +import 'dotenv/config'; import { logger } from './logger.js'; import { server } from './server.js'; diff --git a/desci-repo/src/lib/PartykitNodeWsAdapter.ts b/desci-repo/src/lib/PartykitNodeWsAdapter.ts new file mode 100644 index 000000000..58a13097d --- /dev/null +++ b/desci-repo/src/lib/PartykitNodeWsAdapter.ts @@ -0,0 +1,349 @@ +// import WebSocket from 'isomorphic-ws'; + +import debug from 'debug'; +const log = debug('WebsocketServer'); + +import { cbor as cborHelpers, NetworkAdapter, type PeerMetadata, type PeerId } from '@automerge/automerge-repo/slim'; +import { + FromClientMessage, + FromServerMessage, + assert, + toArrayBuffer, + ProtocolV1, + JoinMessage, + isPeerMessage, + isErrorMessage, +} from './automerge-repo-network-websocket/index.js'; + +import WebSocket from 'ws'; +import { PartySocketOptions, PartySocket } from 'partysocket'; + +const { encode, decode } = cborHelpers; + +type TimeoutId = ReturnType; + +function joinMessage(senderId: PeerId, peerMetadata: PeerMetadata): JoinMessage { + return { + type: 'join', + senderId, + peerMetadata, + supportedProtocolVersions: [ProtocolV1], + }; +} +export class PartykitNodeWsAdapter extends NetworkAdapter { + isReady() { + return this.#ready; + } + + whenReady() { + return this.#readyPromise; + } + + #forceReady() { + // console.log("[party]::forceReady", this.isReady(), this.resolver); + if (!this.#ready) { + this.emit('ready', { network: this }); + this.#ready = true; + this.resolver?.(); + } + } + + #ready = false; + #readyResolver?: () => void; + resolver?: () => void; + #readyPromise: Promise; + + #retryIntervalId?: TimeoutId; + #log = debug('automerge-repo:websocket:browser'); + + remotePeerId?: PeerId; // this adapter only connects to one remote client at a time + + socket?: PartySocket | undefined; + + constructor( + private opts: PartySocketOptions, // public readonly retryInterval = 5000 + ) { + super(); + + this.#ready = false; + this.#readyPromise = new Promise((resolve) => { + this.#readyResolver = resolve; + this.resolver = resolve; + }); + } + + connect(peerId: PeerId, peerMetadata?: PeerMetadata) { + if (!this.socket || !this.peerId) { + // first time connecting + this.#log('connecting'); + this.peerId = peerId; + this.peerMetadata = peerMetadata ?? {}; + } else { + this.#log('reconnecting'); + assert(peerId === this.peerId); + // Remove the old event listeners before creating a new connection. + this.socket.removeEventListener('open', this.onOpen); + this.socket.removeEventListener('close', this.onClose); + this.socket.removeEventListener('message', this.onMessage); + this.socket.removeEventListener('error', this.onError); + } + + this.socket = new PartySocket(this.opts); + + this.socket.binaryType = 'arraybuffer'; + + this.socket.addEventListener('open', this.onOpen); + this.socket.addEventListener('close', this.onClose); + this.socket.addEventListener('message', this.onMessage); + this.socket.addEventListener('error', this.onError); + + // Mark this adapter as ready if we haven't received an ack in 1 second. + // We might hear back from the other end at some point but we shouldn't + // hold up marking things as unavailable for any longer + setTimeout(() => this.#forceReady(), 1000); + this.join(); + } + + onOpen = () => { + this.#log('open'); + clearInterval(this.#retryIntervalId); + // this.#retryIntervalId = undefined; + this.join(); + }; + + // When a socket closes, or disconnects, remove it from the array. + onClose = () => { + this.#log('close'); + if (this.remotePeerId) this.emit('peer-disconnected', { peerId: this.remotePeerId }); + }; + + onMessage = (event: MessageEvent) => { + this.receiveMessage(event.data as Uint8Array); + }; + + /** The websocket error handler signature is different on node and the browser. */ + onError = ( + event: + | Event // browser + | ErrorEvent, // node + ) => { + if ('error' in event) { + // (node) + if (event.error.code !== 'ECONNREFUSED') { + /* c8 ignore next */ + // throw event.error; + } + } else { + // (browser) We get no information about errors. https://stackoverflow.com/a/31003057/239663 + // There will be an error logged in the console (`WebSocket connection to 'wss://foo.com/' + // failed`), but by design the error is unavailable to scripts. We'll just assume this is a + // failed connection. + } + this.#log('Connection failed, retrying...'); + }; + + join() { + assert(this.peerId); + assert(this.socket); + if (this.socket.readyState === WebSocket.OPEN) { + this.send(joinMessage(this.peerId!, this.peerMetadata!)); + } else { + // We'll try again in the `onOpen` handler + } + } + + disconnect() { + assert(this.peerId); + assert(this.socket); + const socket = this.socket; + if (socket) { + socket.removeEventListener('open', this.onOpen); + socket.removeEventListener('close', this.onClose); + socket.removeEventListener('message', this.onMessage); + socket.removeEventListener('error', this.onError); + socket.close(); + } + clearInterval(this.#retryIntervalId); + if (this.remotePeerId) this.emit('peer-disconnected', { peerId: this.remotePeerId }); + this.socket = undefined; + } + + send(message: FromClientMessage) { + if ('data' in message && message.data?.byteLength === 0) throw new Error('Tried to send a zero-length message'); + assert(this.peerId); + assert(this.socket); + if (!this.socket) { + this.#log('Tried to send on a disconnected socket.'); + return; + } + if (this.socket.readyState !== WebSocket.OPEN) throw new Error(`Websocket not ready (${this.socket.readyState})`); + + const encoded = encode(message); + this.socket.send(toArrayBuffer(encoded)); + } + + peerCandidate(remotePeerId: PeerId, peerMetadata: PeerMetadata) { + assert(this.socket); + this.#forceReady(); + this.remotePeerId = remotePeerId; + this.emit('peer-candidate', { + peerId: remotePeerId, + peerMetadata, + }); + } + + receiveMessage(messageBytes: Uint8Array) { + const message: FromServerMessage = decode(new Uint8Array(messageBytes)); + assert(this.socket); + if (messageBytes.byteLength === 0) throw new Error('received a zero-length message'); + + if (isPeerMessage(message)) { + const { peerMetadata } = message; + this.#log(`peer: ${message.senderId}`); + this.peerCandidate(message.senderId, peerMetadata); + } else if (isErrorMessage(message)) { + this.#log(`error: ${message.message}`); + } else { + this.emit('message', message); + } + } +} + +// export class _PartykitNodeWsAdapter extends NetworkAdapter { +// #isReady = false; +// #readyPromise; +// #readyResolver + +// sockets: Set = new Set(); + +// remotePeerId: PeerId; + +// isReady() { +// return this.#isReady; +// } + +// whenReady() { +// return this.#readyPromise; +// } + +// constructor(private socket: WebSocket) { +// super(); + +// this.#readyPromise = new Promise((resolve) => { +// this.#readyResolver = resolve; +// }); +// } + +// connect(peerId: PeerId, peerMetadata: PeerMetadata) { +// console.log('Connect', { peerId, peerMetadata, remotePeer: this.remotePeerId }); +// this.peerId = peerId; +// this.peerMetadata = peerMetadata; + +// this.sockets.add(peerId); + +// const socket = this.socket; + +// socket.addEventListener('close', () => { +// // clearInterval(keepAliveId); +// this.disconnect(); +// }); + +// socket.addEventListener('message', (message) => { +// // console.log('[PARTY]::MESSAGE', message); +// // handleChunked((message) => this.receiveMessage(message as Uint8Array, socket)); +// const data = new Uint8Array(message.data as ArrayBufferLike); +// this.receiveMessage(data as Uint8Array, socket); +// }); + +// // setTimeout(() => this.#ready(), 1000); +// this.emit('ready', { network: this }); +// } + +// disconnect() { +// this.#terminate(this.socket); +// } + +// send(message: FromServerMessage) { +// assert('targetId' in message && message.targetId !== undefined); +// if ('data' in message && message.data?.byteLength === 0) throw new Error('Tried to send a zero-length message'); + +// const senderId = this.peerId; +// assert(senderId, 'No peerId set for the websocket server network adapter.'); + +// // const socket = this.sockets[message.targetId]; + +// if (!this.socket) { +// log(`Tried to send to disconnected peer: ${message.targetId}`); +// return; +// } + +// const encoded = encode(message); +// const arrayBuf = toArrayBuffer(encoded); + +// // sendChunked(arrayBuf, this.socket); +// this.socket.send(arrayBuf); +// } + +// receiveMessage(messageBytes: Uint8Array, socket: WebSocket) { +// const message: FromClientMessage = decode(messageBytes); + +// const { type, senderId } = message; +// // console.log('[party]::ReceivedMessage', { type, senderId }); + +// const myPeerId = this.peerId; +// assert(myPeerId); + +// const documentId = 'documentId' in message ? '@' + message.documentId : ''; +// const { byteLength } = messageBytes; +// log(`[${senderId}->${myPeerId}${documentId}] ${type} | ${byteLength} bytes`); + +// if (isJoinMessage(message)) { +// const { peerMetadata, supportedProtocolVersions } = message; + +// // Let the repo know that we have a new connection. +// this.emit('peer-candidate', { peerId: senderId, peerMetadata }); +// // this.sockets[senderId] = socket; +// this.remotePeerId = senderId; +// this.sockets.add(senderId); + +// const selectedProtocolVersion = selectProtocol(supportedProtocolVersions); +// if (selectedProtocolVersion === null) { +// this.send({ +// type: 'error', +// senderId: this.peerId!, +// message: 'unsupported protocol version', +// targetId: senderId, +// }); +// this.sockets[senderId].close(); +// delete this.sockets[senderId]; +// } else { +// this.send({ +// type: 'peer', +// senderId: this.peerId!, +// peerMetadata: this.peerMetadata!, +// selectedProtocolVersion: ProtocolV1, +// targetId: senderId, +// }); +// } +// } else if (isLeaveMessage(message)) { +// const { senderId } = message; +// const socket = this.sockets[senderId]; +// /* c8 ignore next */ +// if (!socket) return; +// this.#terminate(socket as WebSocket); +// } else { +// this.emit('message', message); +// } +// } + +// #terminate(socket: WebSocket) { +// this.sockets.delete(this.remotePeerId); +// this.emit('peer-disconnected', { peerId: this.remotePeerId }); +// } +// } + +// const selectProtocol = (versions?: ProtocolVersion[]) => { +// if (versions === undefined) return ProtocolV1; +// if (versions.includes(ProtocolV1)) return ProtocolV1; +// return null; +// }; diff --git a/desci-repo/src/lib/PostgresStorageAdapter.ts b/desci-repo/src/lib/PostgresStorageAdapter.ts index f8c3876c4..6bbd5d331 100644 --- a/desci-repo/src/lib/PostgresStorageAdapter.ts +++ b/desci-repo/src/lib/PostgresStorageAdapter.ts @@ -2,8 +2,8 @@ import path from 'path'; import { Chunk, StorageAdapter, StorageKey } from '@automerge/automerge-repo'; -import { logger as parentLogger } from '../logger.js'; import { query } from '../db/index.js'; +import { logger as parentLogger } from '../logger.js'; const logger = parentLogger.child({ module: 'PostgresStorageAdapter' }); export class PostgresStorageAdapter extends StorageAdapter { @@ -21,7 +21,6 @@ export class PostgresStorageAdapter extends StorageAdapter { try { const result = await query(`SELECT * FROM "${this.tableName}" WHERE key = $1`, [key]); - logger.trace({ value: result?.length, key }, '[LOAD DOCUMENT]::'); const response = result?.[0]; // MUST RETURN UNDEFINED! @@ -38,8 +37,6 @@ export class PostgresStorageAdapter extends StorageAdapter { this.cache[key] = binary; try { - logger.trace({ action: 'Save', key }, 'PostgresStorageAdaptser::Save'); - await query( `INSERT INTO "${this.tableName}" (key, value) VALUES ($1, $2) ON CONFLICT(key) DO UPDATE SET value = $2 RETURNING key`, [key, Buffer.from(binary)], @@ -55,7 +52,6 @@ export class PostgresStorageAdapter extends StorageAdapter { delete this.cache[key]; try { - logger.trace({ action: 'Remove', key }, 'PostgresStorageAdapter::Remove'); await query(`DELETE FROM "${this.tableName}" WHERE key = $1 RETURNING key`, [key]); } catch (e) { logger.error({ e, key }, 'PostgresStorageAdapter::Remove ==> Error deleting document'); @@ -81,9 +77,7 @@ export class PostgresStorageAdapter extends StorageAdapter { const key = getKey(keyPrefix); this.cachedKeys(keyPrefix).forEach((key) => delete this.cache[key]); try { - logger.trace({ key, keyPrefix }, 'DELETE DOCUMENT RANGE'); const result = await query(`DELETE FROM "${this.tableName}" WHERE key LIKE $1 RETURNING key`, [`${key}%`]); - console.log({ result, key }, 'DELETED MANY RANGE'); } catch (e) { logger.error({ keyPrefix, key }, '[DELETE RANGE kEYS]'); } @@ -95,9 +89,7 @@ export class PostgresStorageAdapter extends StorageAdapter { } private async loadRangeKeys(keyPrefix: string[]): Promise { - logger.trace({ keyPrefix }, 'LoadRange Keys'); const response = await query(`SELECT key FROM "${this.tableName}" WHERE key LIKE $1`, [`${keyPrefix}%`]); - logger.trace({ keyPrefix, response: response?.length }, '[LOADED RANGE Keys]'); return response ? response.map((row) => row.key) : []; } diff --git a/desci-repo/src/lib/automerge-repo-network-websocket/BrowserWebSocketClientAdapter.ts b/desci-repo/src/lib/automerge-repo-network-websocket/BrowserWebSocketClientAdapter.ts new file mode 100644 index 000000000..966a95a07 --- /dev/null +++ b/desci-repo/src/lib/automerge-repo-network-websocket/BrowserWebSocketClientAdapter.ts @@ -0,0 +1,181 @@ +import { NetworkAdapter, PeerId, PeerMetadata, cbor } from '@automerge/automerge-repo'; +import WebSocket from 'isomorphic-ws'; + +import debug from 'debug'; + +import { FromClientMessage, FromServerMessage, JoinMessage, isErrorMessage, isPeerMessage } from './messages.js'; +import { ProtocolV1 } from './protocolVersion.js'; +import { assert } from './assert.js'; +import { toArrayBuffer } from './toArrayBuffer.js'; + +abstract class WebSocketNetworkAdapter extends NetworkAdapter { + socket?: WebSocket; +} + +// export class BrowserWebSocketClientAdapter extends WebSocketNetworkAdapter { +// #isReady = false; +// #retryIntervalId?: TimeoutId | undefined; +// #log = debug('automerge-repo:websocket:browser'); + +// remotePeerId?: PeerId; // this adapter only connects to one remote client at a time + +// constructor( +// public readonly url: string, +// public readonly retryInterval = 5000, +// ) { +// super(); +// this.#log = this.#log.extend(url); +// } + +// connect(peerId: PeerId, peerMetadata?: PeerMetadata) { +// if (!this.socket || !this.peerId) { +// // first time connecting +// this.#log('connecting'); +// this.peerId = peerId; +// this.peerMetadata = peerMetadata ?? {}; +// } else { +// this.#log('reconnecting'); +// assert(peerId === this.peerId); +// // Remove the old event listeners before creating a new connection. +// this.socket.removeEventListener('open', this.onOpen); +// this.socket.removeEventListener('close', this.onClose); +// this.socket.removeEventListener('message', this.onMessage); +// this.socket.removeEventListener('error', this.onError); +// } +// // Wire up retries +// if (!this.#retryIntervalId) +// this.#retryIntervalId = setInterval(() => { +// this.connect(peerId, peerMetadata); +// }, this.retryInterval); + +// this.socket = new WebSocket(this.url); + +// this.socket.binaryType = 'arraybuffer'; + +// this.socket.addEventListener('open', this.onOpen); +// this.socket.addEventListener('close', this.onClose); +// this.socket.addEventListener('message', this.onMessage); +// this.socket.addEventListener('error', this.onError); + +// // Mark this adapter as ready if we haven't received an ack in 1 second. +// // We might hear back from the other end at some point but we shouldn't +// // hold up marking things as unavailable for any longer +// setTimeout(() => this.#ready(), 1000); +// this.join(); +// } + +// onOpen = () => { +// this.#log('open'); +// clearInterval(this.#retryIntervalId); +// this.#retryIntervalId = undefined; +// this.join(); +// }; + +// // When a socket closes, or disconnects, remove it from the array. +// onClose = () => { +// this.#log('close'); +// if (this.remotePeerId) this.emit('peer-disconnected', { peerId: this.remotePeerId }); + +// if (this.retryInterval > 0 && !this.#retryIntervalId) +// // try to reconnect +// setTimeout(() => { +// assert(this.peerId); +// return this.connect(this.peerId, this.peerMetadata); +// }, this.retryInterval); +// }; + +// onMessage = (event: WebSocket.MessageEvent) => { +// this.receiveMessage(event.data as Uint8Array); +// }; + +// /** The websocket error handler signature is different on node and the browser. */ +// onError = ( +// event: +// | Event // browser +// | WebSocket.ErrorEvent, // node +// ) => { +// if ('error' in event) { +// // (node) +// if (event.error.code !== 'ECONNREFUSED') { +// /* c8 ignore next */ +// throw event.error; +// } +// } else { +// // (browser) We get no information about errors. https://stackoverflow.com/a/31003057/239663 +// // There will be an error logged in the console (`WebSocket connection to 'wss://foo.com/' +// // failed`), but by design the error is unavailable to scripts. We'll just assume this is a +// // failed connection. +// } +// this.#log('Connection failed, retrying...'); +// }; + +// #ready() { +// if (this.#isReady) return; +// this.#isReady = true; +// this.emit('ready', { network: this }); +// } + +// join() { +// assert(this.peerId); +// assert(this.socket); +// if (this.socket.readyState === WebSocket.OPEN) { +// this.send(joinMessage(this.peerId!, this.peerMetadata!)); +// } else { +// // We'll try again in the `onOpen` handler +// } +// } + +// disconnect() { +// assert(this.peerId); +// assert(this.socket); +// this.send({ type: 'leave', senderId: this.peerId }); +// } + +// send(message: FromClientMessage) { +// if ('data' in message && message.data?.byteLength === 0) throw new Error('Tried to send a zero-length message'); +// assert(this.peerId); +// assert(this.socket); +// if (this.socket.readyState !== WebSocket.OPEN) throw new Error(`Websocket not ready (${this.socket.readyState})`); + +// const encoded = cbor.encode(message); +// this.socket.send(toArrayBuffer(encoded)); +// } + +// peerCandidate(remotePeerId: PeerId, peerMetadata: PeerMetadata) { +// assert(this.socket); +// this.#ready(); +// this.remotePeerId = remotePeerId; +// this.emit('peer-candidate', { +// peerId: remotePeerId, +// peerMetadata, +// }); +// } + +// receiveMessage(messageBytes: Uint8Array) { +// const message: FromServerMessage = cbor.decode(new Uint8Array(messageBytes)); + +// assert(this.socket); +// if (messageBytes.byteLength === 0) throw new Error('received a zero-length message'); + +// if (isPeerMessage(message)) { +// const { peerMetadata } = message; +// this.#log(`peer: ${message.senderId}`); +// this.peerCandidate(message.senderId, peerMetadata); +// } else if (isErrorMessage(message)) { +// this.#log(`error: ${message.message}`); +// } else { +// this.emit('message', message); +// } +// } +// } + +function joinMessage(senderId: PeerId, peerMetadata: PeerMetadata): JoinMessage { + return { + type: 'join', + senderId, + peerMetadata, + supportedProtocolVersions: [ProtocolV1], + }; +} + +type TimeoutId = ReturnType; // https://stackoverflow.com/questions/45802988 diff --git a/desci-repo/src/lib/automerge-repo-network-websocket/PartykitWsServerAdapter.ts b/desci-repo/src/lib/automerge-repo-network-websocket/PartykitWsServerAdapter.ts new file mode 100644 index 000000000..19451eb5a --- /dev/null +++ b/desci-repo/src/lib/automerge-repo-network-websocket/PartykitWsServerAdapter.ts @@ -0,0 +1,160 @@ +// import WebSocket from 'isomorphic-ws'; +// import { type WebSocketServer } from 'isomorphic-ws'; + +import debug from 'debug'; +const log = debug('WebsocketServer'); + +import { cbor as cborHelpers, NetworkAdapter, type PeerMetadata, type PeerId } from '@automerge/automerge-repo/slim'; +import { FromClientMessage, FromServerMessage, isJoinMessage, isLeaveMessage } from './messages.js'; +import { ProtocolV1, ProtocolVersion } from './protocolVersion.js'; +import { assert } from './assert.js'; +import { toArrayBuffer } from './toArrayBuffer.js'; +import { Connection as WebSocket } from 'partyserver'; +// import { handleChunked, sendChunked } from './chunking.js'; + +const { encode, decode } = cborHelpers; + +export class PartyKitWSServerAdapter extends NetworkAdapter { + #isReady = false; + #readyPromise; + #readyResolver; + + sockets: Set = new Set(); + + remotePeerId: PeerId; + + isReady() { + return this.#isReady; + } + + whenReady() { + return this.#readyPromise; + } + + #ready() { + if (this.#isReady) return; + this.#isReady = true; + this.#readyResolver?.(); + } + + constructor(private socket: WebSocket) { + super(); + + this.#readyPromise = new Promise((resolve) => { + this.#readyResolver = resolve; + }); + } + + connect(peerId: PeerId, peerMetadata: PeerMetadata) { + // console.log('Connect', { peerId, peerMetadata, remotePeer: this.remotePeerId }); + this.peerId = peerId; + this.peerMetadata = peerMetadata; + + this.sockets.add(peerId); + + const socket = this.socket; + + socket.addEventListener('close', () => { + // clearInterval(keepAliveId); + this.disconnect(); + }); + + socket.addEventListener('message', (message) => { + // console.log('[PARTY]::MESSAGE', message); + // handleChunked((message) => this.receiveMessage(message as Uint8Array, socket)); + const data = new Uint8Array(message.data as ArrayBufferLike); + this.receiveMessage(data as Uint8Array, socket); + }); + + // setTimeout(() => this.#ready(), 1000); + // this.emit('ready', { network: this }); + } + + disconnect() { + this.#terminate(this.socket); + } + + send(message: FromServerMessage) { + assert('targetId' in message && message.targetId !== undefined); + if ('data' in message && message.data?.byteLength === 0) throw new Error('Tried to send a zero-length message'); + + const senderId = this.peerId; + assert(senderId, 'No peerId set for the websocket server network adapter.'); + + // const socket = this.sockets[message.targetId]; + + if (!this.socket) { + log(`Tried to send to disconnected peer: ${message.targetId}`); + return; + } + + const encoded = encode(message); + const arrayBuf = toArrayBuffer(encoded); + + // sendChunked(arrayBuf, this.socket); + this.socket.send(arrayBuf); + } + + receiveMessage(messageBytes: Uint8Array, socket: WebSocket) { + const message: FromClientMessage = decode(messageBytes); + + const { type, senderId } = message; + // console.log('[party]::ReceivedMessage', { type, senderId }); + + const myPeerId = this.peerId; + assert(myPeerId); + + const documentId = 'documentId' in message ? '@' + message.documentId : ''; + const { byteLength } = messageBytes; + log(`[${senderId}->${myPeerId}${documentId}] ${type} | ${byteLength} bytes`); + + if (isJoinMessage(message)) { + const { peerMetadata, supportedProtocolVersions } = message; + + // Let the repo know that we have a new connection. + this.emit('peer-candidate', { peerId: senderId, peerMetadata }); + // this.sockets[senderId] = socket; + this.remotePeerId = senderId; + this.sockets.add(senderId); + + const selectedProtocolVersion = selectProtocol(supportedProtocolVersions); + if (selectedProtocolVersion === null) { + this.send({ + type: 'error', + senderId: this.peerId!, + message: 'unsupported protocol version', + targetId: senderId, + }); + this.sockets[senderId].close(); + delete this.sockets[senderId]; + } else { + this.send({ + type: 'peer', + senderId: this.peerId!, + peerMetadata: this.peerMetadata!, + selectedProtocolVersion: ProtocolV1, + targetId: senderId, + }); + } + } else if (isLeaveMessage(message)) { + const { senderId } = message; + const socket = this.sockets[senderId]; + /* c8 ignore next */ + if (!socket) return; + this.#terminate(socket as WebSocket); + } else { + this.emit('message', message); + } + } + + #terminate(socket: WebSocket) { + this.sockets.delete(this.remotePeerId); + this.emit('peer-disconnected', { peerId: this.remotePeerId }); + } +} + +const selectProtocol = (versions?: ProtocolVersion[]) => { + if (versions === undefined) return ProtocolV1; + if (versions.includes(ProtocolV1)) return ProtocolV1; + return null; +}; diff --git a/desci-repo/src/lib/automerge-repo-network-websocket/assert.ts b/desci-repo/src/lib/automerge-repo-network-websocket/assert.ts new file mode 100644 index 000000000..82bd71e1c --- /dev/null +++ b/desci-repo/src/lib/automerge-repo-network-websocket/assert.ts @@ -0,0 +1,28 @@ +/* c8 ignore start */ + +export function assert(value: boolean, message?: string): asserts value +export function assert( + value: T | undefined, + message?: string +): asserts value is T +export function assert(value: any, message = "Assertion failed") { + if (value === false || value === null || value === undefined) { + const error = new Error(trimLines(message)) + error.stack = removeLine(error.stack, "assert.ts") + throw error + } +} + +const trimLines = (s: string) => + s + .split("\n") + .map(s => s.trim()) + .join("\n") + +const removeLine = (s = "", targetText: string) => + s + .split("\n") + .filter(line => !line.includes(targetText)) + .join("\n") + +/* c8 ignore end */ diff --git a/desci-repo/src/lib/automerge-repo-network-websocket/chunking.ts b/desci-repo/src/lib/automerge-repo-network-websocket/chunking.ts new file mode 100644 index 000000000..f9d140167 --- /dev/null +++ b/desci-repo/src/lib/automerge-repo-network-websocket/chunking.ts @@ -0,0 +1,174 @@ +// This file contains a shared implementation of chunking logic for binary +// WebSocket messages. Because the PartyKit platform limits individual +// WebSocket messages to 1MB, we need to split larger messages into chunks. +export const CHUNK_MAX_SIZE = 1024 * 1024; + +const BATCH_SENTINEL = 'batch-sentinel'; +const TRACE_ENABLED = false; +const trace = (...args: unknown[]) => TRACE_ENABLED && console.log(...args); + +let warnedAboutLargeMessage = false; + +type MessageData = ArrayBufferLike | string; +type MessageHandler = (message: { data: MessageData }) => void; +type Batch = { + id: string; + type: 'start' | 'end'; + size: number; + count: number; +}; + +/** + * Takes an ArrayBuffer and sends it in chunks to the provided send function, + * along with a start and end marker. + * + * 1. The sender splits the message into chunks of 1MB or less. + * 2. The sender sends a chunk start marker + * 3. The sender sends each chunk as a individual packet + * 4. The sender sends a chunk end marker + */ +export const sendChunked = (data: ArrayBufferLike, ws: WebSocket) => { + if (data.byteLength <= CHUNK_MAX_SIZE) { + ws.send(data); + return; + } + + if (!warnedAboutLargeMessage) { + console.warn( + '[y-partykit]', + 'The Y.js update size exceeds 1MB, which is the maximum size for an individual update. The update will be split into chunks. This is an experimental feature.', + `Message size: ${(data.byteLength / 1000 / 1000).toFixed(1)}MB`, + ); + warnedAboutLargeMessage = true; + } + + const id = (Date.now() + Math.random()).toString(36).substring(10); + const chunks = Math.ceil(data.byteLength / CHUNK_MAX_SIZE); + + ws.send( + serializeBatchMarker({ + id, + type: 'start', + size: data.byteLength, + count: chunks, + }), + ); + + let sentSize = 0; + let sentChunks = 0; + for (let i = 0; i < chunks; i++) { + const chunk = data.slice(CHUNK_MAX_SIZE * i, CHUNK_MAX_SIZE * (i + 1)); + ws.send(chunk); + sentChunks += 1; + sentSize += chunk.byteLength; + } + + ws.send( + serializeBatchMarker({ + id, + type: 'end', + size: sentSize, + count: sentChunks, + }), + ); +}; + +/** + * Creates a WebSocket message handler that can handle chunked messages. + * + * Reassembles the chunks into a single ArrayBuffer and pass it to the + * provided receive function. + * + * 1. The server receives a chunk start marker + * 2. The server pools each chunk until it receives a chunk end marker + * 3. The server validates that the received data matches the expected size + * 4. The server forwards the message to handlers + */ +export const handleChunked = (receive: (data: MessageData) => void): MessageHandler => { + let batch: ArrayBuffer[] | undefined; + let start: Batch | undefined; + + return (message) => { + if (typeof message === 'string') { + return; + } + if (isBatchSentinel(message.data)) { + const marker = parseBatchMarker(message.data); + if (marker.type === 'start') { + batch = []; + start = marker; + } + + if (marker.type === 'end') { + if (batch) { + try { + // validate start and end markers match + assertEquality(start?.id, marker.id, 'client id'); + assertEquality(start?.count, marker.count, 'client counts'); + assertEquality(start?.size, marker.size, 'client size'); + + // combine chunks into single buffer + const size = batch.reduce((sum, buffer) => sum + buffer.byteLength, 0); + const bytes = new Uint8Array(size); + let bytesWritten = 0; + for (const chunk of batch) { + bytes.set(new Uint8Array(chunk), bytesWritten); + bytesWritten += chunk.byteLength; + } + + // validate data as read matches expected + assertEquality(marker.count, batch.length, 'received batch count'); + assertEquality(marker.size, bytesWritten, 'client size'); + + receive(bytes); + } catch (e) { + console.error(e); + throw e; + } finally { + batch = undefined; + start = undefined; + } + } + } + } else if (batch) { + batch.push(message.data); + } else { + console.log('[party]::HandledChunk'); + // message too short to be chunked + receive(new Uint8Array(message.data)); + } + }; +}; + +function assertEquality(expected: unknown, actual: unknown, label: string) { + if (expected !== actual) { + throw new Error(`Mismatching ${label}! Expected ${expected}, got ${actual}`); + } else { + trace(`Matching ${label}: ${expected}`); + } +} + +/** Checks whether a message is batch marker */ +function isBatchSentinel(msg: MessageData): msg is string { + return typeof msg === 'string' && msg.startsWith(BATCH_SENTINEL); +} + +/** Encodes a batch marker message so that it can be safely parsed */ +function serializeBatchMarker(batch: Batch): string { + return `${BATCH_SENTINEL}#${JSON.stringify(batch)}`; +} + +/** Parses a batch marker messages and throws if its invalid */ +export function parseBatchMarker(msg: string) { + const [sentinel, data] = msg.split('#', 2); + if (sentinel !== BATCH_SENTINEL) { + throw new Error('Unexpected batch marker: ' + msg); + } + + const batch = JSON.parse(data) as Batch; + if (batch.type !== 'start' && batch.type !== 'end') { + throw new Error('Unexpected batch data: ' + msg); + } + + return batch; +} diff --git a/desci-repo/src/lib/automerge-repo-network-websocket/index.ts b/desci-repo/src/lib/automerge-repo-network-websocket/index.ts new file mode 100644 index 000000000..2d2574712 --- /dev/null +++ b/desci-repo/src/lib/automerge-repo-network-websocket/index.ts @@ -0,0 +1,28 @@ +/** + * A `NetworkAdapter` which connects to a remote host via WebSockets + * + * The websocket protocol requires a server to be listening and a client to + * connect to the server. To that end the {@link NodeWSServerAdapter} does not + * make outbound connections and instead listens on the provided socket for + * new connections whilst the {@link BrowserWebSocketClientAdapter} makes an + * outbound connection to the provided socket. + * + * Note that the "browser" and "node" naming is a bit misleading, both + * implementations work in both the browser and on node via `isomorphic-ws`. + * + * @module + * */ +// export { BrowserWebSocketClientAdapter } from './BrowserWebSocketClientAdapter.js'; +export type { + FromClientMessage, + FromServerMessage, + JoinMessage, + LeaveMessage, + ErrorMessage, + PeerMessage, +} from './messages.js'; +export { isPeerMessage, isErrorMessage } from './messages.js'; +export type { ProtocolVersion } from './protocolVersion.js'; +export { ProtocolV1 } from './protocolVersion.js'; +export { assert } from './assert.js'; +export { toArrayBuffer } from './toArrayBuffer.js'; diff --git a/desci-repo/src/lib/automerge-repo-network-websocket/messages.ts b/desci-repo/src/lib/automerge-repo-network-websocket/messages.ts new file mode 100644 index 000000000..4a3ebe1e4 --- /dev/null +++ b/desci-repo/src/lib/automerge-repo-network-websocket/messages.ts @@ -0,0 +1,71 @@ +import type { Message, PeerId, PeerMetadata } from "@automerge/automerge-repo" +import type { ProtocolVersion } from "./protocolVersion.js" + +/** The sender is disconnecting */ +export type LeaveMessage = { + type: "leave" + senderId: PeerId +} + +/** Sent by the client to the server to tell the server the clients PeerID */ +export type JoinMessage = { + type: "join" + /** The PeerID of the client */ + senderId: PeerId + + /** Metadata presented by the peer */ + peerMetadata: PeerMetadata + + /** The protocol version the client supports */ + supportedProtocolVersions: ProtocolVersion[] +} + +/** Sent by the server in response to a "join" message to advertise the servers PeerID */ +export type PeerMessage = { + type: "peer" + /** The PeerID of the server */ + senderId: PeerId + + /** Metadata presented by the peer */ + peerMetadata: PeerMetadata + + /** The protocol version the server selected for this connection */ + selectedProtocolVersion: ProtocolVersion + /** The PeerID of the client */ + targetId: PeerId +} + +/** An error occurred. The other end will terminate the connection after sending this message */ +export type ErrorMessage = { + type: "error" + /** The peer sending the message */ + senderId: PeerId + /** A description of the error*/ + message: string + /** The PeerID of the client */ + targetId: PeerId +} + +/** A message from the client to the server */ +export type FromClientMessage = JoinMessage | LeaveMessage | Message + +/** A message from the server to the client */ +export type FromServerMessage = PeerMessage | ErrorMessage | Message + +// TYPE GUARDS + +export const isJoinMessage = ( + message: FromClientMessage +): message is JoinMessage => message.type === "join" + +export const isLeaveMessage = ( + message: FromClientMessage +): message is LeaveMessage => message.type === "leave" + +export const isPeerMessage = ( + message: FromServerMessage +): message is PeerMessage => message.type === "peer" + +export const isErrorMessage = ( + message: FromServerMessage +): message is ErrorMessage => message.type === "error" diff --git a/desci-repo/src/lib/automerge-repo-network-websocket/protocolVersion.ts b/desci-repo/src/lib/automerge-repo-network-websocket/protocolVersion.ts new file mode 100644 index 000000000..a7a6769c9 --- /dev/null +++ b/desci-repo/src/lib/automerge-repo-network-websocket/protocolVersion.ts @@ -0,0 +1,3 @@ +export const ProtocolV1 = "1" +/** The versions of the websocket protocol */ +export type ProtocolVersion = typeof ProtocolV1 diff --git a/desci-repo/src/lib/automerge-repo-network-websocket/toArrayBuffer.ts b/desci-repo/src/lib/automerge-repo-network-websocket/toArrayBuffer.ts new file mode 100644 index 000000000..12a9acee5 --- /dev/null +++ b/desci-repo/src/lib/automerge-repo-network-websocket/toArrayBuffer.ts @@ -0,0 +1,8 @@ +/** + * This incantation deals with websocket sending the whole underlying buffer even if we just have a + * uint8array view on it + */ +export const toArrayBuffer = (bytes: Uint8Array) => { + const { buffer, byteOffset, byteLength } = bytes + return buffer.slice(byteOffset, byteOffset + byteLength) +} diff --git a/desci-repo/src/logger.ts b/desci-repo/src/logger.ts index 22ede5be2..bab514035 100644 --- a/desci-repo/src/logger.ts +++ b/desci-repo/src/logger.ts @@ -1,8 +1,10 @@ -import { pino } from 'pino'; -import { fileURLToPath } from 'url'; +import { AsyncLocalStorage } from 'async_hooks'; import path from 'path'; +import { fileURLToPath } from 'url'; + +import { pino } from 'pino'; + import { pool } from './db/index.js'; -import { AsyncLocalStorage } from 'async_hooks'; export const als = new AsyncLocalStorage(); diff --git a/desci-repo/src/middleware/ensureApiKey.ts b/desci-repo/src/middleware/ensureApiKey.ts index 28433065e..c2c84f993 100644 --- a/desci-repo/src/middleware/ensureApiKey.ts +++ b/desci-repo/src/middleware/ensureApiKey.ts @@ -1,14 +1,18 @@ import { Request, Response, NextFunction } from 'express'; + import { logger } from '../logger.js'; const REPO_SERVICE_API_KEY = process.env.REPO_SERVICE_SECRET_KEY; export const ensureApiKey = async (req: Request, res: Response, next: NextFunction) => { const apiKey = req.headers['x-api-key']; - logger.trace({ module: 'EnsureApiKey', apiKeyLength: apiKey?.length, hostname: req.hostname }, 'VERIFY API KEY from'); if (!apiKey || apiKey !== REPO_SERVICE_API_KEY) { res.sendStatus(401); return; } + // logger.trace( + // { module: 'EnsureApiKey', apiKeyLength: apiKey, REPO_SERVICE_API_KEY, url: req.url, hostname: req.hostname }, + // 'VERIFY API KEY', + // ); next(); }; diff --git a/desci-repo/src/middleware/guard.ts b/desci-repo/src/middleware/guard.ts index 49665ae7b..02797acfc 100644 --- a/desci-repo/src/middleware/guard.ts +++ b/desci-repo/src/middleware/guard.ts @@ -1,10 +1,11 @@ // import { Node, User } from '@prisma/client'; import { Request, Response, NextFunction } from 'express'; -import { extractAuthToken, extractUserFromToken } from './permissions.js'; +import { query } from '../db/index.js'; import { logger as parentLogger } from '../logger.js'; import { hideEmail } from '../services/user.js'; -import { query } from '../db/index.js'; + +import { extractAuthToken, extractUserFromToken } from './permissions.js'; const logger = parentLogger.child({ module: 'MIDDLEWARE/GUARD' }); diff --git a/desci-repo/src/repo.ts b/desci-repo/src/repo.ts index 968c13e50..45ad7aff1 100644 --- a/desci-repo/src/repo.ts +++ b/desci-repo/src/repo.ts @@ -1,54 +1,94 @@ import os from 'os'; -import { DocHandleChangePayload, DocHandleEvents, PeerId, Repo, RepoConfig } from '@automerge/automerge-repo'; -import { NodeWSServerAdapter } from '@automerge/automerge-repo-network-websocket'; -import { WebSocketServer } from 'ws'; - -import { PostgresStorageAdapter } from './lib/PostgresStorageAdapter.js'; +import { + DocHandleChangePayload, + DocHandleEvents, + DocumentId, + PeerId, + Repo, + RepoConfig, +} from '@automerge/automerge-repo'; +import WebSocket from 'isomorphic-ws'; import { logger as parentLogger } from './logger.js'; -import { verifyNodeDocumentAccess } from './services/nodes.js'; import { ResearchObjectDocument } from './types.js'; import * as db from './db/index.js'; import { ensureUuidEndsWithDot } from './controllers/nodes/utils.js'; +import { PartykitNodeWsAdapter } from './lib/PartykitNodeWsAdapter.js'; +import { PostgresStorageAdapter } from './lib/PostgresStorageAdapter.js'; +import { NodeWSServerAdapter } from '@automerge/automerge-repo-network-websocket'; +import { WebSocketServer } from 'ws'; +import { verifyNodeDocumentAccess } from './services/nodes.js'; +import { ENABLE_PARTYKIT_FEATURE, IS_DEV, IS_TEST, PARTY_SERVER_HOST, PARTY_SERVER_TOKEN } from './config.js'; -export const socket = new WebSocketServer({ - port: process.env.WS_PORT ? parseInt(process.env.WS_PORT) : 5445, - path: '/sync', -}); -const hostname = os.hostname(); +const partyServerHost = PARTY_SERVER_HOST || 'localhost:5445'; +const partyServerToken = PARTY_SERVER_TOKEN; const logger = parentLogger.child({ module: 'repo.ts' }); -const adapter = new NodeWSServerAdapter(socket); -const config: RepoConfig = { - network: [adapter], - storage: new PostgresStorageAdapter(), - peerId: `storage-server-${hostname}` as PeerId, - // Since this is a server, we don't share generously β€” meaning we only sync documents they already - // know about and can ask for by ID. - sharePolicy: async (peerId, documentId) => { - try { - if (!documentId) { - logger.trace({ peerId }, 'SharePolicy: Document ID NOT found'); - return false; - } - // peer format: `peer-[user#id]:[unique string combination] - if (peerId.toString().length < 8) { - logger.error({ peerId }, 'SharePolicy: Peer ID invalid'); +if (ENABLE_PARTYKIT_FEATURE && !(partyServerToken && partyServerHost)) { + throw new Error('Missing ENVIRONMENT variables: PARTY_SERVER_HOST or PARTY_SERVER_TOKEN'); +} + +const hostname = os.hostname(); + +logger.trace({ partyServerHost, partyServerToken, serverName: os.hostname() ?? 'no-hostname' }, 'Env checked'); + +let config: RepoConfig; +let socket: WebSocketServer; + +if (ENABLE_PARTYKIT_FEATURE) { + config = { + peerId: `repo-server-${hostname}` as PeerId, + // Since this is a server, we don't share generously β€” meaning we only sync documents they already + // know about and can ask for by ID. + sharePolicy: async (peerId, documentId) => { + logger.trace({ peerId, documentId }, 'SharePolicy called'); + return true; + }, + }; +} else { + socket = new WebSocketServer({ + port: process.env.WS_PORT ? parseInt(process.env.WS_PORT) : 5445, + path: '/sync', + }); + + const adapter = new NodeWSServerAdapter(socket); + + config = { + network: [adapter], + storage: new PostgresStorageAdapter(), + peerId: `repo-server-${hostname}` as PeerId, + // Since this is a server, we don't share generously β€” meaning we only sync documents they already + // know about and can ask for by ID. + sharePolicy: async (peerId, documentId) => { + try { + if (!documentId) { + logger.trace({ peerId }, 'SharePolicy: Document ID NOT found'); + return false; + } + // peer format: `peer-[user#id]:[unique string combination] + if (peerId.toString().length < 8) { + logger.error({ peerId }, 'SharePolicy: Peer ID invalid'); + return false; + } + + const userId = peerId.split(':')?.[0]?.split('-')?.[1]; + const isAuthorised = await verifyNodeDocumentAccess(Number(userId), documentId); + logger.trace({ peerId, userId, documentId, isAuthorised }, '[SHARE POLICY CALLED]::'); + return isAuthorised; + } catch (err) { + logger.error({ err }, 'Error in share policy'); return false; } + }, + }; +} + +export { socket }; - const userId = peerId.split(':')?.[0]?.split('-')?.[1]; - const isAuthorised = await verifyNodeDocumentAccess(Number(userId), documentId); - logger.trace({ peerId, userId, documentId, isAuthorised }, '[SHARE POLICY CALLED]::'); - return isAuthorised; - } catch (err) { - logger.error({ err }, 'Error in share policy'); - return false; - } - }, -}; export const backendRepo = new Repo(config); + +// move logic to sync server const handleChange = async (change: DocHandleChangePayload) => { logger.trace({ change: change.handle.documentId, uuid: change.patchInfo.after.uuid }, 'Document Changed'); const newTitle = change.patchInfo.after.manifest.title; @@ -80,6 +120,7 @@ const handleChange = async (change: DocHandleChangePayload { + logger.trace({ documentId: doc.handle.documentId }, 'DOCUMENT Ready'); doc.handle.on>('change', handleChange); }); @@ -87,4 +128,71 @@ backendRepo.off('document', async (doc) => { doc.handle.off('change', handleChange); }); -// todo: Recover from RangeError -> reset repo and return a new instance +class RepoManager { + clients: Map = new Map(); + intervalId: ReturnType; + + constructor(private repo: Repo) {} + + isConnected(documentId: DocumentId) { + if (!ENABLE_PARTYKIT_FEATURE) return true; + return this.clients.has(documentId); + } + + connect(documentId: DocumentId) { + logger.trace({ documentId, IS_DEV, IS_TEST, exists: this.clients.has(documentId) }, 'RepoManager#Connect'); + const adapter = new PartykitNodeWsAdapter({ + host: partyServerHost, + party: 'automerge', + room: documentId, + query: { auth: partyServerToken }, + protocol: IS_DEV || IS_TEST ? 'ws' : 'wss', + WebSocket: WebSocket, + }); + + // adapter.on('ready', (ready) => logger.trace({ ready: ready.network.peerId }, 'networkReady')); + this.repo.networkSubsystem.addNetworkAdapter(adapter); + + this.repo.networkSubsystem.on('peer-disconnected', (peer) => { + if (peer.peerId === adapter.remotePeerId) { + // clean up adapater and it's document handle after timeout + // setTimeout(() => { + // logger.trace( + // { + // peer: peer.peerId, + // remotePeerId: adapter.remotePeerId, + // documentId, + // socketState: adapter.socket?.readyState, + // }, + // 'Post disconnect', + // ); + // if (adapter.socket?.readyState !== WebSocket.OPEN || !adapter?.socket) this.cleanUp(documentId); + // }, 60000); + } + logger.trace( + { peer: peer.peerId, remotePeerId: adapter.remotePeerId, documentId, socketState: adapter.socket?.readyState }, + 'peer-disconnected', + ); + }); + + this.clients.set(documentId, adapter); + } + + /** + * Clean up a connection and it's handle to free memory effectively + * @param documentId + */ + cleanUp(documentId) { + const adapter = this.clients.get(documentId); + if (adapter) { + // this.repo.networkSubsystem.removeNetworkAdapter(adapter); + this.clients.delete(documentId); + // const handle = this.repo.find(documentId); + // handle.unload(); + // delete this.repo.handles[documentId]; + logger.trace({ documentId }, ' RepoManager#cleanUp'); + } + } +} + +export const repoManager = new RepoManager(backendRepo); diff --git a/desci-repo/src/routes/v1/nodes.ts b/desci-repo/src/routes/v1/nodes.ts index 6714813db..d039cea44 100644 --- a/desci-repo/src/routes/v1/nodes.ts +++ b/desci-repo/src/routes/v1/nodes.ts @@ -1,4 +1,5 @@ import { Router } from 'express'; + import { createNodeDocument, dispatchDocumentActions, diff --git a/desci-repo/src/server.ts b/desci-repo/src/server.ts index f8b95d724..0934bab2c 100644 --- a/desci-repo/src/server.ts +++ b/desci-repo/src/server.ts @@ -1,3 +1,6 @@ +import 'reflect-metadata'; +import path from 'path'; + import * as Sentry from '@sentry/node'; import { nodeProfilingIntegration } from '@sentry/profiling-node'; @@ -5,28 +8,25 @@ const ENABLE_TELEMETRY = process.env.NODE_ENV === 'production'; const IS_DEV = !ENABLE_TELEMETRY; // @ts-check + +import type { Server as HttpServer } from 'http'; +import { fileURLToPath } from 'url'; + import 'dotenv/config'; import 'reflect-metadata'; -import path from 'path'; - +import bodyParser from 'body-parser'; +import cors from 'cors'; import express from 'express'; import type { Express, Request } from 'express'; -import cors from 'cors'; -import bodyParser from 'body-parser'; - -import type { Server as HttpServer } from 'http'; +import { pinoHttp } from 'pino-http'; import { v4 } from 'uuid'; import { als, logger } from './logger.js'; +import { RequestWithUser } from './middleware/guard.js'; +import { extractAuthToken, extractUserFromToken } from './middleware/permissions.js'; import routes from './routes/index.js'; -// import SocketServer from './wsServer.js'; -import { fileURLToPath } from 'url'; -import { socket as wsSocket } from './repo.js'; - -import { extractAuthToken, extractUserFromToken } from './middleware/permissions.js'; -import { pinoHttp } from 'pino-http'; -import { RequestWithUser } from './middleware/guard.js'; +import { ENABLE_PARTYKIT_FEATURE } from './config.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -136,12 +136,21 @@ class AppServer { logger.info(`Server running on port ${this.port}`); }); + if (!ENABLE_PARTYKIT_FEATURE) { + this.acceptWebsocketConnections(); + } + } + + async acceptWebsocketConnections() { + const wsSocket = await import('./repo.js').then((x) => x.socket); + wsSocket.on('listening', () => { logger.info({ module: 'WebSocket SERVER', port: wsSocket.address() }, 'WebSocket Server Listening'); }); + wsSocket.on('connection', async (socket, request) => { try { - logger.info({ module: 'WebSocket SERVER' }, 'WebSocket Connection Attempt'); + logger.info({ module: 'WebSocket' }, 'WebSocket Connection Attempt'); const token = await extractAuthToken(request as Request); const authUser = await extractUserFromToken(token!); if (!authUser) { diff --git a/desci-repo/src/services/manifestRepo.ts b/desci-repo/src/services/manifestRepo.ts index b82b6e1d0..a03f50a3f 100644 --- a/desci-repo/src/services/manifestRepo.ts +++ b/desci-repo/src/services/manifestRepo.ts @@ -15,7 +15,7 @@ import { import isEqual from 'deep-equal'; import { logger as parentLogger } from '../logger.js'; -import { backendRepo } from '../repo.js'; +import { backendRepo, repoManager } from '../repo.js'; import { ResearchObjectDocument } from '../types.js'; const logger = parentLogger.child({ module: 'manifestRepo.ts' }); @@ -31,11 +31,24 @@ export function assertNever(value: never) { throw Error('Not Possible'); } -export const getDocumentUpdater = (documentId: DocumentId) => { +const getDocumentHandle = async (documentId: DocumentId) => { + const logger = parentLogger.child({ module: 'connectRepoToDocument', documentId }); + + if (!repoManager.isConnected(documentId)) { + repoManager.connect(documentId); + } + const automergeUrl = getAutomergeUrl(documentId); - logger.trace({ automergeUrl }, 'Find handle'); + await backendRepo.networkSubsystem.whenReady(); + logger.trace({ documentId }, 'ready'); const handle = backendRepo.find(automergeUrl as AutomergeUrl); - logger.trace({ automergeUrl }, 'Retrieved handle'); + logger.trace({ handle: handle.url }, 'handle resolved'); + return handle; +}; + +export const getDocumentUpdater = async (documentId: DocumentId) => { + const handle = await getDocumentHandle(documentId); //backendRepo.find(automergeUrl as AutomergeUrl); + logger.trace({ handle: handle.isReady() }, 'Retrieved handle'); return async (action: ManifestActions) => { if (!handle) return; @@ -45,12 +58,10 @@ export const getDocumentUpdater = (documentId: DocumentId) => { if (!latestDocument) { logger.error({ node: documentId }, 'Automerge document not found'); - // throw new Error('Automerge Document Not found'); return; } const heads = getHeads(latestDocument); - // logger.info({ heads, action }, `Document Heads`); logger.trace({ action, heads }, `DocumentUpdater::Dispatched`); switch (action.type) { @@ -196,22 +207,6 @@ export const getDocumentUpdater = (documentId: DocumentId) => { { time: Date.now(), message: action.type }, ); break; - case 'Delete Component': - handle.change( - (document) => { - deleteComponent(document, action.path); - }, - { time: Date.now(), message: action.type }, - ); - break; - case 'Update Component': - handle.change( - (document) => { - updateManifestComponent(document, action.component, action.componentIndex); - }, - { time: Date.now(), message: action.type }, - ); - break; case 'Upsert Component': handle.change( (document) => { @@ -247,7 +242,7 @@ export const getDocumentUpdater = (documentId: DocumentId) => { ); break; case 'Pin Component': - let componentIndex = latestDocument?.manifest.components.findIndex((c) => c.payload?.path === action.path); + const componentIndex = latestDocument?.manifest.components.findIndex((c) => c.payload?.path === action.path); if (componentIndex && componentIndex != -1) { handle.change( (document) => { @@ -258,7 +253,7 @@ export const getDocumentUpdater = (documentId: DocumentId) => { } break; case 'UnPin Component': - let index = latestDocument?.manifest.components.findIndex((c) => c.payload?.path === action.path); + const index = latestDocument?.manifest.components.findIndex((c) => c.payload?.path === action.path); if (index && index != -1) { handle.change( (document) => { @@ -336,18 +331,26 @@ export const getDocumentUpdater = (documentId: DocumentId) => { document.manifest.references = []; } - for (const reference of action.reference) { + for (const reference of action.references) { if (!document.manifest.references.find((ref) => ref.id === reference.id)) document.manifest.references.push(reference); } }); break; + case 'Set References': + handle.change((document) => { + if (!document.manifest.references) { + document.manifest.references = []; + } + document.manifest.references = action.references; + }); + break; case 'Delete Reference': if (!action.referenceId) return; const deletedIdx = latestDocument.manifest.references?.findIndex((ref) => ref.id === action.referenceId); - if (deletedIdx !== -1) { + if (deletedIdx !== undefined && deletedIdx !== -1) { handle.change((document) => { - document.manifest.references?.splice(deleteIdx, 1); + document.manifest.references?.splice(deletedIdx, 1); }); } break; @@ -494,6 +497,7 @@ const upsertManifestComponent = (doc: Doc, component: Re } }; +// eslint-disable-next-line @typescript-eslint/ban-types type TypeInitialisers = {} | '' | 0 | []; const getTypeDefault = (value: unknown): TypeInitialisers => { diff --git a/desci-repo/src/services/nodes.ts b/desci-repo/src/services/nodes.ts index d7d60236b..6af9f294b 100644 --- a/desci-repo/src/services/nodes.ts +++ b/desci-repo/src/services/nodes.ts @@ -1,25 +1,21 @@ import { DocumentId } from '@automerge/automerge-repo'; + import { query } from '../db/index.js'; import { logger } from '../logger.js'; export const verifyNodeDocumentAccess = async (userId: number, documentId: DocumentId) => { try { - logger.trace({ userId, documentId }, 'START [verifyNodeDocumentAccess]::Node'); const rows = await query('SELECT * FROM "Node" WHERE "manifestDocumentId" = $1 AND "ownerId" = $2', [ documentId, userId, ]); const node = rows?.[0]; - logger.trace( - { uuid: node.uuid, userId, ownerId: node.ownerId, documentId: node.manifestDocumentId }, - '[verifyNodeDocumentAccess]::Node', - ); - if (!node) return false; if (node.manifestDocumentId === documentId && node.ownerId === userId) return true; return false; - } catch (e) { + } catch (error) { + logger.error({ error }, 'VerifyNodeDocumentAccess'); return false; } }; diff --git a/desci-repo/src/services/user.ts b/desci-repo/src/services/user.ts index 3f8e40d99..6d88dddf1 100644 --- a/desci-repo/src/services/user.ts +++ b/desci-repo/src/services/user.ts @@ -1,5 +1,5 @@ -import { logger as parentLogger } from '../logger.js'; import { query } from '../db/index.js'; +import { logger as parentLogger } from '../logger.js'; export const hideEmail = (email: string) => { return email.replace(/(.{1,1})(.*)(@.*)/, '$1...$3'); diff --git a/desci-repo/src/types.ts b/desci-repo/src/types.ts index 79d6062c8..56f660a18 100644 --- a/desci-repo/src/types.ts +++ b/desci-repo/src/types.ts @@ -4,4 +4,4 @@ export interface ResearchObjectDocument { manifest: ResearchObjectV1; uuid: string; driveClock: string; -} \ No newline at end of file +} diff --git a/desci-repo/src/validators/schema.ts b/desci-repo/src/validators/schema.ts index a93669e47..e745cd841 100644 --- a/desci-repo/src/validators/schema.ts +++ b/desci-repo/src/validators/schema.ts @@ -1,4 +1,3 @@ -import { z } from 'zod'; import { ResearchObjectComponentType, ResearchObjectV1AuthorRole, @@ -8,6 +7,7 @@ import { ManifestActions, ResearchObjectReference, } from '@desci-labs/desci-models'; +import { z } from 'zod'; const researchObject = z .object({ @@ -64,7 +64,7 @@ const componentSchema: z.ZodType = z export const DPID_PATH_REGEX = /^https:\/\/(?dev-beta|beta)\.dpid\.org(?\/\d+)(?\/v\d+)?(?\/root.*)?/m; -export const DOI_REGEX = /(https:\/\/doi.org\/)?(?10.\d{4,9}\/[-._;()/:A-Z0-9]+$)/i; +export const DOI_REGEX = /(https:\/\/doi.org\/)?(?10.\d{4,9}\/[-+<>._;()/:A-Z0-9]+$)/i; const referenceSchema: z.ZodType = z .object({ @@ -97,7 +97,8 @@ export const actionsSchema = z.array( z.object({ type: z.literal('UnPin Component'), componentIndex: z.number() }), z.object({ type: z.literal('Update CoverImage'), cid: z.string().optional() }), z.object({ type: z.literal('Add Reference'), reference: referenceSchema }), - z.object({ type: z.literal('Add References'), references: z.array(referenceSchema) }), + z.object({ type: z.literal('Add References'), reference: z.array(referenceSchema) }), + // z.object({ type: z.literal('Set References'), references: z.array(referenceSchema) }), z.object({ type: z.literal('Delete Reference'), referenceId: z.string() }), ]), ); diff --git a/desci-repo/src/validators/test/schema.spec.ts b/desci-repo/src/validators/test/schema.spec.ts index fbb4e24f5..590e57224 100644 --- a/desci-repo/src/validators/test/schema.spec.ts +++ b/desci-repo/src/validators/test/schema.spec.ts @@ -1,7 +1,4 @@ import 'mocha'; -import { expect } from 'chai'; -import { actionsSchema } from '../../validators/schema.js'; -import { ZodError } from 'zod'; import { CodeComponent, ExternalLinkComponent, @@ -11,6 +8,10 @@ import { ResearchObjectV1AuthorRole, ResearchObjectV1Component, } from '@desci-labs/desci-models'; +import { expect } from 'chai'; +import { ZodError } from 'zod'; + +import { actionsSchema } from '../../validators/schema.js'; describe('ManifestActions Schema', () => { describe('Valid Actions', () => { @@ -312,8 +313,9 @@ describe('ManifestActions Schema', () => { console.log('error' in validated && validated.error); expect(validated.success).to.be.true; }); + it('should validate add new references', () => { - let validated = actionsSchema.safeParse([ + const validated = actionsSchema.safeParse([ { type: 'Add References', references: [ @@ -325,8 +327,21 @@ describe('ManifestActions Schema', () => { expect(validated.success).to.be.true; }); + it('should validate ovewriting references', () => { + const validated = actionsSchema.safeParse([ + { + type: 'Set References', + references: [ + { id: 'https://doi.org/10.1111/af325', type: 'doi' }, + { id: 'https://beta.dpid.org/165/v6', type: 'dpid' }, + ], + }, + ]); + expect(validated.success).to.be.true; + }); + it('should reject invalid references', () => { - let validated = actionsSchema.safeParse([ + const validated = actionsSchema.safeParse([ { type: 'Add References', references: [ @@ -339,7 +354,7 @@ describe('ManifestActions Schema', () => { }); it('should reject reference Id/type mismatch', () => { - let validated = actionsSchema.safeParse([ + const validated = actionsSchema.safeParse([ { type: 'Add References', references: [ @@ -370,7 +385,7 @@ describe('ManifestActions Schema', () => { }); it('should validate delete existing reference', () => { - let validated = actionsSchema.safeParse([ + const validated = actionsSchema.safeParse([ { type: 'Delete Reference', referenceId: 'https://doi.org/10.111/af325' }, ]); expect(validated.success).to.be.true; diff --git a/desci-repo/tsconfig.json b/desci-repo/tsconfig.json index 74fe79023..6126c7564 100755 --- a/desci-repo/tsconfig.json +++ b/desci-repo/tsconfig.json @@ -9,10 +9,7 @@ "target": "esnext", // Recommended by docs, but a lot of errors // "verbatimModuleSyntax": true, - "lib": [ - "esnext", - "dom" - ], + "lib": ["esnext", "dom"], "outDir": "./dist", "removeComments": true, "emitDecoratorMetadata": true, @@ -26,18 +23,12 @@ "inlineSourceMap": true, "paths": { // Overrides a built-in Response type - "express": [ - "./src/types/express" - ] + "express": ["./src/types/express"], }, "strictNullChecks": true, - "exactOptionalPropertyTypes": true + "exactOptionalPropertyTypes": true, }, - "include": [ - "./src/**/*.ts", - ], - "exclude": [ - "test/**/*.ts" - ], - "compileOnSave": true -} \ No newline at end of file + "include": ["./src/**/*.ts"], + "exclude": ["test/**/*.ts", "./src/party/"], + "compileOnSave": true, +} diff --git a/desci-repo/yarn.lock b/desci-repo/yarn.lock index e6744e445..ef3dfed8b 100644 --- a/desci-repo/yarn.lock +++ b/desci-repo/yarn.lock @@ -7,48 +7,31 @@ resolved "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz" integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== -"@automerge/automerge-repo-network-websocket@^1.0.19": - version "1.1.0" - resolved "https://registry.npmjs.org/@automerge/automerge-repo-network-websocket/-/automerge-repo-network-websocket-1.1.0.tgz" - integrity sha512-D3k/RKI5xVPb+ZEmEmL/MiuGiu2vzujOloyHveLmd1R9BL2JakbKk1s4G2MhTBT1qF8Io02pIa1+lsaG9HlULA== +"@automerge/automerge-repo-network-websocket@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@automerge/automerge-repo-network-websocket/-/automerge-repo-network-websocket-1.2.1.tgz#1596929fec3f4f1a0f0da7fb4e9350b304d4604e" + integrity sha512-n4sI6l51iBf0edWtX+vhk+sc8wJL72IVZl682SvzRHakA5CzyNZiC8sVzc142zRT3RDN12jCWGpwA2Voq6EXsQ== dependencies: - "@automerge/automerge-repo" "1.1.0" + "@automerge/automerge-repo" "1.2.1" cbor-x "^1.3.0" debug "^4.3.4" eventemitter3 "^5.0.1" isomorphic-ws "^5.0.0" ws "^8.7.0" -"@automerge/automerge-repo-storage-nodefs@^1.0.19": - version "1.1.0" - resolved "https://registry.npmjs.org/@automerge/automerge-repo-storage-nodefs/-/automerge-repo-storage-nodefs-1.1.0.tgz" - integrity sha512-31vTq4ItdV0n4x7MOF/mmKwUqEwYQMekYZ3OEgUdJAhw7qIrF1lY0IM194DjVp9V55UFFMQyb5vx+VJ4GpKewA== +"@automerge/automerge-repo-storage-indexeddb@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@automerge/automerge-repo-storage-indexeddb/-/automerge-repo-storage-indexeddb-1.2.1.tgz#1c6080079b5ffaf862afd00757404f12b2aadead" + integrity sha512-u+9eZZJK7DAr541buF4ut1ipkuiKRoaAtoFYo/ilq7zOLO7JX+GQOFx/8eKKRDlGt/AHTcDaFktkcaX0vKahQQ== dependencies: - "@automerge/automerge-repo" "1.1.0" - rimraf "^5.0.1" + "@automerge/automerge-repo" "1.2.1" -"@automerge/automerge-repo@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@automerge/automerge-repo/-/automerge-repo-1.1.0.tgz" - integrity sha512-QRSt2s89Uhrlofbkipsb/9Alyp65/e1PocNzY+L4J7yDDXD7fbEW5uThXey2lSb1m98Fe0+NtzyKD1we6lvAkA== - dependencies: - "@automerge/automerge" "^2.1.9" - bs58check "^3.0.1" - cbor-x "^1.3.0" - debug "^4.3.4" - eventemitter3 "^5.0.1" - fast-sha256 "^1.3.0" - tiny-typed-emitter "^2.1.0" - ts-node "^10.9.1" - uuid "^9.0.0" - xstate "^4.37.0" - -"@automerge/automerge-repo@^1.1.0": - version "1.1.1" - resolved "https://registry.npmjs.org/@automerge/automerge-repo/-/automerge-repo-1.1.1.tgz" - integrity sha512-fQq+4eUadubzHOUi2BIiC5f/XFUHixJ/kdfnbXRoh2xwzojMfQIlrRfZzxkuW5AdD9LOC2/LoWJs+ak4a9vq4Q== +"@automerge/automerge-repo@1.2.1", "@automerge/automerge-repo@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@automerge/automerge-repo/-/automerge-repo-1.2.1.tgz#73ae042accee275ee74f014f7ddbed6950c77204" + integrity sha512-uEBr4bM01aSWkEt2tDKQxfW0Pahz2zbTTn4sRJfeKJlAg2SLr4QepFJ+3Tp4CNEkkU485olfnKYf6gt7uilMZQ== dependencies: - "@automerge/automerge" "^2.1.9" + "@automerge/automerge" "^2.2.5" bs58check "^3.0.1" cbor-x "^1.3.0" debug "^4.3.4" @@ -57,19 +40,13 @@ tiny-typed-emitter "^2.1.0" ts-node "^10.9.1" uuid "^9.0.0" - xstate "^4.37.0" - -"@automerge/automerge-wasm@0.9.0": - version "0.9.0" - resolved "https://registry.npmjs.org/@automerge/automerge-wasm/-/automerge-wasm-0.9.0.tgz" - integrity sha512-wTPcW3wVk20D1x0DOko/RsfZV1mlc8HJynqgTRhVocOxFIU/RCilnYRfJmSb8LwCG2uZzfqg0DLsEBqQZ53KBQ== + xstate "^5.9.1" -"@automerge/automerge@^2.1.10", "@automerge/automerge@^2.1.9": - version "2.1.10" - resolved "https://registry.npmjs.org/@automerge/automerge/-/automerge-2.1.10.tgz" - integrity sha512-xj8R3fQHZmDYnrYW5WrBqWm/r5sLV9Z7mu89pJ10wGLVS2V+iAB2os85DoOGI2etzjmQsoHyrd97GBmszjH4zQ== +"@automerge/automerge@^2.2.5": + version "2.2.8" + resolved "https://registry.yarnpkg.com/@automerge/automerge/-/automerge-2.2.8.tgz#6e33f271b99a652751c1a53048df2a2b2a80dcc2" + integrity sha512-kP6Z9lIkNeIGe/jhF8SUQAgUMwVjtXCBL0eZEgQGCoWvPNTPcg8fnQco28XkYBrfkkuqiEUAbdHhJmSp0y79ug== dependencies: - "@automerge/automerge-wasm" "0.9.0" uuid "^9.0.0" "@babel/code-frame@^7.0.0": @@ -124,17 +101,92 @@ resolved "https://registry.yarnpkg.com/@cbor-extract/cbor-extract-win32-x64/-/cbor-extract-win32-x64-2.2.0.tgz#4b3f07af047f984c082de34b116e765cb9af975f" integrity sha512-l2M+Z8DO2vbvADOBNLbbh9y5ST1RY5sqkWOg/58GkUPBYou/cuNZ68SGQ644f1CvZ8kcOxyZtw06+dxWHIoN/w== -"@cspotcode/source-map-support@^0.8.0": +"@cloudflare/kv-asset-handler@0.3.4": + version "0.3.4" + resolved "https://registry.yarnpkg.com/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.3.4.tgz#5cc152847c8ae4d280ec5d7f4f6ba8c976b585c3" + integrity sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q== + dependencies: + mime "^3.0.0" + +"@cloudflare/workerd-darwin-64@1.20240718.0": + version "1.20240718.0" + resolved "https://registry.yarnpkg.com/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20240718.0.tgz#46f438fb86ccd4772c29db52fe1d076bc9e6ffb4" + integrity sha512-BsPZcSCgoGnufog2GIgdPuiKicYTNyO/Dp++HbpLRH+yQdX3x4aWx83M+a0suTl1xv76dO4g9aw7SIB6OSgIyQ== + +"@cloudflare/workerd-darwin-64@1.20241022.0": + version "1.20241022.0" + resolved "https://registry.yarnpkg.com/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20241022.0.tgz#1d22149152ad32672971e3be48ab1491ff236eb3" + integrity sha512-1NNYun37myMTgCUiPQEJ0cMal4mKZVTpkD0b2tx9hV70xji+frVJcSK8YVLeUm1P+Rw1d/ct8DMgQuCpsz3Fsw== + +"@cloudflare/workerd-darwin-arm64@1.20240718.0": + version "1.20240718.0" + resolved "https://registry.yarnpkg.com/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20240718.0.tgz#70e1dca5de4869ef3a9b9e296e934848bca6c74f" + integrity sha512-nlr4gaOO5gcJerILJQph3+2rnas/nx/lYsuaot1ntHu4LAPBoQo1q/Pucj2cSIav4UiMzTbDmoDwPlls4Kteog== + +"@cloudflare/workerd-darwin-arm64@1.20241022.0": + version "1.20241022.0" + resolved "https://registry.yarnpkg.com/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20241022.0.tgz#6ec4e4fd1427ac09d9cfea38db849799755029e5" + integrity sha512-FOO/0P0U82EsTLTdweNVgw+4VOk5nghExLPLSppdOziq6IR5HVgP44Kmq5LdsUeHUhwUmfOh9hzaTpkNzUqKvw== + +"@cloudflare/workerd-linux-64@1.20240718.0": + version "1.20240718.0" + resolved "https://registry.yarnpkg.com/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20240718.0.tgz#802c04a1a5729f3881c675be3d158ee06c6b1a36" + integrity sha512-LJ/k3y47pBcjax0ee4K+6ZRrSsqWlfU4lbU8Dn6u5tSC9yzwI4YFNXDrKWInB0vd7RT3w4Yqq1S6ZEbfRrqVUg== + +"@cloudflare/workerd-linux-64@1.20241022.0": + version "1.20241022.0" + resolved "https://registry.yarnpkg.com/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20241022.0.tgz#0297222e46ce8b2c55b591ae87ee2bbb85830e20" + integrity sha512-RsNc19BQJG9yd+ngnjuDeG9ywZG+7t1L4JeglgceyY5ViMNMKVO7Zpbsu69kXslU9h6xyQG+lrmclg3cBpnhYA== + +"@cloudflare/workerd-linux-arm64@1.20240718.0": + version "1.20240718.0" + resolved "https://registry.yarnpkg.com/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20240718.0.tgz#cebff9115d48f8d0c2649fdf86ef46b726d1841f" + integrity sha512-zBEZvy88EcAMGRGfuVtS00Yl7lJdUM9sH7i651OoL+q0Plv9kphlCC0REQPwzxrEYT1qibSYtWcD9IxQGgx2/g== + +"@cloudflare/workerd-linux-arm64@1.20241022.0": + version "1.20241022.0" + resolved "https://registry.yarnpkg.com/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20241022.0.tgz#7637092b14129c94ddb87990221d38623e4fd498" + integrity sha512-x5mUXpKxfsosxcFmcq5DaqLs37PejHYVRsNz1cWI59ma7aC4y4Qn6Tf3i0r9MwQTF/MccP4SjVslMU6m4W7IaA== + +"@cloudflare/workerd-windows-64@1.20240718.0": + version "1.20240718.0" + resolved "https://registry.yarnpkg.com/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20240718.0.tgz#940893e62df7f5a8ec895572b834c95c1e256fbd" + integrity sha512-YpCRvvT47XanFum7C3SedOZKK6BfVhqmwdAAVAQFyc4gsCdegZo0JkUkdloC/jwuWlbCACOG2HTADHOqyeolzQ== + +"@cloudflare/workerd-windows-64@1.20241022.0": + version "1.20241022.0" + resolved "https://registry.yarnpkg.com/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20241022.0.tgz#64f05a2bc475e1450154942c060555184e6350de" + integrity sha512-eBCClx4szCOgKqOlxxbdNszMqQf3MRG1B9BRIqEM/diDfdR9IrZ8l3FaEm+l9gXgPmS6m1NBn40aWuGBl8UTSw== + +"@cloudflare/workers-shared@0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@cloudflare/workers-shared/-/workers-shared-0.7.0.tgz#ecb6a3a1f483989c1ca10d5ed0592d01c7eff0c0" + integrity sha512-LLQRTqx7lKC7o2eCYMpyc5FXV8d0pUX6r3A+agzhqS9aoR5A6zCPefwQGcvbKx83ozX22ATZcemwxQXn12UofQ== + dependencies: + mime "^3.0.0" + zod "^3.22.3" + +"@cloudflare/workers-types@4.20240718.0": + version "4.20240718.0" + resolved "https://registry.yarnpkg.com/@cloudflare/workers-types/-/workers-types-4.20240718.0.tgz#6541a3dad04215af5030afe4ce879b7091051458" + integrity sha512-7RqxXIM9HyhjfZ9ztXjITuc7mL0w4s+zXgypqKmMuvuObC3DgXutJ3bOYbQ+Ss5QbywrzWSNMlmGdL/ldg/yZg== + +"@cloudflare/workers-types@^4.20241022.0": + version "4.20241022.0" + resolved "https://registry.yarnpkg.com/@cloudflare/workers-types/-/workers-types-4.20241022.0.tgz#4f751ec29b9a2a0cef83bdc797b02089462ee48d" + integrity sha512-1zOAw5QIDKItzGatzCrEpfLOB1AuMTwVqKmbw9B9eBfCUGRFNfJYMrJxIwcse9EmKahsQt2GruqU00pY/GyXgg== + +"@cspotcode/source-map-support@0.8.1", "@cspotcode/source-map-support@^0.8.0": version "0.8.1" resolved "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz" integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@desci-labs/desci-models@0.2.11": - version "0.2.11" - resolved "https://registry.yarnpkg.com/@desci-labs/desci-models/-/desci-models-0.2.11.tgz#3dabeeb606ce34f98597c36a92bb1235ebd88265" - integrity sha512-U+Svmqn2vzK967zoHek2oxNkELowKL87JSplh41V7eMjZMUeaDvnkWS5FCbn4YtjDaMOYVHBVV9CpDUWO+dAvQ== +"@desci-labs/desci-models@^0.2.19": + version "0.2.19" + resolved "https://registry.yarnpkg.com/@desci-labs/desci-models/-/desci-models-0.2.19.tgz#430f8e6b6a1967d6b06fc8a36e6c32536e1a4a42" + integrity sha512-XaZyLom2z4vi+A47qS5G1ecc65fw3MxfAKutH1iXrb92AXmxQG7TcH313O3qv4206pIDdNfmJNfgjo4h78cVJw== dependencies: jsonld "^8.1.1" schema-dts "^1.1.2" @@ -148,6 +200,244 @@ ky-universal "^0.11.0" undici "^5.21.2" +"@esbuild-plugins/node-globals-polyfill@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@esbuild-plugins/node-globals-polyfill/-/node-globals-polyfill-0.2.3.tgz#0e4497a2b53c9e9485e149bc92ddb228438d6bcf" + integrity sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw== + +"@esbuild-plugins/node-modules-polyfill@^0.2.2": + version "0.2.2" + resolved "https://registry.yarnpkg.com/@esbuild-plugins/node-modules-polyfill/-/node-modules-polyfill-0.2.2.tgz#cefa3dc0bd1c16277a8338b52833420c94987327" + integrity sha512-LXV7QsWJxRuMYvKbiznh+U1ilIop3g2TeKRzUxOG5X3YITc8JyyTa90BmLwqqv0YnX4v32CSlG+vsziZp9dMvA== + dependencies: + escape-string-regexp "^4.0.0" + rollup-plugin-node-polyfills "^0.2.1" + +"@esbuild/aix-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f" + integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ== + +"@esbuild/android-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz#bafb75234a5d3d1b690e7c2956a599345e84a2fd" + integrity sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA== + +"@esbuild/android-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052" + integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A== + +"@esbuild/android-arm@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.19.tgz#5898f7832c2298bc7d0ab53701c57beb74d78b4d" + integrity sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A== + +"@esbuild/android-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28" + integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg== + +"@esbuild/android-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.19.tgz#658368ef92067866d95fb268719f98f363d13ae1" + integrity sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww== + +"@esbuild/android-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e" + integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA== + +"@esbuild/darwin-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz#584c34c5991b95d4d48d333300b1a4e2ff7be276" + integrity sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg== + +"@esbuild/darwin-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz#e495b539660e51690f3928af50a76fb0a6ccff2a" + integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ== + +"@esbuild/darwin-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz#7751d236dfe6ce136cce343dce69f52d76b7f6cb" + integrity sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw== + +"@esbuild/darwin-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22" + integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw== + +"@esbuild/freebsd-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz#cacd171665dd1d500f45c167d50c6b7e539d5fd2" + integrity sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ== + +"@esbuild/freebsd-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e" + integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g== + +"@esbuild/freebsd-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz#0769456eee2a08b8d925d7c00b79e861cb3162e4" + integrity sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ== + +"@esbuild/freebsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261" + integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ== + +"@esbuild/linux-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz#38e162ecb723862c6be1c27d6389f48960b68edb" + integrity sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg== + +"@esbuild/linux-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b" + integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q== + +"@esbuild/linux-arm@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz#1a2cd399c50040184a805174a6d89097d9d1559a" + integrity sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA== + +"@esbuild/linux-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9" + integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA== + +"@esbuild/linux-ia32@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz#e28c25266b036ce1cabca3c30155222841dc035a" + integrity sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ== + +"@esbuild/linux-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2" + integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg== + +"@esbuild/linux-loong64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz#0f887b8bb3f90658d1a0117283e55dbd4c9dcf72" + integrity sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ== + +"@esbuild/linux-loong64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df" + integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg== + +"@esbuild/linux-mips64el@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz#f5d2a0b8047ea9a5d9f592a178ea054053a70289" + integrity sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A== + +"@esbuild/linux-mips64el@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe" + integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg== + +"@esbuild/linux-ppc64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz#876590e3acbd9fa7f57a2c7d86f83717dbbac8c7" + integrity sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg== + +"@esbuild/linux-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4" + integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w== + +"@esbuild/linux-riscv64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz#7f49373df463cd9f41dc34f9b2262d771688bf09" + integrity sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA== + +"@esbuild/linux-riscv64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc" + integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA== + +"@esbuild/linux-s390x@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz#e2afd1afcaf63afe2c7d9ceacd28ec57c77f8829" + integrity sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q== + +"@esbuild/linux-s390x@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de" + integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A== + +"@esbuild/linux-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz#8a0e9738b1635f0c53389e515ae83826dec22aa4" + integrity sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw== + +"@esbuild/linux-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0" + integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ== + +"@esbuild/netbsd-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz#c29fb2453c6b7ddef9a35e2c18b37bda1ae5c462" + integrity sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q== + +"@esbuild/netbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047" + integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg== + +"@esbuild/openbsd-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz#95e75a391403cb10297280d524d66ce04c920691" + integrity sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g== + +"@esbuild/openbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70" + integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow== + +"@esbuild/sunos-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz#722eaf057b83c2575937d3ffe5aeb16540da7273" + integrity sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg== + +"@esbuild/sunos-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b" + integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg== + +"@esbuild/win32-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz#9aa9dc074399288bdcdd283443e9aeb6b9552b6f" + integrity sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag== + +"@esbuild/win32-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d" + integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A== + +"@esbuild/win32-ia32@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz#95ad43c62ad62485e210f6299c7b2571e48d2b03" + integrity sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw== + +"@esbuild/win32-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b" + integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA== + +"@esbuild/win32-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz#8cfaf2ff603e9aabb910e9c0558c26cf32744061" + integrity sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA== + +"@esbuild/win32-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c" + integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw== + "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.0" resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" @@ -808,6 +1098,11 @@ dependencies: "@types/node" "*" +"@types/deep-equal@^1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@types/deep-equal/-/deep-equal-1.0.4.tgz#c0a854be62d6b9fae665137a6639aab53389a147" + integrity sha512-tqdiS4otQP4KmY0PR3u6KbZ5EWvhNdUoS/jc93UuK23C220lOZ/9TvjfxdPcKvqwwDVtmtSCrnr0p/2dirAxkA== + "@types/express-serve-static-core@^4.17.33": version "4.17.42" resolved "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.42.tgz" @@ -879,6 +1174,13 @@ dependencies: "@types/node" "*" +"@types/node-forge@^1.3.0": + version "1.3.11" + resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.11.tgz#0972ea538ddb0f4d9c2fa0ec5db5724773a604da" + integrity sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ== + dependencies: + "@types/node" "*" + "@types/node@*": version "20.11.13" resolved "https://registry.npmjs.org/@types/node/-/node-20.11.13.tgz" @@ -972,6 +1274,11 @@ resolved "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz" integrity sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ== +"@types/uuid@^10.0.0": + version "10.0.0" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-10.0.0.tgz#e9c07fe50da0f53dc24970cca94d619ff03f6f6d" + integrity sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ== + "@types/ws@^8.5.10": version "8.5.10" resolved "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz" @@ -996,6 +1303,17 @@ semver "^7.5.4" ts-api-utils "^1.0.1" +"@typescript-eslint/parser@^8.14.0": + version "8.14.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.14.0.tgz#0a7e9dbc11bc07716ab2d7b1226217e9f6b51fc8" + integrity sha512-2p82Yn9juUJq0XynBXtFCyrBDb6/dJombnz6vbo6mgQEtWHfvHbQuEa9kAOVIt1c9YFwi7H6WxtPj1kg+80+RA== + dependencies: + "@typescript-eslint/scope-manager" "8.14.0" + "@typescript-eslint/types" "8.14.0" + "@typescript-eslint/typescript-estree" "8.14.0" + "@typescript-eslint/visitor-keys" "8.14.0" + debug "^4.3.4" + "@typescript-eslint/scope-manager@6.20.0": version "6.20.0" resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.20.0.tgz" @@ -1004,6 +1322,14 @@ "@typescript-eslint/types" "6.20.0" "@typescript-eslint/visitor-keys" "6.20.0" +"@typescript-eslint/scope-manager@8.14.0": + version "8.14.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.14.0.tgz#01f37c147a735cd78f0ff355e033b9457da1f373" + integrity sha512-aBbBrnW9ARIDn92Zbo7rguLnqQ/pOrUguVpbUwzOhkFg2npFDwTgPGqFqE0H5feXcOoJOfX3SxlJaKEVtq54dw== + dependencies: + "@typescript-eslint/types" "8.14.0" + "@typescript-eslint/visitor-keys" "8.14.0" + "@typescript-eslint/type-utils@6.20.0": version "6.20.0" resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.20.0.tgz" @@ -1019,6 +1345,11 @@ resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.20.0.tgz" integrity sha512-MM9mfZMAhiN4cOEcUOEx+0HmuaW3WBfukBZPCfwSqFnQy0grXYtngKCqpQN339X3RrwtzspWJrpbrupKYUSBXQ== +"@typescript-eslint/types@8.14.0": + version "8.14.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.14.0.tgz#0d33d8d0b08479c424e7d654855fddf2c71e4021" + integrity sha512-yjeB9fnO/opvLJFAsPNYlKPnEM8+z4og09Pk504dkqonT02AyL5Z9SSqlE0XqezS93v6CXn49VHvB2G7XSsl0g== + "@typescript-eslint/typescript-estree@6.20.0": version "6.20.0" resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.20.0.tgz" @@ -1033,6 +1364,20 @@ semver "^7.5.4" ts-api-utils "^1.0.1" +"@typescript-eslint/typescript-estree@8.14.0": + version "8.14.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.14.0.tgz#a7a3a5a53a6c09313e12fb4531d4ff582ee3c312" + integrity sha512-OPXPLYKGZi9XS/49rdaCbR5j/S14HazviBlUQFvSKz3npr3NikF+mrgK7CFVur6XEt95DZp/cmke9d5i3vtVnQ== + dependencies: + "@typescript-eslint/types" "8.14.0" + "@typescript-eslint/visitor-keys" "8.14.0" + debug "^4.3.4" + fast-glob "^3.3.2" + is-glob "^4.0.3" + minimatch "^9.0.4" + semver "^7.6.0" + ts-api-utils "^1.3.0" + "@typescript-eslint/utils@6.20.0": version "6.20.0" resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.20.0.tgz" @@ -1054,6 +1399,14 @@ "@typescript-eslint/types" "6.20.0" eslint-visitor-keys "^3.4.1" +"@typescript-eslint/visitor-keys@8.14.0": + version "8.14.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.14.0.tgz#2418d5a54669af9658986ade4e6cfb7767d815ad" + integrity sha512-vG0XZo8AdTH9OE6VFRwAZldNc7qtJ/6NLGWak+BtENuEUXGZgFpihILPiBvKXvJ2nFu27XNGC6rKiwuaoMbYzQ== + dependencies: + "@typescript-eslint/types" "8.14.0" + eslint-visitor-keys "^3.4.3" + "@ungap/structured-clone@^1.2.0": version "1.2.0" resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz" @@ -1099,6 +1452,18 @@ acorn-walk@^8.1.1: resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz" integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A== +acorn-walk@^8.2.0: + version "8.3.4" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.4.tgz#794dd169c3977edf4ba4ea47583587c5866236b7" + integrity sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g== + dependencies: + acorn "^8.11.0" + +acorn@^8.11.0, acorn@^8.8.0: + version "8.14.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.0.tgz#063e2c70cac5fb4f6467f0b11152e04c682795b0" + integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA== + acorn@^8.4.1, acorn@^8.9.0: version "8.11.3" resolved "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz" @@ -1264,6 +1629,13 @@ arraybuffer.prototype.slice@^1.0.2: is-array-buffer "^3.0.2" is-shared-array-buffer "^1.0.2" +as-table@^1.0.36: + version "1.0.55" + resolved "https://registry.yarnpkg.com/as-table/-/as-table-1.0.55.tgz#dc984da3937745de902cea1d45843c01bdbbec4f" + integrity sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ== + dependencies: + printable-characters "^1.0.42" + assertion-error@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz" @@ -1325,6 +1697,11 @@ binary-extensions@^2.0.0: resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== +blake3-wasm@^2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/blake3-wasm/-/blake3-wasm-2.1.5.tgz#b22dbb84bc9419ed0159caa76af4b1b132e6ba52" + integrity sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g== + body-parser@1.20.1: version "1.20.1" resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz" @@ -1395,11 +1772,6 @@ buffer-from@^1.0.0: resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -buffer-writer@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz" - integrity sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw== - buffer@^6.0.3: version "6.0.3" resolved "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz" @@ -1437,6 +1809,14 @@ canonicalize@^1.0.1: resolved "https://registry.yarnpkg.com/canonicalize/-/canonicalize-1.0.8.tgz#24d1f1a00ed202faafd9bf8e63352cd4450c6df1" integrity sha512-0CNTVCLZggSh7bc5VkX5WWPWO+cyZbNd07IHIsSXLia/eAq+r836hgk+8BKoEh7949Mda87VUOitx5OddVj64A== +capnp-ts@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/capnp-ts/-/capnp-ts-0.7.0.tgz#16fd8e76b667d002af8fcf4bf92bf15d1a7b54a9" + integrity sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g== + dependencies: + debug "^4.3.1" + tslib "^2.2.0" + cbor-extract@^2.2.0: version "2.2.0" resolved "https://registry.npmjs.org/cbor-extract/-/cbor-extract-2.2.0.tgz" @@ -1509,6 +1889,21 @@ chokidar@3.5.3, chokidar@^3.5.1, chokidar@^3.5.2: optionalDependencies: fsevents "~2.3.2" +chokidar@^3.5.3: + version "3.6.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" + integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + cjs-module-lexer@^1.2.2: version "1.4.1" resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz#707413784dbb3a72aa11c2f2b042a0bef4004170" @@ -1534,6 +1929,15 @@ cli-truncate@^2.1.0: slice-ansi "^3.0.0" string-width "^4.2.0" +clipboardy@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/clipboardy/-/clipboardy-4.0.0.tgz#e73ced93a76d19dd379ebf1f297565426dffdca1" + integrity sha512-5mOlNS0mhX0707P2I0aZ2V/cmHUEO/fL7VFLqszkhUsxt7RwnmrInf/eEQKlf5GzvYeHIjT+Ov1HRfNmymlG0w== + dependencies: + execa "^8.0.1" + is-wsl "^3.1.0" + is64bit "^2.0.0" + cliui@^7.0.2, cliui@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" @@ -1611,6 +2015,11 @@ cookie@0.5.0: resolved "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz" integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== +cookie@^0.7.1: + version "0.7.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7" + integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w== + cors@^2.8.5: version "2.8.5" resolved "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz" @@ -1655,11 +2064,21 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" +data-uri-to-buffer@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-2.0.2.tgz#d296973d5a4897a5dbe31716d118211921f04770" + integrity sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA== + data-uri-to-buffer@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz#d8feb2b2881e6a4f58c2e08acfd0e2834e26222e" integrity sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A== +date-fns@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-4.1.0.tgz#64b3d83fff5aa80438f5b1a633c2e83b8a1c2d14" + integrity sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg== + dateformat@^4.6.3: version "4.6.3" resolved "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz" @@ -1752,6 +2171,11 @@ define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1: has-property-descriptors "^1.0.0" object-keys "^1.1.1" +defu@^6.1.4: + version "6.1.4" + resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.4.tgz#4e0c9cf9ff68fe5f3d7f2765cc1a012dfdcb0479" + integrity sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg== + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" @@ -1974,6 +2398,63 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +esbuild@0.17.19: + version "0.17.19" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.19.tgz#087a727e98299f0462a3d0bcdd9cd7ff100bd955" + integrity sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw== + optionalDependencies: + "@esbuild/android-arm" "0.17.19" + "@esbuild/android-arm64" "0.17.19" + "@esbuild/android-x64" "0.17.19" + "@esbuild/darwin-arm64" "0.17.19" + "@esbuild/darwin-x64" "0.17.19" + "@esbuild/freebsd-arm64" "0.17.19" + "@esbuild/freebsd-x64" "0.17.19" + "@esbuild/linux-arm" "0.17.19" + "@esbuild/linux-arm64" "0.17.19" + "@esbuild/linux-ia32" "0.17.19" + "@esbuild/linux-loong64" "0.17.19" + "@esbuild/linux-mips64el" "0.17.19" + "@esbuild/linux-ppc64" "0.17.19" + "@esbuild/linux-riscv64" "0.17.19" + "@esbuild/linux-s390x" "0.17.19" + "@esbuild/linux-x64" "0.17.19" + "@esbuild/netbsd-x64" "0.17.19" + "@esbuild/openbsd-x64" "0.17.19" + "@esbuild/sunos-x64" "0.17.19" + "@esbuild/win32-arm64" "0.17.19" + "@esbuild/win32-ia32" "0.17.19" + "@esbuild/win32-x64" "0.17.19" + +esbuild@0.21.5: + version "0.21.5" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.21.5.tgz#9ca301b120922959b766360d8ac830da0d02997d" + integrity sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw== + optionalDependencies: + "@esbuild/aix-ppc64" "0.21.5" + "@esbuild/android-arm" "0.21.5" + "@esbuild/android-arm64" "0.21.5" + "@esbuild/android-x64" "0.21.5" + "@esbuild/darwin-arm64" "0.21.5" + "@esbuild/darwin-x64" "0.21.5" + "@esbuild/freebsd-arm64" "0.21.5" + "@esbuild/freebsd-x64" "0.21.5" + "@esbuild/linux-arm" "0.21.5" + "@esbuild/linux-arm64" "0.21.5" + "@esbuild/linux-ia32" "0.21.5" + "@esbuild/linux-loong64" "0.21.5" + "@esbuild/linux-mips64el" "0.21.5" + "@esbuild/linux-ppc64" "0.21.5" + "@esbuild/linux-riscv64" "0.21.5" + "@esbuild/linux-s390x" "0.21.5" + "@esbuild/linux-x64" "0.21.5" + "@esbuild/netbsd-x64" "0.21.5" + "@esbuild/openbsd-x64" "0.21.5" + "@esbuild/sunos-x64" "0.21.5" + "@esbuild/win32-arm64" "0.21.5" + "@esbuild/win32-ia32" "0.21.5" + "@esbuild/win32-x64" "0.21.5" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" @@ -2136,6 +2617,11 @@ estraverse@^5.1.0, estraverse@^5.2.0: resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== +estree-walker@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362" + integrity sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w== + esutils@^2.0.2: version "2.0.3" resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" @@ -2151,6 +2637,11 @@ event-target-shim@^5.0.0: resolved "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== +event-target-shim@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-6.0.2.tgz#ea5348c3618ee8b62ff1d344f01908ee2b8a2b71" + integrity sha512-8q3LsZjRezbFZ2PN+uP+Q7pnHUMmAOziU2vA2OwoFaKIXxlxl38IylhSSgUorWu/rf4er67w0ikBqjBFk/pomA== + eventemitter3@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz" @@ -2191,6 +2682,26 @@ execa@^5.0.0: signal-exit "^3.0.3" strip-final-newline "^2.0.0" +execa@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-8.0.1.tgz#51f6a5943b580f963c3ca9c6321796db8cc39b8c" + integrity sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^8.0.1" + human-signals "^5.0.0" + is-stream "^3.0.0" + merge-stream "^2.0.0" + npm-run-path "^5.1.0" + onetime "^6.0.0" + signal-exit "^4.1.0" + strip-final-newline "^3.0.0" + +exit-hook@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-2.2.1.tgz#007b2d92c6428eda2b76e7016a34351586934593" + integrity sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw== + express@^4.18.2: version "4.18.2" resolved "https://registry.npmjs.org/express/-/express-4.18.2.tgz" @@ -2243,7 +2754,7 @@ fast-diff@^1.1.2: resolved "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz" integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== -fast-glob@^3.2.9: +fast-glob@^3.2.9, fast-glob@^3.3.2: version "3.3.2" resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz" integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== @@ -2407,7 +2918,7 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@~2.3.2: +fsevents@2.3.3, fsevents@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== @@ -2457,6 +2968,14 @@ get-own-enumerable-property-symbols@^3.0.0: resolved "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz" integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== +get-source@^2.0.12: + version "2.0.12" + resolved "https://registry.yarnpkg.com/get-source/-/get-source-2.0.12.tgz#0b47d57ea1e53ce0d3a69f4f3d277eb8047da944" + integrity sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w== + dependencies: + data-uri-to-buffer "^2.0.0" + source-map "^0.6.1" + get-stream@^5.0.0: version "5.2.0" resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz" @@ -2469,6 +2988,11 @@ get-stream@^6.0.0: resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== +get-stream@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-8.0.1.tgz#def9dfd71742cd7754a7761ed43749a27d02eca2" + integrity sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA== + get-symbol-description@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz" @@ -2491,6 +3015,11 @@ glob-parent@^6.0.2: dependencies: is-glob "^4.0.3" +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + glob@7.2.0: version "7.2.0" resolved "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz" @@ -2651,6 +3180,11 @@ human-signals@^2.1.0: resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== +human-signals@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-5.0.0.tgz#42665a284f9ae0dade3ba41ebc37eb4b852f3a28" + integrity sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ== + iconv-lite@0.4.24: version "0.4.24" resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" @@ -2801,6 +3335,11 @@ is-date-object@^1.0.1, is-date-object@^1.0.5: dependencies: has-tostringtag "^1.0.0" +is-docker@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-3.0.0.tgz#90093aa3106277d8a77a5910dbae71747e15a200" + integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== + is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" @@ -2818,6 +3357,13 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-inside-container@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-inside-container/-/is-inside-container-1.0.0.tgz#e81fba699662eb31dbdaf26766a61d4814717ea4" + integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA== + dependencies: + is-docker "^3.0.0" + is-map@^2.0.1, is-map@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz" @@ -2885,6 +3431,11 @@ is-stream@^2.0.0: resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== +is-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" + integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== + is-string@^1.0.5, is-string@^1.0.7: version "1.0.7" resolved "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz" @@ -2931,6 +3482,20 @@ is-weakset@^2.0.1: call-bind "^1.0.2" get-intrinsic "^1.1.1" +is-wsl@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-3.1.0.tgz#e1c657e39c10090afcbedec61720f6b924c3cbd2" + integrity sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw== + dependencies: + is-inside-container "^1.0.0" + +is64bit@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is64bit/-/is64bit-2.0.0.tgz#198c627cbcb198bbec402251f88e5e1a51236c07" + integrity sha512-jv+8jaWCl0g2lSBkNSVXdzfBA0npK1HGC2KtWM9FumFRoGS94g3NbCCLVnCYHLjp4GrW2KZeeSTMo5ddtznmGw== + dependencies: + system-architecture "^0.1.0" + isarray@^2.0.5: version "2.0.5" resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz" @@ -2943,9 +3508,14 @@ isexe@^2.0.0: isomorphic-ws@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz#e5529148912ecb9b451b46ed44d53dae1ce04bbf" integrity sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw== +itty-time@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/itty-time/-/itty-time-1.0.6.tgz#a6eeda619f19d2f4c480ceddd013b93acb05714d" + integrity sha512-+P8IZaLLBtFv8hCkIjcymZOp4UJ+xW6bSlQsXGqrkmJh7vSiMFSlNne0mCYagEE0N7HDNR5jJBRxwN0oYv61Rw== + jackspeak@^2.3.5: version "2.3.6" resolved "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz" @@ -2962,7 +3532,7 @@ joycon@^3.1.1: js-tokens@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== js-yaml@4.1.0, js-yaml@^4.1.0: @@ -3208,6 +3778,13 @@ lru-cache@^6.0.0: resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz" integrity sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q== +magic-string@^0.25.3: + version "0.25.9" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c" + integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ== + dependencies: + sourcemap-codec "^1.4.8" + make-error@^1.1.1: version "1.3.6" resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" @@ -3268,11 +3845,57 @@ mime@1.6.0: resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== +mime@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-3.0.0.tgz#b374550dca3a0c18443b0c950a6a58f1931cf7a7" + integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A== + mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +mimic-fn@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" + integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== + +miniflare@3.20240718.0: + version "3.20240718.0" + resolved "https://registry.yarnpkg.com/miniflare/-/miniflare-3.20240718.0.tgz#41561c6620b2b15803f5b3d2e903ed3af40f3b0b" + integrity sha512-TKgSeyqPBeT8TBLxbDJOKPWlq/wydoJRHjAyDdgxbw59N6wbP8JucK6AU1vXCfu21eKhrEin77ssXOpbfekzPA== + dependencies: + "@cspotcode/source-map-support" "0.8.1" + acorn "^8.8.0" + acorn-walk "^8.2.0" + capnp-ts "^0.7.0" + exit-hook "^2.2.1" + glob-to-regexp "^0.4.1" + stoppable "^1.1.0" + undici "^5.28.4" + workerd "1.20240718.0" + ws "^8.17.1" + youch "^3.2.2" + zod "^3.22.3" + +miniflare@3.20241022.0: + version "3.20241022.0" + resolved "https://registry.yarnpkg.com/miniflare/-/miniflare-3.20241022.0.tgz#31b8a2bc53b411ac814b55db9c31aebfe475f344" + integrity sha512-x9Fbq1Hmz1f0osIT9Qmj78iX4UpCP2EqlZnA/tzj/3+I49vc3Kq0fNqSSKplcdf6HlCHdL3fOBicmreQF4BUUQ== + dependencies: + "@cspotcode/source-map-support" "0.8.1" + acorn "^8.8.0" + acorn-walk "^8.2.0" + capnp-ts "^0.7.0" + exit-hook "^2.2.1" + glob-to-regexp "^0.4.1" + stoppable "^1.1.0" + undici "^5.28.4" + workerd "1.20241022.0" + ws "^8.17.1" + youch "^3.2.2" + zod "^3.22.3" + minimatch@5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz" @@ -3294,6 +3917,13 @@ minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" +minimatch@^9.0.4: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== + dependencies: + brace-expansion "^2.0.1" + minimist@^1.2.0, minimist@^1.2.6: version "1.2.8" resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" @@ -3372,11 +4002,26 @@ ms@2.1.3, ms@^2.1.1, ms@^2.1.3: resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +mustache@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/mustache/-/mustache-4.2.0.tgz#e5892324d60a12ec9c2a73359edca52972bf6f64" + integrity sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ== + nanoid@3.3.3: version "3.3.3" resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz" integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== +nanoid@^3.3.3: + version "3.3.7" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" + integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== + +nanoid@^5.0.7: + version "5.0.8" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-5.0.8.tgz#7610003f6b3b761b5c244bb342c112c5312512bf" + integrity sha512-TcJPw+9RV9dibz1hHUzlLVy8N4X9TnwirAjrU08Juo6BNKggzVfP2ZJ/3ZUSq15Xl5i85i+Z89XBO90pB2PghQ== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" @@ -3413,6 +4058,11 @@ node-fetch@^3.2.10: fetch-blob "^3.1.4" formdata-polyfill "^4.0.10" +node-forge@^1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== + node-gyp-build-optional-packages@5.1.1: version "5.1.1" resolved "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.1.1.tgz" @@ -3480,6 +4130,13 @@ npm-run-path@^4.0.0, npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" +npm-run-path@^5.1.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.3.0.tgz#e23353d0ebb9317f174e93417e4a4d82d0249e9f" + integrity sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ== + dependencies: + path-key "^4.0.0" + object-assign@^4: version "4.1.1" resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" @@ -3546,6 +4203,11 @@ obuf@~1.1.2: resolved "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== +ohash@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/ohash/-/ohash-1.1.4.tgz#ae8d83014ab81157d2c285abf7792e2995fadd72" + integrity sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g== + on-exit-leak-free@^2.1.0: version "2.1.2" resolved "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz" @@ -3584,6 +4246,13 @@ onetime@^5.1.0, onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" +onetime@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" + integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== + dependencies: + mimic-fn "^4.0.0" + opentelemetry-instrumentation-fetch-node@1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/opentelemetry-instrumentation-fetch-node/-/opentelemetry-instrumentation-fetch-node-1.2.3.tgz#beb24048bdccb1943ba2a5bbadca68020e448ea7" @@ -3644,11 +4313,6 @@ p-try@^2.0.0: resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== -packet-reader@1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz" - integrity sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ== - parent-module@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" @@ -3679,6 +4343,33 @@ parseurl@~1.3.3: resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== +partykit@^0.0.111: + version "0.0.111" + resolved "https://registry.yarnpkg.com/partykit/-/partykit-0.0.111.tgz#240e735d129d537dcfe97eb1dfaca4fcdf123889" + integrity sha512-pbUzJmulPTqZWgtH++eClnLlddTWS0RPKOAQyexYiSqGEg2/Ff84Ep0qWFqy+53wiz098DPFekRI375Qy2GsZw== + dependencies: + "@cloudflare/workers-types" "4.20240718.0" + clipboardy "4.0.0" + esbuild "0.21.5" + miniflare "3.20240718.0" + yoga-wasm-web "0.3.3" + optionalDependencies: + fsevents "2.3.3" + +partyserver@^0.0.57: + version "0.0.57" + resolved "https://registry.yarnpkg.com/partyserver/-/partyserver-0.0.57.tgz#f02ebe389b438a4d2474ea33474e0bbefaa1678a" + integrity sha512-AVoNcslX+z8XjcESoNFC0WLYIH0WdxtnbaRKOHqHfzVOmEDvOlh/WUsWxeRY38f5v6aFH/gyUHNcxiW1KXlabw== + dependencies: + nanoid "^5.0.7" + +partysocket@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/partysocket/-/partysocket-1.0.2.tgz#5859dbbe1c89742db17afa2635e164d8916350cf" + integrity sha512-rAFOUKImaq+VBk2B+2RTBsWEvlnarEP53nchoUHzpVs8V6fG2/estihOTslTQUWHVuHEKDL5k8htG8K3TngyFA== + dependencies: + event-target-shim "^6.0.2" + path-exists@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" @@ -3699,6 +4390,11 @@ path-key@^3.0.0, path-key@^3.1.0: resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== +path-key@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" + integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== + path-parse@^1.0.7: version "1.0.7" resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" @@ -3717,6 +4413,11 @@ path-to-regexp@0.1.7: resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz" integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== +path-to-regexp@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.3.0.tgz#2b6a26a337737a8e1416f9272ed0766b1c0389f4" + integrity sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ== + path-type@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz" @@ -3729,6 +4430,11 @@ path-type@^4.0.0: resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +pathe@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.2.tgz#6c4cb47a945692e48a1ddd6e4094d170516437ec" + integrity sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ== + pathval@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz" @@ -3739,10 +4445,10 @@ pg-cloudflare@^1.1.1: resolved "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz" integrity sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q== -pg-connection-string@^2.6.2: - version "2.6.2" - resolved "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz" - integrity sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA== +pg-connection-string@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.7.0.tgz#f1d3489e427c62ece022dba98d5262efcb168b37" + integrity sha512-PI2W9mv53rXJQEOb8xNR8lH7Hr+EKa6oJa38zsK0S/ky2er16ios1wLKhZyxzD7jUReiWokc9WK5nxSnC7W1TA== pg-int8@1.0.1: version "1.0.1" @@ -3754,16 +4460,21 @@ pg-numeric@1.0.2: resolved "https://registry.npmjs.org/pg-numeric/-/pg-numeric-1.0.2.tgz" integrity sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw== -pg-pool@^3.6.1: - version "3.6.1" - resolved "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz" - integrity sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og== +pg-pool@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.7.0.tgz#d4d3c7ad640f8c6a2245adc369bafde4ebb8cbec" + integrity sha512-ZOBQForurqh4zZWjrgSwwAtzJ7QiRX0ovFkZr2klsen3Nm0aoh33Ls0fzfv3imeH/nw/O27cjdz5kzYJfeGp/g== -pg-protocol@*, pg-protocol@^1.6.0: +pg-protocol@*: version "1.6.0" resolved "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz" integrity sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q== +pg-protocol@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.7.0.tgz#ec037c87c20515372692edac8b63cf4405448a93" + integrity sha512-hTK/mE36i8fDDhgDFjy6xNOG+LCorxLG3WO17tku+ij6sVHXh1jQUJ8hYAnRhNla4QVD2H8er/FOjc/+EgC6yQ== + pg-types@^2.1.0, pg-types@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3" @@ -3788,16 +4499,14 @@ pg-types@^4.0.1: postgres-interval "^3.0.0" postgres-range "^1.1.1" -pg@^8.11.3: - version "8.11.3" - resolved "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz" - integrity sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g== - dependencies: - buffer-writer "2.0.0" - packet-reader "1.0.0" - pg-connection-string "^2.6.2" - pg-pool "^3.6.1" - pg-protocol "^1.6.0" +pg@^8.13.1: + version "8.13.1" + resolved "https://registry.yarnpkg.com/pg/-/pg-8.13.1.tgz#6498d8b0a87ff76c2df7a32160309d3168c0c080" + integrity sha512-OUir1A0rPNZlX//c7ksiu7crsGZTKSOXJPgtNiHGIlC9H0lO+NC6ZDYksSgBYY/thSWhnSRBv8w1lieNNGATNQ== + dependencies: + pg-connection-string "^2.7.0" + pg-pool "^3.7.0" + pg-protocol "^1.7.0" pg-types "^2.1.0" pgpass "1.x" optionalDependencies: @@ -3951,6 +4660,11 @@ postgres-range@^1.1.1: resolved "https://registry.npmjs.org/postgres-range/-/postgres-range-1.1.4.tgz" integrity sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w== +postgres@^3.4.5: + version "3.4.5" + resolved "https://registry.yarnpkg.com/postgres/-/postgres-3.4.5.tgz#1ef99e51b0ba9b53cbda8a215dd406725f7d15f9" + integrity sha512-cDWgoah1Gez9rN3H4165peY9qfpEo+SA61oQv65O3cRUE1pOEoJWwddwcqKE8XZYjbblOJlYDlLV4h67HrEVDg== + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" @@ -3981,6 +4695,11 @@ pretty-quick@^3.1.3: picomatch "^3.0.1" tslib "^2.6.2" +printable-characters@^1.0.42: + version "1.0.42" + resolved "https://registry.yarnpkg.com/printable-characters/-/printable-characters-1.0.42.tgz#3f18e977a9bd8eb37fcc4ff5659d7be90868b3d8" + integrity sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ== + process-warning@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz" @@ -4138,6 +4857,11 @@ resolve-from@^4.0.0: resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== +resolve.exports@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" + integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg== + resolve@^1.0.0, resolve@^1.10.0, resolve@^1.22.4, resolve@^1.22.8: version "1.22.8" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" @@ -4179,13 +4903,36 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" -rimraf@^5.0.1, rimraf@^5.0.5: +rimraf@^5.0.5: version "5.0.5" resolved "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz" integrity sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A== dependencies: glob "^10.3.7" +rollup-plugin-inject@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rollup-plugin-inject/-/rollup-plugin-inject-3.0.2.tgz#e4233855bfba6c0c12a312fd6649dff9a13ee9f4" + integrity sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w== + dependencies: + estree-walker "^0.6.1" + magic-string "^0.25.3" + rollup-pluginutils "^2.8.1" + +rollup-plugin-node-polyfills@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/rollup-plugin-node-polyfills/-/rollup-plugin-node-polyfills-0.2.1.tgz#53092a2744837164d5b8a28812ba5f3ff61109fd" + integrity sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA== + dependencies: + rollup-plugin-inject "^3.0.0" + +rollup-pluginutils@^2.8.1: + version "2.8.2" + resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz#72f2af0748b592364dbd3389e600e5a9444a351e" + integrity sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ== + dependencies: + estree-walker "^0.6.1" + run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" @@ -4249,6 +4996,14 @@ secure-json-parse@^2.4.0: resolved "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz" integrity sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw== +selfsigned@^2.0.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.4.1.tgz#560d90565442a3ed35b674034cec4e95dceb4ae0" + integrity sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q== + dependencies: + "@types/node-forge" "^1.3.0" + node-forge "^1" + semver-compare@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz" @@ -4264,7 +5019,7 @@ semver@^6.3.1: resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.5, semver@^7.5.2: +semver@^7.3.5, semver@^7.5.2, semver@^7.6.0: version "7.6.3" resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== @@ -4390,7 +5145,7 @@ signal-exit@^3.0.2, signal-exit@^3.0.3: resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== -signal-exit@^4.0.1: +signal-exit@^4.0.1, signal-exit@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz" integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== @@ -4440,11 +5195,16 @@ source-map-support@^0.5.12: buffer-from "^1.0.0" source-map "^0.6.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" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +sourcemap-codec@^1.4.8: + version "1.4.8" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" + integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== + spdx-correct@^3.0.0: version "3.2.0" resolved "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz" @@ -4476,6 +5236,14 @@ split2@^4.0.0, split2@^4.1.0: resolved "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz" integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== +stacktracey@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/stacktracey/-/stacktracey-2.1.8.tgz#bf9916020738ce3700d1323b32bd2c91ea71199d" + integrity sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw== + dependencies: + as-table "^1.0.36" + get-source "^2.0.12" + statuses@2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" @@ -4488,6 +5256,11 @@ stop-iteration-iterator@^1.0.0: dependencies: internal-slot "^1.0.4" +stoppable@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/stoppable/-/stoppable-1.1.0.tgz#32da568e83ea488b08e4d7ea2c3bcc9d75015d5b" + integrity sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw== + string-argv@0.3.1: version "0.3.1" resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz" @@ -4603,6 +5376,11 @@ strip-final-newline@^2.0.0: resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== +strip-final-newline@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" + integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== + strip-json-comments@3.1.1, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" @@ -4647,6 +5425,11 @@ synckit@^0.8.6: "@pkgr/core" "^0.1.0" tslib "^2.6.2" +system-architecture@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/system-architecture/-/system-architecture-0.1.0.tgz#71012b3ac141427d97c67c56bc7921af6bff122d" + integrity sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA== + text-table@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" @@ -4698,6 +5481,11 @@ ts-api-utils@^1.0.1: resolved "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz" integrity sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg== +ts-api-utils@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.4.0.tgz#709c6f2076e511a81557f3d07a0cbd566ae8195c" + integrity sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ== + ts-node-dev@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/ts-node-dev/-/ts-node-dev-2.0.0.tgz" @@ -4777,6 +5565,11 @@ tslib@^2.1.0, tslib@^2.6.2: resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== +tslib@^2.2.0: + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" @@ -4851,6 +5644,11 @@ typescript@5.1.6: resolved "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz" integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== +ufo@^1.5.4: + version "1.5.4" + resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.5.4.tgz#16d6949674ca0c9e0fbbae1fa20a71d7b1ded754" + integrity sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ== + unbox-primitive@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz" @@ -4871,13 +5669,23 @@ undici-types@~5.26.4: resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== -undici@^5.21.2: +undici@^5.21.2, undici@^5.28.4: version "5.28.4" resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.4.tgz#6b280408edb6a1a604a9b20340f45b422e373068" integrity sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g== dependencies: "@fastify/busboy" "^2.0.0" +"unenv@npm:unenv-nightly@2.0.0-20241024-111401-d4156ac": + version "2.0.0-20241024-111401-d4156ac" + resolved "https://registry.yarnpkg.com/unenv-nightly/-/unenv-nightly-2.0.0-20241024-111401-d4156ac.tgz#000835e7383ace38ad31351dc13e623d20b82855" + integrity sha512-xJO1hfY+Te+/XnfCYrCbFbRcgu6XEODND1s5wnVbaBCkuQX7JXF7fHEXPrukFE2j8EOH848P8QN19VO47XN8hw== + dependencies: + defu "^6.1.4" + ohash "^1.1.4" + pathe "^1.1.2" + ufo "^1.5.4" + unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" @@ -4969,11 +5777,60 @@ which@^2.0.1: dependencies: isexe "^2.0.0" +workerd@1.20240718.0: + version "1.20240718.0" + resolved "https://registry.yarnpkg.com/workerd/-/workerd-1.20240718.0.tgz#7a397d0a159f7362dc3f7b19472190a858d96f7c" + integrity sha512-w7lOLRy0XecQTg/ujTLWBiJJuoQvzB3CdQ6/8Wgex3QxFhV9Pbnh3UbwIuUfMw3OCCPQc4o7y+1P+mISAgp6yg== + optionalDependencies: + "@cloudflare/workerd-darwin-64" "1.20240718.0" + "@cloudflare/workerd-darwin-arm64" "1.20240718.0" + "@cloudflare/workerd-linux-64" "1.20240718.0" + "@cloudflare/workerd-linux-arm64" "1.20240718.0" + "@cloudflare/workerd-windows-64" "1.20240718.0" + +workerd@1.20241022.0: + version "1.20241022.0" + resolved "https://registry.yarnpkg.com/workerd/-/workerd-1.20241022.0.tgz#45ab10642009b4573ae78df784e0a8c5b338914e" + integrity sha512-jyGXsgO9DRcJyx6Ovv7gUyDPc3UYC2i/E0p9GFUg6GUzpldw4Y93y9kOmdfsOnKZ3+lY53veSiUniiBPE6Q2NQ== + optionalDependencies: + "@cloudflare/workerd-darwin-64" "1.20241022.0" + "@cloudflare/workerd-darwin-arm64" "1.20241022.0" + "@cloudflare/workerd-linux-64" "1.20241022.0" + "@cloudflare/workerd-linux-arm64" "1.20241022.0" + "@cloudflare/workerd-windows-64" "1.20241022.0" + workerpool@6.2.1: version "6.2.1" resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz" integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== +wrangler@^3.84.1: + version "3.85.0" + resolved "https://registry.yarnpkg.com/wrangler/-/wrangler-3.85.0.tgz#def6e562158b56257aa716f1ed8b1c5293128359" + integrity sha512-r5YCWUaF4ApLnloNE6jHHgRYdFzYHoajTlC1tns42UzQ2Ls63VAqD3b0cxOqzDUfmlSb3skpmu0B0Ssi3QWPAg== + dependencies: + "@cloudflare/kv-asset-handler" "0.3.4" + "@cloudflare/workers-shared" "0.7.0" + "@esbuild-plugins/node-globals-polyfill" "^0.2.3" + "@esbuild-plugins/node-modules-polyfill" "^0.2.2" + blake3-wasm "^2.1.5" + chokidar "^3.5.3" + date-fns "^4.1.0" + esbuild "0.17.19" + itty-time "^1.0.6" + miniflare "3.20241022.0" + nanoid "^3.3.3" + path-to-regexp "^6.3.0" + resolve "^1.22.8" + resolve.exports "^2.0.2" + selfsigned "^2.0.1" + source-map "^0.6.1" + unenv "npm:unenv-nightly@2.0.0-20241024-111401-d4156ac" + workerd "1.20241022.0" + xxhash-wasm "^1.0.1" + optionalDependencies: + fsevents "~2.3.2" + "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" @@ -5020,16 +5877,26 @@ ws@^8.14.2, ws@^8.7.0: resolved "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz" integrity sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ== -xstate@^4.37.0: - version "4.38.3" - resolved "https://registry.npmjs.org/xstate/-/xstate-4.38.3.tgz" - integrity sha512-SH7nAaaPQx57dx6qvfcIgqKRXIh4L0A1iYEqim4s1u7c9VoCgzZc+63FY90AKU4ZzOC2cfJzTnpO4zK7fCUzzw== +ws@^8.17.1: + version "8.18.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" + integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== + +xstate@^5.9.1: + version "5.18.2" + resolved "https://registry.yarnpkg.com/xstate/-/xstate-5.18.2.tgz#924122af5102f3c3f7e172ebf20a09455ddb2963" + integrity sha512-hab5VOe29D0agy8/7dH1lGw+7kilRQyXwpaChoMu4fe6rDP+nsHYhDYKfS2O4iXE7myA98TW6qMEudj/8NXEkA== xtend@^4.0.0: version "4.0.2" resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== +xxhash-wasm@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/xxhash-wasm/-/xxhash-wasm-1.0.2.tgz#ecc0f813219b727af4d5f3958ca6becee2f2f1ff" + integrity sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A== + y18n@^5.0.5: version "5.0.8" resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" @@ -5088,6 +5955,25 @@ yocto-queue@^0.1.0: resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== +yoga-wasm-web@0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/yoga-wasm-web/-/yoga-wasm-web-0.3.3.tgz#eb8e9fcb18e5e651994732f19a220cb885d932ba" + integrity sha512-N+d4UJSJbt/R3wqY7Coqs5pcV0aUj2j9IaQ3rNj9bVCLld8tTGKRa2USARjnvZJWVx1NDmQev8EknoczaOQDOA== + +youch@^3.2.2: + version "3.3.4" + resolved "https://registry.yarnpkg.com/youch/-/youch-3.3.4.tgz#f13ee0966846c6200e7fb9ece89306d95df5e489" + integrity sha512-UeVBXie8cA35DS6+nBkls68xaBBXCye0CNznrhszZjTbRVnJKQuNsyLKBTTL4ln1o1rh2PKtv35twV7irj5SEg== + dependencies: + cookie "^0.7.1" + mustache "^4.2.0" + stacktracey "^2.1.8" + +zod@^3.22.3: + version "3.23.8" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d" + integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g== + zod@^3.22.4: version "3.22.4" resolved "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz" diff --git a/desci-server/package.json b/desci-server/package.json index 90016a60f..f3232611d 100755 --- a/desci-server/package.json +++ b/desci-server/package.json @@ -28,6 +28,7 @@ "script:backfill-annotations": "debug=* node --no-warnings --enable-source-maps --loader ts-node/esm ./src/scripts/backfill-annotations.ts", "script:prune-auth-tokens": "debug=* node --no-warnings --enable-source-maps --loader ts-node/esm ./src/scripts/prune-auth-tokens.ts", "build": "rimraf dist && tsc && yarn copy-files; if [ \"$SENTRY_AUTH_TOKEN\" ]; then yarn sentry:sourcemaps; else echo 'SENTRY_AUTH_TOKEN not set, sourcemaps will not upload'; fi", + "build:worker": "cd ../sync-server && ./scripts/build.sh test", "copy-files": "copyfiles -u 1 src/**/*.cjs dist/", "generate": "npx prisma generate", "migrate:local": "DATABASE_URL=postgresql://walter:white@localhost:5433/boilerplate npx prisma migrate dev", @@ -41,7 +42,8 @@ "test:destructive": "NODE_OPTIONS=\"--experimental-specifier-resolution=node --loader=ts-node/esm\" mocha --colors --require ts-node/register 'test/integration/**/*.test.ts' --timeout 20000 --exit", "test:destructive:debug": "yarn test:destructive --inspect=0.0.0.0:9227", "test:check": "npx tsc --project ./tsconfig-test.json", - "test": "yarn test:check && yarn docker:test; export EXIT=$(echo $?); docker compose --file ../docker-compose.test.yml --compatibility down; exit $EXIT", + "sync:build": "cd ../sync-server && ./scripts/build.sh test", + "test": "yarn test:check && yarn sync:build && yarn docker:test; export EXIT=$(echo $?); docker compose --file ../docker-compose.test.yml --compatibility down; exit $EXIT", "coverage:destructive": "nyc --all --parser-plugins='[\"importAssertions\"]' -r lcov -e .ts -x \"*.test.ts\" npm run test:destructive", "coverage:destructive:debug": "nyc --all --parser-plugins='[\"importAssertions\"]' -r lcov -e .ts -x \"*.test.ts\" npm run test:destructive:debug", "db:forward": "kubectl run --env REMOTE_HOST=$REMOTE_HOST --env REMOTE_PORT=5432 --env LOCAL_PORT=8080 --port 8080 --image marcnuri/port-forward test-port-forward ; kubectl port-forward test-port-forward 8080:8080", @@ -61,7 +63,7 @@ "@aws-sdk/client-s3": "^3.537.0", "@desci-labs/desci-codex-lib": "^1.1.7", "@desci-labs/desci-contracts": "^0.2.7", - "@desci-labs/desci-models": "0.2.15", + "@desci-labs/desci-models": "^0.2.19", "@elastic/elasticsearch": "^8.14.0", "@honeycombio/opentelemetry-node": "^0.3.2", "@ipld/dag-pb": "^4.0.0", @@ -178,4 +180,4 @@ "prisma": { "seed": "node --no-warnings=ExperimentalWarning --loader ts-node/esm prisma/seed.ts" } -} +} \ No newline at end of file diff --git a/desci-server/src/controllers/admin/communities/index.ts b/desci-server/src/controllers/admin/communities/index.ts index 915f3132d..d00fd460a 100644 --- a/desci-server/src/controllers/admin/communities/index.ts +++ b/desci-server/src/controllers/admin/communities/index.ts @@ -4,6 +4,7 @@ import _ from 'lodash'; import { z } from 'zod'; import { prisma } from '../../../client.js'; +import { PUBLIC_IPFS_PATH } from '../../../config/index.js'; import { BadRequestError, NotFoundError } from '../../../core/ApiError.js'; import { SuccessMessageResponse, SuccessResponse } from '../../../core/ApiResponse.js'; import { DuplicateDataError } from '../../../core/communities/error.js'; @@ -44,15 +45,15 @@ export const createCommunity = async (req: Request, res: Response, _next: NextFu if (uploads?.length > 0) { uploads = uploads.map((file) => { - file.originalname = `${file.fieldname}.${file.originalname.split('.')?.[1]}`; + file.originalname = `${file.fieldname}-${Math.random()}.${file.originalname.split('.')?.[1]}`; + logger.info({ orginalname: file.originalname, fieldname: file.fieldname }, 'Upload'); return file; }); - logger.info({ uploads }, 'Uploads'); const { ok, value } = await processUploadToIpfs({ files: uploads }); if (ok && value) { assets = value.map((ipfsImg) => ({ key: ipfsImg.path, - url: `${process.env.IPFS_RESOLVER_OVERRIDE}/${ipfsImg.cid}`, + url: `${PUBLIC_IPFS_PATH}/${ipfsImg.cid}`, })); } else { throw new BadRequestError('Could not upload file to ipfs'); @@ -88,14 +89,14 @@ export const updateCommunity = async (req: Request, res: Response, _next: NextFu logger.info({ uploads: !!uploads }, 'Uploads'); if (uploads?.length > 0) { uploads = uploads.map((file) => { - file.originalname = `${file.fieldname}.${file.originalname.split('.')?.[1]}`; + file.originalname = `${file.fieldname}-${Math.random()}.${file.originalname.split('.')?.[1]}`; return file; }); const { ok, value } = await processUploadToIpfs({ files: uploads }); if (ok && value) { assets = value.map((ipfsImg) => ({ key: ipfsImg.path, - url: `${process.env.IPFS_RESOLVER_OVERRIDE}/${ipfsImg.cid}`, + url: `${PUBLIC_IPFS_PATH}/${ipfsImg.cid}`, })); } else { throw new BadRequestError('Could not upload file to ipfs'); @@ -219,7 +220,7 @@ export const createAttestation = async (req: Request, res: Response, _next: Next if (uploads?.length > 0) { uploads = uploads.map((file) => { - file.originalname = `${file.fieldname}.${file.originalname.split('.')?.[1]}`; + file.originalname = `${file.fieldname}-${Math.random()}.${file.originalname.split('.')?.[1]}`; return file; }); @@ -227,7 +228,7 @@ export const createAttestation = async (req: Request, res: Response, _next: Next if (ok && value) { assets = value.map((ipfsImg) => ({ key: ipfsImg.path, - url: `${process.env.IPFS_RESOLVER_OVERRIDE}/${ipfsImg.cid}`, + url: `${PUBLIC_IPFS_PATH}/${ipfsImg.cid}`, })); } else { throw new BadRequestError('Could not upload file to ipfs'); @@ -286,7 +287,7 @@ export const updateAttestation = async (req: Request, res: Response, _next: Next logger.info({ uploads: uploads?.map((up) => up.fieldname) }, 'Uploads'); if (uploads?.length > 0) { uploads = uploads.map((file) => { - file.originalname = `${file.fieldname}.${file.originalname.split('.')?.[1]}`; + file.originalname = `${file.fieldname}-${Math.random()}.${file.originalname.split('.')?.[1]}`; return file; }); const { ok, value } = await processUploadToIpfs({ files: uploads }); @@ -294,7 +295,7 @@ export const updateAttestation = async (req: Request, res: Response, _next: Next if (ok && value) { assets = value.map((ipfsImg) => ({ key: ipfsImg.path, - url: `${process.env.IPFS_RESOLVER_OVERRIDE}/${ipfsImg.cid}`, + url: `${PUBLIC_IPFS_PATH}/${ipfsImg.cid}`, })); } else { throw new BadRequestError('Could not upload file to ipfs'); diff --git a/desci-server/src/controllers/auth/index.ts b/desci-server/src/controllers/auth/index.ts index 49f777d5d..91d4ed082 100755 --- a/desci-server/src/controllers/auth/index.ts +++ b/desci-server/src/controllers/auth/index.ts @@ -1,6 +1,5 @@ export * from './login.js'; export * from './logout.js'; -export * from './register.js'; export * from './profile.js'; export * from './orcid.js'; export * from './magic.js'; diff --git a/desci-server/src/controllers/auth/login.ts b/desci-server/src/controllers/auth/login.ts index c29974632..55d293bc1 100755 --- a/desci-server/src/controllers/auth/login.ts +++ b/desci-server/src/controllers/auth/login.ts @@ -14,5 +14,5 @@ export const check = async (req: RequestWithUser, res: Response, next: NextFunct return; } - res.send({ ok: false }); + res.status(401).send({ ok: false }); }; diff --git a/desci-server/src/controllers/auth/orcid.ts b/desci-server/src/controllers/auth/orcid.ts index 9fc8e8944..03d7d9f2c 100755 --- a/desci-server/src/controllers/auth/orcid.ts +++ b/desci-server/src/controllers/auth/orcid.ts @@ -36,7 +36,7 @@ export const validateOrcid = async (req: Request, res: Response) => { res.send({ data, ok: true }); } catch (err) { logger.error({ err, fn: 'validateOrcid', req }); - res.status(400).send({ ok: false, err }); + res.status(400).send({ ok: false, msg: 'Validation failed' }); } }; @@ -144,7 +144,7 @@ const processOrcidConnect = async (req: Request, res: Response, closing: boolean return; } catch (err) { logger.error({ fn: 'processOrcidConnect', err }, 'error processing orcid connect'); - res.status(400).send({ err }); + res.status(400).send('Orcid connect failed'); } }; @@ -203,6 +203,6 @@ const processOrcidAuth = async (req: Request, res: Response, closing: boolean) = return; } catch (err) { logger.error({ fn: 'processOrcidAuth', err }, 'error processing orcid auth'); - res.status(400).send({ err }); + res.status(500).send({ msg: 'processing ORCID auth failed' }); } }; diff --git a/desci-server/src/controllers/auth/register.ts b/desci-server/src/controllers/auth/register.ts deleted file mode 100755 index 84900f77c..000000000 --- a/desci-server/src/controllers/auth/register.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { Request, Response, NextFunction } from 'express'; - -import { prisma } from '../../client.js'; - -export const register = async (req: Request, res: Response, next: NextFunction) => { - const { email, tokendId } = req.body; - - if (!email) { - res.status(400).send({ ok: false }); - return; - } - - const user = await prisma.user.upsert({ - where: { - email, - }, - update: {}, - create: { - email, - isPatron: false, - isWarden: false, - isKeeper: false, - }, - }); - - res.send(user); - - // const userRepository = getRepository(User); - // try { - // const user = await userRepository.findOne({ where: { email } }); - - // if (user) { - // const customError = new CustomError(400, 'General', 'User already exists', [ - // `Email '${user.email}' already exists`, - // ]); - // return next(customError); - // } - - // try { - // const newUser = new User(); - // newUser.email = email; - - // await userRepository.save(newUser); - - // res.customSuccess(200, 'User successfully created.'); - // } catch (err) { - // const customError = new CustomError(400, 'Raw', `User '${email}' can't be created`, null, err); - // return next(customError); - // } - // } catch (err) { - // const customError = new CustomError(400, 'Raw', 'Error', null, err); - // return next(customError); - // } -}; diff --git a/desci-server/src/controllers/data/google/import.ts b/desci-server/src/controllers/data/google/import.ts index 376f87898..9da0e0c78 100644 --- a/desci-server/src/controllers/data/google/import.ts +++ b/desci-server/src/controllers/data/google/import.ts @@ -51,7 +51,14 @@ export const googleImport = async ( fileStream = await googleService.getFileStream(googleFileId); } // debugger; - const files = [{ originalname: '/' + fileName, content: fileStream, size: fileMd.size }]; + const files = [ + { + originalname: '/' + fileName, + content: fileStream, + // If unset (should only happen on folders and links, which prob don't work anyway), pass undefined instead of NaN + size: Number(fileMd.size) || undefined, + }, + ]; const { ok, value } = await processS3DataToIpfs({ files, user: owner, diff --git a/desci-server/src/controllers/doi/mint.ts b/desci-server/src/controllers/doi/mint.ts index a3d120dd1..0a797222e 100644 --- a/desci-server/src/controllers/doi/mint.ts +++ b/desci-server/src/controllers/doi/mint.ts @@ -3,13 +3,37 @@ import { Request, Response, NextFunction } from 'express'; import _ from 'lodash'; import { prisma } from '../../client.js'; +import { BadRequestError } from '../../core/ApiError.js'; import { SuccessMessageResponse, SuccessResponse } from '../../core/ApiResponse.js'; +import { MintError } from '../../core/doi/error.js'; import { logger as parentLogger } from '../../logger.js'; import { EmailTypes, sendEmail } from '../../services/email.js'; import { getTargetDpidUrl } from '../../services/fixDpid.js'; import { crossRefClient, doiService } from '../../services/index.js'; import { DiscordChannel, discordNotify, DiscordNotifyType } from '../../utils/discordUtils.js'; +export const retryDoiMint = async (req: Request, res: Response, _next: NextFunction) => { + const { submissionId } = req.params; + if (!submissionId) throw new BadRequestError(); + + const submission = await doiService.getSubmissionById(parseInt(submissionId)); + if (!submission) { + throw new MintError('No pending submission found'); + } + + await doiService.retryDoiMint(submission); + + const targetDpidUrl = getTargetDpidUrl(); + discordNotify({ + channel: DiscordChannel.DoiMinting, + type: DiscordNotifyType.INFO, + title: 'Retry DOI Minting', + message: `${targetDpidUrl}/${submission.dpid} sent a request to mint: ${submission.uniqueDoi}`, + }); + + new SuccessMessageResponse().send(res); +}; + export interface RequestWithCrossRefPayload extends Request { payload: { notifyEndpoint: string; diff --git a/desci-server/src/controllers/nodes/contributions/prepubEmail.ts b/desci-server/src/controllers/nodes/contributions/prepubEmail.ts index 877902b2a..5df86b75b 100644 --- a/desci-server/src/controllers/nodes/contributions/prepubEmail.ts +++ b/desci-server/src/controllers/nodes/contributions/prepubEmail.ts @@ -48,7 +48,7 @@ export const emailPublishPackage = async ( nodeUuid, userId: user.id, }); - // debugger; //// + // debugger; // logger.trace({ fn: 'Distributing Publish Package' }); if (!nodeUuid) return res.status(400).json({ ok: false, error: 'nodeUuid is required.' }); diff --git a/desci-server/src/controllers/nodes/doi.ts b/desci-server/src/controllers/nodes/doi.ts index fcbbd47e4..74eab7d9e 100644 --- a/desci-server/src/controllers/nodes/doi.ts +++ b/desci-server/src/controllers/nodes/doi.ts @@ -185,7 +185,7 @@ export const automateManuscriptDoi = async (req: RequestWithNode, res: Response, contributors: authors.map((author) => ({ id: uuidv4(), name: author.name, - role: ResearchObjectV1AuthorRole.AUTHOR, + role: [], ...(author.affiliations.length > 0 && { organizations: author.affiliations }), ...(author.orcid && { orcid: getOrcidFromURL(author.orcid) }), })), diff --git a/desci-server/src/controllers/nodes/publish.ts b/desci-server/src/controllers/nodes/publish.ts index 8bf756397..d09817834 100644 --- a/desci-server/src/controllers/nodes/publish.ts +++ b/desci-server/src/controllers/nodes/publish.ts @@ -35,6 +35,7 @@ export type PublishReqBody = { ceramicStream?: string; commitId?: string; useNewPublish: boolean; + mintDoi: boolean; }; export type PublishRequest = Request & { @@ -52,7 +53,7 @@ export type PublishResBody = }; export const publish = async (req: PublishRequest, res: Response, _next: NextFunction) => { - const { uuid, cid, manifest, transactionId, ceramicStream, commitId, useNewPublish } = req.body; + const { uuid, cid, manifest, transactionId, ceramicStream, commitId, useNewPublish, mintDoi } = req.body; const email = req.user.email; const owner = req.user; const logger = parentLogger.child({ @@ -154,30 +155,32 @@ export const publish = async (req: PublishRequest, res: Response owner.id, ); - // trigger doi minting workflow - try { - const submission = await doiService.autoMintTrigger(node.uuid); - const targetDpidUrl = getTargetDpidUrl(); - discordNotify({ - channel: DiscordChannel.DoiMinting, - type: DiscordNotifyType.INFO, - title: 'Mint DOI', - message: `${targetDpidUrl}/${submission.dpid} sent a request to mint: ${submission.uniqueDoi}`, - }); - await PublishServices.updatePublishStatusEntry({ - publishStatusId: publishStatusEntry.id, - data: { - triggerDoiMint: true, - }, - }); - } catch (err) { - logger.error({ err }, 'Error: Mint DOI on Publish'); - await PublishServices.updatePublishStatusEntry({ - publishStatusId: publishStatusEntry.id, - data: { - triggerDoiMint: false, - }, - }); + if (mintDoi) { + // trigger doi minting workflow + try { + const submission = await doiService.autoMintTrigger(node.uuid); + const targetDpidUrl = getTargetDpidUrl(); + discordNotify({ + channel: DiscordChannel.DoiMinting, + type: DiscordNotifyType.INFO, + title: 'Mint DOI', + message: `${targetDpidUrl}/${submission.dpid} sent a request to mint: ${submission.uniqueDoi}`, + }); + await PublishServices.updatePublishStatusEntry({ + publishStatusId: publishStatusEntry.id, + data: { + triggerDoiMint: true, + }, + }); + } catch (err) { + logger.error({ err }, 'Error: Mint DOI on Publish'); + await PublishServices.updatePublishStatusEntry({ + publishStatusId: publishStatusEntry.id, + data: { + triggerDoiMint: false, + }, + }); + } } return res.send({ diff --git a/desci-server/src/routes/index.ts b/desci-server/src/routes/index.ts index 85660009d..4fd6d1216 100755 --- a/desci-server/src/routes/index.ts +++ b/desci-server/src/routes/index.ts @@ -1,30 +1,15 @@ import { Router } from 'express'; -import { handleCrossrefNotificationCallback } from '../controllers/doi/mint.js'; import { resolve } from '../controllers/raw/resolve.js'; -import { asyncHandler } from '../utils/asyncHandler.js'; import page404 from './pages/404.js'; import pageRoot from './pages/root.js'; -import { ensureCrossrefNotifier, identifyEndpoint } from './v1/crossref.js'; import v1 from './v1/index.js'; const router = Router(); router.use(`/v1`, v1); -// potential notification fallback catch -router.post( - '/crossref/callback', - [identifyEndpoint('/crossref/callback'), ensureCrossrefNotifier], - asyncHandler(handleCrossrefNotificationCallback), -); -router.post( - '/crossref/callback/v1/crossref/callback', - [identifyEndpoint('/crossref/callback/v1/crossref/callback'), ensureCrossrefNotifier], - asyncHandler(handleCrossrefNotificationCallback), -); - router.get('/:query*', resolve); router.use(pageRoot); diff --git a/desci-server/src/routes/v1/admin/communities/index.ts b/desci-server/src/routes/v1/admin/communities/index.ts index 3bfedd08f..03949ced0 100644 --- a/desci-server/src/routes/v1/admin/communities/index.ts +++ b/desci-server/src/routes/v1/admin/communities/index.ts @@ -47,12 +47,12 @@ const upload = isS3Configured bucket: process.env.AWS_S3_BUCKET_NAME, key: (req, file, cb) => { // const userId = (req as any).user.id; - const { name, communitySlug } = (req as any).body; - if (!name || !name) { + const { name } = (req as any).body; + if (!name) { cb(new Error('Missing required params to form key')); } - const key = `${communitySlug}${name ? +'/' + name : ''}/${file.filename}`; // adjust for dir uploads, doesn't start with '/' - logger.info({ fileName: key }, 'Upload asset'); + const key = `community-assets/${name ? +'/' + name : ''}/${file.fieldname}`; // adjust for dir uploads, doesn't start with '/' + logger.info({ key }, 'Upload asset'); cb(null, key); }, }), diff --git a/desci-server/src/routes/v1/admin/communities/schema.ts b/desci-server/src/routes/v1/admin/communities/schema.ts index 9a314adfd..0494645a8 100644 --- a/desci-server/src/routes/v1/admin/communities/schema.ts +++ b/desci-server/src/routes/v1/admin/communities/schema.ts @@ -10,7 +10,9 @@ export const addCommunitySchema = z.object({ .boolean() .transform((value) => (value.toString() === 'true' ? true : false)) .default(false), - keywords: z.array(z.string()).min(1, 'Community must have at least one keyword'), + keywords: z + .array(z.string().min(1, 'Keyword cannot be an empty string')) + .min(1, 'Community must have at least one keyword'), imageUrl: z.string().url().optional(), //"https://pub.desci.com/ipfs/bafkreie7kxhzpzhsbywcrpgyv5yvy3qxcjsibuxsnsh5olaztl2uvnrzx4", slug: z.string().min(3), links: z.array(z.string().url()), @@ -26,7 +28,10 @@ export const updateCommunitySchema = z.object({ .boolean() .transform((value) => (value.toString() === 'true' ? true : false)) .default(false), - keywords: z.array(z.string()).min(1, 'Community must have at least one keyword').optional(), + keywords: z + .array(z.string().min(1, 'Keyword cannot be an empty string')) + .min(1, 'Community must have at least one keyword') + .optional(), imageUrl: z.string().url().optional(), //"https://pub.desci.com/ipfs/bafkreie7kxhzpzhsbywcrpgyv5yvy3qxcjsibuxsnsh5olaztl2uvnrzx4", slug: z.string().min(3).optional(), links: z.array(z.string().url()).optional(), diff --git a/desci-server/src/routes/v1/admin/doi.ts b/desci-server/src/routes/v1/admin/doi.ts new file mode 100644 index 000000000..d7f9dece8 --- /dev/null +++ b/desci-server/src/routes/v1/admin/doi.ts @@ -0,0 +1,11 @@ +import { Router } from 'express'; + +import { retryDoiMint } from '../../../controllers/doi/mint.js'; +import { ensureAdmin } from '../../../middleware/ensureAdmin.js'; +import { ensureUser } from '../../../middleware/permissions.js'; +import { asyncHandler } from '../../../utils/asyncHandler.js'; + +const router = Router(); +router.post('/retry-mint/:submissionId', [ensureUser, ensureAdmin], asyncHandler(retryDoiMint)); + +export default router; diff --git a/desci-server/src/routes/v1/admin/index.ts b/desci-server/src/routes/v1/admin/index.ts index 22907b561..a3bb6733d 100644 --- a/desci-server/src/routes/v1/admin/index.ts +++ b/desci-server/src/routes/v1/admin/index.ts @@ -10,6 +10,7 @@ import { ensureUser } from '../../../middleware/permissions.js'; import { asyncHandler } from '../../../utils/asyncHandler.js'; import communities from './communities/index.js'; +import doiRouter from './doi.js'; const router = Router(); @@ -28,4 +29,6 @@ router.use('/communities', [ensureUser, ensureAdmin], communities); router.get('/attestations', [ensureUser, ensureAdmin], asyncHandler(listAttestations)); // router.use('/users', [ensureUser, ensureAdmin], usersRouter); +router.use('/doi', doiRouter); + export default router; diff --git a/desci-server/src/routes/v1/auth.ts b/desci-server/src/routes/v1/auth.ts index 5d2f7ad35..f7a107fe0 100755 --- a/desci-server/src/routes/v1/auth.ts +++ b/desci-server/src/routes/v1/auth.ts @@ -3,7 +3,6 @@ import { Router } from 'express'; import { login, logout, - register, profile, orcidAuth, orcidAuthClose, @@ -28,7 +27,6 @@ router.post('/login/did', asyncHandler(walletLogin)); router.get('/login/did/:walletAddress', asyncHandler(walletNonce)); router.delete('/logout', logout); router.get('/profile', [ensureUser], profile); -router.post('/register', register); router.get('/orcid/auth', orcidAuth); router.get('/orcid/auth/close', orcidAuthClose); router.get('/orcid/connect', orcidConnect); diff --git a/desci-server/src/scripts/invalidate-redis-cache.ts b/desci-server/src/scripts/invalidate-redis-cache.ts index 07b3a3225..ba1761992 100644 --- a/desci-server/src/scripts/invalidate-redis-cache.ts +++ b/desci-server/src/scripts/invalidate-redis-cache.ts @@ -14,19 +14,32 @@ Usage Examples: invalidateByUuid: OPERATION=invalidateByUuid NODE_UUID=noDeUuiD. npm run script:invalidate-redis-cache */ +async function main() { + try { + const { operation, nodeUuid } = getOperationEnvs(); -main(); -function main() { - const { operation, nodeUuid } = getOperationEnvs(); - - switch (operation) { - case 'invalidateByUuid': - if (!nodeUuid) return logger.error('Missing NODE_UUID or MANIFEST_CID'); - invalidateByUuid({ nodeUuid }); - break; - default: - logger.error('Invalid operation, valid operations include: invalidateByUuid'); - return; + switch (operation) { + case 'invalidateByUuid': + if (!nodeUuid) return logger.error('Missing NODE_UUID or MANIFEST_CID'); + await invalidateByUuid({ nodeUuid }); + break; + case 'invalidateAll': + if (nodeUuid) { + logger.error('NODE_UUID was passed to invalidateAll, aborting in case of mistake'); + throw new Error('invalidateAll does not take NODE_UUID'); + } + await invalidateAll(); + break; + default: + logger.error('Invalid operation, valid operations include: invalidateByUuid'); + return; + } + } catch (e) { + const err = e as Error; + console.error('Script failed:', err.message); + process.exit(1); + } finally { + await redisClient.quit(); } } @@ -37,6 +50,11 @@ function getOperationEnvs() { }; } +async function invalidateAll() { + await redisClient.flushDb(); + logger.info('[invalidateAll] Wiped all keys from cache'); +} + async function invalidateByUuid({ nodeUuid }: { nodeUuid: string }) { // Find all published versions of the node if (!nodeUuid.endsWith('.')) nodeUuid += '.'; @@ -98,3 +116,5 @@ async function deleteKeys(pattern: string) { logger.info({ pattern }, `All matching keys deleted.`); } + +main(); diff --git a/desci-server/src/services/Attestation.ts b/desci-server/src/services/Attestation.ts index b80a38817..5e5301768 100644 --- a/desci-server/src/services/Attestation.ts +++ b/desci-server/src/services/Attestation.ts @@ -126,6 +126,7 @@ export class AttestationService { } async create(data: Prisma.AttestationUncheckedCreateInput) { + logger.trace({ data }, 'AttestationService#create'); const community = await communityService.findCommunityById(data.communityId); if (!community) throw new CommunityNotFoundError(); @@ -133,7 +134,19 @@ export class AttestationService { const existing = await prisma.attestation.findFirst({ where: { name: data.name, communityId: data.communityId } }); if (existing) throw new DuplicateDataError(); - const attestation = await prisma.attestation.create({ data: { communityId: community.id, ...data } }); + const attestation = await prisma.attestation.create({ + data: { + name: data.name, + description: data.description, + image_url: data.image_url, + verified_image_url: data.verified_image_url, + protected: data.protected, + canMintDoi: data.canMintDoi, + canUpdateOrcid: data.canUpdateOrcid, + communityId: community.id, + templateId: data.templateId, + }, + }); await this.#publishVersion({ name: attestation.name, @@ -181,12 +194,22 @@ export class AttestationService { canUpdateOrcid: data.canUpdateOrcid, }, }); - await this.#publishVersion({ + const attestationVersion = await this.#publishVersion({ name: data.name as string, description: data.description, image_url: data.image_url, attestationId: attestation.id, }); + + const communityEntryAttestation = await prisma.communityEntryAttestation.findFirst({ + where: { attestationId: attestation.id }, + }); + if (communityEntryAttestation) { + await prisma.communityEntryAttestation.update({ + where: { id: communityEntryAttestation.id }, + data: { attestationVersionId: attestationVersion.id }, + }); + } const updated = await this.findAttestationById(attestation.id); return updated; } diff --git a/desci-server/src/services/AutomatedMetadata.ts b/desci-server/src/services/AutomatedMetadata.ts index 889e50213..a112b9a59 100644 --- a/desci-server/src/services/AutomatedMetadata.ts +++ b/desci-server/src/services/AutomatedMetadata.ts @@ -317,7 +317,7 @@ export class AutomatedMetadataClient { ({ id: uuidv4(), name: author.name, - role: ResearchObjectV1AuthorRole.AUTHOR, + role: [], ...(author.affiliations.length > 0 && { organizations: author.affiliations }), ...(author.orcid && { orcid: getOrcidFromURL(author.orcid) }), }) as ResearchObjectV1Author, diff --git a/desci-server/src/services/Contributors.ts b/desci-server/src/services/Contributors.ts index e5ecc99bd..9991342c3 100644 --- a/desci-server/src/services/Contributors.ts +++ b/desci-server/src/services/Contributors.ts @@ -193,15 +193,18 @@ class ContributorService { node, verifiedOnly, withEmailOnly, + nonDeniedOnly, }: { node: Node; verifiedOnly?: boolean; + nonDeniedOnly?: boolean; withEmailOnly?: boolean; }): Promise<(NodeContribution & { user: User })[]> { let contributions = await prisma.nodeContribution.findMany({ where: { nodeId: node.id, ...(verifiedOnly ? { verified: true } : {}), + ...(nonDeniedOnly ? { denied: false } : {}), }, include: { user: true }, }); diff --git a/desci-server/src/services/Doi.ts b/desci-server/src/services/Doi.ts index dd42641cd..c6dbc63bf 100644 --- a/desci-server/src/services/Doi.ts +++ b/desci-server/src/services/Doi.ts @@ -210,6 +210,47 @@ export class DoiService { return submission; } + async retryDoiMint(submission: DoiSubmissionQueue) { + const { dpid, uuid, manifest, researchObject } = await this.checkMintability(submission.uuid); + // mint new doi + + const latestVersionTimestamp = researchObject.versions[researchObject.versions.length - 1]?.time; + const publicationDate = latestVersionTimestamp + ? new Date(parseInt(latestVersionTimestamp) * 1000).toLocaleDateString().replaceAll('/', '-') + : (await this.getLastPublishedDate(uuid)).toLocaleDateString().replaceAll('/', '-'); + logger.trace( + { + latestVersionTimestamp: new Date(parseInt(latestVersionTimestamp) * 1000) + .toLocaleDateString() + .replaceAll('/', '-'), + publicationDate, + }, + 'latestVersionTimestamp', + ); + + const [month, day, year] = publicationDate.split('-'); + + const metadataResponse = await crossRefClient.registerDoi({ + manifest, + doi: submission.uniqueDoi, + dpid, + publicationDate: { day, month, year }, + }); + + logger.info({ doi: submission.uniqueDoi, uuid, metadataResponse }, 'DOI SUBMITTED'); + if (!metadataResponse.ok) { + throw new MintError("We couldn't register a DOI for this research object"); + } + + await this.dbClient.doiSubmissionQueue.update({ + where: { id: submission.id }, + data: { status: DoiStatus.PENDING }, + }); + + // return submission queue data + return submission; + } + async autoMintTrigger(uuid: string) { const sanitizedUuid = ensureUuidEndsWithDot(uuid); const isPending = await this.hasPendingSubmission(sanitizedUuid); @@ -254,6 +295,12 @@ export class DoiService { }); } + async getSubmissionById(id: number) { + return await this.dbClient.doiSubmissionQueue.findFirst({ + where: { id }, + }); + } + async getPendingSubmissions() { return await this.dbClient.doiSubmissionQueue.findMany({ where: { status: DoiStatus.PENDING }, diff --git a/desci-server/src/services/NotificationService.ts b/desci-server/src/services/NotificationService.ts index 9a164d9dc..92c915b6d 100644 --- a/desci-server/src/services/NotificationService.ts +++ b/desci-server/src/services/NotificationService.ts @@ -491,10 +491,14 @@ export const getUnseenNotificationCount = async ({ userId, user }: { userId?: nu }; export const incrementUnseenNotificationCount = async ({ userId }: { userId: number }) => { - await prisma.user.update({ - where: { id: userId }, - data: { unseenNotificationCount: { increment: 1 } }, - }); + try { + await prisma.user.update({ + where: { id: userId }, + data: { unseenNotificationCount: { increment: 1 } }, + }); + } catch (err) { + logger.error({ err }, 'Error'); + } }; export const resetUnseenNotificationCount = async ({ userId }: { userId: number }) => { diff --git a/desci-server/src/services/PublishServices.ts b/desci-server/src/services/PublishServices.ts index b6778dcb9..e241c9d30 100644 --- a/desci-server/src/services/PublishServices.ts +++ b/desci-server/src/services/PublishServices.ts @@ -35,12 +35,17 @@ async function sendVersionUpdateEmailToAllContributors({ }) { const contributors = ownerOnly ? [] - : await contributorService.retrieveAllContributionsForNode({ node, verifiedOnly, withEmailOnly: true }); + : await contributorService.retrieveAllContributionsForNode({ + node, + verifiedOnly, + withEmailOnly: true, + nonDeniedOnly: true, + }); const nodeOwner = await prisma.user.findUnique({ where: { id: node.ownerId } }); const manifest = await getLatestManifestFromNode(node); const dpid = node.dpidAlias?.toString() ?? manifest.dpid?.id; const versionPublished = await getNodeVersion(node.uuid); - + // debugger; //// if (!dpid) { logger.error( { @@ -95,7 +100,7 @@ async function sendVersionUpdateEmailToAllContributors({ }); if (process.env.SHOULD_SEND_EMAIL && process.env.SENDGRID_API_KEY) { - await Promise.allSettled( + const results = await Promise.allSettled( emailPromises.map(async (emailPromiseEntry) => { const emailEntry = await emailPromiseEntry; if (!emailEntry.contributor.inviteSent) { @@ -108,6 +113,28 @@ async function sendVersionUpdateEmailToAllContributors({ return sgMail.send(emailEntry.emailMsg); }), ); + + const successCount = results.filter((r) => r.status === 'fulfilled').length; + const failureCount = results.filter((r) => r.status === 'rejected').length; + + logger.info( + { + totalEmails: results.length, + successCount, + failureCount, + failedEmails: results + .map((r, i) => + r.status === 'rejected' + ? { + index: i, + reason: (r as PromiseRejectedResult).reason?.message, + } + : null, + ) + .filter(Boolean), + }, + 'Submission package email sending complete', + ); } else { logger.info({ nodeEnv: process.env.NODE_ENV }, 'Skipping add contributor email send in non-production environment'); } diff --git a/desci-server/src/services/data/externalCidProcessing.ts b/desci-server/src/services/data/externalCidProcessing.ts index 02eda7f0a..fab924cc4 100644 --- a/desci-server/src/services/data/externalCidProcessing.ts +++ b/desci-server/src/services/data/externalCidProcessing.ts @@ -13,20 +13,10 @@ import { prisma } from '../../client.js'; import { ExternalCid } from '../../controllers/data/updateExternalCid.js'; import { persistManifest } from '../../controllers/data/utils.js'; import { logger as parentLogger } from '../../logger.js'; -import { ensureUniquePathsDraftTree, getLatestDriveTime } from '../../services/draftTrees.js'; -import { - GetExternalSizeAndTypeResult, - convertToCidV1, - getExternalCidSizeAndType, - pubRecursiveLs, -} from '../../services/ipfs.js'; import { DRAFT_CID } from '../../utils/draftTreeUtils.js'; -import { - FirstNestingComponent, - addComponentsToDraftManifest, - getTreeAndFill, - prepareFirstNestingComponents, -} from '../../utils/driveUtils.js'; +import { getTreeAndFill, prepareFirstNestingComponents } from '../../utils/driveUtils.js'; +import { ensureUniquePathsDraftTree, getLatestDriveTime } from '../draftTrees.js'; +import { GetExternalSizeAndTypeResult, convertToCidV1, getExternalCidSizeAndType, pubRecursiveLs } from '../ipfs.js'; import { NodeUuid, getLatestManifestFromNode } from '../manifestRepo.js'; import repoService from '../repoService.js'; @@ -50,6 +40,7 @@ interface ProcessExternalCidDataToIpfsParams { externalCids: ExternalCid[]; user: User; node: Node; + /** * @type {string} path to the directory to be updated */ @@ -71,6 +62,17 @@ export async function processExternalCidDataToIpfs({ componentSubtype, autoStar, }: ProcessExternalCidDataToIpfsParams) { + logger.debug({ + fn: 'processExternalCidDataToIpfs', + externalCids, + user, + node, + contextPath, + componentType, + componentSubtype, + autoStar, + }); + try { /** * Prepare the CIDs for addition, see if they're resolvable and get their sizes and types @@ -81,7 +83,7 @@ export async function processExternalCidDataToIpfs({ for (const extCid of externalCids) { const { isDirectory, size } = await getExternalCidSizeAndType(extCid.cid); if (size !== undefined && isDirectory !== undefined) { - cidTypesSizes[extCid.cid] = { size, isDirectory }; + cidTypesSizes[extCid.cid] = { size: Number(size), isDirectory }; } else { throw new Error(`Failed to get size and type of external CID: ${extCid}`); } @@ -189,25 +191,6 @@ export async function processExternalCidDataToIpfs({ const componentTypeMap: ResearchObjectComponentTypeMap = constructComponentTypeMapFromFiles(entriesDiscovered); - // Predefine components with their types, only happens if a predefined component type is passed - // if (componentType) { - // const firstNestingComponents: FirstNestingComponent[] = extCidsBeingAdded.map((file) => { - // const neutralFullPath = contextPath + '/' + file.name; - // return { - // name: file.name, - // path: neutralFullPath, - // cid: file.cid, - // componentType, - // componentSubtype, - // star: autoStar, - // }; - // }); - - // if (firstNestingComponents.length > 0) { - // await addComponentsToDraftManifest(node, firstNestingComponents); - // } - // } - let updatedManifest = await getLatestManifestFromNode(ltsNode); if (componentTypeMap) { @@ -231,6 +214,8 @@ export async function processExternalCidDataToIpfs({ pinnedFirstNestingFiles: firstNestingFiles, contextPath, componentTypeMap, + componentType, + componentSubtype, star: true, }); const preparedComponents = prepareFirstNestingComponents(firstNestingComponents); diff --git a/desci-server/src/services/data/processing.ts b/desci-server/src/services/data/processing.ts index 42a18f14f..61d3d7fc0 100644 --- a/desci-server/src/services/data/processing.ts +++ b/desci-server/src/services/data/processing.ts @@ -505,7 +505,9 @@ export function predefineComponentsForPinnedFiles({ star, }: PredefineComponentsForPinnedFilesParams): FirstNestingComponent[] { const firstNestingComponents: FirstNestingComponent[] = pinnedFirstNestingFiles.map((file) => { - const neutralFullPath = contextPath + '/' + file.path; + const neutralFullPath = file.path.startsWith(contextPath) + ? file.path + : contextPath + '/' + file.path; const pathSplit = file.path.split('/'); const name = pathSplit.pop(); return { diff --git a/desci-server/src/services/ipfs.ts b/desci-server/src/services/ipfs.ts index 3fadd2d55..8c1aeeed5 100644 --- a/desci-server/src/services/ipfs.ts +++ b/desci-server/src/services/ipfs.ts @@ -1,6 +1,5 @@ import fs from 'fs'; import https from 'https'; -import path from 'path'; import { Readable } from 'stream'; import { @@ -30,9 +29,6 @@ import { DRIVE_NODE_ROOT_PATH, type ExternalCidMap, type newCid, type oldCid } f import { getGithubExternalUrl, processGithubUrl } from '../utils/githubUtils.js'; import { createManifest, getUrlsFromParam, makePublic } from '../utils/manifestDraftUtils.js'; -// eslint-disable-next-line @typescript-eslint/no-var-requires -export const IPFS_PATH_TMP = '/tmp/ipfs'; - const logger = parentLogger.child({ module: 'Services::Ipfs', }); @@ -59,8 +55,9 @@ export const readerClient = create({ url: PUBLIC_IPFS_PATH }); export const publicIpfs = create({ url: process.env.PUBLIC_IPFS_RESOLVER + '/api/v0', options: { agent: httpsAgent } }); // Timeouts for resolution on internal and external IPFS nodes, to prevent server hanging, in ms. -const INTERNAL_IPFS_TIMEOUT = 30000; -const EXTERNAL_IPFS_TIMEOUT = 120000; +const INTERNAL_IPFS_TIMEOUT = 30_000; +// We mostly fetch single blocks, so this does not limit transfers +const EXTERNAL_IPFS_TIMEOUT = 30_000; export const updateManifestAndAddToIpfs = async ( manifest: ResearchObjectV1, @@ -94,15 +91,16 @@ export const updateManifestAndAddToIpfs = async ( return { cid: result.cid.toString(), size: result.size, ref, nodeVersion: version }; }; -export const addBufferToIpfs = (buf: Buffer, key: string) => { - return client.add(buf, { cidVersion: 1 }).then((res) => { - return { cid: res.cid.toString(), size: res.size, key }; - }); +export const addBufferToIpfs = async ( + buf: Buffer, + key: string, +): Promise<{ cid: string; size: number; key: string }> => { + const { cid, size } = await client.add(buf, { cidVersion: 1 }); + return { cid: cid.toString(), size: Number(size), key }; }; export const getSizeForCid = async (cid: string, asDirectory: boolean | undefined): Promise => { - const size = await getSize(client, cid, asDirectory); - return size; + return await getSize(client, cid, asDirectory); }; export const downloadFilesAndMakeManifest = async ({ title, defaultLicense, pdf, code, researchFields }) => { @@ -182,7 +180,7 @@ interface CodeComponentSingle { const processUrls = (key: string, data: Array): Array> => { logger.trace({ fn: 'processUrls' }, `processUrls key: ${key}, data: ${data}`); - return data.map(async (e, i) => { + return data.map(async (e) => { // if our payload points to github, download a zip of the main branch if (key === 'code') { if (e.indexOf('github.com') > -1) { @@ -205,10 +203,10 @@ export const downloadFile = async (url: string, key: string): Promise { + return new Promise(async (resolve, _reject) => { try { logger.info({ fn: 'downloadFile' }, `start download ${url.substring(0, 256)}`); - const { data, headers } = await axios({ + const { data } = await axios({ method: 'get', url: url, responseType: 'stream', @@ -322,12 +320,9 @@ export interface RecursiveLsResult extends IpfsPinnedResult { export const convertToCidV1 = (cid: string | multiformats.CID): string => { if (typeof cid === 'string') { - const c = multiformats.CID.parse(cid); - return c.toV1().toString(); - } else { - const cV1 = cid.toV1().toString(); - return cV1; + cid = multiformats.CID.parse(cid); } + return cid.toV1().toString(); }; export const resolveIpfsData = async (cid: string): Promise => { @@ -361,8 +356,7 @@ export const resolveIpfsData = async (cid: string): Promise => { targetValue = (targetValue as Uint8Array).buffer; } - const buffer = Buffer.from(targetValue); - return buffer; + return Buffer.from(targetValue); } }; @@ -407,32 +401,20 @@ export const getDirectoryTree = async ( { fn: 'getDirectoryTree', cid, returnFiles, returnExternalFiles }, `[getDirectoryTree]retrieving tree for cid: ${cid}, ipfs online: ${isOnline}`, ); - try { - // const tree = await getOrCache( - // `full-tree-${cid}${!returnFiles ? '-no-files' : ''}${cid}${!returnExternalFiles ? '-no-ext-files' : ''}`, - // getTree, - // ); - const tree = null; - if (tree) return tree; - throw new Error('[getDirectoryTree] Failed to retrieve tree from cache'); - } catch (err) { - logger.warn({ fn: 'getDirectoryTree', err }, '[getDirectoryTree] error'); - logger.info('[getDirectoryTree] Falling back on uncached tree retrieval'); - const startTime = process.hrtime(); - const treeRes = await getTree(); - // return getTree(); - const endTime = process.hrtime(startTime); - logger.info(`[getDirectoryTree] Execution time: ${endTime[0]}s ${endTime[1] / 1000000}ms`); - return treeRes; - } + + const startTime = process.hrtime(); + const treeRes = await getTree(); + const endTime = process.hrtime(startTime); + logger.info(`[getDirectoryTree] Execution time: ${endTime[0]}s ${endTime[1] / 1000000}ms`); + return treeRes; + async function getTree() { if (Object.keys(externalCidMap).length === 0) { logger.info({ fn: 'getDirectoryTree' }, `[getDirectoryTree] using standard ls, dagCid: ${cid}`); return await recursiveLs(cid); } else { logger.info({ fn: 'getDirectoryTree' }, `[getDirectoryTree] using mixed ls, dagCid: ${cid}`); - const tree = await mixedLs(cid, externalCidMap, returnFiles, returnExternalFiles); - return tree; + return await mixedLs(cid, externalCidMap, returnFiles, returnExternalFiles); } } }; @@ -445,7 +427,7 @@ export const recursiveLs = async (cid: string, carryPath?: string) => { const lsOp = client.ls(cid, { timeout: INTERNAL_IPFS_TIMEOUT }); for await (const filedir of lsOp) { - const promise = new Promise(async (resolve, reject) => { + const promise = new Promise(async (resolve, _reject) => { const res: any = filedir; // if (parent) { // res.parent = parent; @@ -486,7 +468,7 @@ export async function mixedLs( carryPath = carryPath || convertToCidV1(dagCid); const tree: RecursiveLsResult[] = []; const cidObject = multiformats.CID.parse(dagCid); - let block; + let block: Uint8Array; try { block = await client.block.get(cidObject, { timeout: INTERNAL_IPFS_TIMEOUT }); //instead of throwing, catch and print cid } catch (err) { @@ -518,7 +500,7 @@ export async function mixedLs( if (linkCidObject.code === rawCode || isFile) { result.size = link.Tsize; } else { - let linkBlock; + let linkBlock: Uint8Array; try { linkBlock = await client.block.get(linkCidObject, { timeout: INTERNAL_IPFS_TIMEOUT }); //instead of throwing, catch and print cid } catch (err) { @@ -596,12 +578,18 @@ export async function discoveryLs(dagCid: string, externalCidMap: ExternalCidMap const tree: RecursiveLsResult[] = []; const cidObject = multiformats.CID.parse(dagCid); let block = await client.block.get(cidObject, { timeout: INTERNAL_IPFS_TIMEOUT }); - if (!block) block = await publicIpfs.block.get(cidObject, { timeout: INTERNAL_IPFS_TIMEOUT }); - if (!block) throw new Error('Could not find block for cid: ' + dagCid); + if (!block) { + block = await publicIpfs.block.get(cidObject, { timeout: INTERNAL_IPFS_TIMEOUT }); + } + if (!block) { + throw new Error('Could not find block for cid: ' + dagCid); + } const { Data, Links } = dagPb.decode(block); const unixFs = UnixFS.unmarshal(Data); const isDir = dirTypes.includes(unixFs?.type); - if (!isDir) return null; + if (!isDir) { + return null; + } for (const link of Links) { const result: RecursiveLsResult = { name: link.Name, @@ -611,15 +599,21 @@ export async function discoveryLs(dagCid: string, externalCidMap: ExternalCidMap type: 'file', }; const externalCidMapEntry = externalCidMap[result.cid]; - if (externalCidMapEntry) result.external = true; + if (externalCidMapEntry) { + result.external = true; + } const isExternalFile = externalCidMapEntry && externalCidMapEntry.directory == false; const linkCidObject = multiformats.CID.parse(result.cid); if (linkCidObject.code === rawCode || isExternalFile) { result.size = link.Tsize; } else { let linkBlock = await client.block.get(linkCidObject, { timeout: INTERNAL_IPFS_TIMEOUT }); - if (!linkBlock) linkBlock = await publicIpfs.block.get(cidObject, { timeout: EXTERNAL_IPFS_TIMEOUT }); - if (!linkBlock) throw new Error('Could not find block for cid: ' + dagCid); + if (!linkBlock) { + linkBlock = await publicIpfs.block.get(cidObject, { timeout: EXTERNAL_IPFS_TIMEOUT }); + } + if (!linkBlock) { + throw new Error('Could not find block for cid: ' + dagCid); + } const { Data: linkData } = dagPb.decode(linkBlock); const unixFsLink = UnixFS.unmarshal(linkData); const isLinkDir = dirTypes.includes(unixFsLink?.type); @@ -646,16 +640,14 @@ export async function discoveryLs(dagCid: string, externalCidMap: ExternalCidMap } export const getDag = async (cid: CID) => { - const dag = await client.dag.get(cid); - return dag; + return await client.dag.get(cid); }; -export const getDatasetTar = async (cid) => { - const files = await client.get(cid, { archive: true }); - return files; +export const getDatasetTar = async (cid: CID | string): Promise> => { + return client.get(cid, { archive: true }); }; -export const getDataset = async (cid: CID) => { +export const getDataset = async (cid: CID | string) => { const files = []; for await (const file of client.get(cid)) { files.push(file); @@ -702,7 +694,7 @@ type FileInfo = { cid: string; size?: number }; export type FilesToAddToDag = Record; export const addFilesToDag = async (rootCid: string, contextPath: string, filesToAddToDag: FilesToAddToDag) => { - const dagCidsToBeReset = []; + const dagCidsToBeReset: CID[] = []; // CID(String): DAGNode - cached to prevent duplicate calls const dagsLoaded: Record = {}; dagCidsToBeReset.push(CID.parse(rootCid)); @@ -711,8 +703,7 @@ export const addFilesToDag = async (rootCid: string, contextPath: string, filesT for (let i = 0; i < stagingDagNames.length; i++) { const dagLinkName = stagingDagNames[i]; const containingDagCid = dagCidsToBeReset[i]; - //FIXME containingDag is of type PBNode - const containingDag: any = await client.object.get(containingDagCid); + const containingDag: PBNode = await client.object.get(containingDagCid); if (!containingDag) { throw Error('Failed updating dataset, existing DAG not found'); } @@ -727,9 +718,7 @@ export const addFilesToDag = async (rootCid: string, contextPath: string, filesT //if context path doesn't exist(update add at DAG root level), the dag won't be cached yet. if (!dagsLoaded.length) { - //FIXME rootDag is of type PBNode - const rootDag = await client.object.get(dagCidsToBeReset[0]); - dagsLoaded[rootCid] = rootDag; + dagsLoaded[rootCid] = await client.object.get(dagCidsToBeReset[0]); } //establishing the tail dag that's being updated @@ -748,8 +737,7 @@ export const addFilesToDag = async (rootCid: string, contextPath: string, filesT while (dagCidsToBeReset.length) { const currentNodeCid = dagCidsToBeReset.pop(); - //FIXME should be PBLink - const currentNode: any = dagsLoaded[currentNodeCid.toString()] + const currentNode: PBNode = dagsLoaded[currentNodeCid.toString()] ? dagsLoaded[currentNodeCid.toString()] : await client.object.get(currentNodeCid); const linkName = stagingDagNames.pop(); @@ -771,7 +759,7 @@ export const addFilesToDag = async (rootCid: string, contextPath: string, filesT }; export const removeFileFromDag = async (rootCid: string, contextPath: string, fileNameToRemove: string) => { - const dagCidsToBeReset = []; + const dagCidsToBeReset: CID[] = []; // CID(String): DAGNode - cached to prevent duplicate calls const dagsLoaded: Record = {}; dagCidsToBeReset.push(CID.parse(rootCid)); @@ -780,8 +768,7 @@ export const removeFileFromDag = async (rootCid: string, contextPath: string, fi for (let i = 0; i < stagingDagNames.length; i++) { const dagLinkName = stagingDagNames[i]; const containingDagCid = dagCidsToBeReset[i]; - //FIXME containingDag is of type PBNode - const containingDag: any = await client.object.get(containingDagCid); + const containingDag: PBNode = await client.object.get(containingDagCid); if (!containingDag) { throw Error('Failed updating dataset, existing DAG not found'); } @@ -796,9 +783,7 @@ export const removeFileFromDag = async (rootCid: string, contextPath: string, fi //if context path doesn't exist(update add at DAG root level), the dag won't be cached yet. if (!dagsLoaded.length) { - //FIXME rootDag is of type PBNode - const rootDag = await client.object.get(dagCidsToBeReset[0]); - dagsLoaded[rootCid] = rootDag; + dagsLoaded[rootCid] = await client.object.get(dagCidsToBeReset[0]); } //establishing the tail dag that's being updated @@ -814,8 +799,7 @@ export const removeFileFromDag = async (rootCid: string, contextPath: string, fi let lastUpdatedCid = updatedTailNodeCid; while (dagCidsToBeReset.length) { const currentNodeCid = dagCidsToBeReset.pop(); - //FIXME should be PBLink - const currentNode: any = dagsLoaded[currentNodeCid.toString()] + const currentNode: PBNode = dagsLoaded[currentNodeCid.toString()] ? dagsLoaded[currentNodeCid.toString()] : await client.object.get(currentNodeCid); const linkName = stagingDagNames.pop(); @@ -830,7 +814,9 @@ export const removeFileFromDag = async (rootCid: string, contextPath: string, fi }; export async function removeDagLink(dagCid: string | multiformats.CID, linkName: string) { - if (typeof dagCid === 'string') dagCid = multiformats.CID.parse(dagCid); + if (typeof dagCid === 'string') { + dagCid = multiformats.CID.parse(dagCid); + } if (dagCid.code == rawCode) { throw new Error('raw cid -- not a directory'); @@ -860,7 +846,7 @@ export async function removeDagLink(dagCid: string | multiformats.CID, linkName: } export const renameFileInDag = async (rootCid: string, contextPath: string, linkToRename: string, newName: string) => { - const dagCidsToBeReset = []; + const dagCidsToBeReset: CID[] = []; // CID(String): DAGNode - cached to prevent duplicate calls const dagsLoaded: Record = {}; dagCidsToBeReset.push(CID.parse(rootCid)); @@ -869,8 +855,7 @@ export const renameFileInDag = async (rootCid: string, contextPath: string, link for (let i = 0; i < stagingDagNames.length; i++) { const dagLinkName = stagingDagNames[i]; const containingDagCid = dagCidsToBeReset[i]; - //FIXME containingDag is of type PBNode - const containingDag: any = await client.object.get(containingDagCid); + const containingDag: PBNode = await client.object.get(containingDagCid); if (!containingDag) { throw Error('Failed updating dataset, existing DAG not found'); } @@ -885,9 +870,7 @@ export const renameFileInDag = async (rootCid: string, contextPath: string, link //if context path doesn't exist(update add at DAG root level), the dag won't be cached yet. if (!dagsLoaded.length) { - //FIXME rootDag is of type PBNode - const rootDag = await client.object.get(dagCidsToBeReset[0]); - dagsLoaded[rootCid] = rootDag; + dagsLoaded[rootCid] = await client.object.get(dagCidsToBeReset[0]); } //establishing the tail dag that's being updated @@ -903,8 +886,7 @@ export const renameFileInDag = async (rootCid: string, contextPath: string, link let lastUpdatedCid = updatedTailNodeCid; while (dagCidsToBeReset.length) { const currentNodeCid = dagCidsToBeReset.pop(); - //FIXME should be PBLink - const currentNode: any = dagsLoaded[currentNodeCid.toString()] + const currentNode: PBNode = dagsLoaded[currentNodeCid.toString()] ? dagsLoaded[currentNodeCid.toString()] : await client.object.get(currentNodeCid); const linkName = stagingDagNames.pop(); @@ -946,7 +928,9 @@ export const moveFileInDag = async (rootCid: string, contextPath: string, fileTo }; export async function renameDagLink(dagCid: string | multiformats.CID, linkName: string, newName: string) { - if (typeof dagCid === 'string') dagCid = multiformats.CID.parse(dagCid); + if (typeof dagCid === 'string') { + dagCid = multiformats.CID.parse(dagCid); + } if (dagCid.code == rawCode) { throw new Error('raw cid -- not a directory'); @@ -999,8 +983,8 @@ export async function getExternalCidSizeAndType(cid: string) { const { Data } = dagPb.decode(block); const unixFs = UnixFS.unmarshal(Data); - let isDirectory; - let size; + let isDirectory: boolean; + let size: number; const isDir = dirTypes.includes(unixFs?.type); if (code === 0x70 && isDir) { //0x70 === dag-pb @@ -1010,12 +994,14 @@ export async function getExternalCidSizeAndType(cid: string) { isDirectory = false; const fSize = unixFs.fileSize(); if (fSize) { - size = fSize; + size = Number(fSize); } else { - size = unixFs.blockSizes.reduce((a, b) => a + b, BigInt(0)); + size = unixFs.blockSizes.map(Number).reduce((a, b) => a + b, 0); } } - if (isDirectory !== undefined && size !== undefined) return { isDirectory, size }; + if (size !== undefined) { + return { isDirectory, size }; + } throw new Error(`Failed to resolve CID or determine file size/type for cid: ${cid}`); } catch (error) { logger.error({ fn: 'getExternalCidSizeAndType', error }, `[getExternalCidSizeAndType]Error: ${error.message}`); @@ -1048,8 +1034,7 @@ export function strIsCid(cid: string) { const cidObj = multiformats.CID.parse(cid); const validCid = multiformats.CID.asCID(cidObj); - if (!!validCid) return true; - return false; + return !!validCid; } catch (e) { return false; } @@ -1113,16 +1098,14 @@ export type BlockMetadata = { CumulativeSize: number; }; export async function getCidMetadata(cid: string, external?: boolean): Promise { - /* - ** External handling should be added once our pub node is properly configured - */ try { - // const metadata: BlockMetadata = await client.block.stat(CID.parse(cid), { timeout: INTERNAL_IPFS_TIMEOUT }); - const metadata: BlockMetadata = await client.object.stat(CID.parse(cid), { timeout: INTERNAL_IPFS_TIMEOUT }); - // let localResolver = process.env.IPFS_RESOLVER_OVERRIDE; - // if (localResolver.endsWith('/ipfs')) localResolver = localResolver.slice(0, -5); - // const url = `${localResolver}/api/v0/object/stat?arg=${cid}`; - // const metadata = await axios.get(url).then((res) => res.data); + let metadata: BlockMetadata; + if (external) { + metadata = await publicIpfs.object.stat(CID.parse(cid), { timeout: EXTERNAL_IPFS_TIMEOUT }); + } else { + metadata = await client.object.stat(CID.parse(cid), { timeout: INTERNAL_IPFS_TIMEOUT }); + } + return metadata; } catch (e) { logger.trace({ fn: 'getCidMetadata', cid, e }, 'Failed to get CID metadata'); diff --git a/desci-server/src/services/repoService.ts b/desci-server/src/services/repoService.ts index 35b9bf030..609400c7b 100644 --- a/desci-server/src/services/repoService.ts +++ b/desci-server/src/services/repoService.ts @@ -17,7 +17,7 @@ class RepoService { baseUrl: string; - defaultTimeoutInMilliseconds: 5000; + defaultTimeoutInMilliseconds = 5000; timeoutErrorMessage = 'Timeout: Call to Repo service timed out'; constructor() { @@ -105,18 +105,28 @@ class RepoService { logger.warn({ arg }, 'Attempt to retrieve draft manifest for empty UUID'); return null; } - logger.info({ arg }, 'Retrieve Draft Document'); try { + // const controller = new AbortController(); + // setTimeout(() => { + // logger.trace('Abort request'); + // controller.abort(); + // }, arg.timeout ?? this.defaultTimeoutInMilliseconds); + logger.trace( + { timout: arg.timeout || this.defaultTimeoutInMilliseconds, uuid: arg.uuid, documentId: arg.documentId }, + '[getDraftDocument]', + ); const response = await this.#client.get>( `${this.baseUrl}/v1/nodes/documents/draft/${arg.uuid}?documentId=${arg.documentId}`, { headers: { 'x-api-remote-traceid': (als.getStore() as any)?.traceId, }, - timeout: arg.timeout ?? this.defaultTimeoutInMilliseconds, + // timeout: arg.timeout ?? this.defaultTimeoutInMilliseconds, + signal: AbortSignal.timeout(arg.timeout ?? this.defaultTimeoutInMilliseconds), // controller.signal, timeoutErrorMessage: this.timeoutErrorMessage, }, ); + logger.info({ arg }, 'Retrieve Draft Document'); if (response.status === 200 && response.data.ok) { return response.data.document; } else { @@ -141,7 +151,6 @@ class RepoService { documentId?: string | DocumentId; timeout?: number; }) { - logger.info({ uuid }, 'Retrieve Draft Document'); try { const response = await this.getDraftDocument({ uuid, timeout, documentId }); return response ? response.manifest : null; diff --git a/desci-server/src/templates/emails/ContributorInvite.tsx b/desci-server/src/templates/emails/ContributorInvite.tsx index d110e4e7b..6bf3c28a3 100644 --- a/desci-server/src/templates/emails/ContributorInvite.tsx +++ b/desci-server/src/templates/emails/ContributorInvite.tsx @@ -55,19 +55,20 @@ export const ContributorInvite = ({ You've been invited as a contributor! - {inviter} has added you as a contributor to {!!nodeTitle && {nodeTitle}} + {inviter} has added you as a co-author to {!!nodeTitle && {nodeTitle}} {!!!nodeTitle ? fallbackTitle : ''}. {newUser ? NEW_USER_TEXT : EXISTING_USER_TEXT} -
+