diff --git a/.prettierignore b/.prettierignore index f298afef4..99958d592 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,4 +1,3 @@ types/ schema.graphql -*.generated.* -src/graphql/extendedTypes.ts \ No newline at end of file +*.generated.* \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index be2446273..84ba62605 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ All notable, unreleased changes to this project will be documented in this file. - Enable save button on page pages - #2325 by @orzechdev - Fix pagination errors on voucher and sale pages - #2317 by @orzechdev - Add format tip for text attribute rows - #2340 by @orzechdev +- Add GraphiQL editor to webhook form for defining the subscription query #2885 by @2can @zaiste ## 3.4 diff --git a/locale/defaultMessages.json b/locale/defaultMessages.json index 7c263674d..f66314ac8 100644 --- a/locale/defaultMessages.json +++ b/locale/defaultMessages.json @@ -394,10 +394,6 @@ "context": "delete custom app", "string": "Deleting this app, you will delete all the data and webhooks regarding this app." }, - "1+M/52": { - "context": "section header", - "string": "Webhook Status" - }, "1/oG76": { "context": "dialog header", "string": "Delete Sale" @@ -422,6 +418,10 @@ "context": "weeks after label", "string": "weeks after issue" }, + "16Dpgb": { + "context": "Synchronous events description", + "string": "Synchronous webhook sends payload and waits for a response from the target URL to continue processing." + }, "16PGt9": { "context": "WarehouseSettings all warehouses label", "string": "All warehouses" @@ -581,6 +581,10 @@ "context": "search modal shipping title", "string": "Shipping address" }, + "2RYRdr": { + "context": "webhooks active label", + "string": "Active" + }, "2Sx05f": { "context": "Previous discount label", "string": "Previous discount value" @@ -1427,10 +1431,6 @@ "9YazHG": { "string": "Company" }, - "9Yhddc": { - "context": "input label", - "string": "Registered events" - }, "9Zlogd": { "context": "staff member status", "string": "Active" @@ -2160,6 +2160,10 @@ "context": "settings menu item", "string": "Settings" }, + "F6LHyk": { + "context": "Webhook details objects", + "string": "Objects" + }, "F8gsds": { "context": "unpublish page, button", "string": "Unpublish" @@ -2355,14 +2359,14 @@ "context": "billing address", "string": "Same as shipping address" }, - "GLewww": { - "context": "section header", - "string": "Events" - }, "GLy2UR": { "context": "order history message", "string": "Fulfillment was cancelled" }, + "GNKG74": { + "context": "webhooks inactive label", + "string": "Inactive" + }, "GOdq5V": { "string": "Catalog" }, @@ -2615,10 +2619,6 @@ "context": "PageTypeDeleteWarningDialog single assigned items button label", "string": "View pages" }, - "IBCBi1": { - "context": "webhook active description", - "string": "If you want to disable this webhook please uncheck the box below." - }, "IBw72y": { "context": "switch button", "string": "Is this product shippable?" @@ -3687,10 +3687,6 @@ "context": "button", "string": "Delete Search" }, - "QEvH8Q": { - "context": "section description", - "string": "Assign permissions to register asynchronous events for this webhook." - }, "QFBjlV": { "context": "error message", "string": "Stock for this warehouse already exists for this product variant" @@ -3796,6 +3792,10 @@ "context": "label for radio button", "string": "Product prices are entered without tax" }, + "QpSQ5w": { + "context": "Webhook subscription query card title", + "string": "Payload Query" + }, "Qph0GE": { "context": "dialog content", "string": "Add a new address:" @@ -4135,10 +4135,6 @@ "context": "product inventory, checkbox", "string": "Track Inventory" }, - "TjbB4Y": { - "context": "section subheader", - "string": "Asynchronous events" - }, "Tl+7X4": { "context": "tabel column header", "string": "Refunded Qty" @@ -4460,10 +4456,6 @@ "context": "button label", "string": "Deactivate" }, - "W+x5ZI": { - "context": "webhooks active label", - "string": "Webhook is active" - }, "W/Es0H": { "string": "Order successfully cancelled" }, @@ -5367,6 +5359,10 @@ "context": "empty metadata text", "string": "No metadata created for this element. Use the button below to add new metadata field." }, + "cZN5Jd": { + "context": "Webhook details events", + "string": "Events" + }, "caMMWN": { "string": "Search Warehouse" }, @@ -5470,10 +5466,6 @@ "dPYqy0": { "string": "We are currently exporting your requested CSV. As soon as it is available it will be sent to your email address" }, - "dQdxLT": { - "context": "section subheader", - "string": "Synchronous events" - }, "dS+SOT": { "context": "header", "string": "Column settings" @@ -5617,10 +5609,6 @@ "context": "gift card history message", "string": "Gift card was activated by {activatedBy}" }, - "fHopox": { - "context": "section description", - "string": "Assign permissions to register synchronous events for this webhook." - }, "fLhj3a": { "context": "gift card history message", "string": "Gift card expiry date was updated" @@ -6462,6 +6450,10 @@ "context": "taxes title", "string": "Taxes (VAT included)" }, + "mSCZd4": { + "context": "Webhook details asynchronous events", + "string": "Asynchronous" + }, "mSLr9d": { "context": "voucher code, button", "string": "Generate Code" @@ -7922,6 +7914,10 @@ "context": "button", "string": "Create Voucher" }, + "yAFaVK": { + "context": "Webhook details synchronous events", + "string": "Synchronous" + }, "yDkmX7": { "context": "dialog content", "string": "{counter,plural,one{Are you sure you want to delete this product?} other{Are you sure you want to delete {displayQuantity} products?}}" @@ -7944,6 +7940,10 @@ "context": "voucher uses", "string": "Uses" }, + "yJqbYv": { + "context": "Asynchronous events description", + "string": "Asynchronous webhook sends payload and continues processing." + }, "yJynYK": { "context": "discount value", "string": "discount" diff --git a/package-lock.json b/package-lock.json index e8ec2f785..1f1edaa86 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,9 @@ "@editorjs/quote": "^2.4.0", "@floating-ui/react-dom-interactions": "^0.5.0", "@glideapps/glide-data-grid": "^5.0.0", + "@graphiql/plugin-explorer": "^0.1.12", + "@graphiql/react": "^0.15.0", + "@graphiql/toolkit": "^0.8.0", "@material-ui/core": "^4.12.4", "@material-ui/icons": "^4.11.2", "@material-ui/lab": "^4.0.0-alpha.61", @@ -43,6 +46,7 @@ "find-test-names": "^1.17.1", "fuse.js": "^6.6.2", "fuzzaldrin": "^2.1.0", + "graphiql": "^2.2.0", "graphql": "^15.4.0", "hotkeys-js": "^3.8.1", "is-url": "^1.2.4", @@ -205,7 +209,7 @@ "mochawesome": "^7.0.1", "mochawesome-merge": "^4.2.1", "mochawesome-report-generator": "^6.0.1", - "prettier": "^1.19.1", + "prettier": "^2.8.3", "setup-polly-jest": "^0.9.1", "ts-jest": "^27.1.5" } @@ -3209,6 +3213,88 @@ "react-responsive-carousel": "^3.2.7" } }, + "node_modules/@graphiql/plugin-explorer": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/@graphiql/plugin-explorer/-/plugin-explorer-0.1.12.tgz", + "integrity": "sha512-H7YsmXl96QbYo+8tyV7RXhTDzr7q/W34yZXi0ABnxTMx3K0SGFU9fsnfTliM4TpiRm27lysROriWjqvHbOQXYQ==", + "dependencies": { + "@graphiql/react": "^0.15.0", + "graphiql-explorer": "^0.9.0" + }, + "peerDependencies": { + "graphql": "^15.5.0 || ^16.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@graphiql/react": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@graphiql/react/-/react-0.15.0.tgz", + "integrity": "sha512-kJqkdf6d4Cck05Wt5yCDZXWfs7HZgcpuoWq/v8nOa698qVaNMM3qdG4CpRsZEexku0DSSJzWWuanxd5x+sRcFg==", + "dependencies": { + "@graphiql/toolkit": "^0.8.0", + "@reach/combobox": "^0.17.0", + "@reach/dialog": "^0.17.0", + "@reach/listbox": "^0.17.0", + "@reach/menu-button": "^0.17.0", + "@reach/tooltip": "^0.17.0", + "@reach/visually-hidden": "^0.17.0", + "codemirror": "^5.65.3", + "codemirror-graphql": "^2.0.2", + "copy-to-clipboard": "^3.2.0", + "graphql-language-service": "^5.1.0", + "markdown-it": "^12.2.0", + "set-value": "^4.1.0" + }, + "peerDependencies": { + "graphql": "^15.5.0 || ^16.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@graphiql/react/node_modules/is-primitive": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-3.0.1.tgz", + "integrity": "sha512-GljRxhWvlCNRfZyORiH77FwdFwGcMO620o37EOYC0ORWdq+WYNVqW0w2Juzew4M+L81l6/QS3t5gkkihyRqv9w==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@graphiql/react/node_modules/set-value": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-4.1.0.tgz", + "integrity": "sha512-zTEg4HL0RwVrqcWs3ztF+x1vkxfm0lP+MQQFPiMJTKVceBwEV0A569Ou8l9IYQG8jOZdMVI1hGsc0tmeD2o/Lw==", + "funding": [ + "https://github.com/sponsors/jonschlinkert", + "https://paypal.me/jonathanschlinkert", + "https://jonschlinkert.dev/sponsor" + ], + "dependencies": { + "is-plain-object": "^2.0.4", + "is-primitive": "^3.0.1" + }, + "engines": { + "node": ">=11.0" + } + }, + "node_modules/@graphiql/toolkit": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@graphiql/toolkit/-/toolkit-0.8.0.tgz", + "integrity": "sha512-DbMFhEKejpPzB6k8W3Mj+Rl8geXiw49USDF9Wdi06EEk1XLVh1iebDqveYY+4lViITsV4+BeGikxlqi8umfP4g==", + "dependencies": { + "@n1ru4l/push-pull-async-iterable-iterator": "^3.1.0", + "meros": "^1.1.4" + }, + "peerDependencies": { + "graphql": "^15.5.0 || ^16.0.0", + "graphql-ws": ">= 4.5.0" + }, + "peerDependenciesMeta": { + "graphql-ws": { + "optional": true + } + } + }, "node_modules/@graphql-codegen/add": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@graphql-codegen/add/-/add-3.1.1.tgz", @@ -5928,6 +6014,14 @@ "graphql": "^15.4.0" } }, + "node_modules/@n1ru4l/push-pull-async-iterable-iterator": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@n1ru4l/push-pull-async-iterable-iterator/-/push-pull-async-iterable-iterator-3.2.0.tgz", + "integrity": "sha512-3fkKj25kEjsfObL6IlKPAlHYPq/oYwUkkQ03zsTTiDjD7vg/RxjdiLeCydqtxHZP0JgsXL3D/X5oAkMGzuUp/Q==", + "engines": { + "node": ">=12" + } + }, "node_modules/@nicolo-ribaudo/chokidar-2": { "version": "2.1.8-no-fsevents.3", "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz", @@ -6268,6 +6362,390 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" }, + "node_modules/@reach/combobox": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/combobox/-/combobox-0.17.0.tgz", + "integrity": "sha512-2mYvU5agOBCQBMdlM4cri+P1BbNwp05P1OuDyc33xJSNiBG7BMy4+ZSHJ0X4fyle6rHwSgCAOCLOeWV1XUYjoQ==", + "dependencies": { + "@reach/auto-id": "0.17.0", + "@reach/descendants": "0.17.0", + "@reach/popover": "0.17.0", + "@reach/portal": "0.17.0", + "@reach/utils": "0.17.0", + "prop-types": "^15.7.2", + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "react": "^16.8.0 || 17.x", + "react-dom": "^16.8.0 || 17.x" + } + }, + "node_modules/@reach/combobox/node_modules/@reach/auto-id": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/auto-id/-/auto-id-0.17.0.tgz", + "integrity": "sha512-ud8iPwF52RVzEmkHq1twuqGuPA+moreumUHdtgvU3sr3/15BNhwp3KyDLrKKSz0LP1r3V4pSdyF9MbYM8BoSjA==", + "dependencies": { + "@reach/utils": "0.17.0", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "react": "^16.8.0 || 17.x", + "react-dom": "^16.8.0 || 17.x" + } + }, + "node_modules/@reach/combobox/node_modules/@reach/utils": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/utils/-/utils-0.17.0.tgz", + "integrity": "sha512-M5y8fCBbrWeIsxedgcSw6oDlAMQDkl5uv3VnMVJ7guwpf4E48Xlh1v66z/1BgN/WYe2y8mB/ilFD2nysEfdGeA==", + "dependencies": { + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "react": "^16.8.0 || 17.x", + "react-dom": "^16.8.0 || 17.x" + } + }, + "node_modules/@reach/combobox/node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, + "node_modules/@reach/descendants": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/descendants/-/descendants-0.17.0.tgz", + "integrity": "sha512-c7lUaBfjgcmKFZiAWqhG+VnXDMEhPkI4kAav/82XKZD6NVvFjsQOTH+v3tUkskrAPV44Yuch0mFW/u5Ntifr7Q==", + "dependencies": { + "@reach/utils": "0.17.0", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "react": "^16.8.0 || 17.x", + "react-dom": "^16.8.0 || 17.x" + } + }, + "node_modules/@reach/descendants/node_modules/@reach/utils": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/utils/-/utils-0.17.0.tgz", + "integrity": "sha512-M5y8fCBbrWeIsxedgcSw6oDlAMQDkl5uv3VnMVJ7guwpf4E48Xlh1v66z/1BgN/WYe2y8mB/ilFD2nysEfdGeA==", + "dependencies": { + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "react": "^16.8.0 || 17.x", + "react-dom": "^16.8.0 || 17.x" + } + }, + "node_modules/@reach/descendants/node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, + "node_modules/@reach/dialog": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/dialog/-/dialog-0.17.0.tgz", + "integrity": "sha512-AnfKXugqDTGbeG3c8xDcrQDE4h9b/vnc27Sa118oQSquz52fneUeX9MeFb5ZEiBJK8T5NJpv7QUTBIKnFCAH5A==", + "dependencies": { + "@reach/portal": "0.17.0", + "@reach/utils": "0.17.0", + "prop-types": "^15.7.2", + "react-focus-lock": "^2.5.2", + "react-remove-scroll": "^2.4.3", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "react": "^16.8.0 || 17.x", + "react-dom": "^16.8.0 || 17.x" + } + }, + "node_modules/@reach/dialog/node_modules/@reach/utils": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/utils/-/utils-0.17.0.tgz", + "integrity": "sha512-M5y8fCBbrWeIsxedgcSw6oDlAMQDkl5uv3VnMVJ7guwpf4E48Xlh1v66z/1BgN/WYe2y8mB/ilFD2nysEfdGeA==", + "dependencies": { + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "react": "^16.8.0 || 17.x", + "react-dom": "^16.8.0 || 17.x" + } + }, + "node_modules/@reach/dialog/node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, + "node_modules/@reach/dropdown": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/dropdown/-/dropdown-0.17.0.tgz", + "integrity": "sha512-qBTIGInhxtPHtdj4Pl2XZgZMz3e37liydh0xR3qc48syu7g71sL4nqyKjOzThykyfhA3Pb3/wFgsFJKGTSdaig==", + "dependencies": { + "@reach/auto-id": "0.17.0", + "@reach/descendants": "0.17.0", + "@reach/popover": "0.17.0", + "@reach/utils": "0.17.0", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "react": "^16.8.0 || 17.x", + "react-dom": "^16.8.0 || 17.x" + } + }, + "node_modules/@reach/dropdown/node_modules/@reach/auto-id": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/auto-id/-/auto-id-0.17.0.tgz", + "integrity": "sha512-ud8iPwF52RVzEmkHq1twuqGuPA+moreumUHdtgvU3sr3/15BNhwp3KyDLrKKSz0LP1r3V4pSdyF9MbYM8BoSjA==", + "dependencies": { + "@reach/utils": "0.17.0", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "react": "^16.8.0 || 17.x", + "react-dom": "^16.8.0 || 17.x" + } + }, + "node_modules/@reach/dropdown/node_modules/@reach/utils": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/utils/-/utils-0.17.0.tgz", + "integrity": "sha512-M5y8fCBbrWeIsxedgcSw6oDlAMQDkl5uv3VnMVJ7guwpf4E48Xlh1v66z/1BgN/WYe2y8mB/ilFD2nysEfdGeA==", + "dependencies": { + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "react": "^16.8.0 || 17.x", + "react-dom": "^16.8.0 || 17.x" + } + }, + "node_modules/@reach/dropdown/node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, + "node_modules/@reach/listbox": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/listbox/-/listbox-0.17.0.tgz", + "integrity": "sha512-AMnH1P6/3VKy2V/nPb4Es441arYR+t4YRdh9jdcFVrCOD6y7CQrlmxsYjeg9Ocdz08XpdoEBHM3PKLJqNAUr7A==", + "dependencies": { + "@reach/auto-id": "0.17.0", + "@reach/descendants": "0.17.0", + "@reach/machine": "0.17.0", + "@reach/popover": "0.17.0", + "@reach/utils": "0.17.0", + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": "^16.8.0 || 17.x", + "react-dom": "^16.8.0 || 17.x" + } + }, + "node_modules/@reach/listbox/node_modules/@reach/auto-id": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/auto-id/-/auto-id-0.17.0.tgz", + "integrity": "sha512-ud8iPwF52RVzEmkHq1twuqGuPA+moreumUHdtgvU3sr3/15BNhwp3KyDLrKKSz0LP1r3V4pSdyF9MbYM8BoSjA==", + "dependencies": { + "@reach/utils": "0.17.0", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "react": "^16.8.0 || 17.x", + "react-dom": "^16.8.0 || 17.x" + } + }, + "node_modules/@reach/listbox/node_modules/@reach/utils": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/utils/-/utils-0.17.0.tgz", + "integrity": "sha512-M5y8fCBbrWeIsxedgcSw6oDlAMQDkl5uv3VnMVJ7guwpf4E48Xlh1v66z/1BgN/WYe2y8mB/ilFD2nysEfdGeA==", + "dependencies": { + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "react": "^16.8.0 || 17.x", + "react-dom": "^16.8.0 || 17.x" + } + }, + "node_modules/@reach/listbox/node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, + "node_modules/@reach/machine": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/machine/-/machine-0.17.0.tgz", + "integrity": "sha512-9EHnuPgXzkbRENvRUzJvVvYt+C2jp7PGN0xon7ffmKoK8rTO6eA/bb7P0xgloyDDQtu88TBUXKzW0uASqhTXGA==", + "dependencies": { + "@reach/utils": "0.17.0", + "@xstate/fsm": "1.4.0", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "react": "^16.8.0 || 17.x", + "react-dom": "^16.8.0 || 17.x" + } + }, + "node_modules/@reach/machine/node_modules/@reach/utils": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/utils/-/utils-0.17.0.tgz", + "integrity": "sha512-M5y8fCBbrWeIsxedgcSw6oDlAMQDkl5uv3VnMVJ7guwpf4E48Xlh1v66z/1BgN/WYe2y8mB/ilFD2nysEfdGeA==", + "dependencies": { + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "react": "^16.8.0 || 17.x", + "react-dom": "^16.8.0 || 17.x" + } + }, + "node_modules/@reach/machine/node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, + "node_modules/@reach/menu-button": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/menu-button/-/menu-button-0.17.0.tgz", + "integrity": "sha512-YyuYVyMZKamPtivoEI6D0UEILYH3qZtg4kJzEAuzPmoR/aHN66NZO75Fx0gtjG1S6fZfbiARaCOZJC0VEiDOtQ==", + "dependencies": { + "@reach/dropdown": "0.17.0", + "@reach/popover": "0.17.0", + "@reach/utils": "0.17.0", + "prop-types": "^15.7.2", + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "react": "^16.8.0 || 17.x", + "react-dom": "^16.8.0 || 17.x", + "react-is": "^16.8.0 || 17.x" + } + }, + "node_modules/@reach/menu-button/node_modules/@reach/utils": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/utils/-/utils-0.17.0.tgz", + "integrity": "sha512-M5y8fCBbrWeIsxedgcSw6oDlAMQDkl5uv3VnMVJ7guwpf4E48Xlh1v66z/1BgN/WYe2y8mB/ilFD2nysEfdGeA==", + "dependencies": { + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "react": "^16.8.0 || 17.x", + "react-dom": "^16.8.0 || 17.x" + } + }, + "node_modules/@reach/menu-button/node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, + "node_modules/@reach/observe-rect": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@reach/observe-rect/-/observe-rect-1.2.0.tgz", + "integrity": "sha512-Ba7HmkFgfQxZqqaeIWWkNK0rEhpxVQHIoVyW1YDSkGsGIXzcaW4deC8B0pZrNSSyLTdIk7y+5olKt5+g0GmFIQ==" + }, + "node_modules/@reach/popover": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/popover/-/popover-0.17.0.tgz", + "integrity": "sha512-yYbBF4fMz4Ml4LB3agobZjcZ/oPtPsNv70ZAd7lEC2h7cvhF453pA+zOBGYTPGupKaeBvgAnrMjj7RnxDU5hoQ==", + "dependencies": { + "@reach/portal": "0.17.0", + "@reach/rect": "0.17.0", + "@reach/utils": "0.17.0", + "tabbable": "^4.0.0", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "react": "^16.8.0 || 17.x", + "react-dom": "^16.8.0 || 17.x" + } + }, + "node_modules/@reach/popover/node_modules/@reach/utils": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/utils/-/utils-0.17.0.tgz", + "integrity": "sha512-M5y8fCBbrWeIsxedgcSw6oDlAMQDkl5uv3VnMVJ7guwpf4E48Xlh1v66z/1BgN/WYe2y8mB/ilFD2nysEfdGeA==", + "dependencies": { + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "react": "^16.8.0 || 17.x", + "react-dom": "^16.8.0 || 17.x" + } + }, + "node_modules/@reach/popover/node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, + "node_modules/@reach/portal": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/portal/-/portal-0.17.0.tgz", + "integrity": "sha512-+IxsgVycOj+WOeNPL2NdgooUdHPSY285wCtj/iWID6akyr4FgGUK7sMhRM9aGFyrGpx2vzr+eggbUmAVZwOz+A==", + "dependencies": { + "@reach/utils": "0.17.0", + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "react": "^16.8.0 || 17.x", + "react-dom": "^16.8.0 || 17.x" + } + }, + "node_modules/@reach/portal/node_modules/@reach/utils": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/utils/-/utils-0.17.0.tgz", + "integrity": "sha512-M5y8fCBbrWeIsxedgcSw6oDlAMQDkl5uv3VnMVJ7guwpf4E48Xlh1v66z/1BgN/WYe2y8mB/ilFD2nysEfdGeA==", + "dependencies": { + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "react": "^16.8.0 || 17.x", + "react-dom": "^16.8.0 || 17.x" + } + }, + "node_modules/@reach/portal/node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, + "node_modules/@reach/rect": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/rect/-/rect-0.17.0.tgz", + "integrity": "sha512-3YB7KA5cLjbLc20bmPkJ06DIfXSK06Cb5BbD2dHgKXjUkT9WjZaLYIbYCO8dVjwcyO3GCNfOmPxy62VsPmZwYA==", + "dependencies": { + "@reach/observe-rect": "1.2.0", + "@reach/utils": "0.17.0", + "prop-types": "^15.7.2", + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "react": "^16.8.0 || 17.x", + "react-dom": "^16.8.0 || 17.x" + } + }, + "node_modules/@reach/rect/node_modules/@reach/utils": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/utils/-/utils-0.17.0.tgz", + "integrity": "sha512-M5y8fCBbrWeIsxedgcSw6oDlAMQDkl5uv3VnMVJ7guwpf4E48Xlh1v66z/1BgN/WYe2y8mB/ilFD2nysEfdGeA==", + "dependencies": { + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "react": "^16.8.0 || 17.x", + "react-dom": "^16.8.0 || 17.x" + } + }, + "node_modules/@reach/rect/node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, "node_modules/@reach/router": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/@reach/router/-/router-1.3.4.tgz", @@ -6284,6 +6762,56 @@ "react-dom": "15.x || 16.x || 16.4.0-alpha.0911da3" } }, + "node_modules/@reach/tooltip": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/tooltip/-/tooltip-0.17.0.tgz", + "integrity": "sha512-HP8Blordzqb/Cxg+jnhGmWQfKgypamcYLBPlcx6jconyV5iLJ5m93qipr1giK7MqKT2wlsKWy44ZcOrJ+Wrf8w==", + "dependencies": { + "@reach/auto-id": "0.17.0", + "@reach/portal": "0.17.0", + "@reach/rect": "0.17.0", + "@reach/utils": "0.17.0", + "@reach/visually-hidden": "0.17.0", + "prop-types": "^15.7.2", + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "react": "^16.8.0 || 17.x", + "react-dom": "^16.8.0 || 17.x" + } + }, + "node_modules/@reach/tooltip/node_modules/@reach/auto-id": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/auto-id/-/auto-id-0.17.0.tgz", + "integrity": "sha512-ud8iPwF52RVzEmkHq1twuqGuPA+moreumUHdtgvU3sr3/15BNhwp3KyDLrKKSz0LP1r3V4pSdyF9MbYM8BoSjA==", + "dependencies": { + "@reach/utils": "0.17.0", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "react": "^16.8.0 || 17.x", + "react-dom": "^16.8.0 || 17.x" + } + }, + "node_modules/@reach/tooltip/node_modules/@reach/utils": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/utils/-/utils-0.17.0.tgz", + "integrity": "sha512-M5y8fCBbrWeIsxedgcSw6oDlAMQDkl5uv3VnMVJ7guwpf4E48Xlh1v66z/1BgN/WYe2y8mB/ilFD2nysEfdGeA==", + "dependencies": { + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "react": "^16.8.0 || 17.x", + "react-dom": "^16.8.0 || 17.x" + } + }, + "node_modules/@reach/tooltip/node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, "node_modules/@reach/utils": { "version": "0.16.0", "resolved": "https://registry.npmjs.org/@reach/utils/-/utils-0.16.0.tgz", @@ -6302,6 +6830,24 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" }, + "node_modules/@reach/visually-hidden": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/visually-hidden/-/visually-hidden-0.17.0.tgz", + "integrity": "sha512-T6xF3Nv8vVnjVkGU6cm0+kWtvliLqPAo8PcZ+WxkKacZsaHTjaZb4v1PaCcyQHmuTNT/vtTVNOJLG0SjQOIb7g==", + "dependencies": { + "prop-types": "^15.7.2", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "react": "^16.8.0 || 17.x", + "react-dom": "^16.8.0 || 17.x" + } + }, + "node_modules/@reach/visually-hidden/node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, "node_modules/@react-dnd/asap": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-4.0.0.tgz", @@ -10177,6 +10723,11 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" }, + "node_modules/@xstate/fsm": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@xstate/fsm/-/fsm-1.4.0.tgz", + "integrity": "sha512-uTHDeu2xI5E1IFwf37JFQM31RrH7mY7877RqPBS4ZqSNUwoLDuct8AhBWaXGnVizBAYyimVwgCyGa9z/NiRhXA==" + }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", @@ -13514,6 +14065,39 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/codemirror": { + "version": "5.65.11", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.11.tgz", + "integrity": "sha512-Gp62g2eKSCHYt10axmGhKq3WoJSvVpvhXmowNq7pZdRVowwtvBR/hi2LSP5srtctKkRT33T6/n8Kv1UGp7JW4A==" + }, + "node_modules/codemirror-graphql": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/codemirror-graphql/-/codemirror-graphql-2.0.2.tgz", + "integrity": "sha512-9c1cItR+8lG7thmTnDDQ3zI8YesNKiFCp2BnLFkYWCtdhSSuCUHebU/Vurew6ayyUl8MBCldNx3Ev66QAWM5Kw==", + "dependencies": { + "graphql-language-service": "5.0.6" + }, + "peerDependencies": { + "@codemirror/language": "6.0.0", + "codemirror": "^5.65.3", + "graphql": "^15.5.0 || ^16.0.0" + } + }, + "node_modules/codemirror-graphql/node_modules/graphql-language-service": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/graphql-language-service/-/graphql-language-service-5.0.6.tgz", + "integrity": "sha512-FjE23aTy45Lr5metxCv3ZgSKEZOzN7ERR+OFC1isV5mHxI0Ob8XxayLTYjQKrs8b3kOpvgTYmSmu6AyXOzYslg==", + "dependencies": { + "nullthrows": "^1.0.0", + "vscode-languageserver-types": "^3.15.1" + }, + "bin": { + "graphql": "dist/temp-bin.js" + }, + "peerDependencies": { + "graphql": "^15.5.0 || ^16.0.0" + } + }, "node_modules/codex-notifier": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/codex-notifier/-/codex-notifier-1.1.2.tgz", @@ -13875,7 +14459,6 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz", "integrity": "sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==", - "optional": true, "dependencies": { "toggle-selection": "^1.0.6" } @@ -15710,8 +16293,7 @@ "node_modules/detect-node-es": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", - "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", - "optional": true + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" }, "node_modules/detect-port": { "version": "1.3.0", @@ -19291,17 +19873,21 @@ } }, "node_modules/focus-lock": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-0.8.1.tgz", - "integrity": "sha512-/LFZOIo82WDsyyv7h7oc0MJF9ACOvDRdx9rWPZ2pgMfNWu/z8hQDBtOchuB/0BVLmuFOZjV02YwUVzNsWx/EzA==", - "optional": true, + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-0.11.4.tgz", + "integrity": "sha512-LzZWJcOBIcHslQ46N3SUu/760iLPSrUtp8omM4gh9du438V2CQdks8TcOu1yvmu2C68nVOBnl1WFiKGPbQ8L6g==", "dependencies": { - "tslib": "^1.9.3" + "tslib": "^2.0.3" }, "engines": { "node": ">=10" } }, + "node_modules/focus-lock/node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -19823,6 +20409,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "engines": { + "node": ">=6" + } + }, "node_modules/get-own-enumerable-property-symbols": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", @@ -20144,6 +20738,33 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, + "node_modules/graphiql": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/graphiql/-/graphiql-2.2.0.tgz", + "integrity": "sha512-w1ujpCKMlkwkoUjeg0HpRiBBTm1WHAjHNkFv1TbMu6trjzz63mQ48GLZlmyQY1yhwmc+diCcvmmAt+AyvKLWWA==", + "dependencies": { + "@graphiql/react": "^0.15.0", + "@graphiql/toolkit": "^0.8.0", + "entities": "^2.0.0", + "graphql-language-service": "^5.1.0", + "markdown-it": "^12.2.0" + }, + "peerDependencies": { + "graphql": "^15.5.0 || ^16.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/graphiql-explorer": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/graphiql-explorer/-/graphiql-explorer-0.9.0.tgz", + "integrity": "sha512-fZC/wsuatqiQDO2otchxriFO0LaWIo/ovF/CQJ1yOudmY0P7pzDiP+l9CEHUiWbizk3e99x6DQG4XG1VxA+d6A==", + "peerDependencies": { + "graphql": "^0.6.0 || ^0.7.0 || ^0.8.0-b || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0", + "react": "^15.6.0 || ^16.0.0", + "react-dom": "^15.6.0 || ^16.0.0" + } + }, "node_modules/graphql": { "version": "15.5.1", "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.5.1.tgz", @@ -20312,6 +20933,21 @@ "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", "dev": true }, + "node_modules/graphql-language-service": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/graphql-language-service/-/graphql-language-service-5.1.0.tgz", + "integrity": "sha512-APffigZ/l2me6soek+Yq5Us3HBwmfw4vns4QoqsTePXkK3knVO8rn0uAC6PmTyglb1pmFFPbYaRIzW4wmcnnGQ==", + "dependencies": { + "nullthrows": "^1.0.0", + "vscode-languageserver-types": "^3.17.1" + }, + "bin": { + "graphql": "dist/temp-bin.js" + }, + "peerDependencies": { + "graphql": "^15.5.0 || ^16.0.0" + } + }, "node_modules/graphql-request": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-3.7.0.tgz", @@ -21845,7 +22481,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "devOptional": true, "dependencies": { "isobject": "^3.0.1" }, @@ -22141,7 +22776,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -25322,6 +25956,14 @@ "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", "devOptional": true }, + "node_modules/linkify-it": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "dependencies": { + "uc.micro": "^1.0.1" + } + }, "node_modules/lint-staged": { "version": "10.5.4", "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.5.4.tgz", @@ -26398,6 +27040,34 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/markdown-it": { + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", + "dependencies": { + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdown-it/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/markdown-it/node_modules/entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/markdown-to-jsx": { "version": "6.11.4", "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-6.11.4.tgz", @@ -26461,6 +27131,11 @@ "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", "optional": true }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==" + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -26539,7 +27214,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/meros/-/meros-1.1.4.tgz", "integrity": "sha512-E9ZXfK9iQfG9s73ars9qvvvbSIkJZF5yOo9j4tcwM5tN8mUKfj/EKN5PzOr3ZH0y5wL7dLAHw3RVEfpQV9Q7VQ==", - "dev": true, "engines": { "node": ">=12" }, @@ -27886,8 +28560,7 @@ "node_modules/nullthrows": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", - "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", - "dev": true + "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==" }, "node_modules/num2fraction": { "version": "1.2.2", @@ -29248,15 +29921,18 @@ } }, "node_modules/prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz", + "integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==", "optional": true, "bin": { "prettier": "bin-prettier.js" }, "engines": { - "node": ">=4" + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } }, "node_modules/pretty-bytes": { @@ -29789,15 +30465,14 @@ } }, "node_modules/react-clientside-effect": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/react-clientside-effect/-/react-clientside-effect-1.2.5.tgz", - "integrity": "sha512-2bL8qFW1TGBHozGGbVeyvnggRpMjibeZM2536AKNENLECutp2yfs44IL8Hmpn8qjFQ2K7A9PnYf3vc7aQq/cPA==", - "optional": true, + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/react-clientside-effect/-/react-clientside-effect-1.2.6.tgz", + "integrity": "sha512-XGGGRQAKY+q25Lz9a/4EPqom7WRjz3z9R2k4jhVKA/puQFH/5Nt27vFZYql4m4NVNdUvX8PS3O7r/Zzm7cjUlg==", "dependencies": { "@babel/runtime": "^7.12.13" }, "peerDependencies": { - "react": "^15.3.0 || ^16.0.0 || ^17.0.0" + "react": "^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" } }, "node_modules/react-dev-utils": { @@ -30537,20 +31212,25 @@ "optional": true }, "node_modules/react-focus-lock": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.5.0.tgz", - "integrity": "sha512-XLxj6uTXgz0US8TmqNU2jMfnXwZG0mH2r/afQqvPEaX6nyEll5LHVcEXk2XDUQ34RVeLPkO/xK5x6c/qiuSq/A==", - "optional": true, + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.9.2.tgz", + "integrity": "sha512-5JfrsOKyA5Zn3h958mk7bAcfphr24jPoMoznJ8vaJF6fUrPQ8zrtEd3ILLOK8P5jvGxdMd96OxWNjDzATfR2qw==", "dependencies": { "@babel/runtime": "^7.0.0", - "focus-lock": "^0.8.1", + "focus-lock": "^0.11.2", "prop-types": "^15.6.2", - "react-clientside-effect": "^1.2.2", - "use-callback-ref": "^1.2.1", - "use-sidecar": "^1.0.1" + "react-clientside-effect": "^1.2.6", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0" + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, "node_modules/react-from-dom": { @@ -30842,6 +31522,61 @@ "loose-envify": "^1.0.0" } }, + "node_modules/react-remove-scroll": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz", + "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==", + "dependencies": { + "react-remove-scroll-bar": "^2.3.3", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz", + "integrity": "sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==", + "dependencies": { + "react-style-singleton": "^2.2.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar/node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, + "node_modules/react-remove-scroll/node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, "node_modules/react-responsive-carousel": { "version": "3.2.23", "resolved": "https://registry.npmjs.org/react-responsive-carousel/-/react-responsive-carousel-3.2.23.tgz", @@ -30944,6 +31679,33 @@ "react-dom": "^16.3.0" } }, + "node_modules/react-style-singleton": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", + "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", + "dependencies": { + "get-nonce": "^1.0.0", + "invariant": "^2.2.4", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-style-singleton/node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, "node_modules/react-syntax-highlighter": { "version": "11.0.2", "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-11.0.2.tgz", @@ -34423,6 +35185,11 @@ "ieee754": "^1.1.13" } }, + "node_modules/tabbable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-4.0.0.tgz", + "integrity": "sha512-H1XoH1URcBOa/rZZWxLxHCtOdVUEev+9vo5YdYhC9tCY4wnybX+VQrCYuy9ubkg69fCBxCONJOSLGfw0DWMffQ==" + }, "node_modules/table": { "version": "6.8.0", "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", @@ -35099,8 +35866,7 @@ "node_modules/toggle-selection": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", - "integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI=", - "optional": true + "integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI=" }, "node_modules/toidentifier": { "version": "1.0.0", @@ -35489,6 +36255,11 @@ "node": "*" } }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -36090,16 +36861,18 @@ } }, "node_modules/use-callback-ref": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.2.5.tgz", - "integrity": "sha512-gN3vgMISAgacF7sqsLPByqoePooY3n2emTH59Ur5d/M8eg4WTWu1xp8i8DHjohftIyEx0S08RiYxbffr4j8Peg==", - "optional": true, + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.0.tgz", + "integrity": "sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==", + "dependencies": { + "tslib": "^2.0.0" + }, "engines": { - "node": ">=8.5.0" + "node": ">=10" }, "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0", - "react": "^16.8.0 || ^17.0.0" + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -36107,6 +36880,11 @@ } } }, + "node_modules/use-callback-ref/node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, "node_modules/use-force-update": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/use-force-update/-/use-force-update-1.0.7.tgz", @@ -36138,21 +36916,31 @@ } }, "node_modules/use-sidecar": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.0.5.tgz", - "integrity": "sha512-k9jnrjYNwN6xYLj1iaGhonDghfvmeTmYjAiGvOr7clwKfPjMXJf4/HOr7oT5tJwYafgp2tG2l3eZEOfoELiMcA==", - "optional": true, + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", + "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", "dependencies": { "detect-node-es": "^1.1.0", - "tslib": "^1.9.3" + "tslib": "^2.0.0" }, "engines": { - "node": ">=8.5.0" + "node": ">=10" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0" + "@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, + "node_modules/use-sidecar/node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, "node_modules/utf8-byte-length": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", @@ -36778,6 +37566,11 @@ "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", "optional": true }, + "node_modules/vscode-languageserver-types": { + "version": "3.17.2", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.2.tgz", + "integrity": "sha512-zHhCWatviizPIq9B7Vh9uvrH6x3sK8itC84HkamnBWoDFJtzBf7SWlpLCZUit72b3os45h6RWQNC9xHRDF8dRA==" + }, "node_modules/vue": { "version": "3.2.31", "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.31.tgz", @@ -40714,6 +41507,60 @@ "react-number-format": "^4.4.1" } }, + "@graphiql/plugin-explorer": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/@graphiql/plugin-explorer/-/plugin-explorer-0.1.12.tgz", + "integrity": "sha512-H7YsmXl96QbYo+8tyV7RXhTDzr7q/W34yZXi0ABnxTMx3K0SGFU9fsnfTliM4TpiRm27lysROriWjqvHbOQXYQ==", + "requires": { + "@graphiql/react": "^0.15.0", + "graphiql-explorer": "^0.9.0" + } + }, + "@graphiql/react": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@graphiql/react/-/react-0.15.0.tgz", + "integrity": "sha512-kJqkdf6d4Cck05Wt5yCDZXWfs7HZgcpuoWq/v8nOa698qVaNMM3qdG4CpRsZEexku0DSSJzWWuanxd5x+sRcFg==", + "requires": { + "@graphiql/toolkit": "^0.8.0", + "@reach/combobox": "^0.17.0", + "@reach/dialog": "^0.17.0", + "@reach/listbox": "^0.17.0", + "@reach/menu-button": "^0.17.0", + "@reach/tooltip": "^0.17.0", + "@reach/visually-hidden": "^0.17.0", + "codemirror": "^5.65.3", + "codemirror-graphql": "^2.0.2", + "copy-to-clipboard": "^3.2.0", + "graphql-language-service": "^5.1.0", + "markdown-it": "^12.2.0", + "set-value": "^4.1.0" + }, + "dependencies": { + "is-primitive": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-3.0.1.tgz", + "integrity": "sha512-GljRxhWvlCNRfZyORiH77FwdFwGcMO620o37EOYC0ORWdq+WYNVqW0w2Juzew4M+L81l6/QS3t5gkkihyRqv9w==" + }, + "set-value": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-4.1.0.tgz", + "integrity": "sha512-zTEg4HL0RwVrqcWs3ztF+x1vkxfm0lP+MQQFPiMJTKVceBwEV0A569Ou8l9IYQG8jOZdMVI1hGsc0tmeD2o/Lw==", + "requires": { + "is-plain-object": "^2.0.4", + "is-primitive": "^3.0.1" + } + } + } + }, + "@graphiql/toolkit": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@graphiql/toolkit/-/toolkit-0.8.0.tgz", + "integrity": "sha512-DbMFhEKejpPzB6k8W3Mj+Rl8geXiw49USDF9Wdi06EEk1XLVh1iebDqveYY+4lViITsV4+BeGikxlqi8umfP4g==", + "requires": { + "@n1ru4l/push-pull-async-iterable-iterator": "^3.1.0", + "meros": "^1.1.4" + } + }, "@graphql-codegen/add": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@graphql-codegen/add/-/add-3.1.1.tgz", @@ -42836,6 +43683,11 @@ "integrity": "sha512-5kJPe2FkPNsCGu9tocKIzUSNO986qAqdnbk8hIFqWlpVPBAmEAOYb1mr6PA18FYAlu7ojWm9Hm13k29aj2GGlQ==", "dev": true }, + "@n1ru4l/push-pull-async-iterable-iterator": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@n1ru4l/push-pull-async-iterable-iterator/-/push-pull-async-iterable-iterator-3.2.0.tgz", + "integrity": "sha512-3fkKj25kEjsfObL6IlKPAlHYPq/oYwUkkQ03zsTTiDjD7vg/RxjdiLeCydqtxHZP0JgsXL3D/X5oAkMGzuUp/Q==" + }, "@nicolo-ribaudo/chokidar-2": { "version": "2.1.8-no-fsevents.3", "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz", @@ -43144,6 +43996,317 @@ } } }, + "@reach/combobox": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/combobox/-/combobox-0.17.0.tgz", + "integrity": "sha512-2mYvU5agOBCQBMdlM4cri+P1BbNwp05P1OuDyc33xJSNiBG7BMy4+ZSHJ0X4fyle6rHwSgCAOCLOeWV1XUYjoQ==", + "requires": { + "@reach/auto-id": "0.17.0", + "@reach/descendants": "0.17.0", + "@reach/popover": "0.17.0", + "@reach/portal": "0.17.0", + "@reach/utils": "0.17.0", + "prop-types": "^15.7.2", + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + }, + "dependencies": { + "@reach/auto-id": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/auto-id/-/auto-id-0.17.0.tgz", + "integrity": "sha512-ud8iPwF52RVzEmkHq1twuqGuPA+moreumUHdtgvU3sr3/15BNhwp3KyDLrKKSz0LP1r3V4pSdyF9MbYM8BoSjA==", + "requires": { + "@reach/utils": "0.17.0", + "tslib": "^2.3.0" + } + }, + "@reach/utils": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/utils/-/utils-0.17.0.tgz", + "integrity": "sha512-M5y8fCBbrWeIsxedgcSw6oDlAMQDkl5uv3VnMVJ7guwpf4E48Xlh1v66z/1BgN/WYe2y8mB/ilFD2nysEfdGeA==", + "requires": { + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + } + }, + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + } + } + }, + "@reach/descendants": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/descendants/-/descendants-0.17.0.tgz", + "integrity": "sha512-c7lUaBfjgcmKFZiAWqhG+VnXDMEhPkI4kAav/82XKZD6NVvFjsQOTH+v3tUkskrAPV44Yuch0mFW/u5Ntifr7Q==", + "requires": { + "@reach/utils": "0.17.0", + "tslib": "^2.3.0" + }, + "dependencies": { + "@reach/utils": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/utils/-/utils-0.17.0.tgz", + "integrity": "sha512-M5y8fCBbrWeIsxedgcSw6oDlAMQDkl5uv3VnMVJ7guwpf4E48Xlh1v66z/1BgN/WYe2y8mB/ilFD2nysEfdGeA==", + "requires": { + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + } + }, + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + } + } + }, + "@reach/dialog": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/dialog/-/dialog-0.17.0.tgz", + "integrity": "sha512-AnfKXugqDTGbeG3c8xDcrQDE4h9b/vnc27Sa118oQSquz52fneUeX9MeFb5ZEiBJK8T5NJpv7QUTBIKnFCAH5A==", + "requires": { + "@reach/portal": "0.17.0", + "@reach/utils": "0.17.0", + "prop-types": "^15.7.2", + "react-focus-lock": "^2.5.2", + "react-remove-scroll": "^2.4.3", + "tslib": "^2.3.0" + }, + "dependencies": { + "@reach/utils": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/utils/-/utils-0.17.0.tgz", + "integrity": "sha512-M5y8fCBbrWeIsxedgcSw6oDlAMQDkl5uv3VnMVJ7guwpf4E48Xlh1v66z/1BgN/WYe2y8mB/ilFD2nysEfdGeA==", + "requires": { + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + } + }, + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + } + } + }, + "@reach/dropdown": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/dropdown/-/dropdown-0.17.0.tgz", + "integrity": "sha512-qBTIGInhxtPHtdj4Pl2XZgZMz3e37liydh0xR3qc48syu7g71sL4nqyKjOzThykyfhA3Pb3/wFgsFJKGTSdaig==", + "requires": { + "@reach/auto-id": "0.17.0", + "@reach/descendants": "0.17.0", + "@reach/popover": "0.17.0", + "@reach/utils": "0.17.0", + "tslib": "^2.3.0" + }, + "dependencies": { + "@reach/auto-id": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/auto-id/-/auto-id-0.17.0.tgz", + "integrity": "sha512-ud8iPwF52RVzEmkHq1twuqGuPA+moreumUHdtgvU3sr3/15BNhwp3KyDLrKKSz0LP1r3V4pSdyF9MbYM8BoSjA==", + "requires": { + "@reach/utils": "0.17.0", + "tslib": "^2.3.0" + } + }, + "@reach/utils": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/utils/-/utils-0.17.0.tgz", + "integrity": "sha512-M5y8fCBbrWeIsxedgcSw6oDlAMQDkl5uv3VnMVJ7guwpf4E48Xlh1v66z/1BgN/WYe2y8mB/ilFD2nysEfdGeA==", + "requires": { + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + } + }, + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + } + } + }, + "@reach/listbox": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/listbox/-/listbox-0.17.0.tgz", + "integrity": "sha512-AMnH1P6/3VKy2V/nPb4Es441arYR+t4YRdh9jdcFVrCOD6y7CQrlmxsYjeg9Ocdz08XpdoEBHM3PKLJqNAUr7A==", + "requires": { + "@reach/auto-id": "0.17.0", + "@reach/descendants": "0.17.0", + "@reach/machine": "0.17.0", + "@reach/popover": "0.17.0", + "@reach/utils": "0.17.0", + "prop-types": "^15.7.2" + }, + "dependencies": { + "@reach/auto-id": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/auto-id/-/auto-id-0.17.0.tgz", + "integrity": "sha512-ud8iPwF52RVzEmkHq1twuqGuPA+moreumUHdtgvU3sr3/15BNhwp3KyDLrKKSz0LP1r3V4pSdyF9MbYM8BoSjA==", + "requires": { + "@reach/utils": "0.17.0", + "tslib": "^2.3.0" + } + }, + "@reach/utils": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/utils/-/utils-0.17.0.tgz", + "integrity": "sha512-M5y8fCBbrWeIsxedgcSw6oDlAMQDkl5uv3VnMVJ7guwpf4E48Xlh1v66z/1BgN/WYe2y8mB/ilFD2nysEfdGeA==", + "requires": { + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + } + }, + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + } + } + }, + "@reach/machine": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/machine/-/machine-0.17.0.tgz", + "integrity": "sha512-9EHnuPgXzkbRENvRUzJvVvYt+C2jp7PGN0xon7ffmKoK8rTO6eA/bb7P0xgloyDDQtu88TBUXKzW0uASqhTXGA==", + "requires": { + "@reach/utils": "0.17.0", + "@xstate/fsm": "1.4.0", + "tslib": "^2.3.0" + }, + "dependencies": { + "@reach/utils": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/utils/-/utils-0.17.0.tgz", + "integrity": "sha512-M5y8fCBbrWeIsxedgcSw6oDlAMQDkl5uv3VnMVJ7guwpf4E48Xlh1v66z/1BgN/WYe2y8mB/ilFD2nysEfdGeA==", + "requires": { + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + } + }, + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + } + } + }, + "@reach/menu-button": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/menu-button/-/menu-button-0.17.0.tgz", + "integrity": "sha512-YyuYVyMZKamPtivoEI6D0UEILYH3qZtg4kJzEAuzPmoR/aHN66NZO75Fx0gtjG1S6fZfbiARaCOZJC0VEiDOtQ==", + "requires": { + "@reach/dropdown": "0.17.0", + "@reach/popover": "0.17.0", + "@reach/utils": "0.17.0", + "prop-types": "^15.7.2", + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + }, + "dependencies": { + "@reach/utils": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/utils/-/utils-0.17.0.tgz", + "integrity": "sha512-M5y8fCBbrWeIsxedgcSw6oDlAMQDkl5uv3VnMVJ7guwpf4E48Xlh1v66z/1BgN/WYe2y8mB/ilFD2nysEfdGeA==", + "requires": { + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + } + }, + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + } + } + }, + "@reach/observe-rect": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@reach/observe-rect/-/observe-rect-1.2.0.tgz", + "integrity": "sha512-Ba7HmkFgfQxZqqaeIWWkNK0rEhpxVQHIoVyW1YDSkGsGIXzcaW4deC8B0pZrNSSyLTdIk7y+5olKt5+g0GmFIQ==" + }, + "@reach/popover": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/popover/-/popover-0.17.0.tgz", + "integrity": "sha512-yYbBF4fMz4Ml4LB3agobZjcZ/oPtPsNv70ZAd7lEC2h7cvhF453pA+zOBGYTPGupKaeBvgAnrMjj7RnxDU5hoQ==", + "requires": { + "@reach/portal": "0.17.0", + "@reach/rect": "0.17.0", + "@reach/utils": "0.17.0", + "tabbable": "^4.0.0", + "tslib": "^2.3.0" + }, + "dependencies": { + "@reach/utils": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/utils/-/utils-0.17.0.tgz", + "integrity": "sha512-M5y8fCBbrWeIsxedgcSw6oDlAMQDkl5uv3VnMVJ7guwpf4E48Xlh1v66z/1BgN/WYe2y8mB/ilFD2nysEfdGeA==", + "requires": { + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + } + }, + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + } + } + }, + "@reach/portal": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/portal/-/portal-0.17.0.tgz", + "integrity": "sha512-+IxsgVycOj+WOeNPL2NdgooUdHPSY285wCtj/iWID6akyr4FgGUK7sMhRM9aGFyrGpx2vzr+eggbUmAVZwOz+A==", + "requires": { + "@reach/utils": "0.17.0", + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + }, + "dependencies": { + "@reach/utils": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/utils/-/utils-0.17.0.tgz", + "integrity": "sha512-M5y8fCBbrWeIsxedgcSw6oDlAMQDkl5uv3VnMVJ7guwpf4E48Xlh1v66z/1BgN/WYe2y8mB/ilFD2nysEfdGeA==", + "requires": { + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + } + }, + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + } + } + }, + "@reach/rect": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/rect/-/rect-0.17.0.tgz", + "integrity": "sha512-3YB7KA5cLjbLc20bmPkJ06DIfXSK06Cb5BbD2dHgKXjUkT9WjZaLYIbYCO8dVjwcyO3GCNfOmPxy62VsPmZwYA==", + "requires": { + "@reach/observe-rect": "1.2.0", + "@reach/utils": "0.17.0", + "prop-types": "^15.7.2", + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + }, + "dependencies": { + "@reach/utils": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/utils/-/utils-0.17.0.tgz", + "integrity": "sha512-M5y8fCBbrWeIsxedgcSw6oDlAMQDkl5uv3VnMVJ7guwpf4E48Xlh1v66z/1BgN/WYe2y8mB/ilFD2nysEfdGeA==", + "requires": { + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + } + }, + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + } + } + }, "@reach/router": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/@reach/router/-/router-1.3.4.tgz", @@ -43156,6 +44319,46 @@ "react-lifecycles-compat": "^3.0.4" } }, + "@reach/tooltip": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/tooltip/-/tooltip-0.17.0.tgz", + "integrity": "sha512-HP8Blordzqb/Cxg+jnhGmWQfKgypamcYLBPlcx6jconyV5iLJ5m93qipr1giK7MqKT2wlsKWy44ZcOrJ+Wrf8w==", + "requires": { + "@reach/auto-id": "0.17.0", + "@reach/portal": "0.17.0", + "@reach/rect": "0.17.0", + "@reach/utils": "0.17.0", + "@reach/visually-hidden": "0.17.0", + "prop-types": "^15.7.2", + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + }, + "dependencies": { + "@reach/auto-id": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/auto-id/-/auto-id-0.17.0.tgz", + "integrity": "sha512-ud8iPwF52RVzEmkHq1twuqGuPA+moreumUHdtgvU3sr3/15BNhwp3KyDLrKKSz0LP1r3V4pSdyF9MbYM8BoSjA==", + "requires": { + "@reach/utils": "0.17.0", + "tslib": "^2.3.0" + } + }, + "@reach/utils": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/utils/-/utils-0.17.0.tgz", + "integrity": "sha512-M5y8fCBbrWeIsxedgcSw6oDlAMQDkl5uv3VnMVJ7guwpf4E48Xlh1v66z/1BgN/WYe2y8mB/ilFD2nysEfdGeA==", + "requires": { + "tiny-warning": "^1.0.3", + "tslib": "^2.3.0" + } + }, + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + } + } + }, "@reach/utils": { "version": "0.16.0", "resolved": "https://registry.npmjs.org/@reach/utils/-/utils-0.16.0.tgz", @@ -43172,6 +44375,22 @@ } } }, + "@reach/visually-hidden": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@reach/visually-hidden/-/visually-hidden-0.17.0.tgz", + "integrity": "sha512-T6xF3Nv8vVnjVkGU6cm0+kWtvliLqPAo8PcZ+WxkKacZsaHTjaZb4v1PaCcyQHmuTNT/vtTVNOJLG0SjQOIb7g==", + "requires": { + "prop-types": "^15.7.2", + "tslib": "^2.3.0" + }, + "dependencies": { + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + } + } + }, "@react-dnd/asap": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-4.0.0.tgz", @@ -46277,6 +47496,11 @@ } } }, + "@xstate/fsm": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@xstate/fsm/-/fsm-1.4.0.tgz", + "integrity": "sha512-uTHDeu2xI5E1IFwf37JFQM31RrH7mY7877RqPBS4ZqSNUwoLDuct8AhBWaXGnVizBAYyimVwgCyGa9z/NiRhXA==" + }, "@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", @@ -49004,6 +50228,30 @@ } } }, + "codemirror": { + "version": "5.65.11", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.11.tgz", + "integrity": "sha512-Gp62g2eKSCHYt10axmGhKq3WoJSvVpvhXmowNq7pZdRVowwtvBR/hi2LSP5srtctKkRT33T6/n8Kv1UGp7JW4A==" + }, + "codemirror-graphql": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/codemirror-graphql/-/codemirror-graphql-2.0.2.tgz", + "integrity": "sha512-9c1cItR+8lG7thmTnDDQ3zI8YesNKiFCp2BnLFkYWCtdhSSuCUHebU/Vurew6ayyUl8MBCldNx3Ev66QAWM5Kw==", + "requires": { + "graphql-language-service": "5.0.6" + }, + "dependencies": { + "graphql-language-service": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/graphql-language-service/-/graphql-language-service-5.0.6.tgz", + "integrity": "sha512-FjE23aTy45Lr5metxCv3ZgSKEZOzN7ERR+OFC1isV5mHxI0Ob8XxayLTYjQKrs8b3kOpvgTYmSmu6AyXOzYslg==", + "requires": { + "nullthrows": "^1.0.0", + "vscode-languageserver-types": "^3.15.1" + } + } + } + }, "codex-notifier": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/codex-notifier/-/codex-notifier-1.1.2.tgz", @@ -49313,7 +50561,6 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz", "integrity": "sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==", - "optional": true, "requires": { "toggle-selection": "^1.0.6" } @@ -50741,8 +51988,7 @@ "detect-node-es": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", - "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", - "optional": true + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" }, "detect-port": { "version": "1.3.0", @@ -53378,12 +54624,18 @@ } }, "focus-lock": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-0.8.1.tgz", - "integrity": "sha512-/LFZOIo82WDsyyv7h7oc0MJF9ACOvDRdx9rWPZ2pgMfNWu/z8hQDBtOchuB/0BVLmuFOZjV02YwUVzNsWx/EzA==", - "optional": true, + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-0.11.4.tgz", + "integrity": "sha512-LzZWJcOBIcHslQ46N3SUu/760iLPSrUtp8omM4gh9du438V2CQdks8TcOu1yvmu2C68nVOBnl1WFiKGPbQ8L6g==", "requires": { - "tslib": "^1.9.3" + "tslib": "^2.0.3" + }, + "dependencies": { + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + } } }, "for-each": { @@ -53808,6 +55060,11 @@ "has-symbols": "^1.0.3" } }, + "get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==" + }, "get-own-enumerable-property-symbols": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", @@ -54060,6 +55317,23 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, + "graphiql": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/graphiql/-/graphiql-2.2.0.tgz", + "integrity": "sha512-w1ujpCKMlkwkoUjeg0HpRiBBTm1WHAjHNkFv1TbMu6trjzz63mQ48GLZlmyQY1yhwmc+diCcvmmAt+AyvKLWWA==", + "requires": { + "@graphiql/react": "^0.15.0", + "@graphiql/toolkit": "^0.8.0", + "entities": "^2.0.0", + "graphql-language-service": "^5.1.0", + "markdown-it": "^12.2.0" + } + }, + "graphiql-explorer": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/graphiql-explorer/-/graphiql-explorer-0.9.0.tgz", + "integrity": "sha512-fZC/wsuatqiQDO2otchxriFO0LaWIo/ovF/CQJ1yOudmY0P7pzDiP+l9CEHUiWbizk3e99x6DQG4XG1VxA+d6A==" + }, "graphql": { "version": "15.5.1", "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.5.1.tgz", @@ -54181,6 +55455,15 @@ } } }, + "graphql-language-service": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/graphql-language-service/-/graphql-language-service-5.1.0.tgz", + "integrity": "sha512-APffigZ/l2me6soek+Yq5Us3HBwmfw4vns4QoqsTePXkK3knVO8rn0uAC6PmTyglb1pmFFPbYaRIzW4wmcnnGQ==", + "requires": { + "nullthrows": "^1.0.0", + "vscode-languageserver-types": "^3.17.1" + } + }, "graphql-request": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-3.7.0.tgz", @@ -55353,7 +56636,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "devOptional": true, "requires": { "isobject": "^3.0.1" } @@ -55573,8 +56855,7 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "devOptional": true + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" }, "isomorphic-fetch": { "version": "3.0.0", @@ -58076,6 +59357,14 @@ "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", "devOptional": true }, + "linkify-it": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "requires": { + "uc.micro": "^1.0.1" + } + }, "lint-staged": { "version": "10.5.4", "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.5.4.tgz", @@ -58926,6 +60215,30 @@ "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz", "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==" }, + "markdown-it": { + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", + "requires": { + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==" + } + } + }, "markdown-to-jsx": { "version": "6.11.4", "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-6.11.4.tgz", @@ -58977,6 +60290,11 @@ "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", "optional": true }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==" + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -59044,8 +60362,7 @@ "meros": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/meros/-/meros-1.1.4.tgz", - "integrity": "sha512-E9ZXfK9iQfG9s73ars9qvvvbSIkJZF5yOo9j4tcwM5tN8mUKfj/EKN5PzOr3ZH0y5wL7dLAHw3RVEfpQV9Q7VQ==", - "dev": true + "integrity": "sha512-E9ZXfK9iQfG9s73ars9qvvvbSIkJZF5yOo9j4tcwM5tN8mUKfj/EKN5PzOr3ZH0y5wL7dLAHw3RVEfpQV9Q7VQ==" }, "methods": { "version": "1.1.2", @@ -60129,8 +61446,7 @@ "nullthrows": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", - "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", - "dev": true + "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==" }, "num2fraction": { "version": "1.2.2", @@ -61196,9 +62512,9 @@ "optional": true }, "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz", + "integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==", "optional": true }, "pretty-bytes": { @@ -61611,10 +62927,9 @@ } }, "react-clientside-effect": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/react-clientside-effect/-/react-clientside-effect-1.2.5.tgz", - "integrity": "sha512-2bL8qFW1TGBHozGGbVeyvnggRpMjibeZM2536AKNENLECutp2yfs44IL8Hmpn8qjFQ2K7A9PnYf3vc7aQq/cPA==", - "optional": true, + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/react-clientside-effect/-/react-clientside-effect-1.2.6.tgz", + "integrity": "sha512-XGGGRQAKY+q25Lz9a/4EPqom7WRjz3z9R2k4jhVKA/puQFH/5Nt27vFZYql4m4NVNdUvX8PS3O7r/Zzm7cjUlg==", "requires": { "@babel/runtime": "^7.12.13" } @@ -62217,17 +63532,16 @@ "optional": true }, "react-focus-lock": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.5.0.tgz", - "integrity": "sha512-XLxj6uTXgz0US8TmqNU2jMfnXwZG0mH2r/afQqvPEaX6nyEll5LHVcEXk2XDUQ34RVeLPkO/xK5x6c/qiuSq/A==", - "optional": true, + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.9.2.tgz", + "integrity": "sha512-5JfrsOKyA5Zn3h958mk7bAcfphr24jPoMoznJ8vaJF6fUrPQ8zrtEd3ILLOK8P5jvGxdMd96OxWNjDzATfR2qw==", "requires": { "@babel/runtime": "^7.0.0", - "focus-lock": "^0.8.1", + "focus-lock": "^0.11.2", "prop-types": "^15.6.2", - "react-clientside-effect": "^1.2.2", - "use-callback-ref": "^1.2.1", - "use-sidecar": "^1.0.1" + "react-clientside-effect": "^1.2.6", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" } }, "react-from-dom": { @@ -62466,6 +63780,41 @@ "react-popper": "^1.3.7" } }, + "react-remove-scroll": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz", + "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==", + "requires": { + "react-remove-scroll-bar": "^2.3.3", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + }, + "dependencies": { + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + } + } + }, + "react-remove-scroll-bar": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz", + "integrity": "sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==", + "requires": { + "react-style-singleton": "^2.2.1", + "tslib": "^2.0.0" + }, + "dependencies": { + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + } + } + }, "react-responsive-carousel": { "version": "3.2.23", "resolved": "https://registry.npmjs.org/react-responsive-carousel/-/react-responsive-carousel-3.2.23.tgz", @@ -62550,6 +63899,23 @@ "react-virtualized": "^9.21.2" } }, + "react-style-singleton": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", + "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", + "requires": { + "get-nonce": "^1.0.0", + "invariant": "^2.2.4", + "tslib": "^2.0.0" + }, + "dependencies": { + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + } + } + }, "react-syntax-highlighter": { "version": "11.0.2", "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-11.0.2.tgz", @@ -65348,6 +66714,11 @@ } } }, + "tabbable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-4.0.0.tgz", + "integrity": "sha512-H1XoH1URcBOa/rZZWxLxHCtOdVUEev+9vo5YdYhC9tCY4wnybX+VQrCYuy9ubkg69fCBxCONJOSLGfw0DWMffQ==" + }, "table": { "version": "6.8.0", "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", @@ -65889,8 +67260,7 @@ "toggle-selection": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", - "integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI=", - "optional": true + "integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI=" }, "toidentifier": { "version": "1.0.0", @@ -66164,6 +67534,11 @@ "integrity": "sha512-6Gurc1n//gjp9eQNXjD9O3M/sMwVtN5S8Lv9bvOYBfKfDNiIIhqiyi01vMBO45u4zkDE420w/e0se7Vs+sIg+g==", "dev": true }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" + }, "unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -66648,10 +68023,19 @@ "devOptional": true }, "use-callback-ref": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.2.5.tgz", - "integrity": "sha512-gN3vgMISAgacF7sqsLPByqoePooY3n2emTH59Ur5d/M8eg4WTWu1xp8i8DHjohftIyEx0S08RiYxbffr4j8Peg==", - "optional": true + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.0.tgz", + "integrity": "sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==", + "requires": { + "tslib": "^2.0.0" + }, + "dependencies": { + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + } + } }, "use-force-update": { "version": "1.0.7", @@ -66672,13 +68056,19 @@ } }, "use-sidecar": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.0.5.tgz", - "integrity": "sha512-k9jnrjYNwN6xYLj1iaGhonDghfvmeTmYjAiGvOr7clwKfPjMXJf4/HOr7oT5tJwYafgp2tG2l3eZEOfoELiMcA==", - "optional": true, + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", + "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", "requires": { "detect-node-es": "^1.1.0", - "tslib": "^1.9.3" + "tslib": "^2.0.0" + }, + "dependencies": { + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + } } }, "utf8-byte-length": { @@ -67133,6 +68523,11 @@ "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", "optional": true }, + "vscode-languageserver-types": { + "version": "3.17.2", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.2.tgz", + "integrity": "sha512-zHhCWatviizPIq9B7Vh9uvrH6x3sK8itC84HkamnBWoDFJtzBf7SWlpLCZUit72b3os45h6RWQNC9xHRDF8dRA==" + }, "vue": { "version": "3.2.31", "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.31.tgz", diff --git a/package.json b/package.json index aaac2560d..8cf576c99 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,9 @@ "@editorjs/paragraph": "^2.8.0", "@editorjs/quote": "^2.4.0", "@glideapps/glide-data-grid": "^5.0.0", + "@graphiql/plugin-explorer": "^0.1.12", + "@graphiql/react": "^0.15.0", + "@graphiql/toolkit": "^0.8.0", "@material-ui/core": "^4.12.4", "@material-ui/icons": "^4.11.2", "@material-ui/lab": "^4.0.0-alpha.61", @@ -50,6 +53,7 @@ "find-test-names": "^1.17.1", "fuse.js": "^6.6.2", "fuzzaldrin": "^2.1.0", + "graphiql": "^2.2.0", "graphql": "^15.4.0", "hotkeys-js": "^3.8.1", "is-url": "^1.2.4", @@ -207,7 +211,7 @@ "mochawesome": "^7.0.1", "mochawesome-merge": "^4.2.1", "mochawesome-report-generator": "^6.0.1", - "prettier": "^1.19.1", + "prettier": "^2.8.3", "setup-polly-jest": "^0.9.1", "ts-jest": "^27.1.5", "jest-environment-jsdom": "^27.5.1" diff --git a/src/components/GraphiQL/GraphiQL.tsx b/src/components/GraphiQL/GraphiQL.tsx new file mode 100644 index 000000000..36d2ae602 --- /dev/null +++ b/src/components/GraphiQL/GraphiQL.tsx @@ -0,0 +1,298 @@ +import { + CopyIcon, + GraphiQLProvider, + GraphiQLProviderProps, + PrettifyIcon, + QueryEditor, + ToolbarButton, + Tooltip, + UnStyledButton, + useCopyQuery, + useEditorContext, + UseHeaderEditorArgs, + usePluginContext, + usePrettifyEditors, + UseQueryEditorArgs, + UseResponseEditorArgs, + UseVariableEditorArgs, + WriteableEditorProps, +} from "@graphiql/react"; +import clsx from "clsx"; +import React, { ComponentType, PropsWithChildren, ReactNode } from "react"; + +import { + useDashboardTheme, + useEditorStyles, + useGraphiQLThemeSwitcher, + useStyles, +} from "./styles"; + +export interface GraphiQLToolbarConfig { + /** + * This content will be rendered after the built-in buttons of the toolbar. + * Note that this will not apply if you provide a completely custom toolbar + * (by passing `GraphiQL.Toolbar` as child to the `GraphiQL` component). + */ + additionalContent?: React.ReactNode; +} + +export type GraphiQLProps = Omit & + GraphiQLInterfaceProps; + +export function GraphiQL({ + dangerouslyAssumeSchemaIsValid, + defaultQuery, + defaultTabs, + externalFragments, + fetcher, + getDefaultFieldNames, + headers, + initialTabs, + inputValueDeprecation, + introspectionQueryName, + maxHistoryLength, + onEditOperationName, + onSchemaChange, + onTabChange, + onTogglePluginVisibility, + operationName, + plugins, + query, + response, + schema, + schemaDescription, + shouldPersistHeaders, + storage, + validationRules, + variables, + visiblePlugin, + defaultHeaders, + ...props +}: GraphiQLProps) { + // Ensure props are correct + if (typeof fetcher !== "function") { + throw new TypeError( + "The `GraphiQL` component requires a `fetcher` function to be passed as prop.", + ); + } + + return ( + + + + ); +} +// Export main windows/panes to be used separately if desired. +GraphiQL.Toolbar = GraphiQLToolbar; + +type AddSuffix, Suffix extends string> = { + [Key in keyof Obj as `${string & Key}${Suffix}`]: Obj[Key]; +}; + +export type GraphiQLInterfaceProps = WriteableEditorProps & + AddSuffix, "Query"> & + Pick & + AddSuffix, "Variables"> & + AddSuffix, "Headers"> & + Pick & { + children?: ReactNode; + defaultEditorToolsVisibility?: boolean | "variables" | "headers"; + isHeadersEditorEnabled?: boolean; + toolbar?: GraphiQLToolbarConfig; + }; + +export function GraphiQLInterface(props: GraphiQLInterfaceProps) { + const editorContext = useEditorContext({ nonNull: true }); + const pluginContext = usePluginContext(); + + const classes = useStyles(); + const { pluginResize, editorResize, editorToolsResize } = useEditorStyles(); + + const copy = useCopyQuery({ onCopyQuery: props.onCopyQuery }); + const prettify = usePrettifyEditors(); + const { rootStyle } = useDashboardTheme(); + + useGraphiQLThemeSwitcher(); + + const PluginContent = pluginContext?.visiblePlugin?.content; + + const children = React.Children.toArray(props.children); + + const toolbar = children.find(child => + isChildComponentType(child, GraphiQL.Toolbar), + ) || ( + <> + prettify()} + label="Prettify query (Shift-Ctrl-P)" + > + + copy()} label="Copy query (Shift-Ctrl-C)"> + + {props.toolbar?.additionalContent || null} + + ); + + const onClickReference = () => { + if (pluginResize.hiddenElement === "first") { + pluginResize.setHiddenElement(null); + } + }; + + return ( +
+
+
+ {pluginContext?.plugins.map(plugin => { + const isVisible = plugin === pluginContext.visiblePlugin; + const label = `${isVisible ? "Hide" : "Show"} ${plugin.title}`; + const Icon = plugin.icon; + return ( + + { + if (isVisible) { + pluginContext.setVisiblePlugin(null); + pluginResize.setHiddenElement("first"); + } else { + pluginContext.setVisiblePlugin(plugin); + pluginResize.setHiddenElement(null); + } + }} + aria-label={label} + > + + + ); + })} +
+
+
+
+
+
+ {PluginContent ? : null} +
+
+
+ {pluginContext?.visiblePlugin ? ( +
+ ) : null} +
+
+
+
+
+
+
+
+
+ +
+
+ {toolbar} +
+
+
+
+
+
+
+
+
+
+ ); +} + +function GraphiQLToolbar(props: PropsWithChildren) { + return <>{props.children}; +} + +GraphiQLToolbar.displayName = "GraphiQLToolbar"; + +function isChildComponentType( + child: any, + component: T, +): child is T { + if ( + child?.type?.displayName && + child.type.displayName === component.displayName + ) { + return true; + } + + return child.type === component; +} + +export default GraphiQL; diff --git a/src/components/GraphiQL/index.ts b/src/components/GraphiQL/index.ts new file mode 100644 index 000000000..61a2335a9 --- /dev/null +++ b/src/components/GraphiQL/index.ts @@ -0,0 +1,2 @@ +export { default } from "./GraphiQL"; +export * from "./GraphiQL"; diff --git a/src/components/GraphiQL/styles.ts b/src/components/GraphiQL/styles.ts new file mode 100644 index 000000000..81db9cd88 --- /dev/null +++ b/src/components/GraphiQL/styles.ts @@ -0,0 +1,75 @@ +import { + useDragResize, + usePluginContext, + useTheme as useGraphiQLTheme, +} from "@graphiql/react"; +import { makeStyles, useTheme } from "@saleor/macaw-ui"; +import { useEffect } from "react"; + +export const useStyles = makeStyles( + () => ({ + scrollable: { + // Overrides inline styling which breaks scroll + // on doc explorer plugin + "& > :first-child": { + overflowY: "scroll !important", + }, + }, + }), + { name: "GraphiQL" }, +); + +export const useEditorStyles = () => { + const pluginContext = usePluginContext(); + + const pluginResize = useDragResize({ + defaultSizeRelation: 1 / 3, + direction: "horizontal", + initiallyHidden: pluginContext?.visiblePlugin ? undefined : "first", + sizeThresholdSecond: 200, + storageKey: "docExplorerFlex", + }); + const editorResize = useDragResize({ + direction: "horizontal", + storageKey: "editorFlex", + }); + const editorToolsResize = useDragResize({ + defaultSizeRelation: 3, + direction: "vertical", + sizeThresholdSecond: 60, + storageKey: "secondaryEditorFlex", + }); + + return { + pluginResize, + editorResize, + editorToolsResize, + }; +}; + +export const useDashboardTheme = () => { + const theme = useTheme(); + + const rootStyle = { + "--font-size-body": theme.typography?.body2.fontSize, + "--font-size-h2": theme.typography?.h3.fontSize, + "--font-size-h3": theme.typography?.h3.fontSize, + "--font-size-h4": theme.typography?.h4.fontSize, + "--font-size-hint": theme.typography?.caption.fontSize, + "--font-size-inline-code": theme.typography?.caption.fontSize, + } as React.CSSProperties; + + return { rootStyle }; +}; + +export const useGraphiQLThemeSwitcher = () => { + const theme = useTheme(); + const { theme: graphiqlTheme, setTheme: setGraphiqlTheme } = + useGraphiQLTheme(); + + useEffect(() => { + if (theme.themeType !== graphiqlTheme) { + setGraphiqlTheme(theme.themeType); + } + }); +}; diff --git a/src/custom-apps/components/WebhookDetailsPage/WebhookDetailsPage.tsx b/src/custom-apps/components/WebhookDetailsPage/WebhookDetailsPage.tsx index adc5fdec3..7cde5186d 100644 --- a/src/custom-apps/components/WebhookDetailsPage/WebhookDetailsPage.tsx +++ b/src/custom-apps/components/WebhookDetailsPage/WebhookDetailsPage.tsx @@ -2,7 +2,6 @@ import { Backlink } from "@dashboard/components/Backlink"; import Container from "@dashboard/components/Container"; import Form from "@dashboard/components/Form"; import FormSpacer from "@dashboard/components/FormSpacer"; -import Grid from "@dashboard/components/Grid"; import PageHeader from "@dashboard/components/PageHeader"; import Savebar from "@dashboard/components/Savebar"; import WebhookEvents from "@dashboard/custom-apps/components/WebhookEvents"; @@ -13,10 +12,6 @@ import { createSyncEventsSelectHandler, } from "@dashboard/custom-apps/handlers"; import { CustomAppUrls } from "@dashboard/custom-apps/urls"; -import { - mapAsyncEventsToChoices, - mapSyncEventsToChoices, -} from "@dashboard/custom-apps/utils"; import { WebhookDetailsFragment, WebhookErrorFragment, @@ -26,9 +21,11 @@ import { import { SubmitPromise } from "@dashboard/hooks/useForm"; import useNavigator from "@dashboard/hooks/useNavigator"; import { ConfirmButtonTransitionState } from "@saleor/macaw-ui"; -import React from "react"; +import { parse, print } from "graphql"; +import React, { useEffect, useState } from "react"; import { useIntl } from "react-intl"; +import WebhookSubscriptionQuery from "../WebhookSubscriptionQuery/WebhookSubscriptionQuery"; import { getHeaderTitle } from "./messages"; export interface WebhookFormData { @@ -36,8 +33,9 @@ export interface WebhookFormData { asyncEvents: WebhookEventTypeAsyncEnum[]; isActive: boolean; name: string; - secretKey: string | null; + secretKey?: string; targetUrl: string; + subscriptionQuery: string; } export interface WebhookDetailsPageProps { @@ -62,6 +60,13 @@ const WebhookDetailsPage: React.FC = ({ const intl = useIntl(); const navigate = useNavigator(); + let prettified: string; + try { + prettified = print(parse(webhook?.subscriptionQuery)); + } catch { + prettified = webhook?.subscriptionQuery || ""; + } + const initialForm: WebhookFormData = { syncEvents: webhook?.syncEvents?.map(event => event.eventType) || [], asyncEvents: webhook?.asyncEvents?.map(event => event.eventType) || [], @@ -69,61 +74,64 @@ const WebhookDetailsPage: React.FC = ({ name: webhook?.name || "", secretKey: webhook?.secretKey || "", targetUrl: webhook?.targetUrl || "", + subscriptionQuery: prettified || "", }; const backUrl = CustomAppUrls.resolveAppUrl(appId); - return ( -
- {({ data, submit, change }) => { - const syncEventsChoices = disabled - ? [] - : mapSyncEventsToChoices(Object.values(WebhookEventTypeSyncEnum)); - const asyncEventsChoices = disabled - ? [] - : mapAsyncEventsToChoices( - Object.values(WebhookEventTypeAsyncEnum), - data.asyncEvents, - ); + const [query, setQuery] = useState(prettified); + useEffect(() => { + setQuery(prettified); + }, [prettified]); + + const handleSubmit = (data: WebhookFormData) => { + onSubmit({ ...data, ...{ subscriptionQuery: query } }); + }; + + return ( + + {({ data, submit, change }) => { const handleSyncEventsSelect = createSyncEventsSelectHandler( change, data.syncEvents, + setQuery, ); const handleAsyncEventsSelect = createAsyncEventsSelectHandler( change, data.asyncEvents, + query, + setQuery, ); return ( {appName} - - -
- -
-
- - - -
-
+ + + + + + + + void; onAsyncEventChange: (event: ChangeEvent) => void; } const WebhookEvents: React.FC = ({ data, - syncEventsChoices, - asyncEventsChoices, onSyncEventChange, onAsyncEventChange, }) => { const intl = useIntl(); + const classes = useStyles(); + const { checkbox } = useListWidths(); + + const [tab, setTab] = useState("async"); + const [object, setObject] = useState(null); + + const handleEventChange = event => { + if (tab === "sync") { + return onSyncEventChange(event); + } + + return onAsyncEventChange(event); + }; + + const handleTabChange = value => { + setObject(null); + setTab(value); + }; + + const countEvents = object => { + const selected = tab === "sync" ? data.syncEvents : data.asyncEvents; + const objectEvents = EventTypes[tab][object].map( + event => `${object}_${event}`, + ); + + return objectEvents.filter((event: never) => selected.includes(event)) + .length; + }; return ( - - - - - - - - - - - - - + <> + + + + + + + + + + + + + + + +
- - - - - - - - - - -
-
+ +
+ + + + + + + + + + +
+ {Object.keys(EventTypes[tab]).map((object, idx) => ( + setObject(object)} + > + + + {capitalize( + object.replaceAll("_", " ").toLowerCase(), + )} + + + + {countEvents(object) > 0 && ( + + )} + + + ))} +
+
+
+
+
+ + + + + + + + + {object && + EventTypes[tab][object] && + EventTypes[tab][object].map((event, idx) => ( + + + + {capitalize(event.toLowerCase().replaceAll("_", " "))} + + + + + + + ))} + +
+
+ + ); }; WebhookEvents.displayName = "WebhookEvents"; export default WebhookEvents; + +type Actions = string[]; + +const AsyncWebhookTypes: Record = { + ADDRESS: ["CREATED", "UPDATED", "DELETED"], + APP: ["INSTALLED", "UPDATED", "DELETED"], + ATTRIBUTE: ["CREATED", "UPDATED", "DELETED"], + CATEGORY: ["CREATED", "UPDATED", "DELETED"], + CHANNEL: ["CREATED", "UPDATED", "DELETED"], + GIFT_CARD: ["CREATED", "UPDATED", "DELETED", "STATUS_CHANGED"], + + CHECKOUT: ["CREATED", "UPDATED", "DELETED"], + COLLECTION: ["CREATED", "UPDATED", "DELETED"], + CUSTOMER: ["CREATED", "UPDATED", "DELETED"], + FULFILLMENT: ["CREATED"], + INVOICE: ["DELETED", "REQUESTED", "SENT"], + MENU: ["CREATED", "UPDATED", "DELETED"], + ORDER: [ + "CANCELLED", + "CONFIRMED", + "CREATED", + "FULFILLED", + "FULLY_PAID", + "UPDATED", + ], + PAGE: ["CREATED", "UPDATED", "DELETED"], + PRODUCT: ["CREATED", "UPDATED", "DELETED"], + PRODUCT_VARIANT: ["CREATED", "UPDATED", "DELETED"], + SALE: ["CREATED", "UPDATED", "DELETED", "TOGGLE"], + SHIPPING_PRICE: ["CREATED", "UPDATED", "DELETED"], + SHIPPING_ZONE: ["CREATED", "UPDATED", "DELETED"], + STAFF: ["CREATED", "UPDATED", "DELETED"], + TRANSLATION: ["ACTION_REQUEST", "CREATED", "UPDATED"], + VOUCHER: ["CREATED", "UPDATED", "DELETED"], + WAREHOUSE: ["CREATED", "UPDATED", "DELETED"], +}; + +const SyncWebhookTypes: Record = { + PAYMENT: [ + "AUTHORIZE", + "CAPTURE", + "CONFIRM", + "LIST_GATEWAYS", + "PROCESS", + "REFUND", + "VOID", + ], + CHECKOUT: ["CALCULATE_TAXES", "FILTER_SHIPPING_METHODS"], + ORDER: ["CALCULATE_TAXES", "FILTER_SHIPPING_METHODS"], + SHIPPING: ["LIST_METHODS_FOR_CHECKOUT"], +}; + +const EventTypes = { + async: AsyncWebhookTypes, + sync: SyncWebhookTypes, +}; + +const getEventName = (object: string, event: string) => + [object, event].join("_").toUpperCase() as WebhookEventTypeSyncEnum; diff --git a/src/custom-apps/components/WebhookEvents/messages.ts b/src/custom-apps/components/WebhookEvents/messages.ts index c601f23d4..68c0dc9c2 100644 --- a/src/custom-apps/components/WebhookEvents/messages.ts +++ b/src/custom-apps/components/WebhookEvents/messages.ts @@ -2,35 +2,35 @@ import { defineMessages } from "react-intl"; export const messages = defineMessages({ events: { - id: "GLewww", + id: "cZN5Jd", defaultMessage: "Events", - description: "section header", + description: "Webhook details events", }, - synchronousEvents: { - id: "dQdxLT", - defaultMessage: "Synchronous events", - description: "section subheader", + synchronous: { + id: "yAFaVK", + defaultMessage: "Synchronous", + description: "Webhook details synchronous events", }, - asynchronousEvents: { - id: "TjbB4Y", - defaultMessage: "Asynchronous events", - description: "section subheader", + asynchronous: { + id: "mSCZd4", + defaultMessage: "Asynchronous", + description: "Webhook details asynchronous events", }, - assignPermissionsToSynchronousEvents: { - id: "fHopox", + synchronousDescription: { + id: "16Dpgb", defaultMessage: - "Assign permissions to register synchronous events for this webhook.", - description: "section description", + "Synchronous webhook sends payload and waits for a response from the target URL to continue processing.", + description: "Synchronous events description", }, - assignPermissionsToAsynchronousEvents: { - id: "QEvH8Q", + asynchronousDescription: { + id: "yJqbYv", defaultMessage: - "Assign permissions to register asynchronous events for this webhook.", - description: "section description", + "Asynchronous webhook sends payload and continues processing.", + description: "Asynchronous events description", }, - registeredEvents: { - id: "9Yhddc", - defaultMessage: "Registered events", - description: "input label", + objects: { + defaultMessage: "Objects", + id: "F6LHyk", + description: "Webhook details objects", }, }); diff --git a/src/custom-apps/components/WebhookEvents/styles.ts b/src/custom-apps/components/WebhookEvents/styles.ts new file mode 100644 index 000000000..c4862173e --- /dev/null +++ b/src/custom-apps/components/WebhookEvents/styles.ts @@ -0,0 +1,37 @@ +import { makeStyles } from "@saleor/macaw-ui"; + +export const useStyles = makeStyles( + theme => ({ + eventsWrapper: { + overflow: "scroll", + padding: theme.spacing(4), + paddingLeft: 0, + }, + objectsWrapper: { + borderRight: "1px solid", + borderRightColor: theme.palette.divider, + padding: theme.spacing(3), + }, + listHeader: { + textTransform: "uppercase", + padding: theme.spacing(1), + minHeight: 0, + }, + listItem: { + minHeight: 0, + gap: 0, + padding: theme.spacing(1), + }, + listItemCell: { + paddingLeft: "0 !important", + }, + listItems: { + height: 300, + overflow: "scroll", + }, + checkbox: { + padding: 0, + }, + }), + { name: "WebhookEvents" }, +); diff --git a/src/custom-apps/components/WebhookStatus/WebhookStatus.tsx b/src/custom-apps/components/WebhookStatus/WebhookStatus.tsx index a6499d458..469943668 100644 --- a/src/custom-apps/components/WebhookStatus/WebhookStatus.tsx +++ b/src/custom-apps/components/WebhookStatus/WebhookStatus.tsx @@ -1,7 +1,5 @@ -import CardTitle from "@dashboard/components/CardTitle"; -import ControlledCheckbox from "@dashboard/components/ControlledCheckbox"; +import ControlledSwitch from "@dashboard/components/ControlledSwitch"; import { ChangeEvent } from "@dashboard/hooks/useForm"; -import { Card, CardContent, Typography } from "@material-ui/core"; import React from "react"; import { useIntl } from "react-intl"; @@ -21,22 +19,19 @@ const WebhookStatus: React.FC = ({ }) => { const intl = useIntl(); return ( - - - - - {intl.formatMessage(messages.webhookActiveDescription)} - - - - + ); }; + WebhookStatus.displayName = "WebhookStatus"; export default WebhookStatus; diff --git a/src/custom-apps/components/WebhookStatus/messages.ts b/src/custom-apps/components/WebhookStatus/messages.ts index 418e39830..79d9bed22 100644 --- a/src/custom-apps/components/WebhookStatus/messages.ts +++ b/src/custom-apps/components/WebhookStatus/messages.ts @@ -1,20 +1,14 @@ import { defineMessages } from "react-intl"; export const messages = defineMessages({ - webhookStatus: { - id: "1+M/52", - defaultMessage: "Webhook Status", - description: "section header", - }, webhookActive: { - id: "W+x5ZI", - defaultMessage: "Webhook is active", + id: "2RYRdr", + defaultMessage: "Active", description: "webhooks active label", }, - webhookActiveDescription: { - id: "IBCBi1", - defaultMessage: - "If you want to disable this webhook please uncheck the box below.", - description: "webhook active description", + webhookInactive: { + id: "GNKG74", + defaultMessage: "Inactive", + description: "webhooks inactive label", }, }); diff --git a/src/custom-apps/components/WebhookSubscriptionQuery/WebhookSubscriptionQuery.test.tsx b/src/custom-apps/components/WebhookSubscriptionQuery/WebhookSubscriptionQuery.test.tsx new file mode 100644 index 000000000..640cbde8b --- /dev/null +++ b/src/custom-apps/components/WebhookSubscriptionQuery/WebhookSubscriptionQuery.test.tsx @@ -0,0 +1,87 @@ +import "@testing-library/jest-dom"; + +import { + WebhookEventTypeAsyncEnum, + WebhookEventTypeSyncEnum, +} from "@dashboard/graphql"; +import { Fetcher } from "@graphiql/toolkit"; +import { render, screen } from "@testing-library/react"; +import React from "react"; + +import WebhookSubscriptionQuery from "./WebhookSubscriptionQuery"; + +jest.mock("@graphiql/toolkit", () => ({ + clear: jest.fn(), + createGraphiQLFetcher: jest.fn(_x => jest.fn() as Fetcher), +})); + +jest.mock("react-intl", () => ({ + useIntl: jest.fn(() => ({ + formatMessage: jest.fn(x => x.defaultMessage), + })), + defineMessages: jest.fn(x => x), +})); + +jest.mock("@saleor/macaw-ui", () => ({ + useTheme: jest.fn(() => () => ({})), + useStyles: jest.fn(() => () => ({})), + makeStyles: jest.fn(() => () => ({})), + DialogHeader: jest.fn(() => () => <>), +})); + +beforeEach(() => { + window.localStorage.clear(); +}); + +describe("WebhookSubscriptionQuery", () => { + it("is available on the webhook page", async () => { + // Arrange + const props = { + query: "", + setQuery: jest.fn(), + data: { + syncEvents: [] as WebhookEventTypeSyncEnum[], + asyncEvents: [] as WebhookEventTypeAsyncEnum[], + isActive: false, + name: "", + targetUrl: "", + subscriptionQuery: "", + }, + }; + // const user = userEvent.setup(); + + // Act + render(); + + // Assert + expect(screen.queryByTestId("graphiql-container")).toBeInTheDocument(); + expect(screen.queryByTestId("graphiql-container2")).not.toBeInTheDocument(); + }); + + /* + it("triggers setQuery when user enters text", async () => { + // Arrange + const props = { + query: '', + setQuery: jest.fn(), + data: { + syncEvents: [] as WebhookEventTypeSyncEnum[], + asyncEvents: [] as WebhookEventTypeAsyncEnum[], + isActive: false, + name: '', + targetUrl: '', + subscriptionQuery: '' + } + }; + const user = userEvent.setup(); + + // Act + const { getByTestId } = render(); + const graphiQLContainer = getByTestId("graphiql-container"); + user.type(graphiQLContainer, "{}"); + + // Assert + expect(props.setQuery).toHaveBeenCalled(); + }); + */ +}); diff --git a/src/custom-apps/components/WebhookSubscriptionQuery/WebhookSubscriptionQuery.tsx b/src/custom-apps/components/WebhookSubscriptionQuery/WebhookSubscriptionQuery.tsx new file mode 100644 index 000000000..2e7b3dc8f --- /dev/null +++ b/src/custom-apps/components/WebhookSubscriptionQuery/WebhookSubscriptionQuery.tsx @@ -0,0 +1,69 @@ +import "graphiql/graphiql.min.css"; + +import CardTitle from "@dashboard/components/CardTitle"; +import { useExplorerPlugin } from "@graphiql/plugin-explorer"; +import { createGraphiQLFetcher } from "@graphiql/toolkit"; +import { Card, CardContent } from "@material-ui/core"; +import clsx from "clsx"; +import React from "react"; +import { defineMessages, useIntl } from "react-intl"; + +import GraphiQL from "../../../components/GraphiQL"; +import { WebhookFormData } from "../WebhookDetailsPage"; +import { useStyles } from "./styles"; + +const messages = defineMessages({ + title: { + id: "QpSQ5w", + defaultMessage: "Payload Query", + description: "Webhook subscription query card title", + }, +}); + +interface WebhookSubscriptionQueryProps { + query: any; + setQuery: React.Dispatch; + data: WebhookFormData; +} + +const fetcher = createGraphiQLFetcher({ + url: process.env.API_URI, +}); + +const WebhookSubscriptionQuery: React.FC = ({ + query, + setQuery, + data, +}) => { + const intl = useIntl(); + + const explorerPlugin = useExplorerPlugin({ + query, + onEdit: setQuery, + }); + + const classes = useStyles(); + + return ( + + + + + + + ); +}; + +WebhookSubscriptionQuery.displayName = "WebhookSubscriptionQuery"; +export default WebhookSubscriptionQuery; diff --git a/src/custom-apps/components/WebhookSubscriptionQuery/index.ts b/src/custom-apps/components/WebhookSubscriptionQuery/index.ts new file mode 100644 index 000000000..eabc0e29b --- /dev/null +++ b/src/custom-apps/components/WebhookSubscriptionQuery/index.ts @@ -0,0 +1,2 @@ +export { default } from "./WebhookSubscriptionQuery"; +export * from "./WebhookSubscriptionQuery"; diff --git a/src/custom-apps/components/WebhookSubscriptionQuery/messages.ts b/src/custom-apps/components/WebhookSubscriptionQuery/messages.ts new file mode 100644 index 000000000..a7811a8e2 --- /dev/null +++ b/src/custom-apps/components/WebhookSubscriptionQuery/messages.ts @@ -0,0 +1,24 @@ +import { defineMessages } from "react-intl"; + +export const messages = defineMessages({ + createWebhook: { + id: "wlr0Si", + defaultMessage: "Create Webhook", + description: "button", + }, + action: { + id: "a/QJBx", + defaultMessage: "Action", + description: "user action bar", + }, + unnamedWebhook: { + id: "Lm2Zw7", + defaultMessage: "Unnamed webhook", + description: "name placeholder", + }, + noWebhooks: { + id: "Bkxrhw", + defaultMessage: "No webhooks found", + description: "no webhooks message", + }, +}); diff --git a/src/custom-apps/components/WebhookSubscriptionQuery/styles.ts b/src/custom-apps/components/WebhookSubscriptionQuery/styles.ts new file mode 100644 index 000000000..6f1a1a558 --- /dev/null +++ b/src/custom-apps/components/WebhookSubscriptionQuery/styles.ts @@ -0,0 +1,18 @@ +import { makeStyles } from "@saleor/macaw-ui"; + +export const useStyles = makeStyles( + theme => ({ + disabled: { + pointerEvents: "none", + opacity: 0.6, + }, + cardContent: { + height: 500, + padding: 0, + }, + card: { + marginBottom: theme.spacing(2), + }, + }), + { name: "WebhookSubscriptionQuery" }, +); diff --git a/src/custom-apps/fixtures.ts b/src/custom-apps/fixtures.ts index decb995e7..60438971d 100644 --- a/src/custom-apps/fixtures.ts +++ b/src/custom-apps/fixtures.ts @@ -13,5 +13,7 @@ export const webhook: WebhookDetailsFragment = { isActive: true, name: "Webhook Test 2", secretKey: "zxczx_asdas", + subscriptionQuery: + "subscription { event { ... on ProductUpdated { product { name } } } }", targetUrl: "http://www.getsaleor.com", }; diff --git a/src/custom-apps/handlers.ts b/src/custom-apps/handlers.ts index 1bde84949..d18b53dcc 100644 --- a/src/custom-apps/handlers.ts +++ b/src/custom-apps/handlers.ts @@ -3,35 +3,127 @@ import { WebhookEventTypeSyncEnum, } from "@dashboard/graphql"; import { ChangeEvent } from "@dashboard/hooks/useForm"; +import { capitalize } from "@dashboard/misc"; import { toggle } from "@dashboard/utils/lists"; +import { + InlineFragmentNode, + ObjectFieldNode, + parse, + print, + visit, +} from "graphql"; import { filterSelectedAsyncEvents } from "./utils"; -export const createSyncEventsSelectHandler = ( - change: (event: ChangeEvent, cb?: () => void) => void, - syncEvents: WebhookEventTypeSyncEnum[], -) => (event: ChangeEvent) => { - const events = toggle(event.target.value, syncEvents, (a, b) => a === b); +export const createSyncEventsSelectHandler = + ( + change: (event: ChangeEvent, cb?: () => void) => void, + syncEvents: WebhookEventTypeSyncEnum[], + setQuery: React.Dispatch>, + ) => + (event: ChangeEvent) => { + const events = toggle(event.target.value, syncEvents, (a, b) => a === b); - change({ - target: { - name: "syncEvents", - value: events, - }, - }); -}; - -export const createAsyncEventsSelectHandler = ( - change: (event: ChangeEvent, cb?: () => void) => void, - asyncEvents: WebhookEventTypeAsyncEnum[], -) => (event: ChangeEvent) => { - const events = toggle(event.target.value, asyncEvents, (a, b) => a === b); - const filteredEvents = filterSelectedAsyncEvents(events); - - change({ - target: { - name: "asyncEvents", - value: filteredEvents, - }, - }); + // Clear query + setQuery(""); + + // Clear asyncEvents + change({ + target: { + name: "asyncEvents", + value: [], + }, + }); + + change({ + target: { + name: "syncEvents", + value: events, + }, + }); + }; + +export const createAsyncEventsSelectHandler = + ( + change: (event: ChangeEvent, cb?: () => void) => void, + asyncEvents: WebhookEventTypeAsyncEnum[], + query: string, + setQuery: React.Dispatch>, + ) => + (event: ChangeEvent) => { + const events = toggle(event.target.value, asyncEvents, (a, b) => a === b); + const filteredEvents = filterSelectedAsyncEvents(events); + + // Clear syncEvents + change({ + target: { + name: "syncEvents", + value: [], + }, + }); + + change({ + target: { + name: "asyncEvents", + value: filteredEvents, + }, + }); + + handleQuery(filteredEvents, query, setQuery); + }; + +const handleQuery = ( + events: WebhookEventTypeAsyncEnum[], + query: string, + setQuery: React.Dispatch>, +) => { + if (events.length > 0 && query.length === 0) { + const event = events[0] + .toLowerCase() + .split("_") + .map(chunk => capitalize(chunk)) + .join(""); + setQuery( + print(parse(`subscription { event { ... on ${event} { __typename } } }`)), + ); + } + + if (query.length > 0) { + const ast = parse(query); + + visit(ast, { + SelectionSet(node, _key, parent) { + if ((parent as ObjectFieldNode).name?.value === "event") { + const queryEvents = node.selections.map( + selection => + (selection as InlineFragmentNode).typeCondition.name.value, + ); + const newEvents = events + .map(event => + event + .toLowerCase() + .split("_") + .map(chunk => capitalize(chunk)) + .join(""), + ) + .filter(event => !queryEvents.includes(event)); + + if (newEvents.length > 0) { + // TODO modify AST + + const inserted = query.replace(/\n/g, " ").replace( + " } } ", + newEvents + .map(event => ` ... on ${event} { __typename }`) + .join("") + .concat(" } } "), + ); + setQuery(print(parse(inserted))); + } + } + + return undefined; + }, + }); + } }; diff --git a/src/custom-apps/utils.tsx b/src/custom-apps/utils.tsx index 11c76555d..2d4e84fb9 100644 --- a/src/custom-apps/utils.tsx +++ b/src/custom-apps/utils.tsx @@ -14,26 +14,30 @@ export function isUnnamed(webhook: WebhookFragment | undefined): boolean { type WebhookEventType = WebhookEventTypeSyncEnum | WebhookEventTypeAsyncEnum; const isWebhookInPreview = (webhook: WebhookEventType) => - ([ - WebhookEventTypeSyncEnum.CHECKOUT_CALCULATE_TAXES, - WebhookEventTypeSyncEnum.ORDER_CALCULATE_TAXES, - ] as WebhookEventType[]).includes(webhook); + ( + [ + WebhookEventTypeSyncEnum.CHECKOUT_CALCULATE_TAXES, + WebhookEventTypeSyncEnum.ORDER_CALCULATE_TAXES, + ] as WebhookEventType[] + ).includes(webhook); const isAsyncWebhookInPreview = (webhook: WebhookEventType) => - ([ - WebhookEventTypeAsyncEnum.GIFT_CARD_METADATA_UPDATED, - WebhookEventTypeAsyncEnum.ORDER_METADATA_UPDATED, - WebhookEventTypeAsyncEnum.CUSTOMER_METADATA_UPDATED, - WebhookEventTypeAsyncEnum.COLLECTION_METADATA_UPDATED, - WebhookEventTypeAsyncEnum.PRODUCT_METADATA_UPDATED, - WebhookEventTypeAsyncEnum.PRODUCT_VARIANT_METADATA_UPDATED, - WebhookEventTypeAsyncEnum.CHECKOUT_METADATA_UPDATED, - WebhookEventTypeAsyncEnum.FULFILLMENT_METADATA_UPDATED, - WebhookEventTypeAsyncEnum.SHIPPING_ZONE_METADATA_UPDATED, - WebhookEventTypeAsyncEnum.TRANSACTION_ITEM_METADATA_UPDATED, - WebhookEventTypeAsyncEnum.WAREHOUSE_METADATA_UPDATED, - WebhookEventTypeAsyncEnum.VOUCHER_METADATA_UPDATED, - ] as WebhookEventType[]).includes(webhook); + ( + [ + WebhookEventTypeAsyncEnum.GIFT_CARD_METADATA_UPDATED, + WebhookEventTypeAsyncEnum.ORDER_METADATA_UPDATED, + WebhookEventTypeAsyncEnum.CUSTOMER_METADATA_UPDATED, + WebhookEventTypeAsyncEnum.COLLECTION_METADATA_UPDATED, + WebhookEventTypeAsyncEnum.PRODUCT_METADATA_UPDATED, + WebhookEventTypeAsyncEnum.PRODUCT_VARIANT_METADATA_UPDATED, + WebhookEventTypeAsyncEnum.CHECKOUT_METADATA_UPDATED, + WebhookEventTypeAsyncEnum.FULFILLMENT_METADATA_UPDATED, + WebhookEventTypeAsyncEnum.SHIPPING_ZONE_METADATA_UPDATED, + WebhookEventTypeAsyncEnum.TRANSACTION_ITEM_METADATA_UPDATED, + WebhookEventTypeAsyncEnum.WAREHOUSE_METADATA_UPDATED, + WebhookEventTypeAsyncEnum.VOUCHER_METADATA_UPDATED, + ] as WebhookEventType[] + ).includes(webhook); export function mapSyncEventsToChoices( events: WebhookEventTypeSyncEnum[], diff --git a/src/custom-apps/views/CustomAppWebhookCreate.tsx b/src/custom-apps/views/CustomAppWebhookCreate.tsx index 8a04babfe..f68169910 100644 --- a/src/custom-apps/views/CustomAppWebhookCreate.tsx +++ b/src/custom-apps/views/CustomAppWebhookCreate.tsx @@ -58,6 +58,7 @@ export const CustomAppWebhookCreate: React.FC = ({ name: data.name, secretKey: data.secretKey, targetUrl: data.targetUrl, + query: data.subscriptionQuery, }, }, }), diff --git a/src/custom-apps/views/CustomAppWebhookDetails.tsx b/src/custom-apps/views/CustomAppWebhookDetails.tsx index 7b0b68170..8d57f96b8 100644 --- a/src/custom-apps/views/CustomAppWebhookDetails.tsx +++ b/src/custom-apps/views/CustomAppWebhookDetails.tsx @@ -62,10 +62,12 @@ export const CustomAppWebhookDetails: React.FC = ( name: data.name, secretKey: data.secretKey, targetUrl: data.targetUrl, + query: data.subscriptionQuery, }, }, }), ); + if (!webhook && !loading) { return ; } diff --git a/src/fragments/webhooks.ts b/src/fragments/webhooks.ts index 12f879315..0ced39a65 100644 --- a/src/fragments/webhooks.ts +++ b/src/fragments/webhooks.ts @@ -23,5 +23,6 @@ export const webhookDetailsFragment = gql` } secretKey targetUrl + subscriptionQuery } `; diff --git a/src/graphql/hooks.generated.ts b/src/graphql/hooks.generated.ts index d8107a25b..3dae5ce63 100644 --- a/src/graphql/hooks.generated.ts +++ b/src/graphql/hooks.generated.ts @@ -2828,6 +2828,7 @@ export const WebhookDetailsFragmentDoc = gql` } secretKey targetUrl + subscriptionQuery } ${WebhookFragmentDoc}`; export const AppCreateDocument = gql` diff --git a/src/graphql/types.generated.ts b/src/graphql/types.generated.ts index 1caee5168..645273da9 100644 --- a/src/graphql/types.generated.ts +++ b/src/graphql/types.generated.ts @@ -6734,7 +6734,7 @@ export type WebhookCreateMutationVariables = Exact<{ }>; -export type WebhookCreateMutation = { __typename: 'Mutation', webhookCreate: { __typename: 'WebhookCreate', errors: Array<{ __typename: 'WebhookError', code: WebhookErrorCode, field: string | null, message: string | null }>, webhook: { __typename: 'Webhook', secretKey: string | null, targetUrl: string, id: string, name: string, isActive: boolean, syncEvents: Array<{ __typename: 'WebhookEventSync', eventType: WebhookEventTypeSyncEnum }>, asyncEvents: Array<{ __typename: 'WebhookEventAsync', eventType: WebhookEventTypeAsyncEnum }>, app: { __typename: 'App', id: string, name: string | null } } | null } | null }; +export type WebhookCreateMutation = { __typename: 'Mutation', webhookCreate: { __typename: 'WebhookCreate', errors: Array<{ __typename: 'WebhookError', code: WebhookErrorCode, field: string | null, message: string | null }>, webhook: { __typename: 'Webhook', secretKey: string | null, targetUrl: string, subscriptionQuery: string | null, id: string, name: string, isActive: boolean, syncEvents: Array<{ __typename: 'WebhookEventSync', eventType: WebhookEventTypeSyncEnum }>, asyncEvents: Array<{ __typename: 'WebhookEventAsync', eventType: WebhookEventTypeAsyncEnum }>, app: { __typename: 'App', id: string, name: string | null } } | null } | null }; export type WebhookUpdateMutationVariables = Exact<{ id: Scalars['ID']; @@ -6742,7 +6742,7 @@ export type WebhookUpdateMutationVariables = Exact<{ }>; -export type WebhookUpdateMutation = { __typename: 'Mutation', webhookUpdate: { __typename: 'WebhookUpdate', errors: Array<{ __typename: 'WebhookError', code: WebhookErrorCode, field: string | null, message: string | null }>, webhook: { __typename: 'Webhook', secretKey: string | null, targetUrl: string, id: string, name: string, isActive: boolean, syncEvents: Array<{ __typename: 'WebhookEventSync', eventType: WebhookEventTypeSyncEnum }>, asyncEvents: Array<{ __typename: 'WebhookEventAsync', eventType: WebhookEventTypeAsyncEnum }>, app: { __typename: 'App', id: string, name: string | null } } | null } | null }; +export type WebhookUpdateMutation = { __typename: 'Mutation', webhookUpdate: { __typename: 'WebhookUpdate', errors: Array<{ __typename: 'WebhookError', code: WebhookErrorCode, field: string | null, message: string | null }>, webhook: { __typename: 'Webhook', secretKey: string | null, targetUrl: string, subscriptionQuery: string | null, id: string, name: string, isActive: boolean, syncEvents: Array<{ __typename: 'WebhookEventSync', eventType: WebhookEventTypeSyncEnum }>, asyncEvents: Array<{ __typename: 'WebhookEventAsync', eventType: WebhookEventTypeAsyncEnum }>, app: { __typename: 'App', id: string, name: string | null } } | null } | null }; export type WebhookDeleteMutationVariables = Exact<{ id: Scalars['ID']; @@ -6756,7 +6756,7 @@ export type WebhookDetailsQueryVariables = Exact<{ }>; -export type WebhookDetailsQuery = { __typename: 'Query', webhook: { __typename: 'Webhook', secretKey: string | null, targetUrl: string, id: string, name: string, isActive: boolean, syncEvents: Array<{ __typename: 'WebhookEventSync', eventType: WebhookEventTypeSyncEnum }>, asyncEvents: Array<{ __typename: 'WebhookEventAsync', eventType: WebhookEventTypeAsyncEnum }>, app: { __typename: 'App', id: string, name: string | null } } | null }; +export type WebhookDetailsQuery = { __typename: 'Query', webhook: { __typename: 'Webhook', secretKey: string | null, targetUrl: string, subscriptionQuery: string | null, id: string, name: string, isActive: boolean, syncEvents: Array<{ __typename: 'WebhookEventSync', eventType: WebhookEventTypeSyncEnum }>, asyncEvents: Array<{ __typename: 'WebhookEventAsync', eventType: WebhookEventTypeAsyncEnum }>, app: { __typename: 'App', id: string, name: string | null } } | null }; export type UpdateCustomerMutationVariables = Exact<{ id: Scalars['ID']; @@ -7491,7 +7491,7 @@ export type WarehouseDetailsFragment = { __typename: 'Warehouse', isPrivate: boo export type WebhookFragment = { __typename: 'Webhook', id: string, name: string, isActive: boolean, app: { __typename: 'App', id: string, name: string | null } }; -export type WebhookDetailsFragment = { __typename: 'Webhook', secretKey: string | null, targetUrl: string, id: string, name: string, isActive: boolean, syncEvents: Array<{ __typename: 'WebhookEventSync', eventType: WebhookEventTypeSyncEnum }>, asyncEvents: Array<{ __typename: 'WebhookEventAsync', eventType: WebhookEventTypeAsyncEnum }>, app: { __typename: 'App', id: string, name: string | null } }; +export type WebhookDetailsFragment = { __typename: 'Webhook', secretKey: string | null, targetUrl: string, subscriptionQuery: string | null, id: string, name: string, isActive: boolean, syncEvents: Array<{ __typename: 'WebhookEventSync', eventType: WebhookEventTypeSyncEnum }>, asyncEvents: Array<{ __typename: 'WebhookEventAsync', eventType: WebhookEventTypeAsyncEnum }>, app: { __typename: 'App', id: string, name: string | null } }; export type WeightFragment = { __typename: 'Weight', unit: WeightUnitsEnum, value: number }; diff --git a/testUtils/setup.ts b/testUtils/setup.ts index afa38019b..04b228fbe 100644 --- a/testUtils/setup.ts +++ b/testUtils/setup.ts @@ -4,6 +4,22 @@ import { configure } from "@testing-library/react"; document.getElementById = () => document.createElement("div"); +// workaround for `jsdom` +// https://github.com/jsdom/jsdom/issues/3002 +document.createRange = () => { + const range = new Range(); + + range.getBoundingClientRect = jest.fn(); + + range.getClientRects = () => ({ + item: () => null, + length: 0, + [Symbol.iterator]: jest.fn(), + }); + + return range; +}; + window.__SALEOR_CONFIG__ = { API_URL: "http://localhost:8000/graphql/", APP_MOUNT_URI: "/",