From 1980bd2b29d4f2ed1b74a1fb71f24ca6d8d6cf16 Mon Sep 17 00:00:00 2001 From: Dylan Owen Date: Thu, 9 May 2024 14:13:39 -0700 Subject: [PATCH 1/6] Version 3 (#1) --- .github/funding.yml | 1 - .gitignore | 15 + .prettierrc.json | 3 - LICENSE | 21 + package-lock.json | 2910 +++++++++++++++++ package.json | 23 + readme.md | 260 +- scripts/build.js | 181 + scripts/publish.sh | 21 + spec/graphql-multipart-request-v3.md | 783 +++++ spec/metadata.json | 17 + ...raphql-multipart-request-middleware.sketch | Bin 57071 -> 0 bytes ...c-graphql-multipart-request-middleware.svg | 85 - 13 files changed, 3984 insertions(+), 336 deletions(-) delete mode 100644 .github/funding.yml create mode 100644 .gitignore delete mode 100644 .prettierrc.json create mode 100644 LICENSE create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 scripts/build.js create mode 100755 scripts/publish.sh create mode 100644 spec/graphql-multipart-request-v3.md create mode 100644 spec/metadata.json delete mode 100644 sync-vs-async-graphql-multipart-request-middleware.sketch delete mode 100644 sync-vs-async-graphql-multipart-request-middleware.svg diff --git a/.github/funding.yml b/.github/funding.yml deleted file mode 100644 index 4c5a7a0..0000000 --- a/.github/funding.yml +++ /dev/null @@ -1 +0,0 @@ -github: jaydenseric diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..79b8cb7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +# Personal Configs +.DS_Store + +# node directories +node_modules +*.tsbuildinfo + +# build folder +build + +# IntelliJ +*.iml +*.ipr +*.iws +.idea diff --git a/.prettierrc.json b/.prettierrc.json deleted file mode 100644 index d2504b4..0000000 --- a/.prettierrc.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "proseWrap": "never" -} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..64bdd4d --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Workday, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..4ecfbfc --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2910 @@ +{ + "name": "graphql-multipart-request-spec", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "graphql-multipart-request-spec", + "devDependencies": { + "chokidar": "^3.6.0", + "live-server": "^1.2.2", + "prettier": "^3.2.5", + "rimraf": "^5.0.5", + "spec-md": "^3.1.0" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/git@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/git@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/gitaccepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/gitansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha1-MYPjj66aZdfLXlOUXNWJfQJgoGo=", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/gitansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/gitanymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/apache-crypt": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/gitapache-crypt/-/apache-crypt-1.2.6.tgz", + "integrity": "sha512-072WetlM4blL8PREJVeY+WHiUh1R5VNt2HfceGS8aKqttPHcmqE5pkKuXPz/ULmJOFkc8Hw3kfKl6vy7Qka6DA==", + "dev": true, + "dependencies": { + "unix-crypt-td-js": "^1.1.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/apache-md5": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/gitapache-md5/-/apache-md5-1.1.8.tgz", + "integrity": "sha512-FCAJojipPn0bXjuEpjOOOMN8FZDkxfWWp4JGN9mifU2IhxvKyXZYqpzPHdnTSUpmPDy+tsslB6Z1g+Vg6nVbYA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/gitarr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/gitarr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha1-NgSLv/TntH4TZkQxbJlmnqWukfE=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/gitarr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/gitarray-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gitassign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/async-each": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/gitasync-each/-/async-each-1.0.6.tgz", + "integrity": "sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==", + "dev": true + }, + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/gitatob/-/atob-2.1.2.tgz", + "integrity": "sha1-bZUX654DDSQ2ZmZR6GvZ9vE1M8k=", + "dev": true, + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/gitbalanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha1-6D46fj8wCzTLnYf2FfoMvzV2kO4=", + "dev": true + }, + "node_modules/base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/gitbase/-/base-0.11.2.tgz", + "integrity": "sha1-e95c7RRbbVUakNuH+DxVi060io8=", + "dev": true, + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gitdefine-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/gitbasic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha1-uZgnm/R844NEtPPPkW1Gebv1Hjo=", + "dev": true, + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/gitbatch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", + "dev": true + }, + "node_modules/bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/gitbcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/gitbinary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/gitbindings/-/bindings-1.5.0.tgz", + "integrity": "sha1-EDU8npRTNLwFEabZCzj7x8nFBN8=", + "dev": true, + "optional": true, + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/gitbrace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha1-HtxFng8MVISG7Pn8mfIiE2S5oK4=", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gitbraces/-/braces-3.0.2.tgz", + "integrity": "sha1-NFThpGLujVmeI23zNs2epPiv4Qc=", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gitcache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha1-Cn9GQWgxyLZi7jb+TnxZ129marI=", + "dev": true, + "dependencies": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/gitchokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "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/class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/gitclass-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha1-+TNprouafOAv1B+q0MqDAzGQxGM=", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/gitdefine-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-descriptor": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/gitis-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gitcollection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/gitcolor-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/gitcolor-name/-/color-name-1.1.4.tgz", + "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=", + "dev": true + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/gitcolors/-/colors-1.4.0.tgz", + "integrity": "sha1-xQSRR51MG9rtLJztMs98fcI2D3g=", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/component-emitter": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/gitcomponent-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", + "dev": true + }, + "node_modules/connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/gitconnect/-/connect-3.7.0.tgz", + "integrity": "sha1-XUk0iRDKpeB6AYALAw0MNfIEhPg=", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/gitcopy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/gitcore-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha1-pgQtNjTCsn6TKPg3uWX6yDgI24U=", + "dev": true + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/gitcors/-/cors-2.8.5.tgz", + "integrity": "sha1-6sEdpRWS3Ya58G9uesKTs9+HXSk=", + "dev": true, + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/gitcross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha1-9zqFudXUHQRVUcF34ogtSshXKKY=", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/gitdebug/-/debug-2.6.9.tgz", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/gitdecode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/gitdefine-property/-/define-property-2.0.2.tgz", + "integrity": "sha1-1Flono1lS6d+AqgX+HENcCyxbp0=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/gitdepd/-/depd-2.0.0.tgz", + "integrity": "sha1-tpYWPMdXVg0JzyLMj60Vcbeedt8=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gitdestroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/gitduplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha1-Or5DrvODX4rgd9E23c4PJ2sEAOY=", + "dev": true + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/giteastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha1-aWzi7Aqg5uqTo5f/zySqeEDIJ8s=", + "dev": true + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/gitee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/gitemoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha1-hAyIA7DYBH9P8M+WMXazLU7z7XI=", + "dev": true + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/gitencodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/gitescape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/gitetag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-stream": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/gitevent-stream/-/event-stream-3.3.4.tgz", + "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", + "dev": true, + "dependencies": { + "duplexer": "~0.1.1", + "from": "~0", + "map-stream": "~0.1.0", + "pause-stream": "0.0.11", + "split": "0.3", + "stream-combiner": "~0.0.4", + "through": "~2.3.1" + } + }, + "node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/gitexpand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/gitdefine-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/gitextend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-descriptor": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/gitis-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/expand-brackets/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/gitis-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gitextend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/gitextglob/-/extglob-2.0.4.tgz", + "integrity": "sha1-rQD+TcYSqSMuhxhxHcXLWrAoVUM=", + "dev": true, + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gitdefine-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/gitextend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/gitis-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/gitfaye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha1-fw2Sdc/dhqHJY9yLZfzEUe3Lsdo=", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gitfile-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha1-VTp7hEb/b2hDWcRF8eN6BdrMM90=", + "dev": true, + "optional": true + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/gitfill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha1-GRmmp8df44ssfHflGYU12prN2kA=", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/gitfinalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha1-t+fQAP/RGTjQ/bBTUG9uur6fWH0=", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/gitfor-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/gitforeground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/gitfragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/gitfresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/gitfrom/-/from-0.1.7.tgz", + "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/gitfsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/gitfunction-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true + }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/gitget-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob": { + "version": "10.3.12", + "resolved": "https://registry.npmjs.org/gitglob/-/glob-10.3.12.tgz", + "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.6", + "minimatch": "^9.0.1", + "minipass": "^7.0.4", + "path-scurry": "^1.10.2" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/gitglob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha1-hpgyxYA0/mikCTwX3BXoNA2EAcQ=", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/gitgraceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/githas-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/githas-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/gitis-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/gitkind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/gitkind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/githasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-auth": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/githttp-auth/-/http-auth-3.1.3.tgz", + "integrity": "sha1-lFz63WZSHq+PfISRPTd9exXyTjE=", + "dev": true, + "dependencies": { + "apache-crypt": "^1.1.2", + "apache-md5": "^1.0.6", + "bcryptjs": "^2.3.0", + "uuid": "^3.0.0" + }, + "engines": { + "node": ">=4.6.1" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/githttp-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/gitstatuses/-/statuses-2.0.1.tgz", + "integrity": "sha1-VcsADM8dSHKL0jxoWgY5mM8aG2M=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/githttp-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/gitinherits/-/inherits-2.0.4.tgz", + "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w=", + "dev": true + }, + "node_modules/is-accessor-descriptor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gitis-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz", + "integrity": "sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/gitis-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha1-6h9/O4DwZCNug0cPhsCcJU+0Wwk=", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/gitis-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha1-76ouqdqg16suoTqXsritUf776L4=", + "dev": true + }, + "node_modules/is-data-descriptor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gitis-data-descriptor/-/is-data-descriptor-1.0.1.tgz", + "integrity": "sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-descriptor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/gitis-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gitis-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ=", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/gitis-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/gitis-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha1-8Rb4Bk/pCz94RKOJl8C3UFEmnx0=", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gitis-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha1-ZPYeQsu7LuwgcanawLKLoeZdUIQ=", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/gitis-number/-/is-number-7.0.0.tgz", + "integrity": "sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss=", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/gitis-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha1-LBY7P6+xtgbZ0Xko8FwqHDjgdnc=", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/gitis-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha1-0YUOuXkezRjmGCzhKjDzlmNLsZ0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/gitis-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gitisarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/gitisexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/gitisobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/gitjackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/gitkind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha1-B8BQNKbDSfoG4k+jWqdttFgM5N0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/gitlive-server/-/live-server-1.2.2.tgz", + "integrity": "sha512-t28HXLjITRGoMSrCOv4eZ88viHaBVIjKjdI5PO92Vxlu+twbk6aE0t7dVIaz6ZWkjPilYFV6OSdMYl9ybN2B4w==", + "dev": true, + "dependencies": { + "chokidar": "^2.0.4", + "colors": "1.4.0", + "connect": "^3.6.6", + "cors": "latest", + "event-stream": "3.3.4", + "faye-websocket": "0.11.x", + "http-auth": "3.1.x", + "morgan": "^1.9.1", + "object-assign": "latest", + "opn": "latest", + "proxy-middleware": "latest", + "send": "latest", + "serve-index": "^1.9.1" + }, + "bin": { + "live-server": "live-server.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/gitanymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha1-vLJLTzeTTZqnrBe0ra+J58du8us=", + "dev": true, + "dependencies": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "node_modules/live-server/node_modules/anymatch/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/gitnormalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/gitbinary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha1-WYr+VHVbKGilMw0q/51Ou1Mgm2U=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/gitbraces/-/braces-2.3.2.tgz", + "integrity": "sha1-WXn9PxTNUxVl5fot8av/8d+u5yk=", + "dev": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/gitchokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha1-gEs6e2qZNYw8XGHnHYco8EHP+Rc=", + "deprecated": "Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.", + "dev": true, + "dependencies": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "optionalDependencies": { + "fsevents": "^1.2.7" + } + }, + "node_modules/live-server/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/gitextend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/gitfill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/gitfsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha1-8yXLBFVZJCi88Rs4M3DvcOO/zDg=", + "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/live-server/node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/gitglob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/live-server/node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/gitis-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gitis-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "dependencies": { + "binary-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/gitis-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/gitis-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/gitkind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/live-server/node_modules/readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/gitreaddirp/-/readdirp-2.2.1.tgz", + "integrity": "sha1-DodiKjMlqjPokihcr4tOhGUppSU=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/live-server/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/gitto-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lru-cache": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/gitlru-cache/-/lru-cache-10.2.2.tgz", + "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/gitmap-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/gitmap-stream/-/map-stream-0.1.0.tgz", + "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", + "dev": true + }, + "node_modules/map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gitmap-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/gitmicromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha1-cIWbyVyYQJUvNZoGij/En57PrCM=", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/gitbraces/-/braces-2.3.2.tgz", + "integrity": "sha1-WXn9PxTNUxVl5fot8av/8d+u5yk=", + "dev": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/gitextend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/gitfill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/gitextend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/gitis-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/gitis-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/gitkind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/gitto-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/gitmime/-/mime-1.6.0.tgz", + "integrity": "sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE=", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/gitmime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/gitmime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/gitminimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/gitminipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/gitmixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha1-ESC0PcNZp4Xc5ltVuC4lfM9HlWY=", + "dev": true, + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/morgan": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/gitmorgan/-/morgan-1.10.0.tgz", + "integrity": "sha1-CRd4q8H8R801CYJGU9rh+qtrF9c=", + "dev": true, + "dependencies": { + "basic-auth": "~2.0.1", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-finished": "~2.3.0", + "on-headers": "~1.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/gitms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/nan": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/gitnan/-/nan-2.19.0.tgz", + "integrity": "sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==", + "dev": true, + "optional": true + }, + "node_modules/nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/gitnanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha1-uHqKpPwN6P5r6IiVs4mD/yZb0Rk=", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/gitnegotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/gitnormalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha1-Dc1p/yOhybEf0JeDFmRKA4ghamU=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/gitobject-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/gitobject-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "dependencies": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/gitdefine-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-descriptor": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/gitis-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-copy/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/gitkind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gitobject-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/gitobject.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/giton-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/giton-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha1-dysK5qqlJcOZ5Imt+tkMQD6zwo8=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/opn": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gitopn/-/opn-6.0.0.tgz", + "integrity": "sha1-PFsNtnbV+X2hIz0e1C0YK8WifS0=", + "deprecated": "The package has been renamed to `open`", + "dev": true, + "dependencies": { + "is-wsl": "^1.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/gitparseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha1-naGee+6NEt/wUT7Vt2lXeTvC6NQ=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/gitpascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/gitpath-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gitpath-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/gitpath-key/-/path-key-3.1.1.tgz", + "integrity": "sha1-WB9q3mWMu6ZaDTOA3ndTKVBU83U=", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/gitpath-scurry/-/path-scurry-1.10.2.tgz", + "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/pause-stream": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/gitpause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", + "dev": true, + "dependencies": { + "through": "~2.3" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/gitpicomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/gitposix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/prettier": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/gitprettier/-/prettier-3.2.5.tgz", + "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/prismjs": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/gitprismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/gitprocess-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha1-eCDZsWEgzFXKmud5JoCufbptf+I=", + "dev": true + }, + "node_modules/proxy-middleware": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/gitproxy-middleware/-/proxy-middleware-0.15.0.tgz", + "integrity": "sha1-o/3xvvtzD5UZZYcqwvYHTGFHelY=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/gitrange-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha1-PPNwI9GZ4cJNGlW4SADC8+ZGgDE=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/gitreadable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/gitreaddirp/-/readdirp-3.6.0.tgz", + "integrity": "sha1-dKNwvYVxFuJFspzJc0DNQxoCpsc=", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/gitregex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha1-H07OJ+ALC2XgJHpoEOaoXYOldSw=", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/gitremove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "node_modules/repeat-element": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/gitrepeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha1-vmgVIIR6tYx1aKx1+/rSjtQtOek=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/gitrepeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/gitresolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "deprecated": "https://github.com/lydell/resolve-url#deprecated", + "dev": true + }, + "node_modules/ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/gitret/-/ret-0.1.15.tgz", + "integrity": "sha1-uKSCXVvbH8P29Twrwz+BOIaBx7w=", + "dev": true, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/rimraf": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/gitrimraf/-/rimraf-5.0.5.tgz", + "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", + "dev": true, + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/gitsafe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=", + "dev": true + }, + "node_modules/safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/gitsafe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "dependencies": { + "ret": "~0.1.10" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/gitsend/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/gitms/-/ms-2.1.3.tgz", + "integrity": "sha1-V0yBOM4dK1hh8LRFedut1gxmFbI=", + "dev": true + }, + "node_modules/send/node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/giton-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/gitstatuses/-/statuses-2.0.1.tgz", + "integrity": "sha1-VcsADM8dSHKL0jxoWgY5mM8aG2M=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/gitserve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/gitdepd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/githttp-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/gitinherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/gitsetprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha1-0L2FU2iHtv58DYGMuWLZ2RxU5lY=", + "dev": true + }, + "node_modules/set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/gitset-value/-/set-value-2.0.1.tgz", + "integrity": "sha1-oY1AUw5vB95CKMfe/kInr4ytAFs=", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/gitextend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/gitis-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gitsetprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha1-ZsmiSnP5/CjL5msJ/tPTPcrxtCQ=", + "dev": true + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/gitshebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha1-zNCvT4g1+9wmW4JGGq8MNmY/NOo=", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/gitshebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha1-rhbxZE2HPsrYQ7AwexQzYtTEIXI=", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/gitsignal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/gitsnapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha1-ZJIufFZbDhQgS6GqfWlkJ40lGC0=", + "dev": true, + "dependencies": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/gitsnapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha1-bBdfhv8UvbByRWPo88GwIaKGhTs=", + "dev": true, + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gitdefine-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/gitsnapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha1-+VZHlIbyrNeXAGk/b3uAXkWrVuI=", + "dev": true, + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/gitkind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/gitdefine-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/gitextend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-descriptor": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/gitis-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/snapdragon/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/gitis-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/gitsource-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/gitsource-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha1-GQhmvs51U+H48mei7oLGBrVQmho=", + "dev": true, + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/gitsource-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha1-CvZmBadFpaL5HPG7+KevvCg97FY=", + "dev": true + }, + "node_modules/spec-md": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/gitspec-md/-/spec-md-3.1.0.tgz", + "integrity": "sha512-h4/Pc+ICB+q8cXKTyy8f5JJHSQRNy1oh05P/vTrq+qIV2fLmEaalwpZMRYMzlq/g+qxnIp/hywGGYA3rpefYmA==", + "dev": true, + "dependencies": { + "prismjs": "^1.23.0" + }, + "bin": { + "spec-md": "bin/spec-md" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/split": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/gitsplit/-/split-0.3.3.tgz", + "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", + "dev": true, + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/gitsplit-string/-/split-string-3.1.0.tgz", + "integrity": "sha1-fLCd2jqGWFcFxks5pkZgOGguj+I=", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/gitstatic-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/gitdefine-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-descriptor": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/gitis-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/gitstatuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stream-combiner": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/gitstream-combiner/-/stream-combiner-0.0.4.tgz", + "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", + "dev": true, + "dependencies": { + "duplexer": "~0.1.1" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/gitstring_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/gitstring-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/gitstring-width/-/string-width-4.2.3.tgz", + "integrity": "sha1-JpxxF9J7Ba0uU2gwqOyJXvnG0BA=", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/gitansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha1-CCyyyJyf6GWaMRpTvWpNxTAdswQ=", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/gitemoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha1-6Bj9ac5cz8tARZT4QpY79TFkzDc=", + "dev": true + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/gitstrip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha1-nibGPTD1NEPpSJSVshBdN7Z6hdk=", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/gitstrip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/gitstrip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha1-nibGPTD1NEPpSJSVshBdN7Z6hdk=", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/gitansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha1-CCyyyJyf6GWaMRpTvWpNxTAdswQ=", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/gitthrough/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "node_modules/to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/gitto-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-object-path/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/gitkind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gitto-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha1-E8/dmzNlUvMLUfM6iuG0Knp1mc4=", + "dev": true, + "dependencies": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/gitto-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha1-FkjESq58jZiKMmAY7XL1tN0DkuQ=", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gittoidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gitunion-value/-/union-value-1.0.1.tgz", + "integrity": "sha1-C2/nuDWuzaYcbqTU8CwUIh4QmEc=", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/union-value/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/gitis-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unix-crypt-td-js": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/gitunix-crypt-td-js/-/unix-crypt-td-js-1.1.4.tgz", + "integrity": "sha1-SRLfrRyK630g+go55MMZGMHV1d0=", + "dev": true + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gitunpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gitunset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "dependencies": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/githas-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/gitisobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/githas-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gitupath/-/upath-1.2.0.tgz", + "integrity": "sha1-j2bbzVWog6za5ECK+LA1pQRMGJQ=", + "dev": true, + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/giturix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "deprecated": "Please see https://github.com/lydell/urix#deprecated", + "dev": true + }, + "node_modules/use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/gituse/-/use-3.1.1.tgz", + "integrity": "sha1-1QyMrHmhn7wg8pEfVuuXP04QBw8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/gitutil-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gitutils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/gituuid/-/uuid-3.4.0.tgz", + "integrity": "sha1-sj5DWK+oogL+ehAK8fX4g/AgB+4=", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/gitvary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/gitwebsocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha1-ia1Slbv2S0gKvLox5JU6ynBvV2A=", + "dev": true, + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/gitwebsocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha1-f4RzvIOd/YdgituV1+sHUhFXikI=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/gitwhich/-/which-2.0.2.tgz", + "integrity": "sha1-fGqN0KY2oDJ+ELWckobu6T8/UbE=", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/gitwrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/gitwrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha1-Z+FFz/UQpqaYS98RUpEdadLrnkM=", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/gitansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha1-CCyyyJyf6GWaMRpTvWpNxTAdswQ=", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/gitansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/gitemoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha1-6Bj9ac5cz8tARZT4QpY79TFkzDc=", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/gitstring-width/-/string-width-4.2.3.tgz", + "integrity": "sha1-JpxxF9J7Ba0uU2gwqOyJXvnG0BA=", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/gitstrip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha1-nibGPTD1NEPpSJSVshBdN7Z6hdk=", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..ee12bd3 --- /dev/null +++ b/package.json @@ -0,0 +1,23 @@ +{ + "name": "graphql-multipart-request-spec", + "private": true, + "scripts": { + "build": "node scripts/build.js", + "dev": "node scripts/build.js --watch", + "release": "npm run build", + "publish": "npm run release && ./scripts/publish.sh", + "clean": "rimraf build" + }, + "type": "module", + "devDependencies": { + "chokidar": "^3.6.0", + "live-server": "^1.2.2", + "prettier": "^3.2.5", + "rimraf": "^5.0.5", + "spec-md": "^3.1.0" + }, + "prettier": { + "proseWrap": "always", + "trailingComma": "none" + } +} diff --git a/readme.md b/readme.md index 54067a3..9cfa3c3 100644 --- a/readme.md +++ b/readme.md @@ -1,259 +1,25 @@ -# GraphQL multipart request specification +# GraphQL Multipart Request Spec -An interoperable [multipart form](https://tools.ietf.org/html/rfc7578) field structure for GraphQL requests, used by various file upload client/server implementations. +This specification describes how to attach additional files to a GraphQL request using `multipart/form-data`. The intent +is to be the continuation of https://github.com/jaydenseric/graphql-multipart-request-spec starting at Version 3 and to +support backwards compatibility with Version 2 for both clients and servers. -It’s possible to implement: +## Example -- Nesting files anywhere within operations (usually in `variables`). -- Operation batching. -- File deduplication. -- File upload streams in resolvers. -- Aborting file uploads in resolvers. +```http +POST https://example.com/graphql +content-type: multipart/form-data; boundary=--boundary -![Sync vs async GraphQL multipart request middleware](sync-vs-async-graphql-multipart-request-middleware.svg) - -## Multipart form field structure - -An “operations object” is an [Apollo GraphQL POST request](https://www.apollographql.com/docs/apollo-server/workflow/requests/#post-requests) (or array of requests if batching). An “operations path” is an [`object-path`](https://npm.im/object-path) string to locate a file within an operations object. - -So operations can be resolved while the files are still uploading, the fields are ordered: - -1. `operations`: A JSON encoded operations object with files replaced with `null`. -2. `map`: A JSON encoded map of where files occurred in the operations. For each file, the key is the file multipart form field name and the value is an array of operations paths. -3. File fields: Each file extracted from the operations object with a unique, arbitrary field name. - -## Examples - -### Single file - -#### Operations - -```js -{ - query: ` - mutation($file: Upload!) { - singleUpload(file: $file) { - id - } - } - `, - variables: { - file: File // a.txt - } -} -``` - -#### cURL request - -```shell -curl localhost:3001/graphql \ - -F operations='{ "query": "mutation ($file: Upload!) { singleUpload(file: $file) { id } }", "variables": { "file": null } }' \ - -F map='{ "0": ["variables.file"] }' \ - -F 0=@a.txt -``` - -#### Request payload - -``` ---------------------------cec8e8123c05ba25 -Content-Disposition: form-data; name="operations" - -{ "query": "mutation ($file: Upload!) { singleUpload(file: $file) { id } }", "variables": { "file": null } } ---------------------------cec8e8123c05ba25 -Content-Disposition: form-data; name="map" - -{ "0": ["variables.file"] } ---------------------------cec8e8123c05ba25 -Content-Disposition: form-data; name="0"; filename="a.txt" -Content-Type: text/plain - -Alpha file content. - ---------------------------cec8e8123c05ba25-- -``` - -### File list - -#### Operations - -```js -{ - query: ` - mutation($files: [Upload!]!) { - multipleUpload(files: $files) { - id - } - } - `, - variables: { - files: [ - File, // b.txt - File // c.txt - ] - } -} -``` - -#### cURL request - -```shell -curl localhost:3001/graphql \ - -F operations='{ "query": "mutation($files: [Upload!]!) { multipleUpload(files: $files) { id } }", "variables": { "files": [null, null] } }' \ - -F map='{ "0": ["variables.files.0"], "1": ["variables.files.1"] }' \ - -F 0=@b.txt \ - -F 1=@c.txt -``` - -#### Request payload - -``` ---------------------------ec62457de6331cad -Content-Disposition: form-data; name="operations" - -{ "query": "mutation($files: [Upload!]!) { multipleUpload(files: $files) { id } }", "variables": { "files": [null, null] } } ---------------------------ec62457de6331cad -Content-Disposition: form-data; name="map" - -{ "0": ["variables.files.0"], "1": ["variables.files.1"] } ---------------------------ec62457de6331cad -Content-Disposition: form-data; name="0"; filename="b.txt" -Content-Type: text/plain - -Bravo file content. - ---------------------------ec62457de6331cad -Content-Disposition: form-data; name="1"; filename="c.txt" -Content-Type: text/plain - -Charlie file content. - ---------------------------ec62457de6331cad-- -``` - -### Batching - -#### Operations - -```js -[ - { - query: ` - mutation($file: Upload!) { - singleUpload(file: $file) { - id - } - } - `, - variables: { - file: File, // a.txt - }, - }, - { - query: ` - mutation($files: [Upload!]!) { - multipleUpload(files: $files) { - id - } - } - `, - variables: { - files: [ - File, // b.txt - File, // c.txt - ], - }, - }, -]; -``` - -#### cURL request - -```shell -curl localhost:3001/graphql \ - -F operations='[{ "query": "mutation ($file: Upload!) { singleUpload(file: $file) { id } }", "variables": { "file": null } }, { "query": "mutation($files: [Upload!]!) { multipleUpload(files: $files) { id } }", "variables": { "files": [null, null] } }]' \ - -F map='{ "0": ["0.variables.file"], "1": ["1.variables.files.0"], "2": ["1.variables.files.1"] }' \ - -F 0=@a.txt \ - -F 1=@b.txt \ - -F 2=@c.txt -``` - -#### Request payload - -``` ---------------------------627436eaefdbc285 +--boundary Content-Disposition: form-data; name="operations" -[{ "query": "mutation ($file: Upload!) { singleUpload(file: $file) { id } }", "variables": { "file": null } }, { "query": "mutation($files: [Upload!]!) { multipleUpload(files: $files) { id } }", "variables": { "files": [null, null] } }] ---------------------------627436eaefdbc285 -Content-Disposition: form-data; name="map" +{ "query": "mutation { upload(file: \"fileA\") }" } -{ "0": ["0.variables.file"], "1": ["1.variables.files.0"], "2": ["1.variables.files.1"] } ---------------------------627436eaefdbc285 -Content-Disposition: form-data; name="0"; filename="a.txt" +--boundary +Content-Disposition: form-data; name="fileA"; filename="a.txt" Content-Type: text/plain Alpha file content. ---------------------------627436eaefdbc285 -Content-Disposition: form-data; name="1"; filename="b.txt" -Content-Type: text/plain - -Bravo file content. - ---------------------------627436eaefdbc285 -Content-Disposition: form-data; name="2"; filename="c.txt" -Content-Type: text/plain - -Charlie file content. - ---------------------------627436eaefdbc285-- +--boundary-- ``` - -## Security - -GraphQL server authentication and security mechanisms are beyond the scope of this specification, which only covers a multipart form field structure for GraphQL requests. - -Note that a GraphQL multipart request has the [Content-Type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) `multipart/form-data`; if a browser making such a request determines it meets the criteria for a “[simple request](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests)” as defined in the [Fetch specification](https://fetch.spec.whatwg.org) for the [Cross-Origin Resource Sharing](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) (CORS) protocol, it won’t cause a [CORS preflight request](https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request). GraphQL server authentication and security mechanisms must consider this to prevent [Cross-Site Request Forgery](https://developer.mozilla.org/en-US/docs/Glossary/CSRF) (CSRF) attacks. - -## Implementations - -Pull requests adding either experimental or mature implementations to these lists are welcome! ~~Strikethrough~~ means the project was renamed, deprecated, or no longer supports this spec out of the box (but might via an optional integration). - -### Client - -- [jaydenseric/graphql-react](https://github.com/jaydenseric/graphql-react) (JS: [npm](https://npm.im/graphql-react)) -- [jaydenseric/apollo-upload-client](https://github.com/jaydenseric/apollo-upload-client) (JS: [npm](https://npm.im/apollo-upload-client)) -- [jaydenseric/extract-files](https://github.com/jaydenseric/extract-files) (JS: [npm](https://npm.im/extract-files)) -- [nearform/graphql-hooks](https://github.com/nearform/graphql-hooks) (JS: [npm](https://npm.im/graphql-hooks)) -- [klis87/redux-saga-requests-graphql](https://github.com/klis87/redux-saga-requests/tree/master/packages/redux-saga-requests-graphql) (JS: [npm](https://npm.im/redux-saga-requests-graphql)) -- [imolorhe/altair](https://github.com/imolorhe/altair) (JS: [npm](https://npm.im/altair-static)) -- [haffdata/buoy](https://github.com/haffdata/buoy) (JS: [npm](https://npm.im/@buoy/client)) -- [FormidableLabs/urql](https://github.com/FormidableLabs/urql) (JS: [npm](https://npm.im/@urql/exchange-multipart-fetch)) -- [~~apollo-fetch-upload~~](https://github.com/apollographql/apollo-fetch/tree/master/packages/apollo-fetch-upload) (JS: [npm](https://npm.im/apollo-fetch-upload)) -- [apollographql/apollo-ios](https://github.com/apollographql/apollo-ios) (Swift: [CocoaPods](https://cocoapods.org/pods/Apollo)) -- [apollographql/apollo-android](https://github.com/apollographql/apollo-android) (Java: [Bintray](https://bintray.com/apollographql/android)) -- [zino-app/graphql-flutter](https://github.com/zino-app/graphql-flutter) (Dart: [Pub](https://pub.dev/packages/graphql)) -- [samirelanduk/kirjava](https://github.com/samirelanduk/kirjava) (Python: [PyPi](https://pypi.org/project/kirjava)) -- [DoctorJohn/aiogqlc](https://github.com/DoctorJohn/aiogqlc) (Python: [PyPi](https://pypi.org/project/aiogqlc)) -- [graphql-python/gql](https://github.com/graphql-python/gql) (Python: [PyPi](https://pypi.org/project/gql)) - -### Server - -- [jaydenseric/graphql-upload](https://github.com/jaydenseric/graphql-upload) (JS: [npm](https://npm.im/graphql-upload)) -- [koresar/graphql-upload-minimal](https://github.com/koresar/graphql-upload-minimal) (JS: [npm](https://npm.im/graphql-upload-minimal)) -- [dotansimha/graphql-yoga](https://github.com/dotansimha/graphql-yoga) (JS: [npm](https://npm.im/@graphql-yoga/common)) -- [~~apollographql/apollo-server~~](https://github.com/apollographql/apollo-server) (JS: [npm](https://npm.im/apollo-server)) -- [~~jaydenseric/apollo-upload-server~~](https://github.com/jaydenseric/apollo-upload-server) (JS: [npm](https://npm.im/apollo-upload-server)) -- [99designs/gqlgen](https://github.com/99designs/gqlgen) (Go: [GitHub](https://github.com/99designs/gqlgen)) -- [jpascal/graphql-upload](https://github.com/jpascal/graphql-upload) (Go: [GitHub](https://github.com/jpascal/graphql-upload)) -- [jetruby/apollo_upload_server-ruby](https://github.com/jetruby/apollo_upload_server-ruby) (Ruby: [Gem](https://rubygems.org/gems/apollo_upload_server)) -- [Ecodev/graphql-upload](https://github.com/Ecodev/graphql-upload) (PHP: [Composer](https://packagist.org/packages/ecodev/graphql-upload)) -- [rebing/graphql-laravel](https://github.com/rebing/graphql-laravel) (PHP: [Composer](https://packagist.org/packages/rebing/graphql-laravel)) -- [nuwave/lighthouse](https://github.com/nuwave/lighthouse) (PHP: [Composer](https://packagist.org/packages/nuwave/lighthouse)) -- [overblog/graphql-bundle](https://github.com/overblog/GraphQLBundle) (PHP: [Composer](https://packagist.org/packages/overblog/graphql-bundle)) -- [infinityloop-dev/graphpinator](https://github.com/infinityloop-dev/graphpinator) (PHP: [Composer](https://packagist.org/packages/infinityloop-dev/graphpinator)) -- [lmcgartland/graphene-file-upload](https://github.com/lmcgartland/graphene-file-upload) (Python: [PyPi](https://pypi.org/project/graphene-file-upload)) -- [strawberry-graphql/strawberry](https://github.com/strawberry-graphql/strawberry) (Python: [PyPi](https://pypi.org/project/strawberry-graphql)) -- [graphql-java-kickstart/graphql-java-servlet](https://github.com/graphql-java-kickstart/graphql-java-servlet) (Java: [Maven](https://mvnrepository.com/artifact/com.graphql-java/graphql-java-servlet)) -- [ChilliCream/hotchocolate](https://github.com/ChilliCream/hotchocolate) (C#: [NuGet](https://www.nuget.org/packages/HotChocolate)) -- [async-graphql/async-graphql](https://github.com/async-graphql/async-graphql) (Rust: [Crates](https://crates.io/crates/async-graphql)) diff --git a/scripts/build.js b/scripts/build.js new file mode 100644 index 0000000..17578af --- /dev/null +++ b/scripts/build.js @@ -0,0 +1,181 @@ +import { existsSync, mkdirSync } from "node:fs"; +import { readdir, readFile, writeFile } from "node:fs/promises"; +import path from "path"; +import process from "process"; +import { fileURLToPath } from "url"; + +import chokidar from "chokidar"; +import liveServer from "live-server"; +import specmd from "spec-md"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const rootFolder = path.resolve(__dirname, ".."); +const specFolder = path.resolve(rootFolder, "spec"); +const buildFolder = path.resolve(rootFolder, "build"); + +const metadataPath = path.resolve(specFolder, "metadata.json"); + +let metadata = readMetadata(); +let specPaths = refreshSpecPaths(); + +// make sure our build folder exists +if (!existsSync(buildFolder)) { + mkdirSync(buildFolder); +} + +// run a full build +(async function() { + await Promise.all((await specPaths).map(async specPath => await buildSpec(specPath, await metadata))); +})().catch((error) => logError("Full Build", error)); + +// start our watcher +if (process.argv.length > 1 && process.argv.reduce((acc, argv) => acc || argv === "--watch" || argv === "-w", false)) { + chokidar.watch(specFolder, { ignoreInitial: true }) + .on("all", (event, eventPath) => { + switch (path.extname(eventPath)) { + case ".md": + (async function() { + process.stderr.write(`Change Detected: ${path.relative(rootFolder, eventPath)} @ ${event}\n`); + if (event === "add" || event === "unlink") { + process.stderr.write("Refreshing Specs\n"); + specPaths = refreshSpecPaths(); + } + if (event !== "unlink") { + await buildSpec(eventPath, await metadata); + } + })().catch((error) => { + logError(`${path.relative(rootFolder, eventPath)}:${event}`, error); + }); + break; + case ".json": + (async function() { + process.stderr.write(`Change Detected: ${path.relative(rootFolder, eventPath)} @ ${event}\n`); + metadata = readMetadata(); + await Promise.all( + (await specPaths) + .map(async specPath => await buildSpec(specPath, await metadata)) + ); + })().catch((error) => { + logError(`${path.relative(rootFolder, eventPath)}:${event}`, error); + }); + break; + } + }); + + liveServer.start({ + host: "localhost", + root: buildFolder, + open: false, + logLevel: 2 + }); +} + +async function readMetadata() { + return JSON.parse(await readFile(metadataPath)); +} + +async function refreshSpecPaths() { + const specPaths = (await readdir(specFolder)) + .filter(file => path.extname(file) === ".md") + .reduce((results, specFile) => { + const version = /v(\d+)/.exec(specFile); + if (version != null) { + results.push({ + version: parseInt(version[1]), + specPath: path.resolve(specFolder, specFile), + basename: path.basename(specFile, ".md") + }); + } + return results; + }, []) + .sort(({ version: a }, { version: b }) => b - a); + + let latest = true; + const specsTable = specPaths.map(({ version, basename }) => { + const row = ` + ${(latest) ? "Latest Release" : ""} + Version ${version} + `; + latest = false; + return row; + }).join("\n"); + + const indexHtml = ` + + GraphQL Multipart Request Specification Versions + + + +

GraphQL Multipart Request

+ + ${specsTable} +
+ + +`; + + const indexPath = path.resolve(buildFolder, "index.html"); + await writeFile(indexPath, indexHtml); + process.stderr.write(`Built ${path.relative(rootFolder, indexPath)}\n`); + + return specPaths + .map(({ specPath }) => specPath); +} + +async function buildSpec(specPath, options) { + try { + const outputPath = path.resolve(buildFolder, `${path.basename(specPath, ".md")}.html`); + const result = specmd.html(specPath, options); + await writeFile(outputPath, result); + process.stderr.write(`Built ${path.relative(rootFolder, specPath)} -> ${path.relative(rootFolder, outputPath)}\n`); + + return Promise.resolve(); + } catch (error) { + return Promise.reject(error); + } +} + +function logError(context, error) { + process.stderr.write(`${context}\n`); + process.stderr.write(error.location ? error.message : (error.stack || error) + "\n"); +} + diff --git a/scripts/publish.sh b/scripts/publish.sh new file mode 100755 index 0000000..7670ec9 --- /dev/null +++ b/scripts/publish.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +set -euo pipefail + +BASEDIR=$(cd $(dirname $0); pwd) +REPO_DIR=$(cd ${BASEDIR}/..; pwd) + +echo "====> deploying to github" + +PAGES_DIR=$(mktemp -d) +git worktree add -f ${PAGES_DIR} gh-pages +rm -rf ${PAGES_DIR}/* + +# copy the build files to the gh-pages folder +cp -rp ${REPO_DIR}/build/* ${PAGES_DIR} + +cd ${PAGES_DIR} +git add -A +git commit -m "deployed on $(date) by ${USER}" +git push origin gh-pages +git worktree remove ${PAGES_DIR} diff --git a/spec/graphql-multipart-request-v3.md b/spec/graphql-multipart-request-v3.md new file mode 100644 index 0000000..3a06be3 --- /dev/null +++ b/spec/graphql-multipart-request-v3.md @@ -0,0 +1,783 @@ +# GraphQL Multipart Request V3 + +# GraphQL Multipart Request + +## Overview + +This specification describes how a [GraphQL Over HTTP](https://graphql.github.io/graphql-over-http/draft) compliant +{Server} and {Client} can support passing additional data alongside a GraphQL request using *multipart/form-data*. + +Note: The traditional usage is to upload files as part of a GraphQL request and reference the uploaded file during the +GraphQL resolution. + +```http example +POST https://example.com/graphql +content-type: multipart/form-data; boundary=--boundary + +--boundary +Content-Disposition: form-data; name="operations" + +{ "query": "mutation { upload(file: \"fileA\") }" } + +--boundary +Content-Disposition: form-data; name="fileA"; filename="a.txt" +Content-Type: text/plain + +Alpha file content. + +--boundary-- +``` + +## Conformance + +A conforming implementation of GraphQL Multipart Request must fulfill all normative +requirements. Conformance requirements are described in this document via both +descriptive assertions and key words with clearly defined meanings. + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", " +RECOMMENDED", "MAY", and "OPTIONAL" in the normative portions of this document are to be interpreted +as described in [IETF RFC 2119](https://tools.ietf.org/html/rfc2119). These key words may appear +in lowercase and still retain their meaning unless explicitly declared as non-normative. + +A conforming implementation of Multipart Request may provide additional +functionality, but must not where explicitly disallowed or would otherwise +result in non-conformance. + +## Non-Normative Portions + +All contents of this document are normative except portions explicitly declared +as non-normative. + +Examples in this document are non-normative, and are presented to aid +understanding of introduced concepts and the behavior of normative portions of +the specification. Examples are either introduced explicitly in prose (e.g. "for +example") or are set apart in example or counter-example blocks, like this: + +```example +This is an example of a non-normative example. +``` + +```counter-example +This is an example of a non-normative counter-example. +``` + +Notes in this document are non-normative, and are presented to clarify intent, +draw attention to potential edge-cases and pit-falls, and answer common +questions that arise during implementation. Notes are either introduced +explicitly in prose (e.g. "Note: ") or are set apart in a note block, like this: + +Note: This is an example of a non-normative note. + +# multipart/form-data Format + +:: *multipart/form-data* is defined by [RFC7578](https://datatracker.ietf.org/doc/html/rfc7578) + +## Parts + +A GraphQL {MultipartRequest} is made up of multiple {Part}s. These {Part}s MAY be arranged in any order, +however a {Client} SHOULD send the *operations part* first for optimal performance. The {Server} MUST +support receiving the parts in any order. + +Note: When the *operations part* is first received the {Server} can start processing the GraphQL Request before the +entire payload has been uploaded. + +### Operations Part + +operations part +: A {Part} with the {Name} `operations`. This part includes the GraphQL payload as defined in **GraphQL Over HTTP**. +: There MUST be exactly one *operations part*. + +```http example +POST https://example.com/graphql +content-type: multipart/form-data; boundary=--boundary + +--boundary +Content-Disposition: form-data; name="operations" + +{ "query": "query { field }" } +--boundary-- +``` + +### Embedded Parts + +embedded part +: There MAY be zero or more {Part}s in our *multipart/form-data* request which include additional data. +: These {Part}s MUST not have the name `operations`. + +Note: Supplying a *filename* for the *content-disposition* in an *embedded part* is optional. However, the {Server} MAY +choose to reject requests based on the presence of a *filename*. + +```http example +POST https://example.com/graphql +content-type: multipart/form-data; boundary=--boundary + +--boundary +Content-Disposition: form-data; name="operations" + +{ "query": "mutation { upload(file: \"fileA\") upload(file: \"fileB\") }" } + +--boundary +Content-Disposition: form-data; name="fileA"; filename="a.txt" +Content-Type: text/plain + +Alpha file content. + +--boundary +Content-Disposition: form-data; name="fileB" +Content-Type: text/plain + +Beta file content. + +--boundary-- +``` + +### Map Part + +map part +: There MAY be a single {Part} with the name `map`. +: A server implementing only V3 of this specification MUST ignore this `map` {Part}. + +Note: The *map part* is a legacy {Part} from V2 of the specification. If the {Server} only implements V3 of this +specification it ignores the *map part* so that clients can support sending +[backwards compatible](#sec-Backwards-Compatability) V2/V3 requests. + +# Schema + +There are no requirements on the GraphQL Schema by this specification. + +Note: The {Server} MAY choose to use a GraphQL `scalar` type to reference the *embedded part*s. The {Server} MAY have +multiple different `scalar`s with different meanings in the Schema. + +```graphql example +scalar Upload +scalar File +scalar Part +``` + +# Execution + +ExecuteRequest(httpRequest) : + +1. If the {Server} finds that {httpRequest} is a *multipart/form-data* request: + * Return {ExecuteMultipartRequest(httpRequest)} +2. Else + * Return {ExecuteGraphQLOverHTTPRequest(httpRequest)} + +ExecuteMultipartRequest(multipartRequest) : + +1. Let {partsMap} be the result of parsing the {multipartRequest} into a map of {Name} -> {Part} +2. Let {embeddedPartsMap} be an empty Map. +3. For each {partsMap} entry {partName} -> {partValue} + * If {partName} is `operations` + * Return {ProcessGraphQLRequest(partValue, embeddedPartsMap)} + * Else If {partName} is `map` + * If this server supports V2 via backwards compatability + * The {Server} must handle {multipartRequest} according + to [V2 of this spec](https://github.com/jaydenseric/graphql-multipart-request-spec) + * Else ignore this {Part} + * Else Store the entry {partName} -> {partValue} in {embeddedPartsMap} + +ProcessGraphQLRequest(query, embeddedPartsMap) : + +1. Process this according to {ExecuteGraphQLRequest(query)} +2. If the {Server} finds a piece of the GraphQL request that expects additional data it must pull this additional data + from the {embeddedPartsMap} as referenced by the {Name} and provide it to the internal resolver. + * If the {Server} encounters an error when looking up the additional data in the {embeddedPartsMap} it MUST bubble + up this error from the location in the GraphQL query that requested it. + +Note: {ProcessGraphQLRequest()} depends on async data being pulled from {embeddedPartsMap}. The {Server} shouldn't +fail if a required *embedded part* isn't available until the entire {multipartRequest} has been read. + +Note: This specification doesn't put any specific requirements on how the server knows that additional data is required +or what key to use to look this up. However, as mentioned, the expected flow is that a special `scalar` is created where +the client can set a key to reference the {Name} of one of the *embedded part*s. + +```graphql example +scalar Attachment + +type Mutation { + upload(attachment: Attachment): Boolean +} +``` + +```http example +POST https://example.com/graphql +content-type: multipart/form-data; boundary=--boundary + +--boundary +Content-Disposition: form-data; name="operations" + +{ "query": "mutation { upload(attachment: \"fileA\") }" } + +--boundary +Content-Disposition: form-data; name="fileA"; filename="a.txt" +Content-Type: text/plain + +Alpha file content. + +--boundary-- +``` + +## Error Handling + +Note: if the {Client}'s GraphQL request doesn't reference any *embedded part*s this isn't an error. + +### Missing Operations Part + +If the {Client} sends a *multipart/form-data* request without an *operations part*, the {Server} MUST respond according +to the GraphQL Over HTTP specification when receiving an invalid GraphQL request. + +**Request** + +```http counter-example +POST /graphql HTTP/1.1 +Host: localhost:3001 +content-type: multipart/form-data; boundary=------------------------cec8e8123c05ba25 +content-length: ? + +--------------------------cec8e8123c05ba25 +Content-Disposition: form-data; name="fileA"; filename="a.txt" +Content-Type: text/plain + +Alpha file content. + +--------------------------cec8e8123c05ba25-- +``` + +**Response** + +```json example +{ + "errors": [ + { + "message": "Missing GraphQL Operation" + } + ] +} +``` + +### Missing Embedded Parts + +The request is invalid if it is missing referenced *embedded part*s. This can happen when the {Client} sends a non +*multipart/form-data* request or sends a *multipart/form-data* request missing referenced *embedded part*s. The {Server} +MUST handle these errors as outlined in the GraphQL Spec: {HandleFieldError()}. + +**Request** + +```http counter-example +POST /graphql HTTP/1.1 +Host: localhost:3001 +content-type: multipart/form-data; boundary=------------------------cec8e8123c05ba25 +content-length: ? + +--------------------------cec8e8123c05ba25 +Content-Disposition: form-data; name="operations" + +{ "query": "mutation { upload(file: \"fileA\") }" } + +--------------------------cec8e8123c05ba25 +``` + +**Response** + +```json example +{ + "data": { + "upload": null + }, + "errors": [ + { + "message": "Missing fileA", + "location": [ + { + "line": 1, + "column": 37 + } + ], + "path": [ + "upload" + ] + } + ] +} +``` + +### Duplicate Embedded Parts + +If the {Client} sends a *multipart/form-data* request with duplicate `name`s the {Server} MUST return an error for the +request. + +Note: The {Client} MAY send multiple files with the same `filename` + +**Invalid Request** + +```http counter-example +POST /graphql HTTP/1.1 +Host: localhost:3001 +content-type: multipart/form-data; boundary=------------------------cec8e8123c05ba25 +content-length: ? + +--------------------------cec8e8123c05ba25 +Content-Disposition: form-data; name="operations" + +{ "query": "mutation { upload(file: \"fileA\") }" } + +--------------------------cec8e8123c05ba25 +Content-Disposition: form-data; name="fileA"; filename="a.txt" +Content-Type: text/plain + +Alpha file content. + +--------------------------cec8e8123c05ba25 +Content-Disposition: form-data; name="fileA"; filename="a.txt" +Content-Type: text/plain + +Alpha file content Again. + +--------------------------cec8e8123c05ba25-- +``` + +**Response** + +```json example +{ + "errors": [ + { + "message": "Found duplicate parts: fileA" + } + ] +} +``` + +**Valid Request** + +```http example +POST /graphql HTTP/1.1 +Host: localhost:3001 +content-type: multipart/form-data; boundary=------------------------cec8e8123c05ba25 +content-length: ? + +--------------------------cec8e8123c05ba25 +Content-Disposition: form-data; name="operations" + +{ "query": "mutation { upload(file: \"fileA\") }" } + +--------------------------cec8e8123c05ba25 +Content-Disposition: form-data; name="fileA"; filename="a.txt" +Content-Type: text/plain + +Alpha file content. + +--------------------------cec8e8123c05ba25 +Content-Disposition: form-data; name="fileB"; filename="a.txt" +Content-Type: text/plain + +Alpha file content Again. + +--------------------------cec8e8123c05ba25-- +``` + +# Backwards Compatability + +With [V2 of this spec](https://github.com/jaydenseric/graphql-multipart-request-spec) + +## Client Backwards Compatibility + +V3 {Client}s MAY choose to make requests that are compatible with both V2 AND V3 of this specification. + +A cross compatible request is a V2 compliant request where instead of using `null` for additional data. The *embedded +part* +name is used instead. + +* V2 Servers will overwrite the *embedded part* name when processing the *map part* +* V3 Servers will ignore the *map part* and process the request like normal. + +Note: This allows the V3 {Client} to not worry about the supported specification version of the {Server} as both V2 and +V3 {Server}s will be able to handle the request. + +**GraphQL Request** + +```graphql example +mutation($file: Upload!) { + upload(file: $file) +} +``` + +**Variables** + +```json example +{ + "file": "fileA" +} +``` + +**Map Part** + +```json example +{ + "fileA": [ + "variables.file" + ] +} +``` + +Note: In the above example, note that the key in the *map part* SHOULD be the same as the name of the *embedded part* +that contains the relevant additional data for clarity. + +## Server Backwards Compatibility + +V3 {Server}s MAY choose to support V2 requests of this specification. If a backwards compatible V3 {Server} receives +a request with a *map part* it must implement the execution flow defined +by [V2 of this spec](https://github.com/jaydenseric/graphql-multipart-request-spec). The file key's values MUST be +ignored and substituted sequentially with the contents of the *map part*. If no *map part* is present, it MUST implement +the flow described in {ExecuteMultipartRequest()}. + +# Examples + +**Schema** + +This is the schema for all of the examples in this section. + +```graphql example +scalar Upload + +type Mutation { + upload(file: Upload!): String +} + +``` + +## Single File + +**GraphQL Request** + +```graphql example +mutation { + upload(file: "fileA") +} +``` + +**Payload** + +```http example +POST /graphql HTTP/1.1 +Host: localhost:3001 +content-type: multipart/form-data; boundary=------------------------cec8e8123c05ba25 +content-length: ? + +--------------------------cec8e8123c05ba25 +Content-Disposition: form-data; name="operations" + +{ "query": "mutation { upload(file: \"fileA\") }" } + +--------------------------cec8e8123c05ba25 +Content-Disposition: form-data; name="fileA"; filename="a.txt" +Content-Type: text/plain + +Alpha file content. + +--------------------------cec8e8123c05ba25-- +``` + +**cURL Request** + +```shell example +curl localhost:3001/graphql \ + -F operations='{ "query": "mutation { upload(file: \"fileA\") }" }' \ + -F fileA=@a.txt +``` + +## Multiple Files + +**GraphQL Request** + +```graphql example +mutation { + a: upload(file: "fileA") + b: upload(file: "fileB") +} +``` + +**Payload** + +```http example +POST /graphql HTTP/1.1 +Host: localhost:3001 +content-type: multipart/form-data; boundary=------------------------cec8e8123c05ba25 +content-length: ? + +--------------------------cec8e8123c05ba25 +Content-Disposition: form-data; name="operations" + +{ "query": "mutation { a: upload(file: \"fileA\") b: upload(file: \"fileB\") }" } + +--------------------------cec8e8123c05ba25 +Content-Disposition: form-data; name="fileA"; filename="a.txt" +Content-Type: text/plain + +Alpha file content. + +--------------------------cec8e8123c05ba25 +Content-Disposition: form-data; name="fileB"; filename="b.mpg" +Content-Type: video/mpeg + +Beta file content. + +--------------------------cec8e8123c05ba25-- +``` + +**cURL Request** + +```shell example +curl localhost:3001/graphql \ + -F operations='{ "query": "mutation { a: upload(file: \"fileA\") b: upload(file: \"fileB\") }" }' \ + -F fileA=@a.txt \ + -F fileB=@b.mpg +``` + +## Variables And File Reuse + +**GraphQL Request** + +```graphql example +mutation($file: Upload!) { + a: upload(file: $file) + b: upload(file: $file) +} +``` + +**Variables** + +```json example +{ + "file": "fileA" +} +``` + +**Payload** + +```http example +POST /graphql HTTP/1.1 +Host: localhost:3001 +content-type: multipart/form-data; boundary=------------------------cec8e8123c05ba25 +content-length: ? + +--------------------------cec8e8123c05ba25 +Content-Disposition: form-data; name="operations" + +{ "query": "mutation($file: Upload!) { a: upload(file: $file) b: upload(file: $file) }", "variables": { "file": "fileA" } } + +--------------------------cec8e8123c05ba25 +Content-Disposition: form-data; name="fileA"; filename="a.txt" +Content-Type: text/plain + +Alpha file content. + +--------------------------cec8e8123c05ba25-- +``` + +**cURL Request** + +```shell example +curl localhost:3001/graphql \ + -F operations='{ "query": "mutation($file: Upload!) { a: upload(file: $file) b: upload(file: $file) }", "variables": { "file": "fileA" } }' \ + -F fileA=@a.txt +``` + +## V2 Client -> V3 Backwards Compatible Server + +The Backwards Compatible V3 {Server} will find the `map` {Part} and use it to replace the `null` value in +the `operations` json before executing the request via its standard flow. + +**GraphQL Request** + +```graphql example +mutation($file: Upload!) { + upload(file: $file) +} +``` + +**Variables** + +```json example +{ + "file": null +} +``` + +**Map Part** + +```json example +{ + "fileA": [ + "variables.file" + ] +} +``` + +**Payload** + +```http example +POST /graphql HTTP/1.1 +Host: localhost:3001 +content-type: multipart/form-data; boundary=------------------------cec8e8123c05ba25 +content-length: ? + +--------------------------cec8e8123c05ba25 +Content-Disposition: form-data; name="operations" + +{ "query": "mutation($file: Upload!) { upload(file: $file) }", "variables": { "file": null } } + +Content-Disposition: form-data; name="map" + +{ "fileA": ["variables.file"] } + +--------------------------cec8e8123c05ba25 +Content-Disposition: form-data; name="fileA"; filename="a.txt" +Content-Type: text/plain + +Alpha file content. + +--------------------------cec8e8123c05ba25-- +``` + +**cURL Request** + +```shell example +curl localhost:3001/graphql \ + -F operations='{ "query": "mutation($file: Upload!) { upload(file: $file) }", "variables": { "file": null } }' \ + -F map='{ "fileA": ["variables.file"] }' \ + -F fileA=@a.txt +``` + +## V3 Backwards Compatible Client -> V2 Server + +The V3 {Client} has already filled in the value for the `file` variable in the *operations part* json. The V2 +{Server} will ignore this and still pull the value from the *map part*. + +**GraphQL Request** + +```graphql example +mutation($file: Upload!) { + upload(file: $file) +} +``` + +**Variables** + +```json example +{ + "file": "fileA" +} +``` + +**Map Part** + +```json example +{ + "fileA": [ + "variables.file" + ] +} +``` + +**Payload** + +```http example +POST /graphql HTTP/1.1 +Host: localhost:3001 +content-type: multipart/form-data; boundary=------------------------cec8e8123c05ba25 +content-length: ? + +--------------------------cec8e8123c05ba25 +Content-Disposition: form-data; name="operations" + +{ "query": "mutation($file: Upload!) { upload(file: $file) }", "variables": { "file": "fileA" } } + +Content-Disposition: form-data; name="map" + +{ "fileA": ["variables.file"] } + +--------------------------cec8e8123c05ba25 +Content-Disposition: form-data; name="fileA"; filename="a.txt" +Content-Type: text/plain + +Alpha file content. + +--------------------------cec8e8123c05ba25-- +``` + +**cURL Request** + +```shell example +curl localhost:3001/graphql \ + -F operations='{ "query": "mutation($file: Upload!) { upload(file: $file) }", "variables": { "file": "fileA" } }' \ + -F map='{ "fileA": ["variables.file"] }' \ + -F fileA=@a.txt +``` + +## V3 Backwards Compatible Client -> Non Backwards Compatible V3 Server + +The V3 {Server} will ignore the *map part* however the client has already filled in the `fileA` key in +the `variables` json. The V3 {Server} will use this value. + +**GraphQL Request** + +```graphql example +mutation($file: Upload!) { + upload(file: $file) +} +``` + +**Variables** + +```json example +{ + "file": "fileA" +} +``` + +**Map Part** + +```json example +{ + "fileA": [ + "variables.file" + ] +} +``` + +**Payload** + +```http example +POST /graphql HTTP/1.1 +Host: localhost:3001 +content-type: multipart/form-data; boundary=------------------------cec8e8123c05ba25 +content-length: ? + +--------------------------cec8e8123c05ba25 +Content-Disposition: form-data; name="operations" + +{ "query": "mutation($file: Upload!) { upload(file: $file) }", "variables": { "file": "fileA" } } + +Content-Disposition: form-data; name="map" + +{ "fileA": ["variables.file"] } + +--------------------------cec8e8123c05ba25 +Content-Disposition: form-data; name="fileA"; filename="a.txt" +Content-Type: text/plain + +Alpha file content. + +--------------------------cec8e8123c05ba25-- +``` + +**cURL Request** + +```shell example +curl localhost:3001/graphql \ + -F operations='{ "query": "mutation($file: Upload!) { upload(file: $file) }", "variables": { "file": "fileA" } }' \ + -F map='{ "fileA": ["variables.file"] }' \ + -F fileA=@a.txt +``` diff --git a/spec/metadata.json b/spec/metadata.json new file mode 100644 index 0000000..3b5f7ed --- /dev/null +++ b/spec/metadata.json @@ -0,0 +1,17 @@ +{ + "biblio": { + "https://spec.graphql.org/draft/": { + "ExecuteGraphQLRequest()": "#sec-Execution", + "HandleFieldError()": "#sec-Handling-Field-Errors" + }, + "https://graphql.github.io/graphql-over-http/draft": { + "Server": "#sec-Overview", + "Client": "#sec-Overview", + "ExecuteGraphQLOverHTTPRequest()": "#sec-Execution" + }, + "https://datatracker.ietf.org/doc/html/rfc7578": { + "Part": "#section-4", + "Name": "#section-4.2" + } + } +} diff --git a/sync-vs-async-graphql-multipart-request-middleware.sketch b/sync-vs-async-graphql-multipart-request-middleware.sketch deleted file mode 100644 index 3ed8d3c345c5d6d55c7bc8e22742e2341a533ad2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57071 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 diff --git a/sync-vs-async-graphql-multipart-request-middleware.svg b/sync-vs-async-graphql-multipart-request-middleware.svg deleted file mode 100644 index 96becab..0000000 --- a/sync-vs-async-graphql-multipart-request-middleware.svg +++ /dev/null @@ -1,85 +0,0 @@ - - Sync vs async GraphQL multipart request middleware - - - - GraphQL API upload - - - - Cloud storage upload - - - - - - 1mb.png - - - - - - 2mb.png - - - - - - 3mb.png - - - - Response - - - Receive - request - - - Run - resolver - - - Sync: - Store files temporarily on API server (filesystem or memory). - - - - - - 1mb.png - - - - - - 2mb.png - - - - - - 3mb.png - - - - Receive - request - - - Response - - - Run - resolver - - - Async: - Pass file upload streams into resolver. - - - Sync vs async GraphQL - multipart request middleware - - - From 10da3c077cf1ed5017c06ef3eabc9cd37dc1cd15 Mon Sep 17 00:00:00 2001 From: Dylan Owen Date: Thu, 9 May 2024 14:24:57 -0700 Subject: [PATCH 2/6] Add github actions for publishing gh-pages (#2) --- .github/workflows/ci.yml | 58 +++++ .nvmrc | 1 + package-lock.json | 520 +++++++++++++++++++-------------------- 3 files changed, 319 insertions(+), 260 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .nvmrc diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..1ac914c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,58 @@ +name: ci + +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events but only for the "master" branch + push: + branches: [ "master" ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: "pages" + cancel-in-progress: false + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + build: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + cache: npm + - name: Install our dependencies + run: npm install + - name: Build our release + run: npm run release + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: build + + # Deployment job + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..f203ab8 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +20.13.1 diff --git a/package-lock.json b/package-lock.json index 4ecfbfc..00b7560 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ }, "node_modules/@isaacs/cliui": { "version": "8.0.2", - "resolved": "https://registry.npmjs.org/git@isaacs/cliui/-/cliui-8.0.2.tgz", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dev": true, "dependencies": { @@ -32,7 +32,7 @@ }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", - "resolved": "https://registry.npmjs.org/git@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "dev": true, "optional": true, @@ -42,7 +42,7 @@ }, "node_modules/accepts": { "version": "1.3.8", - "resolved": "https://registry.npmjs.org/gitaccepts/-/accepts-1.3.8.tgz", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, "dependencies": { @@ -55,7 +55,7 @@ }, "node_modules/ansi-regex": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/gitansi-regex/-/ansi-regex-6.0.1.tgz", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", "integrity": "sha1-MYPjj66aZdfLXlOUXNWJfQJgoGo=", "dev": true, "engines": { @@ -64,7 +64,7 @@ }, "node_modules/ansi-styles": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/gitansi-styles/-/ansi-styles-6.2.1.tgz", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, "engines": { @@ -73,7 +73,7 @@ }, "node_modules/anymatch": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/gitanymatch/-/anymatch-3.1.3.tgz", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "dependencies": { @@ -86,7 +86,7 @@ }, "node_modules/apache-crypt": { "version": "1.2.6", - "resolved": "https://registry.npmjs.org/gitapache-crypt/-/apache-crypt-1.2.6.tgz", + "resolved": "https://registry.npmjs.org/apache-crypt/-/apache-crypt-1.2.6.tgz", "integrity": "sha512-072WetlM4blL8PREJVeY+WHiUh1R5VNt2HfceGS8aKqttPHcmqE5pkKuXPz/ULmJOFkc8Hw3kfKl6vy7Qka6DA==", "dev": true, "dependencies": { @@ -98,7 +98,7 @@ }, "node_modules/apache-md5": { "version": "1.1.8", - "resolved": "https://registry.npmjs.org/gitapache-md5/-/apache-md5-1.1.8.tgz", + "resolved": "https://registry.npmjs.org/apache-md5/-/apache-md5-1.1.8.tgz", "integrity": "sha512-FCAJojipPn0bXjuEpjOOOMN8FZDkxfWWp4JGN9mifU2IhxvKyXZYqpzPHdnTSUpmPDy+tsslB6Z1g+Vg6nVbYA==", "dev": true, "engines": { @@ -107,7 +107,7 @@ }, "node_modules/arr-diff": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/gitarr-diff/-/arr-diff-4.0.0.tgz", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", "dev": true, "engines": { @@ -116,7 +116,7 @@ }, "node_modules/arr-flatten": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/gitarr-flatten/-/arr-flatten-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", "integrity": "sha1-NgSLv/TntH4TZkQxbJlmnqWukfE=", "dev": true, "engines": { @@ -125,7 +125,7 @@ }, "node_modules/arr-union": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/gitarr-union/-/arr-union-3.1.0.tgz", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true, "engines": { @@ -134,7 +134,7 @@ }, "node_modules/array-unique": { "version": "0.3.2", - "resolved": "https://registry.npmjs.org/gitarray-unique/-/array-unique-0.3.2.tgz", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true, "engines": { @@ -143,7 +143,7 @@ }, "node_modules/assign-symbols": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gitassign-symbols/-/assign-symbols-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true, "engines": { @@ -152,13 +152,13 @@ }, "node_modules/async-each": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/gitasync-each/-/async-each-1.0.6.tgz", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.6.tgz", "integrity": "sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==", "dev": true }, "node_modules/atob": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/gitatob/-/atob-2.1.2.tgz", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", "integrity": "sha1-bZUX654DDSQ2ZmZR6GvZ9vE1M8k=", "dev": true, "bin": { @@ -170,13 +170,13 @@ }, "node_modules/balanced-match": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/gitbalanced-match/-/balanced-match-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha1-6D46fj8wCzTLnYf2FfoMvzV2kO4=", "dev": true }, "node_modules/base": { "version": "0.11.2", - "resolved": "https://registry.npmjs.org/gitbase/-/base-0.11.2.tgz", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", "integrity": "sha1-e95c7RRbbVUakNuH+DxVi060io8=", "dev": true, "dependencies": { @@ -194,7 +194,7 @@ }, "node_modules/base/node_modules/define-property": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gitdefine-property/-/define-property-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "dependencies": { @@ -206,7 +206,7 @@ }, "node_modules/basic-auth": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/gitbasic-auth/-/basic-auth-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", "integrity": "sha1-uZgnm/R844NEtPPPkW1Gebv1Hjo=", "dev": true, "dependencies": { @@ -218,19 +218,19 @@ }, "node_modules/batch": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/gitbatch/-/batch-0.6.1.tgz", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", "dev": true }, "node_modules/bcryptjs": { "version": "2.4.3", - "resolved": "https://registry.npmjs.org/gitbcryptjs/-/bcryptjs-2.4.3.tgz", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=", "dev": true }, "node_modules/binary-extensions": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/gitbinary-extensions/-/binary-extensions-2.3.0.tgz", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, "engines": { @@ -239,7 +239,7 @@ }, "node_modules/bindings": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/gitbindings/-/bindings-1.5.0.tgz", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", "integrity": "sha1-EDU8npRTNLwFEabZCzj7x8nFBN8=", "dev": true, "optional": true, @@ -249,7 +249,7 @@ }, "node_modules/brace-expansion": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/gitbrace-expansion/-/brace-expansion-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha1-HtxFng8MVISG7Pn8mfIiE2S5oK4=", "dev": true, "dependencies": { @@ -258,7 +258,7 @@ }, "node_modules/braces": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/gitbraces/-/braces-3.0.2.tgz", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha1-NFThpGLujVmeI23zNs2epPiv4Qc=", "dev": true, "dependencies": { @@ -270,7 +270,7 @@ }, "node_modules/cache-base": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gitcache-base/-/cache-base-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", "integrity": "sha1-Cn9GQWgxyLZi7jb+TnxZ129marI=", "dev": true, "dependencies": { @@ -290,7 +290,7 @@ }, "node_modules/chokidar": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/gitchokidar/-/chokidar-3.6.0.tgz", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, "dependencies": { @@ -311,7 +311,7 @@ }, "node_modules/class-utils": { "version": "0.3.6", - "resolved": "https://registry.npmjs.org/gitclass-utils/-/class-utils-0.3.6.tgz", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", "integrity": "sha1-+TNprouafOAv1B+q0MqDAzGQxGM=", "dev": true, "dependencies": { @@ -326,7 +326,7 @@ }, "node_modules/class-utils/node_modules/define-property": { "version": "0.2.5", - "resolved": "https://registry.npmjs.org/gitdefine-property/-/define-property-0.2.5.tgz", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "dependencies": { @@ -338,7 +338,7 @@ }, "node_modules/class-utils/node_modules/is-descriptor": { "version": "0.1.7", - "resolved": "https://registry.npmjs.org/gitis-descriptor/-/is-descriptor-0.1.7.tgz", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", "dev": true, "dependencies": { @@ -351,7 +351,7 @@ }, "node_modules/collection-visit": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gitcollection-visit/-/collection-visit-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, "dependencies": { @@ -364,7 +364,7 @@ }, "node_modules/color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/gitcolor-convert/-/color-convert-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=", "dev": true, "dependencies": { @@ -376,13 +376,13 @@ }, "node_modules/color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/gitcolor-name/-/color-name-1.1.4.tgz", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=", "dev": true }, "node_modules/colors": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/gitcolors/-/colors-1.4.0.tgz", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", "integrity": "sha1-xQSRR51MG9rtLJztMs98fcI2D3g=", "dev": true, "engines": { @@ -391,13 +391,13 @@ }, "node_modules/component-emitter": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/gitcomponent-emitter/-/component-emitter-1.3.1.tgz", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", "dev": true }, "node_modules/connect": { "version": "3.7.0", - "resolved": "https://registry.npmjs.org/gitconnect/-/connect-3.7.0.tgz", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", "integrity": "sha1-XUk0iRDKpeB6AYALAw0MNfIEhPg=", "dev": true, "dependencies": { @@ -412,7 +412,7 @@ }, "node_modules/copy-descriptor": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/gitcopy-descriptor/-/copy-descriptor-0.1.1.tgz", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true, "engines": { @@ -421,13 +421,13 @@ }, "node_modules/core-util-is": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/gitcore-util-is/-/core-util-is-1.0.3.tgz", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha1-pgQtNjTCsn6TKPg3uWX6yDgI24U=", "dev": true }, "node_modules/cors": { "version": "2.8.5", - "resolved": "https://registry.npmjs.org/gitcors/-/cors-2.8.5.tgz", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", "integrity": "sha1-6sEdpRWS3Ya58G9uesKTs9+HXSk=", "dev": true, "dependencies": { @@ -440,7 +440,7 @@ }, "node_modules/cross-spawn": { "version": "7.0.3", - "resolved": "https://registry.npmjs.org/gitcross-spawn/-/cross-spawn-7.0.3.tgz", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha1-9zqFudXUHQRVUcF34ogtSshXKKY=", "dev": true, "dependencies": { @@ -454,7 +454,7 @@ }, "node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/gitdebug/-/debug-2.6.9.tgz", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "dev": true, "dependencies": { @@ -463,7 +463,7 @@ }, "node_modules/decode-uri-component": { "version": "0.2.2", - "resolved": "https://registry.npmjs.org/gitdecode-uri-component/-/decode-uri-component-0.2.2.tgz", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", "dev": true, "engines": { @@ -472,7 +472,7 @@ }, "node_modules/define-property": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/gitdefine-property/-/define-property-2.0.2.tgz", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", "integrity": "sha1-1Flono1lS6d+AqgX+HENcCyxbp0=", "dev": true, "dependencies": { @@ -485,7 +485,7 @@ }, "node_modules/depd": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/gitdepd/-/depd-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha1-tpYWPMdXVg0JzyLMj60Vcbeedt8=", "dev": true, "engines": { @@ -494,7 +494,7 @@ }, "node_modules/destroy": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gitdestroy/-/destroy-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "dev": true, "engines": { @@ -504,31 +504,31 @@ }, "node_modules/duplexer": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/gitduplexer/-/duplexer-0.1.2.tgz", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", "integrity": "sha1-Or5DrvODX4rgd9E23c4PJ2sEAOY=", "dev": true }, "node_modules/eastasianwidth": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/giteastasianwidth/-/eastasianwidth-0.2.0.tgz", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "integrity": "sha1-aWzi7Aqg5uqTo5f/zySqeEDIJ8s=", "dev": true }, "node_modules/ee-first": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/gitee-first/-/ee-first-1.1.1.tgz", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", "dev": true }, "node_modules/emoji-regex": { "version": "9.2.2", - "resolved": "https://registry.npmjs.org/gitemoji-regex/-/emoji-regex-9.2.2.tgz", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha1-hAyIA7DYBH9P8M+WMXazLU7z7XI=", "dev": true }, "node_modules/encodeurl": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/gitencodeurl/-/encodeurl-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", "dev": true, "engines": { @@ -537,13 +537,13 @@ }, "node_modules/escape-html": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/gitescape-html/-/escape-html-1.0.3.tgz", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", "dev": true }, "node_modules/etag": { "version": "1.8.1", - "resolved": "https://registry.npmjs.org/gitetag/-/etag-1.8.1.tgz", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", "dev": true, "engines": { @@ -552,7 +552,7 @@ }, "node_modules/event-stream": { "version": "3.3.4", - "resolved": "https://registry.npmjs.org/gitevent-stream/-/event-stream-3.3.4.tgz", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", "dev": true, "dependencies": { @@ -567,7 +567,7 @@ }, "node_modules/expand-brackets": { "version": "2.1.4", - "resolved": "https://registry.npmjs.org/gitexpand-brackets/-/expand-brackets-2.1.4.tgz", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, "dependencies": { @@ -585,7 +585,7 @@ }, "node_modules/expand-brackets/node_modules/define-property": { "version": "0.2.5", - "resolved": "https://registry.npmjs.org/gitdefine-property/-/define-property-0.2.5.tgz", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "dependencies": { @@ -597,7 +597,7 @@ }, "node_modules/expand-brackets/node_modules/extend-shallow": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/gitextend-shallow/-/extend-shallow-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "dependencies": { @@ -609,7 +609,7 @@ }, "node_modules/expand-brackets/node_modules/is-descriptor": { "version": "0.1.7", - "resolved": "https://registry.npmjs.org/gitis-descriptor/-/is-descriptor-0.1.7.tgz", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", "dev": true, "dependencies": { @@ -622,7 +622,7 @@ }, "node_modules/expand-brackets/node_modules/is-extendable": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/gitis-extendable/-/is-extendable-0.1.1.tgz", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true, "engines": { @@ -631,7 +631,7 @@ }, "node_modules/extend-shallow": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/gitextend-shallow/-/extend-shallow-3.0.2.tgz", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, "dependencies": { @@ -644,7 +644,7 @@ }, "node_modules/extglob": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/gitextglob/-/extglob-2.0.4.tgz", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", "integrity": "sha1-rQD+TcYSqSMuhxhxHcXLWrAoVUM=", "dev": true, "dependencies": { @@ -663,7 +663,7 @@ }, "node_modules/extglob/node_modules/define-property": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gitdefine-property/-/define-property-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "dependencies": { @@ -675,7 +675,7 @@ }, "node_modules/extglob/node_modules/extend-shallow": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/gitextend-shallow/-/extend-shallow-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "dependencies": { @@ -687,7 +687,7 @@ }, "node_modules/extglob/node_modules/is-extendable": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/gitis-extendable/-/is-extendable-0.1.1.tgz", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true, "engines": { @@ -696,7 +696,7 @@ }, "node_modules/faye-websocket": { "version": "0.11.4", - "resolved": "https://registry.npmjs.org/gitfaye-websocket/-/faye-websocket-0.11.4.tgz", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", "integrity": "sha1-fw2Sdc/dhqHJY9yLZfzEUe3Lsdo=", "dev": true, "dependencies": { @@ -708,14 +708,14 @@ }, "node_modules/file-uri-to-path": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gitfile-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", "integrity": "sha1-VTp7hEb/b2hDWcRF8eN6BdrMM90=", "dev": true, "optional": true }, "node_modules/fill-range": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/gitfill-range/-/fill-range-7.0.1.tgz", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha1-GRmmp8df44ssfHflGYU12prN2kA=", "dev": true, "dependencies": { @@ -727,7 +727,7 @@ }, "node_modules/finalhandler": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/gitfinalhandler/-/finalhandler-1.1.2.tgz", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", "integrity": "sha1-t+fQAP/RGTjQ/bBTUG9uur6fWH0=", "dev": true, "dependencies": { @@ -745,7 +745,7 @@ }, "node_modules/for-in": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/gitfor-in/-/for-in-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true, "engines": { @@ -754,7 +754,7 @@ }, "node_modules/foreground-child": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/gitforeground-child/-/foreground-child-3.1.1.tgz", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", "dev": true, "dependencies": { @@ -767,7 +767,7 @@ }, "node_modules/fragment-cache": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/gitfragment-cache/-/fragment-cache-0.2.1.tgz", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "dev": true, "dependencies": { @@ -779,7 +779,7 @@ }, "node_modules/fresh": { "version": "0.5.2", - "resolved": "https://registry.npmjs.org/gitfresh/-/fresh-0.5.2.tgz", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", "dev": true, "engines": { @@ -788,13 +788,13 @@ }, "node_modules/from": { "version": "0.1.7", - "resolved": "https://registry.npmjs.org/gitfrom/-/from-0.1.7.tgz", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", "dev": true }, "node_modules/fsevents": { "version": "2.3.3", - "resolved": "https://registry.npmjs.org/gitfsevents/-/fsevents-2.3.3.tgz", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, @@ -805,13 +805,13 @@ }, "node_modules/function-bind": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/gitfunction-bind/-/function-bind-1.1.2.tgz", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true }, "node_modules/get-value": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/gitget-value/-/get-value-2.0.6.tgz", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", "dev": true, "engines": { @@ -820,7 +820,7 @@ }, "node_modules/glob": { "version": "10.3.12", - "resolved": "https://registry.npmjs.org/gitglob/-/glob-10.3.12.tgz", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", "dev": true, "dependencies": { @@ -839,7 +839,7 @@ }, "node_modules/glob-parent": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/gitglob-parent/-/glob-parent-5.1.2.tgz", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha1-hpgyxYA0/mikCTwX3BXoNA2EAcQ=", "dev": true, "dependencies": { @@ -851,13 +851,13 @@ }, "node_modules/graceful-fs": { "version": "4.2.11", - "resolved": "https://registry.npmjs.org/gitgraceful-fs/-/graceful-fs-4.2.11.tgz", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, "node_modules/has-value": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/githas-value/-/has-value-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "dev": true, "dependencies": { @@ -871,7 +871,7 @@ }, "node_modules/has-values": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/githas-values/-/has-values-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "dev": true, "dependencies": { @@ -884,7 +884,7 @@ }, "node_modules/has-values/node_modules/is-number": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/gitis-number/-/is-number-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "dependencies": { @@ -896,7 +896,7 @@ }, "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/gitkind-of/-/kind-of-3.2.2.tgz", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "dependencies": { @@ -908,7 +908,7 @@ }, "node_modules/has-values/node_modules/kind-of": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/gitkind-of/-/kind-of-4.0.0.tgz", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "dependencies": { @@ -920,7 +920,7 @@ }, "node_modules/hasown": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/githasown/-/hasown-2.0.2.tgz", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, "dependencies": { @@ -932,7 +932,7 @@ }, "node_modules/http-auth": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/githttp-auth/-/http-auth-3.1.3.tgz", + "resolved": "https://registry.npmjs.org/http-auth/-/http-auth-3.1.3.tgz", "integrity": "sha1-lFz63WZSHq+PfISRPTd9exXyTjE=", "dev": true, "dependencies": { @@ -947,7 +947,7 @@ }, "node_modules/http-errors": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/githttp-errors/-/http-errors-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dev": true, "dependencies": { @@ -963,7 +963,7 @@ }, "node_modules/http-errors/node_modules/statuses": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/gitstatuses/-/statuses-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha1-VcsADM8dSHKL0jxoWgY5mM8aG2M=", "dev": true, "engines": { @@ -972,19 +972,19 @@ }, "node_modules/http-parser-js": { "version": "0.5.8", - "resolved": "https://registry.npmjs.org/githttp-parser-js/-/http-parser-js-0.5.8.tgz", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", "dev": true }, "node_modules/inherits": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/gitinherits/-/inherits-2.0.4.tgz", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w=", "dev": true }, "node_modules/is-accessor-descriptor": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gitis-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz", "integrity": "sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==", "dev": true, "dependencies": { @@ -996,7 +996,7 @@ }, "node_modules/is-binary-path": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/gitis-binary-path/-/is-binary-path-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha1-6h9/O4DwZCNug0cPhsCcJU+0Wwk=", "dev": true, "dependencies": { @@ -1008,13 +1008,13 @@ }, "node_modules/is-buffer": { "version": "1.1.6", - "resolved": "https://registry.npmjs.org/gitis-buffer/-/is-buffer-1.1.6.tgz", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha1-76ouqdqg16suoTqXsritUf776L4=", "dev": true }, "node_modules/is-data-descriptor": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gitis-data-descriptor/-/is-data-descriptor-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz", "integrity": "sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==", "dev": true, "dependencies": { @@ -1026,7 +1026,7 @@ }, "node_modules/is-descriptor": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/gitis-descriptor/-/is-descriptor-1.0.3.tgz", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", "dev": true, "dependencies": { @@ -1039,7 +1039,7 @@ }, "node_modules/is-extendable": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gitis-extendable/-/is-extendable-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ=", "dev": true, "dependencies": { @@ -1051,7 +1051,7 @@ }, "node_modules/is-extglob": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/gitis-extglob/-/is-extglob-2.1.1.tgz", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true, "engines": { @@ -1060,7 +1060,7 @@ }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/gitis-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha1-8Rb4Bk/pCz94RKOJl8C3UFEmnx0=", "dev": true, "engines": { @@ -1069,7 +1069,7 @@ }, "node_modules/is-glob": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/gitis-glob/-/is-glob-4.0.3.tgz", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha1-ZPYeQsu7LuwgcanawLKLoeZdUIQ=", "dev": true, "dependencies": { @@ -1081,7 +1081,7 @@ }, "node_modules/is-number": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/gitis-number/-/is-number-7.0.0.tgz", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss=", "dev": true, "engines": { @@ -1090,7 +1090,7 @@ }, "node_modules/is-plain-object": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/gitis-plain-object/-/is-plain-object-2.0.4.tgz", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha1-LBY7P6+xtgbZ0Xko8FwqHDjgdnc=", "dev": true, "dependencies": { @@ -1102,7 +1102,7 @@ }, "node_modules/is-windows": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/gitis-windows/-/is-windows-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", "integrity": "sha1-0YUOuXkezRjmGCzhKjDzlmNLsZ0=", "dev": true, "engines": { @@ -1111,7 +1111,7 @@ }, "node_modules/is-wsl": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/gitis-wsl/-/is-wsl-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", "dev": true, "engines": { @@ -1120,19 +1120,19 @@ }, "node_modules/isarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gitisarray/-/isarray-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, "node_modules/isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/gitisexe/-/isexe-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, "node_modules/isobject": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/gitisobject/-/isobject-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true, "engines": { @@ -1141,7 +1141,7 @@ }, "node_modules/jackspeak": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/gitjackspeak/-/jackspeak-2.3.6.tgz", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", "dev": true, "dependencies": { @@ -1156,7 +1156,7 @@ }, "node_modules/kind-of": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/gitkind-of/-/kind-of-6.0.3.tgz", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha1-B8BQNKbDSfoG4k+jWqdttFgM5N0=", "dev": true, "engines": { @@ -1165,7 +1165,7 @@ }, "node_modules/live-server": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/gitlive-server/-/live-server-1.2.2.tgz", + "resolved": "https://registry.npmjs.org/live-server/-/live-server-1.2.2.tgz", "integrity": "sha512-t28HXLjITRGoMSrCOv4eZ88viHaBVIjKjdI5PO92Vxlu+twbk6aE0t7dVIaz6ZWkjPilYFV6OSdMYl9ybN2B4w==", "dev": true, "dependencies": { @@ -1192,7 +1192,7 @@ }, "node_modules/live-server/node_modules/anymatch": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/gitanymatch/-/anymatch-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", "integrity": "sha1-vLJLTzeTTZqnrBe0ra+J58du8us=", "dev": true, "dependencies": { @@ -1202,7 +1202,7 @@ }, "node_modules/live-server/node_modules/anymatch/node_modules/normalize-path": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/gitnormalize-path/-/normalize-path-2.1.1.tgz", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, "dependencies": { @@ -1214,7 +1214,7 @@ }, "node_modules/live-server/node_modules/binary-extensions": { "version": "1.13.1", - "resolved": "https://registry.npmjs.org/gitbinary-extensions/-/binary-extensions-1.13.1.tgz", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", "integrity": "sha1-WYr+VHVbKGilMw0q/51Ou1Mgm2U=", "dev": true, "engines": { @@ -1223,7 +1223,7 @@ }, "node_modules/live-server/node_modules/braces": { "version": "2.3.2", - "resolved": "https://registry.npmjs.org/gitbraces/-/braces-2.3.2.tgz", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha1-WXn9PxTNUxVl5fot8av/8d+u5yk=", "dev": true, "dependencies": { @@ -1244,7 +1244,7 @@ }, "node_modules/live-server/node_modules/chokidar": { "version": "2.1.8", - "resolved": "https://registry.npmjs.org/gitchokidar/-/chokidar-2.1.8.tgz", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", "integrity": "sha1-gEs6e2qZNYw8XGHnHYco8EHP+Rc=", "deprecated": "Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.", "dev": true, @@ -1267,7 +1267,7 @@ }, "node_modules/live-server/node_modules/extend-shallow": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/gitextend-shallow/-/extend-shallow-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "dependencies": { @@ -1279,7 +1279,7 @@ }, "node_modules/live-server/node_modules/fill-range": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/gitfill-range/-/fill-range-4.0.0.tgz", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "dependencies": { @@ -1294,7 +1294,7 @@ }, "node_modules/live-server/node_modules/fsevents": { "version": "1.2.13", - "resolved": "https://registry.npmjs.org/gitfsevents/-/fsevents-1.2.13.tgz", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha1-8yXLBFVZJCi88Rs4M3DvcOO/zDg=", "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", "dev": true, @@ -1310,7 +1310,7 @@ }, "node_modules/live-server/node_modules/glob-parent": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/gitglob-parent/-/glob-parent-3.1.0.tgz", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, "dependencies": { @@ -1320,7 +1320,7 @@ }, "node_modules/live-server/node_modules/glob-parent/node_modules/is-glob": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/gitis-glob/-/is-glob-3.1.0.tgz", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "dependencies": { @@ -1332,7 +1332,7 @@ }, "node_modules/live-server/node_modules/is-binary-path": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gitis-binary-path/-/is-binary-path-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "dependencies": { @@ -1344,7 +1344,7 @@ }, "node_modules/live-server/node_modules/is-extendable": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/gitis-extendable/-/is-extendable-0.1.1.tgz", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true, "engines": { @@ -1353,7 +1353,7 @@ }, "node_modules/live-server/node_modules/is-number": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/gitis-number/-/is-number-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "dependencies": { @@ -1365,7 +1365,7 @@ }, "node_modules/live-server/node_modules/kind-of": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/gitkind-of/-/kind-of-3.2.2.tgz", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "dependencies": { @@ -1377,7 +1377,7 @@ }, "node_modules/live-server/node_modules/readdirp": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/gitreaddirp/-/readdirp-2.2.1.tgz", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", "integrity": "sha1-DodiKjMlqjPokihcr4tOhGUppSU=", "dev": true, "dependencies": { @@ -1391,7 +1391,7 @@ }, "node_modules/live-server/node_modules/to-regex-range": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/gitto-regex-range/-/to-regex-range-2.1.1.tgz", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, "dependencies": { @@ -1404,7 +1404,7 @@ }, "node_modules/lru-cache": { "version": "10.2.2", - "resolved": "https://registry.npmjs.org/gitlru-cache/-/lru-cache-10.2.2.tgz", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", "dev": true, "engines": { @@ -1413,7 +1413,7 @@ }, "node_modules/map-cache": { "version": "0.2.2", - "resolved": "https://registry.npmjs.org/gitmap-cache/-/map-cache-0.2.2.tgz", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", "dev": true, "engines": { @@ -1422,13 +1422,13 @@ }, "node_modules/map-stream": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/gitmap-stream/-/map-stream-0.1.0.tgz", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", "dev": true }, "node_modules/map-visit": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gitmap-visit/-/map-visit-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "dev": true, "dependencies": { @@ -1440,7 +1440,7 @@ }, "node_modules/micromatch": { "version": "3.1.10", - "resolved": "https://registry.npmjs.org/gitmicromatch/-/micromatch-3.1.10.tgz", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha1-cIWbyVyYQJUvNZoGij/En57PrCM=", "dev": true, "dependencies": { @@ -1464,7 +1464,7 @@ }, "node_modules/micromatch/node_modules/braces": { "version": "2.3.2", - "resolved": "https://registry.npmjs.org/gitbraces/-/braces-2.3.2.tgz", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha1-WXn9PxTNUxVl5fot8av/8d+u5yk=", "dev": true, "dependencies": { @@ -1485,7 +1485,7 @@ }, "node_modules/micromatch/node_modules/braces/node_modules/extend-shallow": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/gitextend-shallow/-/extend-shallow-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "dependencies": { @@ -1497,7 +1497,7 @@ }, "node_modules/micromatch/node_modules/fill-range": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/gitfill-range/-/fill-range-4.0.0.tgz", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "dependencies": { @@ -1512,7 +1512,7 @@ }, "node_modules/micromatch/node_modules/fill-range/node_modules/extend-shallow": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/gitextend-shallow/-/extend-shallow-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "dependencies": { @@ -1524,7 +1524,7 @@ }, "node_modules/micromatch/node_modules/is-extendable": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/gitis-extendable/-/is-extendable-0.1.1.tgz", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true, "engines": { @@ -1533,7 +1533,7 @@ }, "node_modules/micromatch/node_modules/is-number": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/gitis-number/-/is-number-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "dependencies": { @@ -1545,7 +1545,7 @@ }, "node_modules/micromatch/node_modules/is-number/node_modules/kind-of": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/gitkind-of/-/kind-of-3.2.2.tgz", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "dependencies": { @@ -1557,7 +1557,7 @@ }, "node_modules/micromatch/node_modules/to-regex-range": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/gitto-regex-range/-/to-regex-range-2.1.1.tgz", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, "dependencies": { @@ -1570,7 +1570,7 @@ }, "node_modules/mime": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/gitmime/-/mime-1.6.0.tgz", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE=", "dev": true, "bin": { @@ -1582,7 +1582,7 @@ }, "node_modules/mime-db": { "version": "1.52.0", - "resolved": "https://registry.npmjs.org/gitmime-db/-/mime-db-1.52.0.tgz", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true, "engines": { @@ -1591,7 +1591,7 @@ }, "node_modules/mime-types": { "version": "2.1.35", - "resolved": "https://registry.npmjs.org/gitmime-types/-/mime-types-2.1.35.tgz", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, "dependencies": { @@ -1603,7 +1603,7 @@ }, "node_modules/minimatch": { "version": "9.0.4", - "resolved": "https://registry.npmjs.org/gitminimatch/-/minimatch-9.0.4.tgz", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", "dev": true, "dependencies": { @@ -1615,7 +1615,7 @@ }, "node_modules/minipass": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/gitminipass/-/minipass-7.1.0.tgz", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "dev": true, "engines": { @@ -1624,7 +1624,7 @@ }, "node_modules/mixin-deep": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/gitmixin-deep/-/mixin-deep-1.3.2.tgz", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", "integrity": "sha1-ESC0PcNZp4Xc5ltVuC4lfM9HlWY=", "dev": true, "dependencies": { @@ -1637,7 +1637,7 @@ }, "node_modules/morgan": { "version": "1.10.0", - "resolved": "https://registry.npmjs.org/gitmorgan/-/morgan-1.10.0.tgz", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", "integrity": "sha1-CRd4q8H8R801CYJGU9rh+qtrF9c=", "dev": true, "dependencies": { @@ -1653,20 +1653,20 @@ }, "node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/gitms/-/ms-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, "node_modules/nan": { "version": "2.19.0", - "resolved": "https://registry.npmjs.org/gitnan/-/nan-2.19.0.tgz", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.19.0.tgz", "integrity": "sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==", "dev": true, "optional": true }, "node_modules/nanomatch": { "version": "1.2.13", - "resolved": "https://registry.npmjs.org/gitnanomatch/-/nanomatch-1.2.13.tgz", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", "integrity": "sha1-uHqKpPwN6P5r6IiVs4mD/yZb0Rk=", "dev": true, "dependencies": { @@ -1688,7 +1688,7 @@ }, "node_modules/negotiator": { "version": "0.6.3", - "resolved": "https://registry.npmjs.org/gitnegotiator/-/negotiator-0.6.3.tgz", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "dev": true, "engines": { @@ -1697,7 +1697,7 @@ }, "node_modules/normalize-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/gitnormalize-path/-/normalize-path-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha1-Dc1p/yOhybEf0JeDFmRKA4ghamU=", "dev": true, "engines": { @@ -1706,7 +1706,7 @@ }, "node_modules/object-assign": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/gitobject-assign/-/object-assign-4.1.1.tgz", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true, "engines": { @@ -1715,7 +1715,7 @@ }, "node_modules/object-copy": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/gitobject-copy/-/object-copy-0.1.0.tgz", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "dev": true, "dependencies": { @@ -1729,7 +1729,7 @@ }, "node_modules/object-copy/node_modules/define-property": { "version": "0.2.5", - "resolved": "https://registry.npmjs.org/gitdefine-property/-/define-property-0.2.5.tgz", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "dependencies": { @@ -1741,7 +1741,7 @@ }, "node_modules/object-copy/node_modules/is-descriptor": { "version": "0.1.7", - "resolved": "https://registry.npmjs.org/gitis-descriptor/-/is-descriptor-0.1.7.tgz", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", "dev": true, "dependencies": { @@ -1754,7 +1754,7 @@ }, "node_modules/object-copy/node_modules/kind-of": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/gitkind-of/-/kind-of-3.2.2.tgz", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "dependencies": { @@ -1766,7 +1766,7 @@ }, "node_modules/object-visit": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gitobject-visit/-/object-visit-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "dev": true, "dependencies": { @@ -1778,7 +1778,7 @@ }, "node_modules/object.pick": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/gitobject.pick/-/object.pick-1.3.0.tgz", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, "dependencies": { @@ -1790,7 +1790,7 @@ }, "node_modules/on-finished": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/giton-finished/-/on-finished-2.3.0.tgz", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", "dev": true, "dependencies": { @@ -1802,7 +1802,7 @@ }, "node_modules/on-headers": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/giton-headers/-/on-headers-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", "integrity": "sha1-dysK5qqlJcOZ5Imt+tkMQD6zwo8=", "dev": true, "engines": { @@ -1811,7 +1811,7 @@ }, "node_modules/opn": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gitopn/-/opn-6.0.0.tgz", + "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz", "integrity": "sha1-PFsNtnbV+X2hIz0e1C0YK8WifS0=", "deprecated": "The package has been renamed to `open`", "dev": true, @@ -1824,7 +1824,7 @@ }, "node_modules/parseurl": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/gitparseurl/-/parseurl-1.3.3.tgz", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha1-naGee+6NEt/wUT7Vt2lXeTvC6NQ=", "dev": true, "engines": { @@ -1833,7 +1833,7 @@ }, "node_modules/pascalcase": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/gitpascalcase/-/pascalcase-0.1.1.tgz", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", "dev": true, "engines": { @@ -1842,13 +1842,13 @@ }, "node_modules/path-dirname": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/gitpath-dirname/-/path-dirname-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", "dev": true }, "node_modules/path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gitpath-is-absolute/-/path-is-absolute-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true, "engines": { @@ -1857,7 +1857,7 @@ }, "node_modules/path-key": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/gitpath-key/-/path-key-3.1.1.tgz", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha1-WB9q3mWMu6ZaDTOA3ndTKVBU83U=", "dev": true, "engines": { @@ -1866,7 +1866,7 @@ }, "node_modules/path-scurry": { "version": "1.10.2", - "resolved": "https://registry.npmjs.org/gitpath-scurry/-/path-scurry-1.10.2.tgz", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", "dev": true, "dependencies": { @@ -1879,7 +1879,7 @@ }, "node_modules/pause-stream": { "version": "0.0.11", - "resolved": "https://registry.npmjs.org/gitpause-stream/-/pause-stream-0.0.11.tgz", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", "dev": true, "dependencies": { @@ -1888,7 +1888,7 @@ }, "node_modules/picomatch": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/gitpicomatch/-/picomatch-2.3.1.tgz", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "engines": { @@ -1897,7 +1897,7 @@ }, "node_modules/posix-character-classes": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/gitposix-character-classes/-/posix-character-classes-0.1.1.tgz", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", "dev": true, "engines": { @@ -1906,7 +1906,7 @@ }, "node_modules/prettier": { "version": "3.2.5", - "resolved": "https://registry.npmjs.org/gitprettier/-/prettier-3.2.5.tgz", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", "dev": true, "bin": { @@ -1918,7 +1918,7 @@ }, "node_modules/prismjs": { "version": "1.29.0", - "resolved": "https://registry.npmjs.org/gitprismjs/-/prismjs-1.29.0.tgz", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", "dev": true, "engines": { @@ -1927,13 +1927,13 @@ }, "node_modules/process-nextick-args": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/gitprocess-nextick-args/-/process-nextick-args-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha1-eCDZsWEgzFXKmud5JoCufbptf+I=", "dev": true }, "node_modules/proxy-middleware": { "version": "0.15.0", - "resolved": "https://registry.npmjs.org/gitproxy-middleware/-/proxy-middleware-0.15.0.tgz", + "resolved": "https://registry.npmjs.org/proxy-middleware/-/proxy-middleware-0.15.0.tgz", "integrity": "sha1-o/3xvvtzD5UZZYcqwvYHTGFHelY=", "dev": true, "engines": { @@ -1942,7 +1942,7 @@ }, "node_modules/range-parser": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/gitrange-parser/-/range-parser-1.2.1.tgz", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha1-PPNwI9GZ4cJNGlW4SADC8+ZGgDE=", "dev": true, "engines": { @@ -1951,7 +1951,7 @@ }, "node_modules/readable-stream": { "version": "2.3.8", - "resolved": "https://registry.npmjs.org/gitreadable-stream/-/readable-stream-2.3.8.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, "dependencies": { @@ -1966,7 +1966,7 @@ }, "node_modules/readdirp": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/gitreaddirp/-/readdirp-3.6.0.tgz", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha1-dKNwvYVxFuJFspzJc0DNQxoCpsc=", "dev": true, "dependencies": { @@ -1978,7 +1978,7 @@ }, "node_modules/regex-not": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/gitregex-not/-/regex-not-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "integrity": "sha1-H07OJ+ALC2XgJHpoEOaoXYOldSw=", "dev": true, "dependencies": { @@ -1991,13 +1991,13 @@ }, "node_modules/remove-trailing-separator": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/gitremove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", "dev": true }, "node_modules/repeat-element": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/gitrepeat-element/-/repeat-element-1.1.4.tgz", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", "integrity": "sha1-vmgVIIR6tYx1aKx1+/rSjtQtOek=", "dev": true, "engines": { @@ -2006,7 +2006,7 @@ }, "node_modules/repeat-string": { "version": "1.6.1", - "resolved": "https://registry.npmjs.org/gitrepeat-string/-/repeat-string-1.6.1.tgz", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true, "engines": { @@ -2015,14 +2015,14 @@ }, "node_modules/resolve-url": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/gitresolve-url/-/resolve-url-0.2.1.tgz", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "deprecated": "https://github.com/lydell/resolve-url#deprecated", "dev": true }, "node_modules/ret": { "version": "0.1.15", - "resolved": "https://registry.npmjs.org/gitret/-/ret-0.1.15.tgz", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", "integrity": "sha1-uKSCXVvbH8P29Twrwz+BOIaBx7w=", "dev": true, "engines": { @@ -2031,7 +2031,7 @@ }, "node_modules/rimraf": { "version": "5.0.5", - "resolved": "https://registry.npmjs.org/gitrimraf/-/rimraf-5.0.5.tgz", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", "dev": true, "dependencies": { @@ -2046,13 +2046,13 @@ }, "node_modules/safe-buffer": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/gitsafe-buffer/-/safe-buffer-5.1.2.tgz", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=", "dev": true }, "node_modules/safe-regex": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/gitsafe-regex/-/safe-regex-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "dependencies": { @@ -2061,7 +2061,7 @@ }, "node_modules/send": { "version": "0.18.0", - "resolved": "https://registry.npmjs.org/gitsend/-/send-0.18.0.tgz", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "dev": true, "dependencies": { @@ -2085,13 +2085,13 @@ }, "node_modules/send/node_modules/ms": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/gitms/-/ms-2.1.3.tgz", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha1-V0yBOM4dK1hh8LRFedut1gxmFbI=", "dev": true }, "node_modules/send/node_modules/on-finished": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/giton-finished/-/on-finished-2.4.1.tgz", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dev": true, "dependencies": { @@ -2103,7 +2103,7 @@ }, "node_modules/send/node_modules/statuses": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/gitstatuses/-/statuses-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha1-VcsADM8dSHKL0jxoWgY5mM8aG2M=", "dev": true, "engines": { @@ -2112,7 +2112,7 @@ }, "node_modules/serve-index": { "version": "1.9.1", - "resolved": "https://registry.npmjs.org/gitserve-index/-/serve-index-1.9.1.tgz", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", "dev": true, "dependencies": { @@ -2130,7 +2130,7 @@ }, "node_modules/serve-index/node_modules/depd": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/gitdepd/-/depd-1.1.2.tgz", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", "dev": true, "engines": { @@ -2139,7 +2139,7 @@ }, "node_modules/serve-index/node_modules/http-errors": { "version": "1.6.3", - "resolved": "https://registry.npmjs.org/githttp-errors/-/http-errors-1.6.3.tgz", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "dev": true, "dependencies": { @@ -2154,19 +2154,19 @@ }, "node_modules/serve-index/node_modules/inherits": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/gitinherits/-/inherits-2.0.3.tgz", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, "node_modules/serve-index/node_modules/setprototypeof": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/gitsetprototypeof/-/setprototypeof-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", "integrity": "sha1-0L2FU2iHtv58DYGMuWLZ2RxU5lY=", "dev": true }, "node_modules/set-value": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/gitset-value/-/set-value-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", "integrity": "sha1-oY1AUw5vB95CKMfe/kInr4ytAFs=", "dev": true, "dependencies": { @@ -2181,7 +2181,7 @@ }, "node_modules/set-value/node_modules/extend-shallow": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/gitextend-shallow/-/extend-shallow-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "dependencies": { @@ -2193,7 +2193,7 @@ }, "node_modules/set-value/node_modules/is-extendable": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/gitis-extendable/-/is-extendable-0.1.1.tgz", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true, "engines": { @@ -2202,13 +2202,13 @@ }, "node_modules/setprototypeof": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gitsetprototypeof/-/setprototypeof-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha1-ZsmiSnP5/CjL5msJ/tPTPcrxtCQ=", "dev": true }, "node_modules/shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/gitshebang-command/-/shebang-command-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha1-zNCvT4g1+9wmW4JGGq8MNmY/NOo=", "dev": true, "dependencies": { @@ -2220,7 +2220,7 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/gitshebang-regex/-/shebang-regex-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha1-rhbxZE2HPsrYQ7AwexQzYtTEIXI=", "dev": true, "engines": { @@ -2229,7 +2229,7 @@ }, "node_modules/signal-exit": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/gitsignal-exit/-/signal-exit-4.1.0.tgz", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, "engines": { @@ -2238,7 +2238,7 @@ }, "node_modules/snapdragon": { "version": "0.8.2", - "resolved": "https://registry.npmjs.org/gitsnapdragon/-/snapdragon-0.8.2.tgz", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", "integrity": "sha1-ZJIufFZbDhQgS6GqfWlkJ40lGC0=", "dev": true, "dependencies": { @@ -2257,7 +2257,7 @@ }, "node_modules/snapdragon-node": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/gitsnapdragon-node/-/snapdragon-node-2.1.1.tgz", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", "integrity": "sha1-bBdfhv8UvbByRWPo88GwIaKGhTs=", "dev": true, "dependencies": { @@ -2271,7 +2271,7 @@ }, "node_modules/snapdragon-node/node_modules/define-property": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gitdefine-property/-/define-property-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "dependencies": { @@ -2283,7 +2283,7 @@ }, "node_modules/snapdragon-util": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/gitsnapdragon-util/-/snapdragon-util-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", "integrity": "sha1-+VZHlIbyrNeXAGk/b3uAXkWrVuI=", "dev": true, "dependencies": { @@ -2295,7 +2295,7 @@ }, "node_modules/snapdragon-util/node_modules/kind-of": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/gitkind-of/-/kind-of-3.2.2.tgz", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "dependencies": { @@ -2307,7 +2307,7 @@ }, "node_modules/snapdragon/node_modules/define-property": { "version": "0.2.5", - "resolved": "https://registry.npmjs.org/gitdefine-property/-/define-property-0.2.5.tgz", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "dependencies": { @@ -2319,7 +2319,7 @@ }, "node_modules/snapdragon/node_modules/extend-shallow": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/gitextend-shallow/-/extend-shallow-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "dependencies": { @@ -2331,7 +2331,7 @@ }, "node_modules/snapdragon/node_modules/is-descriptor": { "version": "0.1.7", - "resolved": "https://registry.npmjs.org/gitis-descriptor/-/is-descriptor-0.1.7.tgz", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", "dev": true, "dependencies": { @@ -2344,7 +2344,7 @@ }, "node_modules/snapdragon/node_modules/is-extendable": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/gitis-extendable/-/is-extendable-0.1.1.tgz", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true, "engines": { @@ -2353,7 +2353,7 @@ }, "node_modules/source-map": { "version": "0.5.7", - "resolved": "https://registry.npmjs.org/gitsource-map/-/source-map-0.5.7.tgz", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true, "engines": { @@ -2362,7 +2362,7 @@ }, "node_modules/source-map-resolve": { "version": "0.5.3", - "resolved": "https://registry.npmjs.org/gitsource-map-resolve/-/source-map-resolve-0.5.3.tgz", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", "integrity": "sha1-GQhmvs51U+H48mei7oLGBrVQmho=", "dev": true, "dependencies": { @@ -2375,13 +2375,13 @@ }, "node_modules/source-map-url": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/gitsource-map-url/-/source-map-url-0.4.1.tgz", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", "integrity": "sha1-CvZmBadFpaL5HPG7+KevvCg97FY=", "dev": true }, "node_modules/spec-md": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/gitspec-md/-/spec-md-3.1.0.tgz", + "resolved": "https://registry.npmjs.org/spec-md/-/spec-md-3.1.0.tgz", "integrity": "sha512-h4/Pc+ICB+q8cXKTyy8f5JJHSQRNy1oh05P/vTrq+qIV2fLmEaalwpZMRYMzlq/g+qxnIp/hywGGYA3rpefYmA==", "dev": true, "dependencies": { @@ -2396,7 +2396,7 @@ }, "node_modules/split": { "version": "0.3.3", - "resolved": "https://registry.npmjs.org/gitsplit/-/split-0.3.3.tgz", + "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", "dev": true, "dependencies": { @@ -2408,7 +2408,7 @@ }, "node_modules/split-string": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/gitsplit-string/-/split-string-3.1.0.tgz", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", "integrity": "sha1-fLCd2jqGWFcFxks5pkZgOGguj+I=", "dev": true, "dependencies": { @@ -2420,7 +2420,7 @@ }, "node_modules/static-extend": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/gitstatic-extend/-/static-extend-0.1.2.tgz", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "dev": true, "dependencies": { @@ -2433,7 +2433,7 @@ }, "node_modules/static-extend/node_modules/define-property": { "version": "0.2.5", - "resolved": "https://registry.npmjs.org/gitdefine-property/-/define-property-0.2.5.tgz", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "dependencies": { @@ -2445,7 +2445,7 @@ }, "node_modules/static-extend/node_modules/is-descriptor": { "version": "0.1.7", - "resolved": "https://registry.npmjs.org/gitis-descriptor/-/is-descriptor-0.1.7.tgz", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", "dev": true, "dependencies": { @@ -2458,7 +2458,7 @@ }, "node_modules/statuses": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/gitstatuses/-/statuses-1.5.0.tgz", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", "dev": true, "engines": { @@ -2467,7 +2467,7 @@ }, "node_modules/stream-combiner": { "version": "0.0.4", - "resolved": "https://registry.npmjs.org/gitstream-combiner/-/stream-combiner-0.0.4.tgz", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", "dev": true, "dependencies": { @@ -2476,7 +2476,7 @@ }, "node_modules/string_decoder": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/gitstring_decoder/-/string_decoder-1.1.1.tgz", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", "dev": true, "dependencies": { @@ -2485,7 +2485,7 @@ }, "node_modules/string-width": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/gitstring-width/-/string-width-5.1.2.tgz", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, "dependencies": { @@ -2500,7 +2500,7 @@ "node_modules/string-width-cjs": { "name": "string-width", "version": "4.2.3", - "resolved": "https://registry.npmjs.org/gitstring-width/-/string-width-4.2.3.tgz", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha1-JpxxF9J7Ba0uU2gwqOyJXvnG0BA=", "dev": true, "dependencies": { @@ -2514,7 +2514,7 @@ }, "node_modules/string-width-cjs/node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/gitansi-regex/-/ansi-regex-5.0.1.tgz", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha1-CCyyyJyf6GWaMRpTvWpNxTAdswQ=", "dev": true, "engines": { @@ -2523,13 +2523,13 @@ }, "node_modules/string-width-cjs/node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/gitemoji-regex/-/emoji-regex-8.0.0.tgz", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha1-6Bj9ac5cz8tARZT4QpY79TFkzDc=", "dev": true }, "node_modules/string-width-cjs/node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/gitstrip-ansi/-/strip-ansi-6.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha1-nibGPTD1NEPpSJSVshBdN7Z6hdk=", "dev": true, "dependencies": { @@ -2541,7 +2541,7 @@ }, "node_modules/strip-ansi": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/gitstrip-ansi/-/strip-ansi-7.1.0.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "dependencies": { @@ -2554,7 +2554,7 @@ "node_modules/strip-ansi-cjs": { "name": "strip-ansi", "version": "6.0.1", - "resolved": "https://registry.npmjs.org/gitstrip-ansi/-/strip-ansi-6.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha1-nibGPTD1NEPpSJSVshBdN7Z6hdk=", "dev": true, "dependencies": { @@ -2566,7 +2566,7 @@ }, "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/gitansi-regex/-/ansi-regex-5.0.1.tgz", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha1-CCyyyJyf6GWaMRpTvWpNxTAdswQ=", "dev": true, "engines": { @@ -2575,13 +2575,13 @@ }, "node_modules/through": { "version": "2.3.8", - "resolved": "https://registry.npmjs.org/gitthrough/-/through-2.3.8.tgz", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, "node_modules/to-object-path": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/gitto-object-path/-/to-object-path-0.3.0.tgz", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "dev": true, "dependencies": { @@ -2593,7 +2593,7 @@ }, "node_modules/to-object-path/node_modules/kind-of": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/gitkind-of/-/kind-of-3.2.2.tgz", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "dependencies": { @@ -2605,7 +2605,7 @@ }, "node_modules/to-regex": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/gitto-regex/-/to-regex-3.0.2.tgz", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", "integrity": "sha1-E8/dmzNlUvMLUfM6iuG0Knp1mc4=", "dev": true, "dependencies": { @@ -2620,7 +2620,7 @@ }, "node_modules/to-regex-range": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/gitto-regex-range/-/to-regex-range-5.0.1.tgz", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha1-FkjESq58jZiKMmAY7XL1tN0DkuQ=", "dev": true, "dependencies": { @@ -2632,7 +2632,7 @@ }, "node_modules/toidentifier": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gittoidentifier/-/toidentifier-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true, "engines": { @@ -2641,7 +2641,7 @@ }, "node_modules/union-value": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gitunion-value/-/union-value-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", "integrity": "sha1-C2/nuDWuzaYcbqTU8CwUIh4QmEc=", "dev": true, "dependencies": { @@ -2656,7 +2656,7 @@ }, "node_modules/union-value/node_modules/is-extendable": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/gitis-extendable/-/is-extendable-0.1.1.tgz", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true, "engines": { @@ -2665,13 +2665,13 @@ }, "node_modules/unix-crypt-td-js": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/gitunix-crypt-td-js/-/unix-crypt-td-js-1.1.4.tgz", + "resolved": "https://registry.npmjs.org/unix-crypt-td-js/-/unix-crypt-td-js-1.1.4.tgz", "integrity": "sha1-SRLfrRyK630g+go55MMZGMHV1d0=", "dev": true }, "node_modules/unpipe": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gitunpipe/-/unpipe-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", "dev": true, "engines": { @@ -2680,7 +2680,7 @@ }, "node_modules/unset-value": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gitunset-value/-/unset-value-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "dev": true, "dependencies": { @@ -2693,7 +2693,7 @@ }, "node_modules/unset-value/node_modules/has-value": { "version": "0.3.1", - "resolved": "https://registry.npmjs.org/githas-value/-/has-value-0.3.1.tgz", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", "dev": true, "dependencies": { @@ -2707,7 +2707,7 @@ }, "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/gitisobject/-/isobject-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", "dev": true, "dependencies": { @@ -2719,7 +2719,7 @@ }, "node_modules/unset-value/node_modules/has-values": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/githas-values/-/has-values-0.1.4.tgz", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", "dev": true, "engines": { @@ -2728,7 +2728,7 @@ }, "node_modules/upath": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gitupath/-/upath-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", "integrity": "sha1-j2bbzVWog6za5ECK+LA1pQRMGJQ=", "dev": true, "engines": { @@ -2738,14 +2738,14 @@ }, "node_modules/urix": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/giturix/-/urix-0.1.0.tgz", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", "deprecated": "Please see https://github.com/lydell/urix#deprecated", "dev": true }, "node_modules/use": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/gituse/-/use-3.1.1.tgz", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", "integrity": "sha1-1QyMrHmhn7wg8pEfVuuXP04QBw8=", "dev": true, "engines": { @@ -2754,13 +2754,13 @@ }, "node_modules/util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/gitutil-deprecate/-/util-deprecate-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, "node_modules/utils-merge": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gitutils-merge/-/utils-merge-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", "dev": true, "engines": { @@ -2769,7 +2769,7 @@ }, "node_modules/uuid": { "version": "3.4.0", - "resolved": "https://registry.npmjs.org/gituuid/-/uuid-3.4.0.tgz", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha1-sj5DWK+oogL+ehAK8fX4g/AgB+4=", "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", "dev": true, @@ -2779,7 +2779,7 @@ }, "node_modules/vary": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/gitvary/-/vary-1.1.2.tgz", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", "dev": true, "engines": { @@ -2788,7 +2788,7 @@ }, "node_modules/websocket-driver": { "version": "0.7.4", - "resolved": "https://registry.npmjs.org/gitwebsocket-driver/-/websocket-driver-0.7.4.tgz", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", "integrity": "sha1-ia1Slbv2S0gKvLox5JU6ynBvV2A=", "dev": true, "dependencies": { @@ -2802,7 +2802,7 @@ }, "node_modules/websocket-extensions": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/gitwebsocket-extensions/-/websocket-extensions-0.1.4.tgz", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", "integrity": "sha1-f4RzvIOd/YdgituV1+sHUhFXikI=", "dev": true, "engines": { @@ -2811,7 +2811,7 @@ }, "node_modules/which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/gitwhich/-/which-2.0.2.tgz", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha1-fGqN0KY2oDJ+ELWckobu6T8/UbE=", "dev": true, "dependencies": { @@ -2826,7 +2826,7 @@ }, "node_modules/wrap-ansi": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/gitwrap-ansi/-/wrap-ansi-8.1.0.tgz", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, "dependencies": { @@ -2841,7 +2841,7 @@ "node_modules/wrap-ansi-cjs": { "name": "wrap-ansi", "version": "7.0.0", - "resolved": "https://registry.npmjs.org/gitwrap-ansi/-/wrap-ansi-7.0.0.tgz", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha1-Z+FFz/UQpqaYS98RUpEdadLrnkM=", "dev": true, "dependencies": { @@ -2855,7 +2855,7 @@ }, "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/gitansi-regex/-/ansi-regex-5.0.1.tgz", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha1-CCyyyJyf6GWaMRpTvWpNxTAdswQ=", "dev": true, "engines": { @@ -2864,7 +2864,7 @@ }, "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/gitansi-styles/-/ansi-styles-4.3.0.tgz", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=", "dev": true, "dependencies": { @@ -2876,13 +2876,13 @@ }, "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/gitemoji-regex/-/emoji-regex-8.0.0.tgz", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha1-6Bj9ac5cz8tARZT4QpY79TFkzDc=", "dev": true }, "node_modules/wrap-ansi-cjs/node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/gitstring-width/-/string-width-4.2.3.tgz", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha1-JpxxF9J7Ba0uU2gwqOyJXvnG0BA=", "dev": true, "dependencies": { @@ -2896,7 +2896,7 @@ }, "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/gitstrip-ansi/-/strip-ansi-6.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha1-nibGPTD1NEPpSJSVshBdN7Z6hdk=", "dev": true, "dependencies": { From 183bd0cbd2446e7c9248465c66291793cd722597 Mon Sep 17 00:00:00 2001 From: Dylan Owen Date: Thu, 9 May 2024 14:39:19 -0700 Subject: [PATCH 3/6] Version 3 --- readme.md | 65 ++++++++- spec/graphql-multipart-request-v2.md | 204 +++++++++++++++++++++++++++ 2 files changed, 266 insertions(+), 3 deletions(-) create mode 100644 spec/graphql-multipart-request-v2.md diff --git a/readme.md b/readme.md index 9cfa3c3..fef7438 100644 --- a/readme.md +++ b/readme.md @@ -1,8 +1,14 @@ # GraphQL Multipart Request Spec -This specification describes how to attach additional files to a GraphQL request using `multipart/form-data`. The intent -is to be the continuation of https://github.com/jaydenseric/graphql-multipart-request-spec starting at Version 3 and to -support backwards compatibility with Version 2 for both clients and servers. +An interoperable [multipart form](https://tools.ietf.org/html/rfc7578) field structure for GraphQL requests, used by various file upload client/server implementations. + +It’s possible to implement: + +- Nesting files anywhere within operations. +- Operation batching. +- File deduplication. +- File upload streams in resolvers. +- Aborting file uploads in resolvers. ## Example @@ -23,3 +29,56 @@ Alpha file content. --boundary-- ``` + +![Sync vs async GraphQL multipart request middleware](sync-vs-async-graphql-multipart-request-middleware.svg) + +## [Spec](./spec/GraphQLMultipartRequest.md) + +## Security + +GraphQL server authentication and security mechanisms are beyond the scope of this specification, which only covers a multipart form field structure for GraphQL requests. + +Note that a GraphQL multipart request has the [Content-Type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) `multipart/form-data`; if a browser making such a request determines it meets the criteria for a “[simple request](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests)” as defined in the [Fetch specification](https://fetch.spec.whatwg.org) for the [Cross-Origin Resource Sharing](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) (CORS) protocol, it won’t cause a [CORS preflight request](https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request). GraphQL server authentication and security mechanisms must consider this to prevent [Cross-Site Request Forgery](https://developer.mozilla.org/en-US/docs/Glossary/CSRF) (CSRF) attacks. + +## Implementations + +Pull requests adding either experimental or mature implementations to these lists are welcome! ~~Strikethrough~~ means the project was renamed, deprecated, or no longer supports this spec out of the box (but might via an optional integration). + +### Client + +- [jaydenseric/graphql-react](https://github.com/jaydenseric/graphql-react) (JS: [npm](https://npm.im/graphql-react)) +- [jaydenseric/apollo-upload-client](https://github.com/jaydenseric/apollo-upload-client) (JS: [npm](https://npm.im/apollo-upload-client)) +- [jaydenseric/extract-files](https://github.com/jaydenseric/extract-files) (JS: [npm](https://npm.im/extract-files)) +- [nearform/graphql-hooks](https://github.com/nearform/graphql-hooks) (JS: [npm](https://npm.im/graphql-hooks)) +- [klis87/redux-saga-requests-graphql](https://github.com/klis87/redux-saga-requests/tree/master/packages/redux-saga-requests-graphql) (JS: [npm](https://npm.im/redux-saga-requests-graphql)) +- [imolorhe/altair](https://github.com/imolorhe/altair) (JS: [npm](https://npm.im/altair-static)) +- [haffdata/buoy](https://github.com/haffdata/buoy) (JS: [npm](https://npm.im/@buoy/client)) +- [FormidableLabs/urql](https://github.com/FormidableLabs/urql) (JS: [npm](https://npm.im/@urql/exchange-multipart-fetch)) +- [~~apollo-fetch-upload~~](https://github.com/apollographql/apollo-fetch/tree/master/packages/apollo-fetch-upload) (JS: [npm](https://npm.im/apollo-fetch-upload)) +- [apollographql/apollo-ios](https://github.com/apollographql/apollo-ios) (Swift: [CocoaPods](https://cocoapods.org/pods/Apollo)) +- [apollographql/apollo-android](https://github.com/apollographql/apollo-android) (Java: [Bintray](https://bintray.com/apollographql/android)) +- [zino-app/graphql-flutter](https://github.com/zino-app/graphql-flutter) (Dart: [Pub](https://pub.dev/packages/graphql)) +- [samirelanduk/kirjava](https://github.com/samirelanduk/kirjava) (Python: [PyPi](https://pypi.org/project/kirjava)) +- [DoctorJohn/aiogqlc](https://github.com/DoctorJohn/aiogqlc) (Python: [PyPi](https://pypi.org/project/aiogqlc)) +- [graphql-python/gql](https://github.com/graphql-python/gql) (Python: [PyPi](https://pypi.org/project/gql)) + +### Server + +- [jaydenseric/graphql-upload](https://github.com/jaydenseric/graphql-upload) (JS: [npm](https://npm.im/graphql-upload)) +- [koresar/graphql-upload-minimal](https://github.com/koresar/graphql-upload-minimal) (JS: [npm](https://npm.im/graphql-upload-minimal)) +- [dotansimha/graphql-yoga](https://github.com/dotansimha/graphql-yoga) (JS: [npm](https://npm.im/@graphql-yoga/common)) +- [~~apollographql/apollo-server~~](https://github.com/apollographql/apollo-server) (JS: [npm](https://npm.im/apollo-server)) +- [~~jaydenseric/apollo-upload-server~~](https://github.com/jaydenseric/apollo-upload-server) (JS: [npm](https://npm.im/apollo-upload-server)) +- [99designs/gqlgen](https://github.com/99designs/gqlgen) (Go: [GitHub](https://github.com/99designs/gqlgen)) +- [jpascal/graphql-upload](https://github.com/jpascal/graphql-upload) (Go: [GitHub](https://github.com/jpascal/graphql-upload)) +- [jetruby/apollo_upload_server-ruby](https://github.com/jetruby/apollo_upload_server-ruby) (Ruby: [Gem](https://rubygems.org/gems/apollo_upload_server)) +- [Ecodev/graphql-upload](https://github.com/Ecodev/graphql-upload) (PHP: [Composer](https://packagist.org/packages/ecodev/graphql-upload)) +- [rebing/graphql-laravel](https://github.com/rebing/graphql-laravel) (PHP: [Composer](https://packagist.org/packages/rebing/graphql-laravel)) +- [nuwave/lighthouse](https://github.com/nuwave/lighthouse) (PHP: [Composer](https://packagist.org/packages/nuwave/lighthouse)) +- [overblog/graphql-bundle](https://github.com/overblog/GraphQLBundle) (PHP: [Composer](https://packagist.org/packages/overblog/graphql-bundle)) +- [infinityloop-dev/graphpinator](https://github.com/infinityloop-dev/graphpinator) (PHP: [Composer](https://packagist.org/packages/infinityloop-dev/graphpinator)) +- [lmcgartland/graphene-file-upload](https://github.com/lmcgartland/graphene-file-upload) (Python: [PyPi](https://pypi.org/project/graphene-file-upload)) +- [strawberry-graphql/strawberry](https://github.com/strawberry-graphql/strawberry) (Python: [PyPi](https://pypi.org/project/strawberry-graphql)) +- [graphql-java-kickstart/graphql-java-servlet](https://github.com/graphql-java-kickstart/graphql-java-servlet) (Java: [Maven](https://mvnrepository.com/artifact/com.graphql-java/graphql-java-servlet)) +- [ChilliCream/hotchocolate](https://github.com/ChilliCream/hotchocolate) (C#: [NuGet](https://www.nuget.org/packages/HotChocolate)) +- [async-graphql/async-graphql](https://github.com/async-graphql/async-graphql) (Rust: [Crates](https://crates.io/crates/async-graphql)) diff --git a/spec/graphql-multipart-request-v2.md b/spec/graphql-multipart-request-v2.md new file mode 100644 index 0000000..3f252a2 --- /dev/null +++ b/spec/graphql-multipart-request-v2.md @@ -0,0 +1,204 @@ +# GraphQL Multipart Request V2 + +## Multipart form field structure + +An “operations object” is an [Apollo GraphQL POST request](https://www.apollographql.com/docs/apollo-server/workflow/requests/#post-requests) (or array of requests if batching). An “operations path” is an [`object-path`](https://npm.im/object-path) string to locate a file within an operations object. + +So operations can be resolved while the files are still uploading, the fields are ordered: + +1. `operations`: A JSON encoded operations object with files replaced with `null`. +2. `map`: A JSON encoded map of where files occurred in the operations. For each file, the key is the file multipart form field name and the value is an array of operations paths. +3. File fields: Each file extracted from the operations object with a unique, arbitrary field name. + +## Examples + +### Single file + +#### Operations + +```js +{ + query: ` + mutation($file: Upload!) { + singleUpload(file: $file) { + id + } + } + `, + variables: { + file: File // a.txt + } +} +``` + +#### cURL request + +```shell +curl localhost:3001/graphql \ + -F operations='{ "query": "mutation ($file: Upload!) { singleUpload(file: $file) { id } }", "variables": { "file": null } }' \ + -F map='{ "0": ["variables.file"] }' \ + -F 0=@a.txt +``` + +#### Request payload + +``` +--------------------------cec8e8123c05ba25 +Content-Disposition: form-data; name="operations" + +{ "query": "mutation ($file: Upload!) { singleUpload(file: $file) { id } }", "variables": { "file": null } } +--------------------------cec8e8123c05ba25 +Content-Disposition: form-data; name="map" + +{ "0": ["variables.file"] } +--------------------------cec8e8123c05ba25 +Content-Disposition: form-data; name="0"; filename="a.txt" +Content-Type: text/plain + +Alpha file content. + +--------------------------cec8e8123c05ba25-- +``` + +### File list + +#### Operations + +```js +{ + query: ` + mutation($files: [Upload!]!) { + multipleUpload(files: $files) { + id + } + } + `, + variables: { + files: [ + File, // b.txt + File // c.txt + ] + } +} +``` + +#### cURL request + +```shell +curl localhost:3001/graphql \ + -F operations='{ "query": "mutation($files: [Upload!]!) { multipleUpload(files: $files) { id } }", "variables": { "files": [null, null] } }' \ + -F map='{ "0": ["variables.files.0"], "1": ["variables.files.1"] }' \ + -F 0=@b.txt \ + -F 1=@c.txt +``` + +#### Request payload + +``` +--------------------------ec62457de6331cad +Content-Disposition: form-data; name="operations" + +{ "query": "mutation($files: [Upload!]!) { multipleUpload(files: $files) { id } }", "variables": { "files": [null, null] } } +--------------------------ec62457de6331cad +Content-Disposition: form-data; name="map" + +{ "0": ["variables.files.0"], "1": ["variables.files.1"] } +--------------------------ec62457de6331cad +Content-Disposition: form-data; name="0"; filename="b.txt" +Content-Type: text/plain + +Bravo file content. + +--------------------------ec62457de6331cad +Content-Disposition: form-data; name="1"; filename="c.txt" +Content-Type: text/plain + +Charlie file content. + +--------------------------ec62457de6331cad-- +``` + +### Batching + +#### Operations + +```js +[ + { + query: ` + mutation($file: Upload!) { + singleUpload(file: $file) { + id + } + } + `, + variables: { + file: File, // a.txt + }, + }, + { + query: ` + mutation($files: [Upload!]!) { + multipleUpload(files: $files) { + id + } + } + `, + variables: { + files: [ + File, // b.txt + File, // c.txt + ], + }, + }, +]; +``` + +#### cURL request + +```shell +curl localhost:3001/graphql \ + -F operations='[{ "query": "mutation ($file: Upload!) { singleUpload(file: $file) { id } }", "variables": { "file": null } }, { "query": "mutation($files: [Upload!]!) { multipleUpload(files: $files) { id } }", "variables": { "files": [null, null] } }]' \ + -F map='{ "0": ["0.variables.file"], "1": ["1.variables.files.0"], "2": ["1.variables.files.1"] }' \ + -F 0=@a.txt \ + -F 1=@b.txt \ + -F 2=@c.txt +``` + +#### Request payload + +``` +--------------------------627436eaefdbc285 +Content-Disposition: form-data; name="operations" + +[{ "query": "mutation ($file: Upload!) { singleUpload(file: $file) { id } }", "variables": { "file": null } }, { "query": "mutation($files: [Upload!]!) { multipleUpload(files: $files) { id } }", "variables": { "files": [null, null] } }] +--------------------------627436eaefdbc285 +Content-Disposition: form-data; name="map" + +{ "0": ["0.variables.file"], "1": ["1.variables.files.0"], "2": ["1.variables.files.1"] } +--------------------------627436eaefdbc285 +Content-Disposition: form-data; name="0"; filename="a.txt" +Content-Type: text/plain + +Alpha file content. + +--------------------------627436eaefdbc285 +Content-Disposition: form-data; name="1"; filename="b.txt" +Content-Type: text/plain + +Bravo file content. + +--------------------------627436eaefdbc285 +Content-Disposition: form-data; name="2"; filename="c.txt" +Content-Type: text/plain + +Charlie file content. + +--------------------------627436eaefdbc285-- +``` + +## Security + +GraphQL server authentication and security mechanisms are beyond the scope of this specification, which only covers a multipart form field structure for GraphQL requests. + +Note that a GraphQL multipart request has the [Content-Type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) `multipart/form-data`; if a browser making such a request determines it meets the criteria for a “[simple request](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests)” as defined in the [Fetch specification](https://fetch.spec.whatwg.org) for the [Cross-Origin Resource Sharing](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) (CORS) protocol, it won’t cause a [CORS preflight request](https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request). GraphQL server authentication and security mechanisms must consider this to prevent [Cross-Site Request Forgery](https://developer.mozilla.org/en-US/docs/Glossary/CSRF) (CSRF) attacks. From 5c599f1ca36284bda453f9808de40cd8771aa6c6 Mon Sep 17 00:00:00 2001 From: Dylan Owen Date: Thu, 9 May 2024 14:44:33 -0700 Subject: [PATCH 4/6] put back links / files --- .github/funding.yml | 1 + .prettierrc.json | 3 + spec/graphql-multipart-request-v3.md | 12 +-- ...raphql-multipart-request-middleware.sketch | Bin 0 -> 57071 bytes ...c-graphql-multipart-request-middleware.svg | 85 ++++++++++++++++++ 5 files changed, 95 insertions(+), 6 deletions(-) create mode 100644 .github/funding.yml create mode 100644 .prettierrc.json create mode 100644 sync-vs-async-graphql-multipart-request-middleware.sketch create mode 100644 sync-vs-async-graphql-multipart-request-middleware.svg diff --git a/.github/funding.yml b/.github/funding.yml new file mode 100644 index 0000000..4c5a7a0 --- /dev/null +++ b/.github/funding.yml @@ -0,0 +1 @@ +github: jaydenseric diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..d2504b4 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,3 @@ +{ + "proseWrap": "never" +} diff --git a/spec/graphql-multipart-request-v3.md b/spec/graphql-multipart-request-v3.md index 3a06be3..7bda7c5 100644 --- a/spec/graphql-multipart-request-v3.md +++ b/spec/graphql-multipart-request-v3.md @@ -173,7 +173,7 @@ ExecuteMultipartRequest(multipartRequest) : * Else If {partName} is `map` * If this server supports V2 via backwards compatability * The {Server} must handle {multipartRequest} according - to [V2 of this spec](https://github.com/jaydenseric/graphql-multipart-request-spec) + to [V2 of this spec](./graphql-multipart-request-v2.html) * Else ignore this {Part} * Else Store the entry {partName} -> {partValue} in {embeddedPartsMap} @@ -259,7 +259,7 @@ Alpha file content. ### Missing Embedded Parts The request is invalid if it is missing referenced *embedded part*s. This can happen when the {Client} sends a non -*multipart/form-data* request or sends a *multipart/form-data* request missing referenced *embedded part*s. The {Server} +*multipart/form-data* request or sends a *multipart/form-data* request missing referenced *embedded part*s. The {Server} MUST handle these errors as outlined in the GraphQL Spec: {HandleFieldError()}. **Request** @@ -379,7 +379,7 @@ Alpha file content Again. # Backwards Compatability -With [V2 of this spec](https://github.com/jaydenseric/graphql-multipart-request-spec) +With [V2 of this spec](./graphql-multipart-request-v2.html) ## Client Backwards Compatibility @@ -428,9 +428,9 @@ that contains the relevant additional data for clarity. V3 {Server}s MAY choose to support V2 requests of this specification. If a backwards compatible V3 {Server} receives a request with a *map part* it must implement the execution flow defined -by [V2 of this spec](https://github.com/jaydenseric/graphql-multipart-request-spec). The file key's values MUST be -ignored and substituted sequentially with the contents of the *map part*. If no *map part* is present, it MUST implement -the flow described in {ExecuteMultipartRequest()}. +by [V2 of this spec](./graphql-multipart-request-v2.html). The file key's values MUST be ignored and substituted +sequentially with the contents of the *map part*. If no *map part* is present, it MUST implement the flow described in +{ExecuteMultipartRequest()}. # Examples diff --git a/sync-vs-async-graphql-multipart-request-middleware.sketch b/sync-vs-async-graphql-multipart-request-middleware.sketch new file mode 100644 index 0000000000000000000000000000000000000000..3ed8d3c345c5d6d55c7bc8e22742e2341a533ad2 GIT binary patch literal 57071 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 literal 0 HcmV?d00001 diff --git a/sync-vs-async-graphql-multipart-request-middleware.svg b/sync-vs-async-graphql-multipart-request-middleware.svg new file mode 100644 index 0000000..96becab --- /dev/null +++ b/sync-vs-async-graphql-multipart-request-middleware.svg @@ -0,0 +1,85 @@ + + Sync vs async GraphQL multipart request middleware + + + + GraphQL API upload + + + + Cloud storage upload + + + + + + 1mb.png + + + + + + 2mb.png + + + + + + 3mb.png + + + + Response + + + Receive + request + + + Run + resolver + + + Sync: + Store files temporarily on API server (filesystem or memory). + + + + + + 1mb.png + + + + + + 2mb.png + + + + + + 3mb.png + + + + Receive + request + + + Response + + + Run + resolver + + + Async: + Pass file upload streams into resolver. + + + Sync vs async GraphQL + multipart request middleware + + + From bd8f7e636f6a12799c0a526a9593b3b497f51807 Mon Sep 17 00:00:00 2001 From: Dylan Owen Date: Thu, 9 May 2024 14:46:41 -0700 Subject: [PATCH 5/6] readme reorg --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index fef7438..2cfe426 100644 --- a/readme.md +++ b/readme.md @@ -2,6 +2,8 @@ An interoperable [multipart form](https://tools.ietf.org/html/rfc7578) field structure for GraphQL requests, used by various file upload client/server implementations. +## [Spec](./spec/GraphQLMultipartRequest.md) + It’s possible to implement: - Nesting files anywhere within operations. @@ -32,8 +34,6 @@ Alpha file content. ![Sync vs async GraphQL multipart request middleware](sync-vs-async-graphql-multipart-request-middleware.svg) -## [Spec](./spec/GraphQLMultipartRequest.md) - ## Security GraphQL server authentication and security mechanisms are beyond the scope of this specification, which only covers a multipart form field structure for GraphQL requests. From 7b5e7936c45225e8b98c48a95ce7adf65a0f1388 Mon Sep 17 00:00:00 2001 From: Dylan Owen Date: Thu, 9 May 2024 14:50:42 -0700 Subject: [PATCH 6/6] update links --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 2cfe426..a5c7697 100644 --- a/readme.md +++ b/readme.md @@ -2,7 +2,7 @@ An interoperable [multipart form](https://tools.ietf.org/html/rfc7578) field structure for GraphQL requests, used by various file upload client/server implementations. -## [Spec](./spec/GraphQLMultipartRequest.md) +## [Spec](./spec/graphql-multipart-request-v3.md) It’s possible to implement: