diff --git a/.changeset/brown-glasses-complain.md b/.changeset/brown-glasses-complain.md deleted file mode 100644 index 1dd24fb1cbd..00000000000 --- a/.changeset/brown-glasses-complain.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@keystone-next/fields': major -'@keystone-next/keystone': major -'@keystone-next/types': major ---- - -Removed `_ListKeyMeta` and `_toManyRelationshipFieldMeta` fields. You should use `listKeyCount` and `toManyRelationshipFieldCount` instead diff --git a/.changeset/chilled-grapes-cry.md b/.changeset/chilled-grapes-cry.md deleted file mode 100644 index 8900a01a4fe..00000000000 --- a/.changeset/chilled-grapes-cry.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@keystone-next/example-ecommerce': patch -'@keystone-next/fields-document': patch -'@keystone-next/keystone': patch ---- - -Updated internal type definitions. diff --git a/.changeset/cold-cycles-cry.md b/.changeset/cold-cycles-cry.md deleted file mode 100644 index 01d444759a0..00000000000 --- a/.changeset/cold-cycles-cry.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@keystone-next/keystone': major -'@keystone-next/types': major ---- - -Removed all arguments from `context.lists.List.count` and `context.db.lists.List.count` except for `where`. diff --git a/.changeset/dull-humans-yell.md b/.changeset/dull-humans-yell.md deleted file mode 100644 index 2c54e688c64..00000000000 --- a/.changeset/dull-humans-yell.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@keystone-next/keystone': major -'@keystone-next/types': major ---- - -The create one mutation now requires a non-null `data` argument and the create many mutation accepts a list of `ItemCreateInput` directly instead of being nested inside of an object with the `ItemCreateInput` in a `data` field. - -If you have a list called `Item`, `createItem` now looks like `createItem(data: ItemCreateInput!): Item` and `createItems` now looks like `createItems(data: [ItemCreateInput!]!): [Item]`. diff --git a/.changeset/early-experts-allow.md b/.changeset/early-experts-allow.md deleted file mode 100644 index 0ba0c99a6e4..00000000000 --- a/.changeset/early-experts-allow.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@keystone-next/fields': major -'@keystone-next/keystone': major -'@keystone-next/types': major ---- - -Removed `search` argument from the GraphQL API for finding many items, Lists/DB API and to-many relationship fields. You should use `contains` filters instead. diff --git a/.changeset/eleven-mayflies-kneel.md b/.changeset/eleven-mayflies-kneel.md deleted file mode 100644 index 1dbd83a8621..00000000000 --- a/.changeset/eleven-mayflies-kneel.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@keystone-ui/notice': patch -'@keystone-ui/toast': patch ---- - -Updated css to preserve whitespace formatting of error messages. diff --git a/.changeset/empty-baboons-unite.md b/.changeset/empty-baboons-unite.md deleted file mode 100644 index 0e612be3d43..00000000000 --- a/.changeset/empty-baboons-unite.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@keystone-next/keystone': patch ---- - -Removed unused code path in Admin UI error display. diff --git a/.changeset/fast-guests-tickle.md b/.changeset/fast-guests-tickle.md deleted file mode 100644 index 6fcc1576912..00000000000 --- a/.changeset/fast-guests-tickle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@keystone-next/fields': patch ---- - -Updated timestamp field to default time to 00:00 when no time is selected. diff --git a/.changeset/fluffy-coins-argue.md b/.changeset/fluffy-coins-argue.md deleted file mode 100644 index 214507238cc..00000000000 --- a/.changeset/fluffy-coins-argue.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@keystone-next/example-testing': patch -'@keystone-next/keystone': patch ---- - -Added more details to validation failure error messages. diff --git a/.changeset/good-cycles-ring.md b/.changeset/good-cycles-ring.md deleted file mode 100644 index 9aefdfff97e..00000000000 --- a/.changeset/good-cycles-ring.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@keystone-next/example-custom-admin-ui-pages': major ---- - -Initial version of the custom-admin-ui-pages example. diff --git a/.changeset/happy-seals-cheat.md b/.changeset/happy-seals-cheat.md deleted file mode 100644 index 3251f247d82..00000000000 --- a/.changeset/happy-seals-cheat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@keystone-next/keystone': major ---- - -Removed the `uid` and `name` properties from the errors returned by the GraphQL API. diff --git a/.changeset/khaki-ducks-poke.md b/.changeset/khaki-ducks-poke.md deleted file mode 100644 index 4f3a5c1675a..00000000000 --- a/.changeset/khaki-ducks-poke.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@keystone-next/fields-document': patch ---- - -Suppressed error logging during tests. diff --git a/.changeset/lovely-pears-sort.md b/.changeset/lovely-pears-sort.md deleted file mode 100644 index 4522dc1b66e..00000000000 --- a/.changeset/lovely-pears-sort.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@keystone-next/fields': major -'@keystone-next/keystone': major -'@keystone-next/types': major ---- - -Removed `sortBy` argument from the GraphQL API for finding many items, Lists/DB API and to-many relationship fields. You should use `orderBy` instead. diff --git a/.changeset/nasty-windows-study.md b/.changeset/nasty-windows-study.md deleted file mode 100644 index ddfd1ef4d16..00000000000 --- a/.changeset/nasty-windows-study.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -'@keystone-next/fields': major -'@keystone-next/keystone': major -'@keystone-next/types': major ---- - -`disconnectAll` has been renamed to `disconnect` in to-one relationship inputs and the old `disconnect` field has been removed. There are also seperate input types for create and update where the input for create doesn't have `disconnect`. It's also now required that if you provide a to-one relationship input, you must provide exactly one field to the input. - -If you have a list called `Item`, the to-one relationship inputs now look like this: - -```graphql -input ItemRelateToOneForCreateInput { - create: ItemCreateInput - connect: ItemWhereUniqueInput -} -input ItemRelateToOneForUpdateInput { - create: ItemCreateInput - connect: ItemWhereUniqueInput - disconnect: Boolean -} -``` diff --git a/.changeset/olive-maps-serve.md b/.changeset/olive-maps-serve.md deleted file mode 100644 index ac2ca1c4f58..00000000000 --- a/.changeset/olive-maps-serve.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@keystone-next/keystone': patch ---- - -Added more details to before/after change/delete hook error messages. diff --git a/.changeset/olive-poems-explode.md b/.changeset/olive-poems-explode.md deleted file mode 100644 index 05499df63c9..00000000000 --- a/.changeset/olive-poems-explode.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@keystone-next/keystone': patch ---- - -Removed unused dependency `@graphql-tools/schema`. diff --git a/.changeset/proud-impalas-flash.md b/.changeset/proud-impalas-flash.md deleted file mode 100644 index c190c8b8943..00000000000 --- a/.changeset/proud-impalas-flash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@keystone-ui/segmented-control': patch ---- - -Fixed segmented-control focus style. diff --git a/.changeset/rich-tomatoes-own.md b/.changeset/rich-tomatoes-own.md deleted file mode 100644 index 03f9139408a..00000000000 --- a/.changeset/rich-tomatoes-own.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -'@keystone-next/fields': major -'@keystone-next/keystone': major -'@keystone-next/types': major ---- - -`disconnectAll` has been replaced by `set` in to-many relationship inputs, the equivalent to `disconnectAll: true` is now `set: []`. There are also seperate input types for create and update where the input for create doesn't have `disconnect` or `set`. The inputs in the lists in the input field are now also non-null. - -If you have a list called `Item`, the to-many relationship inputs now look like this: - -```graphql -input ItemRelateToManyForCreateInput { - create: [ItemCreateInput!] - connect: [ItemWhereUniqueInput!] -} -input ItemRelateToManyForUpdateInput { - disconnect: [ItemWhereUniqueInput!] - set: [ItemWhereUniqueInput!] - create: [ItemCreateInput!] - connect: [ItemWhereUniqueInput!] -} -``` diff --git a/.changeset/silly-impalas-type.md b/.changeset/silly-impalas-type.md deleted file mode 100644 index e58a4065155..00000000000 --- a/.changeset/silly-impalas-type.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@keystone-next/example-custom-admin-ui-navigation': major ---- - -Initial version of the custom-admin-ui-navigation example. diff --git a/.changeset/smooth-moose-eat.md b/.changeset/smooth-moose-eat.md deleted file mode 100644 index 63c01fa8093..00000000000 --- a/.changeset/smooth-moose-eat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@keystone-next/keystone": patch ---- - -Updated Prisma dependencies to `2.28.0`. diff --git a/.changeset/strange-crabs-glow.md b/.changeset/strange-crabs-glow.md deleted file mode 100644 index ada423ec843..00000000000 --- a/.changeset/strange-crabs-glow.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -'@keystone-next/keystone': major -'@keystone-next/types': major -'@keystone-next/fields-document': patch -'@keystone-next/fields': patch ---- - -The generated CRUD queries, and some of the input types, in the GraphQL API have been renamed. - -If you have a list called `Item`, the query for multiple values, `allItems` will be renamed to `items`. The query for a single value, `Item`, will be renamed to `item`. - -Also, the input type used in the `updateItems` mutation has been renamed from `ItemsUpdateInput` to `ItemUpdateArgs`. diff --git a/.changeset/tidy-suits-refuse.md b/.changeset/tidy-suits-refuse.md deleted file mode 100644 index 88067ac37d5..00000000000 --- a/.changeset/tidy-suits-refuse.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@keystone-next/keystone': patch ---- - -Updated internal error handling to use the `apollo-server-errors` package instead of `apollo-errors`. \ No newline at end of file diff --git a/.changeset/tough-geese-trade.md b/.changeset/tough-geese-trade.md deleted file mode 100644 index 02343afcfbd..00000000000 --- a/.changeset/tough-geese-trade.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@keystone-next/types': patch ---- - -Updated types to allow the `'id'` field in `ui.labelField`, `ui.listView.initialColumns`, and `ui.listView.initialSort`. diff --git a/.changeset/wet-frogs-share.md b/.changeset/wet-frogs-share.md deleted file mode 100644 index e939b428e24..00000000000 --- a/.changeset/wet-frogs-share.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -'@keystone-next/auth': major -'@keystone-next/fields': major -'@keystone-next/keystone': major -'@keystone-next/types': major ---- - -The update mutations now accept `where` unique inputs instead of only an `id` and the `where` and `data` arguments are non-null. - -If you have a list called `Item`, the update mutations now look like this: - -```graphql -type Mutation { - updateItem(where: ItemWhereUniqueInput!, data: ItemUpdateInput!): Item - updateItems(data: [ItemUpdateArgs!]!): [Item] -} - -input ItemUpdateArgs { - where: ItemWhereUniqueInput! - data: ItemUpdateInput! -} -``` diff --git a/.changeset/wise-pianos-flash.md b/.changeset/wise-pianos-flash.md deleted file mode 100644 index 9a6d732caf1..00000000000 --- a/.changeset/wise-pianos-flash.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@keystone-next/keystone': major -'@keystone-next/types': major ---- - -The delete mutations now accept `where` unique inputs instead of only an `id`. - -If you have a list called `Item`, `deleteItem` now looks like `deleteItem(where: ItemWhereUniqueInput!): Item` and `deleteItems` now looks like `deleteItems(where: [ItemWhereUniqueInput!]!): [Item]` diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0e1e0d9cf98..fb9ea6031fd 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -298,10 +298,10 @@ jobs: run: yarn - name: Install Dependencies of Browsers if: needs.should_run_tests.outputs.shouldRunTests == 'true' - uses: microsoft/playwright-github-action@v1 - - name: Install Browsers for Playwright + run: npx playwright install-deps + - name: Install Browsers if: needs.should_run_tests.outputs.shouldRunTests == 'true' - run: node ./node_modules/playwright/install.js + run: npx playwright install - name: Unit tests if: needs.should_run_tests.outputs.shouldRunTests == 'true' run: yarn jest --ci --runInBand tests/examples-smoke-tests/${{ matrix.test }} @@ -396,3 +396,5 @@ jobs: run: yarn lint:markdown - name: Example schemas run: yarn lint:examples + - name: Prisma Filters + run: yarn lint:filters diff --git a/.prettierignore b/.prettierignore index dd5329b7230..023ecfd4978 100644 --- a/.prettierignore +++ b/.prettierignore @@ -8,3 +8,4 @@ coverage **/.keystone docs/public/assets/ .keystone/tests +prisma-utils/src/generated diff --git a/design-system/packages/button/package.json b/design-system/packages/button/package.json index fa23ea95133..5f81ce360d2 100644 --- a/design-system/packages/button/package.json +++ b/design-system/packages/button/package.json @@ -5,10 +5,10 @@ "main": "dist/button.cjs.js", "module": "dist/button.esm.js", "devDependencies": { - "@types/react": "^17.0.15" + "@types/react": "^17.0.18" }, "dependencies": { - "@babel/runtime": "^7.14.8", + "@babel/runtime": "^7.15.3", "@keystone-ui/core": "^3.0.0", "@keystone-ui/icons": "^4.0.0", "@keystone-ui/loading": "^4.0.0", diff --git a/design-system/packages/core/package.json b/design-system/packages/core/package.json index ed7cad3272a..672d1c3ff4d 100644 --- a/design-system/packages/core/package.json +++ b/design-system/packages/core/package.json @@ -5,7 +5,7 @@ "main": "dist/core.cjs.js", "module": "dist/core.esm.js", "devDependencies": { - "@types/react": "^17.0.15", + "@types/react": "^17.0.18", "react": "^17.0.2", "react-dom": "^17.0.2" }, @@ -14,8 +14,8 @@ "react-dom": "^17.0.2" }, "dependencies": { - "@babel/runtime": "^7.14.8", - "@emotion/react": "^11.4.0", + "@babel/runtime": "^7.15.3", + "@emotion/react": "^11.4.1", "@types/facepaint": "^1.2.2", "facepaint": "^1.2.1" }, diff --git a/design-system/packages/fields/package.json b/design-system/packages/fields/package.json index 8813ee40496..a82ec123dc0 100644 --- a/design-system/packages/fields/package.json +++ b/design-system/packages/fields/package.json @@ -5,10 +5,10 @@ "main": "dist/fields.cjs.js", "module": "dist/fields.esm.js", "devDependencies": { - "@types/react": "^17.0.15" + "@types/react": "^17.0.18" }, "dependencies": { - "@babel/runtime": "^7.14.8", + "@babel/runtime": "^7.15.3", "@keystone-ui/core": "^3.1.0", "@keystone-ui/icons": "^4.0.0", "@keystone-ui/popover": "^4.0.2", diff --git a/design-system/packages/icons/package.json b/design-system/packages/icons/package.json index 3938ba866a9..7a3c11a6eb2 100644 --- a/design-system/packages/icons/package.json +++ b/design-system/packages/icons/package.json @@ -12,7 +12,7 @@ "@svgr/plugin-jsx": "^5.5.0", "@svgr/plugin-prettier": "^5.5.0", "@svgr/plugin-svgo": "^5.5.0", - "@types/react": "^17.0.15", + "@types/react": "^17.0.18", "chalk": "^4.1.2", "feather-icons": "^4.28.0", "fs-extra": "^10.0.0", @@ -21,7 +21,7 @@ "to-pascal-case": "^1.0.0" }, "dependencies": { - "@babel/runtime": "^7.14.8", + "@babel/runtime": "^7.15.3", "@keystone-ui/core": "^3.0.0" }, "peerDependencies": { diff --git a/design-system/packages/loading/package.json b/design-system/packages/loading/package.json index b037e822fec..98a7c74bebc 100644 --- a/design-system/packages/loading/package.json +++ b/design-system/packages/loading/package.json @@ -5,10 +5,10 @@ "main": "dist/loading.cjs.js", "module": "dist/loading.esm.js", "devDependencies": { - "@types/react": "^17.0.15" + "@types/react": "^17.0.18" }, "dependencies": { - "@babel/runtime": "^7.14.8", + "@babel/runtime": "^7.15.3", "@keystone-ui/core": "^3.0.0", "react": "^17.0.2" }, diff --git a/design-system/packages/modals/package.json b/design-system/packages/modals/package.json index b71ad2e6deb..43f4ad1d17c 100644 --- a/design-system/packages/modals/package.json +++ b/design-system/packages/modals/package.json @@ -5,10 +5,10 @@ "main": "dist/modals.cjs.js", "module": "dist/modals.esm.js", "devDependencies": { - "@types/react": "^17.0.15" + "@types/react": "^17.0.18" }, "dependencies": { - "@babel/runtime": "^7.14.8", + "@babel/runtime": "^7.15.3", "@keystone-ui/button": "^5.0.0", "@keystone-ui/core": "^3.0.0", "react": "^17.0.2", diff --git a/design-system/packages/notice/CHANGELOG.md b/design-system/packages/notice/CHANGELOG.md index 54449b00a52..9f450557c56 100644 --- a/design-system/packages/notice/CHANGELOG.md +++ b/design-system/packages/notice/CHANGELOG.md @@ -1,5 +1,11 @@ # @keystone-ui/notice +## 4.0.1 + +### Patch Changes + +- [#6220](https://github.com/keystonejs/keystone/pull/6220) [`c2bb6a9a5`](https://github.com/keystonejs/keystone/commit/c2bb6a9a596fc52a3c61ec5d91c79758e417e61d) Thanks [@timleslie](https://github.com/timleslie)! - Updated css to preserve whitespace formatting of error messages. + ## 4.0.0 ### Major Changes diff --git a/design-system/packages/notice/package.json b/design-system/packages/notice/package.json index e3a225031c7..77428a5a921 100644 --- a/design-system/packages/notice/package.json +++ b/design-system/packages/notice/package.json @@ -1,14 +1,14 @@ { "name": "@keystone-ui/notice", - "version": "4.0.0", + "version": "4.0.1", "license": "MIT", "main": "dist/notice.cjs.js", "module": "dist/notice.esm.js", "devDependencies": { - "@types/react": "^17.0.15" + "@types/react": "^17.0.18" }, "dependencies": { - "@babel/runtime": "^7.14.8", + "@babel/runtime": "^7.15.3", "@keystone-ui/button": "^5.0.0", "@keystone-ui/core": "^3.0.0", "@keystone-ui/icons": "^4.0.0", diff --git a/design-system/packages/options/package.json b/design-system/packages/options/package.json index 71e80dde29d..2a16ea71b94 100644 --- a/design-system/packages/options/package.json +++ b/design-system/packages/options/package.json @@ -11,7 +11,7 @@ "react": "^17.0.2" }, "dependencies": { - "@babel/runtime": "^7.14.8", + "@babel/runtime": "^7.15.3", "@keystone-ui/core": "^3.0.0", "@keystone-ui/fields": "^4.1.2", "@keystone-ui/icons": "^4.0.0", diff --git a/design-system/packages/pill/package.json b/design-system/packages/pill/package.json index 53ee6464e98..7687bdb2767 100644 --- a/design-system/packages/pill/package.json +++ b/design-system/packages/pill/package.json @@ -11,7 +11,7 @@ "react": "^17.0.2" }, "dependencies": { - "@babel/runtime": "^7.14.8", + "@babel/runtime": "^7.15.3", "@keystone-ui/core": "^3.0.0", "@keystone-ui/icons": "^4.0.0" }, diff --git a/design-system/packages/popover/package.json b/design-system/packages/popover/package.json index b1b4acb6245..52762002475 100644 --- a/design-system/packages/popover/package.json +++ b/design-system/packages/popover/package.json @@ -13,10 +13,10 @@ "react-dom": "^17.0.2" }, "dependencies": { - "@babel/runtime": "^7.14.8", + "@babel/runtime": "^7.15.3", "@keystone-ui/core": "^3.0.0", - "@popperjs/core": "^2.9.2", - "focus-trap": "^6.6.0", + "@popperjs/core": "^2.9.3", + "focus-trap": "^6.6.1", "react-popper": "^2.2.5" }, "engines": { diff --git a/design-system/packages/segmented-control/CHANGELOG.md b/design-system/packages/segmented-control/CHANGELOG.md index 339613f37d8..537191bf60f 100644 --- a/design-system/packages/segmented-control/CHANGELOG.md +++ b/design-system/packages/segmented-control/CHANGELOG.md @@ -1,5 +1,11 @@ # @keystone-ui/segmented-control +## 4.0.2 + +### Patch Changes + +- [#6235](https://github.com/keystonejs/keystone/pull/6235) [`6cd7ab78e`](https://github.com/keystonejs/keystone/commit/6cd7ab78e018fa0ffaddc1258426d23da19cd854) Thanks [@gwyneplaine](https://github.com/gwyneplaine)! - Fixed segmented-control focus style. + ## 4.0.1 ### Patch Changes diff --git a/design-system/packages/segmented-control/package.json b/design-system/packages/segmented-control/package.json index dc1d54f67d7..51d0acd8fdd 100644 --- a/design-system/packages/segmented-control/package.json +++ b/design-system/packages/segmented-control/package.json @@ -1,15 +1,15 @@ { "name": "@keystone-ui/segmented-control", - "version": "4.0.1", + "version": "4.0.2", "license": "MIT", "main": "dist/segmented-control.cjs.js", "module": "dist/segmented-control.esm.js", "devDependencies": { - "@types/react": "^17.0.15", + "@types/react": "^17.0.18", "react": "^17.0.2" }, "dependencies": { - "@babel/runtime": "^7.14.8", + "@babel/runtime": "^7.15.3", "@keystone-ui/core": "^3.1.0" }, "peerDependencies": { diff --git a/design-system/packages/toast/CHANGELOG.md b/design-system/packages/toast/CHANGELOG.md index 24cfbd25711..ae0d11b3ad0 100644 --- a/design-system/packages/toast/CHANGELOG.md +++ b/design-system/packages/toast/CHANGELOG.md @@ -1,5 +1,11 @@ # @keystone-ui/toast +## 4.0.2 + +### Patch Changes + +- [#6220](https://github.com/keystonejs/keystone/pull/6220) [`c2bb6a9a5`](https://github.com/keystonejs/keystone/commit/c2bb6a9a596fc52a3c61ec5d91c79758e417e61d) Thanks [@timleslie](https://github.com/timleslie)! - Updated css to preserve whitespace formatting of error messages. + ## 4.0.1 ### Patch Changes diff --git a/design-system/packages/toast/package.json b/design-system/packages/toast/package.json index 13eebb8f486..3c1ebc4c2df 100644 --- a/design-system/packages/toast/package.json +++ b/design-system/packages/toast/package.json @@ -1,15 +1,15 @@ { "name": "@keystone-ui/toast", - "version": "4.0.1", + "version": "4.0.2", "license": "MIT", "main": "dist/toast.cjs.js", "module": "dist/toast.esm.js", "devDependencies": { - "@types/react": "^17.0.15", + "@types/react": "^17.0.18", "react": "^17.0.2" }, "dependencies": { - "@babel/runtime": "^7.14.8", + "@babel/runtime": "^7.15.3", "@keystone-ui/core": "^3.0.0", "@keystone-ui/icons": "^4.0.0" }, diff --git a/design-system/packages/tooltip/package.json b/design-system/packages/tooltip/package.json index 8d1769949e8..57cefc86d4d 100644 --- a/design-system/packages/tooltip/package.json +++ b/design-system/packages/tooltip/package.json @@ -13,7 +13,7 @@ "react-dom": "^17.0.2" }, "dependencies": { - "@babel/runtime": "^7.14.8", + "@babel/runtime": "^7.15.3", "@keystone-ui/core": "^3.0.0", "@keystone-ui/popover": "^4.0.0", "apply-ref": "^1.0.0" diff --git a/design-system/website/package.json b/design-system/website/package.json index 80c912e0e83..f5816f89485 100644 --- a/design-system/website/package.json +++ b/design-system/website/package.json @@ -7,7 +7,7 @@ "dev": "next -p 8080" }, "dependencies": { - "@babel/runtime": "^7.14.8", + "@babel/runtime": "^7.15.3", "@keystone-ui/button": "^5.0.0", "@keystone-ui/core": "^3.0.0", "@keystone-ui/fields": "^4.1.2", @@ -21,7 +21,7 @@ "@keystone-ui/toast": "^4.0.1", "@keystone-ui/tooltip": "^4.0.0", "@preconstruct/next": "^3.0.0", - "@types/react": "^17.0.15", + "@types/react": "^17.0.18", "@types/react-dom": "^17.0.9", "@types/tinycolor2": "^1.4.3", "@types/webpack": "^4.41.30", diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 201702ee365..a1174b7a435 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,5 +1,12 @@ # @keystone-next/website +## 3.1.4 + +### Patch Changes + +- Updated dependencies [[`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`e985aa010`](https://github.com/keystonejs/keystone/commit/e985aa0104d30a779f21ec05d80e6b98ece87dfb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`69f47bfed`](https://github.com/keystonejs/keystone/commit/69f47bfed1eaa1269cfdc42071268a914bd4aa17), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda)]: + - @keystone-next/fields-document@8.0.0 + ## 3.1.3 ### Patch Changes diff --git a/docs/babel.config.js b/docs/babel.config.js new file mode 100644 index 00000000000..8808c5f11d7 --- /dev/null +++ b/docs/babel.config.js @@ -0,0 +1 @@ +module.exports = require('../babel.config'); diff --git a/docs/components/docs/Navigation.tsx b/docs/components/docs/Navigation.tsx index e4e4f641ca5..f854aea01c7 100644 --- a/docs/components/docs/Navigation.tsx +++ b/docs/components/docs/Navigation.tsx @@ -136,28 +136,22 @@ export function DocsNavigation() { Keystone 5 vs 6 Command Line Relationships - Query Filters + + Query Filters Updated + Hooks Document Fields Document Field Demo - - Virtual Fields New - - - Testing New - + Virtual Fields + Testing - Custom Fields New - - - Custom Admin UI Logo New + Custom Fields Updated + Custom Admin UI Logo - Custom Admin UI Pages New - - - Custom Admin UI Navigation New + Custom Admin UI Pages Updated + Custom Admin UI Navigation Access Control @@ -190,8 +184,12 @@ export function DocsNavigation() { DB Item API GraphQL - GraphQL API - Query Filter API + + GraphQL API Updated + + + Query Filter API Updated + ); diff --git a/docs/next-env.d.ts b/docs/next-env.d.ts index 7b7aa2c7727..f87ea7fa66a 100644 --- a/docs/next-env.d.ts +++ b/docs/next-env.d.ts @@ -1,2 +1,4 @@ +// @ts-ignore /// /// +/// diff --git a/docs/next.config.js b/docs/next.config.js index e3c02223414..cd2df154aed 100644 --- a/docs/next.config.js +++ b/docs/next.config.js @@ -1,6 +1,5 @@ const withPreconstruct = require('@preconstruct/next'); const withPlugins = require('next-compose-plugins'); -const withImages = require('next-images'); const mdxHints = require('remark-hint'); const gfm = require('remark-gfm'); @@ -20,7 +19,6 @@ const redirects = { module.exports = withPlugins([ withPreconstruct, - withImages, [ withMDX, { @@ -31,9 +29,7 @@ module.exports = withPlugins([ nextConfig.env = { siteUrl: 'https://keystonejs.com', }; - nextConfig.future = { - webpack5: true, - }; + nextConfig.eslint = { ignoreDuringBuilds: true }; nextConfig.typescript = { ...nextConfig.typescript, // we run TS elsewhere, Next runs against a different TS config which it insists on existing diff --git a/docs/package.json b/docs/package.json index 7e15ef884bb..4020fe7a8a1 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/website", - "version": "3.1.3", + "version": "3.1.4", "private": true, "license": "MIT", "scripts": { @@ -13,20 +13,20 @@ "cypress:run:ci": "yarn build && start-server-and-test start http://localhost:8000 cy:run" }, "dependencies": { - "@babel/runtime": "^7.14.8", + "@babel/runtime": "^7.15.3", "@emotion/cache": "11.4.0", - "@emotion/react": "^11.4.0", + "@emotion/react": "^11.4.1", "@emotion/server": "11.4.0", "@emotion/weak-memoize": "^0.2.5", - "@keystone-next/fields-document": "^7.0.2", + "@keystone-next/fields-document": "^8.0.0", "@mdx-js/loader": "next", "@mdx-js/react": "^1.6.22", - "@next/mdx": "^10.2.3", + "@next/mdx": "^11.1.0", "@preconstruct/next": "^3.0.0", "@sindresorhus/slugify": "^1.1.2", "@types/gtag.js": "^0.0.7", "@types/mdx-js__react": "^1.5.4", - "@types/react": "^17.0.15", + "@types/react": "^17.0.18", "@types/react-dom": "^17.0.9", "@types/webpack": "^4.41.30", "classnames": "^2.3.1", @@ -34,9 +34,8 @@ "cypress": "^5.6.0", "date-fns": "^2.23.0", "facepaint": "^1.2.1", - "next": "^10.2.3", + "next": "npm:next@^11.1.0", "next-compose-plugins": "^2.2.1", - "next-images": "^1.8.1", "prism-react-renderer": "^1.2.1", "react": "^17.0.2", "react-dom": "^17.0.2", @@ -46,7 +45,7 @@ "remark-hint": "^1.0.10" }, "devDependencies": { - "next-sitemap": "^1.6.140", + "next-sitemap": "^1.6.157", "start-server-and-test": "^1.13.1", "typescript": "^4.3.5" }, diff --git a/docs/pages/docs/apis/access-control.mdx b/docs/pages/docs/apis/access-control.mdx index b44076c2b11..d408568a48d 100644 --- a/docs/pages/docs/apis/access-control.mdx +++ b/docs/pages/docs/apis/access-control.mdx @@ -105,7 +105,7 @@ export default config({ ListKey: list({ fields: { isLocked: checkbox() }, // Declarative access control definition - access: { isLocked: false }, + access: { isLocked: { equals: false } }, }), }), }); diff --git a/docs/pages/docs/apis/auth.mdx b/docs/pages/docs/apis/auth.mdx index 2026ab6e974..bca3897dbd6 100644 --- a/docs/pages/docs/apis/auth.mdx +++ b/docs/pages/docs/apis/auth.mdx @@ -78,11 +78,11 @@ const { withAuth } = createAuth({ The following elements will be added to the GraphQL API. ```graphql -Mutation { +type Mutation { authenticateUserWithPassword(email: String!, password: String!): UserAuthenticationWithPasswordResult! } -Query { +type Query { authenticatedItem: AuthenticatedItem } @@ -188,7 +188,7 @@ const { withAuth } = createAuth({ Enabling `initFirstItem` will add the following elements to the GraphQL API. ```graphql -Mutation { +type Mutation { createInitialUser(data: CreateInitialUserInput!): UserAuthenticationWithPasswordSuccess! } @@ -274,12 +274,12 @@ const fields = { Enabling `passwordResetLink` will add the following elements to the GraphQL API. ```graphql -Mutation { +type Mutation { sendUserPasswordResetLink(email: String!): SendUserPasswordResetLinkResult redeemUserPasswordResetToken(email: String!, token: String!, password: String!): RedeemUserPasswordResetTokenResult } -Query { +type Query { validateUserPasswordResetToken(email: String!, token: String!): ValidateUserPasswordResetTokenResult } @@ -413,7 +413,7 @@ const fields = { Enabling `magicAuthLink` will add the following elements to the GraphQL API. ```graphql -Mutation { +type Mutation { sendUserMagicAuthLink(email: String!): SendUserMagicAuthLinkResult redeemUserMagicAuthToken(email: String!, token: String!): RedeemUserMagicAuthTokenResult! } diff --git a/docs/pages/docs/apis/config.mdx b/docs/pages/docs/apis/config.mdx index aa881ffab0e..3b6e7618400 100644 --- a/docs/pages/docs/apis/config.mdx +++ b/docs/pages/docs/apis/config.mdx @@ -119,13 +119,15 @@ The `sqlite` provider is not intended to be used in production systems, and has - `decimal`: The `decimal` field type is not supported. - `timestamp`: The `timestamp` field type only supports times within the range `1970 - 2038`. -- `text`: The `text` field type does not support the advanced filtering operations `contains`, `starts_with`, `ends_with`, or case insensitive filtering. -- `autoIncrement`: The `autoIncrement` field type can only be used as an `id` field. +- `text`: The `text` field type does not support setting a filter as case sensitive or insensitive. + Assuming default collation, all the filters except `contains`, `startsWith` and `endsWith` will be case sensitive + and `contains`, `startsWith` and `endsWith` will be case insensitive but only for ASCII characters. +- `autoIncrement`: The `autoIncrement` field type is not supported. - `select`: Using the `dataType: 'enum'` will use a GraphQL `String` type, rather than an `Enum` type. ## ui -``` +```ts import type { AdminUIConfig } from '@keystone-next/types'; ``` @@ -277,6 +279,8 @@ It has a TypeScript type of `GraphQLConfig`. Options: +- `debug` (default: `process.env.NODE_ENV !== 'production'`): If `true`, stacktraces from both Apollo errors and Keystone errors will be included in the errors returned from the GraphQL API. + These can be filtered out with `apolloConfig.formatError` if you need to process them, but do not want them returned over the GraphQL API. - `queryLimits` (default: `undefined`): Allows you to limit the total number of results returned from a query to your GraphQL API. See also the per-list `graphql.queryLimits` option in the [Schema API](./schema). - `apolloConfig` (default: `undefined`): Allows you to pass extra options into the `ApolloServer` constructor. @@ -287,6 +291,7 @@ Options: ```typescript export default config({ graphql: { + debug: process.env.NODE_ENV !== 'production', queryLimits: { maxTotalResults: 100 }, apolloConfig: { playground: process.env.NODE_ENV !== 'production', diff --git a/docs/pages/docs/apis/db-items.mdx b/docs/pages/docs/apis/db-items.mdx index 80544c7d345..e857f995535 100644 --- a/docs/pages/docs/apis/db-items.mdx +++ b/docs/pages/docs/apis/db-items.mdx @@ -16,14 +16,14 @@ For each list in your system the following API is available at `context.db.lists ``` { findOne({ where: { id } }), - findMany({ where, first, skip, sortBy }), - count({ where, first, skip }), + findMany({ where, take, skip, orderBy }), + count({ where }), createOne({ data }), createMany({ data }), - updateOne({ id, data }), + updateOne({ where, data }), updateMany({ data }), - deleteOne({ id }), - deleteMany({ ids }), + deleteOne({ where }), + deleteMany({ where }), } ``` @@ -44,10 +44,10 @@ All arguments are optional. ```typescript const users = await context.db.lists.User.findMany({ - where: { name_starts_with: 'A' }, - first: 10, + where: { name: { startsWith: 'A' } }, + take: 10, skip: 20, - sortBy: ['name_ASC'], + orderBy: [{ name: 'asc' }], }); ``` @@ -57,9 +57,7 @@ All arguments are optional. ```typescript const count = await context.db.lists.User.count({ - where: { name_starts_with: 'A' }, - first: 10, - skip: 20, + where: { name: { startsWith: 'A' } }, }); ``` @@ -80,16 +78,12 @@ const user = await context.db.lists.User.createOne({ const users = await context.db.lists.User.createMany({ data: [ { - data: { - name: 'Alice', - posts: [{ create: { title: 'Alices first post' } }], - }, + name: 'Alice', + posts: [{ create: { title: 'Alices first post' } }], }, { - data: { - name: 'Bob', - posts: [{ create: { title: 'Bobs first post' } }], - }, + name: 'Bob', + posts: [{ create: { title: 'Bobs first post' } }], }, ], }); @@ -99,7 +93,7 @@ const users = await context.db.lists.User.createMany({ ```typescript const user = await context.db.lists.User.updateOne({ - id: '...', + where: { id: '...' }, data: { name: 'Alice', posts: { create: [{ title: 'My first post' }] }, @@ -113,14 +107,14 @@ const user = await context.db.lists.User.updateOne({ const users = await context.db.lists.User.updateMany({ data: [ { - id: '...', + where: { id: '...' }, data: { name: 'Alice', posts: [{ create: { title: 'Alices first post' } }], }, }, { - id: '...', + where: { id: '...' }, data: { name: 'Bob', posts: [{ create: { title: 'Bobs first post' } }], @@ -134,15 +128,15 @@ const users = await context.db.lists.User.updateMany({ ```typescript const user = await context.db.lists.User.deleteOne({ - id: '...', + where: { id: '...' }, }); ``` ### deleteMany ```typescript -const user = await context.db.lists.User.deleteMany({ - ids: ['...', '...'], +const users = await context.db.lists.User.deleteMany({ + where: [{ id: '...' }, { id: '...' }], }); ``` diff --git a/docs/pages/docs/apis/filters.mdx b/docs/pages/docs/apis/filters.mdx index 6fbee0d3c38..5e58fc12cad 100644 --- a/docs/pages/docs/apis/filters.mdx +++ b/docs/pages/docs/apis/filters.mdx @@ -6,30 +6,27 @@ Each field type provides its own set of filters which can be used with [queries] This page lists all the filters available for each field type. For more details on how to use filters in queries please consult to the [GraphQL Queries - Filters](../guides/filters) guide. -Keystone filters are typically named after the field they are filtering. For example, a `text` field called `foo` would have filters named `foo_starts_with`, `foo_contains`, etc. -In all the examples below we will use a field named `foo` as the base of the filter names. - ## Scalar types ### checkbox -| **Filter name** | **Type** | **Description** | -| --------------- | --------- | --------------- | -| `foo` | `Boolean` | Equals | -| `foo_not` | `Boolean` | Does not equal | +| **Filter name** | **Type** | **Description** | +| --------------- | ----------------------- | ------------------------------- | +| `equals` | `Boolean` | Equals | +| `not` | `BooleanNullableFilter` | Does not match the inner filter | ### integer -| **Filter name** | **Type** | **Description** | -| --------------- | -------- | --------------------- | -| `foo` | `Int` | Equals | -| `foo_not` | `Int` | Does not equal | -| `foo_lt` | `Int` | Less than | -| `foo_lte` | `Int` | Less than or equal | -| `foo_gt` | `Int` | Greater than | -| `foo_gte` | `Int` | Greater than or equal | -| `foo_in` | `[Int]` | Is in the array | -| `foo_not_in` | `[Int]` | Is not in the array | +| **Filter name** | **Type** | **Description** | +| --------------- | ------------------- | ------------------------------- | +| `equals` | `Int` | Equals | +| `lt` | `Int` | Less than | +| `lte` | `Int` | Less than or equal | +| `gt` | `Int` | Greater than | +| `gte` | `Int` | Greater than or equal | +| `in` | `[Int!]` | Is in the array | +| `notIn` | `[Int!]` | Is not in the array | +| `not` | `IntNullableFilter` | Does not match the inner filter | ### json @@ -37,67 +34,69 @@ The `json` field type does not support filters. ### float -| **Filter name** | **Type** | **Description** | -| --------------- | --------- | --------------------- | -| `foo` | `Float` | Equals | -| `foo_not` | `Float` | Does not equal | -| `foo_lt` | `Float` | Less than | -| `foo_lte` | `Float` | Less than or equal | -| `foo_gt` | `Float` | Greater than | -| `foo_gte` | `Float` | Greater than or equal | -| `foo_in` | `[Float]` | Is in the array | -| `foo_not_in` | `[Float]` | Is not in the array | +| **Filter name** | **Type** | **Description** | +| --------------- | --------------------- | ------------------------------- | +| `equals` | `Float` | Equals | +| `lt` | `Float` | Less than | +| `lte` | `Float` | Less than or equal | +| `gt` | `Float` | Greater than | +| `gte` | `Float` | Greater than or equal | +| `in` | `[Float!]` | Is in the array | +| `notIn` | `[Float!]` | Is not in the array | +| `not` | `FloatNullableFilter` | Does not match the inner filter | ### password | **Filter name** | **Type** | **Description** | | --------------- | --------- | --------------- | -| `foo_is_set` | `Boolean` | A value is set | +| `isSet` | `Boolean` | A value is set | ### select -| **Filter name** | **Type** | **Description** | -| --------------- | ---------- | ------------------- | -| `foo` | `String` | Equals | -| `foo_not` | `String` | Does not equal | -| `foo_in` | `[String]` | Is in the array | -| `foo_not_in` | `[String]` | Is not in the array | +- If the `dataType` is `string`(the default), the same filters as `text` will be available. +- If the `dataType` is `integer`, the same filters as `integer` will be available. +- If the `dataType` is `enum`, the following filters will be available: + | **Filter name** | **Type** | **Description** | + | --------------- | ---------- | ------------------- | + | `equals` | `ListKeyFieldKeyType` | Equals | + | `in` | `[ListKeyFieldKeyType!]` | Is in the array | + | `notIn` | `[ListKeyFieldKeyType!]` | Is not in the array | + | `not` | `ListKeyFieldKeyTypeNullableFilter` | Does not match the inner filter | ### text -| **Filter name** | **Type** | **Description** | ** Notes ** | -| ----------------------- | ---------- | -------------------------------------- | ----------------- | -| `foo` | `String` | Equals | -| `foo_not` | `String` | Does not equal | -| `foo_contains` | `String` | Contains | -| `foo_not_contains` | `String` | Does not contain | -| `foo_starts_with` | `String` | Starts with | `postgresql` only | -| `foo_not_starts_with` | `String` | Does not start with | `postgresql` only | -| `foo_ends_with` | `String` | Ends with | `postgresql` only | -| `foo_not_ends_with` | `String` | Does not end with | `postgresql` only | -| `foo_i` | `String` | Equals (case insensitive) | `postgresql` only | -| `foo_not_i` | `String` | Does not equal (case insensitive) | `postgresql` only | -| `foo_contains_i` | `String` | Contains (case insensitive) | `postgresql` only | -| `foo_not_contains_i` | `String` | Does not contain (case insensitive) | `postgresql` only | -| `foo_starts_with_i` | `String` | Starts with (case insensitive) | `postgresql` only | -| `foo_not_starts_with_i` | `String` | Does not start with (case insensitive) | `postgresql` only | -| `foo_ends_with_i` | `String` | Ends with (case insensitive) | `postgresql` only | -| `foo_not_ends_with_i` | `String` | Does not end with (case insensitive) | `postgresql` only | -| `foo_in` | `[String]` | Is in the array | -| `foo_not_in` | `[String]` | Is not in the array | +| **Filter name** | **Type** | **Description** | **Notes** | +| --------------- | ---------------------------------------- | ----------------------------------------------------- | --------- | +| `equals` | `String` | Equals | +| `lt` | `String` | Less than | +| `lte` | `String` | Less than or equal | +| `gt` | `String` | Greater than | +| `gte` | `String` | Greater than or equal | +| `contains` | `String` | Contains | [1] | +| `startsWith` | `String` | Starts with | [1] | +| `endsWith` | `String` | Ends with | [1] | +| `in` | `[String!]` | Is in the array | +| `notIn` | `[String!]` | Is not in the array | +| `mode` | `QueryMode` (`default` or `insensitive`) | Whether the filters should be case insensitive or not | [2] | +| `not` | `NestedStringNullableFilter` | Does not match the inner filter | + +#### Notes + +- [1] Will follow the setting of the `mode` on `postgresql` and will be case insensitive but only for ASCII characters on `sqlite` +- [2] `postgresql` only ### timestamp -| **Filter name** | **Type** | **Description** | -| --------------- | ---------- | --------------------- | -| `foo` | `String` | Equals | -| `foo_not` | `String` | Does not equal | -| `foo_lt` | `String` | Less than | -| `foo_lte` | `String` | Less than or equal | -| `foo_gt` | `String` | Greater than | -| `foo_gte` | `String` | Greater than or equal | -| `foo_in` | `[String]` | Is in the array | -| `foo_not_in` | `[String]` | Is not in the array | +| **Filter name** | **Type** | **Description** | +| --------------- | ------------------------ | ------------------------------- | +| `equals` | `String` | Equals | +| `lt` | `String` | Less than | +| `lte` | `String` | Less than or equal | +| `gt` | `String` | Greater than | +| `gte` | `String` | Greater than or equal | +| `in` | `[String!]` | Is in the array | +| `notIn` | `[String!]` | Is not in the array | +| `not` | `DateTimeNullableFilter` | Does not match the inner filter | ## Relationship type @@ -107,31 +106,30 @@ The `json` field type does not support filters. | **Filter name** | **Type** | **Description** | | --------------- | --------------- | ------------------------------------------ | -| `foos_every` | `FooWhereInput` | All related items match the nested filter | -| `foos_some` | `FooWhereInput` | Some related items match the nested filter | -| `foos_none` | `FooWhereInput` | No related items match the nested filter | +| `every` | `FooWhereInput` | All related items match the nested filter | +| `some` | `FooWhereInput` | Some related items match the nested filter | +| `none` | `FooWhereInput` | No related items match the nested filter | #### many: false | **Filter name** | **Type** | **Description** | | --------------- | --------------- | ------------------------- | | `foo` | `FooWhereInput` | Matches the nested filter | -| `foo_is_null` | `Boolean` | Is `null` | ## Index types ### autoIncrement -| **Filter name** | **Type** | **Description** | -| --------------- | -------- | --------------------- | -| `id` | `ID` | Equals | -| `id_not` | `ID` | Does not equal | -| `id_lt` | `ID` | Less than | -| `id_lte` | `ID` | Less than or equal | -| `id_gt` | `ID` | Greater than | -| `id_gte` | `ID` | Greater than or equal | -| `id_in` | `[ID]` | Is in the array | -| `id_not_in` | `[ID]` | Is not in the array | +| **Filter name** | **Type** | **Description** | +| --------------- | ------------------- | ------------------------------- | +| `equals` | `Int` | Equals | +| `lt` | `Int` | Less than | +| `lte` | `Int` | Less than or equal | +| `gt` | `Int` | Greater than | +| `gte` | `Int` | Greater than or equal | +| `in` | `[Int!]` | Is in the array | +| `notIn` | `[Int!]` | Is not in the array | +| `not` | `IntNullableFilter` | Does not match the inner filter | ## Virtual type diff --git a/docs/pages/docs/apis/graphql.mdx b/docs/pages/docs/apis/graphql.mdx index 4299ec7f2b2..37c9099195d 100644 --- a/docs/pages/docs/apis/graphql.mdx +++ b/docs/pages/docs/apis/graphql.mdx @@ -24,18 +24,14 @@ This system will generate the following GraphQL API. ```graphql type Query { - User(where: UserWhereUniqueInput!): User - allUsers(where: UserWhereInput, search: String, orderBy: [UserOrderByInput!]! = [], first: Int, skip: Int! = 0): [User] - _allUsersMeta(where: UserWhereInput, search: String, orderBy: [UserOrderByInput!]! = [], first: Int, skip: Int! = 0): _QueryMeta -} - -type Mutation { - createUser(data: UserCreateInput): User - createUsers(data: [UsersCreateInput]): [User] - updateUser(id: ID!, data: UserUpdateInput): User - updateUsers(data: [UsersUpdateInput]): [User] - deleteUser(id: ID!): User - deleteUsers(ids: [ID!]): [User] + users( + where: UserWhereInput! = {} + orderBy: [UserOrderByInput!]! = [] + take: Int + skip: Int! = 0 + ): [User!] + user(where: UserWhereUniqueInput!): User + usersCount(where: UserWhereInput! = {}): Int } type User { @@ -43,39 +39,61 @@ type User { name: String } -input UserWhereInput { - AND: [UserWhereInput!] - OR: [UserWhereInput!] +input UserWhereUniqueInput { id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_starts_with: String - name_not_starts_with: String - name_ends_with: String - name_not_ends_with: String - name_i: String - name_not_i: String - name_contains_i: String - name_not_contains_i: String - name_starts_with_i: String - name_not_starts_with_i: String - name_ends_with_i: String - name_not_ends_with_i: String - name_in: [String] - name_not_in: [String] } -input UserWhereUniqueInput { - id: ID +input UserWhereInput { + AND: [UserWhereInput!] + OR: [UserWhereInput!] + NOT: [UserWhereInput!] + id: IDFilter + name: StringNullableFilter +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + mode: QueryMode + not: NestedStringNullableFilter +} + +enum QueryMode { + default + insensitive +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter } input UserOrderByInput { @@ -88,83 +106,116 @@ enum OrderDirection { desc } +type Mutation { + createUser(data: UserCreateInput!): User + createUsers(data: [UserCreateInput!]!): [User] + updateUser(where: UserWhereUniqueInput!, data: UserUpdateInput!): User + updateUsers(data: [UserUpdateArgs!]!): [User] + deleteUser(where: UserWhereUniqueInput!): User + deleteUsers(where: [UserWhereUniqueInput!]!): [User] +} + input UserUpdateInput { name: String } -input UsersUpdateInput { - id: ID! - data: UserUpdateInput +input UserUpdateArgs { + where: UserWhereUniqueInput! + data: UserUpdateInput! } input UserCreateInput { name: String } - -input UsersCreateInput { - data: UserCreateInput -} - -type _QueryMeta { - count: Int -} ``` ## Queries -### User +### user ```graphql type Query { - User(where: UserWhereUniqueInput!): User -} - -input UserWhereUniqueInput { - id: ID + user(where: UserWhereUniqueInput!): User } type User { id: ID! name: String } + +input UserWhereUniqueInput { + id: ID +} ``` -### allUsers +### users ```graphql type Query { - allUsers(where: UserWhereInput, search: String, orderBy: [UserOrderByInput!]! = [], first: Int, skip: Int! = 0): [User] + users( + where: UserWhereInput! = {} + orderBy: [UserOrderByInput!]! = [] + take: Int + skip: Int! = 0 + ): [User!] +} + +type User { + id: ID! + name: String } input UserWhereInput { AND: [UserWhereInput!] OR: [UserWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_starts_with: String - name_not_starts_with: String - name_ends_with: String - name_not_ends_with: String - name_i: String - name_not_i: String - name_contains_i: String - name_not_contains_i: String - name_starts_with_i: String - name_not_starts_with_i: String - name_ends_with_i: String - name_not_ends_with_i: String - name_in: [String] - name_not_in: [String] + NOT: [UserWhereInput!] + id: IDFilter + name: StringNullableFilter +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + mode: QueryMode + not: NestedStringNullableFilter +} + +enum QueryMode { + default + insensitive +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter } input UserOrderByInput { @@ -176,63 +227,66 @@ enum OrderDirection { asc desc } - -type User { - id: ID! - name: String -} ``` ### usersCount ```graphql type Query { - usersCount(where: UserWhereInput! = {}): Int! + usersCount(where: UserWhereInput! = {}): Int } input UserWhereInput { AND: [UserWhereInput!] OR: [UserWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_starts_with: String - name_not_starts_with: String - name_ends_with: String - name_not_ends_with: String - name_i: String - name_not_i: String - name_contains_i: String - name_not_contains_i: String - name_starts_with_i: String - name_not_starts_with_i: String - name_ends_with_i: String - name_not_ends_with_i: String - name_in: [String] - name_not_in: [String] -} - -input UserOrderByInput { - id: OrderDirection - name: OrderDirection -} - -enum OrderDirection { - asc - desc -} - -type _QueryMeta { - count: Int + NOT: [UserWhereInput!] + id: IDFilter + name: StringNullableFilter +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + mode: QueryMode + not: NestedStringNullableFilter +} + +enum QueryMode { + default + insensitive +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter } ``` @@ -242,7 +296,7 @@ type _QueryMeta { ```graphql type Mutation { - createUser(data: UserCreateInput): User + createUser(data: UserCreateInput!): User } input UserCreateInput { @@ -259,11 +313,7 @@ type User { ```graphql type Mutation { - createUsers(data: [UsersCreateInput]): [User] -} - -input UsersCreateInput { - data: UserCreateInput + createUsers(data: [UserCreateInput!]!): [User] } input UserCreateInput { @@ -280,7 +330,11 @@ type User { ```graphql type Mutation { - updateUser(id: ID!, data: UserUpdateInput): User + updateUser(where: UserWhereUniqueInput!, data: UserUpdateInput!): User +} + +input UserWhereUniqueInput { + id: ID } input UserUpdateInput { @@ -297,12 +351,16 @@ type User { ```graphql type Mutation { - updateUsers(data: [UsersUpdateInput]): [User] + updateUsers(data: [UserUpdateArgs!]!): [User] } -input UsersUpdateInput { - id: ID! - data: UserUpdateInput +input UserUpdateArgs { + where: UserWhereUniqueInput! + data: UserUpdateInput! +} + +input UserWhereUniqueInput { + id: ID } input UserUpdateInput { @@ -319,7 +377,11 @@ type User { ```graphql type Mutation { - deleteUser(id: ID!): User + deleteUser(where: UserWhereUniqueInput!): User +} + +input UserWhereUniqueInput { + id: ID } type User { @@ -332,7 +394,11 @@ type User { ```graphql type Mutation { - deleteUsers(ids: [ID!]): [User] + deleteUsers(ids: [UserWhereUniqueInput!]!): [User] +} + +input UserWhereUniqueInput { + id: ID } type User { diff --git a/docs/pages/docs/apis/list-items.mdx b/docs/pages/docs/apis/list-items.mdx index f8559c0d52a..12630497fd1 100644 --- a/docs/pages/docs/apis/list-items.mdx +++ b/docs/pages/docs/apis/list-items.mdx @@ -8,14 +8,14 @@ For each list in your system the following API is available at `context.lists. **Note:** This feature will improve over time. It has been released ahead of time to unblock developers. We are working on improving support for other styling frameworks besides Emotion and will be making it easier by exporting more Admin UI components in the near future. +In this guide we'll show you how to add custom pages to the Keystone Admin UI. +As the Admin UI is built on top of [Next.js](https://nextjs.org/docs/basic-features/pages), it exposes the same pages directory for adding custom pages. To create a custom page, ensure that the `admin/pages` directory exists in the root of your Keystone Project. Much like with Next.js, all files in this directory will be added as routes to the Admin UI. The default export of every file in this directory is expected to be a valid React Component rendered out as the contents of the route. ```tsx -// admin/pages/MyCustomPage.tsx -export default function () { +// admin/pages/custom-page.tsx +export default function CustomPage () { return ( <>

This is a custom Admin UI Page

-

It can be accessed via the route '/MyCustomPage'

+

It can be accessed via the route /custom-page

) } ``` -If you have styling constraints, we recommend using the jsx export from the `@keystone-ui/core` package, as this will ensure that the version of emotion you're using conforms with the version of emotion used internally within Keystone. +x> **Not all Next.js exports are available:** Keystone **only** supports the page component as a default export in the pages directory. This means that unlike with Next, auxillary exports such as `getStaticProps` and `getServerProps` are not supported. + +With this in place, we now have a nice simple custom Admin UI page at `http://localhost:3000/custom-page`. +![example of a simple custom-page in the Admin UI](/assets/guides/custom-admin-ui-pages/simple-custom-page.png) + +## Adding Admin UI layout + +At the moment this page is pretty bare bones. We want our page to look more like an Admin UI page. +Keystone helps us do this via the `PageContainer` component exported from `@keystone-next/keystone/admin-ui/components`. + +The `PageContainer` component takes a `header` prop, which is expected to be a `ReactElement`. +This `header` prop is rendered out as the page title at the top of the page. + +```tsx +// admin/pages/custom-page.tsx +import { PageContainer } from '@keystone-next/keystone/admin-ui/components'; +export default function CustomPage () { + return ( + +

This is a custom Admin UI Page

+

It can be accessed via the route /custom-page

+
+ ) +} +``` + +With the above snippet, our custom page looks a lot more like the other pages in the Admin UI. +![example of the custom Admin UI page with the PageContainer component](/assets/guides/custom-admin-ui-pages/custom-page-w-page-container.png) + +There's still a problem though, the header doesn't look right. If we compare the header of our custom page with the header for the Dashboard, there's quite a bit of difference in the styling and font-weight. +![example of the Dashboard header element](/assets/guides/custom-admin-ui-pages/header-prop.png) + +Keystone pages leverage the `Heading` component from the `@keystone-ui/core` package to style the header, so let's use this to give our header the same styling. + +```tsx +// admin/pages/custom-page.tsx +import { PageContainer } from '@keystone-next/keystone/admin-ui/components'; +import { Heading } from '@keystone-ui/core'; + +export default function CustomPage () { + return ( + Custom Page}> +

This is a custom Admin UI Page

+

It can be accessed via the route `/custom-page`

+
+ ) +} +``` + +Much better, our custom page looks and feels like an Admin UI page now. +![custom page with correctly styled header](/assets/guides/custom-admin-ui-pages/custom-page-with-styled-header.png) + +## Custom route in Admin UI Navigation + +Yes, our custom page is looking pretty great, and much more like an Admin UI page, but it's not visible as a navigation item. +We can fix this by adding a custom Navigation component with a route pointing to our custom page. + +First add the following files to the `/admin` directory in the root of your Keystone project. + +```tsx +// admin/config.ts +import type { AdminConfig } from '@keystone-next/types'; +import { CustomNavigation } from './components/CustomNavigation'; +export const components: AdminConfig['components']= { + Navigation: CustomNavigation +}; +``` + +```tsx +// admin/components/CustomNavigation.tsx +import { NavigationContainer, ListNavItems, NavItem } from '@keystone-next/keystone/admin-ui/components'; +import type { NavigationProps } from '@keystone-next/keystone/admin-ui/components'; +export function CustomNavigation({ lists, authenticatedItem }: NavigationProps) { + return ( + + Dashboard + + + ) +} +``` + +!> You will need to restart your Keystone system after adding `admin/config.ts` for the custom Navigation component to be loaded. + +!> If you're interested in more details on creating a custom Navigation component check out the [Custom Admin UI Navigation](/docs/guides/custom-admin-ui-navigation) guide. + +Lastly we'll add our new route to the newly created `CustomNavigation` component. ```tsx -// admin/pages/MyCustomPage.tsx +// admin/components/CustomNavigation.tsx +import { NavigationContainer, ListNavItems, NavItem } from '@keystone-next/keystone/admin-ui/components'; +import type { NavigationProps } from '@keystone-next/keystone/admin-ui/components'; +export function CustomNavigation({ lists, authenticatedItem }: NavigationProps) { + return ( + + Dashboard + + Custom Page + + ) +} +``` + +!> Under the hood Keystone's Admin UI is powered by Next.js, so the route to our custom page is the filename of our custom page component. In this case it's `/custom-page`. + +With all that in place, our custom Admin UI page is now navigable from the Admin UI Navigation component, and we can access it from other pages in the Admin UI. +![completed custom Admin UI page](/assets/guides/custom-admin-ui-pages/custom-page-completed.png) + +## Styling + +There are other styling considerations when adding a custom page to the Admin UI that go beyond making it _look_ and _feel_ like an Admin UI page. +For this, we recommend using the `jsx` runtime export from the `@keystone-ui/core` package, as this will ensure that the version of [emotion](https://emotion.sh/docs/introduction) you're using conforms with the version of emotion used internally used by Keystone. + +The snippet below uses the emotion `jsx` runtime exported from `@keystone-ui/core` to help add some basic allignment and layout styling to the contents of our Admin UI custom page. + +```tsx +// admin/pages/custom-page.tsx /** @jsxRuntime classic */ /** @jsx jsx */ + import { jsx } from '@keystone-ui/core'; -export default function () { +import { PageContainer } from '@keystone-next/keystone/admin-ui/components'; +import { Heading } from '@keystone-ui/core'; + +export default function CustomPage () { return ( - <> + + Custom Page + + )}>

This is a custom Admin UI Page

-

It can be accessed via the route '/MyCustomPage'

- + width: '100%', + textAlign: 'center', + }}> + This is a custom Admin UI Page + +

+ It can be accessed via the route /custom-page +

+
) } ``` -Of course this is purely a recommendation, if you would prefer to roll your own css-in-js solution in with your custom component please feel free to! Although this may require additional configuration outside of the scope of this guide. - -x> **Not all Next.js exports are available:** Keystone **only** supports the page component as a default export in the pages directory. This means that unlike with Next, auxillary exports such as `getStaticProps` and `getServerProps` are not supported. +Using `emotion` for styling is purely a recommendation, if you would prefer to use another css-in-js or css solution for your custom component please feel free to. This may require additional configuration currently outside of the scope of this guide. export default ({ children }) => {children}; diff --git a/docs/pages/docs/guides/custom-fields.mdx b/docs/pages/docs/guides/custom-fields.mdx index 5861be45495..8ccae1ba737 100644 --- a/docs/pages/docs/guides/custom-fields.mdx +++ b/docs/pages/docs/guides/custom-fields.mdx @@ -29,7 +29,7 @@ import { fieldType, schema, orderDirectionEnum, - legacyFilters, + filters, FieldDefaultValue, } from '@keystone-next/types'; @@ -58,6 +58,7 @@ export const myInt = })({ ...config, input: { + where: { arg: schema.arg({ type: filters[meta.provider].Int.optional }), resolve: filters.resolveCommon }, create: { arg: schema.arg({ type: schema.Int }) }, update: { arg: schema.arg({ type: schema.Int }) }, orderBy: { arg: schema.arg({ type: orderDirectionEnum }) }, @@ -65,18 +66,6 @@ export const myInt = output: schema.field({ type: schema.Int }), views: require.resolve('./view.tsx'), __legacy: { - filters: { - fields: { - ...legacyFilters.fields.equalityInputFields(meta.fieldKey, schema.Int), - ...legacyFilters.fields.orderingInputFields(meta.fieldKey, schema.Int), - ...legacyFilters.fields.inInputFields(meta.fieldKey, schema.Int), - }, - impls: { - ...legacyFilters.impls.equalityConditions(meta.fieldKey), - ...legacyFilters.impls.orderingConditions(meta.fieldKey), - ...legacyFilters.impls.inConditions(meta.fieldKey), - }, - }, isRequired, defaultValue, }, @@ -94,6 +83,7 @@ The `input` object defines the GraphQL inputs for the field type. ```ts input: { + where: { arg: schema.arg({ type: filters[meta.provider].Int.optional }), resolve: filters.resolveCommon }, create: { arg: schema.arg({ type: schema.Int }) }, update: { arg: schema.arg({ type: schema.Int }) }, orderBy: { arg: schema.arg({ type: orderDirectionEnum }) }, @@ -104,6 +94,7 @@ You can also provide resolvers to transform the value coming from GraphQL into t ```ts input: { + where: { arg: schema.arg({ type: filters[meta.provider].Int.optional }), resolve: filters.resolveCommon }, create: { arg: schema.arg({ type: schema.Int }), resolve: (val, context) => val }, update: { arg: schema.arg({ type: schema.Int }), resolve: (val, context) => val }, orderBy: { arg: schema.arg({ type: orderDirectionEnum }), resolve: (val, context) => val }, diff --git a/docs/pages/docs/guides/document-fields.mdx b/docs/pages/docs/guides/document-fields.mdx index fa27c56962e..9b2b5da7aa7 100644 --- a/docs/pages/docs/guides/document-fields.mdx +++ b/docs/pages/docs/guides/document-fields.mdx @@ -97,11 +97,11 @@ type Post_content_DocumentField { } ``` -To query the content we can run the following GraphQL query, which will return the JSON representation of the content in `allPosts.content.document`. +To query the content we can run the following GraphQL query, which will return the JSON representation of the content in `posts.content.document`. ```graphql query { - allPosts { + posts { content { document } @@ -219,7 +219,7 @@ If you query for the document, the inline relationship block will include the ID "id": "ckqk4hkcg0030f5mu6le6xydu" }, "relationship": "mention", - "children": [{ "text": "" } + "children": [{ "text": "" }] }, ... ``` @@ -229,7 +229,7 @@ To obtain more useful data, we can pass the `hydrateRelationships: true` option ```graphql query { - allPosts { + posts { content { document(hydrateRelationships: true) } diff --git a/docs/pages/docs/guides/filters.mdx b/docs/pages/docs/guides/filters.mdx index 99420a8b3de..869cb8acfe3 100644 --- a/docs/pages/docs/guides/filters.mdx +++ b/docs/pages/docs/guides/filters.mdx @@ -10,25 +10,25 @@ This guide will show you how to use filters to get data you need. ## Scalar Filters -If we want to find all the `Tasks` in our system, we can use the query `allTasks()`. +If we want to find all the `Tasks` in our system, we can use the query `tasks()`. ```graphql { - allTasks { + tasks { id label } } ``` -In general we don't want to grab all the tasks at once, but want to find a particular set of tasks which match a certain condition. -In Keystone we can do this by passing a `where` argument to the `allTasks()` query. +In general we don't want to grab all the tasks at once, but we want to find a particular set of tasks which match a certain condition. +In Keystone we can do this by passing a `where` argument to the `tasks()` query. If we want to find all the tasks with a label equal to `"Hello"` we can write: ```graphql { - allTasks(where: { label: "Hello" }) { + tasks(where: { label: { equals: "Hello" } }) { id label } @@ -39,7 +39,7 @@ Keystone provides a wide range of different filters. If we want to find all thos ```graphql { - allTasks(where: { label_not: "Hello" }) { + tasks(where: { label: { not: { equals: "Hello" } } }) { id label } @@ -50,7 +50,7 @@ The `text()` field type also supports searching for sub-strings within a field: ```graphql { - allTasks(where: { label_contains: "He" }) { + tasks(where: { label: { contains: "He" } }) { id label } @@ -61,7 +61,7 @@ Different field types support different filters. The field `finishBy: timestamp( ```graphql { - allTasks(where: { finishBy_gt: "2022-01-01T00:00:00.000Z" }) { + tasks(where: { finishBy: { gt: "2022-01-01T00:00:00.000Z" } }) { id label } @@ -74,9 +74,9 @@ For more complex queries, you can combine multiple filters, and only those items ```graphql { - allTasks(where: { - label_contains: "He", - finishBy_gt: "2022-01-01T00:00:00.000Z" + tasks(where: { + label: { contains: "He" }, + finishBy: { gt: "2022-01-01T00:00:00.000Z" } }) { id label @@ -94,9 +94,9 @@ The `AND` operater accepts a list of sub-filters, and will only return those ite ```graphql { - allTasks(where: { AND: [ - { label_contains: "H" }, - { label_contains: "ll" } + tasks(where: { AND: [ + { label: { contains: "H" } }, + { label: { contains: "ll" } } ] }) { id label @@ -110,9 +110,9 @@ The `OR` operater accepts a list of sub-filters, and will only return those item ```graphql { - allTasks(where: { OR: [ - { label_contains: "H" }, - { label_contains: "ll" } + tasks(where: { OR: [ + { label: { contains: "H" } }, + { label: { contains: "ll" } } ] }) { id label @@ -120,6 +120,22 @@ The `OR` operater accepts a list of sub-filters, and will only return those item } ``` +### NOT + +The `NOT` operater accepts a list of sub-filters, and will only return those items which don't match the conditions. +You'll generally only pass a single filter to `NOT` rather than a list but if you do a pass a list, they're `AND`ed together. + +```graphql +{ + tasks(where: { NOT: { + label: { contains: "H" } + } }) { + id + label + } +} +``` + ## Relationship Filters As well as filtering by scalar fields, you can also filter against relationship fields. @@ -133,7 +149,7 @@ For example, to find all the tasks where the task is assigned to a used named `" ```graphql { - allTasks(where: { assignedTo: { name: "Alice" } }) { + tasks(where: { assignedTo: { name: { equals: "Alice" } } }) { id label } @@ -142,13 +158,13 @@ For example, to find all the tasks where the task is assigned to a used named `" ### Many -If you have `many: true` configured on the relationship field, then you can find items based on whether `some`, `none`, or `all` of the related items match a `where` filter using the fields from the related list. +If you have `many: true` configured on the relationship field, then you can find items based on whether `some`, `none`, or `every` of the related items match a `where` filter using the fields from the related list. For example, to find all the people which have `some` posts with the label `"Hello"`, we can run the following query: ```graphql { - allPeople(where: { tasks_some: { label: "Hello" } }) { + people(where: { tasks: { some: { label: { equals: "Hello" } } } }) { id name } diff --git a/docs/pages/docs/guides/hooks.mdx b/docs/pages/docs/guides/hooks.mdx index b76871e50a1..fbfb9eff43e 100644 --- a/docs/pages/docs/guides/hooks.mdx +++ b/docs/pages/docs/guides/hooks.mdx @@ -27,7 +27,7 @@ export default config({ hooks: { afterChange: ({ operation, updatedItem }) => { if (operation === 'create') { - console.log('New user created. Name: ${updatedItem.name}, Email: ${updatedItem.email}); + console.log(`New user created. Name: ${updatedItem.name}, Email: ${updatedItem.email}`); } } }, @@ -209,7 +209,7 @@ export default config({ validateInput: ({ addValidationError, resolvedData, fieldPath }) => { const email = resolvedData[fieldPath]; if (email !== undefined && email !== null && !email.includes('@')) { - addValidationError('The email address ${email} provided for the field ${fieldPath} must contain an '@' character); + addValidationError(`The email address ${email} provided for the field ${fieldPath} must contain an '@' character`); } }, }, diff --git a/docs/pages/docs/guides/relationships.mdx b/docs/pages/docs/guides/relationships.mdx index 0708baa3d5b..cd5ac552c5e 100644 --- a/docs/pages/docs/guides/relationships.mdx +++ b/docs/pages/docs/guides/relationships.mdx @@ -54,8 +54,8 @@ In Keystone it’s possible to define relationships from one, or both sides of t Our example above is one-sided: the `Post` list relates to the `User` list via the `authors` field. This kind of relationship will let us query for the `authors` of a post in our GraphQL API like so: ```graphql -Query { - allPosts { +query { + posts { title content authors { @@ -86,8 +86,8 @@ export default config({ fields: { title: text(), content: text(), - // relates authors to posts - authors: relationship({ ref: 'User.posts', many: true }), + // relates authors to posts + authors: relationship({ ref: 'User.posts', many: true }), }, }), }), @@ -101,8 +101,8 @@ In the example above we added a `posts` field to the `User` list, and changed th Now that our relationship is two-sided we can query all the posts written by each user like so: ```graphql -Query { - allUsers { +query { + users { name posts { title diff --git a/docs/pages/docs/guides/testing.mdx b/docs/pages/docs/guides/testing.mdx index 0436857190e..e70afacb7e0 100644 --- a/docs/pages/docs/guides/testing.mdx +++ b/docs/pages/docs/guides/testing.mdx @@ -109,8 +109,8 @@ runner(async ({ context }) => { // Create some users const [alice, bob] = await context.lists.Person.createMany({ data: [ - { data: { name: 'Alice', email: 'alice@example.com', password: 'super-secret' } }, - { data: { name: 'Bob', email: 'bob@example.com', password: 'super-secret' } }, + { name: 'Alice', email: 'alice@example.com', password: 'super-secret' }, + { name: 'Bob', email: 'bob@example.com', password: 'super-secret' }, ], }); @@ -129,7 +129,7 @@ runner(async ({ context }) => { .withSession({ itemId: bob.id, data: {} }) .graphql.raw({ query: `mutation update($id: ID!) { - updateTask(id: $id data: { isComplete: true }) { + updateTask(where: { id: $id }, data: { isComplete: true }) { id } }`, diff --git a/docs/pages/docs/guides/virtual-fields.mdx b/docs/pages/docs/guides/virtual-fields.mdx index 4eae2e7be9a..e1a697ee4f7 100644 --- a/docs/pages/docs/guides/virtual-fields.mdx +++ b/docs/pages/docs/guides/virtual-fields.mdx @@ -42,7 +42,7 @@ We can now run a GraphQL query and request the `hello` field on one of our `Exam ```graphql { - Example(where: { id: "1" }) { + example(where: { id: "1" }) { id hello } @@ -52,7 +52,7 @@ We can now run a GraphQL query and request the `hello` field on one of our `Exam which gives the response: ```javascript -{ Example: { id: "1", hello: "Hello, world! } } +{ example: { id: "1", hello: "Hello, world! } } ``` The value of `hello` is generated from the `resolve` function, which returns the string `"Hello, world!"`. @@ -170,9 +170,9 @@ type Post { We can now perform the following query to get all the excerpts without over-fetching on the client. -``` +```graphql { - allPosts { + posts { id excerpt(length: 100) } @@ -284,7 +284,7 @@ export const lists = createSchema({ where: { id: item.id.toString() }, query: `posts( orderBy: { publishDate: desc } - first: 1 + take: 1 ) { id }`, }); if (posts.length > 0) { diff --git a/docs/pages/ds.tsx b/docs/pages/ds.tsx index ce07fabddf5..b47d461d437 100644 --- a/docs/pages/ds.tsx +++ b/docs/pages/ds.tsx @@ -576,7 +576,7 @@ Some code...`} {`{ - allPosts (first: 2, where: { title_contains: "content" }) { + posts(take: 2, where: { title: { contains: "content" } }) { title author { name @@ -587,7 +587,7 @@ Some code...`} {`{ "data": { - "allPosts": [ + "posts": [ { "title": "How structured content gives you superpowers", "author": { diff --git a/docs/pages/index.tsx b/docs/pages/index.tsx index c4a6f18f522..47f7c55c695 100644 --- a/docs/pages/index.tsx +++ b/docs/pages/index.tsx @@ -565,8 +565,8 @@ export const lists = createSchema({ {`{ - allPosts (first: 2, where: { - title_contains: "content" + posts(take: 2, where: { + title: { contains: "content" } }) { title author { @@ -580,7 +580,7 @@ export const lists = createSchema({ {`{ "data": { - "allPosts": [ + "posts": [ { "title": "How structured content gives you superpowers", "author": { diff --git a/docs/pages/updates/new-graphql-api.mdx b/docs/pages/updates/new-graphql-api.mdx new file mode 100644 index 00000000000..47c6b0afc89 --- /dev/null +++ b/docs/pages/updates/new-graphql-api.mdx @@ -0,0 +1,405 @@ +import { Markdown, getServerSideProps } from '../../components/Markdown'; +import { Emoji } from '../../components/primitives/Emoji'; + +# A new & improved GraphQL API + +As we move closer to a _General Availability_ release for Keystone 6, we've taken the opportunity to make the experience of working with Keystone’s GraphQL API easier to program and reason about. + +This guide describes the improvements we've made, and walks you through the steps you need to take to upgrade your Keystone projects. + +!> If you get stuck, or want to discuss these changes, reach out to us in the [Keystone community slack](https://community.keystonejs.com/). + +## Example Schema + +To illustrate the changes, we’ll refer to the `Task` list in the following schema, from our [Task Manager](https://github.com/keystonejs/keystone/tree/master/examples/task-manager) example project. + +``` +export const lists = createSchema({ + Task: list({ + fields: { + label: text({ isRequired: true }), + priority: select({ + dataType: 'enum', + options: [ + { label: 'Low', value: 'low' }, + { label: 'Medium', value: 'medium' }, + { label: 'High', value: 'high' }, + ], + }), + isComplete: checkbox(), + assignedTo: relationship({ ref: 'Person.tasks', many: false }), + tags: relationship({ ref: 'Tag', many: true }), + finishBy: timestamp(), + }, + }), + Person: list({ + fields: { + name: text({ isRequired: true }), + tasks: relationship({ ref: 'Task.assignedTo', many: true }), + }, + }), + Tag: list({ + fields: { + name: text(), + }, + }), +}); +``` + +## Query + +We’ve changed the names of our top-level queries easier understand. +We also took this opportunity to remove deprecated and unused legacy features. + +### Changes + +| Action | Item | Before | After | +| ---------------------------------------------------- | -------------------------------------------------------------- | ----------------- | -------------- | +|   Renamed | Generated query for a single item | `Task()` | `task()` | +|   Renamed | Generated query for multiple items | `allTasks()` | `tasks()` | +|   Renamed | Pagination argument to align with arguments provided by Prisma | `first` | `take` | +|   Removed | Legacy `search` argument | `search` | `where` | +|   Removed | Deprecated `sortBy` argument | `sortBy` | `orderBy` | +|   Removed | Deprecated `_allTasksMeta` query | `_allTasksMeta()` | `tasksCount()` | + +!> We’ve also changed the format of filters used in `TaskWhereInput`. See [Filter changes](#filters) for more details. + +### Example + +```graphql +// Before + +type Query { + allTasks( + where: TaskWhereInput! = {} + search: String + sortBy: [SortTasksBy!] + @deprecated(reason: "sortBy has been deprecated in favour of orderBy") + orderBy: [TaskOrderByInput!]! = [] + first: Int + skip: Int! = 0 + ): [Task!] + Task(where: TaskWhereUniqueInput!): Task + _allTasksMeta( + where: TaskWhereInput! = {} + search: String + sortBy: [SortTasksBy!] + @deprecated(reason: "sortBy has been deprecated in favour of orderBy") + orderBy: [TaskOrderByInput!]! = [] + first: Int + skip: Int! = 0 + ): _QueryMeta + @deprecated( + reason: "This query will be removed in a future version. Please use tasksCount instead." + ) + tasksCount(where: TaskWhereInput! = {}): Int + ... +} + +// After +type Query { + tasks( + where: TaskWhereInput! = {} + orderBy: [TaskOrderByInput!]! = [] + take: Int + skip: Int! = 0 + ): [Task!] + task(where: TaskWhereUniqueInput!): Task + tasksCount(where: TaskWhereInput! = {}): Int + ... +} +``` + +## Filters + +The filter arguments used in queries have been updated to accept a filter object for each field, rather than having all the filter options available at the top level. + +An example of a query in the old format is: + +```graphql +allTasks( + where: { + label_starts_with: "Hello", + finishBy_lt: "2022-01-01T00:00:00.000Z", + isComplete: true + } +) { id } +``` + +Using the new filter syntax, this becomes: + +```graphql +tasks( + where: { + label: { startsWith: "Hello" } + finishBy: { lt: "2022-01-01T00:00:00.000Z" } + isComplete: { equals: true } + } +) { id } +``` + +There is a one-to-one correspondence between the old filters and the new filters, so you can make a simple systematic set of changes to bring your filters up to date. + +?> **Note:** The old filter syntax used `{ fieldName: value }` to test for equality. The new syntax requires you to make this explicit, and write `{ fieldName: { equals: value} }`. + +!> See the [Filters Guide](/docs/guides/filters) for a detailed walk through the new filtering syntex. + +!> See the [API docs](/docs/apis/filters) for a comprehensive list of all the new filters for each field type. + +## Mutations + +All generated CRUD mutations have the same names and return types, but their inputs have changed. + +- `update` and `delete` mutations no longer accept `id` or `ids` to indicate which items to update. We now use `where` so you can select the item based on any of its unique fields. +- The **types** used for `create` and `update` mutations [have been updated](#input-types). +- All inputs are now **non-optional**. + +#### Create mutation + +| Before | After | +| ----------------------------------------------- | ------------------------------------------------ | +| `createTask(data: TaskCreateInput): Task` | `createTask(data: TaskCreateInput!): Task` | +| `createTasks(data: [TasksCreateInput]): [Task]` | `createTasks(data: [TaskCreateInput!]!): [Task]` | + +```graphql +// Before +mutation { + createTask(data: { label: "Upgrade keystone" }) { + id + } +} + +mutation { + createTasks( + data: [ + { data: { label: "Upgrade keystone" } } + { data: { label: "Build great products" } } + ] + ) { + id + } +} + +// After +mutation { + createTask(data: { label: "Upgrade keystone" }) { + id + } +} + +mutation { + createTasks( + data: [ + { label: "Upgrade keystone" }, + { label: "Build great products" } + ] + ) { + id + } +} +``` + +#### Update mutation + +| Before | After | +| -------------------------------------------------- | ------------------------------------------------------------------------ | +| `updateTask(id: ID!, data: TaskUpdateInput): Task` | `updateTask(where: TaskWhereUniqueInput!, data: TaskUpdateInput!): Task` | +| `updateTasks(data: [TasksUpdateInput]): [Task]` | `updateTasks(data: [TaskUpdateArgs!]!): [Task]` | + +```graphql +// Before +mutation { + updateTask(id: "cksdyag9w0000pioj44kinqsp", data: { isComplete: true }) { + id + } + + updateTasks( + data: [ + { id: "cksdyaga50007pioj1oc37msr", data: { isComplete: true } } + { id: "cksdyj6wd0000epoj0585uzbq", data: { isComplete: true } } + ] + ) { + id + } +} + +// After +mutation { + updateTask( + where: { id: "cksdyag9w0000pioj44kinqsp" } + data: { isComplete: true } + ) { + id + } + + updateTasks( + data: [ + { where: { id: "cksdyaga50007pioj1oc37msr" }, data: { isComplete: true } } + { where: { id: "cksdyj6wd0000epoj0585uzbq" }, data: { isComplete: true } } + ] + ) { + id + } +} +``` + +#### Delete mutation + +| Before | After | +| --------------------------------- | ------------------------------------------------------ | +| `deleteTask(id: ID!): Task` | `deleteTask(where: TaskWhereUniqueInput!): Task` | +| `deleteTasks(ids: [ID!]): [Task]` | `deleteTasks(where: [TaskWhereUniqueInput!]!): [Task]` | + +```graphql +// Before +mutation { + deleteTask(id: "cksdyaga50007pioj1oc37msr") { + id + } + + deleteTasks(ids: ["cksdyjrbj0007epojilbv3d6k", "cksdyjrbp0014epoja2uddwl1"]) { + id + } +} + +// After +mutation { + deleteTask(where: { id: "cksdyag9w0000pioj44kinqsp" }) { + id + } + + deleteTasks( + where: [ + { id: "ckrlp28lf001908lu9tyzxhuq" } + { id: "ckroflp7h0019t9lulhw6pggp" } + ] + ) { + id + } +} +``` + +## Input Types + +We’ve updated the input types used for relationship fields in `update` and `create` operations, removing obsolete options and making the syntax between the two operations easier to differentiate. + +- There are now separate types for `create` and `update` operations. +- Inputs for `create` operations no longer support the `disconnect` or `disconnectAll` options. These options didn't do anything during a `create` operation in the previous API. +- For to-one relationships, the `disconnect` option is now a `Boolean`, rather than accepting a unique input. If you only have one related item, there's no need to specify its value when disconnecting it. +- For to-many relationships, the `disconnectAll` operation has been removed in favour of a new `set` operation, which allows you to explicitly set the connected items. + You can use `{ set: [] }` to achieve the same results as the old `{ disconnectAll: true }`. + +### Example + +```graphql +// Before + +input TasksUpdateInput { + id: ID! + data: TaskUpdateInput +} + +input TaskUpdateInput { + label: String + priority: TaskPriorityType + isComplete: Boolean + assignedTo: PersonRelateToOneInput + tags: TagRelateToManyInput + finishBy: String +} + +input TasksCreateInput { + data: TaskCreateInput +} + +input TaskCreateInput { + label: String + priority: TaskPriorityType + isComplete: Boolean + assignedTo: PersonRelateToOneInput + tags: TagRelateToManyInput + finishBy: String +} + +input PersonRelateToOneInput { + create: PersonCreateInput + connect: PersonWhereUniqueInput + disconnect: PersonWhereUniqueInput + disconnectAll: Boolean +} + +input TagRelateToManyInput { + create: [TagCreateInput] + connect: [TagWhereUniqueInput] + disconnect: [TagWhereUniqueInput] + disconnectAll: Boolean +} + +// After + +input TaskUpdateArgs { + where: TaskWhereUniqueInput! + data: TaskUpdateInput! +} + +input TaskUpdateInput { + label: String + priority: TaskPriorityType + isComplete: Boolean + assignedTo: PersonRelateToOneForUpdateInput + tags: TagRelateToManyForUpdateInput + finishBy: String +} + +input TaskCreateInput { + label: String + priority: TaskPriorityType + isComplete: Boolean + assignedTo: PersonRelateToOneForCreateInput + tags: TagRelateToManyForCreateInput + finishBy: String +} + +input PersonRelateToOneForUpdateInput { + create: PersonCreateInput + connect: PersonWhereUniqueInput + disconnect: Boolean +} + +input PersonRelateToOneForCreateInput { + create: PersonCreateInput + connect: PersonWhereUniqueInput +} + +input TagRelateToManyForUpdateInput { + disconnect: [TagWhereUniqueInput!] + set: [TagWhereUniqueInput!] + create: [TagCreateInput!] + connect: [TagWhereUniqueInput!] +} + +input TagRelateToManyForCreateInput { + create: [TagCreateInput!] + connect: [TagWhereUniqueInput!] +} +``` + +## Upgrade Checklist + +While there are a lot of changes to this API, if you approach the upgrade process systematically your experience should be pretty smooth. If you get stuck or have questions, reach out to us in the [Keystone community slack](https://community.keystonejs.com/) to get the help you need. + +?> Before you begin: check that your project doesn't rely on any of the features we've marked as deprecated in this document, or the `search` argument to filters. If you do, apply the recommended substitute. + +1. Update top level queries. Be sure to rename `Task` to `task` and `allTasks` to `tasks` for all your queries. +2. Update filters. Find and replace all the old Keystone filters with their new equivalent. +3. Update mutation arguments to match the new input types. Make sure you replace `{ id: "..."}` with `{where: { id: "..."} }` in your `update` and `delete` operations. +4. Update relationship inputs to `create` and `update` operations. Ensure you've replaced usage of `{ disconnectAll: true }` with `{ set: [] }` in to-many relationships, and have used `{ disconnect: true }` rather than `{ disconnect: { id: "..."} }` in to-one relationships. + +!> Finally, make sure you apply corresponding changes to filters and input arguments when using the [List Items API](docs/apis/list-items). + +--- + +That's everything! While we acknowledge that API changes are an inconvenience, we believe the time spent navigating these upgrades will be offset many times over by a more fun and productive developer experience going forward. + +export default ({ children, ...props }) => {children}; +export { getServerSideProps } diff --git a/docs/public/assets/guides/custom-admin-ui-pages/custom-page-completed.png b/docs/public/assets/guides/custom-admin-ui-pages/custom-page-completed.png new file mode 100644 index 00000000000..52ba2d2df31 Binary files /dev/null and b/docs/public/assets/guides/custom-admin-ui-pages/custom-page-completed.png differ diff --git a/docs/public/assets/guides/custom-admin-ui-pages/custom-page-w-page-container.png b/docs/public/assets/guides/custom-admin-ui-pages/custom-page-w-page-container.png new file mode 100644 index 00000000000..4624b489197 Binary files /dev/null and b/docs/public/assets/guides/custom-admin-ui-pages/custom-page-w-page-container.png differ diff --git a/docs/public/assets/guides/custom-admin-ui-pages/custom-page-with-styled-header.png b/docs/public/assets/guides/custom-admin-ui-pages/custom-page-with-styled-header.png new file mode 100644 index 00000000000..80fc2092c07 Binary files /dev/null and b/docs/public/assets/guides/custom-admin-ui-pages/custom-page-with-styled-header.png differ diff --git a/docs/public/assets/guides/custom-admin-ui-pages/header-prop.png b/docs/public/assets/guides/custom-admin-ui-pages/header-prop.png new file mode 100644 index 00000000000..6da7fde25b8 Binary files /dev/null and b/docs/public/assets/guides/custom-admin-ui-pages/header-prop.png differ diff --git a/docs/public/assets/guides/custom-admin-ui-pages/simple-custom-page.png b/docs/public/assets/guides/custom-admin-ui-pages/simple-custom-page.png new file mode 100644 index 00000000000..580403af877 Binary files /dev/null and b/docs/public/assets/guides/custom-admin-ui-pages/simple-custom-page.png differ diff --git a/examples-staging/assets-cloud/CHANGELOG.md b/examples-staging/assets-cloud/CHANGELOG.md index 8be6e833770..1a314b62681 100644 --- a/examples-staging/assets-cloud/CHANGELOG.md +++ b/examples-staging/assets-cloud/CHANGELOG.md @@ -1,5 +1,13 @@ # @keystone-next/example-assets-cloud +## 1.0.4 + +### Patch Changes + +- Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 + ## 1.0.3 ### Patch Changes diff --git a/examples-staging/assets-cloud/package.json b/examples-staging/assets-cloud/package.json index c9721c12144..a2b772456eb 100644 --- a/examples-staging/assets-cloud/package.json +++ b/examples-staging/assets-cloud/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/example-assets-cloud", - "version": "1.0.3", + "version": "1.0.4", "private": true, "license": "MIT", "scripts": { @@ -9,8 +9,8 @@ "build": "keystone-next build" }, "dependencies": { - "@keystone-next/fields": "^13.0.0", - "@keystone-next/keystone": "^23.0.0", + "@keystone-next/fields": "^14.0.0", + "@keystone-next/keystone": "^24.0.0", "dotenv": "^10.0.0" }, "devDependencies": { diff --git a/examples-staging/assets-cloud/schema.graphql b/examples-staging/assets-cloud/schema.graphql index b2b130fdb47..8441a287b5b 100644 --- a/examples-staging/assets-cloud/schema.graphql +++ b/examples-staging/assets-cloud/schema.graphql @@ -58,40 +58,70 @@ type LocalFileFieldOutput implements FileFieldOutput { input PostWhereInput { AND: [PostWhereInput!] OR: [PostWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - title: String - title_not: String - title_contains: String - title_not_contains: String - title_in: [String] - title_not_in: [String] - status: PostStatusType - status_not: PostStatusType - status_in: [PostStatusType] - status_not_in: [PostStatusType] - content: String - content_not: String - content_contains: String - content_not_contains: String - content_in: [String] - content_not_in: [String] - publishDate: String - publishDate_not: String - publishDate_lt: String - publishDate_lte: String - publishDate_gt: String - publishDate_gte: String - publishDate_in: [String] - publishDate_not_in: [String] + NOT: [PostWhereInput!] + id: IDFilter + title: StringNullableFilter + status: PostStatusTypeNullableFilter + content: StringNullableFilter + publishDate: DateTimeNullableFilter author: AuthorWhereInput - author_is_null: Boolean +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input PostStatusTypeNullableFilter { + equals: PostStatusType + in: [PostStatusType!] + notIn: [PostStatusType!] + not: PostStatusTypeNullableFilter +} + +input DateTimeNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + not: DateTimeNullableFilter } input PostWhereUniqueInput { @@ -169,7 +199,7 @@ type Author { posts( where: PostWhereInput! = {} orderBy: [PostOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Post!] postsCount(where: PostWhereInput! = {}): Int @@ -178,29 +208,17 @@ type Author { input AuthorWhereInput { AND: [AuthorWhereInput!] OR: [AuthorWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_in: [String] - name_not_in: [String] - email: String - email_not: String - email_contains: String - email_not_contains: String - email_in: [String] - email_not_in: [String] - posts_every: PostWhereInput - posts_some: PostWhereInput - posts_none: PostWhereInput + NOT: [AuthorWhereInput!] + id: IDFilter + name: StringNullableFilter + email: StringNullableFilter + posts: PostManyRelationFilter +} + +input PostManyRelationFilter { + every: PostWhereInput + some: PostWhereInput + none: PostWhereInput } input AuthorWhereUniqueInput { @@ -270,7 +288,7 @@ type Query { posts( where: PostWhereInput! = {} orderBy: [PostOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Post!] post(where: PostWhereUniqueInput!): Post @@ -278,7 +296,7 @@ type Query { authors( where: AuthorWhereInput! = {} orderBy: [AuthorOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Author!] author(where: AuthorWhereUniqueInput!): Author diff --git a/examples-staging/assets-local/CHANGELOG.md b/examples-staging/assets-local/CHANGELOG.md index 7c9d895ac5a..f3c8c3c2db4 100644 --- a/examples-staging/assets-local/CHANGELOG.md +++ b/examples-staging/assets-local/CHANGELOG.md @@ -1,5 +1,13 @@ # @keystone-next/example-assets-local +## 1.0.4 + +### Patch Changes + +- Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 + ## 1.0.3 ### Patch Changes diff --git a/examples-staging/assets-local/package.json b/examples-staging/assets-local/package.json index 4f4a1d69bc3..59aea3525ca 100644 --- a/examples-staging/assets-local/package.json +++ b/examples-staging/assets-local/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/example-assets-local", - "version": "1.0.3", + "version": "1.0.4", "private": true, "license": "MIT", "scripts": { @@ -9,8 +9,8 @@ "build": "keystone-next build" }, "dependencies": { - "@keystone-next/fields": "^13.0.0", - "@keystone-next/keystone": "^23.0.0" + "@keystone-next/fields": "^14.0.0", + "@keystone-next/keystone": "^24.0.0" }, "devDependencies": { "typescript": "^4.3.5" diff --git a/examples-staging/assets-local/schema.graphql b/examples-staging/assets-local/schema.graphql index a174bdfed03..c98080ea689 100644 --- a/examples-staging/assets-local/schema.graphql +++ b/examples-staging/assets-local/schema.graphql @@ -43,40 +43,70 @@ type LocalImageFieldOutput implements ImageFieldOutput { input PostWhereInput { AND: [PostWhereInput!] OR: [PostWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - title: String - title_not: String - title_contains: String - title_not_contains: String - title_in: [String] - title_not_in: [String] - status: PostStatusType - status_not: PostStatusType - status_in: [PostStatusType] - status_not_in: [PostStatusType] - content: String - content_not: String - content_contains: String - content_not_contains: String - content_in: [String] - content_not_in: [String] - publishDate: String - publishDate_not: String - publishDate_lt: String - publishDate_lte: String - publishDate_gt: String - publishDate_gte: String - publishDate_in: [String] - publishDate_not_in: [String] + NOT: [PostWhereInput!] + id: IDFilter + title: StringNullableFilter + status: PostStatusTypeNullableFilter + content: StringNullableFilter + publishDate: DateTimeNullableFilter author: AuthorWhereInput - author_is_null: Boolean +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input PostStatusTypeNullableFilter { + equals: PostStatusType + in: [PostStatusType!] + notIn: [PostStatusType!] + not: PostStatusTypeNullableFilter +} + +input DateTimeNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + not: DateTimeNullableFilter } input PostWhereUniqueInput { @@ -147,7 +177,7 @@ type Author { posts( where: PostWhereInput! = {} orderBy: [PostOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Post!] postsCount(where: PostWhereInput! = {}): Int @@ -156,29 +186,17 @@ type Author { input AuthorWhereInput { AND: [AuthorWhereInput!] OR: [AuthorWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_in: [String] - name_not_in: [String] - email: String - email_not: String - email_contains: String - email_not_contains: String - email_in: [String] - email_not_in: [String] - posts_every: PostWhereInput - posts_some: PostWhereInput - posts_none: PostWhereInput + NOT: [AuthorWhereInput!] + id: IDFilter + name: StringNullableFilter + email: StringNullableFilter + posts: PostManyRelationFilter +} + +input PostManyRelationFilter { + every: PostWhereInput + some: PostWhereInput + none: PostWhereInput } input AuthorWhereUniqueInput { @@ -248,7 +266,7 @@ type Query { posts( where: PostWhereInput! = {} orderBy: [PostOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Post!] post(where: PostWhereUniqueInput!): Post @@ -256,7 +274,7 @@ type Query { authors( where: AuthorWhereInput! = {} orderBy: [AuthorOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Author!] author(where: AuthorWhereUniqueInput!): Author diff --git a/examples-staging/auth/CHANGELOG.md b/examples-staging/auth/CHANGELOG.md index f98370bf2f7..a8439b3ad63 100644 --- a/examples-staging/auth/CHANGELOG.md +++ b/examples-staging/auth/CHANGELOG.md @@ -1,5 +1,16 @@ # @keystone-next/example-auth +## 4.0.6 + +### Patch Changes + +- [#6310](https://github.com/keystonejs/keystone/pull/6310) [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053) Thanks [@timleslie](https://github.com/timleslie)! - Updated dependencies to use `mergeSchemas` from `@graphql-tools/schema`, rather than its old location in `@graphql-tools/merge`. You might see a reordering of the contents of your `graphql.schema` file. + +- Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 + - @keystone-next/auth@31.0.0 + ## 4.0.5 ### Patch Changes diff --git a/examples-staging/auth/package.json b/examples-staging/auth/package.json index 7fc11399c4e..d3775b189f3 100644 --- a/examples-staging/auth/package.json +++ b/examples-staging/auth/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/example-auth", - "version": "4.0.5", + "version": "4.0.6", "private": true, "license": "MIT", "scripts": { @@ -9,9 +9,9 @@ "build": "keystone-next build" }, "dependencies": { - "@keystone-next/auth": "^30.0.0", - "@keystone-next/fields": "^13.0.0", - "@keystone-next/keystone": "^23.0.0", + "@keystone-next/auth": "^31.0.0", + "@keystone-next/fields": "^14.0.0", + "@keystone-next/keystone": "^24.0.0", "next": "^10.2.3", "react": "^17.0.2", "react-dom": "^17.0.2" diff --git a/examples-staging/auth/schema.graphql b/examples-staging/auth/schema.graphql index ab34231511a..d2c5409d59e 100644 --- a/examples-staging/auth/schema.graphql +++ b/examples-staging/auth/schema.graphql @@ -1,3 +1,50 @@ +input CreateInitialUserInput { + name: String + email: String + password: String +} + +type Mutation { + createInitialUser( + data: CreateInitialUserInput! + ): UserAuthenticationWithPasswordSuccess! + authenticateUserWithPassword( + email: String! + password: String! + ): UserAuthenticationWithPasswordResult! + createUser(data: UserCreateInput!): User + createUsers(data: [UserCreateInput!]!): [User] + updateUser(where: UserWhereUniqueInput!, data: UserUpdateInput!): User + updateUsers(data: [UserUpdateArgs!]!): [User] + deleteUser(where: UserWhereUniqueInput!): User + deleteUsers(where: [UserWhereUniqueInput!]!): [User] + endSession: Boolean! +} + +union AuthenticatedItem = User + +union UserAuthenticationWithPasswordResult = + UserAuthenticationWithPasswordSuccess + | UserAuthenticationWithPasswordFailure + +type UserAuthenticationWithPasswordSuccess { + sessionToken: String! + item: User! +} + +type UserAuthenticationWithPasswordFailure { + code: PasswordAuthErrorCode! + message: String! +} + +enum PasswordAuthErrorCode { + FAILURE + IDENTITY_NOT_FOUND + SECRET_NOT_SET + MULTIPLE_IDENTITY_MATCHES + SECRET_MISMATCH +} + type User { id: ID! name: String @@ -13,29 +60,60 @@ type PasswordState { input UserWhereInput { AND: [UserWhereInput!] OR: [UserWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_in: [String] - name_not_in: [String] - email: String - email_not: String - email_contains: String - email_not_contains: String - email_in: [String] - email_not_in: [String] - password_is_set: Boolean - isAdmin: Boolean - isAdmin_not: Boolean + NOT: [UserWhereInput!] + id: IDFilter + name: StringNullableFilter + email: StringNullableFilter + password: PasswordFilter + isAdmin: BooleanNullableFilter +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input PasswordFilter { + isSet: Boolean! +} + +input BooleanNullableFilter { + equals: Boolean + not: BooleanNullableFilter } input UserWhereUniqueInput { @@ -82,63 +160,16 @@ scalar JSON url: "http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf" ) -type Mutation { - createUser(data: UserCreateInput!): User - createUsers(data: [UserCreateInput!]!): [User] - updateUser(where: UserWhereUniqueInput!, data: UserUpdateInput!): User - updateUsers(data: [UserUpdateArgs!]!): [User] - deleteUser(where: UserWhereUniqueInput!): User - deleteUsers(where: [UserWhereUniqueInput!]!): [User] - authenticateUserWithPassword( - email: String! - password: String! - ): UserAuthenticationWithPasswordResult! - createInitialUser( - data: CreateInitialUserInput! - ): UserAuthenticationWithPasswordSuccess! - endSession: Boolean! -} - -union AuthenticatedItem = User - -union UserAuthenticationWithPasswordResult = - UserAuthenticationWithPasswordSuccess - | UserAuthenticationWithPasswordFailure - -type UserAuthenticationWithPasswordSuccess { - sessionToken: String! - item: User! -} - -type UserAuthenticationWithPasswordFailure { - code: PasswordAuthErrorCode! - message: String! -} - -enum PasswordAuthErrorCode { - FAILURE - IDENTITY_NOT_FOUND - SECRET_NOT_SET - MULTIPLE_IDENTITY_MATCHES - SECRET_MISMATCH -} - -input CreateInitialUserInput { - name: String - email: String - password: String -} - type Query { + authenticatedItem: AuthenticatedItem users( where: UserWhereInput! = {} orderBy: [UserOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [User!] user(where: UserWhereUniqueInput!): User usersCount(where: UserWhereInput! = {}): Int - authenticatedItem: AuthenticatedItem keystone: KeystoneMeta! } diff --git a/examples-staging/basic/CHANGELOG.md b/examples-staging/basic/CHANGELOG.md index 403b221ace0..41001b2b185 100644 --- a/examples-staging/basic/CHANGELOG.md +++ b/examples-staging/basic/CHANGELOG.md @@ -1,5 +1,18 @@ # @keystone-next/example-app-basic +## 4.0.6 + +### Patch Changes + +- [#6310](https://github.com/keystonejs/keystone/pull/6310) [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053) Thanks [@timleslie](https://github.com/timleslie)! - Updated dependencies to use `mergeSchemas` from `@graphql-tools/schema`, rather than its old location in `@graphql-tools/merge`. You might see a reordering of the contents of your `graphql.schema` file. + +- Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`e985aa010`](https://github.com/keystonejs/keystone/commit/e985aa0104d30a779f21ec05d80e6b98ece87dfb), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`69f47bfed`](https://github.com/keystonejs/keystone/commit/69f47bfed1eaa1269cfdc42071268a914bd4aa17), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`8187ea019`](https://github.com/keystonejs/keystone/commit/8187ea019a212874f3c602573af3382c6f3bd3b2), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 + - @keystone-next/types@24.0.0 + - @keystone-next/fields-document@8.0.0 + - @keystone-next/auth@31.0.0 + ## 4.0.5 ### Patch Changes diff --git a/examples-staging/basic/package.json b/examples-staging/basic/package.json index 57397719aec..dfa1fae5fab 100644 --- a/examples-staging/basic/package.json +++ b/examples-staging/basic/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/examples-app-basic", - "version": "4.0.5", + "version": "4.0.6", "private": true, "license": "MIT", "scripts": { @@ -9,20 +9,19 @@ "build": "keystone-next build" }, "dependencies": { - "@babel/runtime": "^7.14.8", - "@graphql-tools/merge": "^6.2.16", - "@keystone-next/auth": "^30.0.0", + "@babel/runtime": "^7.15.3", + "@keystone-next/auth": "^31.0.0", "@keystone-next/document-renderer": "^4.0.0", - "@keystone-next/fields": "^13.0.0", - "@keystone-next/fields-document": "^7.0.3", - "@keystone-next/keystone": "^23.0.0", - "@keystone-next/types": "^23.0.0", + "@keystone-next/fields": "^14.0.0", + "@keystone-next/fields-document": "^8.0.0", + "@keystone-next/keystone": "^24.0.0", + "@keystone-next/types": "^24.0.0", "@keystone-ui/core": "^3.1.1", "@keystone-ui/fields": "^4.1.1", "@keystone-ui/icons": "^4.0.0", "@keystone-ui/tooltip": "^4.0.1", "@preconstruct/next": "^3.0.0", - "@types/react": "^17.0.15", + "@types/react": "^17.0.18", "apollo-server-micro": "^2.25.2", "graphql": "^15.5.1", "graphql-tag": "^2.12.5", diff --git a/examples-staging/basic/schema.graphql b/examples-staging/basic/schema.graphql index b3a2ec16f98..9800f4b99ce 100644 --- a/examples-staging/basic/schema.graphql +++ b/examples-staging/basic/schema.graphql @@ -1,3 +1,71 @@ +type RandomNumber { + number: Int + generatedAt: Int +} + +type Mutation { + createRandomPosts: [Post!]! + createInitialUser( + data: CreateInitialUserInput! + ): UserAuthenticationWithPasswordSuccess! + authenticateUserWithPassword( + email: String! + password: String! + ): UserAuthenticationWithPasswordResult! + createUser(data: UserCreateInput!): User + createUsers(data: [UserCreateInput!]!): [User] + updateUser(where: UserWhereUniqueInput!, data: UserUpdateInput!): User + updateUsers(data: [UserUpdateArgs!]!): [User] + deleteUser(where: UserWhereUniqueInput!): User + deleteUsers(where: [UserWhereUniqueInput!]!): [User] + createPhoneNumber(data: PhoneNumberCreateInput!): PhoneNumber + createPhoneNumbers(data: [PhoneNumberCreateInput!]!): [PhoneNumber] + updatePhoneNumber( + where: PhoneNumberWhereUniqueInput! + data: PhoneNumberUpdateInput! + ): PhoneNumber + updatePhoneNumbers(data: [PhoneNumberUpdateArgs!]!): [PhoneNumber] + deletePhoneNumber(where: PhoneNumberWhereUniqueInput!): PhoneNumber + deletePhoneNumbers(where: [PhoneNumberWhereUniqueInput!]!): [PhoneNumber] + createPost(data: PostCreateInput!): Post + createPosts(data: [PostCreateInput!]!): [Post] + updatePost(where: PostWhereUniqueInput!, data: PostUpdateInput!): Post + updatePosts(data: [PostUpdateArgs!]!): [Post] + deletePost(where: PostWhereUniqueInput!): Post + deletePosts(where: [PostWhereUniqueInput!]!): [Post] + endSession: Boolean! +} + +input CreateInitialUserInput { + name: String + email: String + password: String +} + +union AuthenticatedItem = User + +union UserAuthenticationWithPasswordResult = + UserAuthenticationWithPasswordSuccess + | UserAuthenticationWithPasswordFailure + +type UserAuthenticationWithPasswordSuccess { + sessionToken: String! + item: User! +} + +type UserAuthenticationWithPasswordFailure { + code: PasswordAuthErrorCode! + message: String! +} + +enum PasswordAuthErrorCode { + FAILURE + IDENTITY_NOT_FOUND + SECRET_NOT_SET + MULTIPLE_IDENTITY_MATCHES + SECRET_MISMATCH +} + type User { id: ID! name: String @@ -10,14 +78,14 @@ type User { phoneNumbers( where: PhoneNumberWhereInput! = {} orderBy: [PhoneNumberOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [PhoneNumber!] phoneNumbersCount(where: PhoneNumberWhereInput! = {}): Int posts( where: PostWhereInput! = {} orderBy: [PostOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Post!] postsCount(where: PostWhereInput! = {}): Int @@ -72,41 +140,75 @@ type LocalFileFieldOutput implements FileFieldOutput { input UserWhereInput { AND: [UserWhereInput!] OR: [UserWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_in: [String] - name_not_in: [String] - email: String - email_not: String - email_contains: String - email_not_contains: String - email_in: [String] - email_not_in: [String] - password_is_set: Boolean - isAdmin: Boolean - isAdmin_not: Boolean - roles: String - roles_not: String - roles_contains: String - roles_not_contains: String - roles_in: [String] - roles_not_in: [String] - phoneNumbers_every: PhoneNumberWhereInput - phoneNumbers_some: PhoneNumberWhereInput - phoneNumbers_none: PhoneNumberWhereInput - posts_every: PostWhereInput - posts_some: PostWhereInput - posts_none: PostWhereInput + NOT: [UserWhereInput!] + id: IDFilter + name: StringNullableFilter + email: StringNullableFilter + password: PasswordFilter + isAdmin: BooleanNullableFilter + roles: StringNullableFilter + phoneNumbers: PhoneNumberManyRelationFilter + posts: PostManyRelationFilter +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input PasswordFilter { + isSet: Boolean! +} + +input BooleanNullableFilter { + equals: Boolean + not: BooleanNullableFilter +} + +input PhoneNumberManyRelationFilter { + every: PhoneNumberWhereInput + some: PhoneNumberWhereInput + none: PhoneNumberWhereInput +} + +input PostManyRelationFilter { + every: PostWhereInput + some: PostWhereInput + none: PostWhereInput } input UserWhereUniqueInput { @@ -206,26 +308,11 @@ type PhoneNumber { input PhoneNumberWhereInput { AND: [PhoneNumberWhereInput!] OR: [PhoneNumberWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] + NOT: [PhoneNumberWhereInput!] + id: IDFilter user: UserWhereInput - user_is_null: Boolean - type: String - type_not: String - type_in: [String] - type_not_in: [String] - value: String - value_not: String - value_contains: String - value_not_contains: String - value_in: [String] - value_not_in: [String] + type: StringNullableFilter + value: StringNullableFilter } input PhoneNumberWhereUniqueInput { @@ -282,34 +369,23 @@ type Post_content_DocumentField { input PostWhereInput { AND: [PostWhereInput!] OR: [PostWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - title: String - title_not: String - title_contains: String - title_not_contains: String - title_in: [String] - title_not_in: [String] - status: String - status_not: String - status_in: [String] - status_not_in: [String] - publishDate: String - publishDate_not: String - publishDate_lt: String - publishDate_lte: String - publishDate_gt: String - publishDate_gte: String - publishDate_in: [String] - publishDate_not_in: [String] + NOT: [PostWhereInput!] + id: IDFilter + title: StringNullableFilter + status: StringNullableFilter + publishDate: DateTimeNullableFilter author: UserWhereInput - author_is_null: Boolean +} + +input DateTimeNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + not: DateTimeNullableFilter } input PostWhereUniqueInput { @@ -352,79 +428,13 @@ scalar JSON url: "http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf" ) -type Mutation { - createUser(data: UserCreateInput!): User - createUsers(data: [UserCreateInput!]!): [User] - updateUser(where: UserWhereUniqueInput!, data: UserUpdateInput!): User - updateUsers(data: [UserUpdateArgs!]!): [User] - deleteUser(where: UserWhereUniqueInput!): User - deleteUsers(where: [UserWhereUniqueInput!]!): [User] - createPhoneNumber(data: PhoneNumberCreateInput!): PhoneNumber - createPhoneNumbers(data: [PhoneNumberCreateInput!]!): [PhoneNumber] - updatePhoneNumber( - where: PhoneNumberWhereUniqueInput! - data: PhoneNumberUpdateInput! - ): PhoneNumber - updatePhoneNumbers(data: [PhoneNumberUpdateArgs!]!): [PhoneNumber] - deletePhoneNumber(where: PhoneNumberWhereUniqueInput!): PhoneNumber - deletePhoneNumbers(where: [PhoneNumberWhereUniqueInput!]!): [PhoneNumber] - createPost(data: PostCreateInput!): Post - createPosts(data: [PostCreateInput!]!): [Post] - updatePost(where: PostWhereUniqueInput!, data: PostUpdateInput!): Post - updatePosts(data: [PostUpdateArgs!]!): [Post] - deletePost(where: PostWhereUniqueInput!): Post - deletePosts(where: [PostWhereUniqueInput!]!): [Post] - authenticateUserWithPassword( - email: String! - password: String! - ): UserAuthenticationWithPasswordResult! - createInitialUser( - data: CreateInitialUserInput! - ): UserAuthenticationWithPasswordSuccess! - createRandomPosts: [Post!]! - endSession: Boolean! -} - -union AuthenticatedItem = User - -union UserAuthenticationWithPasswordResult = - UserAuthenticationWithPasswordSuccess - | UserAuthenticationWithPasswordFailure - -type UserAuthenticationWithPasswordSuccess { - sessionToken: String! - item: User! -} - -type UserAuthenticationWithPasswordFailure { - code: PasswordAuthErrorCode! - message: String! -} - -enum PasswordAuthErrorCode { - FAILURE - IDENTITY_NOT_FOUND - SECRET_NOT_SET - MULTIPLE_IDENTITY_MATCHES - SECRET_MISMATCH -} - -input CreateInitialUserInput { - name: String - email: String - password: String -} - -type RandomNumber { - number: Int - generatedAt: Int -} - type Query { + randomNumber: RandomNumber + authenticatedItem: AuthenticatedItem users( where: UserWhereInput! = {} orderBy: [UserOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [User!] user(where: UserWhereUniqueInput!): User @@ -432,7 +442,7 @@ type Query { phoneNumbers( where: PhoneNumberWhereInput! = {} orderBy: [PhoneNumberOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [PhoneNumber!] phoneNumber(where: PhoneNumberWhereUniqueInput!): PhoneNumber @@ -440,13 +450,11 @@ type Query { posts( where: PostWhereInput! = {} orderBy: [PostOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Post!] post(where: PostWhereUniqueInput!): Post postsCount(where: PostWhereInput! = {}): Int - authenticatedItem: AuthenticatedItem - randomNumber: RandomNumber keystone: KeystoneMeta! } diff --git a/examples-staging/basic/schema.ts b/examples-staging/basic/schema.ts index 0e053b105dd..ea795626295 100644 --- a/examples-staging/basic/schema.ts +++ b/examples-staging/basic/schema.ts @@ -156,7 +156,7 @@ export const lists = createSchema({ kind: 'prop', listKey: 'User', many: true, - selection: `posts(first: 10) { + selection: `posts(take: 10) { title }`, }, diff --git a/examples-staging/ecommerce/CHANGELOG.md b/examples-staging/ecommerce/CHANGELOG.md index 0ee99f0c99c..4b1574ed36b 100644 --- a/examples-staging/ecommerce/CHANGELOG.md +++ b/examples-staging/ecommerce/CHANGELOG.md @@ -1,5 +1,20 @@ # @keystone-next/example-ecommerce +## 4.0.7 + +### Patch Changes + +- [#6250](https://github.com/keystonejs/keystone/pull/6250) [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450) Thanks [@timleslie](https://github.com/timleslie)! - Updated internal type definitions. + +* [#6310](https://github.com/keystonejs/keystone/pull/6310) [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053) Thanks [@timleslie](https://github.com/timleslie)! - Updated dependencies to use `mergeSchemas` from `@graphql-tools/schema`, rather than its old location in `@graphql-tools/merge`. You might see a reordering of the contents of your `graphql.schema` file. + +* Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`8187ea019`](https://github.com/keystonejs/keystone/commit/8187ea019a212874f3c602573af3382c6f3bd3b2), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 + - @keystone-next/types@24.0.0 + - @keystone-next/auth@31.0.0 + - @keystone-next/cloudinary@6.0.6 + ## 4.0.6 ### Patch Changes diff --git a/examples-staging/ecommerce/access.ts b/examples-staging/ecommerce/access.ts index fc43810001a..30885a68882 100644 --- a/examples-staging/ecommerce/access.ts +++ b/examples-staging/ecommerce/access.ts @@ -35,7 +35,7 @@ export const rules = { return true; } // 2. If not, do they own this item? - return { user: { id: session?.itemId } }; + return { user: { id: { equals: session?.itemId } } }; }, canOrder({ session }: ListAccessArgs) { if (!isSignedIn({ session })) { @@ -46,7 +46,7 @@ export const rules = { return true; } // 2. If not, do they own this item? - return { user: { id: session?.itemId } }; + return { user: { id: { equals: session?.itemId } } }; }, canManageOrderItems({ session }: ListAccessArgs) { if (!isSignedIn({ session })) { @@ -57,7 +57,7 @@ export const rules = { return true; } // 2. If not, do they own this item? - return { order: { user: { id: session?.itemId } } }; + return { order: { user: { id: { equals: session?.itemId } } } }; }, canReadProducts({ session }: ListAccessArgs) { if (!isSignedIn({ session })) { @@ -67,7 +67,7 @@ export const rules = { return true; // They can read everything! } // They should only see available products (based on the status field) - return { status: 'AVAILABLE' }; + return { status: { equals: 'AVAILABLE' } }; }, canManageUsers({ session }: ListAccessArgs) { if (!isSignedIn({ session })) { @@ -77,6 +77,6 @@ export const rules = { return true; } // Otherwise they may only update themselves! - return { id: session?.itemId }; + return { id: { equals: session?.itemId } }; }, }; diff --git a/examples-staging/ecommerce/mutations/addToCart.ts b/examples-staging/ecommerce/mutations/addToCart.ts index 14f9416e169..e071e44cd0d 100644 --- a/examples-staging/ecommerce/mutations/addToCart.ts +++ b/examples-staging/ecommerce/mutations/addToCart.ts @@ -14,7 +14,7 @@ async function addToCart( } // 2. Query the current users cart const allCartItems = await context.lists.CartItem.findMany({ - where: { user: { id: sesh.itemId }, product: { id: productId } }, + where: { user: { id: { equals: sesh.itemId } }, product: { id: { equals: productId } } }, query: 'id quantity', }); diff --git a/examples-staging/ecommerce/package.json b/examples-staging/ecommerce/package.json index 48ffc9b9b6a..4a174a517da 100644 --- a/examples-staging/ecommerce/package.json +++ b/examples-staging/ecommerce/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/example-ecommerce", - "version": "4.0.6", + "version": "4.0.7", "private": true, "author": "Wes Bos & Jed Watson", "license": "MIT", @@ -11,26 +11,26 @@ "seed-data": "keystone-next --seed-data" }, "dependencies": { - "@babel/plugin-transform-runtime": "^7.14.5", - "@babel/preset-env": "^7.14.9", + "@babel/plugin-transform-runtime": "^7.15.0", + "@babel/preset-env": "^7.15.0", "@babel/preset-react": "^7.14.5", - "@babel/preset-typescript": "^7.14.5", - "@babel/runtime": "^7.14.8", - "@keystone-next/auth": "^30.0.0", - "@keystone-next/cloudinary": "^6.0.5", - "@keystone-next/fields": "^13.0.0", - "@keystone-next/keystone": "^23.0.0", - "@keystone-next/types": "^23.0.0", + "@babel/preset-typescript": "^7.15.0", + "@babel/runtime": "^7.15.3", + "@keystone-next/auth": "^31.0.0", + "@keystone-next/cloudinary": "^6.0.6", + "@keystone-next/fields": "^14.0.0", + "@keystone-next/keystone": "^24.0.0", + "@keystone-next/types": "^24.0.0", "@types/nodemailer": "^6.4.4", "dotenv": "^10.0.0", "next": "^10.2.3", "nodemailer": "^6.6.3", "react": "^17.0.2", "react-dom": "^17.0.2", - "stripe": "^8.167.0" + "stripe": "^8.169.0" }, "devDependencies": { - "@keystone-next/testing": "^1.1.0", + "@keystone-next/testing": "^1.1.1", "typescript": "^4.3.5" }, "engines": { diff --git a/examples-staging/ecommerce/schema.graphql b/examples-staging/ecommerce/schema.graphql index d918cf69b1d..4b3d0b5cc08 100644 --- a/examples-staging/ecommerce/schema.graphql +++ b/examples-staging/ecommerce/schema.graphql @@ -1,3 +1,136 @@ +type Mutation { + addToCart(productId: ID): CartItem + checkout(token: String!): Order + sendUserPasswordResetLink(email: String!): SendUserPasswordResetLinkResult + redeemUserPasswordResetToken( + email: String! + token: String! + password: String! + ): RedeemUserPasswordResetTokenResult + createInitialUser( + data: CreateInitialUserInput! + ): UserAuthenticationWithPasswordSuccess! + authenticateUserWithPassword( + email: String! + password: String! + ): UserAuthenticationWithPasswordResult! + createUser(data: UserCreateInput!): User + createUsers(data: [UserCreateInput!]!): [User] + updateUser(where: UserWhereUniqueInput!, data: UserUpdateInput!): User + updateUsers(data: [UserUpdateArgs!]!): [User] + deleteUser(where: UserWhereUniqueInput!): User + deleteUsers(where: [UserWhereUniqueInput!]!): [User] + createProduct(data: ProductCreateInput!): Product + createProducts(data: [ProductCreateInput!]!): [Product] + updateProduct( + where: ProductWhereUniqueInput! + data: ProductUpdateInput! + ): Product + updateProducts(data: [ProductUpdateArgs!]!): [Product] + deleteProduct(where: ProductWhereUniqueInput!): Product + deleteProducts(where: [ProductWhereUniqueInput!]!): [Product] + createProductImage(data: ProductImageCreateInput!): ProductImage + createProductImages(data: [ProductImageCreateInput!]!): [ProductImage] + updateProductImage( + where: ProductImageWhereUniqueInput! + data: ProductImageUpdateInput! + ): ProductImage + updateProductImages(data: [ProductImageUpdateArgs!]!): [ProductImage] + deleteProductImage(where: ProductImageWhereUniqueInput!): ProductImage + deleteProductImages(where: [ProductImageWhereUniqueInput!]!): [ProductImage] + createCartItem(data: CartItemCreateInput!): CartItem + createCartItems(data: [CartItemCreateInput!]!): [CartItem] + updateCartItem( + where: CartItemWhereUniqueInput! + data: CartItemUpdateInput! + ): CartItem + updateCartItems(data: [CartItemUpdateArgs!]!): [CartItem] + deleteCartItem(where: CartItemWhereUniqueInput!): CartItem + deleteCartItems(where: [CartItemWhereUniqueInput!]!): [CartItem] + createOrderItem(data: OrderItemCreateInput!): OrderItem + createOrderItems(data: [OrderItemCreateInput!]!): [OrderItem] + updateOrderItem( + where: OrderItemWhereUniqueInput! + data: OrderItemUpdateInput! + ): OrderItem + updateOrderItems(data: [OrderItemUpdateArgs!]!): [OrderItem] + deleteOrderItem(where: OrderItemWhereUniqueInput!): OrderItem + deleteOrderItems(where: [OrderItemWhereUniqueInput!]!): [OrderItem] + createOrder(data: OrderCreateInput!): Order + createOrders(data: [OrderCreateInput!]!): [Order] + updateOrder(where: OrderWhereUniqueInput!, data: OrderUpdateInput!): Order + updateOrders(data: [OrderUpdateArgs!]!): [Order] + deleteOrder(where: OrderWhereUniqueInput!): Order + deleteOrders(where: [OrderWhereUniqueInput!]!): [Order] + createRole(data: RoleCreateInput!): Role + createRoles(data: [RoleCreateInput!]!): [Role] + updateRole(where: RoleWhereUniqueInput!, data: RoleUpdateInput!): Role + updateRoles(data: [RoleUpdateArgs!]!): [Role] + deleteRole(where: RoleWhereUniqueInput!): Role + deleteRoles(where: [RoleWhereUniqueInput!]!): [Role] + endSession: Boolean! +} + +type SendUserPasswordResetLinkResult { + code: PasswordResetRequestErrorCode! + message: String! +} + +enum PasswordResetRequestErrorCode { + IDENTITY_NOT_FOUND + MULTIPLE_IDENTITY_MATCHES +} + +type ValidateUserPasswordResetTokenResult { + code: PasswordResetRedemptionErrorCode! + message: String! +} + +type RedeemUserPasswordResetTokenResult { + code: PasswordResetRedemptionErrorCode! + message: String! +} + +enum PasswordResetRedemptionErrorCode { + FAILURE + IDENTITY_NOT_FOUND + MULTIPLE_IDENTITY_MATCHES + TOKEN_NOT_SET + TOKEN_MISMATCH + TOKEN_EXPIRED + TOKEN_REDEEMED +} + +input CreateInitialUserInput { + name: String + email: String + password: String +} + +union AuthenticatedItem = User + +union UserAuthenticationWithPasswordResult = + UserAuthenticationWithPasswordSuccess + | UserAuthenticationWithPasswordFailure + +type UserAuthenticationWithPasswordSuccess { + sessionToken: String! + item: User! +} + +type UserAuthenticationWithPasswordFailure { + code: PasswordAuthErrorCode! + message: String! +} + +enum PasswordAuthErrorCode { + FAILURE + IDENTITY_NOT_FOUND + SECRET_NOT_SET + MULTIPLE_IDENTITY_MATCHES + SECRET_MISMATCH +} + type User { id: ID! name: String @@ -6,14 +139,14 @@ type User { cart( where: CartItemWhereInput! = {} orderBy: [CartItemOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [CartItem!] cartCount(where: CartItemWhereInput! = {}): Int orders( where: OrderWhereInput! = {} orderBy: [OrderOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Order!] ordersCount(where: OrderWhereInput! = {}): Int @@ -21,7 +154,7 @@ type User { products( where: ProductWhereInput! = {} orderBy: [ProductOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Product!] productsCount(where: ProductWhereInput! = {}): Int @@ -37,55 +170,90 @@ type PasswordState { input UserWhereInput { AND: [UserWhereInput!] OR: [UserWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_in: [String] - name_not_in: [String] - email: String - email_not: String - email_contains: String - email_not_contains: String - email_in: [String] - email_not_in: [String] - password_is_set: Boolean - cart_every: CartItemWhereInput - cart_some: CartItemWhereInput - cart_none: CartItemWhereInput - orders_every: OrderWhereInput - orders_some: OrderWhereInput - orders_none: OrderWhereInput + NOT: [UserWhereInput!] + id: IDFilter + name: StringNullableFilter + email: StringNullableFilter + password: PasswordFilter + cart: CartItemManyRelationFilter + orders: OrderManyRelationFilter role: RoleWhereInput - role_is_null: Boolean - products_every: ProductWhereInput - products_some: ProductWhereInput - products_none: ProductWhereInput - passwordResetToken_is_set: Boolean - passwordResetIssuedAt: String - passwordResetIssuedAt_not: String - passwordResetIssuedAt_lt: String - passwordResetIssuedAt_lte: String - passwordResetIssuedAt_gt: String - passwordResetIssuedAt_gte: String - passwordResetIssuedAt_in: [String] - passwordResetIssuedAt_not_in: [String] - passwordResetRedeemedAt: String - passwordResetRedeemedAt_not: String - passwordResetRedeemedAt_lt: String - passwordResetRedeemedAt_lte: String - passwordResetRedeemedAt_gt: String - passwordResetRedeemedAt_gte: String - passwordResetRedeemedAt_in: [String] - passwordResetRedeemedAt_not_in: [String] + products: ProductManyRelationFilter + passwordResetToken: PasswordFilter + passwordResetIssuedAt: DateTimeNullableFilter + passwordResetRedeemedAt: DateTimeNullableFilter +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input PasswordFilter { + isSet: Boolean! +} + +input CartItemManyRelationFilter { + every: CartItemWhereInput + some: CartItemWhereInput + none: CartItemWhereInput +} + +input OrderManyRelationFilter { + every: OrderWhereInput + some: OrderWhereInput + none: OrderWhereInput +} + +input ProductManyRelationFilter { + every: ProductWhereInput + some: ProductWhereInput + none: ProductWhereInput +} + +input DateTimeNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + not: DateTimeNullableFilter } input UserWhereUniqueInput { @@ -197,42 +365,25 @@ type Product { input ProductWhereInput { AND: [ProductWhereInput!] OR: [ProductWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_in: [String] - name_not_in: [String] - description: String - description_not: String - description_contains: String - description_not_contains: String - description_in: [String] - description_not_in: [String] + NOT: [ProductWhereInput!] + id: IDFilter + name: StringNullableFilter + description: StringNullableFilter photo: ProductImageWhereInput - photo_is_null: Boolean - status: String - status_not: String - status_in: [String] - status_not_in: [String] - price: Int - price_not: Int - price_lt: Int - price_lte: Int - price_gt: Int - price_gte: Int - price_in: [Int] - price_not_in: [Int] + status: StringNullableFilter + price: IntNullableFilter user: UserWhereInput - user_is_null: Boolean +} + +input IntNullableFilter { + equals: Int + in: [Int!] + notIn: [Int!] + lt: Int + lte: Int + gt: Int + gte: Int + not: IntNullableFilter } input ProductWhereUniqueInput { @@ -351,26 +502,10 @@ input CloudinaryImageFormat { input ProductImageWhereInput { AND: [ProductImageWhereInput!] OR: [ProductImageWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - image: String - image_not: String - image_in: [String] - image_not_in: [String] - altText: String - altText_not: String - altText_contains: String - altText_not_contains: String - altText_in: [String] - altText_not_in: [String] + NOT: [ProductImageWhereInput!] + id: IDFilter + altText: StringNullableFilter product: ProductWhereInput - product_is_null: Boolean } input ProductImageWhereUniqueInput { @@ -425,26 +560,11 @@ type CartItem { input CartItemWhereInput { AND: [CartItemWhereInput!] OR: [CartItemWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - quantity: Int - quantity_not: Int - quantity_lt: Int - quantity_lte: Int - quantity_gt: Int - quantity_gte: Int - quantity_in: [Int] - quantity_not_in: [Int] + NOT: [CartItemWhereInput!] + id: IDFilter + quantity: IntNullableFilter product: ProductWhereInput - product_is_null: Boolean user: UserWhereInput - user_is_null: Boolean } input CartItemWhereUniqueInput { @@ -486,46 +606,14 @@ type OrderItem { input OrderItemWhereInput { AND: [OrderItemWhereInput!] OR: [OrderItemWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_in: [String] - name_not_in: [String] - description: String - description_not: String - description_contains: String - description_not_contains: String - description_in: [String] - description_not_in: [String] + NOT: [OrderItemWhereInput!] + id: IDFilter + name: StringNullableFilter + description: StringNullableFilter photo: ProductImageWhereInput - photo_is_null: Boolean - price: Int - price_not: Int - price_lt: Int - price_lte: Int - price_gt: Int - price_gte: Int - price_in: [Int] - price_not_in: [Int] - quantity: Int - quantity_not: Int - quantity_lt: Int - quantity_lte: Int - quantity_gt: Int - quantity_gte: Int - quantity_in: [Int] - quantity_not_in: [Int] + price: IntNullableFilter + quantity: IntNullableFilter order: OrderWhereInput - order_is_null: Boolean } input OrderItemWhereUniqueInput { @@ -581,7 +669,7 @@ type Order { items( where: OrderItemWhereInput! = {} orderBy: [OrderItemOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [OrderItem!] itemsCount(where: OrderItemWhereInput! = {}): Int @@ -592,33 +680,18 @@ type Order { input OrderWhereInput { AND: [OrderWhereInput!] OR: [OrderWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - total: Int - total_not: Int - total_lt: Int - total_lte: Int - total_gt: Int - total_gte: Int - total_in: [Int] - total_not_in: [Int] - items_every: OrderItemWhereInput - items_some: OrderItemWhereInput - items_none: OrderItemWhereInput + NOT: [OrderWhereInput!] + id: IDFilter + total: IntNullableFilter + items: OrderItemManyRelationFilter user: UserWhereInput - user_is_null: Boolean - charge: String - charge_not: String - charge_contains: String - charge_not_contains: String - charge_in: [String] - charge_not_in: [String] + charge: StringNullableFilter +} + +input OrderItemManyRelationFilter { + every: OrderItemWhereInput + some: OrderItemWhereInput + none: OrderItemWhereInput } input OrderWhereUniqueInput { @@ -674,7 +747,7 @@ type Role { assignedTo( where: UserWhereInput! = {} orderBy: [UserOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [User!] assignedToCount(where: UserWhereInput! = {}): Int @@ -683,35 +756,27 @@ type Role { input RoleWhereInput { AND: [RoleWhereInput!] OR: [RoleWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_in: [String] - name_not_in: [String] - canManageProducts: Boolean - canManageProducts_not: Boolean - canSeeOtherUsers: Boolean - canSeeOtherUsers_not: Boolean - canManageUsers: Boolean - canManageUsers_not: Boolean - canManageRoles: Boolean - canManageRoles_not: Boolean - canManageCart: Boolean - canManageCart_not: Boolean - canManageOrders: Boolean - canManageOrders_not: Boolean - assignedTo_every: UserWhereInput - assignedTo_some: UserWhereInput - assignedTo_none: UserWhereInput + NOT: [RoleWhereInput!] + id: IDFilter + name: StringNullableFilter + canManageProducts: BooleanNullableFilter + canSeeOtherUsers: BooleanNullableFilter + canManageUsers: BooleanNullableFilter + canManageRoles: BooleanNullableFilter + canManageCart: BooleanNullableFilter + canManageOrders: BooleanNullableFilter + assignedTo: UserManyRelationFilter +} + +input BooleanNullableFilter { + equals: Boolean + not: BooleanNullableFilter +} + +input UserManyRelationFilter { + every: UserWhereInput + some: UserWhereInput + none: UserWhereInput } input RoleWhereUniqueInput { @@ -776,144 +841,16 @@ scalar JSON url: "http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf" ) -type Mutation { - createUser(data: UserCreateInput!): User - createUsers(data: [UserCreateInput!]!): [User] - updateUser(where: UserWhereUniqueInput!, data: UserUpdateInput!): User - updateUsers(data: [UserUpdateArgs!]!): [User] - deleteUser(where: UserWhereUniqueInput!): User - deleteUsers(where: [UserWhereUniqueInput!]!): [User] - createProduct(data: ProductCreateInput!): Product - createProducts(data: [ProductCreateInput!]!): [Product] - updateProduct( - where: ProductWhereUniqueInput! - data: ProductUpdateInput! - ): Product - updateProducts(data: [ProductUpdateArgs!]!): [Product] - deleteProduct(where: ProductWhereUniqueInput!): Product - deleteProducts(where: [ProductWhereUniqueInput!]!): [Product] - createProductImage(data: ProductImageCreateInput!): ProductImage - createProductImages(data: [ProductImageCreateInput!]!): [ProductImage] - updateProductImage( - where: ProductImageWhereUniqueInput! - data: ProductImageUpdateInput! - ): ProductImage - updateProductImages(data: [ProductImageUpdateArgs!]!): [ProductImage] - deleteProductImage(where: ProductImageWhereUniqueInput!): ProductImage - deleteProductImages(where: [ProductImageWhereUniqueInput!]!): [ProductImage] - createCartItem(data: CartItemCreateInput!): CartItem - createCartItems(data: [CartItemCreateInput!]!): [CartItem] - updateCartItem( - where: CartItemWhereUniqueInput! - data: CartItemUpdateInput! - ): CartItem - updateCartItems(data: [CartItemUpdateArgs!]!): [CartItem] - deleteCartItem(where: CartItemWhereUniqueInput!): CartItem - deleteCartItems(where: [CartItemWhereUniqueInput!]!): [CartItem] - createOrderItem(data: OrderItemCreateInput!): OrderItem - createOrderItems(data: [OrderItemCreateInput!]!): [OrderItem] - updateOrderItem( - where: OrderItemWhereUniqueInput! - data: OrderItemUpdateInput! - ): OrderItem - updateOrderItems(data: [OrderItemUpdateArgs!]!): [OrderItem] - deleteOrderItem(where: OrderItemWhereUniqueInput!): OrderItem - deleteOrderItems(where: [OrderItemWhereUniqueInput!]!): [OrderItem] - createOrder(data: OrderCreateInput!): Order - createOrders(data: [OrderCreateInput!]!): [Order] - updateOrder(where: OrderWhereUniqueInput!, data: OrderUpdateInput!): Order - updateOrders(data: [OrderUpdateArgs!]!): [Order] - deleteOrder(where: OrderWhereUniqueInput!): Order - deleteOrders(where: [OrderWhereUniqueInput!]!): [Order] - createRole(data: RoleCreateInput!): Role - createRoles(data: [RoleCreateInput!]!): [Role] - updateRole(where: RoleWhereUniqueInput!, data: RoleUpdateInput!): Role - updateRoles(data: [RoleUpdateArgs!]!): [Role] - deleteRole(where: RoleWhereUniqueInput!): Role - deleteRoles(where: [RoleWhereUniqueInput!]!): [Role] - authenticateUserWithPassword( - email: String! - password: String! - ): UserAuthenticationWithPasswordResult! - createInitialUser( - data: CreateInitialUserInput! - ): UserAuthenticationWithPasswordSuccess! - sendUserPasswordResetLink(email: String!): SendUserPasswordResetLinkResult - redeemUserPasswordResetToken( +type Query { + validateUserPasswordResetToken( email: String! token: String! - password: String! - ): RedeemUserPasswordResetTokenResult - addToCart(productId: ID): CartItem - checkout(token: String!): Order - endSession: Boolean! -} - -union AuthenticatedItem = User - -union UserAuthenticationWithPasswordResult = - UserAuthenticationWithPasswordSuccess - | UserAuthenticationWithPasswordFailure - -type UserAuthenticationWithPasswordSuccess { - sessionToken: String! - item: User! -} - -type UserAuthenticationWithPasswordFailure { - code: PasswordAuthErrorCode! - message: String! -} - -enum PasswordAuthErrorCode { - FAILURE - IDENTITY_NOT_FOUND - SECRET_NOT_SET - MULTIPLE_IDENTITY_MATCHES - SECRET_MISMATCH -} - -input CreateInitialUserInput { - name: String - email: String - password: String -} - -type SendUserPasswordResetLinkResult { - code: PasswordResetRequestErrorCode! - message: String! -} - -enum PasswordResetRequestErrorCode { - IDENTITY_NOT_FOUND - MULTIPLE_IDENTITY_MATCHES -} - -type ValidateUserPasswordResetTokenResult { - code: PasswordResetRedemptionErrorCode! - message: String! -} - -type RedeemUserPasswordResetTokenResult { - code: PasswordResetRedemptionErrorCode! - message: String! -} - -enum PasswordResetRedemptionErrorCode { - FAILURE - IDENTITY_NOT_FOUND - MULTIPLE_IDENTITY_MATCHES - TOKEN_NOT_SET - TOKEN_MISMATCH - TOKEN_EXPIRED - TOKEN_REDEEMED -} - -type Query { + ): ValidateUserPasswordResetTokenResult + authenticatedItem: AuthenticatedItem users( where: UserWhereInput! = {} orderBy: [UserOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [User!] user(where: UserWhereUniqueInput!): User @@ -921,7 +858,7 @@ type Query { products( where: ProductWhereInput! = {} orderBy: [ProductOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Product!] product(where: ProductWhereUniqueInput!): Product @@ -929,7 +866,7 @@ type Query { productImages( where: ProductImageWhereInput! = {} orderBy: [ProductImageOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [ProductImage!] productImage(where: ProductImageWhereUniqueInput!): ProductImage @@ -937,7 +874,7 @@ type Query { cartItems( where: CartItemWhereInput! = {} orderBy: [CartItemOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [CartItem!] cartItem(where: CartItemWhereUniqueInput!): CartItem @@ -945,7 +882,7 @@ type Query { orderItems( where: OrderItemWhereInput! = {} orderBy: [OrderItemOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [OrderItem!] orderItem(where: OrderItemWhereUniqueInput!): OrderItem @@ -953,7 +890,7 @@ type Query { orders( where: OrderWhereInput! = {} orderBy: [OrderOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Order!] order(where: OrderWhereUniqueInput!): Order @@ -961,16 +898,11 @@ type Query { roles( where: RoleWhereInput! = {} orderBy: [RoleOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Role!] role(where: RoleWhereUniqueInput!): Role rolesCount(where: RoleWhereInput! = {}): Int - authenticatedItem: AuthenticatedItem - validateUserPasswordResetToken( - email: String! - token: String! - ): ValidateUserPasswordResetTokenResult keystone: KeystoneMeta! } diff --git a/examples-staging/ecommerce/tests/mutations.test.ts b/examples-staging/ecommerce/tests/mutations.test.ts index d706825a7c2..6a114e9ea51 100644 --- a/examples-staging/ecommerce/tests/mutations.test.ts +++ b/examples-staging/ecommerce/tests/mutations.test.ts @@ -311,13 +311,13 @@ describe(`Custom mutations`, () => { await q({ query, variables: { productId: product2.id } }); await q({ query, variables: { productId: product1.id } }); const result1 = await context.sudo().lists.CartItem.findMany({ - where: { product: { id: product1.id } }, + where: { product: { id: { equals: product1.id } } }, query: 'quantity', }); expect(result1).toHaveLength(1); expect(result1[0].quantity).toEqual(3); const result2 = await context.sudo().lists.CartItem.findMany({ - where: { product: { id: product2.id } }, + where: { product: { id: { equals: product2.id } } }, query: 'quantity', }); expect(result2).toHaveLength(1); diff --git a/examples-staging/embedded-nextjs/CHANGELOG.md b/examples-staging/embedded-nextjs/CHANGELOG.md index cb97e8a55a9..9e03eb1293c 100644 --- a/examples-staging/embedded-nextjs/CHANGELOG.md +++ b/examples-staging/embedded-nextjs/CHANGELOG.md @@ -1,5 +1,13 @@ # @keystone-next/example-next-lite +## 3.0.6 + +### Patch Changes + +- Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 + ## 3.0.5 ### Patch Changes diff --git a/examples-staging/embedded-nextjs/package.json b/examples-staging/embedded-nextjs/package.json index e09673d4696..54d6edeac8c 100644 --- a/examples-staging/embedded-nextjs/package.json +++ b/examples-staging/embedded-nextjs/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/example-embedded-nextjs", - "version": "3.0.5", + "version": "3.0.6", "private": true, "license": "MIT", "scripts": { @@ -9,8 +9,8 @@ "build": "next build" }, "dependencies": { - "@keystone-next/fields": "^13.0.0", - "@keystone-next/keystone": "^23.0.0", + "@keystone-next/fields": "^14.0.0", + "@keystone-next/keystone": "^24.0.0", "dotenv": "^10.0.0", "next": "^10.2.3", "react": "^17.0.2", diff --git a/examples-staging/embedded-nextjs/schema.graphql b/examples-staging/embedded-nextjs/schema.graphql index 4aeb0f138f9..0c723ddb1de 100644 --- a/examples-staging/embedded-nextjs/schema.graphql +++ b/examples-staging/embedded-nextjs/schema.graphql @@ -8,32 +8,50 @@ type Post { input PostWhereInput { AND: [PostWhereInput!] OR: [PostWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - title: String - title_not: String - title_contains: String - title_not_contains: String - title_in: [String] - title_not_in: [String] - slug: String - slug_not: String - slug_contains: String - slug_not_contains: String - slug_in: [String] - slug_not_in: [String] - content: String - content_not: String - content_contains: String - content_not_contains: String - content_in: [String] - content_not_in: [String] + NOT: [PostWhereInput!] + id: IDFilter + title: StringNullableFilter + slug: StringNullableFilter + content: StringNullableFilter +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter } input PostWhereUniqueInput { @@ -90,7 +108,7 @@ type Query { posts( where: PostWhereInput! = {} orderBy: [PostOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Post!] post(where: PostWhereUniqueInput!): Post diff --git a/examples-staging/graphql-api-endpoint/CHANGELOG.md b/examples-staging/graphql-api-endpoint/CHANGELOG.md index c12e0035a69..3ba38d49da6 100644 --- a/examples-staging/graphql-api-endpoint/CHANGELOG.md +++ b/examples-staging/graphql-api-endpoint/CHANGELOG.md @@ -1,5 +1,17 @@ # keystone-next-app +## 1.0.6 + +### Patch Changes + +- [#6310](https://github.com/keystonejs/keystone/pull/6310) [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053) Thanks [@timleslie](https://github.com/timleslie)! - Updated dependencies to use `mergeSchemas` from `@graphql-tools/schema`, rather than its old location in `@graphql-tools/merge`. You might see a reordering of the contents of your `graphql.schema` file. + +- Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`e985aa010`](https://github.com/keystonejs/keystone/commit/e985aa0104d30a779f21ec05d80e6b98ece87dfb), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`69f47bfed`](https://github.com/keystonejs/keystone/commit/69f47bfed1eaa1269cfdc42071268a914bd4aa17), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 + - @keystone-next/fields-document@8.0.0 + - @keystone-next/auth@31.0.0 + ## 1.0.5 ### Patch Changes diff --git a/examples-staging/graphql-api-endpoint/package.json b/examples-staging/graphql-api-endpoint/package.json index a8b38a078d8..11958b4f72c 100644 --- a/examples-staging/graphql-api-endpoint/package.json +++ b/examples-staging/graphql-api-endpoint/package.json @@ -1,6 +1,6 @@ { "name": "keystone-next-app", - "version": "1.0.5", + "version": "1.0.6", "private": true, "scripts": { "dev": "keystone-next dev", @@ -11,11 +11,11 @@ "node": "^12.20 || >= 14.13" }, "dependencies": { - "@babel/runtime": "^7.14.8", - "@keystone-next/auth": "^30.0.0", - "@keystone-next/fields": "^13.0.0", - "@keystone-next/fields-document": "^7.0.3", - "@keystone-next/keystone": "^23.0.0", + "@babel/runtime": "^7.15.3", + "@keystone-next/auth": "^31.0.0", + "@keystone-next/fields": "^14.0.0", + "@keystone-next/fields-document": "^8.0.0", + "@keystone-next/keystone": "^24.0.0", "apollo-server-micro": "^2.25.2" }, "repository": "https://github.com/keystonejs/keystone/tree/master/examples-staging/graphql-api-endpoint" diff --git a/examples-staging/graphql-api-endpoint/schema.graphql b/examples-staging/graphql-api-endpoint/schema.graphql index 13fde63066a..1203d46c607 100644 --- a/examples-staging/graphql-api-endpoint/schema.graphql +++ b/examples-staging/graphql-api-endpoint/schema.graphql @@ -1,3 +1,62 @@ +input CreateInitialUserInput { + name: String + email: String + password: String +} + +type Mutation { + createInitialUser( + data: CreateInitialUserInput! + ): UserAuthenticationWithPasswordSuccess! + authenticateUserWithPassword( + email: String! + password: String! + ): UserAuthenticationWithPasswordResult! + createUser(data: UserCreateInput!): User + createUsers(data: [UserCreateInput!]!): [User] + updateUser(where: UserWhereUniqueInput!, data: UserUpdateInput!): User + updateUsers(data: [UserUpdateArgs!]!): [User] + deleteUser(where: UserWhereUniqueInput!): User + deleteUsers(where: [UserWhereUniqueInput!]!): [User] + createPost(data: PostCreateInput!): Post + createPosts(data: [PostCreateInput!]!): [Post] + updatePost(where: PostWhereUniqueInput!, data: PostUpdateInput!): Post + updatePosts(data: [PostUpdateArgs!]!): [Post] + deletePost(where: PostWhereUniqueInput!): Post + deletePosts(where: [PostWhereUniqueInput!]!): [Post] + createTag(data: TagCreateInput!): Tag + createTags(data: [TagCreateInput!]!): [Tag] + updateTag(where: TagWhereUniqueInput!, data: TagUpdateInput!): Tag + updateTags(data: [TagUpdateArgs!]!): [Tag] + deleteTag(where: TagWhereUniqueInput!): Tag + deleteTags(where: [TagWhereUniqueInput!]!): [Tag] + endSession: Boolean! +} + +union AuthenticatedItem = User + +union UserAuthenticationWithPasswordResult = + UserAuthenticationWithPasswordSuccess + | UserAuthenticationWithPasswordFailure + +type UserAuthenticationWithPasswordSuccess { + sessionToken: String! + item: User! +} + +type UserAuthenticationWithPasswordFailure { + code: PasswordAuthErrorCode! + message: String! +} + +enum PasswordAuthErrorCode { + FAILURE + IDENTITY_NOT_FOUND + SECRET_NOT_SET + MULTIPLE_IDENTITY_MATCHES + SECRET_MISMATCH +} + type User { id: ID! name: String @@ -6,7 +65,7 @@ type User { posts( where: PostWhereInput! = {} orderBy: [PostOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Post!] postsCount(where: PostWhereInput! = {}): Int @@ -19,54 +78,67 @@ type PasswordState { input UserWhereInput { AND: [UserWhereInput!] OR: [UserWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_starts_with: String - name_not_starts_with: String - name_ends_with: String - name_not_ends_with: String - name_i: String - name_not_i: String - name_contains_i: String - name_not_contains_i: String - name_starts_with_i: String - name_not_starts_with_i: String - name_ends_with_i: String - name_not_ends_with_i: String - name_in: [String] - name_not_in: [String] - email: String - email_not: String - email_contains: String - email_not_contains: String - email_starts_with: String - email_not_starts_with: String - email_ends_with: String - email_not_ends_with: String - email_i: String - email_not_i: String - email_contains_i: String - email_not_contains_i: String - email_starts_with_i: String - email_not_starts_with_i: String - email_ends_with_i: String - email_not_ends_with_i: String - email_in: [String] - email_not_in: [String] - password_is_set: Boolean - posts_every: PostWhereInput - posts_some: PostWhereInput - posts_none: PostWhereInput + NOT: [UserWhereInput!] + id: IDFilter + name: StringNullableFilter + email: StringNullableFilter + password: PasswordFilter + posts: PostManyRelationFilter +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + mode: QueryMode + not: NestedStringNullableFilter +} + +enum QueryMode { + default + insensitive +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input PasswordFilter { + isSet: Boolean! +} + +input PostManyRelationFilter { + every: PostWhereInput + some: PostWhereInput + none: PostWhereInput } input UserWhereUniqueInput { @@ -126,7 +198,7 @@ type Post { tags( where: TagWhereInput! = {} orderBy: [TagOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Tag!] tagsCount(where: TagWhereInput! = {}): Int @@ -139,49 +211,30 @@ type Post_content_DocumentField { input PostWhereInput { AND: [PostWhereInput!] OR: [PostWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - title: String - title_not: String - title_contains: String - title_not_contains: String - title_starts_with: String - title_not_starts_with: String - title_ends_with: String - title_not_ends_with: String - title_i: String - title_not_i: String - title_contains_i: String - title_not_contains_i: String - title_starts_with_i: String - title_not_starts_with_i: String - title_ends_with_i: String - title_not_ends_with_i: String - title_in: [String] - title_not_in: [String] - status: String - status_not: String - status_in: [String] - status_not_in: [String] - publishDate: String - publishDate_not: String - publishDate_lt: String - publishDate_lte: String - publishDate_gt: String - publishDate_gte: String - publishDate_in: [String] - publishDate_not_in: [String] + NOT: [PostWhereInput!] + id: IDFilter + title: StringNullableFilter + status: StringNullableFilter + publishDate: DateTimeNullableFilter author: UserWhereInput - author_is_null: Boolean - tags_every: TagWhereInput - tags_some: TagWhereInput - tags_none: TagWhereInput + tags: TagManyRelationFilter +} + +input DateTimeNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + not: DateTimeNullableFilter +} + +input TagManyRelationFilter { + every: TagWhereInput + some: TagWhereInput + none: TagWhereInput } input PostWhereUniqueInput { @@ -247,7 +300,7 @@ type Tag { posts( where: PostWhereInput! = {} orderBy: [PostOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Post!] postsCount(where: PostWhereInput! = {}): Int @@ -256,35 +309,10 @@ type Tag { input TagWhereInput { AND: [TagWhereInput!] OR: [TagWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_starts_with: String - name_not_starts_with: String - name_ends_with: String - name_not_ends_with: String - name_i: String - name_not_i: String - name_contains_i: String - name_not_contains_i: String - name_starts_with_i: String - name_not_starts_with_i: String - name_ends_with_i: String - name_not_ends_with_i: String - name_in: [String] - name_not_in: [String] - posts_every: PostWhereInput - posts_some: PostWhereInput - posts_none: PostWhereInput + NOT: [TagWhereInput!] + id: IDFilter + name: StringNullableFilter + posts: PostManyRelationFilter } input TagWhereUniqueInput { @@ -319,70 +347,12 @@ scalar JSON url: "http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf" ) -type Mutation { - createUser(data: UserCreateInput!): User - createUsers(data: [UserCreateInput!]!): [User] - updateUser(where: UserWhereUniqueInput!, data: UserUpdateInput!): User - updateUsers(data: [UserUpdateArgs!]!): [User] - deleteUser(where: UserWhereUniqueInput!): User - deleteUsers(where: [UserWhereUniqueInput!]!): [User] - createPost(data: PostCreateInput!): Post - createPosts(data: [PostCreateInput!]!): [Post] - updatePost(where: PostWhereUniqueInput!, data: PostUpdateInput!): Post - updatePosts(data: [PostUpdateArgs!]!): [Post] - deletePost(where: PostWhereUniqueInput!): Post - deletePosts(where: [PostWhereUniqueInput!]!): [Post] - createTag(data: TagCreateInput!): Tag - createTags(data: [TagCreateInput!]!): [Tag] - updateTag(where: TagWhereUniqueInput!, data: TagUpdateInput!): Tag - updateTags(data: [TagUpdateArgs!]!): [Tag] - deleteTag(where: TagWhereUniqueInput!): Tag - deleteTags(where: [TagWhereUniqueInput!]!): [Tag] - authenticateUserWithPassword( - email: String! - password: String! - ): UserAuthenticationWithPasswordResult! - createInitialUser( - data: CreateInitialUserInput! - ): UserAuthenticationWithPasswordSuccess! - endSession: Boolean! -} - -union AuthenticatedItem = User - -union UserAuthenticationWithPasswordResult = - UserAuthenticationWithPasswordSuccess - | UserAuthenticationWithPasswordFailure - -type UserAuthenticationWithPasswordSuccess { - sessionToken: String! - item: User! -} - -type UserAuthenticationWithPasswordFailure { - code: PasswordAuthErrorCode! - message: String! -} - -enum PasswordAuthErrorCode { - FAILURE - IDENTITY_NOT_FOUND - SECRET_NOT_SET - MULTIPLE_IDENTITY_MATCHES - SECRET_MISMATCH -} - -input CreateInitialUserInput { - name: String - email: String - password: String -} - type Query { + authenticatedItem: AuthenticatedItem users( where: UserWhereInput! = {} orderBy: [UserOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [User!] user(where: UserWhereUniqueInput!): User @@ -390,7 +360,7 @@ type Query { posts( where: PostWhereInput! = {} orderBy: [PostOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Post!] post(where: PostWhereUniqueInput!): Post @@ -398,12 +368,11 @@ type Query { tags( where: TagWhereInput! = {} orderBy: [TagOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Tag!] tag(where: TagWhereUniqueInput!): Tag tagsCount(where: TagWhereInput! = {}): Int - authenticatedItem: AuthenticatedItem keystone: KeystoneMeta! } @@ -478,11 +447,6 @@ enum KeystoneAdminUIFieldMetaItemViewFieldMode { hidden } -enum QueryMode { - default - insensitive -} - type KeystoneAdminUISort { field: String! direction: KeystoneAdminUISortDirection! diff --git a/examples-staging/playground/CHANGELOG.md b/examples-staging/playground/CHANGELOG.md index 2fc651dc077..fe7a35f17b9 100644 --- a/examples-staging/playground/CHANGELOG.md +++ b/examples-staging/playground/CHANGELOG.md @@ -1,5 +1,13 @@ # @keystone-next/example-playground +## 1.0.5 + +### Patch Changes + +- Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 + ## 1.0.4 ### Patch Changes diff --git a/examples-staging/playground/package.json b/examples-staging/playground/package.json index b81a675af63..b9720b7c057 100644 --- a/examples-staging/playground/package.json +++ b/examples-staging/playground/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/example-playground", - "version": "1.0.4", + "version": "1.0.5", "private": true, "license": "MIT", "scripts": { @@ -9,8 +9,8 @@ "build": "keystone-next build" }, "dependencies": { - "@keystone-next/fields": "^13.0.0", - "@keystone-next/keystone": "^23.0.0" + "@keystone-next/fields": "^14.0.0", + "@keystone-next/keystone": "^24.0.0" }, "devDependencies": { "typescript": "^4.3.5" diff --git a/examples-staging/playground/schema.graphql b/examples-staging/playground/schema.graphql index f7dd94aea96..67148d43a55 100644 --- a/examples-staging/playground/schema.graphql +++ b/examples-staging/playground/schema.graphql @@ -6,20 +6,48 @@ type Note { input NoteWhereInput { AND: [NoteWhereInput!] OR: [NoteWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - label: String - label_not: String - label_contains: String - label_not_contains: String - label_in: [String] - label_not_in: [String] + NOT: [NoteWhereInput!] + id: IDFilter + label: StringNullableFilter +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter } input NoteWhereUniqueInput { @@ -70,7 +98,7 @@ type Query { notes( where: NoteWhereInput! = {} orderBy: [NoteOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Note!] note(where: NoteWhereUniqueInput!): Note diff --git a/examples-staging/roles/CHANGELOG.md b/examples-staging/roles/CHANGELOG.md index 61de99f174e..25431826da1 100644 --- a/examples-staging/roles/CHANGELOG.md +++ b/examples-staging/roles/CHANGELOG.md @@ -1,5 +1,17 @@ # @keystone-next/example-roles +## 4.0.6 + +### Patch Changes + +- [#6310](https://github.com/keystonejs/keystone/pull/6310) [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053) Thanks [@timleslie](https://github.com/timleslie)! - Updated dependencies to use `mergeSchemas` from `@graphql-tools/schema`, rather than its old location in `@graphql-tools/merge`. You might see a reordering of the contents of your `graphql.schema` file. + +- Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`8187ea019`](https://github.com/keystonejs/keystone/commit/8187ea019a212874f3c602573af3382c6f3bd3b2), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 + - @keystone-next/types@24.0.0 + - @keystone-next/auth@31.0.0 + ## 4.0.5 ### Patch Changes diff --git a/examples-staging/roles/access.ts b/examples-staging/roles/access.ts index 25eb86a5195..4f31e1c101a 100644 --- a/examples-staging/roles/access.ts +++ b/examples-staging/roles/access.ts @@ -32,14 +32,14 @@ export const rules = { // Can see all todos that are: assigned to them, or not private return { OR: [ - { assignedTo: { id: session.itemId } }, - { assignedTo_is_null: true, isPrivate: true }, - { isPrivate_not: true }, + { assignedTo: { id: { equals: session.itemId } } }, + { assignedTo: null, isPrivate: { equals: true } }, + { NOT: { isPrivate: { equals: true } } }, ], }; } else { // Can only see their own todos - return { assignedTo: { id: session.itemId } }; + return { assignedTo: { id: { equals: session.itemId } } }; } }, canManageTodos: ({ session }: ListAccessArgs) => { @@ -51,7 +51,7 @@ export const rules = { return true; } else { // Can only manage their own todos - return { assignedTo: { id: session.itemId } }; + return { assignedTo: { id: { equals: session.itemId } } }; } }, canReadPeople: ({ session }: ListAccessArgs) => { @@ -63,7 +63,7 @@ export const rules = { return true; } else { // Can only see yourself - return { id: session.itemId }; + return { id: { equals: session.itemId } }; } }, canUpdatePeople: ({ session }: ListAccessArgs) => { @@ -75,7 +75,7 @@ export const rules = { return true; } else { // Can update yourself - return { id: session.itemId }; + return { id: { equals: session.itemId } }; } }, }; diff --git a/examples-staging/roles/package.json b/examples-staging/roles/package.json index 07f1b9f6494..7734e122ecf 100644 --- a/examples-staging/roles/package.json +++ b/examples-staging/roles/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/example-roles", - "version": "4.0.5", + "version": "4.0.6", "private": true, "license": "MIT", "scripts": { @@ -9,10 +9,10 @@ "build": "keystone-next build" }, "dependencies": { - "@keystone-next/auth": "^30.0.0", - "@keystone-next/fields": "^13.0.0", - "@keystone-next/keystone": "^23.0.0", - "@keystone-next/types": "^23.0.0", + "@keystone-next/auth": "^31.0.0", + "@keystone-next/fields": "^14.0.0", + "@keystone-next/keystone": "^24.0.0", + "@keystone-next/types": "^24.0.0", "next": "^10.2.3", "react": "^17.0.2", "react-dom": "^17.0.2" diff --git a/examples-staging/roles/schema.graphql b/examples-staging/roles/schema.graphql index be44e3407d0..ba8201c3db0 100644 --- a/examples-staging/roles/schema.graphql +++ b/examples-staging/roles/schema.graphql @@ -1,3 +1,62 @@ +input CreateInitialPersonInput { + name: String + email: String + password: String +} + +type Mutation { + createInitialPerson( + data: CreateInitialPersonInput! + ): PersonAuthenticationWithPasswordSuccess! + authenticatePersonWithPassword( + email: String! + password: String! + ): PersonAuthenticationWithPasswordResult! + createTodo(data: TodoCreateInput!): Todo + createTodos(data: [TodoCreateInput!]!): [Todo] + updateTodo(where: TodoWhereUniqueInput!, data: TodoUpdateInput!): Todo + updateTodos(data: [TodoUpdateArgs!]!): [Todo] + deleteTodo(where: TodoWhereUniqueInput!): Todo + deleteTodos(where: [TodoWhereUniqueInput!]!): [Todo] + createPerson(data: PersonCreateInput!): Person + createPeople(data: [PersonCreateInput!]!): [Person] + updatePerson(where: PersonWhereUniqueInput!, data: PersonUpdateInput!): Person + updatePeople(data: [PersonUpdateArgs!]!): [Person] + deletePerson(where: PersonWhereUniqueInput!): Person + deletePeople(where: [PersonWhereUniqueInput!]!): [Person] + createRole(data: RoleCreateInput!): Role + createRoles(data: [RoleCreateInput!]!): [Role] + updateRole(where: RoleWhereUniqueInput!, data: RoleUpdateInput!): Role + updateRoles(data: [RoleUpdateArgs!]!): [Role] + deleteRole(where: RoleWhereUniqueInput!): Role + deleteRoles(where: [RoleWhereUniqueInput!]!): [Role] + endSession: Boolean! +} + +union AuthenticatedItem = Person + +union PersonAuthenticationWithPasswordResult = + PersonAuthenticationWithPasswordSuccess + | PersonAuthenticationWithPasswordFailure + +type PersonAuthenticationWithPasswordSuccess { + sessionToken: String! + item: Person! +} + +type PersonAuthenticationWithPasswordFailure { + code: PasswordAuthErrorCode! + message: String! +} + +enum PasswordAuthErrorCode { + FAILURE + IDENTITY_NOT_FOUND + SECRET_NOT_SET + MULTIPLE_IDENTITY_MATCHES + SECRET_MISMATCH +} + type Todo { id: ID! label: String @@ -9,26 +68,56 @@ type Todo { input TodoWhereInput { AND: [TodoWhereInput!] OR: [TodoWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - label: String - label_not: String - label_contains: String - label_not_contains: String - label_in: [String] - label_not_in: [String] - isComplete: Boolean - isComplete_not: Boolean - isPrivate: Boolean - isPrivate_not: Boolean + NOT: [TodoWhereInput!] + id: IDFilter + label: StringNullableFilter + isComplete: BooleanNullableFilter + isPrivate: BooleanNullableFilter assignedTo: PersonWhereInput - assignedTo_is_null: Boolean +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input BooleanNullableFilter { + equals: Boolean + not: BooleanNullableFilter } input TodoWhereUniqueInput { @@ -86,7 +175,7 @@ type Person { tasks( where: TodoWhereInput! = {} orderBy: [TodoOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Todo!] tasksCount(where: TodoWhereInput! = {}): Int @@ -99,32 +188,23 @@ type PasswordState { input PersonWhereInput { AND: [PersonWhereInput!] OR: [PersonWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_in: [String] - name_not_in: [String] - email: String - email_not: String - email_contains: String - email_not_contains: String - email_in: [String] - email_not_in: [String] - password_is_set: Boolean + NOT: [PersonWhereInput!] + id: IDFilter + name: StringNullableFilter + email: StringNullableFilter + password: PasswordFilter role: RoleWhereInput - role_is_null: Boolean - tasks_every: TodoWhereInput - tasks_some: TodoWhereInput - tasks_none: TodoWhereInput + tasks: TodoManyRelationFilter +} + +input PasswordFilter { + isSet: Boolean! +} + +input TodoManyRelationFilter { + every: TodoWhereInput + some: TodoWhereInput + none: TodoWhereInput } input PersonWhereUniqueInput { @@ -194,7 +274,7 @@ type Role { assignedTo( where: PersonWhereInput! = {} orderBy: [PersonOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Person!] assignedToCount(where: PersonWhereInput! = {}): Int @@ -203,35 +283,22 @@ type Role { input RoleWhereInput { AND: [RoleWhereInput!] OR: [RoleWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_in: [String] - name_not_in: [String] - canCreateTodos: Boolean - canCreateTodos_not: Boolean - canManageAllTodos: Boolean - canManageAllTodos_not: Boolean - canSeeOtherPeople: Boolean - canSeeOtherPeople_not: Boolean - canEditOtherPeople: Boolean - canEditOtherPeople_not: Boolean - canManagePeople: Boolean - canManagePeople_not: Boolean - canManageRoles: Boolean - canManageRoles_not: Boolean - assignedTo_every: PersonWhereInput - assignedTo_some: PersonWhereInput - assignedTo_none: PersonWhereInput + NOT: [RoleWhereInput!] + id: IDFilter + name: StringNullableFilter + canCreateTodos: BooleanNullableFilter + canManageAllTodos: BooleanNullableFilter + canSeeOtherPeople: BooleanNullableFilter + canEditOtherPeople: BooleanNullableFilter + canManagePeople: BooleanNullableFilter + canManageRoles: BooleanNullableFilter + assignedTo: PersonManyRelationFilter +} + +input PersonManyRelationFilter { + every: PersonWhereInput + some: PersonWhereInput + none: PersonWhereInput } input RoleWhereUniqueInput { @@ -296,70 +363,12 @@ scalar JSON url: "http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf" ) -type Mutation { - createTodo(data: TodoCreateInput!): Todo - createTodos(data: [TodoCreateInput!]!): [Todo] - updateTodo(where: TodoWhereUniqueInput!, data: TodoUpdateInput!): Todo - updateTodos(data: [TodoUpdateArgs!]!): [Todo] - deleteTodo(where: TodoWhereUniqueInput!): Todo - deleteTodos(where: [TodoWhereUniqueInput!]!): [Todo] - createPerson(data: PersonCreateInput!): Person - createPeople(data: [PersonCreateInput!]!): [Person] - updatePerson(where: PersonWhereUniqueInput!, data: PersonUpdateInput!): Person - updatePeople(data: [PersonUpdateArgs!]!): [Person] - deletePerson(where: PersonWhereUniqueInput!): Person - deletePeople(where: [PersonWhereUniqueInput!]!): [Person] - createRole(data: RoleCreateInput!): Role - createRoles(data: [RoleCreateInput!]!): [Role] - updateRole(where: RoleWhereUniqueInput!, data: RoleUpdateInput!): Role - updateRoles(data: [RoleUpdateArgs!]!): [Role] - deleteRole(where: RoleWhereUniqueInput!): Role - deleteRoles(where: [RoleWhereUniqueInput!]!): [Role] - authenticatePersonWithPassword( - email: String! - password: String! - ): PersonAuthenticationWithPasswordResult! - createInitialPerson( - data: CreateInitialPersonInput! - ): PersonAuthenticationWithPasswordSuccess! - endSession: Boolean! -} - -union AuthenticatedItem = Person - -union PersonAuthenticationWithPasswordResult = - PersonAuthenticationWithPasswordSuccess - | PersonAuthenticationWithPasswordFailure - -type PersonAuthenticationWithPasswordSuccess { - sessionToken: String! - item: Person! -} - -type PersonAuthenticationWithPasswordFailure { - code: PasswordAuthErrorCode! - message: String! -} - -enum PasswordAuthErrorCode { - FAILURE - IDENTITY_NOT_FOUND - SECRET_NOT_SET - MULTIPLE_IDENTITY_MATCHES - SECRET_MISMATCH -} - -input CreateInitialPersonInput { - name: String - email: String - password: String -} - type Query { + authenticatedItem: AuthenticatedItem todos( where: TodoWhereInput! = {} orderBy: [TodoOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Todo!] todo(where: TodoWhereUniqueInput!): Todo @@ -367,7 +376,7 @@ type Query { people( where: PersonWhereInput! = {} orderBy: [PersonOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Person!] person(where: PersonWhereUniqueInput!): Person @@ -375,12 +384,11 @@ type Query { roles( where: RoleWhereInput! = {} orderBy: [RoleOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Role!] role(where: RoleWhereUniqueInput!): Role rolesCount(where: RoleWhereInput! = {}): Int - authenticatedItem: AuthenticatedItem keystone: KeystoneMeta! } diff --git a/examples-staging/sandbox/CHANGELOG.md b/examples-staging/sandbox/CHANGELOG.md index 6c26440d40d..e4c02593c4f 100644 --- a/examples-staging/sandbox/CHANGELOG.md +++ b/examples-staging/sandbox/CHANGELOG.md @@ -1,5 +1,14 @@ # @keystone-next/example-sandbox +## 3.0.6 + +### Patch Changes + +- Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 + - @keystone-next/auth@31.0.0 + ## 3.0.5 ### Patch Changes diff --git a/examples-staging/sandbox/package.json b/examples-staging/sandbox/package.json index faa9b468701..23899c25be7 100644 --- a/examples-staging/sandbox/package.json +++ b/examples-staging/sandbox/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/example-sandbox", - "version": "3.0.5", + "version": "3.0.6", "private": true, "license": "MIT", "scripts": { @@ -8,9 +8,9 @@ "sandbox": "yarn && yarn dev" }, "dependencies": { - "@keystone-next/auth": "^30.0.0", - "@keystone-next/fields": "^13.0.0", - "@keystone-next/keystone": "^23.0.0" + "@keystone-next/auth": "^31.0.0", + "@keystone-next/fields": "^14.0.0", + "@keystone-next/keystone": "^24.0.0" }, "engines": { "node": "^12.20 || >= 14.13" diff --git a/examples-staging/sandbox/schema.graphql b/examples-staging/sandbox/schema.graphql index 66117bc9d9a..265367bfa79 100644 --- a/examples-staging/sandbox/schema.graphql +++ b/examples-staging/sandbox/schema.graphql @@ -11,48 +11,69 @@ type Todo { input TodoWhereInput { AND: [TodoWhereInput!] OR: [TodoWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - label: String - label_not: String - label_contains: String - label_not_contains: String - label_in: [String] - label_not_in: [String] - isComplete: Boolean - isComplete_not: Boolean + NOT: [TodoWhereInput!] + id: IDFilter + label: StringNullableFilter + isComplete: BooleanNullableFilter assignedTo: UserWhereInput - assignedTo_is_null: Boolean - finishBy: String - finishBy_not: String - finishBy_lt: String - finishBy_lte: String - finishBy_gt: String - finishBy_gte: String - finishBy_in: [String] - finishBy_not_in: [String] - createdAt: String - createdAt_not: String - createdAt_lt: String - createdAt_lte: String - createdAt_gt: String - createdAt_gte: String - createdAt_in: [String] - createdAt_not_in: [String] - updatedAt: String - updatedAt_not: String - updatedAt_lt: String - updatedAt_lte: String - updatedAt_gt: String - updatedAt_gte: String - updatedAt_in: [String] - updatedAt_not_in: [String] + finishBy: DateTimeNullableFilter + createdAt: DateTimeNullableFilter + updatedAt: DateTimeNullableFilter +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input BooleanNullableFilter { + equals: Boolean + not: BooleanNullableFilter +} + +input DateTimeNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + not: DateTimeNullableFilter } input TodoWhereUniqueInput { @@ -111,7 +132,7 @@ type User { tasks( where: TodoWhereInput! = {} orderBy: [TodoOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Todo!] tasksCount(where: TodoWhereInput! = {}): Int @@ -126,46 +147,24 @@ type PasswordState { input UserWhereInput { AND: [UserWhereInput!] OR: [UserWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_in: [String] - name_not_in: [String] - email: String - email_not: String - email_contains: String - email_not_contains: String - email_in: [String] - email_not_in: [String] - password_is_set: Boolean - tasks_every: TodoWhereInput - tasks_some: TodoWhereInput - tasks_none: TodoWhereInput - createdAt: String - createdAt_not: String - createdAt_lt: String - createdAt_lte: String - createdAt_gt: String - createdAt_gte: String - createdAt_in: [String] - createdAt_not_in: [String] - updatedAt: String - updatedAt_not: String - updatedAt_lt: String - updatedAt_lte: String - updatedAt_gt: String - updatedAt_gte: String - updatedAt_in: [String] - updatedAt_not_in: [String] + NOT: [UserWhereInput!] + id: IDFilter + name: StringNullableFilter + email: StringNullableFilter + password: PasswordFilter + tasks: TodoManyRelationFilter + createdAt: DateTimeNullableFilter + updatedAt: DateTimeNullableFilter +} + +input PasswordFilter { + isSet: Boolean! +} + +input TodoManyRelationFilter { + every: TodoWhereInput + some: TodoWhereInput + none: TodoWhereInput } input UserWhereUniqueInput { @@ -238,7 +237,7 @@ type Query { todos( where: TodoWhereInput! = {} orderBy: [TodoOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Todo!] todo(where: TodoWhereUniqueInput!): Todo @@ -246,7 +245,7 @@ type Query { users( where: UserWhereInput! = {} orderBy: [UserOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [User!] user(where: UserWhereUniqueInput!): User diff --git a/examples/blog/CHANGELOG.md b/examples/blog/CHANGELOG.md index e6b48d54dff..d15f710f338 100644 --- a/examples/blog/CHANGELOG.md +++ b/examples/blog/CHANGELOG.md @@ -1,5 +1,13 @@ # @keystone-next/example-blog +## 2.0.6 + +### Patch Changes + +- Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 + ## 2.0.5 ### Patch Changes diff --git a/examples/blog/package.json b/examples/blog/package.json index 047521e8beb..d9bac9e7a8d 100644 --- a/examples/blog/package.json +++ b/examples/blog/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/example-blog", - "version": "2.0.5", + "version": "2.0.6", "private": true, "license": "MIT", "scripts": { @@ -9,8 +9,8 @@ "build": "keystone-next build" }, "dependencies": { - "@keystone-next/fields": "^13.0.0", - "@keystone-next/keystone": "^23.0.0" + "@keystone-next/fields": "^14.0.0", + "@keystone-next/keystone": "^24.0.0" }, "devDependencies": { "typescript": "^4.3.5" diff --git a/examples/blog/schema.graphql b/examples/blog/schema.graphql index 1cd125ef525..1dd72c9481f 100644 --- a/examples/blog/schema.graphql +++ b/examples/blog/schema.graphql @@ -15,40 +15,70 @@ enum PostStatusType { input PostWhereInput { AND: [PostWhereInput!] OR: [PostWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - title: String - title_not: String - title_contains: String - title_not_contains: String - title_in: [String] - title_not_in: [String] - status: PostStatusType - status_not: PostStatusType - status_in: [PostStatusType] - status_not_in: [PostStatusType] - content: String - content_not: String - content_contains: String - content_not_contains: String - content_in: [String] - content_not_in: [String] - publishDate: String - publishDate_not: String - publishDate_lt: String - publishDate_lte: String - publishDate_gt: String - publishDate_gte: String - publishDate_in: [String] - publishDate_not_in: [String] + NOT: [PostWhereInput!] + id: IDFilter + title: StringNullableFilter + status: PostStatusTypeNullableFilter + content: StringNullableFilter + publishDate: DateTimeNullableFilter author: AuthorWhereInput - author_is_null: Boolean +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input PostStatusTypeNullableFilter { + equals: PostStatusType + in: [PostStatusType!] + notIn: [PostStatusType!] + not: PostStatusTypeNullableFilter +} + +input DateTimeNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + not: DateTimeNullableFilter } input PostWhereUniqueInput { @@ -107,7 +137,7 @@ type Author { posts( where: PostWhereInput! = {} orderBy: [PostOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Post!] postsCount(where: PostWhereInput! = {}): Int @@ -116,29 +146,17 @@ type Author { input AuthorWhereInput { AND: [AuthorWhereInput!] OR: [AuthorWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_in: [String] - name_not_in: [String] - email: String - email_not: String - email_contains: String - email_not_contains: String - email_in: [String] - email_not_in: [String] - posts_every: PostWhereInput - posts_some: PostWhereInput - posts_none: PostWhereInput + NOT: [AuthorWhereInput!] + id: IDFilter + name: StringNullableFilter + email: StringNullableFilter + posts: PostManyRelationFilter +} + +input PostManyRelationFilter { + every: PostWhereInput + some: PostWhereInput + none: PostWhereInput } input AuthorWhereUniqueInput { @@ -208,7 +226,7 @@ type Query { posts( where: PostWhereInput! = {} orderBy: [PostOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Post!] post(where: PostWhereUniqueInput!): Post @@ -216,7 +234,7 @@ type Query { authors( where: AuthorWhereInput! = {} orderBy: [AuthorOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Author!] author(where: AuthorWhereUniqueInput!): Author diff --git a/examples/custom-admin-ui-logo/CHANGELOG.md b/examples/custom-admin-ui-logo/CHANGELOG.md index fc29b50ebb5..000593008f5 100644 --- a/examples/custom-admin-ui-logo/CHANGELOG.md +++ b/examples/custom-admin-ui-logo/CHANGELOG.md @@ -1,5 +1,14 @@ # @keystone-next/example-custom-admin-ui-logo +## 1.0.1 + +### Patch Changes + +- Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`8187ea019`](https://github.com/keystonejs/keystone/commit/8187ea019a212874f3c602573af3382c6f3bd3b2), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 + - @keystone-next/types@24.0.0 + ## 1.0.0 ### Major Changes diff --git a/examples/custom-admin-ui-logo/package.json b/examples/custom-admin-ui-logo/package.json index 6450ae841c8..376a249bed9 100644 --- a/examples/custom-admin-ui-logo/package.json +++ b/examples/custom-admin-ui-logo/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/example-custom-admin-ui-logo", - "version": "1.0.0", + "version": "1.0.1", "private": true, "license": "MIT", "scripts": { @@ -9,9 +9,9 @@ "build": "keystone-next build" }, "dependencies": { - "@keystone-next/fields": "^13.0.0", - "@keystone-next/keystone": "^23.0.0", - "@keystone-next/types": "^23.0.0", + "@keystone-next/fields": "^14.0.0", + "@keystone-next/keystone": "^24.0.0", + "@keystone-next/types": "^24.0.0", "@keystone-ui/core": "^3.1.0", "next": "^10.2.3", "react": "^17.0.2" diff --git a/examples/custom-admin-ui-logo/schema.graphql b/examples/custom-admin-ui-logo/schema.graphql index 49a0f225167..e194b7cb406 100644 --- a/examples/custom-admin-ui-logo/schema.graphql +++ b/examples/custom-admin-ui-logo/schema.graphql @@ -16,36 +16,75 @@ enum TaskPriorityType { input TaskWhereInput { AND: [TaskWhereInput!] OR: [TaskWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - label: String - label_not: String - label_contains: String - label_not_contains: String - label_in: [String] - label_not_in: [String] - priority: TaskPriorityType - priority_not: TaskPriorityType - priority_in: [TaskPriorityType] - priority_not_in: [TaskPriorityType] - isComplete: Boolean - isComplete_not: Boolean + NOT: [TaskWhereInput!] + id: IDFilter + label: StringNullableFilter + priority: TaskPriorityTypeNullableFilter + isComplete: BooleanNullableFilter assignedTo: PersonWhereInput - assignedTo_is_null: Boolean - finishBy: String - finishBy_not: String - finishBy_lt: String - finishBy_lte: String - finishBy_gt: String - finishBy_gte: String - finishBy_in: [String] - finishBy_not_in: [String] + finishBy: DateTimeNullableFilter +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input TaskPriorityTypeNullableFilter { + equals: TaskPriorityType + in: [TaskPriorityType!] + notIn: [TaskPriorityType!] + not: TaskPriorityTypeNullableFilter +} + +input BooleanNullableFilter { + equals: Boolean + not: BooleanNullableFilter +} + +input DateTimeNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + not: DateTimeNullableFilter } input TaskWhereUniqueInput { @@ -103,7 +142,7 @@ type Person { tasks( where: TaskWhereInput! = {} orderBy: [TaskOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Task!] tasksCount(where: TaskWhereInput! = {}): Int @@ -112,23 +151,16 @@ type Person { input PersonWhereInput { AND: [PersonWhereInput!] OR: [PersonWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_in: [String] - name_not_in: [String] - tasks_every: TaskWhereInput - tasks_some: TaskWhereInput - tasks_none: TaskWhereInput + NOT: [PersonWhereInput!] + id: IDFilter + name: StringNullableFilter + tasks: TaskManyRelationFilter +} + +input TaskManyRelationFilter { + every: TaskWhereInput + some: TaskWhereInput + none: TaskWhereInput } input PersonWhereUniqueInput { @@ -194,7 +226,7 @@ type Query { tasks( where: TaskWhereInput! = {} orderBy: [TaskOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Task!] task(where: TaskWhereUniqueInput!): Task @@ -202,7 +234,7 @@ type Query { people( where: PersonWhereInput! = {} orderBy: [PersonOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Person!] person(where: PersonWhereUniqueInput!): Person diff --git a/examples/custom-admin-ui-navigation/CHANGELOG.md b/examples/custom-admin-ui-navigation/CHANGELOG.md index 1aabc24b86e..a9d48b60e5a 100644 --- a/examples/custom-admin-ui-navigation/CHANGELOG.md +++ b/examples/custom-admin-ui-navigation/CHANGELOG.md @@ -1 +1,14 @@ # @keystone-next/example-custom-navigation-component + +## 5.0.0 + +### Major Changes + +- [#6185](https://github.com/keystonejs/keystone/pull/6185) [`bc00c0a17`](https://github.com/keystonejs/keystone/commit/bc00c0a17b41a9ef016ec41b59ac394013be916d) Thanks [@gwyneplaine](https://github.com/gwyneplaine)! - Initial version of the custom-admin-ui-navigation example. + +### Patch Changes + +- Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`8187ea019`](https://github.com/keystonejs/keystone/commit/8187ea019a212874f3c602573af3382c6f3bd3b2), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 + - @keystone-next/types@24.0.0 diff --git a/examples/custom-admin-ui-navigation/package.json b/examples/custom-admin-ui-navigation/package.json index bc9c7a10355..461c3c0d424 100644 --- a/examples/custom-admin-ui-navigation/package.json +++ b/examples/custom-admin-ui-navigation/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/example-custom-admin-ui-navigation", - "version": "4.0.4", + "version": "5.0.0", "private": true, "license": "MIT", "scripts": { @@ -9,9 +9,9 @@ "build": "keystone-next build" }, "dependencies": { - "@keystone-next/fields": "^13.0.0", - "@keystone-next/keystone": "^23.0.1", - "@keystone-next/types": "^23.0.0", + "@keystone-next/fields": "^14.0.0", + "@keystone-next/keystone": "^24.0.0", + "@keystone-next/types": "^24.0.0", "react": "^17.0.2" }, "devDependencies": { diff --git a/examples/custom-admin-ui-navigation/schema.graphql b/examples/custom-admin-ui-navigation/schema.graphql index 49a0f225167..e194b7cb406 100644 --- a/examples/custom-admin-ui-navigation/schema.graphql +++ b/examples/custom-admin-ui-navigation/schema.graphql @@ -16,36 +16,75 @@ enum TaskPriorityType { input TaskWhereInput { AND: [TaskWhereInput!] OR: [TaskWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - label: String - label_not: String - label_contains: String - label_not_contains: String - label_in: [String] - label_not_in: [String] - priority: TaskPriorityType - priority_not: TaskPriorityType - priority_in: [TaskPriorityType] - priority_not_in: [TaskPriorityType] - isComplete: Boolean - isComplete_not: Boolean + NOT: [TaskWhereInput!] + id: IDFilter + label: StringNullableFilter + priority: TaskPriorityTypeNullableFilter + isComplete: BooleanNullableFilter assignedTo: PersonWhereInput - assignedTo_is_null: Boolean - finishBy: String - finishBy_not: String - finishBy_lt: String - finishBy_lte: String - finishBy_gt: String - finishBy_gte: String - finishBy_in: [String] - finishBy_not_in: [String] + finishBy: DateTimeNullableFilter +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input TaskPriorityTypeNullableFilter { + equals: TaskPriorityType + in: [TaskPriorityType!] + notIn: [TaskPriorityType!] + not: TaskPriorityTypeNullableFilter +} + +input BooleanNullableFilter { + equals: Boolean + not: BooleanNullableFilter +} + +input DateTimeNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + not: DateTimeNullableFilter } input TaskWhereUniqueInput { @@ -103,7 +142,7 @@ type Person { tasks( where: TaskWhereInput! = {} orderBy: [TaskOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Task!] tasksCount(where: TaskWhereInput! = {}): Int @@ -112,23 +151,16 @@ type Person { input PersonWhereInput { AND: [PersonWhereInput!] OR: [PersonWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_in: [String] - name_not_in: [String] - tasks_every: TaskWhereInput - tasks_some: TaskWhereInput - tasks_none: TaskWhereInput + NOT: [PersonWhereInput!] + id: IDFilter + name: StringNullableFilter + tasks: TaskManyRelationFilter +} + +input TaskManyRelationFilter { + every: TaskWhereInput + some: TaskWhereInput + none: TaskWhereInput } input PersonWhereUniqueInput { @@ -194,7 +226,7 @@ type Query { tasks( where: TaskWhereInput! = {} orderBy: [TaskOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Task!] task(where: TaskWhereUniqueInput!): Task @@ -202,7 +234,7 @@ type Query { people( where: PersonWhereInput! = {} orderBy: [PersonOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Person!] person(where: PersonWhereUniqueInput!): Person diff --git a/examples/custom-admin-ui-pages/CHANGELOG.md b/examples/custom-admin-ui-pages/CHANGELOG.md index 88b4c31f841..68e1f42b5a0 100644 --- a/examples/custom-admin-ui-pages/CHANGELOG.md +++ b/examples/custom-admin-ui-pages/CHANGELOG.md @@ -1 +1,16 @@ # @keystone-next/example-custom-admin-ui-pages + +## 1.0.0 + +### Major Changes + +- [#6082](https://github.com/keystonejs/keystone/pull/6082) [`e0b9e8d38`](https://github.com/keystonejs/keystone/commit/e0b9e8d38b0d531bcc921f05435bd1985b47781a) Thanks [@gwyneplaine](https://github.com/gwyneplaine)! - Initial version of the custom-admin-ui-pages example. + +### Patch Changes + +- [#6264](https://github.com/keystonejs/keystone/pull/6264) [`df10c42a2`](https://github.com/keystonejs/keystone/commit/df10c42a2c4fb4d48060b118de3111fd14cdc412) Thanks [@gwyneplaine](https://github.com/gwyneplaine)! - Additional content added to example for making the custom-page look more like the Admin UI, as well as adding a route to the custom page to the Admin UI Navigation. + +- Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`8187ea019`](https://github.com/keystonejs/keystone/commit/8187ea019a212874f3c602573af3382c6f3bd3b2), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 + - @keystone-next/types@24.0.0 diff --git a/examples/custom-admin-ui-pages/README.md b/examples/custom-admin-ui-pages/README.md index 37622aac6b1..59b084aba29 100644 --- a/examples/custom-admin-ui-pages/README.md +++ b/examples/custom-admin-ui-pages/README.md @@ -19,10 +19,44 @@ You can also access a GraphQL Playground at [localhost:3000/api/graphql](http:// 🚀 Congratulations, you're now up and running with Keystone! -## admin/pages +## /admin/pages -This project leverages the `/admin/pages` directory. As elaborated on in the [Custom Pages](https://keystonejs.com/docs/guides/custom-admin-ui-pages) guide, this directory is used to generate additional routes in the Admin UI, a behaviour inherited from `Next.js`. The default export of files in this directory are expected to be **React Components**. +This project leverages the `/admin/pages` directory. As elaborated on in the [Custom Pages](https://keystonejs.com/docs/guides/custom-admin-ui-pages) guide, this directory is used to generate additional pages in the Admin UI, a behaviour inherited from `Next.js`. The default export of files in this directory are expected to be **React Components**. **All other exports are ignored** -**NOTE** The Keystone monorepo leverages a babel config that means we use the old jsx transform (this doesn't have an impact on the code we ship to npm). -This is why there are `import React from 'react'` statements in our examples, this is NOT necessary outside of the Keystone repo (unless you have a babel config with the old jsx transform which is currently the default with @babel/preset-react) as you'll be using Next's babel config which uses the new jsx transform. +**NOTE**: The Keystone monorepo leverages a babel config that means we use the old jsx transform (this doesn't have an impact on the code we ship to npm). +This is why there are `import React from 'react'` statements in our examples, this is NOT necessary outside of the Keystone repo (unless you have a babel config with the old jsx transform which is currently the default with `@babel/preset-react`) as you'll be using Next's babel config which uses the new jsx transform. + +## Custom Navigation + +In order to ensure that the new page is visible and navigable within the Admin UI, this example also adds a custom Navigation component with the +route to the custom page included. For much more detail on adding custom navigation, please see the Custom Admin UI Navigation [guide](https://keystonejs.com/docs/guides/custom-admin-ui-navigation) and [example](../custom-admin-ui-navigation). + +## Layout components + +In order to help us build custom pages that _look_ and _feel_ like part of the Admin UI, Keystone exports the `PageContainer` component from +the `@keystone-next/keystone/admin-ui/components` package. + +### PageContainer + +PageContainer has the following types: + +```typescript +type PageContainerProps = { + header: ReactElement; + children: ReactNode; +}; +``` + +To match the header style applied to all Admin UI standard pages, we use the `Heading` component from `@keystone-ui/core` as an `h3` element. + +```tsx +import { PageContainer } from '@keystone-next/keystone/admin-ui/component'; +import { Heading } from '@keystone-ui/core'; + +export default () => { + return ( + Custom Page}>{/* ... */} + ); +}; +``` diff --git a/examples/custom-admin-ui-pages/admin/components/CustomNavigation.tsx b/examples/custom-admin-ui-pages/admin/components/CustomNavigation.tsx new file mode 100644 index 00000000000..4c30c4d376a --- /dev/null +++ b/examples/custom-admin-ui-pages/admin/components/CustomNavigation.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import { + NavItem, + ListNavItems, + NavigationContainer, +} from '@keystone-next/keystone/admin-ui/components'; +import type { NavigationProps } from '@keystone-next/keystone/admin-ui/components'; + +export function CustomNavigation({ lists, authenticatedItem }: NavigationProps) { + return ( + + Dashboard + + Custom Page + + ); +} diff --git a/examples/custom-admin-ui-pages/admin/config.ts b/examples/custom-admin-ui-pages/admin/config.ts new file mode 100644 index 00000000000..12e80c22bb2 --- /dev/null +++ b/examples/custom-admin-ui-pages/admin/config.ts @@ -0,0 +1,5 @@ +import type { AdminConfig } from '@keystone-next/types'; +import { CustomNavigation } from './components/CustomNavigation'; +export const components: AdminConfig['components'] = { + Navigation: CustomNavigation, +}; diff --git a/examples/custom-admin-ui-pages/admin/pages/custom-page.tsx b/examples/custom-admin-ui-pages/admin/pages/custom-page.tsx index f109f136375..4e14dbb36cf 100644 --- a/examples/custom-admin-ui-pages/admin/pages/custom-page.tsx +++ b/examples/custom-admin-ui-pages/admin/pages/custom-page.tsx @@ -1,34 +1,27 @@ /** @jsx jsx */ -import { Fragment } from 'react'; -import { jsx } from '@keystone-ui/core'; +import { PageContainer } from '@keystone-next/keystone/admin-ui/components'; +import { jsx, Heading } from '@keystone-ui/core'; // Please note that while this capability is driven by Next.js's pages directory // We do not currently support any of the auxillary methods that Next.js provides i.e. `getStaticProps` // Presently the only export from the directory that is supported is the page component itself. export default function CustomPage() { return ( - -
Custom Page}> +

-

- Hello this is a custom page -

-

- This is a custom page added to the Admin UI, leveraging @keystone-ui/core -

-
-
+ This is a custom Admin UI Page + +

+ It can be accessed via the route /custom-page +

+ ); } diff --git a/examples/custom-admin-ui-pages/package.json b/examples/custom-admin-ui-pages/package.json index 574a7a771e8..c89af45ea77 100644 --- a/examples/custom-admin-ui-pages/package.json +++ b/examples/custom-admin-ui-pages/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/example-custom-admin-ui-pages", - "version": "0.0.1", + "version": "1.0.0", "private": true, "license": "MIT", "scripts": { @@ -9,11 +9,10 @@ "build": "keystone-next build" }, "dependencies": { - "@keystone-next/fields": "^13.0.0", - "@keystone-next/keystone": "^23.0.0", - "@keystone-next/types": "^23.0.0", + "@keystone-next/fields": "^14.0.0", + "@keystone-next/keystone": "^24.0.0", + "@keystone-next/types": "^24.0.0", "@keystone-ui/core": "^3.1.0", - "next": "^10.2.3", "react": "^17.0.2" }, "devDependencies": { diff --git a/examples/custom-admin-ui-pages/schema.graphql b/examples/custom-admin-ui-pages/schema.graphql index 49a0f225167..e194b7cb406 100644 --- a/examples/custom-admin-ui-pages/schema.graphql +++ b/examples/custom-admin-ui-pages/schema.graphql @@ -16,36 +16,75 @@ enum TaskPriorityType { input TaskWhereInput { AND: [TaskWhereInput!] OR: [TaskWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - label: String - label_not: String - label_contains: String - label_not_contains: String - label_in: [String] - label_not_in: [String] - priority: TaskPriorityType - priority_not: TaskPriorityType - priority_in: [TaskPriorityType] - priority_not_in: [TaskPriorityType] - isComplete: Boolean - isComplete_not: Boolean + NOT: [TaskWhereInput!] + id: IDFilter + label: StringNullableFilter + priority: TaskPriorityTypeNullableFilter + isComplete: BooleanNullableFilter assignedTo: PersonWhereInput - assignedTo_is_null: Boolean - finishBy: String - finishBy_not: String - finishBy_lt: String - finishBy_lte: String - finishBy_gt: String - finishBy_gte: String - finishBy_in: [String] - finishBy_not_in: [String] + finishBy: DateTimeNullableFilter +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input TaskPriorityTypeNullableFilter { + equals: TaskPriorityType + in: [TaskPriorityType!] + notIn: [TaskPriorityType!] + not: TaskPriorityTypeNullableFilter +} + +input BooleanNullableFilter { + equals: Boolean + not: BooleanNullableFilter +} + +input DateTimeNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + not: DateTimeNullableFilter } input TaskWhereUniqueInput { @@ -103,7 +142,7 @@ type Person { tasks( where: TaskWhereInput! = {} orderBy: [TaskOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Task!] tasksCount(where: TaskWhereInput! = {}): Int @@ -112,23 +151,16 @@ type Person { input PersonWhereInput { AND: [PersonWhereInput!] OR: [PersonWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_in: [String] - name_not_in: [String] - tasks_every: TaskWhereInput - tasks_some: TaskWhereInput - tasks_none: TaskWhereInput + NOT: [PersonWhereInput!] + id: IDFilter + name: StringNullableFilter + tasks: TaskManyRelationFilter +} + +input TaskManyRelationFilter { + every: TaskWhereInput + some: TaskWhereInput + none: TaskWhereInput } input PersonWhereUniqueInput { @@ -194,7 +226,7 @@ type Query { tasks( where: TaskWhereInput! = {} orderBy: [TaskOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Task!] task(where: TaskWhereUniqueInput!): Task @@ -202,7 +234,7 @@ type Query { people( where: PersonWhereInput! = {} orderBy: [PersonOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Person!] person(where: PersonWhereUniqueInput!): Person diff --git a/examples/custom-field-view/CHANGELOG.md b/examples/custom-field-view/CHANGELOG.md index 23caa3ea685..372a08a14be 100644 --- a/examples/custom-field-view/CHANGELOG.md +++ b/examples/custom-field-view/CHANGELOG.md @@ -1,5 +1,14 @@ # @keystone-next/example-custom-field-view +## 1.0.2 + +### Patch Changes + +- Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`8187ea019`](https://github.com/keystonejs/keystone/commit/8187ea019a212874f3c602573af3382c6f3bd3b2), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 + - @keystone-next/types@24.0.0 + ## 1.0.1 ### Patch Changes diff --git a/examples/custom-field-view/package.json b/examples/custom-field-view/package.json index c2882d1aa7d..cdf9cf19396 100644 --- a/examples/custom-field-view/package.json +++ b/examples/custom-field-view/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/example-custom-field-view", - "version": "1.0.1", + "version": "1.0.2", "private": true, "license": "MIT", "scripts": { @@ -10,9 +10,9 @@ }, "dependencies": { "@emotion/css": "^11.1.3", - "@keystone-next/fields": "^13.0.0", - "@keystone-next/keystone": "^23.0.0", - "@keystone-next/types": "^23.0.0", + "@keystone-next/fields": "^14.0.0", + "@keystone-next/keystone": "^24.0.0", + "@keystone-next/types": "^24.0.0", "@keystone-ui/button": "^5.0.0", "@keystone-ui/core": "^3.1.1", "@keystone-ui/fields": "^4.1.2", diff --git a/examples/custom-field-view/schema.graphql b/examples/custom-field-view/schema.graphql index 049042c59fb..8f3770570e0 100644 --- a/examples/custom-field-view/schema.graphql +++ b/examples/custom-field-view/schema.graphql @@ -17,36 +17,75 @@ enum TaskPriorityType { input TaskWhereInput { AND: [TaskWhereInput!] OR: [TaskWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - label: String - label_not: String - label_contains: String - label_not_contains: String - label_in: [String] - label_not_in: [String] - priority: TaskPriorityType - priority_not: TaskPriorityType - priority_in: [TaskPriorityType] - priority_not_in: [TaskPriorityType] - isComplete: Boolean - isComplete_not: Boolean + NOT: [TaskWhereInput!] + id: IDFilter + label: StringNullableFilter + priority: TaskPriorityTypeNullableFilter + isComplete: BooleanNullableFilter assignedTo: PersonWhereInput - assignedTo_is_null: Boolean - finishBy: String - finishBy_not: String - finishBy_lt: String - finishBy_lte: String - finishBy_gt: String - finishBy_gte: String - finishBy_in: [String] - finishBy_not_in: [String] + finishBy: DateTimeNullableFilter +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input TaskPriorityTypeNullableFilter { + equals: TaskPriorityType + in: [TaskPriorityType!] + notIn: [TaskPriorityType!] + not: TaskPriorityTypeNullableFilter +} + +input BooleanNullableFilter { + equals: Boolean + not: BooleanNullableFilter +} + +input DateTimeNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + not: DateTimeNullableFilter } input TaskWhereUniqueInput { @@ -106,7 +145,7 @@ type Person { tasks( where: TaskWhereInput! = {} orderBy: [TaskOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Task!] tasksCount(where: TaskWhereInput! = {}): Int @@ -115,23 +154,16 @@ type Person { input PersonWhereInput { AND: [PersonWhereInput!] OR: [PersonWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_in: [String] - name_not_in: [String] - tasks_every: TaskWhereInput - tasks_some: TaskWhereInput - tasks_none: TaskWhereInput + NOT: [PersonWhereInput!] + id: IDFilter + name: StringNullableFilter + tasks: TaskManyRelationFilter +} + +input TaskManyRelationFilter { + every: TaskWhereInput + some: TaskWhereInput + none: TaskWhereInput } input PersonWhereUniqueInput { @@ -197,7 +229,7 @@ type Query { tasks( where: TaskWhereInput! = {} orderBy: [TaskOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Task!] task(where: TaskWhereUniqueInput!): Task @@ -205,7 +237,7 @@ type Query { people( where: PersonWhereInput! = {} orderBy: [PersonOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Person!] person(where: PersonWhereUniqueInput!): Person diff --git a/examples/custom-field/CHANGELOG.md b/examples/custom-field/CHANGELOG.md index a5efaa3027f..5e7867dc6a5 100644 --- a/examples/custom-field/CHANGELOG.md +++ b/examples/custom-field/CHANGELOG.md @@ -1,5 +1,14 @@ # @keystone-next/example-custom-field +## 0.0.3 + +### Patch Changes + +- Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`8187ea019`](https://github.com/keystonejs/keystone/commit/8187ea019a212874f3c602573af3382c6f3bd3b2), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 + - @keystone-next/types@24.0.0 + ## 0.0.2 ### Patch Changes diff --git a/examples/custom-field/package.json b/examples/custom-field/package.json index 79513877337..b8e4b695650 100644 --- a/examples/custom-field/package.json +++ b/examples/custom-field/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/example-custom-field", - "version": "0.0.2", + "version": "0.0.3", "private": true, "license": "MIT", "scripts": { @@ -9,9 +9,9 @@ "build": "keystone-next build" }, "dependencies": { - "@keystone-next/fields": "^13.0.0", - "@keystone-next/keystone": "^23.0.0", - "@keystone-next/types": "^23.0.0", + "@keystone-next/fields": "^14.0.0", + "@keystone-next/keystone": "^24.0.0", + "@keystone-next/types": "^24.0.0", "@keystone-ui/fields": "^4.1.2", "react": "^17.0.2" }, diff --git a/examples/custom-field/schema.graphql b/examples/custom-field/schema.graphql index bce900c79cd..9a94c244dfd 100644 --- a/examples/custom-field/schema.graphql +++ b/examples/custom-field/schema.graphql @@ -16,48 +16,70 @@ enum PostStatusType { input PostWhereInput { AND: [PostWhereInput!] OR: [PostWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - title: String - title_not: String - title_contains: String - title_not_contains: String - title_in: [String] - title_not_in: [String] - status: PostStatusType - status_not: PostStatusType - status_in: [PostStatusType] - status_not_in: [PostStatusType] - content: String - content_not: String - content_contains: String - content_not_contains: String - content_in: [String] - content_not_in: [String] - rating: Int - rating_not: Int - rating_lt: Int - rating_lte: Int - rating_gt: Int - rating_gte: Int - rating_in: [Int] - rating_not_in: [Int] - publishDate: String - publishDate_not: String - publishDate_lt: String - publishDate_lte: String - publishDate_gt: String - publishDate_gte: String - publishDate_in: [String] - publishDate_not_in: [String] + NOT: [PostWhereInput!] + id: IDFilter + title: StringNullableFilter + status: PostStatusTypeNullableFilter + content: StringNullableFilter + publishDate: DateTimeNullableFilter author: AuthorWhereInput - author_is_null: Boolean +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input PostStatusTypeNullableFilter { + equals: PostStatusType + in: [PostStatusType!] + notIn: [PostStatusType!] + not: PostStatusTypeNullableFilter +} + +input DateTimeNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + not: DateTimeNullableFilter } input PostWhereUniqueInput { @@ -119,7 +141,7 @@ type Author { posts( where: PostWhereInput! = {} orderBy: [PostOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Post!] postsCount(where: PostWhereInput! = {}): Int @@ -128,29 +150,17 @@ type Author { input AuthorWhereInput { AND: [AuthorWhereInput!] OR: [AuthorWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_in: [String] - name_not_in: [String] - email: String - email_not: String - email_contains: String - email_not_contains: String - email_in: [String] - email_not_in: [String] - posts_every: PostWhereInput - posts_some: PostWhereInput - posts_none: PostWhereInput + NOT: [AuthorWhereInput!] + id: IDFilter + name: StringNullableFilter + email: StringNullableFilter + posts: PostManyRelationFilter +} + +input PostManyRelationFilter { + every: PostWhereInput + some: PostWhereInput + none: PostWhereInput } input AuthorWhereUniqueInput { @@ -220,7 +230,7 @@ type Query { posts( where: PostWhereInput! = {} orderBy: [PostOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Post!] post(where: PostWhereUniqueInput!): Post @@ -228,7 +238,7 @@ type Query { authors( where: AuthorWhereInput! = {} orderBy: [AuthorOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Author!] author(where: AuthorWhereUniqueInput!): Author diff --git a/examples/default-values/CHANGELOG.md b/examples/default-values/CHANGELOG.md index 28487e9dc40..40fe398fb9a 100644 --- a/examples/default-values/CHANGELOG.md +++ b/examples/default-values/CHANGELOG.md @@ -1,5 +1,13 @@ # @keystone-next/example-default-values +## 1.0.6 + +### Patch Changes + +- Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 + ## 1.0.5 ### Patch Changes diff --git a/examples/default-values/package.json b/examples/default-values/package.json index 608ca218f02..af3ba2e7b19 100644 --- a/examples/default-values/package.json +++ b/examples/default-values/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/example-default-values", - "version": "1.0.5", + "version": "1.0.6", "private": true, "license": "MIT", "scripts": { @@ -9,8 +9,8 @@ "build": "keystone-next build" }, "dependencies": { - "@keystone-next/fields": "^13.0.0", - "@keystone-next/keystone": "^23.0.0" + "@keystone-next/fields": "^14.0.0", + "@keystone-next/keystone": "^24.0.0" }, "devDependencies": { "typescript": "^4.3.5" diff --git a/examples/default-values/schema.graphql b/examples/default-values/schema.graphql index 49a0f225167..e194b7cb406 100644 --- a/examples/default-values/schema.graphql +++ b/examples/default-values/schema.graphql @@ -16,36 +16,75 @@ enum TaskPriorityType { input TaskWhereInput { AND: [TaskWhereInput!] OR: [TaskWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - label: String - label_not: String - label_contains: String - label_not_contains: String - label_in: [String] - label_not_in: [String] - priority: TaskPriorityType - priority_not: TaskPriorityType - priority_in: [TaskPriorityType] - priority_not_in: [TaskPriorityType] - isComplete: Boolean - isComplete_not: Boolean + NOT: [TaskWhereInput!] + id: IDFilter + label: StringNullableFilter + priority: TaskPriorityTypeNullableFilter + isComplete: BooleanNullableFilter assignedTo: PersonWhereInput - assignedTo_is_null: Boolean - finishBy: String - finishBy_not: String - finishBy_lt: String - finishBy_lte: String - finishBy_gt: String - finishBy_gte: String - finishBy_in: [String] - finishBy_not_in: [String] + finishBy: DateTimeNullableFilter +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input TaskPriorityTypeNullableFilter { + equals: TaskPriorityType + in: [TaskPriorityType!] + notIn: [TaskPriorityType!] + not: TaskPriorityTypeNullableFilter +} + +input BooleanNullableFilter { + equals: Boolean + not: BooleanNullableFilter +} + +input DateTimeNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + not: DateTimeNullableFilter } input TaskWhereUniqueInput { @@ -103,7 +142,7 @@ type Person { tasks( where: TaskWhereInput! = {} orderBy: [TaskOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Task!] tasksCount(where: TaskWhereInput! = {}): Int @@ -112,23 +151,16 @@ type Person { input PersonWhereInput { AND: [PersonWhereInput!] OR: [PersonWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_in: [String] - name_not_in: [String] - tasks_every: TaskWhereInput - tasks_some: TaskWhereInput - tasks_none: TaskWhereInput + NOT: [PersonWhereInput!] + id: IDFilter + name: StringNullableFilter + tasks: TaskManyRelationFilter +} + +input TaskManyRelationFilter { + every: TaskWhereInput + some: TaskWhereInput + none: TaskWhereInput } input PersonWhereUniqueInput { @@ -194,7 +226,7 @@ type Query { tasks( where: TaskWhereInput! = {} orderBy: [TaskOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Task!] task(where: TaskWhereUniqueInput!): Task @@ -202,7 +234,7 @@ type Query { people( where: PersonWhereInput! = {} orderBy: [PersonOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Person!] person(where: PersonWhereUniqueInput!): Person diff --git a/examples/default-values/schema.ts b/examples/default-values/schema.ts index f3f71a39b9e..945e8f259f5 100644 --- a/examples/default-values/schema.ts +++ b/examples/default-values/schema.ts @@ -30,7 +30,7 @@ export const lists = createSchema({ // Dynamic default: Find an anonymous user and assign the task to them defaultValue: async ({ context }) => { const anonymous = await context.lists.Person.findMany({ - where: { name: 'Anonymous' }, + where: { name: { equals: 'Anonymous' } }, }); if (anonymous.length > 0) { return { connect: { id: anonymous[0].id } }; diff --git a/examples/document-field/CHANGELOG.md b/examples/document-field/CHANGELOG.md index 52ab3591275..894c979f97a 100644 --- a/examples/document-field/CHANGELOG.md +++ b/examples/document-field/CHANGELOG.md @@ -1,5 +1,14 @@ # @keystone-next/example-document-field +## 1.1.2 + +### Patch Changes + +- Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`e985aa010`](https://github.com/keystonejs/keystone/commit/e985aa0104d30a779f21ec05d80e6b98ece87dfb), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`69f47bfed`](https://github.com/keystonejs/keystone/commit/69f47bfed1eaa1269cfdc42071268a914bd4aa17), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 + - @keystone-next/fields-document@8.0.0 + ## 1.1.1 ### Patch Changes diff --git a/examples/document-field/package.json b/examples/document-field/package.json index e9684469656..03ffa30eeb0 100644 --- a/examples/document-field/package.json +++ b/examples/document-field/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/example-document-field", - "version": "1.1.1", + "version": "1.1.2", "private": true, "license": "MIT", "scripts": { @@ -11,9 +11,9 @@ }, "dependencies": { "@keystone-next/document-renderer": "^4.0.0", - "@keystone-next/fields": "^13.0.0", - "@keystone-next/fields-document": "^7.0.3", - "@keystone-next/keystone": "^23.0.0", + "@keystone-next/fields": "^14.0.0", + "@keystone-next/fields-document": "^8.0.0", + "@keystone-next/keystone": "^24.0.0", "@preconstruct/next": "^3.0.0", "next": "^10.2.3", "react": "^17.0.2" diff --git a/examples/document-field/schema.graphql b/examples/document-field/schema.graphql index 0c1e7ab5741..af2cccf7c54 100644 --- a/examples/document-field/schema.graphql +++ b/examples/document-field/schema.graphql @@ -20,40 +20,70 @@ type Post_content_DocumentField { input PostWhereInput { AND: [PostWhereInput!] OR: [PostWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - title: String - title_not: String - title_contains: String - title_not_contains: String - title_in: [String] - title_not_in: [String] - slug: String - slug_not: String - slug_contains: String - slug_not_contains: String - slug_in: [String] - slug_not_in: [String] - status: PostStatusType - status_not: PostStatusType - status_in: [PostStatusType] - status_not_in: [PostStatusType] - publishDate: String - publishDate_not: String - publishDate_lt: String - publishDate_lte: String - publishDate_gt: String - publishDate_gte: String - publishDate_in: [String] - publishDate_not_in: [String] + NOT: [PostWhereInput!] + id: IDFilter + title: StringNullableFilter + slug: StringNullableFilter + status: PostStatusTypeNullableFilter + publishDate: DateTimeNullableFilter author: AuthorWhereInput - author_is_null: Boolean +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input PostStatusTypeNullableFilter { + equals: PostStatusType + in: [PostStatusType!] + notIn: [PostStatusType!] + not: PostStatusTypeNullableFilter +} + +input DateTimeNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + not: DateTimeNullableFilter } input PostWhereUniqueInput { @@ -115,7 +145,7 @@ type Author { posts( where: PostWhereInput! = {} orderBy: [PostOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Post!] postsCount(where: PostWhereInput! = {}): Int @@ -129,29 +159,17 @@ type Author_bio_DocumentField { input AuthorWhereInput { AND: [AuthorWhereInput!] OR: [AuthorWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_in: [String] - name_not_in: [String] - email: String - email_not: String - email_contains: String - email_not_contains: String - email_in: [String] - email_not_in: [String] - posts_every: PostWhereInput - posts_some: PostWhereInput - posts_none: PostWhereInput + NOT: [AuthorWhereInput!] + id: IDFilter + name: StringNullableFilter + email: StringNullableFilter + posts: PostManyRelationFilter +} + +input PostManyRelationFilter { + every: PostWhereInput + some: PostWhereInput + none: PostWhereInput } input AuthorWhereUniqueInput { @@ -223,7 +241,7 @@ type Query { posts( where: PostWhereInput! = {} orderBy: [PostOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Post!] post(where: PostWhereUniqueInput!): Post @@ -231,7 +249,7 @@ type Query { authors( where: AuthorWhereInput! = {} orderBy: [AuthorOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Author!] author(where: AuthorWhereUniqueInput!): Author diff --git a/examples/extend-graphql-schema/CHANGELOG.md b/examples/extend-graphql-schema/CHANGELOG.md index 24c56f59629..0982ae9ed25 100644 --- a/examples/extend-graphql-schema/CHANGELOG.md +++ b/examples/extend-graphql-schema/CHANGELOG.md @@ -1,5 +1,15 @@ # @keystone-next/example-extend-graphql-schema +## 1.0.6 + +### Patch Changes + +- [#6310](https://github.com/keystonejs/keystone/pull/6310) [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053) Thanks [@timleslie](https://github.com/timleslie)! - Updated dependencies to use `mergeSchemas` from `@graphql-tools/schema`, rather than its old location in `@graphql-tools/merge`. You might see a reordering of the contents of your `graphql.schema` file. + +- Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 + ## 1.0.5 ### Patch Changes diff --git a/examples/extend-graphql-schema/README.md b/examples/extend-graphql-schema/README.md index 82ffce5897d..5047e37b0d4 100644 --- a/examples/extend-graphql-schema/README.md +++ b/examples/extend-graphql-schema/README.md @@ -105,7 +105,7 @@ We add a custom type to our schema using `type Statisics` in the `typeDefs`, and }); const { posts } = await context.lists.Author.findOne({ where: { id }, - query: 'posts(first: 1, orderBy: { publishDate: desc }) { id }', + query: 'posts(take: 1, orderBy: { publishDate: desc }) { id }', }); return { draft, published, latestPostId: posts ? posts[0].id : null }; }, diff --git a/examples/extend-graphql-schema/custom-schema.ts b/examples/extend-graphql-schema/custom-schema.ts index 42a9f9482f1..b29ddd7c49a 100644 --- a/examples/extend-graphql-schema/custom-schema.ts +++ b/examples/extend-graphql-schema/custom-schema.ts @@ -47,19 +47,19 @@ export const extendGraphqlSchema = graphQLSchemaExtension({ // If you accidentally use `context.lists.Post` here you can expect problems // when accessing the fields in your GraphQL client. return context.db.lists.Post.findMany({ - where: { author: { id }, publishDate_gt: cutoff }, + where: { author: { id: { equals: id } }, publishDate: { gt: cutoff } }, }); }, stats: async (root, { id }, context) => { const draft = await context.lists.Post.count({ - where: { author: { id }, status: 'draft' }, + where: { author: { id: { equals: id } }, status: { equals: 'draft' } }, }); const published = await context.lists.Post.count({ - where: { author: { id }, status: 'published' }, + where: { author: { id: { equals: id } }, status: { equals: 'published' } }, }); const { posts } = await context.lists.Author.findOne({ where: { id }, - query: 'posts(first: 1, orderBy: { publishDate: desc }) { id }', + query: 'posts(take: 1, orderBy: { publishDate: desc }) { id }', }); return { draft, published, latestPostId: posts ? posts[0].id : null }; }, diff --git a/examples/extend-graphql-schema/package.json b/examples/extend-graphql-schema/package.json index de95d078b43..e6dd1fab575 100644 --- a/examples/extend-graphql-schema/package.json +++ b/examples/extend-graphql-schema/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/example-extend-graphql-schema", - "version": "1.0.5", + "version": "1.0.6", "private": true, "license": "MIT", "scripts": { @@ -9,8 +9,8 @@ "build": "keystone-next build" }, "dependencies": { - "@keystone-next/fields": "^13.0.0", - "@keystone-next/keystone": "^23.0.0" + "@keystone-next/fields": "^14.0.0", + "@keystone-next/keystone": "^24.0.0" }, "devDependencies": { "typescript": "^4.3.5" diff --git a/examples/extend-graphql-schema/schema.graphql b/examples/extend-graphql-schema/schema.graphql index 65fa2e55582..5268dc2c516 100644 --- a/examples/extend-graphql-schema/schema.graphql +++ b/examples/extend-graphql-schema/schema.graphql @@ -1,3 +1,31 @@ +type Mutation { + """ + Publish a post + """ + publishPost(id: ID!): Post + createPost(data: PostCreateInput!): Post + createPosts(data: [PostCreateInput!]!): [Post] + updatePost(where: PostWhereUniqueInput!, data: PostUpdateInput!): Post + updatePosts(data: [PostUpdateArgs!]!): [Post] + deletePost(where: PostWhereUniqueInput!): Post + deletePosts(where: [PostWhereUniqueInput!]!): [Post] + createAuthor(data: AuthorCreateInput!): Author + createAuthors(data: [AuthorCreateInput!]!): [Author] + updateAuthor(where: AuthorWhereUniqueInput!, data: AuthorUpdateInput!): Author + updateAuthors(data: [AuthorUpdateArgs!]!): [Author] + deleteAuthor(where: AuthorWhereUniqueInput!): Author + deleteAuthors(where: [AuthorWhereUniqueInput!]!): [Author] +} + +""" + A custom type to represent statistics for a user +""" +type Statistics { + draft: Int + published: Int + latest: Post +} + type Post { id: ID! title: String @@ -15,40 +43,70 @@ enum PostStatusType { input PostWhereInput { AND: [PostWhereInput!] OR: [PostWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - title: String - title_not: String - title_contains: String - title_not_contains: String - title_in: [String] - title_not_in: [String] - status: PostStatusType - status_not: PostStatusType - status_in: [PostStatusType] - status_not_in: [PostStatusType] - content: String - content_not: String - content_contains: String - content_not_contains: String - content_in: [String] - content_not_in: [String] - publishDate: String - publishDate_not: String - publishDate_lt: String - publishDate_lte: String - publishDate_gt: String - publishDate_gte: String - publishDate_in: [String] - publishDate_not_in: [String] + NOT: [PostWhereInput!] + id: IDFilter + title: StringNullableFilter + status: PostStatusTypeNullableFilter + content: StringNullableFilter + publishDate: DateTimeNullableFilter author: AuthorWhereInput - author_is_null: Boolean +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input PostStatusTypeNullableFilter { + equals: PostStatusType + in: [PostStatusType!] + notIn: [PostStatusType!] + not: PostStatusTypeNullableFilter +} + +input DateTimeNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + not: DateTimeNullableFilter } input PostWhereUniqueInput { @@ -107,7 +165,7 @@ type Author { posts( where: PostWhereInput! = {} orderBy: [PostOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Post!] postsCount(where: PostWhereInput! = {}): Int @@ -116,29 +174,17 @@ type Author { input AuthorWhereInput { AND: [AuthorWhereInput!] OR: [AuthorWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_in: [String] - name_not_in: [String] - email: String - email_not: String - email_contains: String - email_not_contains: String - email_in: [String] - email_not_in: [String] - posts_every: PostWhereInput - posts_some: PostWhereInput - posts_none: PostWhereInput + NOT: [AuthorWhereInput!] + id: IDFilter + name: StringNullableFilter + email: StringNullableFilter + posts: PostManyRelationFilter +} + +input PostManyRelationFilter { + every: PostWhereInput + some: PostWhereInput + none: PostWhereInput } input AuthorWhereUniqueInput { @@ -189,40 +235,20 @@ scalar JSON url: "http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf" ) -type Mutation { - createPost(data: PostCreateInput!): Post - createPosts(data: [PostCreateInput!]!): [Post] - updatePost(where: PostWhereUniqueInput!, data: PostUpdateInput!): Post - updatePosts(data: [PostUpdateArgs!]!): [Post] - deletePost(where: PostWhereUniqueInput!): Post - deletePosts(where: [PostWhereUniqueInput!]!): [Post] - createAuthor(data: AuthorCreateInput!): Author - createAuthors(data: [AuthorCreateInput!]!): [Author] - updateAuthor(where: AuthorWhereUniqueInput!, data: AuthorUpdateInput!): Author - updateAuthors(data: [AuthorUpdateArgs!]!): [Author] - deleteAuthor(where: AuthorWhereUniqueInput!): Author - deleteAuthors(where: [AuthorWhereUniqueInput!]!): [Author] - +type Query { """ - Publish a post + Return all posts for a user from the last days """ - publishPost(id: ID!): Post -} - -""" - A custom type to represent statistics for a user -""" -type Statistics { - draft: Int - published: Int - latest: Post -} + recentPosts(id: ID!, days: Int! = 7): [Post] -type Query { + """ + Compute statistics for a user + """ + stats(id: ID!): Statistics posts( where: PostWhereInput! = {} orderBy: [PostOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Post!] post(where: PostWhereUniqueInput!): Post @@ -230,21 +256,11 @@ type Query { authors( where: AuthorWhereInput! = {} orderBy: [AuthorOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Author!] author(where: AuthorWhereUniqueInput!): Author authorsCount(where: AuthorWhereInput! = {}): Int - - """ - Return all posts for a user from the last days - """ - recentPosts(id: ID!, days: Int! = 7): [Post] - - """ - Compute statistics for a user - """ - stats(id: ID!): Statistics keystone: KeystoneMeta! } diff --git a/examples/json/CHANGELOG.md b/examples/json/CHANGELOG.md index fd6d222ba2b..02b93900684 100644 --- a/examples/json/CHANGELOG.md +++ b/examples/json/CHANGELOG.md @@ -1,5 +1,13 @@ # @keystone-next/example-json +## 4.0.7 + +### Patch Changes + +- Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 + ## 4.0.6 ### Patch Changes diff --git a/examples/json/package.json b/examples/json/package.json index d244ea7b2bd..683425f4541 100644 --- a/examples/json/package.json +++ b/examples/json/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/example-json-field", - "version": "4.0.6", + "version": "4.0.7", "private": true, "license": "MIT", "scripts": { @@ -9,8 +9,8 @@ "build": "keystone-next build" }, "dependencies": { - "@keystone-next/fields": "^13.0.0", - "@keystone-next/keystone": "^23.0.0" + "@keystone-next/fields": "^14.0.0", + "@keystone-next/keystone": "^24.0.0" }, "devDependencies": { "typescript": "^4.3.5" diff --git a/examples/json/schema.graphql b/examples/json/schema.graphql index 32862af1084..d474f50471c 100644 --- a/examples/json/schema.graphql +++ b/examples/json/schema.graphql @@ -9,24 +9,55 @@ type Package { input PackageWhereInput { AND: [PackageWhereInput!] OR: [PackageWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - label: String - label_not: String - label_contains: String - label_not_contains: String - label_in: [String] - label_not_in: [String] - isPrivate: Boolean - isPrivate_not: Boolean + NOT: [PackageWhereInput!] + id: IDFilter + label: StringNullableFilter + isPrivate: BooleanNullableFilter ownedBy: PersonWhereInput - ownedBy_is_null: Boolean +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input BooleanNullableFilter { + equals: Boolean + not: BooleanNullableFilter } input PackageWhereUniqueInput { @@ -80,7 +111,7 @@ type Person { packages( where: PackageWhereInput! = {} orderBy: [PackageOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Package!] packagesCount(where: PackageWhereInput! = {}): Int @@ -89,23 +120,16 @@ type Person { input PersonWhereInput { AND: [PersonWhereInput!] OR: [PersonWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_in: [String] - name_not_in: [String] - packages_every: PackageWhereInput - packages_some: PackageWhereInput - packages_none: PackageWhereInput + NOT: [PersonWhereInput!] + id: IDFilter + name: StringNullableFilter + packages: PackageManyRelationFilter +} + +input PackageManyRelationFilter { + every: PackageWhereInput + some: PackageWhereInput + none: PackageWhereInput } input PersonWhereUniqueInput { @@ -174,7 +198,7 @@ type Query { packages( where: PackageWhereInput! = {} orderBy: [PackageOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Package!] package(where: PackageWhereUniqueInput!): Package @@ -182,7 +206,7 @@ type Query { people( where: PersonWhereInput! = {} orderBy: [PersonOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Person!] person(where: PersonWhereUniqueInput!): Person diff --git a/examples/task-manager/CHANGELOG.md b/examples/task-manager/CHANGELOG.md index b47181e5bc2..7ffa163a889 100644 --- a/examples/task-manager/CHANGELOG.md +++ b/examples/task-manager/CHANGELOG.md @@ -1,5 +1,13 @@ # @keystone-next/example-task-manager +## 4.0.6 + +### Patch Changes + +- Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 + ## 4.0.5 ### Patch Changes diff --git a/examples/task-manager/package.json b/examples/task-manager/package.json index 3a63680b98d..8680a007e74 100644 --- a/examples/task-manager/package.json +++ b/examples/task-manager/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/example-task-manager", - "version": "4.0.5", + "version": "4.0.6", "private": true, "license": "MIT", "scripts": { @@ -9,8 +9,8 @@ "build": "keystone-next build" }, "dependencies": { - "@keystone-next/fields": "^13.0.0", - "@keystone-next/keystone": "^23.0.0" + "@keystone-next/fields": "^14.0.0", + "@keystone-next/keystone": "^24.0.0" }, "devDependencies": { "typescript": "^4.3.5" diff --git a/examples/task-manager/schema.graphql b/examples/task-manager/schema.graphql index 49a0f225167..e194b7cb406 100644 --- a/examples/task-manager/schema.graphql +++ b/examples/task-manager/schema.graphql @@ -16,36 +16,75 @@ enum TaskPriorityType { input TaskWhereInput { AND: [TaskWhereInput!] OR: [TaskWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - label: String - label_not: String - label_contains: String - label_not_contains: String - label_in: [String] - label_not_in: [String] - priority: TaskPriorityType - priority_not: TaskPriorityType - priority_in: [TaskPriorityType] - priority_not_in: [TaskPriorityType] - isComplete: Boolean - isComplete_not: Boolean + NOT: [TaskWhereInput!] + id: IDFilter + label: StringNullableFilter + priority: TaskPriorityTypeNullableFilter + isComplete: BooleanNullableFilter assignedTo: PersonWhereInput - assignedTo_is_null: Boolean - finishBy: String - finishBy_not: String - finishBy_lt: String - finishBy_lte: String - finishBy_gt: String - finishBy_gte: String - finishBy_in: [String] - finishBy_not_in: [String] + finishBy: DateTimeNullableFilter +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input TaskPriorityTypeNullableFilter { + equals: TaskPriorityType + in: [TaskPriorityType!] + notIn: [TaskPriorityType!] + not: TaskPriorityTypeNullableFilter +} + +input BooleanNullableFilter { + equals: Boolean + not: BooleanNullableFilter +} + +input DateTimeNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + not: DateTimeNullableFilter } input TaskWhereUniqueInput { @@ -103,7 +142,7 @@ type Person { tasks( where: TaskWhereInput! = {} orderBy: [TaskOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Task!] tasksCount(where: TaskWhereInput! = {}): Int @@ -112,23 +151,16 @@ type Person { input PersonWhereInput { AND: [PersonWhereInput!] OR: [PersonWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_in: [String] - name_not_in: [String] - tasks_every: TaskWhereInput - tasks_some: TaskWhereInput - tasks_none: TaskWhereInput + NOT: [PersonWhereInput!] + id: IDFilter + name: StringNullableFilter + tasks: TaskManyRelationFilter +} + +input TaskManyRelationFilter { + every: TaskWhereInput + some: TaskWhereInput + none: TaskWhereInput } input PersonWhereUniqueInput { @@ -194,7 +226,7 @@ type Query { tasks( where: TaskWhereInput! = {} orderBy: [TaskOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Task!] task(where: TaskWhereUniqueInput!): Task @@ -202,7 +234,7 @@ type Query { people( where: PersonWhereInput! = {} orderBy: [PersonOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Person!] person(where: PersonWhereUniqueInput!): Person diff --git a/examples/testing/CHANGELOG.md b/examples/testing/CHANGELOG.md index d858f6edfc1..2b4114cecb1 100644 --- a/examples/testing/CHANGELOG.md +++ b/examples/testing/CHANGELOG.md @@ -1,5 +1,20 @@ # @keystone-next/example-testing +## 0.0.6 + +### Patch Changes + +- [#6218](https://github.com/keystonejs/keystone/pull/6218) [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2) Thanks [@timleslie](https://github.com/timleslie)! - Added more details to validation failure error messages. + +* [#6310](https://github.com/keystonejs/keystone/pull/6310) [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053) Thanks [@timleslie](https://github.com/timleslie)! - Updated dependencies to use `mergeSchemas` from `@graphql-tools/schema`, rather than its old location in `@graphql-tools/merge`. You might see a reordering of the contents of your `graphql.schema` file. + +* Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`8187ea019`](https://github.com/keystonejs/keystone/commit/8187ea019a212874f3c602573af3382c6f3bd3b2), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 + - @keystone-next/types@24.0.0 + - @keystone-next/auth@31.0.0 + - @keystone-next/testing@1.1.1 + ## 0.0.5 ### Patch Changes diff --git a/examples/testing/package.json b/examples/testing/package.json index 5baaa7a8735..e094b5328f9 100644 --- a/examples/testing/package.json +++ b/examples/testing/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/example-testing", - "version": "0.0.5", + "version": "0.0.6", "private": true, "license": "MIT", "scripts": { @@ -10,14 +10,14 @@ "test": "jest --runInBand --testTimeout=60000" }, "dependencies": { - "@babel/core": "^7.14.8", - "@babel/preset-env": "^7.14.9", - "@babel/preset-typescript": "^7.14.5", - "@keystone-next/auth": "^30.0.0", - "@keystone-next/fields": "^13.0.0", - "@keystone-next/keystone": "^23.0.0", - "@keystone-next/testing": "^1.1.0", - "@keystone-next/types": "^23.0.0" + "@babel/core": "^7.15.0", + "@babel/preset-env": "^7.15.0", + "@babel/preset-typescript": "^7.15.0", + "@keystone-next/auth": "^31.0.0", + "@keystone-next/fields": "^14.0.0", + "@keystone-next/keystone": "^24.0.0", + "@keystone-next/testing": "^1.1.1", + "@keystone-next/types": "^24.0.0" }, "devDependencies": { "babel-jest": "^27.0.6", diff --git a/examples/testing/schema.graphql b/examples/testing/schema.graphql index 8a707c22288..c6a5ddc8586 100644 --- a/examples/testing/schema.graphql +++ b/examples/testing/schema.graphql @@ -1,3 +1,56 @@ +input CreateInitialPersonInput { + name: String + email: String + password: String +} + +type Mutation { + createInitialPerson( + data: CreateInitialPersonInput! + ): PersonAuthenticationWithPasswordSuccess! + authenticatePersonWithPassword( + email: String! + password: String! + ): PersonAuthenticationWithPasswordResult! + createTask(data: TaskCreateInput!): Task + createTasks(data: [TaskCreateInput!]!): [Task] + updateTask(where: TaskWhereUniqueInput!, data: TaskUpdateInput!): Task + updateTasks(data: [TaskUpdateArgs!]!): [Task] + deleteTask(where: TaskWhereUniqueInput!): Task + deleteTasks(where: [TaskWhereUniqueInput!]!): [Task] + createPerson(data: PersonCreateInput!): Person + createPeople(data: [PersonCreateInput!]!): [Person] + updatePerson(where: PersonWhereUniqueInput!, data: PersonUpdateInput!): Person + updatePeople(data: [PersonUpdateArgs!]!): [Person] + deletePerson(where: PersonWhereUniqueInput!): Person + deletePeople(where: [PersonWhereUniqueInput!]!): [Person] + endSession: Boolean! +} + +union AuthenticatedItem = Person + +union PersonAuthenticationWithPasswordResult = + PersonAuthenticationWithPasswordSuccess + | PersonAuthenticationWithPasswordFailure + +type PersonAuthenticationWithPasswordSuccess { + sessionToken: String! + item: Person! +} + +type PersonAuthenticationWithPasswordFailure { + code: PasswordAuthErrorCode! + message: String! +} + +enum PasswordAuthErrorCode { + FAILURE + IDENTITY_NOT_FOUND + SECRET_NOT_SET + MULTIPLE_IDENTITY_MATCHES + SECRET_MISMATCH +} + type Task { id: ID! label: String @@ -16,36 +69,75 @@ enum TaskPriorityType { input TaskWhereInput { AND: [TaskWhereInput!] OR: [TaskWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - label: String - label_not: String - label_contains: String - label_not_contains: String - label_in: [String] - label_not_in: [String] - priority: TaskPriorityType - priority_not: TaskPriorityType - priority_in: [TaskPriorityType] - priority_not_in: [TaskPriorityType] - isComplete: Boolean - isComplete_not: Boolean + NOT: [TaskWhereInput!] + id: IDFilter + label: StringNullableFilter + priority: TaskPriorityTypeNullableFilter + isComplete: BooleanNullableFilter assignedTo: PersonWhereInput - assignedTo_is_null: Boolean - finishBy: String - finishBy_not: String - finishBy_lt: String - finishBy_lte: String - finishBy_gt: String - finishBy_gte: String - finishBy_in: [String] - finishBy_not_in: [String] + finishBy: DateTimeNullableFilter +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input TaskPriorityTypeNullableFilter { + equals: TaskPriorityType + in: [TaskPriorityType!] + notIn: [TaskPriorityType!] + not: TaskPriorityTypeNullableFilter +} + +input BooleanNullableFilter { + equals: Boolean + not: BooleanNullableFilter +} + +input DateTimeNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + not: DateTimeNullableFilter } input TaskWhereUniqueInput { @@ -105,7 +197,7 @@ type Person { tasks( where: TaskWhereInput! = {} orderBy: [TaskOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Task!] tasksCount(where: TaskWhereInput! = {}): Int @@ -118,30 +210,22 @@ type PasswordState { input PersonWhereInput { AND: [PersonWhereInput!] OR: [PersonWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_in: [String] - name_not_in: [String] - email: String - email_not: String - email_contains: String - email_not_contains: String - email_in: [String] - email_not_in: [String] - password_is_set: Boolean - tasks_every: TaskWhereInput - tasks_some: TaskWhereInput - tasks_none: TaskWhereInput + NOT: [PersonWhereInput!] + id: IDFilter + name: StringNullableFilter + email: StringNullableFilter + password: PasswordFilter + tasks: TaskManyRelationFilter +} + +input PasswordFilter { + isSet: Boolean! +} + +input TaskManyRelationFilter { + every: TaskWhereInput + some: TaskWhereInput + none: TaskWhereInput } input PersonWhereUniqueInput { @@ -194,64 +278,12 @@ scalar JSON url: "http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf" ) -type Mutation { - createTask(data: TaskCreateInput!): Task - createTasks(data: [TaskCreateInput!]!): [Task] - updateTask(where: TaskWhereUniqueInput!, data: TaskUpdateInput!): Task - updateTasks(data: [TaskUpdateArgs!]!): [Task] - deleteTask(where: TaskWhereUniqueInput!): Task - deleteTasks(where: [TaskWhereUniqueInput!]!): [Task] - createPerson(data: PersonCreateInput!): Person - createPeople(data: [PersonCreateInput!]!): [Person] - updatePerson(where: PersonWhereUniqueInput!, data: PersonUpdateInput!): Person - updatePeople(data: [PersonUpdateArgs!]!): [Person] - deletePerson(where: PersonWhereUniqueInput!): Person - deletePeople(where: [PersonWhereUniqueInput!]!): [Person] - authenticatePersonWithPassword( - email: String! - password: String! - ): PersonAuthenticationWithPasswordResult! - createInitialPerson( - data: CreateInitialPersonInput! - ): PersonAuthenticationWithPasswordSuccess! - endSession: Boolean! -} - -union AuthenticatedItem = Person - -union PersonAuthenticationWithPasswordResult = - PersonAuthenticationWithPasswordSuccess - | PersonAuthenticationWithPasswordFailure - -type PersonAuthenticationWithPasswordSuccess { - sessionToken: String! - item: Person! -} - -type PersonAuthenticationWithPasswordFailure { - code: PasswordAuthErrorCode! - message: String! -} - -enum PasswordAuthErrorCode { - FAILURE - IDENTITY_NOT_FOUND - SECRET_NOT_SET - MULTIPLE_IDENTITY_MATCHES - SECRET_MISMATCH -} - -input CreateInitialPersonInput { - name: String - email: String - password: String -} - type Query { + authenticatedItem: AuthenticatedItem tasks( where: TaskWhereInput! = {} orderBy: [TaskOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Task!] task(where: TaskWhereUniqueInput!): Task @@ -259,12 +291,11 @@ type Query { people( where: PersonWhereInput! = {} orderBy: [PersonOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Person!] person(where: PersonWhereUniqueInput!): Person peopleCount(where: PersonWhereInput! = {}): Int - authenticatedItem: AuthenticatedItem keystone: KeystoneMeta! } diff --git a/examples/virtual-field/CHANGELOG.md b/examples/virtual-field/CHANGELOG.md index 7a25ade4858..87b027c8237 100644 --- a/examples/virtual-field/CHANGELOG.md +++ b/examples/virtual-field/CHANGELOG.md @@ -1,5 +1,14 @@ # @keystone-next/example-virtual-field +## 0.1.4 + +### Patch Changes + +- Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`8187ea019`](https://github.com/keystonejs/keystone/commit/8187ea019a212874f3c602573af3382c6f3bd3b2), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 + - @keystone-next/types@24.0.0 + ## 0.1.3 ### Patch Changes diff --git a/examples/virtual-field/README.md b/examples/virtual-field/README.md index 71b53de5e52..fd452f6068f 100644 --- a/examples/virtual-field/README.md +++ b/examples/virtual-field/README.md @@ -108,7 +108,7 @@ relatedPosts: virtual({ // this could have some logic to get posts that are actually related to this one somehow // this is a just a naive "get the three latest posts that aren't this one" return context.db.lists.Post.findMany({ - first: 3, + take: 3, where: { id_not: item.id, status: 'published' }, orderBy: [{ publishDate: 'desc' }], }); diff --git a/examples/virtual-field/package.json b/examples/virtual-field/package.json index c457d83ce4b..6744cd3dc4e 100644 --- a/examples/virtual-field/package.json +++ b/examples/virtual-field/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/example-virtual-field", - "version": "0.1.3", + "version": "0.1.4", "private": true, "license": "MIT", "scripts": { @@ -9,9 +9,9 @@ "build": "keystone-next build" }, "dependencies": { - "@keystone-next/fields": "^13.0.0", - "@keystone-next/keystone": "^23.0.0", - "@keystone-next/types": "^23.0.0" + "@keystone-next/fields": "^14.0.0", + "@keystone-next/keystone": "^24.0.0", + "@keystone-next/types": "^24.0.0" }, "devDependencies": { "typescript": "^4.3.5" diff --git a/examples/virtual-field/schema.graphql b/examples/virtual-field/schema.graphql index 70b0feee8a5..2a1713840d0 100644 --- a/examples/virtual-field/schema.graphql +++ b/examples/virtual-field/schema.graphql @@ -25,40 +25,70 @@ type PostCounts { input PostWhereInput { AND: [PostWhereInput!] OR: [PostWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - title: String - title_not: String - title_contains: String - title_not_contains: String - title_in: [String] - title_not_in: [String] - status: PostStatusType - status_not: PostStatusType - status_in: [PostStatusType] - status_not_in: [PostStatusType] - content: String - content_not: String - content_contains: String - content_not_contains: String - content_in: [String] - content_not_in: [String] - publishDate: String - publishDate_not: String - publishDate_lt: String - publishDate_lte: String - publishDate_gt: String - publishDate_gte: String - publishDate_in: [String] - publishDate_not_in: [String] + NOT: [PostWhereInput!] + id: IDFilter + title: StringNullableFilter + status: PostStatusTypeNullableFilter + content: StringNullableFilter + publishDate: DateTimeNullableFilter author: AuthorWhereInput - author_is_null: Boolean +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input PostStatusTypeNullableFilter { + equals: PostStatusType + in: [PostStatusType!] + notIn: [PostStatusType!] + not: PostStatusTypeNullableFilter +} + +input DateTimeNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + not: DateTimeNullableFilter } input PostWhereUniqueInput { @@ -117,7 +147,7 @@ type Author { posts( where: PostWhereInput! = {} orderBy: [PostOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Post!] postsCount(where: PostWhereInput! = {}): Int @@ -127,29 +157,17 @@ type Author { input AuthorWhereInput { AND: [AuthorWhereInput!] OR: [AuthorWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_in: [String] - name_not_in: [String] - email: String - email_not: String - email_contains: String - email_not_contains: String - email_in: [String] - email_not_in: [String] - posts_every: PostWhereInput - posts_some: PostWhereInput - posts_none: PostWhereInput + NOT: [AuthorWhereInput!] + id: IDFilter + name: StringNullableFilter + email: StringNullableFilter + posts: PostManyRelationFilter +} + +input PostManyRelationFilter { + every: PostWhereInput + some: PostWhereInput + none: PostWhereInput } input AuthorWhereUniqueInput { @@ -219,7 +237,7 @@ type Query { posts( where: PostWhereInput! = {} orderBy: [PostOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Post!] post(where: PostWhereUniqueInput!): Post @@ -227,7 +245,7 @@ type Query { authors( where: AuthorWhereInput! = {} orderBy: [AuthorOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Author!] author(where: AuthorWhereUniqueInput!): Author diff --git a/examples/virtual-field/schema.ts b/examples/virtual-field/schema.ts index c96eb7ead8b..3dbba311fae 100644 --- a/examples/virtual-field/schema.ts +++ b/examples/virtual-field/schema.ts @@ -102,7 +102,7 @@ export const lists = createSchema({ where: { id: item.id.toString() }, query: `posts( orderBy: { publishDate: desc } - first: 1 + take: 1 ) { id }`, }); if (posts.length > 0) { diff --git a/examples/with-auth/CHANGELOG.md b/examples/with-auth/CHANGELOG.md index e582c7673a6..e179b27cebf 100644 --- a/examples/with-auth/CHANGELOG.md +++ b/examples/with-auth/CHANGELOG.md @@ -1,5 +1,16 @@ # @keystone-next/example-with-auth +## 2.0.7 + +### Patch Changes + +- [#6310](https://github.com/keystonejs/keystone/pull/6310) [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053) Thanks [@timleslie](https://github.com/timleslie)! - Updated dependencies to use `mergeSchemas` from `@graphql-tools/schema`, rather than its old location in `@graphql-tools/merge`. You might see a reordering of the contents of your `graphql.schema` file. + +- Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 + - @keystone-next/auth@31.0.0 + ## 2.0.6 ### Patch Changes diff --git a/examples/with-auth/package.json b/examples/with-auth/package.json index e9caf46bbde..a9cefb11b89 100644 --- a/examples/with-auth/package.json +++ b/examples/with-auth/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/example-with-auth", - "version": "2.0.6", + "version": "2.0.7", "private": true, "license": "MIT", "scripts": { @@ -9,9 +9,9 @@ "build": "keystone-next build" }, "dependencies": { - "@keystone-next/auth": "^30.0.0", - "@keystone-next/fields": "^13.0.0", - "@keystone-next/keystone": "^23.0.0" + "@keystone-next/auth": "^31.0.0", + "@keystone-next/fields": "^14.0.0", + "@keystone-next/keystone": "^24.0.0" }, "devDependencies": { "typescript": "^4.3.5" diff --git a/examples/with-auth/schema.graphql b/examples/with-auth/schema.graphql index 8a707c22288..c6a5ddc8586 100644 --- a/examples/with-auth/schema.graphql +++ b/examples/with-auth/schema.graphql @@ -1,3 +1,56 @@ +input CreateInitialPersonInput { + name: String + email: String + password: String +} + +type Mutation { + createInitialPerson( + data: CreateInitialPersonInput! + ): PersonAuthenticationWithPasswordSuccess! + authenticatePersonWithPassword( + email: String! + password: String! + ): PersonAuthenticationWithPasswordResult! + createTask(data: TaskCreateInput!): Task + createTasks(data: [TaskCreateInput!]!): [Task] + updateTask(where: TaskWhereUniqueInput!, data: TaskUpdateInput!): Task + updateTasks(data: [TaskUpdateArgs!]!): [Task] + deleteTask(where: TaskWhereUniqueInput!): Task + deleteTasks(where: [TaskWhereUniqueInput!]!): [Task] + createPerson(data: PersonCreateInput!): Person + createPeople(data: [PersonCreateInput!]!): [Person] + updatePerson(where: PersonWhereUniqueInput!, data: PersonUpdateInput!): Person + updatePeople(data: [PersonUpdateArgs!]!): [Person] + deletePerson(where: PersonWhereUniqueInput!): Person + deletePeople(where: [PersonWhereUniqueInput!]!): [Person] + endSession: Boolean! +} + +union AuthenticatedItem = Person + +union PersonAuthenticationWithPasswordResult = + PersonAuthenticationWithPasswordSuccess + | PersonAuthenticationWithPasswordFailure + +type PersonAuthenticationWithPasswordSuccess { + sessionToken: String! + item: Person! +} + +type PersonAuthenticationWithPasswordFailure { + code: PasswordAuthErrorCode! + message: String! +} + +enum PasswordAuthErrorCode { + FAILURE + IDENTITY_NOT_FOUND + SECRET_NOT_SET + MULTIPLE_IDENTITY_MATCHES + SECRET_MISMATCH +} + type Task { id: ID! label: String @@ -16,36 +69,75 @@ enum TaskPriorityType { input TaskWhereInput { AND: [TaskWhereInput!] OR: [TaskWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - label: String - label_not: String - label_contains: String - label_not_contains: String - label_in: [String] - label_not_in: [String] - priority: TaskPriorityType - priority_not: TaskPriorityType - priority_in: [TaskPriorityType] - priority_not_in: [TaskPriorityType] - isComplete: Boolean - isComplete_not: Boolean + NOT: [TaskWhereInput!] + id: IDFilter + label: StringNullableFilter + priority: TaskPriorityTypeNullableFilter + isComplete: BooleanNullableFilter assignedTo: PersonWhereInput - assignedTo_is_null: Boolean - finishBy: String - finishBy_not: String - finishBy_lt: String - finishBy_lte: String - finishBy_gt: String - finishBy_gte: String - finishBy_in: [String] - finishBy_not_in: [String] + finishBy: DateTimeNullableFilter +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input TaskPriorityTypeNullableFilter { + equals: TaskPriorityType + in: [TaskPriorityType!] + notIn: [TaskPriorityType!] + not: TaskPriorityTypeNullableFilter +} + +input BooleanNullableFilter { + equals: Boolean + not: BooleanNullableFilter +} + +input DateTimeNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + not: DateTimeNullableFilter } input TaskWhereUniqueInput { @@ -105,7 +197,7 @@ type Person { tasks( where: TaskWhereInput! = {} orderBy: [TaskOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Task!] tasksCount(where: TaskWhereInput! = {}): Int @@ -118,30 +210,22 @@ type PasswordState { input PersonWhereInput { AND: [PersonWhereInput!] OR: [PersonWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_in: [String] - name_not_in: [String] - email: String - email_not: String - email_contains: String - email_not_contains: String - email_in: [String] - email_not_in: [String] - password_is_set: Boolean - tasks_every: TaskWhereInput - tasks_some: TaskWhereInput - tasks_none: TaskWhereInput + NOT: [PersonWhereInput!] + id: IDFilter + name: StringNullableFilter + email: StringNullableFilter + password: PasswordFilter + tasks: TaskManyRelationFilter +} + +input PasswordFilter { + isSet: Boolean! +} + +input TaskManyRelationFilter { + every: TaskWhereInput + some: TaskWhereInput + none: TaskWhereInput } input PersonWhereUniqueInput { @@ -194,64 +278,12 @@ scalar JSON url: "http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf" ) -type Mutation { - createTask(data: TaskCreateInput!): Task - createTasks(data: [TaskCreateInput!]!): [Task] - updateTask(where: TaskWhereUniqueInput!, data: TaskUpdateInput!): Task - updateTasks(data: [TaskUpdateArgs!]!): [Task] - deleteTask(where: TaskWhereUniqueInput!): Task - deleteTasks(where: [TaskWhereUniqueInput!]!): [Task] - createPerson(data: PersonCreateInput!): Person - createPeople(data: [PersonCreateInput!]!): [Person] - updatePerson(where: PersonWhereUniqueInput!, data: PersonUpdateInput!): Person - updatePeople(data: [PersonUpdateArgs!]!): [Person] - deletePerson(where: PersonWhereUniqueInput!): Person - deletePeople(where: [PersonWhereUniqueInput!]!): [Person] - authenticatePersonWithPassword( - email: String! - password: String! - ): PersonAuthenticationWithPasswordResult! - createInitialPerson( - data: CreateInitialPersonInput! - ): PersonAuthenticationWithPasswordSuccess! - endSession: Boolean! -} - -union AuthenticatedItem = Person - -union PersonAuthenticationWithPasswordResult = - PersonAuthenticationWithPasswordSuccess - | PersonAuthenticationWithPasswordFailure - -type PersonAuthenticationWithPasswordSuccess { - sessionToken: String! - item: Person! -} - -type PersonAuthenticationWithPasswordFailure { - code: PasswordAuthErrorCode! - message: String! -} - -enum PasswordAuthErrorCode { - FAILURE - IDENTITY_NOT_FOUND - SECRET_NOT_SET - MULTIPLE_IDENTITY_MATCHES - SECRET_MISMATCH -} - -input CreateInitialPersonInput { - name: String - email: String - password: String -} - type Query { + authenticatedItem: AuthenticatedItem tasks( where: TaskWhereInput! = {} orderBy: [TaskOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Task!] task(where: TaskWhereUniqueInput!): Task @@ -259,12 +291,11 @@ type Query { people( where: PersonWhereInput! = {} orderBy: [PersonOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Person!] person(where: PersonWhereUniqueInput!): Person peopleCount(where: PersonWhereInput! = {}): Int - authenticatedItem: AuthenticatedItem keystone: KeystoneMeta! } diff --git a/package.json b/package.json index 7cf3046e78c..0cbf8275d20 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "lint:prettier": "prettier --list-different \"**/*.{js,json,ts,tsx}\"", "lint:markdown": "remark . --frail --quiet", "lint:types": "tsc", - "lint": "yarn lint:prettier && yarn lint:eslint && yarn lint:markdown && yarn lint:types", + "lint": "yarn lint:prettier && yarn lint:eslint && yarn lint:markdown && yarn lint:types && yarn lint:filters", "test": "yarn lint && yarn test:unit", "test:unit": "cross-env DISABLE_LOGGING=true NODE_ENV=test jest --no-watchman --runInBand --logHeapUsage", "test:unit:debug": "cross-env NODE_ENV=test node --inspect-brk `which jest` --runInBand", @@ -35,17 +35,19 @@ "update": "manypkg upgrade", "no-cypress-install": "cross-env CYPRESS_INSTALL_BINARY=0 yarn", "postinstall-examples": "for d in `find examples -type d -maxdepth 1 -mindepth 1`; do cd $d; yarn keystone-next postinstall --fix; cd ../..; done; for d in `find examples-staging -type d -maxdepth 1 -mindepth 1`; do cd $d; yarn keystone-next postinstall --fix; cd ../..; done; for d in `find tests/test-projects -type d -maxdepth 1 -mindepth 1`; do cd $d; yarn keystone-next postinstall --fix; cd ../..; done", - "lint:examples": "for d in `find examples -type d -maxdepth 1 -mindepth 1`; do cd $d; echo $d; SKIP_PROMPTS=1 yarn keystone-next postinstall; if [ $? -ne 0 ]; then exit 1; fi; cd ../..; done; for d in `find examples-staging -type d -maxdepth 1 -mindepth 1`; do cd $d; echo $d; SKIP_PROMPTS=1 yarn keystone-next postinstall; if [ $? -ne 0 ]; then exit 1; fi; cd ../..; done; for d in `find tests/test-projects -type d -maxdepth 1 -mindepth 1`; do cd $d; echo $d; SKIP_PROMPTS=1 yarn keystone-next postinstall; if [ $? -ne 0 ]; then exit 1; fi; cd ../..; done" + "lint:examples": "for d in `find examples -type d -maxdepth 1 -mindepth 1`; do cd $d; echo $d; SKIP_PROMPTS=1 yarn keystone-next postinstall; if [ $? -ne 0 ]; then exit 1; fi; cd ../..; done; for d in `find examples-staging -type d -maxdepth 1 -mindepth 1`; do cd $d; echo $d; SKIP_PROMPTS=1 yarn keystone-next postinstall; if [ $? -ne 0 ]; then exit 1; fi; cd ../..; done; for d in `find tests/test-projects -type d -maxdepth 1 -mindepth 1`; do cd $d; echo $d; SKIP_PROMPTS=1 yarn keystone-next postinstall; if [ $? -ne 0 ]; then exit 1; fi; cd ../../..; done", + "generate-filters": "cd prisma-utils && yarn generate", + "lint:filters": "cd prisma-utils && yarn verify" }, "dependencies": { - "@babel/core": "^7.14.8", + "@babel/core": "^7.15.0", "@babel/plugin-proposal-class-properties": "^7.14.5", "@babel/plugin-proposal-object-rest-spread": "^7.14.7", "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-transform-runtime": "^7.14.5", - "@babel/preset-env": "^7.14.9", + "@babel/plugin-transform-runtime": "^7.15.0", + "@babel/preset-env": "^7.15.0", "@babel/preset-react": "^7.14.5", - "@babel/preset-typescript": "^7.14.5", + "@babel/preset-typescript": "^7.15.0", "@changesets/changelog-github": "^0.4.0", "@changesets/cli": "^2.16.0", "@jest/test-sequencer": "^27.0.6", @@ -53,15 +55,15 @@ "@preconstruct/cli": "2.1.0", "@preconstruct/eslint-plugin-format-js-tag": "^0.1.0", "@testing-library/jest-dom": "^5.14.1", - "@types/jest": "^26.0.24", + "@types/jest": "^27.0.1", "@types/node-fetch": "^2.5.12", - "@typescript-eslint/eslint-plugin": "^4.29.0", - "@typescript-eslint/parser": "^4.29.0", + "@typescript-eslint/eslint-plugin": "^4.29.2", + "@typescript-eslint/parser": "^4.29.2", "chalk-cli": "^4.1.0", "cross-env": "^7.0.3", "eslint": "^7.32.0", "eslint-plugin-cypress": "^2.11.3", - "eslint-plugin-import": "^2.23.3", + "eslint-plugin-import": "^2.24.0", "eslint-plugin-jest": "^24.4.0", "eslint-plugin-react": "^7.24.0", "eslint-plugin-react-hooks": "^4.2.0", @@ -117,7 +119,8 @@ "tests/api-tests", "tests/benchmarks", "tests/examples-smoke-tests", - "tests/test-projects/*" + "tests/test-projects/*", + "prisma-utils" ], "nohoist": [ "**/cypress-multi-reporters" @@ -126,7 +129,8 @@ "preconstruct": { "packages": [ "packages/*", - "design-system/packages/*" + "design-system/packages/*", + "prisma-utils" ], "distFilenameStrategy": "unscoped-package-name" }, diff --git a/packages/admin-ui-utils/CHANGELOG.md b/packages/admin-ui-utils/CHANGELOG.md index b196a6d926c..5acd3fcae8d 100644 --- a/packages/admin-ui-utils/CHANGELOG.md +++ b/packages/admin-ui-utils/CHANGELOG.md @@ -1,5 +1,12 @@ # @keystone-next/admin-ui-utils +## 5.0.6 + +### Patch Changes + +- Updated dependencies [[`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`8187ea019`](https://github.com/keystonejs/keystone/commit/8187ea019a212874f3c602573af3382c6f3bd3b2), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/types@24.0.0 + ## 5.0.5 ### Patch Changes diff --git a/packages/admin-ui-utils/package.json b/packages/admin-ui-utils/package.json index 23e2be5e864..9a0ba81f77b 100644 --- a/packages/admin-ui-utils/package.json +++ b/packages/admin-ui-utils/package.json @@ -1,15 +1,15 @@ { "name": "@keystone-next/admin-ui-utils", - "version": "5.0.5", + "version": "5.0.6", "main": "dist/admin-ui-utils.cjs.js", "module": "dist/admin-ui-utils.esm.js", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.14.8", + "@babel/runtime": "^7.15.3", "@emotion/weak-memoize": "^0.2.5", - "@keystone-next/types": "^23.0.0", + "@keystone-next/types": "^24.0.0", "@keystone-ui/core": "^3.1.1", - "@types/react": "^17.0.15", + "@types/react": "^17.0.18", "fast-deep-equal": "^3.1.3", "graphql": "^15.5.1" }, diff --git a/packages/auth/CHANGELOG.md b/packages/auth/CHANGELOG.md index 996a127bd09..a37f9e59522 100644 --- a/packages/auth/CHANGELOG.md +++ b/packages/auth/CHANGELOG.md @@ -1,5 +1,36 @@ # @keystone-next/auth +## 31.0.0 + +### Major Changes + +- [#6211](https://github.com/keystonejs/keystone/pull/6211) [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - The update mutations now accept `where` unique inputs instead of only an `id` and the `where` and `data` arguments are non-null. + + If you have a list called `Item`, the update mutations now look like this: + + ```graphql + type Mutation { + updateItem(where: ItemWhereUniqueInput!, data: ItemUpdateInput!): Item + updateItems(data: [ItemUpdateArgs!]!): [Item] + } + + input ItemUpdateArgs { + where: ItemWhereUniqueInput! + data: ItemUpdateInput! + } + ``` + +### Patch Changes + +- [#6310](https://github.com/keystonejs/keystone/pull/6310) [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053) Thanks [@timleslie](https://github.com/timleslie)! - Updated dependencies to use `mergeSchemas` from `@graphql-tools/schema`, rather than its old location in `@graphql-tools/merge`. You might see a reordering of the contents of your `graphql.schema` file. + +- Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`c2bb6a9a5`](https://github.com/keystonejs/keystone/commit/c2bb6a9a596fc52a3c61ec5d91c79758e417e61d), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`8187ea019`](https://github.com/keystonejs/keystone/commit/8187ea019a212874f3c602573af3382c6f3bd3b2), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 + - @keystone-next/types@24.0.0 + - @keystone-ui/notice@4.0.1 + - @keystone-next/admin-ui-utils@5.0.6 + ## 30.0.0 ### Major Changes diff --git a/packages/auth/package.json b/packages/auth/package.json index d02646024d2..1021aa7ca09 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/auth", - "version": "30.0.0", + "version": "31.0.0", "license": "MIT", "main": "dist/auth.cjs.js", "module": "dist/auth.esm.js", @@ -8,25 +8,25 @@ "node": "^12.20 || >= 14.13" }, "dependencies": { - "@babel/runtime": "^7.14.8", - "@graphql-tools/merge": "^6.2.16", - "@keystone-next/admin-ui-utils": "^5.0.5", - "@keystone-next/fields": "^13.0.0", - "@keystone-next/types": "^23.0.0", + "@babel/runtime": "^7.15.3", + "@graphql-tools/schema": "^8.1.1", + "@keystone-next/admin-ui-utils": "^5.0.6", + "@keystone-next/fields": "^14.0.0", + "@keystone-next/types": "^24.0.0", "@keystone-ui/button": "^5.0.0", "@keystone-ui/core": "^3.1.1", "@keystone-ui/fields": "^4.1.1", - "@keystone-ui/notice": "^4.0.0", + "@keystone-ui/notice": "^4.0.1", "cross-fetch": "^3.1.4", "fast-deep-equal": "^3.1.3", "graphql": "^15.5.1" }, "devDependencies": { - "@keystone-next/keystone": "^23.0.0", + "@keystone-next/keystone": "^24.0.0", "react": "^17.0.2" }, "peerDependencies": { - "@keystone-next/keystone": "^23.0.0", + "@keystone-next/keystone": "^24.0.0", "react": "^17.0.2" }, "preconstruct": { diff --git a/packages/auth/src/schema.ts b/packages/auth/src/schema.ts index bc78ec3fd19..64cbef1e917 100644 --- a/packages/auth/src/schema.ts +++ b/packages/auth/src/schema.ts @@ -1,4 +1,4 @@ -import { mergeSchemas } from '@graphql-tools/merge'; +import { mergeSchemas } from '@graphql-tools/schema'; import { ExtendGraphqlSchema } from '@keystone-next/types'; import { diff --git a/packages/cloudinary/CHANGELOG.md b/packages/cloudinary/CHANGELOG.md index bdc6d3709d8..2ccbf371910 100644 --- a/packages/cloudinary/CHANGELOG.md +++ b/packages/cloudinary/CHANGELOG.md @@ -1,5 +1,13 @@ # @keystone-next/cloudinary +## 6.0.6 + +### Patch Changes + +- Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`8187ea019`](https://github.com/keystonejs/keystone/commit/8187ea019a212874f3c602573af3382c6f3bd3b2), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/types@24.0.0 + ## 6.0.5 ### Patch Changes diff --git a/packages/cloudinary/package.json b/packages/cloudinary/package.json index 85814f1e951..5b96740dc23 100644 --- a/packages/cloudinary/package.json +++ b/packages/cloudinary/package.json @@ -1,18 +1,18 @@ { "name": "@keystone-next/cloudinary", - "version": "6.0.5", + "version": "6.0.6", "license": "MIT", "main": "dist/cloudinary.cjs.js", "module": "dist/cloudinary.esm.js", "dependencies": { - "@babel/runtime": "^7.14.8", - "@keystone-next/fields": "^13.0.0", - "@keystone-next/types": "^23.0.0", + "@babel/runtime": "^7.15.3", + "@keystone-next/fields": "^14.0.0", + "@keystone-next/types": "^24.0.0", "@keystone-ui/button": "^5.0.0", "@keystone-ui/core": "^3.1.1", "@keystone-ui/fields": "^4.1.2", "@keystone-ui/pill": "^5.0.0", - "@types/react": "^17.0.15", + "@types/react": "^17.0.18", "cloudinary": "^1.26.3", "cuid": "^2.1.8", "graphql-upload": "^12.0.0", diff --git a/packages/fields-document/CHANGELOG.md b/packages/fields-document/CHANGELOG.md index f76d4cb0624..dae1a7275d3 100644 --- a/packages/fields-document/CHANGELOG.md +++ b/packages/fields-document/CHANGELOG.md @@ -1,5 +1,40 @@ # @keystone-next/fields-document +## 8.0.0 + +### Major Changes + +- [#6095](https://github.com/keystonejs/keystone/pull/6095) [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - Updated filters to be nested instead of flattened and add top-level `NOT` operator. See the [Query Filter API docs](https://keystonejs.com/docs/apis/filters) and the upgrade guide for more information. + + ```graphql + query { + posts(where: { title: { contains: "Something" } }) { + title + content + } + } + ``` + +### Patch Changes + +- [#6250](https://github.com/keystonejs/keystone/pull/6250) [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450) Thanks [@timleslie](https://github.com/timleslie)! - Updated internal type definitions. + +* [#6318](https://github.com/keystonejs/keystone/pull/6318) [`e985aa010`](https://github.com/keystonejs/keystone/commit/e985aa0104d30a779f21ec05d80e6b98ece87dfb) Thanks [@raveling](https://github.com/raveling)! - Updated the document editor's expanded view so that you can click on any of the empty space below the content to focus the editor + +- [#6207](https://github.com/keystonejs/keystone/pull/6207) [`69f47bfed`](https://github.com/keystonejs/keystone/commit/69f47bfed1eaa1269cfdc42071268a914bd4aa17) Thanks [@timleslie](https://github.com/timleslie)! - Suppressed error logging during tests. + +* [#6197](https://github.com/keystonejs/keystone/pull/6197) [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - The generated CRUD queries, and some of the input types, in the GraphQL API have been renamed. + + If you have a list called `Item`, the query for multiple values, `allItems` will be renamed to `items`. The query for a single value, `Item`, will be renamed to `item`. + + Also, the input type used in the `updateItems` mutation has been renamed from `ItemsUpdateInput` to `ItemUpdateArgs`. + +* Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`8187ea019`](https://github.com/keystonejs/keystone/commit/8187ea019a212874f3c602573af3382c6f3bd3b2), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 + - @keystone-next/types@24.0.0 + - @keystone-next/admin-ui-utils@5.0.6 + ## 7.0.3 ### Patch Changes diff --git a/packages/fields-document/package.json b/packages/fields-document/package.json index fa2373d04ca..5484772ac8f 100644 --- a/packages/fields-document/package.json +++ b/packages/fields-document/package.json @@ -1,7 +1,7 @@ { "name": "@keystone-next/fields-document", "description": "KeystoneJS Document Field Type", - "version": "7.0.3", + "version": "8.0.0", "main": "dist/fields-document.cjs.js", "module": "dist/fields-document.esm.js", "files": [ @@ -19,20 +19,20 @@ ] }, "dependencies": { - "@babel/runtime": "^7.14.8", + "@babel/runtime": "^7.15.3", "@braintree/sanitize-url": "^5.0.2", "@emotion/weak-memoize": "^0.2.5", - "@keystone-next/admin-ui-utils": "^5.0.5", - "@keystone-next/fields": "^13.0.0", - "@keystone-next/keystone": "^23.0.0", - "@keystone-next/types": "^23.0.0", + "@keystone-next/admin-ui-utils": "^5.0.6", + "@keystone-next/fields": "^14.0.0", + "@keystone-next/keystone": "^24.0.0", + "@keystone-next/types": "^24.0.0", "@keystone-ui/button": "^5.0.0", "@keystone-ui/core": "^3.1.1", "@keystone-ui/fields": "^4.1.1", "@keystone-ui/icons": "^4.0.0", "@keystone-ui/popover": "^4.0.1", "@keystone-ui/tooltip": "^4.0.1", - "@types/react": "^17.0.15", + "@types/react": "^17.0.18", "apply-ref": "^1.0.0", "fp-ts": "^2.11.1", "graphql": "^15.5.1", diff --git a/packages/fields-document/src/DocumentEditor/index.tsx b/packages/fields-document/src/DocumentEditor/index.tsx index 1a698698273..f68c89d7fef 100644 --- a/packages/fields-document/src/DocumentEditor/index.tsx +++ b/packages/fields-document/src/DocumentEditor/index.tsx @@ -226,7 +226,7 @@ export function DocumentEditor({ documentFeatures: DocumentFeatures; }) { const isShiftPressedRef = useKeyDownRef('Shift'); - const { colors } = useTheme(); + const { colors, spacing } = useTheme(); const [expanded, setExpanded] = useState(false); const editor = useMemo( () => createDocumentEditor(documentFeatures, componentBlocks, relationships, isShiftPressedRef), @@ -235,7 +235,11 @@ export function DocumentEditor({ return (
+ + { // for debugging false && @@ -345,9 +359,11 @@ export function DocumentEditorProvider({ export function DocumentEditorEditable({ autoFocus, readOnly, + className, }: { autoFocus?: boolean; readOnly?: boolean; + className?: string; }) { const editor = useSlate(); const componentBlocks = useContext(ComponentBlockContext); @@ -401,6 +417,7 @@ export function DocumentEditorEditable({ readOnly={readOnly} renderElement={renderElement} renderLeaf={renderLeaf} + className={className} /> ); } @@ -429,7 +446,9 @@ function Debugger() { const orderedListStyles = ['lower-roman', 'decimal', 'lower-alpha']; const unorderedListStyles = ['square', 'disc', 'circle']; -let styles: any = {}; +let styles: any = { + flex: 1, +}; let listDepth = 10; diff --git a/packages/fields-document/src/relationship-data.tsx b/packages/fields-document/src/relationship-data.tsx index 553ab970fab..ede96091c09 100644 --- a/packages/fields-document/src/relationship-data.tsx +++ b/packages/fields-document/src/relationship-data.tsx @@ -27,7 +27,7 @@ export function addRelationshipData( let val = await graphQLAPI.run({ query: `query($ids: [ID!]!) {items:${ gqlNames(relationship.listKey).listQueryName - }(where: {id_in:$ids}) {${idFieldAlias}:id ${labelFieldAlias}:${labelField}\n${ + }(where: { id: { in: $ids } }) {${idFieldAlias}:id ${labelFieldAlias}:${labelField}\n${ relationship.selection || '' }}}`, variables: { ids }, diff --git a/packages/fields/CHANGELOG.md b/packages/fields/CHANGELOG.md index 22b049863d6..cafa88f5de0 100644 --- a/packages/fields/CHANGELOG.md +++ b/packages/fields/CHANGELOG.md @@ -1,5 +1,122 @@ # @keystone-next/fields +## 14.0.0 + +### Major Changes + +- [#6280](https://github.com/keystonejs/keystone/pull/6280) [`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - Removed `gqlType` option to `autoIncrement` field type. The field type will now always be represented with an `Int` in GraphQL + +* [#6196](https://github.com/keystonejs/keystone/pull/6196) [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - Removed `_ListKeyMeta` and `_toManyRelationshipFieldMeta` fields. You should use `listKeyCount` and `toManyRelationshipFieldCount` instead + +- [#6266](https://github.com/keystonejs/keystone/pull/6266) [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - Renamed `first` argument in find many queries to `take` to align with Prisma. + + ```graphql + type Query { + users( + where: UserWhereInput! = {} + orderBy: [UserOrderByInput!]! = [] + # previously was first: Int + take: Int + skip: Int! = 0 + ): [User!] + # ... + } + + type User { + # ... + posts( + where: PostWhereInput! = {} + orderBy: [PostOrderByInput!]! = [] + # previously was first: Int + take: Int + skip: Int! = 0 + ): [Post!] + # ... + } + ``` + +* [#6196](https://github.com/keystonejs/keystone/pull/6196) [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - Removed `search` argument from the GraphQL API for finding many items, Lists/DB API and to-many relationship fields. You should use `contains` filters instead. + +- [#6095](https://github.com/keystonejs/keystone/pull/6095) [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - Updated filters to be nested instead of flattened and add top-level `NOT` operator. See the [Query Filter API docs](https://keystonejs.com/docs/apis/filters) and the upgrade guide for more information. + + ```graphql + query { + posts(where: { title: { contains: "Something" } }) { + title + content + } + } + ``` + +* [#6196](https://github.com/keystonejs/keystone/pull/6196) [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - Removed `sortBy` argument from the GraphQL API for finding many items, Lists/DB API and to-many relationship fields. You should use `orderBy` instead. + +- [#6217](https://github.com/keystonejs/keystone/pull/6217) [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - `disconnectAll` has been renamed to `disconnect` in to-one relationship inputs and the old `disconnect` field has been removed. There are also seperate input types for create and update where the input for create doesn't have `disconnect`. It's also now required that if you provide a to-one relationship input, you must provide exactly one field to the input. + + If you have a list called `Item`, the to-one relationship inputs now look like this: + + ```graphql + input ItemRelateToOneForCreateInput { + create: ItemCreateInput + connect: ItemWhereUniqueInput + } + input ItemRelateToOneForUpdateInput { + create: ItemCreateInput + connect: ItemWhereUniqueInput + disconnect: Boolean + } + ``` + +* [#6224](https://github.com/keystonejs/keystone/pull/6224) [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - `disconnectAll` has been replaced by `set` in to-many relationship inputs, the equivalent to `disconnectAll: true` is now `set: []`. There are also seperate input types for create and update where the input for create doesn't have `disconnect` or `set`. The inputs in the lists in the input field are now also non-null. + + If you have a list called `Item`, the to-many relationship inputs now look like this: + + ```graphql + input ItemRelateToManyForCreateInput { + create: [ItemCreateInput!] + connect: [ItemWhereUniqueInput!] + } + input ItemRelateToManyForUpdateInput { + disconnect: [ItemWhereUniqueInput!] + set: [ItemWhereUniqueInput!] + create: [ItemCreateInput!] + connect: [ItemWhereUniqueInput!] + } + ``` + +- [#6211](https://github.com/keystonejs/keystone/pull/6211) [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - The update mutations now accept `where` unique inputs instead of only an `id` and the `where` and `data` arguments are non-null. + + If you have a list called `Item`, the update mutations now look like this: + + ```graphql + type Mutation { + updateItem(where: ItemWhereUniqueInput!, data: ItemUpdateInput!): Item + updateItems(data: [ItemUpdateArgs!]!): [Item] + } + + input ItemUpdateArgs { + where: ItemWhereUniqueInput! + data: ItemUpdateInput! + } + ``` + +### Patch Changes + +- [#6237](https://github.com/keystonejs/keystone/pull/6237) [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d) Thanks [@gwyneplaine](https://github.com/gwyneplaine)! - Updated timestamp field to default time to 00:00 when no time is selected. + +* [#6197](https://github.com/keystonejs/keystone/pull/6197) [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - The generated CRUD queries, and some of the input types, in the GraphQL API have been renamed. + + If you have a list called `Item`, the query for multiple values, `allItems` will be renamed to `items`. The query for a single value, `Item`, will be renamed to `item`. + + Also, the input type used in the `updateItems` mutation has been renamed from `ItemsUpdateInput` to `ItemUpdateArgs`. + +* Updated dependencies [[`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`c2bb6a9a5`](https://github.com/keystonejs/keystone/commit/c2bb6a9a596fc52a3c61ec5d91c79758e417e61d), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`6cd7ab78e`](https://github.com/keystonejs/keystone/commit/6cd7ab78e018fa0ffaddc1258426d23da19cd854), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`8187ea019`](https://github.com/keystonejs/keystone/commit/8187ea019a212874f3c602573af3382c6f3bd3b2), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/keystone@24.0.0 + - @keystone-next/types@24.0.0 + - @keystone-ui/toast@4.0.2 + - @keystone-ui/segmented-control@4.0.2 + - @keystone-next/admin-ui-utils@5.0.6 + - @keystone-next/utils@1.0.4 + ## 13.0.0 ### Major Changes diff --git a/packages/fields/package.json b/packages/fields/package.json index 3252816db45..27336167293 100644 --- a/packages/fields/package.json +++ b/packages/fields/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/fields", - "version": "13.0.0", + "version": "14.0.0", "license": "MIT", "main": "dist/fields.cjs.js", "module": "dist/fields.esm.js", @@ -11,11 +11,11 @@ "mime": "^2.5.2" }, "dependencies": { - "@babel/runtime": "^7.14.8", - "@keystone-next/admin-ui-utils": "^5.0.5", - "@keystone-next/keystone": "^23.0.0", - "@keystone-next/types": "^23.0.0", - "@keystone-next/utils": "^1.0.3", + "@babel/runtime": "^7.15.3", + "@keystone-next/admin-ui-utils": "^5.0.6", + "@keystone-next/keystone": "^24.0.0", + "@keystone-next/types": "^24.0.0", + "@keystone-next/utils": "^1.0.4", "@keystone-ui/button": "^5.0.0", "@keystone-ui/core": "^3.1.1", "@keystone-ui/fields": "^4.1.2", @@ -23,11 +23,11 @@ "@keystone-ui/loading": "^4.0.0", "@keystone-ui/modals": "^4.0.0", "@keystone-ui/pill": "^5.0.0", - "@keystone-ui/segmented-control": "^4.0.1", - "@keystone-ui/toast": "^4.0.1", + "@keystone-ui/segmented-control": "^4.0.2", + "@keystone-ui/toast": "^4.0.2", "@keystone-ui/tooltip": "^4.0.1", "@types/bcryptjs": "^2.4.2", - "@types/react": "^17.0.15", + "@types/react": "^17.0.18", "bcryptjs": "^2.4.3", "bytes": "^3.1.0", "copy-to-clipboard": "^3.3.1", diff --git a/packages/fields/src/tests/test-fixtures.ts b/packages/fields/src/tests/test-fixtures.ts index b83e5225be1..0c72dadf71c 100644 --- a/packages/fields/src/tests/test-fixtures.ts +++ b/packages/fields/src/tests/test-fixtures.ts @@ -63,20 +63,20 @@ export const filterTests = (withKeystone: any) => { ); test( - 'Filter: id', + 'Filter: equals', withKeystone(async ({ context }: { context: KeystoneContext }) => { const IDs = await getIDs(context); const id = IDs['person2']; - return match(context, { id }, [{ id: IDs['person2'], name: 'person2' }]); + return match(context, { id: { equals: id } }, [{ id: IDs['person2'], name: 'person2' }]); }) ); test( - 'Filter: id_not', + 'Filter: not equals', withKeystone(async ({ context }: { context: KeystoneContext }) => { const IDs = await getIDs(context); const id = IDs['person2']; - return match(context, { id_not: id }, [ + return match(context, { id: { not: { equals: id } } }, [ { id: IDs['person1'], name: 'person1' }, { id: IDs['person3'], name: 'person3' }, { id: IDs['person4'], name: 'person4' }, @@ -85,12 +85,12 @@ export const filterTests = (withKeystone: any) => { ); test( - 'Filter: id_in', + 'Filter: in', withKeystone(async ({ context }: { context: KeystoneContext }) => { const IDs = await getIDs(context); const id2 = IDs['person2']; const id3 = IDs['person3']; - return match(context, { id_in: [id2, id3] }, [ + return match(context, { id: { in: [id2, id3] } }, [ { id: IDs['person2'], name: 'person2' }, { id: IDs['person3'], name: 'person3' }, ]); @@ -98,27 +98,27 @@ export const filterTests = (withKeystone: any) => { ); test( - 'Filter: id_in - empty list', + 'Filter: in - empty list', withKeystone(({ context }: { context: KeystoneContext }) => { - return match(context, { id_in: [] }, []); + return match(context, { id: { in: [] } }, []); }) ); test( - 'Filter: id_in - missing id', + 'Filter: in - missing id', withKeystone(({ context }: { context: KeystoneContext }) => { const fakeID = 'cdafasdfasd'; - return match(context, { id_in: [fakeID] }, []); + return match(context, { id: { in: [fakeID] } }, []); }) ); test( - 'Filter: id_not_in', + 'Filter: not in', withKeystone(async ({ context }: { context: KeystoneContext }) => { const IDs = await getIDs(context); const id2 = IDs['person2']; const id3 = IDs['person3']; - return match(context, { id_not_in: [id2, id3] }, [ + return match(context, { id: { not: { in: [id2, id3] } } }, [ { id: IDs['person1'], name: 'person1' }, { id: IDs['person4'], name: 'person4' }, ]); @@ -126,10 +126,10 @@ export const filterTests = (withKeystone: any) => { ); test( - 'Filter: id_not_in - empty list', + 'Filter: not in - empty list', withKeystone(async ({ context }: { context: KeystoneContext }) => { const IDs = await getIDs(context); - return match(context, { id_not_in: [] }, [ + return match(context, { id: { not: { in: [] } } }, [ { id: IDs['person1'], name: 'person1' }, { id: IDs['person2'], name: 'person2' }, { id: IDs['person3'], name: 'person3' }, @@ -139,11 +139,11 @@ export const filterTests = (withKeystone: any) => { ); test( - 'Filter: id_not_in - missing id', + 'Filter: not in - missing id', withKeystone(async ({ context }: { context: KeystoneContext }) => { const IDs = await getIDs(context); const fakeID = 'cdafasdfasd'; - return match(context, { id_not_in: [fakeID] }, [ + return match(context, { id: { not: { in: [fakeID] } } }, [ { id: IDs['person1'], name: 'person1' }, { id: IDs['person2'], name: 'person2' }, { id: IDs['person3'], name: 'person3' }, diff --git a/packages/fields/src/types/autoIncrement/index.ts b/packages/fields/src/types/autoIncrement/index.ts index ceb6ef68e0f..a4484ec6a65 100644 --- a/packages/fields/src/types/autoIncrement/index.ts +++ b/packages/fields/src/types/autoIncrement/index.ts @@ -7,6 +7,7 @@ import { legacyFilters, orderDirectionEnum, schema, + filters, } from '@keystone-next/types'; import { resolveView } from '../../resolve-view'; import { getIndexType } from '../../get-index-type'; @@ -17,7 +18,6 @@ export type AutoIncrementFieldConfig = {}): FieldTypeFunc => meta => { - const type = meta.fieldKey === 'id' || gqlType === 'ID' ? schema.ID : schema.Int; - const __legacy = { - isRequired, - defaultValue, - filters: { - fields: { - ...legacyFilters.fields.equalityInputFields(meta.fieldKey, type), - ...legacyFilters.fields.orderingInputFields(meta.fieldKey, type), - ...legacyFilters.fields.inInputFields(meta.fieldKey, type), - }, - impls: { - ...equalityConditions(meta.fieldKey, x => Number(x) || -1), - ...legacyFilters.impls.orderingConditions(meta.fieldKey, x => Number(x) || -1), - ...inConditions(meta.fieldKey, x => x.map((xx: any) => Number(xx) || -1)), - }, - }, - }; - if (meta.fieldKey === 'id') { - return fieldType({ - kind: 'scalar', - mode: 'required', - scalar: 'Int', - default: { kind: 'autoincrement' }, - })({ - ...config, - input: { - // TODO: fix the fact that TS did not catch that a resolver is needed here - uniqueWhere: { - arg: schema.arg({ type }), - resolve(value) { - return Number(value); - }, - }, - orderBy: { arg: schema.arg({ type: orderDirectionEnum }) }, - }, - output: schema.field({ - type: schema.nonNull(schema.ID), - resolve({ value }) { - return value.toString(); - }, - }), - views: resolveView('integer/views'), - __legacy, - }); - } - const inputResolver = (val: number | string | null | undefined) => { - if (val == null) { - return val; - } - return Number(val); - }; return fieldType({ kind: 'scalar', mode: 'optional', @@ -90,20 +38,35 @@ export const autoIncrement = })({ ...config, input: { - uniqueWhere: isUnique ? { arg: schema.arg({ type }), resolve: x => Number(x) } : undefined, - create: { arg: schema.arg({ type }), resolve: inputResolver }, - update: { arg: schema.arg({ type }), resolve: inputResolver }, + where: { + arg: schema.arg({ + type: filters[meta.provider].Int.optional, + }), + resolve: filters.resolveCommon, + }, + uniqueWhere: isUnique ? { arg: schema.arg({ type: schema.Int }) } : undefined, + create: { arg: schema.arg({ type: schema.Int }) }, + update: { arg: schema.arg({ type: schema.Int }) }, orderBy: { arg: schema.arg({ type: orderDirectionEnum }) }, }, - output: schema.field({ - type, - resolve({ value }) { - if (value === null) return null; - return type === schema.ID ? value.toString() : value; - }, - }), + output: schema.field({ type: schema.Int }), views: resolveView('integer/views'), - __legacy, + __legacy: { + isRequired, + defaultValue, + filters: { + fields: { + ...legacyFilters.fields.equalityInputFields(meta.fieldKey, schema.Int), + ...legacyFilters.fields.orderingInputFields(meta.fieldKey, schema.Int), + ...legacyFilters.fields.inInputFields(meta.fieldKey, schema.Int), + }, + impls: { + ...equalityConditions(meta.fieldKey, x => Number(x) || -1), + ...legacyFilters.impls.orderingConditions(meta.fieldKey, x => Number(x) || -1), + ...inConditions(meta.fieldKey, x => x.map((xx: any) => Number(xx) || -1)), + }, + }, + }, }); }; diff --git a/packages/fields/src/types/autoIncrement/tests/test-fixtures.ts b/packages/fields/src/types/autoIncrement/tests/test-fixtures.ts index 80796704315..c4659c1f360 100644 --- a/packages/fields/src/types/autoIncrement/tests/test-fixtures.ts +++ b/packages/fields/src/types/autoIncrement/tests/test-fixtures.ts @@ -2,13 +2,10 @@ import { KeystoneContext } from '@keystone-next/types'; import { text } from '../../text'; import { autoIncrement } from '..'; -type MatrixValue = typeof testMatrix[number]; - export const name = 'AutoIncrement'; export const typeFunction = autoIncrement; -export const testMatrix = ['ID', 'Int'] as const; -export const exampleValue = (matrixValue: MatrixValue) => (matrixValue === 'ID' ? '35' : 35); -export const exampleValue2 = (matrixValue: MatrixValue) => (matrixValue === 'ID' ? '36' : 36); +export const exampleValue = () => 35; +export const exampleValue2 = () => 36; export const supportsUnique = true; export const fieldName = 'orderNumber'; export const skipCreateTest = false; @@ -16,21 +13,9 @@ export const skipUpdateTest = true; export const unSupportedAdapterList = ['sqlite']; -// Be default, `AutoIncrement` are read-only. But for `isRequired` test purpose, we need to bypass these restrictions. -export const fieldConfig = (matrixValue: MatrixValue) => ({ - gqlType: matrixValue, - access: { create: true, update: true }, -}); - -export const getTestFields = (matrixValue: MatrixValue) => ({ +export const getTestFields = () => ({ name: text(), - orderNumber: autoIncrement({ - // The gqlType argument is not currently available on the type. - // This will be reviewed when we do our full field type API review - // @ts-ignore - gqlType: matrixValue, - access: { create: true }, - }), + orderNumber: autoIncrement(), }); export const initItems = () => { @@ -45,32 +30,20 @@ export const initItems = () => { ]; }; -export const storedValues = (matrixValue: MatrixValue) => - matrixValue === 'ID' - ? [ - { name: 'product1', orderNumber: '1' }, - { name: 'product2', orderNumber: '2' }, - { name: 'product3', orderNumber: '3' }, - { name: 'product4', orderNumber: '4' }, - { name: 'product5', orderNumber: '5' }, - { name: 'product6', orderNumber: '6' }, - { name: 'product7', orderNumber: '7' }, - ] - : [ - { name: 'product1', orderNumber: 1 }, - { name: 'product2', orderNumber: 2 }, - { name: 'product3', orderNumber: 3 }, - { name: 'product4', orderNumber: 4 }, - { name: 'product5', orderNumber: 5 }, - { name: 'product6', orderNumber: 6 }, - { name: 'product7', orderNumber: 7 }, - ]; +export const storedValues = () => [ + { name: 'product1', orderNumber: 1 }, + { name: 'product2', orderNumber: 2 }, + { name: 'product3', orderNumber: 3 }, + { name: 'product4', orderNumber: 4 }, + { name: 'product5', orderNumber: 5 }, + { name: 'product6', orderNumber: 6 }, + { name: 'product7', orderNumber: 7 }, +]; export const supportedFilters = () => []; -export const filterTests = (withKeystone: (arg: any) => any, matrixValue: MatrixValue) => { - const _storedValues = storedValues(matrixValue); - const _f = matrixValue === 'ID' ? (x: any) => x.toString() : (x: any) => x; +export const filterTests = (withKeystone: (arg: any) => any) => { + const _storedValues = storedValues(); const match = async (context: KeystoneContext, where: Record, expected: any[]) => expect( await context.lists.Test.findMany({ @@ -81,93 +54,79 @@ export const filterTests = (withKeystone: (arg: any) => any, matrixValue: Matrix ).toEqual(expected.map(i => _storedValues[i])); test( - 'Filter: orderNumber', - withKeystone(({ context }: { context: KeystoneContext }) => - match(context, { orderNumber: _f(1) }, [0]) - ) - ); - - test( - 'Filter: orderNumber_not', - withKeystone(({ context }: { context: KeystoneContext }) => - match(context, { orderNumber_not: _f(1) }, [1, 2, 3, 4, 5, 6]) - ) - ); - - test( - 'Filter: orderNumber_not null', + 'Filter: equals', withKeystone(({ context }: { context: KeystoneContext }) => - match(context, { orderNumber_not: null }, [0, 1, 2, 3, 4, 5, 6]) + match(context, { orderNumber: { equals: 1 } }, [0]) ) ); test( - 'Filter: orderNumber_lt', + 'Filter: not', withKeystone(({ context }: { context: KeystoneContext }) => - match(context, { orderNumber_lt: _f(2) }, [0]) + match(context, { orderNumber: { not: { equals: 1 } } }, [1, 2, 3, 4, 5, 6]) ) ); test( - 'Filter: orderNumber_lte', + 'Filter: not null', withKeystone(({ context }: { context: KeystoneContext }) => - match(context, { orderNumber_lte: _f(2) }, [0, 1]) + match(context, { orderNumber: { not: null } }, [0, 1, 2, 3, 4, 5, 6]) ) ); test( - 'Filter: orderNumber_gt', + 'Filter: lt', withKeystone(({ context }: { context: KeystoneContext }) => - match(context, { orderNumber_gt: _f(2) }, [2, 3, 4, 5, 6]) + match(context, { orderNumber: { lt: 2 } }, [0]) ) ); test( - 'Filter: orderNumber_gte', + 'Filter: lte', withKeystone(({ context }: { context: KeystoneContext }) => - match(context, { orderNumber_gte: _f(2) }, [1, 2, 3, 4, 5, 6]) + match(context, { orderNumber: { lte: 2 } }, [0, 1]) ) ); test( - 'Filter: orderNumber_in (empty list)', + 'Filter: gt', withKeystone(({ context }: { context: KeystoneContext }) => - match(context, { orderNumber_in: [] }, []) + match(context, { orderNumber: { gt: 2 } }, [2, 3, 4, 5, 6]) ) ); test( - 'Filter: orderNumber_not_in (empty list)', + 'Filter: gte', withKeystone(({ context }: { context: KeystoneContext }) => - match(context, { orderNumber_not_in: [] }, [0, 1, 2, 3, 4, 5, 6]) + match(context, { orderNumber: { gte: 2 } }, [1, 2, 3, 4, 5, 6]) ) ); test( - 'Filter: orderNumber_in', + 'Filter: in (empty list)', withKeystone(({ context }: { context: KeystoneContext }) => - match(context, { orderNumber_in: ([1, 2, 3] as const).map(_f) }, [0, 1, 2]) + match(context, { orderNumber: { in: [] } }, []) ) ); test( - 'Filter: orderNumber_not_in', + 'Filter: not in (empty list)', withKeystone(({ context }: { context: KeystoneContext }) => - match(context, { orderNumber_not_in: [1, 2, 3].map(_f) }, [3, 4, 5, 6]) + match(context, { orderNumber: { notIn: [] } }, [0, 1, 2, 3, 4, 5, 6]) ) ); test( - 'Filter: orderNumber_in null', + 'Filter: in', withKeystone(({ context }: { context: KeystoneContext }) => - match(context, { orderNumber_in: [null] }, []) + match(context, { orderNumber: { in: [1, 2, 3] } }, [0, 1, 2]) ) ); test( - 'Filter: orderNumber_not_in null', + 'Filter: not in', withKeystone(({ context }: { context: KeystoneContext }) => - match(context, { orderNumber_not_in: [null] }, [0, 1, 2, 3, 4, 5, 6]) + match(context, { orderNumber: { notIn: [1, 2, 3] } }, [3, 4, 5, 6]) ) ); }; diff --git a/packages/fields/src/types/checkbox/index.ts b/packages/fields/src/types/checkbox/index.ts index 1e320de29a6..dd2b36fb891 100644 --- a/packages/fields/src/types/checkbox/index.ts +++ b/packages/fields/src/types/checkbox/index.ts @@ -7,6 +7,7 @@ import { legacyFilters, orderDirectionEnum, schema, + filters, } from '@keystone-next/types'; import { resolveView } from '../../resolve-view'; @@ -30,6 +31,10 @@ export const checkbox = return fieldType({ kind: 'scalar', mode: 'optional', scalar: 'Boolean' })({ ...config, input: { + where: { + arg: schema.arg({ type: filters[meta.provider].Boolean.optional }), + resolve: filters.resolveCommon, + }, create: { arg: schema.arg({ type: schema.Boolean }) }, update: { arg: schema.arg({ type: schema.Boolean }) }, orderBy: { arg: schema.arg({ type: orderDirectionEnum }) }, diff --git a/packages/fields/src/types/checkbox/views/index.tsx b/packages/fields/src/types/checkbox/views/index.tsx index 010f2f4a200..0b40d55766e 100644 --- a/packages/fields/src/types/checkbox/views/index.tsx +++ b/packages/fields/src/types/checkbox/views/index.tsx @@ -72,9 +72,8 @@ export const controller = (config: FieldControllerConfig): CheckboxController => Filter() { return null; }, - graphql({ type, value }) { - const key = type === 'is' ? `${config.path}` : `${config.path}_${type}`; - return { [key]: value }; + graphql({ type }) { + return { [config.path]: { equals: type === 'is' } }; }, Label({ label }) { return label.toLowerCase(); diff --git a/packages/fields/src/types/decimal/index.ts b/packages/fields/src/types/decimal/index.ts index a4b234cdda0..fdfdcaa1abf 100644 --- a/packages/fields/src/types/decimal/index.ts +++ b/packages/fields/src/types/decimal/index.ts @@ -8,6 +8,7 @@ import { Decimal, legacyFilters, FieldDefaultValue, + filters, } from '@keystone-next/types'; import { resolveView } from '../../resolve-view'; import { getIndexType } from '../../get-index-type'; @@ -66,6 +67,10 @@ export const decimal = })({ ...config, input: { + where: { + arg: schema.arg({ type: filters[meta.provider].Decimal.optional }), + resolve: filters.resolveCommon, + }, create: { arg: schema.arg({ type: schema.String }), resolve(val) { diff --git a/packages/fields/src/types/decimal/views/index.tsx b/packages/fields/src/types/decimal/views/index.tsx index 2d135af2d15..7e8b1cea9b8 100644 --- a/packages/fields/src/types/decimal/views/index.tsx +++ b/packages/fields/src/types/decimal/views/index.tsx @@ -70,14 +70,16 @@ export const controller = (config: Config): FieldController => { }, graphql: ({ type, value }) => { - const key = type === 'is' ? config.path : `${config.path}_${type}`; const valueWithoutWhitespace = value.replace(/\s/g, ''); - - return { - [key]: ['in', 'not_in'].includes(type) - ? valueWithoutWhitespace.split(',').map(i => i) - : valueWithoutWhitespace, - }; + const parsed = + type === 'in' || type === 'not_in' + ? valueWithoutWhitespace.split(',') + : valueWithoutWhitespace; + if (type === 'not') { + return { [config.path]: { not: { equals: parsed } } }; + } + const key = type === 'is' ? 'equals' : type === 'not_in' ? 'notIn' : type; + return { [config.path]: { [key]: parsed } }; }, Label({ label, value, type }) { let renderedValue = value; diff --git a/packages/fields/src/types/float/index.ts b/packages/fields/src/types/float/index.ts index c1baa891d85..a7522d3d017 100644 --- a/packages/fields/src/types/float/index.ts +++ b/packages/fields/src/types/float/index.ts @@ -7,6 +7,7 @@ import { orderDirectionEnum, legacyFilters, FieldDefaultValue, + filters, } from '@keystone-next/types'; import { resolveView } from '../../resolve-view'; import { getIndexType } from '../../get-index-type'; @@ -36,6 +37,10 @@ export const float = })({ ...config, input: { + where: { + arg: schema.arg({ type: filters[meta.provider].Float.optional }), + resolve: filters.resolveCommon, + }, create: { arg: schema.arg({ type: schema.Float }) }, update: { arg: schema.arg({ type: schema.Float }) }, orderBy: { arg: schema.arg({ type: orderDirectionEnum }) }, diff --git a/packages/fields/src/types/float/views/index.tsx b/packages/fields/src/types/float/views/index.tsx index 42c845075e1..8dd79257d11 100644 --- a/packages/fields/src/types/float/views/index.tsx +++ b/packages/fields/src/types/float/views/index.tsx @@ -68,14 +68,16 @@ export const controller = (config: FieldControllerConfig): FieldController { - const key = type === 'is' ? config.path : `${config.path}_${type}`; const valueWithoutWhitespace = value.replace(/\s/g, ''); - - return { - [key]: ['in', 'not_in'].includes(type) - ? valueWithoutWhitespace.split(',').map(i => parseFloat(i)) - : parseFloat(valueWithoutWhitespace), - }; + const parsed = + type === 'in' || type === 'not_in' + ? valueWithoutWhitespace.split(',').map(x => parseFloat(x)) + : parseFloat(valueWithoutWhitespace); + if (type === 'not') { + return { [config.path]: { not: { equals: parsed } } }; + } + const key = type === 'is' ? 'equals' : type === 'not_in' ? 'notIn' : type; + return { [config.path]: { [key]: parsed } }; }, Label({ label, value, type }) { let renderedValue = value; diff --git a/packages/fields/src/types/integer/index.ts b/packages/fields/src/types/integer/index.ts index 744bc9d849a..96c07d9af88 100644 --- a/packages/fields/src/types/integer/index.ts +++ b/packages/fields/src/types/integer/index.ts @@ -7,6 +7,7 @@ import { legacyFilters, orderDirectionEnum, schema, + filters, } from '@keystone-next/types'; import { resolveView } from '../../resolve-view'; import { getIndexType } from '../../get-index-type'; @@ -37,6 +38,10 @@ export const integer = ...config, input: { uniqueWhere: isUnique ? { arg: schema.arg({ type: schema.Int }) } : undefined, + where: { + arg: schema.arg({ type: filters[meta.provider].Int.optional }), + resolve: filters.resolveCommon, + }, create: { arg: schema.arg({ type: schema.Int }) }, update: { arg: schema.arg({ type: schema.Int }) }, orderBy: { arg: schema.arg({ type: orderDirectionEnum }) }, diff --git a/packages/fields/src/types/integer/views/index.tsx b/packages/fields/src/types/integer/views/index.tsx index f05f3427065..c1de20b4f05 100644 --- a/packages/fields/src/types/integer/views/index.tsx +++ b/packages/fields/src/types/integer/views/index.tsx @@ -72,14 +72,16 @@ export const controller = (config: FieldControllerConfig): FieldController { - const key = type === 'is' ? config.path : `${config.path}_${type}`; const valueWithoutWhitespace = value.replace(/\s/g, ''); - - return { - [key]: ['in', 'not_in'].includes(type) - ? valueWithoutWhitespace.split(',').map(i => parseInt(i)) - : parseInt(valueWithoutWhitespace), - }; + const parsed = + type === 'in' || type === 'not_in' + ? valueWithoutWhitespace.split(',').map(x => parseInt(x)) + : parseInt(valueWithoutWhitespace); + if (type === 'not') { + return { [config.path]: { not: { equals: parsed } } }; + } + const key = type === 'is' ? 'equals' : type === 'not_in' ? 'notIn' : type; + return { [config.path]: { [key]: parsed } }; }, Label({ label, value, type }) { let renderedValue = value; diff --git a/packages/fields/src/types/password/index.ts b/packages/fields/src/types/password/index.ts index 3f3a10017d3..3bfbc35dc9e 100644 --- a/packages/fields/src/types/password/index.ts +++ b/packages/fields/src/types/password/index.ts @@ -34,6 +34,13 @@ const PasswordState = schema.object<{ isSet: boolean }>()({ }, }); +const PasswordFilter = schema.inputObject({ + name: 'PasswordFilter', + fields: { + isSet: schema.arg({ type: schema.nonNull(schema.Boolean) }), + }, +}); + const bcryptHashRegex = /^\$2[aby]?\$\d{1,2}\$[.\/A-Za-z0-9]{53}$/; export const password = @@ -89,6 +96,20 @@ export const password = })({ ...config, input: { + where: { + arg: schema.arg({ type: PasswordFilter }), + resolve(val) { + if (val === null) { + throw new Error('Password filters cannot be set to null'); + } + if (val.isSet) { + return { + not: null, + }; + } + return null; + }, + }, create: { arg: schema.arg({ type: schema.String }), resolve: inputResolver, diff --git a/packages/fields/src/types/password/views/index.tsx b/packages/fields/src/types/password/views/index.tsx index 0c1ecbfdb5a..7b8b29a3aad 100644 --- a/packages/fields/src/types/password/views/index.tsx +++ b/packages/fields/src/types/password/views/index.tsx @@ -200,8 +200,8 @@ export const controller = ( /> ); }, - graphql: ({ type, value }) => { - return { [`${config.path}_${type}`]: value }; + graphql: ({ value }) => { + return { [config.path]: { isSet: value } }; }, Label({ value }) { return value ? 'is set' : 'is not set'; diff --git a/packages/fields/src/types/relationship/index.ts b/packages/fields/src/types/relationship/index.ts index 65014067a40..6d937dcf8f1 100644 --- a/packages/fields/src/types/relationship/index.ts +++ b/packages/fields/src/types/relationship/index.ts @@ -153,6 +153,12 @@ export const relationship = })({ ...commonConfig, input: { + where: { + arg: schema.arg({ type: listTypes.relateTo.many.where }), + resolve(value, context, resolve) { + return resolve(value); + }, + }, create: { arg: schema.arg({ type: listTypes.relateTo.many.create, @@ -217,6 +223,12 @@ export const relationship = })({ ...commonConfig, input: { + where: { + arg: schema.arg({ type: listTypes.where }), + resolve(value, context, resolve) { + return resolve(value); + }, + }, create: { arg: schema.arg({ type: listTypes.relateTo.one.create }), async resolve(value, context, resolve) { diff --git a/packages/fields/src/types/relationship/tests/implementation.test.ts b/packages/fields/src/types/relationship/tests/implementation.test.ts index ea93d65957f..54de9fd8d69 100644 --- a/packages/fields/src/types/relationship/tests/implementation.test.ts +++ b/packages/fields/src/types/relationship/tests/implementation.test.ts @@ -123,7 +123,7 @@ describe('Type Generation', () => { expect(printType(schema.getType('Test')!)).toMatchInlineSnapshot(` "type Test { id: ID! - foo(where: ZipWhereInput! = {}, orderBy: [ZipOrderByInput!]! = [], first: Int, skip: Int! = 0): [Zip!] + foo(where: ZipWhereInput! = {}, orderBy: [ZipOrderByInput!]! = [], take: Int, skip: Int! = 0): [Zip!] fooCount(where: ZipWhereInput! = {}): Int }" `); @@ -135,7 +135,7 @@ describe('Type Generation', () => { expect(printType(schema.getType('Test')!)).toMatchInlineSnapshot(` "type Test { id: ID! - foo(where: ZipWhereInput! = {}, orderBy: [ZipOrderByInput!]! = [], first: Int, skip: Int! = 0): [Zip!] + foo(where: ZipWhereInput! = {}, orderBy: [ZipOrderByInput!]! = [], take: Int, skip: Int! = 0): [Zip!] }" `); }); diff --git a/packages/fields/src/types/relationship/views/RelationshipSelect.tsx b/packages/fields/src/types/relationship/views/RelationshipSelect.tsx index 44446e7bdd1..6f0a6980c26 100644 --- a/packages/fields/src/types/relationship/views/RelationshipSelect.tsx +++ b/packages/fields/src/types/relationship/views/RelationshipSelect.tsx @@ -105,10 +105,10 @@ export const RelationshipSelect = ({ const QUERY: TypedDocumentNode< { items: { [idField]: string; [labelField]: string | null }[]; count: number }, - { where: Record; first: number; skip: number } + { where: Record; take: number; skip: number } > = gql` - query RelationshipSelect($where: ${list.gqlNames.whereInputName}!, $first: Int!, $skip: Int!) { - items: ${list.gqlNames.listQueryName}(where: $where, first: $first, skip: $skip) { + query RelationshipSelect($where: ${list.gqlNames.whereInputName}!, $take: Int!, $skip: Int!) { + items: ${list.gqlNames.listQueryName}(where: $where, take: $take, skip: $skip) { ${idField}: id ${labelField}: ${list.labelField} ${extraSelection} @@ -121,7 +121,7 @@ export const RelationshipSelect = ({ const { data, error, loading, fetchMore } = useQuery(QUERY, { fetchPolicy: 'network-only', - variables: { where, first: initialItemsToLoad, skip: 0 }, + variables: { where, take: initialItemsToLoad, skip: 0 }, }); const count = data?.count || 0; @@ -146,10 +146,10 @@ export const RelationshipSelect = ({ if (!loading && isIntersecting && options.length < count) { const QUERY: TypedDocumentNode< { items: { [idField]: string; [labelField]: string | null }[] }, - { where: Record; first: number; skip: number } + { where: Record; take: number; skip: number } > = gql` - query RelationshipSelectMore($where: ${list.gqlNames.whereInputName}!, $first: Int!, $skip: Int!) { - items: ${list.gqlNames.listQueryName}(where: $where, first: $first, skip: $skip) { + query RelationshipSelectMore($where: ${list.gqlNames.whereInputName}!, $take: Int!, $skip: Int!) { + items: ${list.gqlNames.listQueryName}(where: $where, take: $take, skip: $skip) { ${labelField}: ${list.labelField} ${idField}: id ${extraSelection} @@ -160,7 +160,7 @@ export const RelationshipSelect = ({ query: QUERY, variables: { where, - first: subsequentItemsToLoad, + take: subsequentItemsToLoad, skip: data!.items.length, }, updateQuery: (prev, { fetchMoreResult }) => { diff --git a/packages/fields/src/types/select/index.ts b/packages/fields/src/types/select/index.ts index 78130da1f6b..8ec53f754e8 100644 --- a/packages/fields/src/types/select/index.ts +++ b/packages/fields/src/types/select/index.ts @@ -8,6 +8,7 @@ import { legacyFilters, orderDirectionEnum, schema, + filters, } from '@keystone-next/types'; // @ts-ignore import inflection from 'inflection'; @@ -68,6 +69,10 @@ export const select = })({ ...commonConfig, input: { + where: { + arg: schema.arg({ type: filters[meta.provider].Int.optional }), + resolve: filters.resolveCommon, + }, create: { arg: schema.arg({ type: schema.Int }) }, update: { arg: schema.arg({ type: schema.Int }) }, orderBy: { arg: schema.arg({ type: orderDirectionEnum }) }, @@ -96,6 +101,10 @@ export const select = )({ ...commonConfig, input: { + where: { + arg: schema.arg({ type: filters[meta.provider].enum(graphQLType).optional }), + resolve: filters.resolveCommon, + }, create: { arg: schema.arg({ type: graphQLType }) }, update: { arg: schema.arg({ type: graphQLType }) }, orderBy: { arg: schema.arg({ type: orderDirectionEnum }) }, @@ -109,6 +118,10 @@ export const select = return fieldType({ kind: 'scalar', scalar: 'String', mode: 'optional', index })({ ...commonConfig, input: { + where: { + arg: schema.arg({ type: filters[meta.provider].String.optional }), + resolve: filters.resolveString, + }, create: { arg: schema.arg({ type: schema.String }) }, update: { arg: schema.arg({ type: schema.String }) }, orderBy: { arg: schema.arg({ type: orderDirectionEnum }) }, diff --git a/packages/fields/src/types/select/views/index.tsx b/packages/fields/src/types/select/views/index.tsx index 6fccd3a0bc0..ca3c939064f 100644 --- a/packages/fields/src/types/select/views/index.tsx +++ b/packages/fields/src/types/select/views/index.tsx @@ -116,31 +116,9 @@ export const controller = ( /> ); }, - - graphql: ({ type, value: options }) => { - const inverted = type === 'not_matches'; - - if (!options.length) { - return { - [`${config.path}${inverted ? '_not' : ''}`]: null, - }; - } - - const isMulti = options.length > 1; - - let key = config.path; - if (isMulti && inverted) { - key = `${config.path}_not_in`; - } else if (isMulti) { - key = `${config.path}_in`; - } else if (inverted) { - key = `${config.path}_not`; - } - - const value = isMulti ? options.map(x => t(x.value)) : t(options[0].value); - - return { [key]: value }; - }, + graphql: ({ type, value: options }) => ({ + [config.path]: { [type === 'not_matches' ? 'notIn' : 'in']: options.map(x => t(x.value)) }, + }), Label({ type, value }) { if (!value.length) { return type === 'not_matches' ? `is set` : `has no value`; diff --git a/packages/fields/src/types/text/index.ts b/packages/fields/src/types/text/index.ts index 8fe1e69f746..ecedaf0a5b4 100644 --- a/packages/fields/src/types/text/index.ts +++ b/packages/fields/src/types/text/index.ts @@ -7,6 +7,7 @@ import { orderDirectionEnum, FieldTypeFunc, legacyFilters, + filters, } from '@keystone-next/types'; import { resolveView } from '../../resolve-view'; import { getIndexType } from '../../get-index-type'; @@ -40,6 +41,10 @@ export const text = ...config, input: { uniqueWhere: isUnique ? { arg: schema.arg({ type: schema.String }) } : undefined, + where: { + arg: schema.arg({ type: filters[meta.provider].String.optional }), + resolve: filters.resolveString, + }, create: { arg: schema.arg({ type: schema.String }) }, update: { arg: schema.arg({ type: schema.String }) }, orderBy: { arg: schema.arg({ type: orderDirectionEnum }) }, @@ -47,7 +52,10 @@ export const text = output: schema.field({ type: schema.String }), views: resolveView('text/views'), getAdminMeta() { - return { displayMode: config.ui?.displayMode ?? 'input' }; + return { + displayMode: config.ui?.displayMode ?? 'input', + shouldUseModeInsensitive: meta.provider === 'postgresql', + }; }, __legacy: { filters: { diff --git a/packages/fields/src/types/text/views/index.tsx b/packages/fields/src/types/text/views/index.tsx index c9fd5cc0245..1405b86df73 100644 --- a/packages/fields/src/types/text/views/index.tsx +++ b/packages/fields/src/types/text/views/index.tsx @@ -50,7 +50,10 @@ export const CardValue: CardValueComponent = ({ item, field }) => { ); }; -type Config = FieldControllerConfig<{ displayMode: 'input' | 'textarea' }>; +type Config = FieldControllerConfig<{ + displayMode: 'input' | 'textarea'; + shouldUseModeInsensitive: boolean; +}>; export const controller = ( config: Config @@ -80,13 +83,25 @@ export const controller = ( }, graphql: ({ type, value }) => { - const key = type === 'is_i' ? `${config.path}_i` : `${config.path}_${type}`; - return { [key]: value }; + const isNot = type.startsWith('not_'); + const key = + type === 'is_i' || type === 'not_i' + ? 'equals' + : type + .replace(/_i$/, '') + .replace('not_', '') + .replace(/_([a-z])/g, (_, char: string) => char.toUpperCase()); + const filter = { [key]: value }; + return { + [config.path]: { + ...(isNot ? { not: filter } : filter), + mode: config.fieldMeta.shouldUseModeInsensitive ? 'insensitive' : undefined, + }, + }; }, Label({ label, value }) { return `${label.toLowerCase()}: "${value}"`; }, - // FIXME: Not all of these options will work with prisma_sqlite types: { contains_i: { label: 'Contains', diff --git a/packages/fields/src/types/timestamp/index.ts b/packages/fields/src/types/timestamp/index.ts index 81df675377d..b5203d908ab 100644 --- a/packages/fields/src/types/timestamp/index.ts +++ b/packages/fields/src/types/timestamp/index.ts @@ -7,6 +7,7 @@ import { orderDirectionEnum, legacyFilters, FieldDefaultValue, + filters, } from '@keystone-next/types'; import { resolveView } from '../../resolve-view'; import { getIndexType } from '../../get-index-type'; @@ -42,6 +43,10 @@ export const timestamp = })({ ...config, input: { + where: { + arg: schema.arg({ type: filters[meta.provider].DateTime.optional }), + resolve: filters.resolveCommon, + }, create: { arg: schema.arg({ type: schema.String }), resolve: inputResolver }, update: { arg: schema.arg({ type: schema.String }), resolve: inputResolver }, orderBy: { arg: schema.arg({ type: orderDirectionEnum }) }, diff --git a/packages/keystone/CHANGELOG.md b/packages/keystone/CHANGELOG.md index eb2919d6459..718e85be1cd 100644 --- a/packages/keystone/CHANGELOG.md +++ b/packages/keystone/CHANGELOG.md @@ -1,5 +1,170 @@ # @keystone-next/keystone +## 24.0.0 + +### Major Changes + +- [#6196](https://github.com/keystonejs/keystone/pull/6196) [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - Removed `_ListKeyMeta` and `_toManyRelationshipFieldMeta` fields. You should use `listKeyCount` and `toManyRelationshipFieldCount` instead + +* [#6196](https://github.com/keystonejs/keystone/pull/6196) [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - Removed all arguments from `context.lists.List.count` and `context.db.lists.List.count` except for `where`. + +- [#6266](https://github.com/keystonejs/keystone/pull/6266) [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - Renamed `first` argument in find many queries to `take` to align with Prisma. + + ```graphql + type Query { + users( + where: UserWhereInput! = {} + orderBy: [UserOrderByInput!]! = [] + # previously was first: Int + take: Int + skip: Int! = 0 + ): [User!] + # ... + } + + type User { + # ... + posts( + where: PostWhereInput! = {} + orderBy: [PostOrderByInput!]! = [] + # previously was first: Int + take: Int + skip: Int! = 0 + ): [Post!] + # ... + } + ``` + +* [#6208](https://github.com/keystonejs/keystone/pull/6208) [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - The create one mutation now requires a non-null `data` argument and the create many mutation accepts a list of `ItemCreateInput` directly instead of being nested inside of an object with the `ItemCreateInput` in a `data` field. + + If you have a list called `Item`, `createItem` now looks like `createItem(data: ItemCreateInput!): Item` and `createItems` now looks like `createItems(data: [ItemCreateInput!]!): [Item]`. + +- [#6196](https://github.com/keystonejs/keystone/pull/6196) [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - Removed `search` argument from the GraphQL API for finding many items, Lists/DB API and to-many relationship fields. You should use `contains` filters instead. + +* [#6095](https://github.com/keystonejs/keystone/pull/6095) [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - Updated filters to be nested instead of flattened and add top-level `NOT` operator. See the [Query Filter API docs](https://keystonejs.com/docs/apis/filters) and the upgrade guide for more information. + + ```graphql + query { + posts(where: { title: { contains: "Something" } }) { + title + content + } + } + ``` + +- [#6198](https://github.com/keystonejs/keystone/pull/6198) [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b) Thanks [@timleslie](https://github.com/timleslie)! - Removed the `uid` and `name` properties from the errors returned by the GraphQL API. + +* [#6196](https://github.com/keystonejs/keystone/pull/6196) [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - Removed `sortBy` argument from the GraphQL API for finding many items, Lists/DB API and to-many relationship fields. You should use `orderBy` instead. + +- [#6312](https://github.com/keystonejs/keystone/pull/6312) [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - Updated `@graphql-ts/schema`. The second type parameter of `schema.Arg` exported from `@keystone-next/types` is now a boolean that defines whether or not the arg has a default value to make it easier to define circular input objects. + +* [#6217](https://github.com/keystonejs/keystone/pull/6217) [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - `disconnectAll` has been renamed to `disconnect` in to-one relationship inputs and the old `disconnect` field has been removed. There are also seperate input types for create and update where the input for create doesn't have `disconnect`. It's also now required that if you provide a to-one relationship input, you must provide exactly one field to the input. + + If you have a list called `Item`, the to-one relationship inputs now look like this: + + ```graphql + input ItemRelateToOneForCreateInput { + create: ItemCreateInput + connect: ItemWhereUniqueInput + } + input ItemRelateToOneForUpdateInput { + create: ItemCreateInput + connect: ItemWhereUniqueInput + disconnect: Boolean + } + ``` + +- [#6224](https://github.com/keystonejs/keystone/pull/6224) [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - `disconnectAll` has been replaced by `set` in to-many relationship inputs, the equivalent to `disconnectAll: true` is now `set: []`. There are also seperate input types for create and update where the input for create doesn't have `disconnect` or `set`. The inputs in the lists in the input field are now also non-null. + + If you have a list called `Item`, the to-many relationship inputs now look like this: + + ```graphql + input ItemRelateToManyForCreateInput { + create: [ItemCreateInput!] + connect: [ItemWhereUniqueInput!] + } + input ItemRelateToManyForUpdateInput { + disconnect: [ItemWhereUniqueInput!] + set: [ItemWhereUniqueInput!] + create: [ItemCreateInput!] + connect: [ItemWhereUniqueInput!] + } + ``` + +* [#6197](https://github.com/keystonejs/keystone/pull/6197) [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - The generated CRUD queries, and some of the input types, in the GraphQL API have been renamed. + + If you have a list called `Item`, the query for multiple values, `allItems` will be renamed to `items`. The query for a single value, `Item`, will be renamed to `item`. + + Also, the input type used in the `updateItems` mutation has been renamed from `ItemsUpdateInput` to `ItemUpdateArgs`. + +- [#6211](https://github.com/keystonejs/keystone/pull/6211) [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - The update mutations now accept `where` unique inputs instead of only an `id` and the `where` and `data` arguments are non-null. + + If you have a list called `Item`, the update mutations now look like this: + + ```graphql + type Mutation { + updateItem(where: ItemWhereUniqueInput!, data: ItemUpdateInput!): Item + updateItems(data: [ItemUpdateArgs!]!): [Item] + } + + input ItemUpdateArgs { + where: ItemWhereUniqueInput! + data: ItemUpdateInput! + } + ``` + +* [#6206](https://github.com/keystonejs/keystone/pull/6206) [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - The delete mutations now accept `where` unique inputs instead of only an `id`. + + If you have a list called `Item`, `deleteItem` now looks like `deleteItem(where: ItemWhereUniqueInput!): Item` and `deleteItems` now looks like `deleteItems(where: [ItemWhereUniqueInput!]!): [Item]` + +### Minor Changes + +- [#6276](https://github.com/keystonejs/keystone/pull/6276) [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb) Thanks [@gautamsi](https://github.com/gautamsi)! - Added option for `Bearer` token auth when using session. + +* [#6267](https://github.com/keystonejs/keystone/pull/6267) [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590) Thanks [@timleslie](https://github.com/timleslie)! - Added `config.graphql.debug` option, which can be used to control whether debug information such as stack traces are included in the errors returned by the GraphQL API. + +### Patch Changes + +- [#6317](https://github.com/keystonejs/keystone/pull/6317) [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18) Thanks [@timleslie](https://github.com/timleslie)! - Separated the resolving of non-relationship field from relationship fields in create/update inputs to allow for better error handling. + +* [#6250](https://github.com/keystonejs/keystone/pull/6250) [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450) Thanks [@timleslie](https://github.com/timleslie)! - Updated internal type definitions. + +- [#6334](https://github.com/keystonejs/keystone/pull/6334) [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0) Thanks [@gwyneplaine](https://github.com/gwyneplaine)! - Resolved bug with visually hidden elements in ListView checkboxes expanding to fill the whole body on click of elements near the bottom of the screen. + +* [#6219](https://github.com/keystonejs/keystone/pull/6219) [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271) Thanks [@timleslie](https://github.com/timleslie)! - Removed unused code path in Admin UI error display. + +- [#6269](https://github.com/keystonejs/keystone/pull/6269) [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93) Thanks [@gwyneplaine](https://github.com/gwyneplaine)! - Added ignoreBuildErrors flag to next-config.js file, to negate false positive errors in keystone builds with imported components. + +* [#6218](https://github.com/keystonejs/keystone/pull/6218) [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2) Thanks [@timleslie](https://github.com/timleslie)! - Added more details to validation failure error messages. + +- [#6316](https://github.com/keystonejs/keystone/pull/6316) [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4) Thanks [@timleslie](https://github.com/timleslie)! - Updated handling of errors in `resolveInput` hooks to provide developers with appropriate debug information. + +* [#6310](https://github.com/keystonejs/keystone/pull/6310) [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053) Thanks [@timleslie](https://github.com/timleslie)! - Updated dependencies to use `mergeSchemas` from `@graphql-tools/schema`, rather than its old location in `@graphql-tools/merge`. You might see a reordering of the contents of your `graphql.schema` file. + +- [#6292](https://github.com/keystonejs/keystone/pull/6292) [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3) Thanks [@renovate](https://github.com/apps/renovate)! - Updated Prisma dependencies to `2.29.1`. + +* [#6263](https://github.com/keystonejs/keystone/pull/6263) [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524) Thanks [@timleslie](https://github.com/timleslie)! - Made the original stacktraces for before/after hooks available on `error.extension.errors`. + +- [#6259](https://github.com/keystonejs/keystone/pull/6259) [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15) Thanks [@gwyneplaine](https://github.com/gwyneplaine)! - Bumped @apollo/client dependency to ^3.4.5, the update resolves the following useQuery [issue](https://github.com/keystonejs/keystone/issues/6254). + +* [#6239](https://github.com/keystonejs/keystone/pull/6239) [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae) Thanks [@timleslie](https://github.com/timleslie)! - Added more details to before/after change/delete hook error messages. + +- [#6248](https://github.com/keystonejs/keystone/pull/6248) [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e) Thanks [@timleslie](https://github.com/timleslie)! - Removed unused dependency `@graphql-tools/schema`. + +* [#6203](https://github.com/keystonejs/keystone/pull/6203) [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3) Thanks [@renovate](https://github.com/apps/renovate)! - Updated Prisma dependencies to `2.28.0`. + +- [#6296](https://github.com/keystonejs/keystone/pull/6296) [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7) Thanks [@gwyneplaine](https://github.com/gwyneplaine)! - Fixed delete success notifications in the Admin UI appearing on failed deletes in List view and Item view. + +* [#6200](https://github.com/keystonejs/keystone/pull/6200) [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e) Thanks [@timleslie](https://github.com/timleslie)! - Updated internal error handling to use the `apollo-server-errors` package instead of `apollo-errors`. + +* Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`c2bb6a9a5`](https://github.com/keystonejs/keystone/commit/c2bb6a9a596fc52a3c61ec5d91c79758e417e61d), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`8187ea019`](https://github.com/keystonejs/keystone/commit/8187ea019a212874f3c602573af3382c6f3bd3b2), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/types@24.0.0 + - @keystone-ui/notice@4.0.1 + - @keystone-ui/toast@4.0.2 + - @keystone-next/admin-ui-utils@5.0.6 + - @keystone-next/utils@1.0.4 + ## 23.0.3 ### Patch Changes diff --git a/packages/keystone/package.json b/packages/keystone/package.json index 5c70c4c0abc..d2be3d4829e 100644 --- a/packages/keystone/package.json +++ b/packages/keystone/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/keystone", - "version": "23.0.3", + "version": "24.0.0", "license": "MIT", "main": "dist/keystone.cjs.js", "module": "dist/keystone.esm.js", @@ -22,33 +22,33 @@ "keystone-next": "bin/cli.js" }, "dependencies": { - "@apollo/client": "3.3.21", - "@babel/core": "^7.14.8", - "@babel/plugin-transform-modules-commonjs": "^7.14.5", - "@babel/runtime": "^7.14.8", + "@apollo/client": "^3.4.8", + "@babel/core": "^7.15.0", + "@babel/plugin-transform-modules-commonjs": "^7.15.0", + "@babel/runtime": "^7.15.3", "@emotion/hash": "^0.8.0", - "@graphql-tools/merge": "^6.2.16", + "@graphql-tools/schema": "^8.1.1", "@hapi/iron": "^6.0.0", - "@keystone-next/admin-ui-utils": "^5.0.5", - "@keystone-next/fields": "^13.0.0", - "@keystone-next/types": "^23.0.0", - "@keystone-next/utils": "^1.0.3", + "@keystone-next/admin-ui-utils": "^5.0.6", + "@keystone-next/fields": "^14.0.0", + "@keystone-next/types": "^24.0.0", + "@keystone-next/utils": "^1.0.4", "@keystone-ui/button": "^5.0.0", "@keystone-ui/core": "^3.1.1", "@keystone-ui/fields": "^4.1.2", "@keystone-ui/icons": "^4.0.0", "@keystone-ui/loading": "^4.0.0", "@keystone-ui/modals": "^4.0.0", - "@keystone-ui/notice": "^4.0.0", + "@keystone-ui/notice": "^4.0.1", "@keystone-ui/options": "^4.0.1", "@keystone-ui/pill": "^5.0.0", "@keystone-ui/popover": "^4.0.2", - "@keystone-ui/toast": "^4.0.1", + "@keystone-ui/toast": "^4.0.2", "@keystone-ui/tooltip": "^4.0.1", "@preconstruct/next": "^3.0.0", - "@prisma/client": "2.28.0", - "@prisma/migrate": "2.28.0", - "@prisma/sdk": "2.28.0", + "@prisma/client": "2.29.1", + "@prisma/migrate": "2.29.1", + "@prisma/sdk": "2.29.1", "@sindresorhus/slugify": "^1.1.2", "@types/apollo-upload-client": "14.1.0", "@types/babel__core": "^7.1.15", @@ -94,7 +94,7 @@ "pirates": "^4.0.1", "pluralize": "^8.0.0", "prettier": "^2.3.2", - "prisma": "2.28.0", + "prisma": "2.29.1", "prompts": "^2.4.1", "react": "^17.0.2", "react-dom": "^17.0.2", diff --git a/packages/keystone/src/___internal-do-not-use-will-break-in-patch/admin-ui/id-field-view.tsx b/packages/keystone/src/___internal-do-not-use-will-break-in-patch/admin-ui/id-field-view.tsx index 53d48f340f5..cba2c258087 100644 --- a/packages/keystone/src/___internal-do-not-use-will-break-in-patch/admin-ui/id-field-view.tsx +++ b/packages/keystone/src/___internal-do-not-use-will-break-in-patch/admin-ui/id-field-view.tsx @@ -53,13 +53,18 @@ export const controller = ( }, graphql: ({ type, value }) => { - const key = type === 'is' ? config.path : `${config.path}_${type}`; + if (type === 'not') { + return { [config.path]: { not: { equals: value } } }; + } const valueWithoutWhitespace = value.replace(/\s/g, ''); + const key = type === 'is' ? 'equals' : type === 'not_in' ? 'notIn' : type; return { - [key]: ['in', 'not_in'].includes(type) - ? valueWithoutWhitespace.split(',') - : valueWithoutWhitespace, + [config.path]: { + [key]: ['in', 'not_in'].includes(type) + ? valueWithoutWhitespace.split(',') + : valueWithoutWhitespace, + }, }; }, Label({ label, value, type }) { diff --git a/packages/keystone/src/___internal-do-not-use-will-break-in-patch/admin-ui/next-config.ts b/packages/keystone/src/___internal-do-not-use-will-break-in-patch/admin-ui/next-config.ts index e7c0984a39f..db51999f8e2 100644 --- a/packages/keystone/src/___internal-do-not-use-will-break-in-patch/admin-ui/next-config.ts +++ b/packages/keystone/src/___internal-do-not-use-will-break-in-patch/admin-ui/next-config.ts @@ -3,6 +3,9 @@ import Path from 'path'; import withPreconstruct from '@preconstruct/next'; export const config = withPreconstruct({ + typescript: { + ignoreBuildErrors: true, + }, webpack(config: any, { isServer }: any) { config.resolve.alias = { ...config.resolve.alias, diff --git a/packages/keystone/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ItemPage/index.tsx b/packages/keystone/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ItemPage/index.tsx index 5ea383f38be..a49288a34c7 100644 --- a/packages/keystone/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ItemPage/index.tsx +++ b/packages/keystone/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ItemPage/index.tsx @@ -253,17 +253,19 @@ function DeleteButton({ confirm: { label: 'Delete', action: async () => { - await deleteItem().catch(err => { - toasts.addToast({ - title: 'Failed to delete item', + try { + await deleteItem(); + } catch (err) { + return toasts.addToast({ + title: `Failed to delete ${list.singular} item: ${itemLabel}`, message: err.message, tone: 'negative', }); - }); + } router.push(`/${list.path}`); - toasts.addToast({ + return toasts.addToast({ title: itemLabel, - message: 'Deleted successfully', + message: `Deleted ${list.singular} item successfully`, tone: 'positive', }); }, diff --git a/packages/keystone/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ListPage/index.tsx b/packages/keystone/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ListPage/index.tsx index e3b977c8737..a3f1e6203ca 100644 --- a/packages/keystone/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ListPage/index.tsx +++ b/packages/keystone/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ListPage/index.tsx @@ -176,12 +176,12 @@ const ListPage = ({ listKey }: ListPageProps) => { }) .join('\n'); return gql` - query ($where: ${list.gqlNames.whereInputName}, $first: Int!, $skip: Int!, $orderBy: [${ + query ($where: ${list.gqlNames.whereInputName}, $take: Int!, $skip: Int!, $orderBy: [${ list.gqlNames.listOrderName }!]) { items: ${ list.gqlNames.listQueryName - }(where: $where,first: $first, skip: $skip, orderBy: $orderBy) { + }(where: $where,take: $take, skip: $skip, orderBy: $orderBy) { ${ // TODO: maybe namespace all the fields instead of doing this selectedFields.has('id') ? '' : 'id' @@ -197,7 +197,7 @@ const ListPage = ({ listKey }: ListPageProps) => { errorPolicy: 'all', variables: { where: filters.where, - first: pageSize, + take: pageSize, skip: (currentPage - 1) * pageSize, orderBy: sort ? [{ [sort.field]: sort.direction.toLowerCase() }] : undefined, }, @@ -244,7 +244,6 @@ const ListPage = ({ listKey }: ListPageProps) => { const theme = useTheme(); const showCreate = !(metaQuery.data?.keystone.adminMeta.list?.hideCreate ?? true) || null; - return ( }> {metaQuery.error ? ( @@ -436,14 +435,18 @@ function DeleteManyButton({ useMemo( () => gql` - mutation($where: [${list.gqlNames.whereUniqueInputName}!]!) { - ${list.gqlNames.deleteManyMutationName}(where: $where) { - id - } - } + mutation($where: [${list.gqlNames.whereUniqueInputName}!]!) { + ${list.gqlNames.deleteManyMutationName}(where: $where) { + id + ${list.labelField} + } + } `, [list] - ) + ), + { + errorPolicy: 'all', + } ); const [isOpen, setIsOpen] = useState(false); const toasts = useToasts(); @@ -467,20 +470,75 @@ function DeleteManyButton({ confirm: { label: 'Delete', action: async () => { - await deleteItems({ + const { data, errors } = await deleteItems({ variables: { where: [...selectedItems].map(id => ({ id })) }, - }).catch(err => { + }); + /* + Data returns an array where successful deletions are item objects + and unsuccessful deletions are null values. + Run a reduce to count success and failure as well as + to generate the success message to be passed to the success toast + */ + const { successfulItems, unsuccessfulItems, successMessage } = data[ + list.gqlNames.deleteManyMutationName + ].reduce( + ( + acc: { + successfulItems: number; + unsuccessfulItems: number; + successMessage: string; + }, + curr: any + ) => { + if (curr) { + acc.successfulItems++; + acc.successMessage = + acc.successMessage === '' + ? (acc.successMessage += curr.label) + : (acc.successMessage += `, ${curr.label}`); + } else { + acc.unsuccessfulItems++; + } + return acc; + }, + { successfulItems: 0, unsuccessfulItems: 0, successMessage: '' } as { + successfulItems: number; + unsuccessfulItems: number; + successMessage: string; + } + ); + + // If there are errors + if (errors?.length) { + // Find out how many items failed to delete. + // Reduce error messages down to unique instances, and append to the toast as a message. toasts.addToast({ - title: 'Failed to delete items', - message: err.message, tone: 'negative', + title: `Failed to delete ${unsuccessfulItems} of ${ + data[list.gqlNames.deleteManyMutationName].length + } ${list.plural}`, + message: errors + .reduce((acc, error) => { + if (acc.indexOf(error.message) < 0) { + acc.push(error.message); + } + return acc; + }, [] as string[]) + .join('\n'), }); - }); - toasts.addToast({ - title: 'Deleted items successfully', - tone: 'positive', - }); - refetch(); + } + + if (successfulItems) { + toasts.addToast({ + tone: 'positive', + title: `Deleted ${successfulItems} of ${ + data[list.gqlNames.deleteManyMutationName].length + } ${list.plural} successfully`, + message: successMessage, + }); + } + + return refetch(); }, }, cancel: { @@ -523,7 +581,6 @@ function ListTable({ const { query } = useRouter(); const shouldShowLinkIcon = !list.fields[selectedFields.keys().next().value].views.Cell.supportsLinkTo; - return ( @@ -614,7 +671,7 @@ function ListTable({ minHeight: 38, alignItems: 'center', justifyContent: 'start', - // cursor: 'pointer', + position: 'relative', }} > ) => { padding: spacing.small, textAlign: 'left', position: 'sticky', + zIndex: 1, top: 0, }} {...props} diff --git a/packages/keystone/src/___internal-do-not-use-will-break-in-patch/next-graphql.ts b/packages/keystone/src/___internal-do-not-use-will-break-in-patch/next-graphql.ts index 0a032bfe62b..78ec432b4c4 100644 --- a/packages/keystone/src/___internal-do-not-use-will-break-in-patch/next-graphql.ts +++ b/packages/keystone/src/___internal-do-not-use-will-break-in-patch/next-graphql.ts @@ -15,7 +15,7 @@ export function nextGraphQLAPIRoute(keystoneConfig: KeystoneConfig, prismaClient graphQLSchema, createContext: keystone.createContext, sessionStrategy: initializedKeystoneConfig.session, - apolloConfig: initializedKeystoneConfig.graphql?.apolloConfig, + graphqlConfig: initializedKeystoneConfig.graphql, connectionPromise: keystone.connect(), }); diff --git a/packages/keystone/src/admin-ui/system/getAdminMetaSchema.ts b/packages/keystone/src/admin-ui/system/getAdminMetaSchema.ts index fcc65b63eda..29bf7753c32 100644 --- a/packages/keystone/src/admin-ui/system/getAdminMetaSchema.ts +++ b/packages/keystone/src/admin-ui/system/getAdminMetaSchema.ts @@ -1,4 +1,4 @@ -import { JSONValue, schema as schemaAPIFromTypesPkg } from '@keystone-next/types'; +import { JSONValue, QueryMode, schema as schemaAPIFromTypesPkg } from '@keystone-next/types'; import { KeystoneContext, KeystoneConfig, @@ -6,7 +6,7 @@ import { ListMetaRootVal, FieldMetaRootVal, } from '@keystone-next/types'; -import { GraphQLSchema, GraphQLObjectType, assertScalarType } from 'graphql'; +import { GraphQLSchema, GraphQLObjectType, assertScalarType, assertEnumType } from 'graphql'; import { InitialisedList } from '../../lib/core/types-for-lists'; const schema = { @@ -35,6 +35,10 @@ export function getAdminMetaSchema({ const jsonScalar = jsonScalarType ? schema.scalar(assertScalarType(jsonScalarType)) : schemaAPIFromTypesPkg.JSON; + const queryModeEnumType = graphQLSchema.getType('QueryMode'); + const queryModeEnum = queryModeEnumType + ? { ...QueryMode, graphQLType: assertEnumType(graphQLSchema.getType('QueryMode')) } + : QueryMode; const KeystoneAdminUIFieldMeta = schema.object()({ name: 'KeystoneAdminUIFieldMeta', @@ -153,10 +157,7 @@ export function getAdminMetaSchema({ }), }), search: schema.field({ - type: schema.enum({ - name: 'QueryMode', - values: schema.enumValues(['default', 'insensitive']), - }), + type: queryModeEnum, }), }, }); diff --git a/packages/keystone/src/admin-ui/templates/api.ts b/packages/keystone/src/admin-ui/templates/api.ts index 01d75117313..c779651e582 100644 --- a/packages/keystone/src/admin-ui/templates/api.ts +++ b/packages/keystone/src/admin-ui/templates/api.ts @@ -9,7 +9,7 @@ const apolloServer = createApolloServerMicro({ graphQLSchema, createContext, sessionStrategy: initializedKeystoneConfig.session ? initializedKeystoneConfig.session() : undefined, - apolloConfig: initializedKeystoneConfig.graphql?.apolloConfig, + graphqlConfig: initializedKeystoneConfig.graphql, connectionPromise: keystone.connect(), }); diff --git a/packages/keystone/src/lib/core/graphql-errors.ts b/packages/keystone/src/lib/core/graphql-errors.ts index cb760fd554d..6587864b984 100644 --- a/packages/keystone/src/lib/core/graphql-errors.ts +++ b/packages/keystone/src/lib/core/graphql-errors.ts @@ -7,9 +7,14 @@ export const validationFailureError = (messages: string[]) => { return new ApolloError(`You provided invalid data for this operation.\n${s}`); }; -export const extensionError = (extension: string, messages: string[]) => { - const s = messages.map(m => ` - ${m}`).join('\n'); - return new ApolloError(`An error occured while running "${extension}".\n${s}`); +export const extensionError = (extension: string, things: { error: Error; tag: string }[]) => { + const s = things.map(t => ` - ${t.tag}: ${t.error.message}`).join('\n'); + return new ApolloError( + `An error occured while running "${extension}".\n${s}`, + 'INTERNAL_SERVER_ERROR', + // Make the original stack traces available. + { debug: things.map(t => ({ stacktrace: t.error.stack, message: t.error.message })) } + ); }; // FIXME: In an upcoming PR we will use these args to construct a better diff --git a/packages/keystone/src/lib/core/mutations/access-control.ts b/packages/keystone/src/lib/core/mutations/access-control.ts index 51efe776857..0756a934f12 100644 --- a/packages/keystone/src/lib/core/mutations/access-control.ts +++ b/packages/keystone/src/lib/core/mutations/access-control.ts @@ -35,7 +35,7 @@ export async function getAccessControlledItemForDelete( // List access: pass 2 let where: PrismaFilter = mapUniqueWhereToWhere(list, uniqueWhere); if (typeof access === 'object') { - where = { AND: [where, await resolveWhereInput(access, list)] }; + where = { AND: [where, await resolveWhereInput(access, list, context)] }; } const item = await runWithPrisma(context, list, model => model.findFirst({ where })); if (item === null) { @@ -78,7 +78,9 @@ export async function getAccessControlledItemForUpdate( where: accessControl === true ? uniqueWhereInWhereForm - : { AND: [uniqueWhereInWhereForm, await resolveWhereInput(accessControl, list)] }, + : { + AND: [uniqueWhereInWhereForm, await resolveWhereInput(accessControl, list, context)], + }, }) ); if (!item) { diff --git a/packages/keystone/src/lib/core/mutations/create-update.ts b/packages/keystone/src/lib/core/mutations/create-update.ts index eda831a0393..289d34a9821 100644 --- a/packages/keystone/src/lib/core/mutations/create-update.ts +++ b/packages/keystone/src/lib/core/mutations/create-update.ts @@ -9,6 +9,7 @@ import { runWithPrisma, } from '../utils'; import { resolveUniqueWhereInput, UniqueInputFilter } from '../where-inputs'; +import { extensionError } from '../graphql-errors'; import { resolveRelateToManyForCreateInput, resolveRelateToManyForUpdateInput, @@ -179,21 +180,32 @@ async function getResolvedData( ); } - // Apply field type input resolvers + // Apply non-relationship field type input resolvers resolvedData = Object.fromEntries( await promiseAllRejectWithAllErrors( Object.entries(list.fields).map(async ([fieldKey, field]) => { const inputResolver = field.input?.[operation]?.resolve; let input = resolvedData[fieldKey]; - if (inputResolver) { + if (inputResolver && field.dbField.kind !== 'relation') { + input = await inputResolver(input, context, undefined); + } + return [fieldKey, input] as const; + }) + ) + ); + + // Apply relationship field type input resolvers + resolvedData = Object.fromEntries( + await promiseAllRejectWithAllErrors( + Object.entries(list.fields).map(async ([fieldKey, field]) => { + const inputResolver = field.input?.[operation]?.resolve; + let input = resolvedData[fieldKey]; + if (inputResolver && field.dbField.kind === 'relation') { input = await inputResolver( input, context, + // This third argument only applies to relationship fields (() => { - // This third argument only applies to relationship fields - if (field.dbField.kind !== 'relation') { - return undefined; - } if (input === undefined) { // No-op: This is what we want return () => undefined; @@ -228,23 +240,37 @@ async function getResolvedData( ); // Resolve input hooks - resolvedData = Object.fromEntries( - await promiseAllRejectWithAllErrors( - Object.entries(list.fields).map(async ([fieldKey, field]) => { - if (field.hooks.resolveInput === undefined) { - return [fieldKey, resolvedData[fieldKey]]; - } - const value = await field.hooks.resolveInput({ + const hookName = 'resolveInput'; + // Field hooks + let _resolvedData: Record = {}; + const fieldsErrors: { error: Error; tag: string }[] = []; + for (const [fieldPath, field] of Object.entries(list.fields)) { + if (field.hooks.resolveInput === undefined) { + _resolvedData[fieldPath] = resolvedData[fieldPath]; + } else { + try { + _resolvedData[fieldPath] = await field.hooks.resolveInput({ ...hookArgs, resolvedData, - fieldPath: fieldKey, + fieldPath, }); - return [fieldKey, value]; - }) - ) - ); + } catch (error) { + fieldsErrors.push({ error, tag: `${list.listKey}.${fieldPath}` }); + } + } + } + if (fieldsErrors.length) { + throw extensionError(hookName, fieldsErrors); + } + resolvedData = _resolvedData; + + // List hooks if (list.hooks.resolveInput) { - resolvedData = (await list.hooks.resolveInput({ ...hookArgs, resolvedData })) as any; + try { + resolvedData = (await list.hooks.resolveInput({ ...hookArgs, resolvedData })) as any; + } catch (error) { + throw extensionError(hookName, [{ error, tag: list.listKey }]); + } } return resolvedData; diff --git a/packages/keystone/src/lib/core/mutations/hooks.ts b/packages/keystone/src/lib/core/mutations/hooks.ts index 38cff0a8d7c..eeac512823f 100644 --- a/packages/keystone/src/lib/core/mutations/hooks.ts +++ b/packages/keystone/src/lib/core/mutations/hooks.ts @@ -31,14 +31,13 @@ export async function runSideEffectOnlyHook< } // Field hooks - const fieldsErrors = []; + const fieldsErrors: { error: Error; tag: string }[] = []; for (const [fieldPath, field] of Object.entries(list.fields)) { if (shouldRunFieldLevelHook(fieldPath)) { try { - // @ts-ignore await field.hooks[hookName]?.({ fieldPath, ...args }); - } catch (err) { - fieldsErrors.push(`${list.listKey}.${fieldPath}: ${err.message}`); + } catch (error) { + fieldsErrors.push({ error, tag: `${list.listKey}.${fieldPath}` }); } } } @@ -49,7 +48,7 @@ export async function runSideEffectOnlyHook< // List hooks try { await list.hooks[hookName]?.(args); - } catch (err) { - throw extensionError(hookName, [`${list.listKey}: ${err.message}`]); + } catch (error) { + throw extensionError(hookName, [{ error, tag: list.listKey }]); } } diff --git a/packages/keystone/src/lib/core/queries/resolvers.ts b/packages/keystone/src/lib/core/queries/resolvers.ts index 35e421b4e26..21a9225146c 100644 --- a/packages/keystone/src/lib/core/queries/resolvers.ts +++ b/packages/keystone/src/lib/core/queries/resolvers.ts @@ -59,7 +59,7 @@ export async function accessControlledFilter( // Merge declarative access control if (typeof access === 'object') { - resolvedWhere = { AND: [resolvedWhere, await resolveWhereInput(access, list)] }; + resolvedWhere = { AND: [resolvedWhere, await resolveWhereInput(access, list, context)] }; } return resolvedWhere; @@ -86,7 +86,7 @@ export async function findOne( } export async function findMany( - { where, first, skip, orderBy: rawOrderBy }: FindManyArgsValue, + { where, take, skip, orderBy: rawOrderBy }: FindManyArgsValue, list: InitialisedList, context: KeystoneContext, info: GraphQLResolveInfo, @@ -94,16 +94,16 @@ export async function findMany( ): Promise { const orderBy = await resolveOrderBy(rawOrderBy, list, context); - applyEarlyMaxResults(first, list); + applyEarlyMaxResults(take, list); - let resolvedWhere = await resolveWhereInput(where || {}, list); + let resolvedWhere = await resolveWhereInput(where, list, context); resolvedWhere = await accessControlledFilter(list, context, resolvedWhere); const results = await runWithPrisma(context, list, model => model.findMany({ where: extraFilter === undefined ? resolvedWhere : { AND: [resolvedWhere, extraFilter] }, orderBy, - take: first ?? undefined, + take: take ?? undefined, skip, }) ); @@ -166,7 +166,7 @@ export async function count( info: GraphQLResolveInfo, extraFilter?: PrismaFilter ) { - let resolvedWhere = await resolveWhereInput(where || {}, list); + let resolvedWhere = await resolveWhereInput(where, list, context); resolvedWhere = await accessControlledFilter(list, context, resolvedWhere); const count = await runWithPrisma(context, list, model => @@ -186,16 +186,16 @@ export async function count( return count; } -function applyEarlyMaxResults(_first: number | null | undefined, list: InitialisedList) { - const first = _first ?? Infinity; +function applyEarlyMaxResults(_take: number | null | undefined, list: InitialisedList) { + const take = _take ?? Infinity; // We want to help devs by failing fast and noisily if limits are violated. // Unfortunately, we can't always be sure of intent. - // E.g., if the query has a "first: 10", is it bad if more results could come back? + // E.g., if the query has a "take: 10", is it bad if more results could come back? // Maybe yes, or maybe the dev is just paginating posts. // But we can be sure there's a problem in two cases: - // * The query explicitly has a "first" that exceeds the limit - // * The query has no "first", and has more results than the limit - if (first < Infinity && first > list.maxResults) { + // * The query explicitly has a "take" that exceeds the limit + // * The query has no "take", and has more results than the limit + if (take < Infinity && take > list.maxResults) { throw limitsExceededError({ list: list.listKey, type: 'maxResults', limit: list.maxResults }); } } diff --git a/packages/keystone/src/lib/core/types-for-lists.ts b/packages/keystone/src/lib/core/types-for-lists.ts index 18ab3c6b78d..d4408407ebc 100644 --- a/packages/keystone/src/lib/core/types-for-lists.ts +++ b/packages/keystone/src/lib/core/types-for-lists.ts @@ -22,7 +22,6 @@ import { } from './access-control'; import { getNamesFromList } from './utils'; import { ResolvedDBField, resolveRelationships } from './resolve-relationships'; -import { InputFilter, PrismaFilter, resolveWhereInput } from './where-inputs'; import { outputTypeField } from './queries/output-field'; import { assertFieldsValid } from './field-assertions'; @@ -37,7 +36,6 @@ export type InitialisedList = { /** This will include the opposites to one-sided relationships */ resolvedDbFields: Record; pluralGraphQLName: string; - filterImpls: Record PrismaFilter>; types: TypesForList; access: ResolvedListAccessControl; hooks: ListHooks; @@ -111,9 +109,12 @@ export function initialiseLists( { AND: schema.arg({ type: schema.list(schema.nonNull(where)) }), OR: schema.arg({ type: schema.list(schema.nonNull(where)) }), + NOT: schema.arg({ type: schema.list(schema.nonNull(where)) }), }, - ...Object.values(fields).map(field => - field.access.read === false ? {} : field.__legacy?.filters?.fields ?? {} + ...Object.entries(fields).map( + ([fieldKey, field]) => + field.input?.where?.arg && + field.access.read !== false && { [fieldKey]: field.input?.where?.arg } ) ); }, @@ -165,7 +166,7 @@ export function initialiseLists( defaultValue: [], }), // TODO: non-nullable when max results is specified in the list with the default of max results - first: schema.arg({ type: schema.Int }), + take: schema.arg({ type: schema.Int }), skip: schema.arg({ type: schema.nonNull(schema.Int), defaultValue: 0 }), }; @@ -234,7 +235,18 @@ export function initialiseLists( update, findManyArgs, relateTo: { - many: { create: relateToManyForCreate, update: relateToManyForUpdate }, + many: { + where: schema.inputObject({ + name: `${listKey}ManyRelationFilter`, + fields: { + every: schema.arg({ type: where }), + some: schema.arg({ type: where }), + none: schema.arg({ type: where }), + }, + }), + create: relateToManyForCreate, + update: relateToManyForUpdate, + }, one: { create: relateToOneForCreate, update: relateToOneForUpdate }, }, }, @@ -304,27 +316,6 @@ export function initialiseLists( ...listInfos[listKey], ...listsWithResolvedDBFields[listKey], hooks: list.hooks || {}, - filterImpls: Object.assign( - {}, - ...Object.values(list.fields).map(field => { - if (field.dbField.kind === 'relation' && field.__legacy?.filters) { - const foreignListKey = field.dbField.list; - return Object.fromEntries( - Object.entries(field.__legacy.filters.impls).map(([key, resolve]) => { - return [ - key, - (val: any) => - resolve(val, foreignListWhereInput => - resolveWhereInput(foreignListWhereInput, lists[foreignListKey]) - ), - ]; - }) - ); - } else { - return field.__legacy?.filters?.impls ?? {}; - } - }) - ), cacheHint: (() => { const cacheHint = listsConfig[listKey].graphql?.cacheHint; if (cacheHint === undefined) { diff --git a/packages/keystone/src/lib/core/where-inputs.ts b/packages/keystone/src/lib/core/where-inputs.ts index 3228f89e657..e6bfab810c6 100644 --- a/packages/keystone/src/lib/core/where-inputs.ts +++ b/packages/keystone/src/lib/core/where-inputs.ts @@ -1,5 +1,6 @@ -import { KeystoneContext } from '@keystone-next/types'; +import { DBField, KeystoneContext } from '@keystone-next/types'; import { InitialisedList } from './types-for-lists'; +import { getDBFieldKeyForFieldOnMultiField } from './utils'; export type InputFilter = Record & { _____?: 'input filter'; @@ -47,20 +48,91 @@ export async function resolveUniqueWhereInput( export async function resolveWhereInput( inputFilter: InputFilter, - list: InitialisedList + list: InitialisedList, + context: KeystoneContext ): Promise { return { AND: await Promise.all( Object.entries(inputFilter).map(async ([fieldKey, value]) => { - if (fieldKey === 'OR' || fieldKey === 'AND') { + if (fieldKey === 'OR' || fieldKey === 'AND' || fieldKey === 'NOT') { return { [fieldKey]: await Promise.all( - value.map((value: any) => resolveWhereInput(value, list)) + value.map((value: any) => resolveWhereInput(value, list, context)) ), }; } - return list.filterImpls[fieldKey](value); + const field = list.fields[fieldKey]; + // we know if there are filters in the input object with the key of a field, the field must have defined a where input so this non null assertion is okay + const where = field.input!.where!; + const dbField = field.dbField; + const ret = where.resolve + ? await where.resolve( + value, + context, + (() => { + if (field.dbField.kind !== 'relation') { + return undefined as any; + } + const foreignList = field.dbField.list; + const whereResolver = (val: any) => + resolveWhereInput(val, list.lists[foreignList], context); + if (field.dbField.mode === 'many') { + return async () => { + if (value === null) { + throw new Error('A many relation filter cannot be set to null'); + } + return Object.fromEntries( + await Promise.all( + Object.entries(value).map(async ([key, val]) => { + if (val === null) { + throw new Error( + `The key ${key} in a many relation filter cannot be set to null` + ); + } + return [key, await whereResolver(val as any)]; + }) + ) + ); + }; + } + return (val: any) => { + if (val === null) { + return null; + } + return whereResolver(val); + }; + })() + ) + : value; + if (ret === null) { + if (field.dbField.kind === 'multi') { + throw new Error('multi db fields cannot return null from where input resolvers'); + } + return { [fieldKey]: null }; + } + return handleOperators(fieldKey, dbField, ret); }) ), }; } + +function handleOperators(fieldKey: string, dbField: DBField, { AND, OR, NOT, ...rest }: any) { + return { + AND: AND?.map((value: any) => handleOperators(fieldKey, dbField, value)), + OR: OR?.map((value: any) => handleOperators(fieldKey, dbField, value)), + NOT: NOT?.map((value: any) => handleOperators(fieldKey, dbField, value)), + ...nestWithAppropiateField(fieldKey, dbField, rest), + }; +} + +function nestWithAppropiateField(fieldKey: string, dbField: DBField, value: any) { + if (dbField.kind === 'multi') { + return Object.fromEntries( + Object.entries(value).map(([key, val]) => [ + getDBFieldKeyForFieldOnMultiField(fieldKey, key), + val, + ]) + ); + } + return { [fieldKey]: value }; +} diff --git a/packages/keystone/src/lib/id-field.ts b/packages/keystone/src/lib/id-field.ts index 39065785c9d..5f3fd34136f 100644 --- a/packages/keystone/src/lib/id-field.ts +++ b/packages/keystone/src/lib/id-field.ts @@ -43,6 +43,63 @@ const idParsers = { }, }; +const nonCircularFields = { + equals: schema.arg({ type: schema.ID }), + in: schema.arg({ type: schema.list(schema.nonNull(schema.ID)) }), + notIn: schema.arg({ type: schema.list(schema.nonNull(schema.ID)) }), + lt: schema.arg({ type: schema.ID }), + lte: schema.arg({ type: schema.ID }), + gt: schema.arg({ type: schema.ID }), + gte: schema.arg({ type: schema.ID }), +}; + +type IDFilterType = schema.InputObjectType< + typeof nonCircularFields & { + not: schema.Arg; + } +>; + +const IDFilter: IDFilterType = schema.inputObject({ + name: 'IDFilter', + fields: () => ({ + ...nonCircularFields, + not: schema.arg({ type: IDFilter }), + }), +}); + +const filterArg = schema.arg({ type: IDFilter }); + +function resolveVal( + input: Exclude, undefined>, + kind: IdFieldConfig['kind'] +): any { + if (input === null) { + throw new Error('id filter cannot be null'); + } + const idParser = idParsers[kind]; + const obj: any = {}; + for (const key of ['equals', 'gt', 'gte', 'lt', 'lte'] as const) { + const val = input[key]; + if (val !== undefined) { + const parsed = idParser(val); + obj[key] = parsed; + } + } + for (const key of ['in', 'notIn'] as const) { + const val = input[key]; + if (val !== undefined) { + if (val === null) { + throw new Error(`${key} id filter cannot be null`); + } + obj[key] = val.map(x => idParser(x)); + } + } + if (input.not !== undefined) { + obj.not = resolveVal(input.not, kind); + } + return obj; +} + export const idFieldType = (config: IdFieldConfig): FieldTypeFunc => meta => { @@ -55,6 +112,12 @@ export const idFieldType = default: { kind: config.kind }, })({ input: { + where: { + arg: filterArg, + resolve(val) { + return resolveVal(val, config.kind); + }, + }, uniqueWhere: { arg: schema.arg({ type: schema.ID }), resolve: parseVal }, orderBy: { arg: schema.arg({ type: orderDirectionEnum }) }, }, diff --git a/packages/keystone/src/lib/server/createApolloServer.ts b/packages/keystone/src/lib/server/createApolloServer.ts index 70cce699e4d..af4d51b3985 100644 --- a/packages/keystone/src/lib/server/createApolloServer.ts +++ b/packages/keystone/src/lib/server/createApolloServer.ts @@ -1,22 +1,22 @@ import type { IncomingMessage, ServerResponse } from 'http'; -import { GraphQLSchema } from 'graphql'; +import { GraphQLError, GraphQLSchema } from 'graphql'; import { ApolloServer as ApolloServerMicro } from 'apollo-server-micro'; import { ApolloServer as ApolloServerExpress } from 'apollo-server-express'; import type { Config } from 'apollo-server-express'; -import type { CreateContext, SessionStrategy } from '@keystone-next/types'; +import type { CreateContext, GraphQLConfig, SessionStrategy } from '@keystone-next/types'; import { createSessionContext } from '../../session'; export const createApolloServerMicro = ({ graphQLSchema, createContext, sessionStrategy, - apolloConfig, + graphqlConfig, connectionPromise, }: { graphQLSchema: GraphQLSchema; createContext: CreateContext; sessionStrategy?: SessionStrategy; - apolloConfig?: Config; + graphqlConfig?: GraphQLConfig; connectionPromise: Promise; }) => { const context = async ({ req, res }: { req: IncomingMessage; res: ServerResponse }) => { @@ -28,7 +28,7 @@ export const createApolloServerMicro = ({ req, }); }; - const serverConfig = _createApolloServerConfig({ graphQLSchema, apolloConfig }); + const serverConfig = _createApolloServerConfig({ graphQLSchema, graphqlConfig }); return new ApolloServerMicro({ ...serverConfig, context }); }; @@ -36,12 +36,12 @@ export const createApolloServerExpress = ({ graphQLSchema, createContext, sessionStrategy, - apolloConfig, + graphqlConfig, }: { graphQLSchema: GraphQLSchema; createContext: CreateContext; sessionStrategy?: SessionStrategy; - apolloConfig?: Config; + graphqlConfig?: GraphQLConfig; }) => { const context = async ({ req, res }: { req: IncomingMessage; res: ServerResponse }) => createContext({ @@ -50,18 +50,19 @@ export const createApolloServerExpress = ({ : undefined, req, }); - const serverConfig = _createApolloServerConfig({ graphQLSchema, apolloConfig }); + const serverConfig = _createApolloServerConfig({ graphQLSchema, graphqlConfig }); return new ApolloServerExpress({ ...serverConfig, context }); }; const _createApolloServerConfig = ({ graphQLSchema, - apolloConfig, + graphqlConfig, }: { graphQLSchema: GraphQLSchema; - apolloConfig?: Config; + graphqlConfig?: GraphQLConfig; }) => { // Playground config, is /api/graphql available? + const apolloConfig = graphqlConfig?.apolloConfig; const pp = apolloConfig?.playground; let playground: Config['playground']; const settings = { 'request.credentials': 'same-origin' }; @@ -86,6 +87,7 @@ const _createApolloServerConfig = ({ return { uploads: false, schema: graphQLSchema, + debug: graphqlConfig?.debug, // If undefined, use Apollo default of NODE_ENV !== 'production' // FIXME: support for apollo studio tracing // ...(process.env.ENGINE_API_KEY || process.env.APOLLO_KEY // ? { tracing: true } @@ -97,6 +99,7 @@ const _createApolloServerConfig = ({ // tracing: dev, // }), ...apolloConfig, + formatError: formatError(graphqlConfig), // Carefully inject the playground playground, // FIXME: Support for file handling configuration @@ -104,3 +107,24 @@ const _createApolloServerConfig = ({ // maxFiles: 5, }; }; + +const formatError = (graphqlConfig: GraphQLConfig | undefined) => { + return (err: GraphQLError) => { + let debug = graphqlConfig?.debug; + if (debug === undefined) { + debug = process.env.NODE_ENV !== 'production'; + } + + if (!debug && err.extensions) { + // Strip out any `debug` extensions + delete err.extensions.debug; + delete err.extensions.exception; + } + + if (graphqlConfig?.apolloConfig?.formatError) { + return graphqlConfig.apolloConfig.formatError(err); + } else { + return err; + } + }; +}; diff --git a/packages/keystone/src/lib/server/createExpressServer.ts b/packages/keystone/src/lib/server/createExpressServer.ts index f4342538093..e94fe7c1297 100644 --- a/packages/keystone/src/lib/server/createExpressServer.ts +++ b/packages/keystone/src/lib/server/createExpressServer.ts @@ -1,9 +1,13 @@ -import type { Config } from 'apollo-server-express'; import cors, { CorsOptions } from 'cors'; import express from 'express'; import { GraphQLSchema } from 'graphql'; import { graphqlUploadExpress } from 'graphql-upload'; -import type { KeystoneConfig, CreateContext, SessionStrategy } from '@keystone-next/types'; +import type { + KeystoneConfig, + CreateContext, + SessionStrategy, + GraphQLConfig, +} from '@keystone-next/types'; import { createAdminUIServer } from '../../admin-ui/system'; import { createApolloServerExpress } from './createApolloServer'; import { addHealthCheck } from './addHealthCheck'; @@ -16,20 +20,20 @@ const addApolloServer = ({ graphQLSchema, createContext, sessionStrategy, - apolloConfig, + graphqlConfig, }: { server: express.Express; config: KeystoneConfig; graphQLSchema: GraphQLSchema; createContext: CreateContext; sessionStrategy?: SessionStrategy; - apolloConfig?: Config; + graphqlConfig?: GraphQLConfig; }) => { const apolloServer = createApolloServerExpress({ graphQLSchema, createContext, sessionStrategy, - apolloConfig, + graphqlConfig, }); const maxFileSize = config.server?.maxFileSize || DEFAULT_MAX_FILE_SIZE; @@ -68,7 +72,7 @@ export const createExpressServer = async ( graphQLSchema, createContext, sessionStrategy: config.session, - apolloConfig: config.graphql?.apolloConfig, + graphqlConfig: config.graphql, }); if (config.ui?.isDisabled) { diff --git a/packages/keystone/src/schema/schema.ts b/packages/keystone/src/schema/schema.ts index c3694e83b19..1c84166a776 100644 --- a/packages/keystone/src/schema/schema.ts +++ b/packages/keystone/src/schema/schema.ts @@ -1,5 +1,5 @@ import type { GraphQLSchema } from 'graphql'; -import { mergeSchemas } from '@graphql-tools/merge'; +import { mergeSchemas } from '@graphql-tools/schema'; import type { BaseFields, diff --git a/packages/keystone/src/scripts/tests/__snapshots__/artifacts.test.ts.snap b/packages/keystone/src/scripts/tests/__snapshots__/artifacts.test.ts.snap index d82fd130fba..40457901eb3 100644 --- a/packages/keystone/src/scripts/tests/__snapshots__/artifacts.test.ts.snap +++ b/packages/keystone/src/scripts/tests/__snapshots__/artifacts.test.ts.snap @@ -19,28 +19,48 @@ type Scalars = { export type TodoWhereInput = { readonly AND?: ReadonlyArray | TodoWhereInput | null; readonly OR?: ReadonlyArray | TodoWhereInput | null; - readonly id?: Scalars['ID'] | null; - readonly id_not?: Scalars['ID'] | null; - readonly id_lt?: Scalars['ID'] | null; - readonly id_lte?: Scalars['ID'] | null; - readonly id_gt?: Scalars['ID'] | null; - readonly id_gte?: Scalars['ID'] | null; - readonly id_in?: ReadonlyArray | Scalars['ID'] | null; - readonly id_not_in?: ReadonlyArray | Scalars['ID'] | null; - readonly title?: Scalars['String'] | null; - readonly title_not?: Scalars['String'] | null; - readonly title_contains?: Scalars['String'] | null; - readonly title_not_contains?: Scalars['String'] | null; - readonly title_in?: - | ReadonlyArray - | Scalars['String'] - | null - | null; - readonly title_not_in?: - | ReadonlyArray - | Scalars['String'] - | null - | null; + readonly NOT?: ReadonlyArray | TodoWhereInput | null; + readonly id?: IDFilter | null; + readonly title?: StringNullableFilter | null; +}; + +export type IDFilter = { + readonly equals?: Scalars['ID'] | null; + readonly in?: ReadonlyArray | Scalars['ID'] | null; + readonly notIn?: ReadonlyArray | Scalars['ID'] | null; + readonly lt?: Scalars['ID'] | null; + readonly lte?: Scalars['ID'] | null; + readonly gt?: Scalars['ID'] | null; + readonly gte?: Scalars['ID'] | null; + readonly not?: IDFilter | null; +}; + +export type StringNullableFilter = { + readonly equals?: Scalars['String'] | null; + readonly in?: ReadonlyArray | Scalars['String'] | null; + readonly notIn?: ReadonlyArray | Scalars['String'] | null; + readonly lt?: Scalars['String'] | null; + readonly lte?: Scalars['String'] | null; + readonly gt?: Scalars['String'] | null; + readonly gte?: Scalars['String'] | null; + readonly contains?: Scalars['String'] | null; + readonly startsWith?: Scalars['String'] | null; + readonly endsWith?: Scalars['String'] | null; + readonly not?: NestedStringNullableFilter | null; +}; + +export type NestedStringNullableFilter = { + readonly equals?: Scalars['String'] | null; + readonly in?: ReadonlyArray | Scalars['String'] | null; + readonly notIn?: ReadonlyArray | Scalars['String'] | null; + readonly lt?: Scalars['String'] | null; + readonly lte?: Scalars['String'] | null; + readonly gt?: Scalars['String'] | null; + readonly gte?: Scalars['String'] | null; + readonly contains?: Scalars['String'] | null; + readonly startsWith?: Scalars['String'] | null; + readonly endsWith?: Scalars['String'] | null; + readonly not?: NestedStringNullableFilter | null; }; export type TodoWhereUniqueInput = { @@ -94,7 +114,7 @@ export type TodoListTypeInfo = { listQuery: { readonly where?: TodoWhereInput; readonly orderBy?: ReadonlyArray | TodoOrderByInput; - readonly first?: Scalars['Int'] | null; + readonly take?: Scalars['Int'] | null; readonly skip?: Scalars['Int']; }; }; diff --git a/packages/keystone/src/scripts/tests/build.test.ts b/packages/keystone/src/scripts/tests/build.test.ts index 97908231a12..46c5b16a45e 100644 --- a/packages/keystone/src/scripts/tests/build.test.ts +++ b/packages/keystone/src/scripts/tests/build.test.ts @@ -77,7 +77,7 @@ test('build works with typescript without the user defining a babel config', asy ✨ Generating Keystone config code ✨ Building Admin UI info - Using webpack 4. Reason: custom webpack configuration in next.config.js https://nextjs.org/docs/messages/webpack5 - info - Checking validity of types... + info - Skipping validation of types... info - Creating an optimized production build... info - Compiled successfully info - Collecting page data... diff --git a/packages/keystone/src/scripts/tests/fixtures/basic-project/schema.graphql b/packages/keystone/src/scripts/tests/fixtures/basic-project/schema.graphql index 2f3cfe2ec31..b0e148762fd 100644 --- a/packages/keystone/src/scripts/tests/fixtures/basic-project/schema.graphql +++ b/packages/keystone/src/scripts/tests/fixtures/basic-project/schema.graphql @@ -6,20 +6,48 @@ type Todo { input TodoWhereInput { AND: [TodoWhereInput!] OR: [TodoWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - title: String - title_not: String - title_contains: String - title_not_contains: String - title_in: [String] - title_not_in: [String] + NOT: [TodoWhereInput!] + id: IDFilter + title: StringNullableFilter +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter } input TodoWhereUniqueInput { @@ -70,7 +98,7 @@ type Query { todos( where: TodoWhereInput! = {} orderBy: [TodoOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Todo!] todo(where: TodoWhereUniqueInput!): Todo diff --git a/packages/keystone/src/session/index.ts b/packages/keystone/src/session/index.ts index 3f16ecd60f2..9843ebe8c9b 100644 --- a/packages/keystone/src/session/index.ts +++ b/packages/keystone/src/session/index.ts @@ -87,11 +87,12 @@ export function statelessSessions({ } return { async get({ req }) { - if (!req.headers.cookie) return; - let cookies = cookie.parse(req.headers.cookie); - if (!cookies[TOKEN_NAME]) return; + const cookies = cookie.parse(req.headers.cookie || ''); + const bearer = req.headers.authorization?.replace('Bearer ', ''); + const token = bearer || cookies[TOKEN_NAME]; + if (!token) return; try { - return await Iron.unseal(cookies[TOKEN_NAME], secret, ironOptions); + return await Iron.unseal(token, secret, ironOptions); } catch (err) {} }, async end({ res }) { diff --git a/packages/session-store-redis/package.json b/packages/session-store-redis/package.json index 201aa83296d..32396318b80 100644 --- a/packages/session-store-redis/package.json +++ b/packages/session-store-redis/package.json @@ -8,7 +8,7 @@ "node": "^12.20 || >= 14.13" }, "dependencies": { - "@babel/runtime": "^7.14.8", + "@babel/runtime": "^7.15.3", "@types/redis": "^2.8.31" }, "devDependencies": { diff --git a/packages/testing/CHANGELOG.md b/packages/testing/CHANGELOG.md index 1f2b8df452e..1b73d7bd019 100644 --- a/packages/testing/CHANGELOG.md +++ b/packages/testing/CHANGELOG.md @@ -1,5 +1,12 @@ # @keystone-next/testing +## 1.1.1 + +### Patch Changes + +- Updated dependencies [[`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/keystone@24.0.0 + ## 1.1.0 ### Minor Changes diff --git a/packages/testing/package.json b/packages/testing/package.json index fc0d46f2c7f..4e1827333ea 100644 --- a/packages/testing/package.json +++ b/packages/testing/package.json @@ -1,7 +1,7 @@ { "name": "@keystone-next/testing", "description": "Tools to assist with testing Keystone projects", - "version": "1.1.0", + "version": "1.1.1", "author": "The KeystoneJS Development Team", "license": "MIT", "main": "dist/testing.cjs.js", @@ -10,11 +10,11 @@ "node": "^12.20 || >= 14.13" }, "dependencies": { - "@keystone-next/keystone": "^23.0.0", + "@keystone-next/keystone": "^24.0.0", "@types/supertest": "^2.0.11", "express": "^4.17.1", "memoize-one": "^5.2.1", - "supertest": "^6.1.4" + "supertest": "^6.1.5" }, "repository": "https://github.com/keystonejs/keystone/tree/master/packages/testing" } diff --git a/packages/types/CHANGELOG.md b/packages/types/CHANGELOG.md index b192772357c..152cc92c772 100644 --- a/packages/types/CHANGELOG.md +++ b/packages/types/CHANGELOG.md @@ -1,5 +1,131 @@ # @keystone-next/types +## 24.0.0 + +### Major Changes + +- [#6196](https://github.com/keystonejs/keystone/pull/6196) [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - Removed `_ListKeyMeta` and `_toManyRelationshipFieldMeta` fields. You should use `listKeyCount` and `toManyRelationshipFieldCount` instead + +* [#6196](https://github.com/keystonejs/keystone/pull/6196) [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - Removed all arguments from `context.lists.List.count` and `context.db.lists.List.count` except for `where`. + +- [#6266](https://github.com/keystonejs/keystone/pull/6266) [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - Renamed `first` argument in find many queries to `take` to align with Prisma. + + ```graphql + type Query { + users( + where: UserWhereInput! = {} + orderBy: [UserOrderByInput!]! = [] + # previously was first: Int + take: Int + skip: Int! = 0 + ): [User!] + # ... + } + + type User { + # ... + posts( + where: PostWhereInput! = {} + orderBy: [PostOrderByInput!]! = [] + # previously was first: Int + take: Int + skip: Int! = 0 + ): [Post!] + # ... + } + ``` + +* [#6208](https://github.com/keystonejs/keystone/pull/6208) [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - The create one mutation now requires a non-null `data` argument and the create many mutation accepts a list of `ItemCreateInput` directly instead of being nested inside of an object with the `ItemCreateInput` in a `data` field. + + If you have a list called `Item`, `createItem` now looks like `createItem(data: ItemCreateInput!): Item` and `createItems` now looks like `createItems(data: [ItemCreateInput!]!): [Item]`. + +- [#6196](https://github.com/keystonejs/keystone/pull/6196) [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - Removed `search` argument from the GraphQL API for finding many items, Lists/DB API and to-many relationship fields. You should use `contains` filters instead. + +* [#6095](https://github.com/keystonejs/keystone/pull/6095) [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - Updated filters to be nested instead of flattened and add top-level `NOT` operator. See the [Query Filter API docs](https://keystonejs.com/docs/apis/filters) and the upgrade guide for more information. + + ```graphql + query { + posts(where: { title: { contains: "Something" } }) { + title + content + } + } + ``` + +- [#6196](https://github.com/keystonejs/keystone/pull/6196) [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - Removed `sortBy` argument from the GraphQL API for finding many items, Lists/DB API and to-many relationship fields. You should use `orderBy` instead. + +* [#6312](https://github.com/keystonejs/keystone/pull/6312) [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - Updated `@graphql-ts/schema`. The second type parameter of `schema.Arg` exported from `@keystone-next/types` is now a boolean that defines whether or not the arg has a default value to make it easier to define circular input objects. + +- [#6217](https://github.com/keystonejs/keystone/pull/6217) [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - `disconnectAll` has been renamed to `disconnect` in to-one relationship inputs and the old `disconnect` field has been removed. There are also seperate input types for create and update where the input for create doesn't have `disconnect`. It's also now required that if you provide a to-one relationship input, you must provide exactly one field to the input. + + If you have a list called `Item`, the to-one relationship inputs now look like this: + + ```graphql + input ItemRelateToOneForCreateInput { + create: ItemCreateInput + connect: ItemWhereUniqueInput + } + input ItemRelateToOneForUpdateInput { + create: ItemCreateInput + connect: ItemWhereUniqueInput + disconnect: Boolean + } + ``` + +* [#6224](https://github.com/keystonejs/keystone/pull/6224) [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - `disconnectAll` has been replaced by `set` in to-many relationship inputs, the equivalent to `disconnectAll: true` is now `set: []`. There are also seperate input types for create and update where the input for create doesn't have `disconnect` or `set`. The inputs in the lists in the input field are now also non-null. + + If you have a list called `Item`, the to-many relationship inputs now look like this: + + ```graphql + input ItemRelateToManyForCreateInput { + create: [ItemCreateInput!] + connect: [ItemWhereUniqueInput!] + } + input ItemRelateToManyForUpdateInput { + disconnect: [ItemWhereUniqueInput!] + set: [ItemWhereUniqueInput!] + create: [ItemCreateInput!] + connect: [ItemWhereUniqueInput!] + } + ``` + +- [#6197](https://github.com/keystonejs/keystone/pull/6197) [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - The generated CRUD queries, and some of the input types, in the GraphQL API have been renamed. + + If you have a list called `Item`, the query for multiple values, `allItems` will be renamed to `items`. The query for a single value, `Item`, will be renamed to `item`. + + Also, the input type used in the `updateItems` mutation has been renamed from `ItemsUpdateInput` to `ItemUpdateArgs`. + +* [#6211](https://github.com/keystonejs/keystone/pull/6211) [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - The update mutations now accept `where` unique inputs instead of only an `id` and the `where` and `data` arguments are non-null. + + If you have a list called `Item`, the update mutations now look like this: + + ```graphql + type Mutation { + updateItem(where: ItemWhereUniqueInput!, data: ItemUpdateInput!): Item + updateItems(data: [ItemUpdateArgs!]!): [Item] + } + + input ItemUpdateArgs { + where: ItemWhereUniqueInput! + data: ItemUpdateInput! + } + ``` + +- [#6206](https://github.com/keystonejs/keystone/pull/6206) [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - The delete mutations now accept `where` unique inputs instead of only an `id`. + + If you have a list called `Item`, `deleteItem` now looks like `deleteItem(where: ItemWhereUniqueInput!): Item` and `deleteItems` now looks like `deleteItems(where: [ItemWhereUniqueInput!]!): [Item]` + +### Minor Changes + +- [#6267](https://github.com/keystonejs/keystone/pull/6267) [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590) Thanks [@timleslie](https://github.com/timleslie)! - Added `config.graphql.debug` option, which can be used to control whether debug information such as stack traces are included in the errors returned by the GraphQL API. + +### Patch Changes + +- [#6249](https://github.com/keystonejs/keystone/pull/6249) [`8187ea019`](https://github.com/keystonejs/keystone/commit/8187ea019a212874f3c602573af3382c6f3bd3b2) Thanks [@timleslie](https://github.com/timleslie)! - Updated types to allow the `'id'` field in `ui.labelField`, `ui.listView.initialColumns`, and `ui.listView.initialSort`. + +- Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e)]: + - @keystone-next/fields@14.0.0 + ## 23.0.0 ### Major Changes diff --git a/packages/types/package.json b/packages/types/package.json index ec7047c5305..e3fadba83dd 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/types", - "version": "23.0.0", + "version": "24.0.0", "license": "MIT", "main": "dist/types.cjs.js", "module": "dist/types.esm.js", @@ -8,8 +8,9 @@ "node": "^12.20 || >= 14.13" }, "dependencies": { - "@graphql-ts/schema": "0.1.2", - "@keystone-next/fields": "^13.0.0", + "@babel/runtime": "^7.15.3", + "@graphql-ts/schema": "0.2.0", + "@keystone-next/fields": "^14.0.0", "apollo-server-types": "^0.9.0", "cors": "^2.8.5", "decimal.js": "10.3.1", diff --git a/packages/types/src/config/index.ts b/packages/types/src/config/index.ts index 0717d6c62aa..c7023c74d30 100644 --- a/packages/types/src/config/index.ts +++ b/packages/types/src/config/index.ts @@ -143,6 +143,40 @@ export type GraphQLConfig = { * @see https://www.apollographql.com/docs/apollo-server/api/apollo-server/#constructor */ apolloConfig?: Config; + /* + * When an error is returned from the GraphQL API, Apollo can include a stacktrace + * indicating where the error occurred. When Keystone is processing mutations, it + * will sometimes captures more than one error at a time, and then group these into + * a single error returned from the GraphQL API. Each of these errors will include + * a stacktrace. + * + * In general both categories of stacktrace are useful for debugging while developing, + * but should not be exposed in production, and this is the default behaviour of Keystone. + * + * You can use the `debug` option to change this behaviour. A use case for this + * would be if you need to send the stacktraces to a log, but do not want to return them + * from the API. In this case you could set `debug: true` and use + * `apolloConfig.formatError` to log the stacktraces and then strip them out before + * returning the error. + * + * ``` + * graphql: { + * debug: true, + * apolloConfig: { + * formatError: err => { + * console.error(err); + * delete err.extensions?.errors; + * delete err.extensions?.exception?.errors; + * delete err.extensions?.exception?.stacktrace; + * return err; + * }, + * }, + * } + * ``` + * * + * Default: process.env.NODE_ENV !== 'production' + */ + debug?: boolean; }; // config.extendGraphqlSchema diff --git a/packages/types/src/filters/enum-filter.ts b/packages/types/src/filters/enum-filter.ts new file mode 100644 index 00000000000..c6d91228411 --- /dev/null +++ b/packages/types/src/filters/enum-filter.ts @@ -0,0 +1,76 @@ +import { schema } from '../schema'; + +// yes, these two types have the fields but they're semantically different types +// (even though, yes, having EnumFilter by defined as EnumNullableFilter, would be the same type but names would show up differently in editors for example) + +export type EnumNullableFilter> = schema.InputObjectType<{ + // can be null + equals: schema.Arg; + // can be null + in: schema.Arg>>; + // can be null + notIn: schema.Arg>>; + // can be null + not: schema.Arg>; +}>; + +export type EnumFilter> = schema.InputObjectType<{ + equals: schema.Arg; + in: schema.Arg>>; + notIn: schema.Arg>>; + not: schema.Arg>; +}>; + +type EnumNullableListFilterType> = schema.InputObjectType<{ + // can be null + equals: schema.Arg>>; + // can be null + has: schema.Arg; + hasEvery: schema.Arg>>; + hasSome: schema.Arg>>; + isEmpty: schema.Arg; +}>; + +export function enumFilters>( + enumType: Enum +): { + optional: EnumNullableFilter; + required: EnumFilter; + many: EnumNullableListFilterType; +} { + const optional: EnumNullableFilter = schema.inputObject({ + name: `${enumType.graphQLType.name}NullableFilter`, + fields: () => ({ + equals: schema.arg({ type: enumType }), + in: schema.arg({ type: schema.list(schema.nonNull(enumType)) }), + notIn: schema.arg({ type: schema.list(schema.nonNull(enumType)) }), + not: schema.arg({ type: optional }), + }), + }); + const required: EnumFilter = schema.inputObject({ + name: `${enumType.graphQLType.name}Filter`, + fields: () => ({ + equals: schema.arg({ type: enumType }), + in: schema.arg({ type: schema.list(schema.nonNull(enumType)) }), + notIn: schema.arg({ type: schema.list(schema.nonNull(enumType)) }), + not: schema.arg({ type: optional }), + }), + }); + const many: EnumNullableListFilterType = schema.inputObject({ + name: `${enumType.graphQLType.name}NullableListFilter`, + fields: () => ({ + // can be null + equals: schema.arg({ type: schema.list(schema.nonNull(enumType)) }), + // can be null + has: schema.arg({ type: enumType }), + hasEvery: schema.arg({ type: schema.list(schema.nonNull(enumType)) }), + hasSome: schema.arg({ type: schema.list(schema.nonNull(enumType)) }), + isEmpty: schema.arg({ type: enumType }), + }), + }); + return { + optional, + required, + many, + }; +} diff --git a/packages/types/src/filters/index.ts b/packages/types/src/filters/index.ts new file mode 100644 index 00000000000..a83f16933d1 --- /dev/null +++ b/packages/types/src/filters/index.ts @@ -0,0 +1,88 @@ +export * as postgresql from './providers/postgresql'; +export * as sqlite from './providers/sqlite'; + +type EntriesAssumingNoExtraProps = { + [Key in keyof T]-?: [Key, T[Key]]; +}[keyof T][]; + +const objectEntriesButAssumeNoExtraProperties: (obj: T) => EntriesAssumingNoExtraProps = + Object.entries as any; + +type CommonFilter = { + equals?: T | null; + in?: readonly T[] | null; + notIn?: readonly T[] | null; + lt?: T | null; + lte?: T | null; + gt?: T | null; + gte?: T | null; + contains?: T | null; + startsWith?: T | null; + endsWith?: T | null; + not?: CommonFilter | null; +}; + +function internalResolveFilter( + entries: EntriesAssumingNoExtraProps>, + mode: 'default' | 'insensitive' | undefined +): object { + const entry = entries.shift(); + if (entry === undefined) return {}; + const [key, val] = entry; + if (val == null) { + return { + AND: [{ [key]: val }, internalResolveFilter(entries, mode)], + }; + } + switch (key) { + case 'equals': + case 'lt': + case 'lte': + case 'gt': + case 'gte': + case 'in': + case 'contains': + case 'startsWith': + case 'endsWith': { + return { + AND: [{ [key]: val, mode }, { not: null }, internalResolveFilter(entries, mode)], + }; + } + + case 'notIn': { + return { + AND: [ + { + NOT: [ + internalResolveFilter(objectEntriesButAssumeNoExtraProperties({ in: val }), mode), + ], + }, + internalResolveFilter(entries, mode), + ], + }; + } + case 'not': { + return { + AND: [ + { + NOT: [internalResolveFilter(objectEntriesButAssumeNoExtraProperties(val) as any, mode)], + }, + internalResolveFilter(entries, mode), + ], + }; + } + } +} + +export function resolveCommon(val: CommonFilter | null) { + if (val === null) return null; + return internalResolveFilter(objectEntriesButAssumeNoExtraProperties(val), undefined); +} + +export function resolveString( + val: (CommonFilter & { mode?: 'default' | 'insensitive' | null }) | null +) { + if (val === null) return null; + let { mode, ...rest } = val; + return internalResolveFilter(objectEntriesButAssumeNoExtraProperties(rest), mode as any); +} diff --git a/packages/types/src/filters/providers/postgresql.ts b/packages/types/src/filters/providers/postgresql.ts new file mode 100644 index 00000000000..cac24d557da --- /dev/null +++ b/packages/types/src/filters/providers/postgresql.ts @@ -0,0 +1,647 @@ +// Do not manually modify this file, it is automatically generated by the package at /prisma-utils in this repo. +// Update the script if you need this file to be different + +import { schema } from '../../schema'; + +import { QueryMode } from '../..'; + +type StringNullableFilterType = schema.InputObjectType<{ + // can be null + equals: schema.Arg; + // can be null + in: schema.Arg>>; + // can be null + notIn: schema.Arg>>; + lt: schema.Arg; + lte: schema.Arg; + gt: schema.Arg; + gte: schema.Arg; + contains: schema.Arg; + startsWith: schema.Arg; + endsWith: schema.Arg; + mode: schema.Arg; + // can be null + not: schema.Arg; +}>; + +const StringNullableFilter: StringNullableFilterType = schema.inputObject({ + name: 'StringNullableFilter', + fields: () => ({ + // can be null + equals: schema.arg({ type: schema.String }), + // can be null + in: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + // can be null + notIn: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + lt: schema.arg({ type: schema.String }), + lte: schema.arg({ type: schema.String }), + gt: schema.arg({ type: schema.String }), + gte: schema.arg({ type: schema.String }), + contains: schema.arg({ type: schema.String }), + startsWith: schema.arg({ type: schema.String }), + endsWith: schema.arg({ type: schema.String }), + mode: schema.arg({ type: QueryMode }), + // can be null + not: schema.arg({ type: NestedStringNullableFilter }), + }), +}); + +type NestedStringNullableFilterType = schema.InputObjectType<{ + // can be null + equals: schema.Arg; + // can be null + in: schema.Arg>>; + // can be null + notIn: schema.Arg>>; + lt: schema.Arg; + lte: schema.Arg; + gt: schema.Arg; + gte: schema.Arg; + contains: schema.Arg; + startsWith: schema.Arg; + endsWith: schema.Arg; + // can be null + not: schema.Arg; +}>; + +const NestedStringNullableFilter: NestedStringNullableFilterType = schema.inputObject({ + name: 'NestedStringNullableFilter', + fields: () => ({ + // can be null + equals: schema.arg({ type: schema.String }), + // can be null + in: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + // can be null + notIn: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + lt: schema.arg({ type: schema.String }), + lte: schema.arg({ type: schema.String }), + gt: schema.arg({ type: schema.String }), + gte: schema.arg({ type: schema.String }), + contains: schema.arg({ type: schema.String }), + startsWith: schema.arg({ type: schema.String }), + endsWith: schema.arg({ type: schema.String }), + // can be null + not: schema.arg({ type: NestedStringNullableFilter }), + }), +}); + +type StringFilterType = schema.InputObjectType<{ + equals: schema.Arg; + in: schema.Arg>>; + notIn: schema.Arg>>; + lt: schema.Arg; + lte: schema.Arg; + gt: schema.Arg; + gte: schema.Arg; + contains: schema.Arg; + startsWith: schema.Arg; + endsWith: schema.Arg; + mode: schema.Arg; + not: schema.Arg; +}>; + +const StringFilter: StringFilterType = schema.inputObject({ + name: 'StringFilter', + fields: () => ({ + equals: schema.arg({ type: schema.String }), + in: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + notIn: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + lt: schema.arg({ type: schema.String }), + lte: schema.arg({ type: schema.String }), + gt: schema.arg({ type: schema.String }), + gte: schema.arg({ type: schema.String }), + contains: schema.arg({ type: schema.String }), + startsWith: schema.arg({ type: schema.String }), + endsWith: schema.arg({ type: schema.String }), + mode: schema.arg({ type: QueryMode }), + not: schema.arg({ type: NestedStringFilter }), + }), +}); + +type NestedStringFilterType = schema.InputObjectType<{ + equals: schema.Arg; + in: schema.Arg>>; + notIn: schema.Arg>>; + lt: schema.Arg; + lte: schema.Arg; + gt: schema.Arg; + gte: schema.Arg; + contains: schema.Arg; + startsWith: schema.Arg; + endsWith: schema.Arg; + not: schema.Arg; +}>; + +const NestedStringFilter: NestedStringFilterType = schema.inputObject({ + name: 'NestedStringFilter', + fields: () => ({ + equals: schema.arg({ type: schema.String }), + in: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + notIn: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + lt: schema.arg({ type: schema.String }), + lte: schema.arg({ type: schema.String }), + gt: schema.arg({ type: schema.String }), + gte: schema.arg({ type: schema.String }), + contains: schema.arg({ type: schema.String }), + startsWith: schema.arg({ type: schema.String }), + endsWith: schema.arg({ type: schema.String }), + not: schema.arg({ type: NestedStringFilter }), + }), +}); + +type StringNullableListFilterType = schema.InputObjectType<{ + // can be null + equals: schema.Arg>>; + // can be null + has: schema.Arg; + hasEvery: schema.Arg>>; + hasSome: schema.Arg>>; + isEmpty: schema.Arg; +}>; + +const StringNullableListFilter: StringNullableListFilterType = schema.inputObject({ + name: 'StringNullableListFilter', + fields: () => ({ + // can be null + equals: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + // can be null + has: schema.arg({ type: schema.String }), + hasEvery: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + hasSome: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + isEmpty: schema.arg({ type: schema.Boolean }), + }), +}); + +type BoolNullableFilterType = schema.InputObjectType<{ + // can be null + equals: schema.Arg; + // can be null + not: schema.Arg; +}>; + +const BoolNullableFilter: BoolNullableFilterType = schema.inputObject({ + name: 'BooleanNullableFilter', + fields: () => ({ + // can be null + equals: schema.arg({ type: schema.Boolean }), + // can be null + not: schema.arg({ type: BoolNullableFilter }), + }), +}); + +type BoolFilterType = schema.InputObjectType<{ + equals: schema.Arg; + not: schema.Arg; +}>; + +const BoolFilter: BoolFilterType = schema.inputObject({ + name: 'BooleanFilter', + fields: () => ({ + equals: schema.arg({ type: schema.Boolean }), + not: schema.arg({ type: BoolFilter }), + }), +}); + +type BoolNullableListFilterType = schema.InputObjectType<{ + // can be null + equals: schema.Arg>>; + // can be null + has: schema.Arg; + hasEvery: schema.Arg>>; + hasSome: schema.Arg>>; + isEmpty: schema.Arg; +}>; + +const BoolNullableListFilter: BoolNullableListFilterType = schema.inputObject({ + name: 'BooleanNullableListFilter', + fields: () => ({ + // can be null + equals: schema.arg({ type: schema.list(schema.nonNull(schema.Boolean)) }), + // can be null + has: schema.arg({ type: schema.Boolean }), + hasEvery: schema.arg({ type: schema.list(schema.nonNull(schema.Boolean)) }), + hasSome: schema.arg({ type: schema.list(schema.nonNull(schema.Boolean)) }), + isEmpty: schema.arg({ type: schema.Boolean }), + }), +}); + +type IntNullableFilterType = schema.InputObjectType<{ + // can be null + equals: schema.Arg; + // can be null + in: schema.Arg>>; + // can be null + notIn: schema.Arg>>; + lt: schema.Arg; + lte: schema.Arg; + gt: schema.Arg; + gte: schema.Arg; + // can be null + not: schema.Arg; +}>; + +const IntNullableFilter: IntNullableFilterType = schema.inputObject({ + name: 'IntNullableFilter', + fields: () => ({ + // can be null + equals: schema.arg({ type: schema.Int }), + // can be null + in: schema.arg({ type: schema.list(schema.nonNull(schema.Int)) }), + // can be null + notIn: schema.arg({ type: schema.list(schema.nonNull(schema.Int)) }), + lt: schema.arg({ type: schema.Int }), + lte: schema.arg({ type: schema.Int }), + gt: schema.arg({ type: schema.Int }), + gte: schema.arg({ type: schema.Int }), + // can be null + not: schema.arg({ type: IntNullableFilter }), + }), +}); + +type IntFilterType = schema.InputObjectType<{ + equals: schema.Arg; + in: schema.Arg>>; + notIn: schema.Arg>>; + lt: schema.Arg; + lte: schema.Arg; + gt: schema.Arg; + gte: schema.Arg; + not: schema.Arg; +}>; + +const IntFilter: IntFilterType = schema.inputObject({ + name: 'IntFilter', + fields: () => ({ + equals: schema.arg({ type: schema.Int }), + in: schema.arg({ type: schema.list(schema.nonNull(schema.Int)) }), + notIn: schema.arg({ type: schema.list(schema.nonNull(schema.Int)) }), + lt: schema.arg({ type: schema.Int }), + lte: schema.arg({ type: schema.Int }), + gt: schema.arg({ type: schema.Int }), + gte: schema.arg({ type: schema.Int }), + not: schema.arg({ type: IntFilter }), + }), +}); + +type IntNullableListFilterType = schema.InputObjectType<{ + // can be null + equals: schema.Arg>>; + // can be null + has: schema.Arg; + hasEvery: schema.Arg>>; + hasSome: schema.Arg>>; + isEmpty: schema.Arg; +}>; + +const IntNullableListFilter: IntNullableListFilterType = schema.inputObject({ + name: 'IntNullableListFilter', + fields: () => ({ + // can be null + equals: schema.arg({ type: schema.list(schema.nonNull(schema.Int)) }), + // can be null + has: schema.arg({ type: schema.Int }), + hasEvery: schema.arg({ type: schema.list(schema.nonNull(schema.Int)) }), + hasSome: schema.arg({ type: schema.list(schema.nonNull(schema.Int)) }), + isEmpty: schema.arg({ type: schema.Boolean }), + }), +}); + +type FloatNullableFilterType = schema.InputObjectType<{ + // can be null + equals: schema.Arg; + // can be null + in: schema.Arg>>; + // can be null + notIn: schema.Arg>>; + lt: schema.Arg; + lte: schema.Arg; + gt: schema.Arg; + gte: schema.Arg; + // can be null + not: schema.Arg; +}>; + +const FloatNullableFilter: FloatNullableFilterType = schema.inputObject({ + name: 'FloatNullableFilter', + fields: () => ({ + // can be null + equals: schema.arg({ type: schema.Float }), + // can be null + in: schema.arg({ type: schema.list(schema.nonNull(schema.Float)) }), + // can be null + notIn: schema.arg({ type: schema.list(schema.nonNull(schema.Float)) }), + lt: schema.arg({ type: schema.Float }), + lte: schema.arg({ type: schema.Float }), + gt: schema.arg({ type: schema.Float }), + gte: schema.arg({ type: schema.Float }), + // can be null + not: schema.arg({ type: FloatNullableFilter }), + }), +}); + +type FloatFilterType = schema.InputObjectType<{ + equals: schema.Arg; + in: schema.Arg>>; + notIn: schema.Arg>>; + lt: schema.Arg; + lte: schema.Arg; + gt: schema.Arg; + gte: schema.Arg; + not: schema.Arg; +}>; + +const FloatFilter: FloatFilterType = schema.inputObject({ + name: 'FloatFilter', + fields: () => ({ + equals: schema.arg({ type: schema.Float }), + in: schema.arg({ type: schema.list(schema.nonNull(schema.Float)) }), + notIn: schema.arg({ type: schema.list(schema.nonNull(schema.Float)) }), + lt: schema.arg({ type: schema.Float }), + lte: schema.arg({ type: schema.Float }), + gt: schema.arg({ type: schema.Float }), + gte: schema.arg({ type: schema.Float }), + not: schema.arg({ type: FloatFilter }), + }), +}); + +type FloatNullableListFilterType = schema.InputObjectType<{ + // can be null + equals: schema.Arg>>; + // can be null + has: schema.Arg; + hasEvery: schema.Arg>>; + hasSome: schema.Arg>>; + isEmpty: schema.Arg; +}>; + +const FloatNullableListFilter: FloatNullableListFilterType = schema.inputObject({ + name: 'FloatNullableListFilter', + fields: () => ({ + // can be null + equals: schema.arg({ type: schema.list(schema.nonNull(schema.Float)) }), + // can be null + has: schema.arg({ type: schema.Float }), + hasEvery: schema.arg({ type: schema.list(schema.nonNull(schema.Float)) }), + hasSome: schema.arg({ type: schema.list(schema.nonNull(schema.Float)) }), + isEmpty: schema.arg({ type: schema.Boolean }), + }), +}); + +type DateTimeNullableFilterType = schema.InputObjectType<{ + // can be null + equals: schema.Arg; + // can be null + in: schema.Arg>>; + // can be null + notIn: schema.Arg>>; + lt: schema.Arg; + lte: schema.Arg; + gt: schema.Arg; + gte: schema.Arg; + // can be null + not: schema.Arg; +}>; + +const DateTimeNullableFilter: DateTimeNullableFilterType = schema.inputObject({ + name: 'DateTimeNullableFilter', + fields: () => ({ + // can be null + equals: schema.arg({ type: schema.String }), + // can be null + in: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + // can be null + notIn: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + lt: schema.arg({ type: schema.String }), + lte: schema.arg({ type: schema.String }), + gt: schema.arg({ type: schema.String }), + gte: schema.arg({ type: schema.String }), + // can be null + not: schema.arg({ type: DateTimeNullableFilter }), + }), +}); + +type DateTimeFilterType = schema.InputObjectType<{ + equals: schema.Arg; + in: schema.Arg>>; + notIn: schema.Arg>>; + lt: schema.Arg; + lte: schema.Arg; + gt: schema.Arg; + gte: schema.Arg; + not: schema.Arg; +}>; + +const DateTimeFilter: DateTimeFilterType = schema.inputObject({ + name: 'DateTimeFilter', + fields: () => ({ + equals: schema.arg({ type: schema.String }), + in: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + notIn: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + lt: schema.arg({ type: schema.String }), + lte: schema.arg({ type: schema.String }), + gt: schema.arg({ type: schema.String }), + gte: schema.arg({ type: schema.String }), + not: schema.arg({ type: DateTimeFilter }), + }), +}); + +type DateTimeNullableListFilterType = schema.InputObjectType<{ + // can be null + equals: schema.Arg>>; + // can be null + has: schema.Arg; + hasEvery: schema.Arg>>; + hasSome: schema.Arg>>; + isEmpty: schema.Arg; +}>; + +const DateTimeNullableListFilter: DateTimeNullableListFilterType = schema.inputObject({ + name: 'DateTimeNullableListFilter', + fields: () => ({ + // can be null + equals: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + // can be null + has: schema.arg({ type: schema.String }), + hasEvery: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + hasSome: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + isEmpty: schema.arg({ type: schema.Boolean }), + }), +}); + +type JsonNullableFilterType = schema.InputObjectType<{ + // can be null + equals: schema.Arg; + // can be null + not: schema.Arg; +}>; + +const JsonNullableFilter: JsonNullableFilterType = schema.inputObject({ + name: 'JsonNullableFilter', + fields: () => ({ + // can be null + equals: schema.arg({ type: schema.JSON }), + // can be null + not: schema.arg({ type: schema.JSON }), + }), +}); + +type JsonFilterType = schema.InputObjectType<{ + equals: schema.Arg; + not: schema.Arg; +}>; + +const JsonFilter: JsonFilterType = schema.inputObject({ + name: 'JsonFilter', + fields: () => ({ + equals: schema.arg({ type: schema.JSON }), + not: schema.arg({ type: schema.JSON }), + }), +}); + +type JsonNullableListFilterType = schema.InputObjectType<{ + // can be null + equals: schema.Arg>>; + // can be null + has: schema.Arg; + hasEvery: schema.Arg>>; + hasSome: schema.Arg>>; + isEmpty: schema.Arg; +}>; + +const JsonNullableListFilter: JsonNullableListFilterType = schema.inputObject({ + name: 'JsonNullableListFilter', + fields: () => ({ + // can be null + equals: schema.arg({ type: schema.list(schema.nonNull(schema.JSON)) }), + // can be null + has: schema.arg({ type: schema.JSON }), + hasEvery: schema.arg({ type: schema.list(schema.nonNull(schema.JSON)) }), + hasSome: schema.arg({ type: schema.list(schema.nonNull(schema.JSON)) }), + isEmpty: schema.arg({ type: schema.Boolean }), + }), +}); + +type DecimalNullableFilterType = schema.InputObjectType<{ + // can be null + equals: schema.Arg; + // can be null + in: schema.Arg>>; + // can be null + notIn: schema.Arg>>; + lt: schema.Arg; + lte: schema.Arg; + gt: schema.Arg; + gte: schema.Arg; + // can be null + not: schema.Arg; +}>; + +const DecimalNullableFilter: DecimalNullableFilterType = schema.inputObject({ + name: 'DecimalNullableFilter', + fields: () => ({ + // can be null + equals: schema.arg({ type: schema.String }), + // can be null + in: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + // can be null + notIn: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + lt: schema.arg({ type: schema.String }), + lte: schema.arg({ type: schema.String }), + gt: schema.arg({ type: schema.String }), + gte: schema.arg({ type: schema.String }), + // can be null + not: schema.arg({ type: DecimalNullableFilter }), + }), +}); + +type DecimalFilterType = schema.InputObjectType<{ + equals: schema.Arg; + in: schema.Arg>>; + notIn: schema.Arg>>; + lt: schema.Arg; + lte: schema.Arg; + gt: schema.Arg; + gte: schema.Arg; + not: schema.Arg; +}>; + +const DecimalFilter: DecimalFilterType = schema.inputObject({ + name: 'DecimalFilter', + fields: () => ({ + equals: schema.arg({ type: schema.String }), + in: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + notIn: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + lt: schema.arg({ type: schema.String }), + lte: schema.arg({ type: schema.String }), + gt: schema.arg({ type: schema.String }), + gte: schema.arg({ type: schema.String }), + not: schema.arg({ type: DecimalFilter }), + }), +}); + +type DecimalNullableListFilterType = schema.InputObjectType<{ + // can be null + equals: schema.Arg>>; + // can be null + has: schema.Arg; + hasEvery: schema.Arg>>; + hasSome: schema.Arg>>; + isEmpty: schema.Arg; +}>; + +const DecimalNullableListFilter: DecimalNullableListFilterType = schema.inputObject({ + name: 'DecimalNullableListFilter', + fields: () => ({ + // can be null + equals: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + // can be null + has: schema.arg({ type: schema.String }), + hasEvery: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + hasSome: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + isEmpty: schema.arg({ type: schema.Boolean }), + }), +}); + +export const String = { + optional: StringNullableFilter, + required: StringFilter, + many: StringNullableListFilter, +}; + +export const Boolean = { + optional: BoolNullableFilter, + required: BoolFilter, + many: BoolNullableListFilter, +}; + +export const Int = { + optional: IntNullableFilter, + required: IntFilter, + many: IntNullableListFilter, +}; + +export const Float = { + optional: FloatNullableFilter, + required: FloatFilter, + many: FloatNullableListFilter, +}; + +export const DateTime = { + optional: DateTimeNullableFilter, + required: DateTimeFilter, + many: DateTimeNullableListFilter, +}; + +export const Json = { + optional: JsonNullableFilter, + required: JsonFilter, + many: JsonNullableListFilter, +}; + +export const Decimal = { + optional: DecimalNullableFilter, + required: DecimalFilter, + many: DecimalNullableListFilter, +}; + +export { enumFilters as enum } from '../enum-filter'; diff --git a/packages/types/src/filters/providers/sqlite.ts b/packages/types/src/filters/providers/sqlite.ts new file mode 100644 index 00000000000..20591155798 --- /dev/null +++ b/packages/types/src/filters/providers/sqlite.ts @@ -0,0 +1,438 @@ +// Do not manually modify this file, it is automatically generated by the package at /prisma-utils in this repo. +// Update the script if you need this file to be different + +import { schema } from '../../schema'; + +type StringNullableFilterType = schema.InputObjectType<{ + // can be null + equals: schema.Arg; + // can be null + in: schema.Arg>>; + // can be null + notIn: schema.Arg>>; + lt: schema.Arg; + lte: schema.Arg; + gt: schema.Arg; + gte: schema.Arg; + contains: schema.Arg; + startsWith: schema.Arg; + endsWith: schema.Arg; + // can be null + not: schema.Arg; +}>; + +const StringNullableFilter: StringNullableFilterType = schema.inputObject({ + name: 'StringNullableFilter', + fields: () => ({ + // can be null + equals: schema.arg({ type: schema.String }), + // can be null + in: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + // can be null + notIn: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + lt: schema.arg({ type: schema.String }), + lte: schema.arg({ type: schema.String }), + gt: schema.arg({ type: schema.String }), + gte: schema.arg({ type: schema.String }), + contains: schema.arg({ type: schema.String }), + startsWith: schema.arg({ type: schema.String }), + endsWith: schema.arg({ type: schema.String }), + // can be null + not: schema.arg({ type: NestedStringNullableFilter }), + }), +}); + +type NestedStringNullableFilterType = schema.InputObjectType<{ + // can be null + equals: schema.Arg; + // can be null + in: schema.Arg>>; + // can be null + notIn: schema.Arg>>; + lt: schema.Arg; + lte: schema.Arg; + gt: schema.Arg; + gte: schema.Arg; + contains: schema.Arg; + startsWith: schema.Arg; + endsWith: schema.Arg; + // can be null + not: schema.Arg; +}>; + +const NestedStringNullableFilter: NestedStringNullableFilterType = schema.inputObject({ + name: 'NestedStringNullableFilter', + fields: () => ({ + // can be null + equals: schema.arg({ type: schema.String }), + // can be null + in: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + // can be null + notIn: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + lt: schema.arg({ type: schema.String }), + lte: schema.arg({ type: schema.String }), + gt: schema.arg({ type: schema.String }), + gte: schema.arg({ type: schema.String }), + contains: schema.arg({ type: schema.String }), + startsWith: schema.arg({ type: schema.String }), + endsWith: schema.arg({ type: schema.String }), + // can be null + not: schema.arg({ type: NestedStringNullableFilter }), + }), +}); + +type StringFilterType = schema.InputObjectType<{ + equals: schema.Arg; + in: schema.Arg>>; + notIn: schema.Arg>>; + lt: schema.Arg; + lte: schema.Arg; + gt: schema.Arg; + gte: schema.Arg; + contains: schema.Arg; + startsWith: schema.Arg; + endsWith: schema.Arg; + not: schema.Arg; +}>; + +const StringFilter: StringFilterType = schema.inputObject({ + name: 'StringFilter', + fields: () => ({ + equals: schema.arg({ type: schema.String }), + in: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + notIn: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + lt: schema.arg({ type: schema.String }), + lte: schema.arg({ type: schema.String }), + gt: schema.arg({ type: schema.String }), + gte: schema.arg({ type: schema.String }), + contains: schema.arg({ type: schema.String }), + startsWith: schema.arg({ type: schema.String }), + endsWith: schema.arg({ type: schema.String }), + not: schema.arg({ type: NestedStringFilter }), + }), +}); + +type NestedStringFilterType = schema.InputObjectType<{ + equals: schema.Arg; + in: schema.Arg>>; + notIn: schema.Arg>>; + lt: schema.Arg; + lte: schema.Arg; + gt: schema.Arg; + gte: schema.Arg; + contains: schema.Arg; + startsWith: schema.Arg; + endsWith: schema.Arg; + not: schema.Arg; +}>; + +const NestedStringFilter: NestedStringFilterType = schema.inputObject({ + name: 'NestedStringFilter', + fields: () => ({ + equals: schema.arg({ type: schema.String }), + in: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + notIn: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + lt: schema.arg({ type: schema.String }), + lte: schema.arg({ type: schema.String }), + gt: schema.arg({ type: schema.String }), + gte: schema.arg({ type: schema.String }), + contains: schema.arg({ type: schema.String }), + startsWith: schema.arg({ type: schema.String }), + endsWith: schema.arg({ type: schema.String }), + not: schema.arg({ type: NestedStringFilter }), + }), +}); + +type BoolNullableFilterType = schema.InputObjectType<{ + // can be null + equals: schema.Arg; + // can be null + not: schema.Arg; +}>; + +const BoolNullableFilter: BoolNullableFilterType = schema.inputObject({ + name: 'BooleanNullableFilter', + fields: () => ({ + // can be null + equals: schema.arg({ type: schema.Boolean }), + // can be null + not: schema.arg({ type: BoolNullableFilter }), + }), +}); + +type BoolFilterType = schema.InputObjectType<{ + equals: schema.Arg; + not: schema.Arg; +}>; + +const BoolFilter: BoolFilterType = schema.inputObject({ + name: 'BooleanFilter', + fields: () => ({ + equals: schema.arg({ type: schema.Boolean }), + not: schema.arg({ type: BoolFilter }), + }), +}); + +type IntNullableFilterType = schema.InputObjectType<{ + // can be null + equals: schema.Arg; + // can be null + in: schema.Arg>>; + // can be null + notIn: schema.Arg>>; + lt: schema.Arg; + lte: schema.Arg; + gt: schema.Arg; + gte: schema.Arg; + // can be null + not: schema.Arg; +}>; + +const IntNullableFilter: IntNullableFilterType = schema.inputObject({ + name: 'IntNullableFilter', + fields: () => ({ + // can be null + equals: schema.arg({ type: schema.Int }), + // can be null + in: schema.arg({ type: schema.list(schema.nonNull(schema.Int)) }), + // can be null + notIn: schema.arg({ type: schema.list(schema.nonNull(schema.Int)) }), + lt: schema.arg({ type: schema.Int }), + lte: schema.arg({ type: schema.Int }), + gt: schema.arg({ type: schema.Int }), + gte: schema.arg({ type: schema.Int }), + // can be null + not: schema.arg({ type: IntNullableFilter }), + }), +}); + +type IntFilterType = schema.InputObjectType<{ + equals: schema.Arg; + in: schema.Arg>>; + notIn: schema.Arg>>; + lt: schema.Arg; + lte: schema.Arg; + gt: schema.Arg; + gte: schema.Arg; + not: schema.Arg; +}>; + +const IntFilter: IntFilterType = schema.inputObject({ + name: 'IntFilter', + fields: () => ({ + equals: schema.arg({ type: schema.Int }), + in: schema.arg({ type: schema.list(schema.nonNull(schema.Int)) }), + notIn: schema.arg({ type: schema.list(schema.nonNull(schema.Int)) }), + lt: schema.arg({ type: schema.Int }), + lte: schema.arg({ type: schema.Int }), + gt: schema.arg({ type: schema.Int }), + gte: schema.arg({ type: schema.Int }), + not: schema.arg({ type: IntFilter }), + }), +}); + +type FloatNullableFilterType = schema.InputObjectType<{ + // can be null + equals: schema.Arg; + // can be null + in: schema.Arg>>; + // can be null + notIn: schema.Arg>>; + lt: schema.Arg; + lte: schema.Arg; + gt: schema.Arg; + gte: schema.Arg; + // can be null + not: schema.Arg; +}>; + +const FloatNullableFilter: FloatNullableFilterType = schema.inputObject({ + name: 'FloatNullableFilter', + fields: () => ({ + // can be null + equals: schema.arg({ type: schema.Float }), + // can be null + in: schema.arg({ type: schema.list(schema.nonNull(schema.Float)) }), + // can be null + notIn: schema.arg({ type: schema.list(schema.nonNull(schema.Float)) }), + lt: schema.arg({ type: schema.Float }), + lte: schema.arg({ type: schema.Float }), + gt: schema.arg({ type: schema.Float }), + gte: schema.arg({ type: schema.Float }), + // can be null + not: schema.arg({ type: FloatNullableFilter }), + }), +}); + +type FloatFilterType = schema.InputObjectType<{ + equals: schema.Arg; + in: schema.Arg>>; + notIn: schema.Arg>>; + lt: schema.Arg; + lte: schema.Arg; + gt: schema.Arg; + gte: schema.Arg; + not: schema.Arg; +}>; + +const FloatFilter: FloatFilterType = schema.inputObject({ + name: 'FloatFilter', + fields: () => ({ + equals: schema.arg({ type: schema.Float }), + in: schema.arg({ type: schema.list(schema.nonNull(schema.Float)) }), + notIn: schema.arg({ type: schema.list(schema.nonNull(schema.Float)) }), + lt: schema.arg({ type: schema.Float }), + lte: schema.arg({ type: schema.Float }), + gt: schema.arg({ type: schema.Float }), + gte: schema.arg({ type: schema.Float }), + not: schema.arg({ type: FloatFilter }), + }), +}); + +type DateTimeNullableFilterType = schema.InputObjectType<{ + // can be null + equals: schema.Arg; + // can be null + in: schema.Arg>>; + // can be null + notIn: schema.Arg>>; + lt: schema.Arg; + lte: schema.Arg; + gt: schema.Arg; + gte: schema.Arg; + // can be null + not: schema.Arg; +}>; + +const DateTimeNullableFilter: DateTimeNullableFilterType = schema.inputObject({ + name: 'DateTimeNullableFilter', + fields: () => ({ + // can be null + equals: schema.arg({ type: schema.String }), + // can be null + in: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + // can be null + notIn: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + lt: schema.arg({ type: schema.String }), + lte: schema.arg({ type: schema.String }), + gt: schema.arg({ type: schema.String }), + gte: schema.arg({ type: schema.String }), + // can be null + not: schema.arg({ type: DateTimeNullableFilter }), + }), +}); + +type DateTimeFilterType = schema.InputObjectType<{ + equals: schema.Arg; + in: schema.Arg>>; + notIn: schema.Arg>>; + lt: schema.Arg; + lte: schema.Arg; + gt: schema.Arg; + gte: schema.Arg; + not: schema.Arg; +}>; + +const DateTimeFilter: DateTimeFilterType = schema.inputObject({ + name: 'DateTimeFilter', + fields: () => ({ + equals: schema.arg({ type: schema.String }), + in: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + notIn: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + lt: schema.arg({ type: schema.String }), + lte: schema.arg({ type: schema.String }), + gt: schema.arg({ type: schema.String }), + gte: schema.arg({ type: schema.String }), + not: schema.arg({ type: DateTimeFilter }), + }), +}); + +type DecimalNullableFilterType = schema.InputObjectType<{ + // can be null + equals: schema.Arg; + // can be null + in: schema.Arg>>; + // can be null + notIn: schema.Arg>>; + lt: schema.Arg; + lte: schema.Arg; + gt: schema.Arg; + gte: schema.Arg; + // can be null + not: schema.Arg; +}>; + +const DecimalNullableFilter: DecimalNullableFilterType = schema.inputObject({ + name: 'DecimalNullableFilter', + fields: () => ({ + // can be null + equals: schema.arg({ type: schema.String }), + // can be null + in: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + // can be null + notIn: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + lt: schema.arg({ type: schema.String }), + lte: schema.arg({ type: schema.String }), + gt: schema.arg({ type: schema.String }), + gte: schema.arg({ type: schema.String }), + // can be null + not: schema.arg({ type: DecimalNullableFilter }), + }), +}); + +type DecimalFilterType = schema.InputObjectType<{ + equals: schema.Arg; + in: schema.Arg>>; + notIn: schema.Arg>>; + lt: schema.Arg; + lte: schema.Arg; + gt: schema.Arg; + gte: schema.Arg; + not: schema.Arg; +}>; + +const DecimalFilter: DecimalFilterType = schema.inputObject({ + name: 'DecimalFilter', + fields: () => ({ + equals: schema.arg({ type: schema.String }), + in: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + notIn: schema.arg({ type: schema.list(schema.nonNull(schema.String)) }), + lt: schema.arg({ type: schema.String }), + lte: schema.arg({ type: schema.String }), + gt: schema.arg({ type: schema.String }), + gte: schema.arg({ type: schema.String }), + not: schema.arg({ type: DecimalFilter }), + }), +}); + +export const String = { + optional: StringNullableFilter, + required: StringFilter, +}; + +export const Boolean = { + optional: BoolNullableFilter, + required: BoolFilter, +}; + +export const Int = { + optional: IntNullableFilter, + required: IntFilter, +}; + +export const Float = { + optional: FloatNullableFilter, + required: FloatFilter, +}; + +export const DateTime = { + optional: DateTimeNullableFilter, + required: DateTimeFilter, +}; + +export const Decimal = { + optional: DecimalNullableFilter, + required: DecimalFilter, +}; + +export { enumFilters as enum } from '../enum-filter'; diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index e3a6ce3cb54..a614595cca9 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -7,5 +7,6 @@ export * from './base'; export * from './context'; export * from './next-fields'; export * as legacyFilters from './legacy-filters'; +export * as filters from './filters'; export * from './schema'; export { jsonFieldTypePolyfilledForSQLite } from './json-field-type-polyfill-for-sqlite'; diff --git a/packages/types/src/json-field-type-polyfill-for-sqlite.ts b/packages/types/src/json-field-type-polyfill-for-sqlite.ts index 5ea475b0fed..9ad7a9a307c 100644 --- a/packages/types/src/json-field-type-polyfill-for-sqlite.ts +++ b/packages/types/src/json-field-type-polyfill-for-sqlite.ts @@ -98,8 +98,8 @@ export function jsonFieldTypePolyfilledForSQLite< ScalarDBField<'Json', 'optional'>, CreateArg, UpdateArg, - schema.Arg, - schema.Arg + schema.Arg, + schema.Arg > & { input?: { uniqueWhere?: undefined; diff --git a/packages/types/src/next-fields.ts b/packages/types/src/next-fields.ts index 349b815ed91..645f36b37a8 100644 --- a/packages/types/src/next-fields.ts +++ b/packages/types/src/next-fields.ts @@ -39,17 +39,21 @@ export type NextFieldType< | schema.Arg | undefined, UpdateArg extends schema.Arg = schema.Arg, - UniqueWhereArg extends schema.Arg = schema.Arg< + UniqueWhereArg extends schema.Arg = schema.Arg< schema.NullableInputType, - undefined + false >, - OrderByArg extends schema.Arg = schema.Arg< + OrderByArg extends schema.Arg = schema.Arg< schema.NullableInputType, - undefined + false + >, + FilterArg extends schema.Arg = schema.Arg< + schema.NullableInputType, + false > > = { dbField: TDBField; -} & FieldTypeWithoutDBField; +} & FieldTypeWithoutDBField; type ScalarPrismaTypes = { String: string; @@ -111,6 +115,11 @@ export const orderDirectionEnum = schema.enum({ values: schema.enumValues(['asc', 'desc']), }); +export const QueryMode = schema.enum({ + name: 'QueryMode', + values: schema.enumValues(['default', 'insensitive']), +}); + export type RelationDBField = { kind: 'relation'; list: string; @@ -224,6 +233,39 @@ type FieldInputResolver = ( relationshipInputResolver: RelationshipInputResolver ) => MaybePromise; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +type DBFieldFiltersInner = Record; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +type DBFieldFilters = + | ({ + AND?: DBFieldFiltersInner; + OR?: DBFieldFiltersInner; + NOT?: DBFieldFiltersInner; + } & DBFieldFiltersInner) + | null; + +export type WhereFieldInputArg< + TDBField extends DBField, + TArg extends schema.Arg +> = { + arg: TArg; +} & ResolveFunc< + FieldInputResolver< + Exclude, undefined>, + DBFieldFilters, + any + // i think this is broken because variance? + // TDBField extends RelationDBField + // ? ( + // input: { + // many: types.InferValueFromArg>; + // one: types.InferValueFromArg>; + // }[Mode] + // ) => Promise + // : undefined + > +>; + export type UpdateFieldInputArg< TDBField extends DBField, TArg extends schema.Arg @@ -309,17 +351,22 @@ export type FieldTypeWithoutDBField< | schema.Arg | undefined, UpdateArg extends schema.Arg = schema.Arg, - UniqueWhereArg extends schema.Arg = schema.Arg< + UniqueWhereArg extends schema.Arg = schema.Arg< schema.NullableInputType, - undefined + false >, - OrderByArg extends schema.Arg = schema.Arg< + OrderByArg extends schema.Arg = schema.Arg< schema.NullableInputType, - undefined + false + >, + FilterArg extends schema.Arg = schema.Arg< + schema.NullableInputType, + false > > = { input?: { uniqueWhere?: UniqueWhereFieldInputArg, UniqueWhereArg>; + where?: WhereFieldInputArg; create?: CreateFieldInputArg; update?: UpdateFieldInputArg; orderBy?: OrderByFieldInputArg, OrderByArg>; @@ -346,10 +393,18 @@ export function fieldType(dbField: TDBField) { return function < CreateArg extends schema.Arg | undefined, UpdateArg extends schema.Arg, - UniqueWhereArg extends schema.Arg, - OrderByArg extends schema.Arg + UniqueWhereArg extends schema.Arg, + OrderByArg extends schema.Arg, + FilterArg extends schema.Arg >( - stuff: FieldTypeWithoutDBField + stuff: FieldTypeWithoutDBField< + TDBField, + CreateArg, + UpdateArg, + UniqueWhereArg, + OrderByArg, + FilterArg + > ): NextFieldType { return { ...stuff, dbField }; }; @@ -367,6 +422,11 @@ export type TypesForList = { findManyArgs: FindManyArgs; relateTo: { many: { + where: schema.InputObjectType<{ + every: schema.Arg; + some: schema.Arg; + none: schema.Arg; + }>; create: schema.InputObjectType<{ connect: schema.Arg>>; create?: schema.Arg>>; @@ -393,13 +453,13 @@ export type TypesForList = { }; export type FindManyArgs = { - where: schema.Arg, {}>; + where: schema.Arg, true>; orderBy: schema.Arg< schema.NonNullType>>, - Record[] + true >; - first: schema.Arg; - skip: schema.Arg, number>; + take: schema.Arg; + skip: schema.Arg, true>; }; export type FindManyArgsValue = schema.InferValueFromArgs; diff --git a/packages/types/src/utils.ts b/packages/types/src/utils.ts index b6aee7d0508..7100c4c35f8 100644 --- a/packages/types/src/utils.ts +++ b/packages/types/src/utils.ts @@ -11,7 +11,7 @@ export type BaseGeneratedListTypes = { args: { listQuery: { readonly where?: GraphQLInput | null; - readonly first?: number | null; + readonly take?: number | null; readonly skip?: number; readonly orderBy?: | Record diff --git a/packages/utils/CHANGELOG.md b/packages/utils/CHANGELOG.md index 494c10fdf6f..3e9da6bed6a 100644 --- a/packages/utils/CHANGELOG.md +++ b/packages/utils/CHANGELOG.md @@ -1,5 +1,12 @@ # @keystone-next/utils +## 1.0.4 + +### Patch Changes + +- Updated dependencies [[`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`8187ea019`](https://github.com/keystonejs/keystone/commit/8187ea019a212874f3c602573af3382c6f3bd3b2), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/types@24.0.0 + ## 1.0.3 ### Patch Changes diff --git a/packages/utils/package.json b/packages/utils/package.json index d7c4246fed3..43197d74571 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,7 +1,7 @@ { "name": "@keystone-next/utils", "description": "Common utility functions used throughout @keystone-next packages.", - "version": "1.0.3", + "version": "1.0.4", "author": "The KeystoneJS Development Team", "license": "MIT", "homepage": "https://github.com/keystonejs/keystone", @@ -11,8 +11,8 @@ "node": "^12.20 || >= 14.13" }, "dependencies": { - "@babel/runtime": "^7.14.8", - "@keystone-next/types": "^23.0.0" + "@babel/runtime": "^7.15.3", + "@keystone-next/types": "^24.0.0" }, "repository": "https://github.com/keystonejs/keystone/tree/master/packages/utils" } diff --git a/prisma-utils/.gitignore b/prisma-utils/.gitignore new file mode 100644 index 00000000000..80697f2272d --- /dev/null +++ b/prisma-utils/.gitignore @@ -0,0 +1 @@ +src/generated \ No newline at end of file diff --git a/prisma-utils/README.md b/prisma-utils/README.md new file mode 100644 index 00000000000..bfe77378a66 --- /dev/null +++ b/prisma-utils/README.md @@ -0,0 +1,5 @@ +# prisma-utils + +This (unpublished) package generates the GraphQL filters for most field types in Keystone from Prisma information. + +You can run it with `yarn generate-filters` from the root, you should run this whenever CI fails because of this which should only be after updating Prisma or the script. diff --git a/prisma-utils/package.json b/prisma-utils/package.json new file mode 100644 index 00000000000..925b4d8e5fa --- /dev/null +++ b/prisma-utils/package.json @@ -0,0 +1,17 @@ +{ + "name": "@keystone-next/prisma-utils", + "version": "0.0.0", + "private": true, + "main": "dist/prisma-utils.cjs.js", + "dependencies": { + "@prisma/generator-helper": "2.29.1", + "@prisma/sdk": "2.29.1", + "fs-extra": "^10.0.0", + "prettier": "^2.3.2" + }, + "scripts": { + "generate": "node .", + "verify": "VERIFY=1 node ." + }, + "repository": "https://github.com/keystonejs/keystone/tree/master/prisma-utils" +} diff --git a/prisma-utils/src/index.ts b/prisma-utils/src/index.ts new file mode 100644 index 00000000000..c4570a8c39f --- /dev/null +++ b/prisma-utils/src/index.ts @@ -0,0 +1,313 @@ +// this file generates the GraphQL filter types for most of our fields. +// generating them from the prisma information isn't really about time or convenience. +// it's about clearly showing what the rules for getting the filters are and what the exceptions are. + +import { deepStrictEqual } from 'assert'; +import { isDeepStrictEqual } from 'util'; +import fs from 'fs-extra'; +import { DMMF } from '@prisma/generator-helper'; +import { getDMMF } from '@prisma/sdk'; +import { format, resolveConfig } from 'prettier'; + +const providers = ['postgresql', 'sqlite'] as const; + +type Provider = typeof providers[number]; + +// https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#model-field-scalar-types +// only the prisma scalars that we currently use are here because adding one requires choosing a graphql scalar +// we can add them when we want field types for those scalars +// the missing ones are: +// - Bytes +// - BigInt +// - Unsupported (this one can't be interacted with in the prisma client (and therefore cannot be filtered) so it's irrelevant here) +const scalarTypes = ['String', 'Boolean', 'Int', 'Float', 'DateTime', 'Json', 'Decimal'] as const; + +const getScalarTypesForProvider = (provider: Provider): readonly typeof scalarTypes[number][] => + provider === 'sqlite' ? scalarTypes.filter(x => x !== 'Json') : scalarTypes; + +const getSchemaForProvider = (provider: Provider) => { + const scalarTypesForProvider = getScalarTypesForProvider(provider); + return `datasource ${provider} { + url = env("DATABASE_URL") + provider = "${provider}" +} + +generator client { + provider = "prisma-client-js" +} + +model Optional { + id Int @id @default(autoincrement()) + ${scalarTypesForProvider.map(scalarType => `${scalarType} ${scalarType}?`).join('\n')} +} + +model Required { + id Int @id @default(autoincrement()) + ${scalarTypesForProvider.map(scalarType => `${scalarType} ${scalarType}`).join('\n')} +} + +${ + provider === 'postgresql' + ? `model Many { + id Int @id @default(autoincrement()) + ${scalarTypesForProvider.map(scalarType => `${scalarType} ${scalarType}[]`).join('\n')} +}` + : '' +} + +`; +}; + +(async () => { + const prettierConfig = await resolveConfig(`${__dirname}/index.ts`); + assert(prettierConfig !== null); + for (const provider of providers) { + const schema = getSchemaForProvider(provider); + const dmmf = await getDMMF({ datamodel: schema }); + + await fs.outputFile( + `${__dirname}/generated/${provider}.json`, + JSON.stringify(dmmf.schema.inputObjectTypes, null, 2) + ); + const types = getInputTypesByName(dmmf.schema.inputObjectTypes.prisma); + const rootTypes = getScalarTypesForProvider(provider).flatMap((scalar: string) => { + if (scalar === 'Boolean') { + scalar = 'Bool'; + } + if (scalar === 'SomeEnum') { + // the filter types have to be generic over the enum so it's just easier to write it out manually + // but we still want this here to snapshot what the filters look like for a given prisma version & provider combination + return []; + } + let types = [`${scalar}NullableFilter`, `${scalar}Filter`]; + if (provider === 'postgresql') { + // i'm not sure this is says nullable when they're not nullable? + // i don't think there is a nullable and non-nullable list? + types.push(`${scalar}NullableListFilter`); + } + return types; + }); + for (const typeName of Object.keys(types)) { + replaceNestedNotFilterTypes(types, typeName); + } + const referencedTypes = new Set(); + for (const typeName of rootTypes) { + collectReferencedTypes(types, typeName, referencedTypes); + } + if (provider !== 'sqlite') { + deepStrictEqual( + dmmf.schema.enumTypes.prisma.find(x => x.name === 'QueryMode'), + { name: 'QueryMode', values: ['default', 'insensitive'] } + ); + } + + await fs.outputFile( + `${__dirname}/generated/only-filters/${provider}.json`, + JSON.stringify( + Object.fromEntries([...referencedTypes].map(typeName => [typeName, types[typeName]])), + null, + 2 + ) + ); + const filepath = `${__dirname}/../../packages/types/src/filters/providers/${provider}.ts`; + const newContent = format( + `// Do not manually modify this file, it is automatically generated by the package at /prisma-utils in this repo. +// Update the script if you need this file to be different + + import { schema } from '../../schema'; + + +${provider !== 'sqlite' ? `import { QueryMode } from '../..'` : ''} + +${[...referencedTypes].map(typeName => printInputTypeForGraphQLTS(typeName, types)).join('\n\n')} + +${getScalarTypesForProvider(provider) + .map(scalar => { + const scalarInFilterName = scalar === 'Boolean' ? 'Bool' : scalar; + return `export const ${scalar} = { +optional: ${scalarInFilterName}NullableFilter, +required: ${scalarInFilterName}Filter, +${provider === 'postgresql' ? `many: ${scalarInFilterName}NullableListFilter` : ''} +}`; + }) + .join('\n\n')} + +export {enumFilters as enum } from '../enum-filter' + `, + { ...prettierConfig, filepath } + ); + if (process.env.VERIFY) { + const contents = await fs.readFile(filepath, 'utf8'); + if (contents !== newContent) { + throw new Error( + `The file at ${filepath} is inconsistent with the expected generated contents, please run \`yarn generate-filters\` from the root to update it` + ); + } + } else { + await fs.outputFile(filepath, newContent); + } + } +})().catch(x => { + console.error(x); + process.exit(1); +}); + +function getInputTypesByName(types: DMMF.InputType[]) { + return Object.fromEntries(types.map(x => [x.name, x])); +} + +function assert(condition: boolean, message?: string): asserts condition { + if (!condition) { + debugger; + throw new Error(`assertion failed${message === undefined ? '' : `: ${message}`}`); + } +} + +function replaceNestedNotFilterTypes( + inputTypesByName: Record, + inputTypeName: string +) { + // we want to not replace the nested filter for strings because we don't replace it on postgresql + // and we want the naming to be the same on SQLite + if (inputTypeName.includes('String')) return; + const inputType = inputTypesByName[inputTypeName]; + for (const field of inputType.fields) { + if (field.name === 'not') { + const objectInput = field.inputTypes.find(input => input.namespace === 'prisma'); + if ( + typeof objectInput?.type === 'string' && + isDeepStrictEqual(inputType.fields, inputTypesByName[objectInput.type].fields) + ) { + objectInput.type = inputTypeName; + } + } + } +} + +const expectedScalars = new Set(['Null', 'QueryMode', ...scalarTypes]); + +function collectReferencedTypes( + inputTypesByName: Record, + inputTypeName: string, + referencedTypes: Set +) { + referencedTypes.add(inputTypeName); + const inputType = inputTypesByName[inputTypeName]; + assert(inputType !== undefined, `could not find input type ${inputTypeName}`); + + for (const field of inputType.fields) { + assert(!field.isRequired, 'unexpected required field'); + for (const inputType of field.inputTypes) { + assert(typeof inputType.type === 'string', 'unexpected non-type name in input types'); + if (inputType.location === 'scalar' || inputType.location === 'enumTypes') { + assert(expectedScalars.has(inputType.type), `unexpected scalar ${inputType.type}`); + continue; + } + assert(inputType.location === 'inputObjectTypes', `unexpected ${inputType.location} type`); + if (!referencedTypes.has(inputType.type)) { + collectReferencedTypes(inputTypesByName, inputType.type, referencedTypes); + } + } + } +} + +/** + * Note a field can be both nullable and a list. + * + * Translated into typescript, that means `Array | null`, + * not `Array` or `Array | null` + */ +type TransformedInputTypeField = { + type: string; + isNullable: boolean; + isList: boolean; +}; + +function pickInputTypeForField(field: DMMF.SchemaArg): TransformedInputTypeField { + assert(!field.isRequired, 'unexpected required field'); + // null is already represented with field.isNullable + const inputTypesWithoutNull = field.inputTypes.filter(type => { + if (type.type === 'Null') { + assert(!type.isList, 'unexpected null list'); + assert(field.isNullable, 'unexpected isNullable false when null type in input types'); + return false; + } + return true; + }); + + assert( + inputTypesWithoutNull.length + Number(field.isNullable) === field.inputTypes.length, + 'unexpected isNullable false when null type in input types' + ); + const inputType = (() => { + if (inputTypesWithoutNull.length === 1) { + return inputTypesWithoutNull[0]; + } + assert( + inputTypesWithoutNull.length === 2, + 'unexpected more than two input types excluding null' + ); + const inputType = inputTypesWithoutNull.find(x => x.location == 'inputObjectTypes'); + assert( + !!inputType, + 'could not find input object type when more than one input type excluding null' + ); + return inputType; + })(); + assert(typeof inputType.type === 'string'); + return { + isList: inputType.isList, + isNullable: field.isNullable, + type: scalarsToGqlScalars[inputType.type] ?? inputType.type, + }; +} + +function printInputTypeForGraphQLTS( + inputTypeName: string, + inputTypesByName: Record +) { + const inputType = inputTypesByName[inputTypeName]; + assert(inputType !== undefined, `could not find input type ${inputTypeName}`); + const expectedMaxMinNumFields = inputTypeName.endsWith('NullableListFilter') ? 1 : null; + assert(inputType.constraints.maxNumFields === expectedMaxMinNumFields); + assert(inputType.constraints.minNumFields === expectedMaxMinNumFields); + const nameOfInputObjectTypeType = `${inputTypeName}Type`; + const fields = inputType.fields.map(x => [x.name, pickInputTypeForField(x)] as const); + return `type ${nameOfInputObjectTypeType} = schema.InputObjectType<{ + ${fields + .map(([name, field]) => { + return `${field.isNullable ? '// can be null\n' : ''}${name}: schema.Arg<${ + field.isList + ? `schema.ListType>` + : `typeof ${field.type}` + }>`; + }) + .join(',\n')} + }> + + const ${inputTypeName}: ${nameOfInputObjectTypeType} = schema.inputObject({ + name: '${ + // we want to use Boolean instead of Bool because GraphQL calls it Boolean + inputTypeName.replace('Bool', 'Boolean') + }', + fields: () => ({ + ${fields + .map(([name, field]) => { + return `${field.isNullable ? '// can be null\n' : ''}${name}: schema.arg({ type: ${ + field.isList ? `schema.list(schema.nonNull(${field.type}))` : field.type + } })`; + }) + .join(',\n')} + }) + })`; +} + +const scalarsToGqlScalars: Record = { + String: 'schema.String', + Boolean: 'schema.Boolean', + Int: 'schema.Int', + Float: 'schema.Float', + Json: 'schema.JSON', + DateTime: 'schema.String', + Decimal: 'schema.String', +}; diff --git a/tests/admin-ui-tests/CHANGELOG.md b/tests/admin-ui-tests/CHANGELOG.md index 5cc500dd0a4..e552f895fa8 100644 --- a/tests/admin-ui-tests/CHANGELOG.md +++ b/tests/admin-ui-tests/CHANGELOG.md @@ -1,5 +1,14 @@ # @keystone-next/admin-ui-tests +## 0.0.4 + +### Patch Changes + +- Updated dependencies [[`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`8187ea019`](https://github.com/keystonejs/keystone/commit/8187ea019a212874f3c602573af3382c6f3bd3b2), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/types@24.0.0 + - @keystone-next/testing@1.1.1 + - @keystone-next/utils@1.0.4 + ## 0.0.3 ### Patch Changes diff --git a/tests/admin-ui-tests/package.json b/tests/admin-ui-tests/package.json index 81d9992dab8..c59a07e04fe 100644 --- a/tests/admin-ui-tests/package.json +++ b/tests/admin-ui-tests/package.json @@ -2,7 +2,7 @@ "name": "@keystone-next/admin-ui-tests", "description": "A set of tests for the KeystoneJS Admin UI.", "private": true, - "version": "0.0.3", + "version": "0.0.4", "author": "The KeystoneJS Development Team", "license": "MIT", "engines": { @@ -16,7 +16,7 @@ "@keystone-next/keystone": "*", "execa": "^5.1.1", "express": "^4.17.1", - "playwright": "^1.13.1", + "playwright": "^1.14.0", "treekill": "^1.0.0" }, "scripts": { @@ -25,9 +25,9 @@ "build": "keystone-next build" }, "dependencies": { - "@keystone-next/testing": "^1.1.0", - "@keystone-next/types": "^23.0.0", - "@keystone-next/utils": "^1.0.3", + "@keystone-next/testing": "^1.1.1", + "@keystone-next/types": "^24.0.0", + "@keystone-next/utils": "^1.0.4", "@manypkg/find-root": "^1.1.0", "dotenv": "^10.0.0", "tree-kill": "^1.2.2" diff --git a/tests/api-tests/CHANGELOG.md b/tests/api-tests/CHANGELOG.md index f48751d233d..59cf2f73b16 100644 --- a/tests/api-tests/CHANGELOG.md +++ b/tests/api-tests/CHANGELOG.md @@ -1,5 +1,18 @@ # @keystonejs/api-tests +## 11.1.0 + +### Minor Changes + +- [#6276](https://github.com/keystonejs/keystone/pull/6276) [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb) Thanks [@gautamsi](https://github.com/gautamsi)! - Added option for `Bearer` token auth when using session. + +### Patch Changes + +- Updated dependencies [[`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`8187ea019`](https://github.com/keystonejs/keystone/commit/8187ea019a212874f3c602573af3382c6f3bd3b2), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/types@24.0.0 + - @keystone-next/testing@1.1.1 + - @keystone-next/utils@1.0.4 + ## 11.0.6 ### Patch Changes diff --git a/tests/api-tests/access-control/authed.test.ts b/tests/api-tests/access-control/authed.test.ts index 963c6e670e9..746bab83f25 100644 --- a/tests/api-tests/access-control/authed.test.ts +++ b/tests/api-tests/access-control/authed.test.ts @@ -22,7 +22,7 @@ const expectNoAccess = ( errors: readonly GraphQLError[] | undefined, name: N ) => { - expectAccessDenied(errors, [{ path: [name] }]); + expectAccessDenied('dev', false, undefined, errors, [{ path: [name] }]); expect(data?.[name]).toBe(null); }; @@ -158,7 +158,9 @@ describe('Authed', () => { expect(data).toEqual({ authenticatedItem: { id: user.id, yesRead: user.yesRead, noRead: null }, }); - expectAccessDenied(errors, [{ path: ['authenticatedItem', 'noRead'] }]); + expectAccessDenied('dev', false, undefined, errors, [ + { path: ['authenticatedItem', 'noRead'] }, + ]); }); (['imperative', 'declarative'] as const).forEach(mode => { @@ -218,7 +220,7 @@ describe('Authed', () => { test(`multiple not existing: ${JSON.stringify(access)}`, async () => { const _items = await context.lists[listKey].findMany({ - where: { id_in: [FAKE_ID[provider], FAKE_ID_2[provider]] }, + where: { id: { in: [FAKE_ID[provider], FAKE_ID_2[provider]] } }, }); expect(_items).toHaveLength(0); }); @@ -442,7 +444,7 @@ describe('Authed', () => { if (mode === 'imperative') { expectNamedArray(data, errors, multiDeleteMutationName, [validId1, validId2]); } else { - expectAccessDenied(errors, [ + expectAccessDenied('dev', false, undefined, errors, [ { path: [multiDeleteMutationName, 0] }, { path: [multiDeleteMutationName, 1] }, ]); @@ -459,7 +461,9 @@ describe('Authed', () => { if (mode === 'imperative') { expectNamedArray(data, errors, multiDeleteMutationName, [validId1, invalidId]); } else { - expectAccessDenied(errors, [{ path: [multiDeleteMutationName, 1] }]); + expectAccessDenied('dev', false, undefined, errors, [ + { path: [multiDeleteMutationName, 1] }, + ]); expect(data).toEqual({ [multiDeleteMutationName]: [{ id: validId1 }, null] }); } }); @@ -468,7 +472,7 @@ describe('Authed', () => { const multiDeleteMutationName = `delete${nameFn[mode](access)}s`; const query = `mutation { ${multiDeleteMutationName}(where: [{ id: "${FAKE_ID[provider]}" }, { id: "${FAKE_ID_2[provider]}" }]) { id } }`; const { data, errors } = await context.graphql.raw({ query }); - expectAccessDenied(errors, [ + expectAccessDenied('dev', false, undefined, errors, [ { path: [multiDeleteMutationName, 0] }, { path: [multiDeleteMutationName, 1] }, ]); diff --git a/tests/api-tests/access-control/mutations-field-static.test.ts b/tests/api-tests/access-control/mutations-field-static.test.ts index 5ce3f47daca..7eebb4e8b4e 100644 --- a/tests/api-tests/access-control/mutations-field-static.test.ts +++ b/tests/api-tests/access-control/mutations-field-static.test.ts @@ -51,7 +51,7 @@ describe('Access control - Imperative => static', () => { // Returns null and throws an error expect(data).toEqual({ createUser: null }); - expectAccessDenied(errors, [{ path: ['createUser'] }]); + expectAccessDenied('dev', false, undefined, errors, [{ path: ['createUser'] }]); // Only the original user should exist const _users = await context.lists.User.findMany({ query: 'id name other' }); @@ -79,7 +79,7 @@ describe('Access control - Imperative => static', () => { // Returns null and throws an error expect(data).toEqual({ updateUser: null }); - expectAccessDenied(errors, [{ path: ['updateUser'] }]); + expectAccessDenied('dev', false, undefined, errors, [{ path: ['updateUser'] }]); // User should have its original name const _users = await context.lists.User.findMany({ query: 'id name other' }); @@ -118,7 +118,10 @@ describe('Access control - Imperative => static', () => { }); // The invalid updates should have errors which point to the nulls in their path - expectAccessDenied(errors, [{ path: ['createUsers', 1] }, { path: ['createUsers', 3] }]); + expectAccessDenied('dev', false, undefined, errors, [ + { path: ['createUsers', 1] }, + { path: ['createUsers', 3] }, + ]); // Valid users should exist in the database const users = await context.lists.User.findMany({ @@ -172,7 +175,10 @@ describe('Access control - Imperative => static', () => { }); // The invalid updates should have errors which point to the nulls in their path - expectAccessDenied(errors, [{ path: ['updateUsers', 1] }, { path: ['updateUsers', 3] }]); + expectAccessDenied('dev', false, undefined, errors, [ + { path: ['updateUsers', 1] }, + { path: ['updateUsers', 3] }, + ]); // All users should still exist in the database const _users = await context.lists.User.findMany({ diff --git a/tests/api-tests/access-control/mutations-list-declarative.test.ts b/tests/api-tests/access-control/mutations-list-declarative.test.ts index cbe015f6a77..c1618c85856 100644 --- a/tests/api-tests/access-control/mutations-list-declarative.test.ts +++ b/tests/api-tests/access-control/mutations-list-declarative.test.ts @@ -12,8 +12,8 @@ const runner = setupTestRunner({ access: { read: true, create: true, - update: () => ({ name_not: 'bad' }), - delete: async () => ({ name_not_contains: 'no delete' }), + update: () => ({ name: { not: { equals: 'bad' } } }), + delete: async () => ({ name: { not: { contains: 'no delete' } } }), }, }), }), @@ -40,7 +40,7 @@ describe('Access control - Imperative => declarative', () => { // Returns null and throws an error expect(data).toEqual({ updateUser: null }); - expectAccessDenied(errors, [{ path: ['updateUser'] }]); + expectAccessDenied('dev', false, undefined, errors, [{ path: ['updateUser'] }]); // User should have its original name const _users = await context.lists.User.findMany({ query: 'id name' }); @@ -65,7 +65,7 @@ describe('Access control - Imperative => declarative', () => { // Returns null and throws an error expect(data).toEqual({ deleteUser: null }); - expectAccessDenied(errors, [{ path: ['deleteUser'] }]); + expectAccessDenied('dev', false, undefined, errors, [{ path: ['deleteUser'] }]); // Bad users should still be in the database. const _users = await context.lists.User.findMany({ query: 'id name' }); @@ -120,7 +120,10 @@ describe('Access control - Imperative => declarative', () => { null, ], }); - expectAccessDenied(errors, [{ path: ['updateUsers', 1] }, { path: ['updateUsers', 3] }]); + expectAccessDenied('dev', false, undefined, errors, [ + { path: ['updateUsers', 1] }, + { path: ['updateUsers', 3] }, + ]); // All users should still exist in the database const _users = await context.lists.User.findMany({ @@ -161,7 +164,10 @@ describe('Access control - Imperative => declarative', () => { }, }); - expectAccessDenied(errors, [{ path: ['deleteUsers', 1] }, { path: ['deleteUsers', 3] }]); + expectAccessDenied('dev', false, undefined, errors, [ + { path: ['deleteUsers', 1] }, + { path: ['deleteUsers', 3] }, + ]); // Valid users are returned, invalid come back as null // The invalid deletes should have errors which point to the nulls in their path diff --git a/tests/api-tests/access-control/mutations-list-static.test.ts b/tests/api-tests/access-control/mutations-list-static.test.ts index 3984c0c9e6f..3c2ce0d1a0a 100644 --- a/tests/api-tests/access-control/mutations-list-static.test.ts +++ b/tests/api-tests/access-control/mutations-list-static.test.ts @@ -46,7 +46,7 @@ describe('Access control - Imperative => static', () => { // Returns null and throws an error expect(data).toEqual({ createUser: null }); - expectAccessDenied(errors, [{ path: ['createUser'] }]); + expectAccessDenied('dev', false, undefined, errors, [{ path: ['createUser'] }]); // Only the original user should exist const _users = await context.lists.User.findMany({ query: 'id name' }); @@ -70,7 +70,7 @@ describe('Access control - Imperative => static', () => { // Returns null and throws an error expect(data).toEqual({ updateUser: null }); - expectAccessDenied(errors, [{ path: ['updateUser'] }]); + expectAccessDenied('dev', false, undefined, errors, [{ path: ['updateUser'] }]); // User should have its original name const _users = await context.lists.User.findMany({ query: 'id name' }); @@ -95,7 +95,7 @@ describe('Access control - Imperative => static', () => { // Returns null and throws an error expect(data).toEqual({ deleteUser: null }); - expectAccessDenied(errors, [{ path: ['deleteUser'] }]); + expectAccessDenied('dev', false, undefined, errors, [{ path: ['deleteUser'] }]); // Bad users should still be in the database. const _users = await context.lists.User.findMany({ query: 'id name' }); @@ -133,7 +133,10 @@ describe('Access control - Imperative => static', () => { }); // The invalid updates should have errors which point to the nulls in their path - expectAccessDenied(errors, [{ path: ['createUsers', 1] }, { path: ['createUsers', 3] }]); + expectAccessDenied('dev', false, undefined, errors, [ + { path: ['createUsers', 1] }, + { path: ['createUsers', 3] }, + ]); // The good users should exist in the database const users = await context.lists.User.findMany(); @@ -182,7 +185,10 @@ describe('Access control - Imperative => static', () => { ]); // The invalid updates should have errors which point to the nulls in their path - expectAccessDenied(errors, [{ path: ['updateUsers', 1] }, { path: ['updateUsers', 3] }]); + expectAccessDenied('dev', false, undefined, errors, [ + { path: ['updateUsers', 1] }, + { path: ['updateUsers', 3] }, + ]); // All users should still exist in the database const _users = await context.lists.User.findMany({ @@ -232,7 +238,10 @@ describe('Access control - Imperative => static', () => { ]); // The invalid updates should have errors which point to the nulls in their path - expectAccessDenied(errors, [{ path: ['deleteUsers', 1] }, { path: ['deleteUsers', 3] }]); + expectAccessDenied('dev', false, undefined, errors, [ + { path: ['deleteUsers', 1] }, + { path: ['deleteUsers', 3] }, + ]); const _users = await context.lists.User.findMany({ orderBy: { name: 'asc' }, diff --git a/tests/api-tests/access-control/not-authed.test.ts b/tests/api-tests/access-control/not-authed.test.ts index 2ac02923d9d..d95b7f3f4f8 100644 --- a/tests/api-tests/access-control/not-authed.test.ts +++ b/tests/api-tests/access-control/not-authed.test.ts @@ -20,7 +20,7 @@ const expectNoAccess = ( name: N ) => { expect(data?.[name]).toBe(null); - expectAccessDenied(errors, [{ path: [name] }]); + expectAccessDenied('dev', false, undefined, errors, [{ path: [name] }]); }; type IdType = any; @@ -136,7 +136,7 @@ describe(`Not authed`, () => { const query = `mutation { ${createMutationName}(data: { ${fieldName}: "bar" }) { id } }`; const { data, errors } = await context.graphql.raw({ query }); expect(data).toEqual({ [createMutationName]: null }); - expectAccessDenied(errors, [{ path: [createMutationName] }]); + expectAccessDenied('dev', false, undefined, errors, [{ path: [createMutationName] }]); }); }); }); @@ -163,7 +163,7 @@ describe(`Not authed`, () => { const query = `query { ${countName} }`; const { data, errors } = await context.graphql.raw({ query }); expect(data).toEqual({ [countName]: null }); - expectAccessDenied(errors, [{ path: [countName] }]); + expectAccessDenied('dev', false, undefined, errors, [{ path: [countName] }]); }); test(`single denied: ${JSON.stringify(access)}`, async () => { @@ -197,7 +197,9 @@ describe(`Not authed`, () => { }); const query = `query { ${singleQueryName}(where: { id: "${item.id}" }) { id ${fieldName} } }`; const { data, errors } = await context.graphql.raw({ query }); - expectAccessDenied(errors, [{ path: [singleQueryName, fieldName] }]); + expectAccessDenied('dev', false, undefined, errors, [ + { path: [singleQueryName, fieldName] }, + ]); expect(data).toEqual({ [singleQueryName]: { id: item.id, [fieldName]: null } }); }); test(`field allowed - multi: ${JSON.stringify(access)}`, async () => { @@ -217,7 +219,7 @@ describe(`Not authed`, () => { }); const query = `query { ${allQueryName} { id ${fieldName} } }`; const { data, errors } = await context.graphql.raw({ query }); - expectAccessDenied(errors, [ + expectAccessDenied('dev', false, undefined, errors, [ { path: [allQueryName, 0, fieldName] }, { path: [allQueryName, 1, fieldName] }, ]); @@ -351,7 +353,7 @@ describe(`Not authed`, () => { const query = `mutation { ${updateMutationName}(where: { id: "${item.id}" }, data: { ${fieldName}: "bar" }) { id } }`; const { data, errors } = await context.graphql.raw({ query }); expect(data).toEqual({ [updateMutationName]: null }); - expectAccessDenied(errors, [{ path: [updateMutationName] }]); + expectAccessDenied('dev', false, undefined, errors, [{ path: [updateMutationName] }]); }); }); }); @@ -377,7 +379,9 @@ describe(`Not authed`, () => { const { data, errors } = await context.graphql.raw({ query }); expect(data).toEqual({ [multiDeleteMutationName]: [null] }); - expectAccessDenied(errors, [{ path: [multiDeleteMutationName, 0] }]); + expectAccessDenied('dev', false, undefined, errors, [ + { path: [multiDeleteMutationName, 0] }, + ]); }); }); }); diff --git a/tests/api-tests/access-control/utils.ts b/tests/api-tests/access-control/utils.ts index 012a038f17c..f8ad58fb1db 100644 --- a/tests/api-tests/access-control/utils.ts +++ b/tests/api-tests/access-control/utils.ts @@ -38,7 +38,7 @@ const getDeclarativeListName = (access: BooleanAccess) => `${getPrefix(access)}D }), {})); } */ -const listAccessVariations: BooleanAccess[] = [ +const listAccessVariations: (BooleanAccess & { delete: boolean })[] = [ { create: false, read: false, update: false, delete: false }, { create: true, read: false, update: false, delete: false }, { create: false, read: true, update: false, delete: false }, @@ -129,9 +129,9 @@ listAccessVariations.forEach(access => { access: { create: access.create, // arbitrarily restrict the data to a single item (see data.js) - read: () => access.read && { name: 'Hello' }, - update: () => access.update && { name: 'Hello' }, - delete: () => access.delete && { name: 'Hello' }, + read: () => access.read && { name: { equals: 'Hello' } }, + update: () => access.update && { name: { equals: 'Hello' } }, + delete: () => access.delete && { name: { equals: 'Hello' } }, }, }); }); diff --git a/tests/api-tests/auth-header.test.ts b/tests/api-tests/auth-header.test.ts index c64eeda9a61..e9d027d55d3 100644 --- a/tests/api-tests/auth-header.test.ts +++ b/tests/api-tests/auth-header.test.ts @@ -83,7 +83,7 @@ describe('Auth testing', () => { } const { data, errors } = await context.graphql.raw({ query: '{ users { id } }' }); expect(data).toEqual({ users: null }); - expectAccessDenied(errors, [{ path: ['users'] }]); + expectAccessDenied('dev', false, undefined, errors, [{ path: ['users'] }]); }) ); @@ -118,8 +118,7 @@ describe('Auth testing', () => { }); describe('logged in', () => { - // eslint-disable-next-line jest/no-disabled-tests - test.skip( + test( 'Allows access with bearer token', runner(async ({ context, graphQLRequest }) => { for (const [listKey, data] of Object.entries(initialData)) { diff --git a/tests/api-tests/extend-graphql-schema/extend-graphql-schema.test.ts b/tests/api-tests/extend-graphql-schema/extend-graphql-schema.test.ts index c14587da68a..5d07a5b50a9 100644 --- a/tests/api-tests/extend-graphql-schema/extend-graphql-schema.test.ts +++ b/tests/api-tests/extend-graphql-schema/extend-graphql-schema.test.ts @@ -70,13 +70,15 @@ describe('extendGraphqlSchema', () => { runner(async ({ graphQLRequest }) => { const { body } = await graphQLRequest({ query: ` - query { - quads(x: 10) - } - `, + query { + quads(x: 10) + } + `, }); expect(body.data).toEqual({ quads: null }); - expectInternalServerError(body.errors, [{ path: ['quads'], message: 'Access denied' }]); + expectInternalServerError(body.errors, false, [ + { path: ['quads'], message: 'Access denied' }, + ]); }) ); it( diff --git a/tests/api-tests/fields/filter.test.ts b/tests/api-tests/fields/filter.test.ts index 96da9dd5ba6..21d803ed0c5 100644 --- a/tests/api-tests/fields/filter.test.ts +++ b/tests/api-tests/fields/filter.test.ts @@ -93,289 +93,357 @@ testModules ? `name ${fieldName} { ${subfieldName} }` : `name ${fieldName}`; - const match = async ( - context: KeystoneContext, - where: Record | undefined, - expected: any[], - orderBy: Record = { name: 'asc' } - ) => - expect(await context.lists[listKey].findMany({ where, orderBy, query })).toEqual( - expected.map(i => storedValues[i]) - ); + describe.each(['without negation', 'with negation'] as const)('%s', kind => { + const match = async ( + context: KeystoneContext, + where: Record | undefined, + expectedIndexes: number[] + ) => { + let expected = expectedIndexes.map(i => storedValues[i]); + if (kind === 'with negation') { + const expectedWithoutNegation = new Set(expected); + expected = storedValues.filter((v: any) => !expectedWithoutNegation.has(v)); + } + expect( + await context.lists[listKey].findMany({ + where: kind === 'with negation' ? { NOT: where } : where, + orderBy: { name: 'asc' }, + query, + }) + ).toEqual(expected); + }; - test( - `No Filter`, - withKeystone(({ context }) => match(context, undefined, [0, 1, 2, 3, 4, 5, 6])) - ); + if (kind === 'without negation') { + test( + `No Filter`, + withKeystone(({ context }) => match(context, undefined, [0, 1, 2, 3, 4, 5, 6])) + ); + // arguably this should return [] when negated + // but i assume prisma is like "this things empty, let's just ignore it" + // this is fine imo since "i want to query this api and have it definitely return no results" + // isn't really very useful + test( + `Empty Filter`, + withKeystone(({ context }) => match(context, {}, [0, 1, 2, 3, 4, 5, 6])) + ); + } - test( - `Empty Filter`, - withKeystone(({ context }) => match(context, {}, [0, 1, 2, 3, 4, 5, 6])) - ); - if (mod.supportedFilters(provider).includes('null_equality')) { - test( - 'Equals null', - withKeystone(({ context }) => match(context, { [`${fieldName}`]: null }, [5, 6])) - ); - test( - 'Not Equals null', - withKeystone(({ context }) => - match(context, { [`${fieldName}_not`]: null }, [0, 1, 2, 3, 4]) - ) - ); - } - if (mod.supportedFilters(provider).includes('equality')) { - test( - 'Equals', - withKeystone(({ context }) => - match(context, { [`${fieldName}`]: storedValues[3][fieldName] }, [3]) - ) - ); - test( - 'Not Equals', - withKeystone(({ context }) => - match( - context, - { [`${fieldName}_not`]: storedValues[3][fieldName] }, - [0, 1, 2, 4, 5, 6] + if (mod.supportedFilters(provider).includes('null_equality')) { + test( + 'Equals null', + withKeystone(({ context }) => + match(context, { [`${fieldName}`]: { equals: null } }, [5, 6]) ) - ) - ); - } - if (mod.supportedFilters(provider).includes('equality_case_insensitive')) { - test( - `Equals - Case Insensitive`, - withKeystone(({ context }) => - match(context, { [`${fieldName}_i`]: storedValues[3][fieldName] }, [2, 3, 4]) - ) - ); - - test( - `Not Equals - Case Insensitive`, - withKeystone(({ context }) => - match(context, { [`${fieldName}_not_i`]: storedValues[3][fieldName] }, [0, 1, 5, 6]) - ) - ); - } - if (mod.supportedFilters(provider).includes('string')) { - test( - `Contains`, - withKeystone(({ context }) => - match(context, { [`${fieldName}_contains`]: 'oo' }, [3, 4]) - ) - ); - test( - `Not Contains`, - withKeystone(({ context }) => - match(context, { [`${fieldName}_not_contains`]: 'oo' }, [0, 1, 2, 5, 6]) - ) - ); - test( - `Starts With`, - withKeystone(({ context }) => - match(context, { [`${fieldName}_starts_with`]: 'foo' }, [3, 4]) - ) - ); - test( - `Not Starts With`, - withKeystone(({ context }) => - match(context, { [`${fieldName}_not_starts_with`]: 'foo' }, [0, 1, 2, 5, 6]) - ) - ); - test( - `Ends With`, - withKeystone(({ context }) => - match(context, { [`${fieldName}_ends_with`]: 'BAR' }, [2, 3]) - ) - ); - test( - `Not Ends With`, - withKeystone(({ context }) => - match(context, { [`${fieldName}_not_ends_with`]: 'BAR' }, [0, 1, 4, 5, 6]) - ) - ); - } - if (mod.supportedFilters(provider).includes('string_case_insensitive')) { - test( - `Contains - Case Insensitive`, - withKeystone(({ context }) => - match(context, { [`${fieldName}_contains_i`]: 'oo' }, [2, 3, 4]) - ) - ); - - test( - `Not Contains - Case Insensitive`, - withKeystone(({ context }) => - match(context, { [`${fieldName}_not_contains_i`]: 'oo' }, [0, 1, 5, 6]) - ) - ); + ); + test( + 'Not Equals null', + withKeystone(({ context }) => + match(context, { [`${fieldName}`]: { not: { equals: null } } }, [0, 1, 2, 3, 4]) + ) + ); + } + if (mod.supportedFilters(provider).includes('equality')) { + test( + 'Equals', + withKeystone(({ context }) => + match(context, { [`${fieldName}`]: { equals: storedValues[3][fieldName] } }, [3]) + ) + ); + test( + 'Not Equals', + withKeystone(({ context }) => + match( + context, + { NOT: { [`${fieldName}`]: { equals: storedValues[3][fieldName] } } }, + [0, 1, 2, 4, 5, 6] + ) + ) + ); + } + if (mod.supportedFilters(provider).includes('equality_case_insensitive')) { + test( + `Equals - Case Insensitive`, + withKeystone(({ context }) => + match( + context, + { + [`${fieldName}`]: { equals: storedValues[3][fieldName], mode: 'insensitive' }, + }, + [2, 3, 4] + ) + ) + ); - test( - `Starts With - Case Insensitive`, - withKeystone(({ context }) => - match(context, { [`${fieldName}_starts_with_i`]: 'foo' }, [2, 3, 4]) - ) - ); + test( + `Not Equals - Case Insensitive`, + withKeystone(({ context }) => + match( + context, + { + [`${fieldName}`]: { + mode: 'insensitive', + not: { equals: storedValues[3][fieldName] }, + }, + }, + [0, 1, 5, 6] + ) + ) + ); + } + if (mod.supportedFilters(provider).includes('string')) { + test( + `Contains`, + withKeystone(({ context }) => + match(context, { [`${fieldName}`]: { contains: 'oo' } }, [3, 4]) + ) + ); + test( + `Not Contains`, + withKeystone(({ context }) => + match(context, { [`${fieldName}`]: { not: { contains: 'oo' } } }, [0, 1, 2, 5, 6]) + ) + ); + test( + `Starts With`, + withKeystone(({ context }) => + match(context, { [`${fieldName}`]: { startsWith: 'foo' } }, [3, 4]) + ) + ); + test( + `Not Starts With`, + withKeystone(({ context }) => + match( + context, + { [`${fieldName}`]: { not: { startsWith: 'foo' } } }, + [0, 1, 2, 5, 6] + ) + ) + ); + test( + `Ends With`, + withKeystone(({ context }) => + match(context, { [`${fieldName}`]: { endsWith: 'BAR' } }, [2, 3]) + ) + ); + test( + `Not Ends With`, + withKeystone(({ context }) => + match( + context, + { [`${fieldName}`]: { not: { endsWith: 'BAR' } } }, + [0, 1, 4, 5, 6] + ) + ) + ); + } + if (mod.supportedFilters(provider).includes('string_case_insensitive')) { + test( + `Contains - Case Insensitive`, + withKeystone(({ context }) => + match( + context, + { [`${fieldName}`]: { mode: 'insensitive', contains: 'oo' } }, + [2, 3, 4] + ) + ) + ); - test( - `Not Starts With - Case Insensitive`, - withKeystone(({ context }) => - match(context, { [`${fieldName}_not_starts_with_i`]: 'foo' }, [0, 1, 5, 6]) - ) - ); + test( + `Not Contains - Case Insensitive`, + withKeystone(({ context }) => + match( + context, + { [`${fieldName}`]: { mode: 'insensitive', not: { contains: 'oo' } } }, + [0, 1, 5, 6] + ) + ) + ); - test( - `Ends With - Case Insensitive`, - withKeystone(({ context }) => - match(context, { [`${fieldName}_ends_with_i`]: 'BAR' }, [2, 3, 4]) - ) - ); + test( + `Starts With - Case Insensitive`, + withKeystone(({ context }) => + match( + context, + { [`${fieldName}`]: { mode: 'insensitive', startsWith: 'foo' } }, + [2, 3, 4] + ) + ) + ); - test( - `Not Ends With - Case Insensitive`, - withKeystone(({ context }) => - match(context, { [`${fieldName}_not_ends_with_i`]: 'BAR' }, [0, 1, 5, 6]) - ) - ); - } - if (mod.supportedFilters(provider).includes('ordering')) { - test( - 'Less than', - withKeystone(({ context }) => - match(context, { [`${fieldName}_lt`]: storedValues[2][fieldName] }, [0, 1]) - ) - ); - test( - 'Less than or equal', - withKeystone(({ context }) => - match(context, { [`${fieldName}_lte`]: storedValues[2][fieldName] }, [0, 1, 2]) - ) - ); - test( - 'Greater than', - withKeystone(({ context }) => - match(context, { [`${fieldName}_gt`]: storedValues[2][fieldName] }, [3, 4]) - ) - ); - test( - 'Greater than or equal', - withKeystone(({ context }) => - match(context, { [`${fieldName}_gte`]: storedValues[2][fieldName] }, [2, 3, 4]) - ) - ); - } - if (mod.supportedFilters(provider).includes('in_empty_null')) { - test( - 'In - Empty List', - withKeystone(({ context }) => match(context, { [`${fieldName}_in`]: [] }, [])) - ); + test( + `Not Starts With - Case Insensitive`, + withKeystone(({ context }) => + match( + context, + { [`${fieldName}`]: { mode: 'insensitive', not: { startsWith: 'foo' } } }, + [0, 1, 5, 6] + ) + ) + ); - test( - 'Not In - Empty List', - withKeystone(({ context }) => - match(context, { [`${fieldName}_not_in`]: [] }, [0, 1, 2, 3, 4, 5, 6]) - ) - ); + test( + `Ends With - Case Insensitive`, + withKeystone(({ context }) => + match( + context, + { [`${fieldName}`]: { mode: 'insensitive', endsWith: 'BAR' } }, + [2, 3, 4] + ) + ) + ); - test( - 'In - null', - withKeystone(({ context }) => match(context, { [`${fieldName}_in`]: [null] }, [5, 6])) - ); + test( + `Not Ends With - Case Insensitive`, + withKeystone(({ context }) => + match( + context, + { + [`${fieldName}`]: { mode: 'insensitive', not: { endsWith: 'BAR' } }, + }, + [0, 1, 5, 6] + ) + ) + ); + } + if (mod.supportedFilters(provider).includes('ordering')) { + test( + 'Less than', + withKeystone(({ context }) => + match(context, { [`${fieldName}`]: { lt: storedValues[2][fieldName] } }, [0, 1]) + ) + ); + test( + 'Less than or equal', + withKeystone(({ context }) => + match( + context, + { [`${fieldName}`]: { lte: storedValues[2][fieldName] } }, + [0, 1, 2] + ) + ) + ); + test( + 'Greater than', + withKeystone(({ context }) => + match(context, { [`${fieldName}`]: { gt: storedValues[2][fieldName] } }, [3, 4]) + ) + ); + test( + 'Greater than or equal', + withKeystone(({ context }) => + match( + context, + { [`${fieldName}`]: { gte: storedValues[2][fieldName] } }, + [2, 3, 4] + ) + ) + ); + } + if (mod.supportedFilters(provider).includes('in_empty_null')) { + test( + 'In - Empty List', + withKeystone(({ context }) => match(context, { [`${fieldName}`]: { in: [] } }, [])) + ); - test( - 'Not In - null', - withKeystone(({ context }) => - match(context, { [`${fieldName}_not_in`]: [null] }, [0, 1, 2, 3, 4]) - ) - ); - } - if (mod.supportedFilters(provider).includes('in_equal')) { - test( - 'In - values', - withKeystone(({ context }) => - match( - context, - { - [`${fieldName}_in`]: [ - storedValues[0][fieldName], - storedValues[2][fieldName], - storedValues[4][fieldName], - ], - }, - [0, 2, 4] + test( + 'Not In - Empty List', + withKeystone(({ context }) => + match(context, { [`${fieldName}`]: { notIn: [] } }, [0, 1, 2, 3, 4, 5, 6]) ) - ) - ); - test( - 'Not In - values', - withKeystone(({ context }) => - match( - context, - { - [`${fieldName}_not_in`]: [ - storedValues[0][fieldName], - storedValues[2][fieldName], - storedValues[4][fieldName], - ], - }, - [1, 3, 5, 6] + ); + } + if (mod.supportedFilters(provider).includes('in_equal')) { + test( + 'In - values', + withKeystone(({ context }) => + match( + context, + { + [`${fieldName}`]: { + in: [ + storedValues[0][fieldName], + storedValues[2][fieldName], + storedValues[4][fieldName], + ], + }, + }, + [0, 2, 4] + ) ) - ) - ); - } - if (mod.supportedFilters(provider).includes('is_set')) { - test( - 'Is Set - true', - withKeystone(({ context }) => - match(context, { [`${fieldName}_is_set`]: true }, [0, 2, 3, 4]) - ) - ); - test( - 'Is Set - false', - withKeystone(({ context }) => - match(context, { [`${fieldName}_is_set`]: false }, [1, 5, 6]) - ) - ); - } - if (mod.supportedFilters(provider).includes('unique_equality')) { - test( - 'Unique equality', - setupTestRunner({ - config: apiTestConfig({ - lists: createSchema({ - [listKey]: list({ - fields: { - field: mod.typeFunction({ isUnique: true }), + ); + test( + 'Not In - values', + withKeystone(({ context }) => + match( + context, + { + [`${fieldName}`]: { + notIn: [ + storedValues[0][fieldName], + storedValues[2][fieldName], + storedValues[4][fieldName], + ], }, + }, + [1, 3, 5, 6] + ) + ) + ); + } + if (mod.supportedFilters(provider).includes('is_set')) { + test( + 'Is Set - true', + withKeystone(({ context }) => + match(context, { [`${fieldName}`]: { isSet: true } }, [0, 2, 3, 4]) + ) + ); + test( + 'Is Set - false', + withKeystone(({ context }) => + match(context, { [`${fieldName}`]: { isSet: false } }, [1, 5, 6]) + ) + ); + } + if (mod.supportedFilters(provider).includes('unique_equality')) { + test( + 'Unique equality', + setupTestRunner({ + config: apiTestConfig({ + lists: createSchema({ + [listKey]: list({ + fields: { + field: mod.typeFunction({ isUnique: true }), + }, + }), }), }), - }), - })(async ({ context }) => { - // Populate the database before running the tests - // Note: this seeding has to be in an order defined by the array returned by `mod.initItems()` - for (const data of mod.initItems(matrixValue)) { - await context.lists[listKey].createOne({ - data: { field: data[fieldName] }, - }); - } - await Promise.all( - storedValues.map(async (val: any) => { - const promise = context.lists[listKey].findOne({ - where: { field: val[fieldName] }, - query: 'field', + })(async ({ context }) => { + // Populate the database before running the tests + // Note: this seeding has to be in an order defined by the array returned by `mod.initItems()` + for (const data of mod.initItems(matrixValue)) { + await context.lists[listKey].createOne({ + data: { field: data[fieldName] }, }); - if (val[fieldName] === null) { - expect(await promise.catch(x => x.toString())).toMatch( - 'The unique value provided in a unique where input must not be null' - ); - } else { - expect(await promise).toEqual({ field: val[fieldName] }); - } - }) - ); - }) - ); - } + } + await Promise.all( + storedValues.map(async (val: any) => { + const promise = context.lists[listKey].findOne({ + where: { field: val[fieldName] }, + query: 'field', + }); + if (val[fieldName] === null) { + expect(await promise.catch(x => x.toString())).toMatch( + 'The unique value provided in a unique where input must not be null' + ); + } else { + expect(await promise).toEqual({ field: val[fieldName] }); + } + }) + ); + }) + ); + } + }); }); } }); diff --git a/tests/api-tests/fields/types/Virtual.test.ts b/tests/api-tests/fields/types/Virtual.test.ts index 93e0093274d..1c06f1b9de6 100644 --- a/tests/api-tests/fields/types/Virtual.test.ts +++ b/tests/api-tests/fields/types/Virtual.test.ts @@ -118,10 +118,14 @@ describe('Virtual field type', () => { async resolve(rootVal, args, context) { const [personAuthors, organisationAuthors] = await Promise.all([ context.db.lists.Person.findMany({ - where: { authoredPosts_some: { id: rootVal.id.toString() } }, + where: { + authoredPosts: { some: { id: { equals: rootVal.id.toString() } } }, + }, }), context.db.lists.Organisation.findMany({ - where: { authoredPosts_some: { id: rootVal.id.toString() } }, + where: { + authoredPosts: { some: { id: { equals: rootVal.id.toString() } } }, + }, }), ]); if (personAuthors.length) { diff --git a/tests/api-tests/fields/types/document.test.ts b/tests/api-tests/fields/types/document.test.ts index c3df3699ba4..8609c0ca211 100644 --- a/tests/api-tests/fields/types/document.test.ts +++ b/tests/api-tests/fields/types/document.test.ts @@ -46,7 +46,7 @@ const runner = setupTestRunner({ }, }), }, - access: { read: { name_not: 'Charlie' } }, + access: { read: { name: { not: { equals: 'Charlie' } } } }, }), }), }), @@ -284,7 +284,7 @@ describe('Document field type', () => { }); // FIXME: The path doesn't match the null field here! expect(body.data).toEqual({ author: { badBio: null } }); - expectInternalServerError(body.errors, [ + expectInternalServerError(body.errors, true, [ { path: ['author', 'badBio', 'document'], message: 'Cannot query field "bad" on type "Author". Did you mean "bio" or "id"?', diff --git a/tests/api-tests/fields/unique.test.ts b/tests/api-tests/fields/unique.test.ts index 8b656ecf57a..b2bf558bb4c 100644 --- a/tests/api-tests/fields/unique.test.ts +++ b/tests/api-tests/fields/unique.test.ts @@ -76,6 +76,8 @@ testModules message: expect.stringMatching( /\nInvalid `prisma\.test\.create\(\)` invocation:\n(.*\n){2} Unique constraint failed on the fields: \(`testField`\)/ ), + code: 'P2002', + target: ['testField'], }, ]); }) @@ -104,6 +106,8 @@ testModules message: expect.stringMatching( /\nInvalid `prisma\.test\.create\(\)` invocation:\n(.*\n){2} Unique constraint failed on the fields: \(`testField`\)/ ), + code: 'P2002', + target: ['testField'], }, ]); }) diff --git a/tests/api-tests/hooks/hook-errors.test.ts b/tests/api-tests/hooks/hook-errors.test.ts index fd9938f5f64..bd2dad79fab 100644 --- a/tests/api-tests/hooks/hook-errors.test.ts +++ b/tests/api-tests/hooks/hook-errors.test.ts @@ -1,407 +1,574 @@ import { text } from '@keystone-next/fields'; import { createSchema, list } from '@keystone-next/keystone/schema'; -import { setupTestRunner } from '@keystone-next/testing'; +import { GraphQLRequest, setupTestRunner } from '@keystone-next/testing'; +import { KeystoneContext } from '../../../packages/types/src'; import { apiTestConfig, expectAccessDenied, expectExtensionError } from '../utils'; -const runner = setupTestRunner({ - config: apiTestConfig({ - lists: createSchema({ - User: list({ - fields: { name: text() }, - hooks: { - beforeChange: ({ resolvedData }) => { - if (resolvedData.name === 'trigger before') { - throw new Error('Simulated error: beforeChange'); - } - }, - afterChange: ({ resolvedData }) => { - if (resolvedData.name === 'trigger after') { - throw new Error('Simulated error: afterChange'); - } - }, - beforeDelete: ({ existingItem }) => { - if (existingItem.name === 'trigger before delete') { - throw new Error('Simulated error: beforeDelete'); - } - }, - afterDelete: ({ existingItem }) => { - if (existingItem.name === 'trigger after delete') { - throw new Error('Simulated error: afterDelete'); - } - }, - }, - }), - Post: list({ - fields: { - title: text({ - hooks: { - beforeChange: ({ resolvedData }) => { - if (resolvedData.title === 'trigger before') { - throw new Error('Simulated error: title: beforeChange'); - } - }, - afterChange: ({ resolvedData }) => { - if (resolvedData.title === 'trigger after') { - throw new Error('Simulated error: title: afterChange'); - } - }, - beforeDelete: ({ existingItem }) => { - if (existingItem.title === 'trigger before delete') { - throw new Error('Simulated error: title: beforeDelete'); - } - }, - afterDelete: ({ existingItem }) => { - if (existingItem.title === 'trigger after delete') { - throw new Error('Simulated error: title: afterDelete'); - } - }, +const runner = (debug: boolean | undefined) => + setupTestRunner({ + config: apiTestConfig({ + lists: createSchema({ + User: list({ + fields: { name: text() }, + hooks: { + beforeChange: ({ resolvedData }) => { + if (resolvedData.name === 'trigger before') { + throw new Error('Simulated error: beforeChange'); + } }, - }), - content: text({ - hooks: { - beforeChange: ({ resolvedData }) => { - if (resolvedData.content === 'trigger before') { - throw new Error('Simulated error: content: beforeChange'); - } - }, - afterChange: ({ resolvedData }) => { - if (resolvedData.content === 'trigger after') { - throw new Error('Simulated error: content: afterChange'); - } - }, - beforeDelete: ({ existingItem }) => { - if (existingItem.content === 'trigger before delete') { - throw new Error('Simulated error: content: beforeDelete'); - } + afterChange: ({ resolvedData }) => { + if (resolvedData.name === 'trigger after') { + throw new Error('Simulated error: afterChange'); + } + }, + beforeDelete: ({ existingItem }) => { + if (existingItem.name === 'trigger before delete') { + throw new Error('Simulated error: beforeDelete'); + } + }, + afterDelete: ({ existingItem }) => { + if (existingItem.name === 'trigger after delete') { + throw new Error('Simulated error: afterDelete'); + } + }, + }, + }), + Post: list({ + fields: { + title: text({ + hooks: { + beforeChange: ({ resolvedData }) => { + if (resolvedData.title === 'trigger before') { + throw new Error('Simulated error: title: beforeChange'); + } + }, + afterChange: ({ resolvedData }) => { + if (resolvedData.title === 'trigger after') { + throw new Error('Simulated error: title: afterChange'); + } + }, + beforeDelete: ({ existingItem }) => { + if (existingItem.title === 'trigger before delete') { + throw new Error('Simulated error: title: beforeDelete'); + } + }, + afterDelete: ({ existingItem }) => { + if (existingItem.title === 'trigger after delete') { + throw new Error('Simulated error: title: afterDelete'); + } + }, }, - afterDelete: ({ existingItem }) => { - if (existingItem.content === 'trigger after delete') { - throw new Error('Simulated error: content: afterDelete'); - } + }), + content: text({ + hooks: { + beforeChange: ({ resolvedData }) => { + if (resolvedData.content === 'trigger before') { + throw new Error('Simulated error: content: beforeChange'); + } + }, + afterChange: ({ resolvedData }) => { + if (resolvedData.content === 'trigger after') { + throw new Error('Simulated error: content: afterChange'); + } + }, + beforeDelete: ({ existingItem }) => { + if (existingItem.content === 'trigger before delete') { + throw new Error('Simulated error: content: beforeDelete'); + } + }, + afterDelete: ({ existingItem }) => { + if (existingItem.content === 'trigger after delete') { + throw new Error('Simulated error: content: afterDelete'); + } + }, }, - }, - }), - }, + }), + }, + }), }), + graphql: { debug }, }), - }), -}); + }); -['before', 'after'].map(phase => { - describe(`List Hooks: ${phase}Change/${phase}Delete()`, () => { - test( - 'createOne', - runner(async ({ context }) => { - // Valid name should pass - await context.lists.User.createOne({ data: { name: 'good' } }); +[true, false].map(useHttp => { + const runQuery = async ( + context: KeystoneContext, + graphQLRequest: GraphQLRequest, + query: { query: string; variables?: Record } + ) => { + if (useHttp) { + const { body } = await graphQLRequest(query); + return body; + } else { + return await context.graphql.raw(query); + } + }; - // Trigger an error - const { data, errors } = await context.graphql.raw({ - query: `mutation ($data: UserCreateInput!) { createUser(data: $data) { id } }`, - variables: { data: { name: `trigger ${phase}` } }, + [true, false, undefined].map(debug => { + (['dev', 'production'] as const).map(mode => + describe(`NODE_ENV=${mode}, debug=${debug} useHttp=${useHttp}`, () => { + beforeAll(() => { + // @ts-ignore + process.env.NODE_ENV = mode; + }); + afterAll(() => { + // @ts-ignore + process.env.NODE_ENV = 'test'; }); - // Returns null and throws an error - expect(data).toEqual({ createUser: null }); - expectExtensionError(errors, `${phase}Change`, [ - { path: ['createUser'], messages: [`User: Simulated error: ${phase}Change`] }, - ]); + ['before', 'after'].map(phase => { + describe(`List Hooks: ${phase}Change/${phase}Delete()`, () => { + test( + 'createOne', + runner(debug)(async ({ context, graphQLRequest }) => { + // Valid name should pass + await context.lists.User.createOne({ data: { name: 'good' } }); - // Only the original user should exist for 'before', both exist for 'after' - const _users = await context.lists.User.findMany({ query: 'id name' }); - expect(_users.map(({ name }) => name)).toEqual( - phase === 'before' ? ['good'] : ['good', 'trigger after'] - ); - }) - ); + // Trigger an error + const { data, errors } = await runQuery(context, graphQLRequest, { + query: `mutation ($data: UserCreateInput!) { createUser(data: $data) { id } }`, + variables: { data: { name: `trigger ${phase}` } }, + }); - test( - 'updateOne', - runner(async ({ context }) => { - // Valid name should pass - const user = await context.lists.User.createOne({ data: { name: 'good' } }); - await context.lists.User.updateOne({ where: { id: user.id }, data: { name: 'better' } }); + // Returns null and throws an error + expect(data).toEqual({ createUser: null }); + const message = `Simulated error: ${phase}Change`; + expectExtensionError(mode, useHttp, debug, errors, `${phase}Change`, [ + { + path: ['createUser'], + messages: [`User: Simulated error: ${phase}Change`], + debug: [ + { + message, + stacktrace: expect.stringMatching( + new RegExp(`Error: ${message}\n[^\n]*${phase}Change .${__filename}`) + ), + }, + ], + }, + ]); - // Invalid name - const { data, errors } = await context.graphql.raw({ - query: `mutation ($id: ID! $data: UserUpdateInput!) { updateUser(where: { id: $id }, data: $data) { id } }`, - variables: { id: user.id, data: { name: `trigger ${phase}` } }, - }); + // Only the original user should exist for 'before', both exist for 'after' + const _users = await context.lists.User.findMany({ query: 'id name' }); + expect(_users.map(({ name }) => name)).toEqual( + phase === 'before' ? ['good'] : ['good', 'trigger after'] + ); + }) + ); - // Returns null and throws an error - expect(data).toEqual({ updateUser: null }); - expectExtensionError(errors, `${phase}Change`, [ - { path: ['updateUser'], messages: [`User: Simulated error: ${phase}Change`] }, - ]); + test( + 'updateOne', + runner(debug)(async ({ context, graphQLRequest }) => { + // Valid name should pass + const user = await context.lists.User.createOne({ data: { name: 'good' } }); + await context.lists.User.updateOne({ + where: { id: user.id }, + data: { name: 'better' }, + }); - // User should have its original name for 'before', and the new name for 'after'. - const _users = await context.lists.User.findMany({ query: 'id name' }); - expect(_users.map(({ name }) => name)).toEqual( - phase === 'before' ? ['better'] : ['trigger after'] - ); - }) - ); + // Invalid name + const { data, errors } = await runQuery(context, graphQLRequest, { + query: `mutation ($id: ID! $data: UserUpdateInput!) { updateUser(where: { id: $id }, data: $data) { id } }`, + variables: { id: user.id, data: { name: `trigger ${phase}` } }, + }); - test( - 'deleteOne', - runner(async ({ context }) => { - // Valid names should pass - const user1 = await context.lists.User.createOne({ data: { name: 'good' } }); - const user2 = await context.lists.User.createOne({ - data: { name: `trigger ${phase} delete` }, - }); - await context.lists.User.deleteOne({ where: { id: user1.id } }); + // Returns null and throws an error + expect(data).toEqual({ updateUser: null }); + const message = `Simulated error: ${phase}Change`; + expectExtensionError(mode, useHttp, debug, errors, `${phase}Change`, [ + { + path: ['updateUser'], + messages: [`User: ${message}`], + debug: [ + { + message, + stacktrace: expect.stringMatching( + new RegExp(`Error: ${message}\n[^\n]*${phase}Change .${__filename}`) + ), + }, + ], + }, + ]); - // Invalid name - const { data, errors } = await context.graphql.raw({ - query: `mutation ($id: ID!) { deleteUser(where: { id: $id }) { id } }`, - variables: { id: user2.id }, - }); + // User should have its original name for 'before', and the new name for 'after'. + const _users = await context.lists.User.findMany({ query: 'id name' }); + expect(_users.map(({ name }) => name)).toEqual( + phase === 'before' ? ['better'] : ['trigger after'] + ); + }) + ); - // Returns null and throws an error - expect(data).toEqual({ deleteUser: null }); - expectExtensionError(errors, `${phase}Delete`, [ - { path: ['deleteUser'], messages: [`User: Simulated error: ${phase}Delete`] }, - ]); + test( + 'deleteOne', + runner(debug)(async ({ context, graphQLRequest }) => { + // Valid names should pass + const user1 = await context.lists.User.createOne({ data: { name: 'good' } }); + const user2 = await context.lists.User.createOne({ + data: { name: `trigger ${phase} delete` }, + }); + await context.lists.User.deleteOne({ where: { id: user1.id } }); - // Bad users should still be in the database for 'before', deleted for 'after'. - const _users = await context.lists.User.findMany({ query: 'id name' }); - expect(_users.map(({ name }) => name)).toEqual( - phase === 'before' ? ['trigger before delete'] : [] - ); - }) - ); + // Invalid name + const { data, errors } = await runQuery(context, graphQLRequest, { + query: `mutation ($id: ID!) { deleteUser(where: { id: $id }) { id } }`, + variables: { id: user2.id }, + }); - test( - 'createMany', - runner(async ({ context }) => { - // Mix of good and bad names - const { data, errors } = await context.graphql.raw({ - query: `mutation ($data: [UserCreateInput!]!) { createUsers(data: $data) { id name } }`, - variables: { - data: [ - { name: 'good 1' }, - { name: `trigger ${phase}` }, - { name: 'good 2' }, - { name: `trigger ${phase}` }, - { name: 'good 3' }, - ], - }, - }); + // Returns null and throws an error + expect(data).toEqual({ deleteUser: null }); + const message = `Simulated error: ${phase}Delete`; + expectExtensionError(mode, useHttp, debug, errors, `${phase}Delete`, [ + { + path: ['deleteUser'], + messages: [`User: ${message}`], + debug: [ + { + message, + stacktrace: expect.stringMatching( + new RegExp(`Error: ${message}\n[^\n]*${phase}Delete .${__filename}`) + ), + }, + ], + }, + ]); - // Valid users are returned, invalid come back as null - expect(data).toEqual({ - createUsers: [ - { id: expect.any(String), name: 'good 1' }, - null, - { id: expect.any(String), name: 'good 2' }, - null, - { id: expect.any(String), name: 'good 3' }, - ], - }); - // The invalid creates should have errors which point to the nulls in their path - expectExtensionError(errors, `${phase}Change`, [ - { path: ['createUsers', 1], messages: [`User: Simulated error: ${phase}Change`] }, - { path: ['createUsers', 3], messages: [`User: Simulated error: ${phase}Change`] }, - ]); + // Bad users should still be in the database for 'before', deleted for 'after'. + const _users = await context.lists.User.findMany({ query: 'id name' }); + expect(_users.map(({ name }) => name)).toEqual( + phase === 'before' ? ['trigger before delete'] : [] + ); + }) + ); - // Three users should exist in the database for 'before,' five for 'after'. - const users = await context.lists.User.findMany({ - orderBy: { name: 'asc' }, - query: 'id name', - }); - expect(users.map(({ name }) => name)).toEqual( - phase === 'before' - ? ['good 1', 'good 2', 'good 3'] - : ['good 1', 'good 2', 'good 3', 'trigger after', 'trigger after'] - ); - }) - ); + test( + 'createMany', + runner(debug)(async ({ context, graphQLRequest }) => { + // Mix of good and bad names + const { data, errors } = await runQuery(context, graphQLRequest, { + query: `mutation ($data: [UserCreateInput!]!) { createUsers(data: $data) { id name } }`, + variables: { + data: [ + { name: 'good 1' }, + { name: `trigger ${phase}` }, + { name: 'good 2' }, + { name: `trigger ${phase}` }, + { name: 'good 3' }, + ], + }, + }); - test( - 'updateMany', - runner(async ({ context }) => { - // Start with some users - const users = await context.lists.User.createMany({ - data: [ - { name: 'good 1' }, - { name: 'good 2' }, - { name: 'good 3' }, - { name: 'good 4' }, - { name: 'good 5' }, - ], - query: 'id name', - }); + // Valid users are returned, invalid come back as null + expect(data).toEqual({ + createUsers: [ + { id: expect.any(String), name: 'good 1' }, + null, + { id: expect.any(String), name: 'good 2' }, + null, + { id: expect.any(String), name: 'good 3' }, + ], + }); + // The invalid creates should have errors which point to the nulls in their path + const message = `Simulated error: ${phase}Change`; + expectExtensionError(mode, useHttp, debug, errors, `${phase}Change`, [ + { + path: ['createUsers', 1], + messages: [`User: ${message}`], + debug: [ + { + message, + stacktrace: expect.stringMatching( + new RegExp(`Error: ${message}\n[^\n]*${phase}Change .${__filename}`) + ), + }, + ], + }, + { + path: ['createUsers', 3], + messages: [`User: ${message}`], + debug: [ + { + message, + stacktrace: expect.stringMatching( + new RegExp(`Error: ${message}\n[^\n]*${phase}Change .${__filename}`) + ), + }, + ], + }, + ]); - // Mix of good and bad names - const { data, errors } = await context.graphql.raw({ - query: `mutation ($data: [UserUpdateArgs!]!) { updateUsers(data: $data) { id name } }`, - variables: { - data: [ - { where: { id: users[0].id }, data: { name: 'still good 1' } }, - { where: { id: users[1].id }, data: { name: `trigger ${phase}` } }, - { where: { id: users[2].id }, data: { name: 'still good 3' } }, - { where: { id: users[3].id }, data: { name: `trigger ${phase}` } }, - ], - }, - }); + // Three users should exist in the database for 'before,' five for 'after'. + const users = await context.lists.User.findMany({ + orderBy: { name: 'asc' }, + query: 'id name', + }); + expect(users.map(({ name }) => name)).toEqual( + phase === 'before' + ? ['good 1', 'good 2', 'good 3'] + : ['good 1', 'good 2', 'good 3', 'trigger after', 'trigger after'] + ); + }) + ); - // Valid users are returned, invalid come back as null - expect(data).toEqual({ - updateUsers: [ - { id: users[0].id, name: 'still good 1' }, - null, - { id: users[2].id, name: 'still good 3' }, - null, - ], - }); - // The invalid updates should have errors which point to the nulls in their path - expectExtensionError(errors, `${phase}Change`, [ - { path: ['updateUsers', 1], messages: [`User: Simulated error: ${phase}Change`] }, - { path: ['updateUsers', 3], messages: [`User: Simulated error: ${phase}Change`] }, - ]); + test( + 'updateMany', + runner(debug)(async ({ context, graphQLRequest }) => { + // Start with some users + const users = await context.lists.User.createMany({ + data: [ + { name: 'good 1' }, + { name: 'good 2' }, + { name: 'good 3' }, + { name: 'good 4' }, + { name: 'good 5' }, + ], + query: 'id name', + }); - // All users should still exist in the database, un-changed for `before`, changed for `after`. - const _users = await context.lists.User.findMany({ - orderBy: { name: 'asc' }, - query: 'id name', - }); - expect(_users.map(({ name }) => name)).toEqual( - phase === 'before' - ? ['good 2', 'good 4', 'good 5', 'still good 1', 'still good 3'] - : ['good 5', 'still good 1', 'still good 3', 'trigger after', 'trigger after'] - ); - }) - ); + // Mix of good and bad names + const { data, errors } = await runQuery(context, graphQLRequest, { + query: `mutation ($data: [UserUpdateArgs!]!) { updateUsers(data: $data) { id name } }`, + variables: { + data: [ + { where: { id: users[0].id }, data: { name: 'still good 1' } }, + { where: { id: users[1].id }, data: { name: `trigger ${phase}` } }, + { where: { id: users[2].id }, data: { name: 'still good 3' } }, + { where: { id: users[3].id }, data: { name: `trigger ${phase}` } }, + ], + }, + }); - test( - 'deleteMany', - runner(async ({ context }) => { - // Start with some users - const users = await context.lists.User.createMany({ - data: [ - { name: 'good 1' }, - { name: `trigger ${phase} delete` }, - { name: 'good 3' }, - { name: `trigger ${phase} delete` }, - { name: 'good 5' }, - ], - query: 'id name', - }); + // Valid users are returned, invalid come back as null + expect(data).toEqual({ + updateUsers: [ + { id: users[0].id, name: 'still good 1' }, + null, + { id: users[2].id, name: 'still good 3' }, + null, + ], + }); + // The invalid updates should have errors which point to the nulls in their path + const message = `Simulated error: ${phase}Change`; + expectExtensionError(mode, useHttp, debug, errors, `${phase}Change`, [ + { + path: ['updateUsers', 1], + messages: [`User: ${message}`], + debug: [ + { + message, + stacktrace: expect.stringMatching( + new RegExp(`Error: ${message}\n[^\n]*${phase}Change .${__filename}`) + ), + }, + ], + }, + { + path: ['updateUsers', 3], + messages: [`User: ${message}`], + debug: [ + { + message, + stacktrace: expect.stringMatching( + new RegExp(`Error: ${message}\n[^\n]*${phase}Change .${__filename}`) + ), + }, + ], + }, + ]); - // Mix of good and bad names - const { data, errors } = await context.graphql.raw({ - query: `mutation ($where: [UserWhereUniqueInput!]!) { deleteUsers(where: $where) { id name } }`, - variables: { - where: [users[0].id, users[1].id, users[2].id, users[3].id].map(id => ({ id })), - }, - }); + // All users should still exist in the database, un-changed for `before`, changed for `after`. + const _users = await context.lists.User.findMany({ + orderBy: { name: 'asc' }, + query: 'id name', + }); + expect(_users.map(({ name }) => name)).toEqual( + phase === 'before' + ? ['good 2', 'good 4', 'good 5', 'still good 1', 'still good 3'] + : ['good 5', 'still good 1', 'still good 3', 'trigger after', 'trigger after'] + ); + }) + ); - // Valid users are returned, invalid come back as null - expect(data).toEqual({ - deleteUsers: [ - { id: users[0].id, name: 'good 1' }, - null, - { id: users[2].id, name: 'good 3' }, - null, - ], - }); - // The invalid deletes should have errors which point to the nulls in their path - expectExtensionError(errors, `${phase}Delete`, [ - { path: ['deleteUsers', 1], messages: [`User: Simulated error: ${phase}Delete`] }, - { path: ['deleteUsers', 3], messages: [`User: Simulated error: ${phase}Delete`] }, - ]); + test( + 'deleteMany', + runner(debug)(async ({ context, graphQLRequest }) => { + // Start with some users + const users = await context.lists.User.createMany({ + data: [ + { name: 'good 1' }, + { name: `trigger ${phase} delete` }, + { name: 'good 3' }, + { name: `trigger ${phase} delete` }, + { name: 'good 5' }, + ], + query: 'id name', + }); - // Three users should still exist in the database for `before`, only 1 for `after`. - const _users = await context.lists.User.findMany({ - orderBy: { name: 'asc' }, - query: 'id name', - }); - expect(_users.map(({ name }) => name)).toEqual( - phase === 'before' - ? ['good 5', 'trigger before delete', 'trigger before delete'] - : ['good 5'] - ); - }) - ); - }); -}); + // Mix of good and bad names + const { data, errors } = await runQuery(context, graphQLRequest, { + query: `mutation ($where: [UserWhereUniqueInput!]!) { deleteUsers(where: $where) { id name } }`, + variables: { + where: [users[0].id, users[1].id, users[2].id, users[3].id].map(id => ({ id })), + }, + }); -['before', 'after'].map(phase => { - describe(`Field Hooks: ${phase}Change/${phase}Delete()`, () => { - test( - 'update', - runner(async ({ context }) => { - const post = await context.lists.Post.createOne({ - data: { title: 'original title', content: 'original content' }, - }); + // Valid users are returned, invalid come back as null + expect(data).toEqual({ + deleteUsers: [ + { id: users[0].id, name: 'good 1' }, + null, + { id: users[2].id, name: 'good 3' }, + null, + ], + }); + // The invalid deletes should have errors which point to the nulls in their path + const message = `Simulated error: ${phase}Delete`; + expectExtensionError(mode, useHttp, debug, errors, `${phase}Delete`, [ + { + path: ['deleteUsers', 1], + messages: [`User: ${message}`], + debug: [ + { + message, + stacktrace: expect.stringMatching( + new RegExp(`Error: ${message}\n[^\n]*${phase}Delete .${__filename}`) + ), + }, + ], + }, + { + path: ['deleteUsers', 3], + messages: [`User: ${message}`], + debug: [ + { + message, + stacktrace: expect.stringMatching( + new RegExp(`Error: ${message}\n[^\n]*${phase}Delete .${__filename}`) + ), + }, + ], + }, + ]); - const { data, errors } = await context.graphql.raw({ - query: `mutation ($id: ID! $data: PostUpdateInput!) { updatePost(where: { id: $id }, data: $data) { id } }`, - variables: { - id: post.id, - data: { title: `trigger ${phase}`, content: `trigger ${phase}` }, - }, + // Three users should still exist in the database for `before`, only 1 for `after`. + const _users = await context.lists.User.findMany({ + orderBy: { name: 'asc' }, + query: 'id name', + }); + expect(_users.map(({ name }) => name)).toEqual( + phase === 'before' + ? ['good 5', 'trigger before delete', 'trigger before delete'] + : ['good 5'] + ); + }) + ); + }); }); - expectExtensionError(errors, `${phase}Change`, [ - { - path: ['updatePost'], - messages: [ - `Post.title: Simulated error: title: ${phase}Change`, - `Post.content: Simulated error: content: ${phase}Change`, - ], - }, - ]); - expect(data).toEqual({ updatePost: null }); - // Post should have its original data for 'before', and the new data for 'after'. - const _post = await context.lists.Post.findOne({ - where: { id: post.id }, - query: 'title content', - }); - expect(_post).toEqual( - phase === 'before' - ? { title: 'original title', content: 'original content' } - : { title: 'trigger after', content: 'trigger after' } - ); - }) - ); + ['before', 'after'].map(phase => { + describe(`Field Hooks: ${phase}Change/${phase}Delete()`, () => { + test( + 'update', + runner(debug)(async ({ context, graphQLRequest }) => { + const post = await context.lists.Post.createOne({ + data: { title: 'original title', content: 'original content' }, + }); - test( - 'delete', - runner(async ({ context }) => { - const post = await context.lists.Post.createOne({ - data: { title: `trigger ${phase} delete`, content: `trigger ${phase} delete` }, - }); - const { data, errors } = await context.graphql.raw({ - query: `mutation ($id: ID!) { deletePost(where: { id: $id }) { id } }`, - variables: { id: post.id }, - }); - expectExtensionError(errors, `${phase}Delete`, [ - { - path: ['deletePost'], - messages: [ - `Post.title: Simulated error: title: ${phase}Delete`, - `Post.content: Simulated error: content: ${phase}Delete`, - ], - }, - ]); - expect(data).toEqual({ deletePost: null }); + const { data, errors } = await runQuery(context, graphQLRequest, { + query: `mutation ($id: ID! $data: PostUpdateInput!) { updatePost(where: { id: $id }, data: $data) { id } }`, + variables: { + id: post.id, + data: { title: `trigger ${phase}`, content: `trigger ${phase}` }, + }, + }); + const message1 = `Simulated error: title: ${phase}Change`; + const message2 = `Simulated error: content: ${phase}Change`; + expectExtensionError(mode, useHttp, debug, errors, `${phase}Change`, [ + { + path: ['updatePost'], + messages: [`Post.title: ${message1}`, `Post.content: ${message2}`], + debug: [ + { + message: message1, + stacktrace: expect.stringMatching( + new RegExp(`Error: ${message1}\n[^\n]*${phase}Change .${__filename}`) + ), + }, + { + message: message2, + stacktrace: expect.stringMatching( + new RegExp(`Error: ${message2}\n[^\n]*${phase}Change .${__filename}`) + ), + }, + ], + }, + ]); + expect(data).toEqual({ updatePost: null }); - // Post should have its original data for 'before', and not exist for 'after'. - const result = await context.graphql.raw({ - query: `query ($id: ID!) { post(where: { id: $id }) { title content} }`, - variables: { id: post.id }, - }); - if (phase === 'before') { - expect(result.errors).toBe(undefined); - expect(result.data).toEqual({ - post: { title: 'trigger before delete', content: 'trigger before delete' }, + // Post should have its original data for 'before', and the new data for 'after'. + const _post = await context.lists.Post.findOne({ + where: { id: post.id }, + query: 'title content', + }); + expect(_post).toEqual( + phase === 'before' + ? { title: 'original title', content: 'original content' } + : { title: 'trigger after', content: 'trigger after' } + ); + }) + ); + + test( + `delete`, + runner(debug)(async ({ context, graphQLRequest }) => { + const post = await context.lists.Post.createOne({ + data: { title: `trigger ${phase} delete`, content: `trigger ${phase} delete` }, + }); + const { data, errors } = await runQuery(context, graphQLRequest, { + query: `mutation ($id: ID!) { deletePost(where: { id: $id }) { id } }`, + variables: { id: post.id }, + }); + const message1 = `Simulated error: title: ${phase}Delete`; + const message2 = `Simulated error: content: ${phase}Delete`; + expectExtensionError(mode, useHttp, debug, errors, `${phase}Delete`, [ + { + path: ['deletePost'], + messages: [`Post.title: ${message1}`, `Post.content: ${message2}`], + debug: [ + { + message: message1, + stacktrace: expect.stringMatching( + new RegExp(`Error: ${message1}\n[^\n]*${phase}Delete .${__filename}`) + ), + }, + { + message: message2, + stacktrace: expect.stringMatching( + new RegExp(`Error: ${message2}\n[^\n]*${phase}Delete .${__filename}`) + ), + }, + ], + }, + ]); + expect(data).toEqual({ deletePost: null }); + + // Post should have its original data for 'before', and not exist for 'after'. + const result = await runQuery(context, graphQLRequest, { + query: `query ($id: ID!) { post(where: { id: $id }) { title content} }`, + variables: { id: post.id }, + }); + if (phase === 'before') { + expect(result.errors).toBe(undefined); + expect(result.data).toEqual({ + post: { title: 'trigger before delete', content: 'trigger before delete' }, + }); + } else { + expectAccessDenied(mode, useHttp, debug, result.errors, [{ path: ['post'] }]); + expect(result.data).toEqual({ post: null }); + } + }) + ); }); - } else { - expectAccessDenied(result.errors, [{ path: ['post'] }]); - expect(result.data).toEqual({ post: null }); - } + }); }) ); }); diff --git a/tests/api-tests/hooks/list-hooks.test.ts b/tests/api-tests/hooks/list-hooks.test.ts index e862804b491..72ab482736c 100644 --- a/tests/api-tests/hooks/list-hooks.test.ts +++ b/tests/api-tests/hooks/list-hooks.test.ts @@ -1,7 +1,7 @@ import { text } from '@keystone-next/fields'; import { createSchema, list } from '@keystone-next/keystone/schema'; import { setupTestRunner } from '@keystone-next/testing'; -import { apiTestConfig } from '../utils'; +import { apiTestConfig, expectExtensionError } from '../utils'; const runner = setupTestRunner({ config: apiTestConfig({ @@ -11,6 +11,10 @@ const runner = setupTestRunner({ name: text({ hooks: { resolveInput: ({ resolvedData }) => { + if (resolvedData.name === 'trigger field error') { + throw new Error('Field error triggered'); + } + return `${resolvedData.name}-field`; }, }, @@ -18,6 +22,9 @@ const runner = setupTestRunner({ }, hooks: { resolveInput: ({ resolvedData }) => { + if (resolvedData.name === 'trigger list error-field') { + throw new Error('List error triggered'); + } return { name: `${resolvedData.name}-list`, }; @@ -29,18 +36,70 @@ const runner = setupTestRunner({ }); describe('List Hooks: #resolveInput()', () => { - it( + test( 'resolves fields first, then passes them to the list', runner(async ({ context }) => { - const user = await context.lists.User.createOne({ - data: { name: 'jess' }, - query: 'name', - }); - + const user = await context.lists.User.createOne({ data: { name: 'jess' }, query: 'name' }); // Field should be executed first, appending `-field`, then the list // should be executed which appends `-list`, and finally that total // result should be stored. expect(user.name).toBe('jess-field-list'); }) ); + + test( + 'List error', + runner(async ({ context }) => { + // Trigger an error + const { data, errors } = await context.graphql.raw({ + query: `mutation ($data: UserCreateInput!) { createUser(data: $data) { id } }`, + variables: { data: { name: `trigger list error` } }, + }); + // Returns null and throws an error + expect(data).toEqual({ createUser: null }); + const message = `List error triggered`; + expectExtensionError('dev', false, undefined, errors, `resolveInput`, [ + { + path: ['createUser'], + messages: [`User: ${message}`], + debug: [ + { + message, + stacktrace: expect.stringMatching( + new RegExp(`Error: ${message}\n[^\n]*resolveInput .${__filename}`) + ), + }, + ], + }, + ]); + }) + ); + + test( + 'Field error', + runner(async ({ context }) => { + // Trigger an error + const { data, errors } = await context.graphql.raw({ + query: `mutation ($data: UserCreateInput!) { createUser(data: $data) { id } }`, + variables: { data: { name: `trigger field error` } }, + }); + // Returns null and throws an error + expect(data).toEqual({ createUser: null }); + const message = `Field error triggered`; + expectExtensionError('dev', false, undefined, errors, `resolveInput`, [ + { + path: ['createUser'], + messages: [`User.name: ${message}`], + debug: [ + { + message, + stacktrace: expect.stringMatching( + new RegExp(`Error: ${message}\n[^\n]*resolveInput .${__filename}`) + ), + }, + ], + }, + ]); + }) + ); }); diff --git a/tests/api-tests/id-field.test.ts b/tests/api-tests/id-field.test.ts index bc5dc63b5ca..095be4f6000 100644 --- a/tests/api-tests/id-field.test.ts +++ b/tests/api-tests/id-field.test.ts @@ -35,7 +35,7 @@ describe.each(['autoincrement', 'cuid', 'uuid'] as const)('%s', kind => { 'Filtering an item with an invalid id throws an error', runner(async ({ graphQLRequest }) => { const { body } = await graphQLRequest({ - query: `{ users(where: { id: "adskjnfasdfkjekfj"}) { id } }`, + query: `{ users(where: { id: { equals: "adskjnfasdfkjekfj" } }) { id } }`, }); expect(body.data).toEqual({ users: null }); const s = kind === 'autoincrement' ? 'an integer' : `a ${kind}`; diff --git a/tests/api-tests/package.json b/tests/api-tests/package.json index f8d1aa978d6..d14c3f9ac32 100644 --- a/tests/api-tests/package.json +++ b/tests/api-tests/package.json @@ -2,7 +2,7 @@ "name": "@keystone-next/api-tests-legacy", "description": "A set of tests for running against the KeystoneJS API.", "private": true, - "version": "11.0.6", + "version": "11.1.0", "author": "The KeystoneJS Development Team", "license": "MIT", "engines": { @@ -22,14 +22,14 @@ "graphql": "^15.5.1", "memoize-one": "^5.2.1", "superagent": "^6.1.0", - "supertest": "^6.1.4", + "supertest": "^6.1.5", "testcheck": "^1.0.0-rc.2", "uuid": "^8.3.2" }, "dependencies": { - "@keystone-next/testing": "^1.1.0", - "@keystone-next/types": "^23.0.0", - "@keystone-next/utils": "^1.0.3", + "@keystone-next/testing": "^1.1.1", + "@keystone-next/types": "^24.0.0", + "@keystone-next/utils": "^1.0.4", "apollo-cache-control": "^0.14.0", "express": "^4.17.1" } diff --git a/tests/api-tests/queries/cache-hints.test.ts b/tests/api-tests/queries/cache-hints.test.ts index acb37a5030d..f2146dcfcfc 100644 --- a/tests/api-tests/queries/cache-hints.test.ts +++ b/tests/api-tests/queries/cache-hints.test.ts @@ -177,7 +177,7 @@ describe('cache hints', () => { const { body, headers } = await graphQLRequest({ query: ` query { - users(where: { name: "nope" }) { + users(where: { name: { equals: "nope" } }) { name } } @@ -270,7 +270,7 @@ describe('cache hints', () => { query: ` query { posts { - author(where: { name: "nope" }) { + author(where: { name: { equals: "nope" } }) { name } } diff --git a/tests/api-tests/queries/filters.test.ts b/tests/api-tests/queries/filters.test.ts index 3b9f05c9a20..c3a731f665b 100644 --- a/tests/api-tests/queries/filters.test.ts +++ b/tests/api-tests/queries/filters.test.ts @@ -23,14 +23,16 @@ describe('filtering on field name', () => { test( 'filter works when there is no dash in field name', runner(async ({ context }) => { - const users = await context.lists.User.findMany({ where: { noDash: 'aValue' } }); + const users = await context.lists.User.findMany({ where: { noDash: { equals: 'aValue' } } }); expect(users).toEqual([]); }) ); test( 'filter works when there is one dash in field name', runner(async ({ context }) => { - const users = await context.lists.User.findMany({ where: { single_dash: 'aValue' } }); + const users = await context.lists.User.findMany({ + where: { single_dash: { equals: 'aValue' } }, + }); expect(users).toEqual([]); }) ); @@ -38,7 +40,7 @@ describe('filtering on field name', () => { 'filter works when there are multiple dashes in field name', runner(async ({ context }) => { const users = await context.lists.User.findMany({ - where: { many_many_many_dashes: 'aValue' }, + where: { many_many_many_dashes: { equals: 'aValue' } }, }); expect(users).toEqual([]); }) @@ -46,7 +48,9 @@ describe('filtering on field name', () => { test( 'filter works when there are multiple dashes in a row in a field name', runner(async ({ context }) => { - const users = await context.lists.User.findMany({ where: { multi____dash: 'aValue' } }); + const users = await context.lists.User.findMany({ + where: { multi____dash: { equals: 'aValue' } }, + }); expect(users).toEqual([]); }) ); @@ -54,7 +58,7 @@ describe('filtering on field name', () => { 'filter works when there is one dash in field name as part of a relationship', runner(async ({ context }) => { const secondaries = await context.lists.SecondaryList.findMany({ - where: { someUser_is_null: false }, + where: { NOT: { someUser: null } }, }); expect(secondaries).toEqual([]); }) diff --git a/tests/api-tests/queries/limits.test.ts b/tests/api-tests/queries/limits.test.ts index c4a9e343d46..dd0ee7e96b8 100644 --- a/tests/api-tests/queries/limits.test.ts +++ b/tests/api-tests/queries/limits.test.ts @@ -54,7 +54,7 @@ describe('maxResults Limit', () => { query: ` query { users( - where: { name_contains: "J" }, + where: { name: { contains: "J" } }, orderBy: { name: asc }, ) { name @@ -71,7 +71,7 @@ describe('maxResults Limit', () => { query: ` query { users( - where: { name: "Nope" } + where: { name: { equals: "Nope" } } ) { name } @@ -90,11 +90,11 @@ describe('maxResults Limit', () => { expect(data).toHaveProperty('usersCount'); expect(data.usersCount).toBe(users.length); - // This query is only okay because of the "first" parameter + // This query is only okay because of the "take" parameter data = await context.graphql.run({ query: ` query { - users(first: 1) { + users(take: 1) { name } } @@ -118,13 +118,13 @@ describe('maxResults Limit', () => { expectLimitsExceededError(errors, [{ path: ['users'] }]); - // The query results don't break the limits, but the "first" parameter does + // The query results don't break the limits, but the "take" parameter does ({ errors } = await context.graphql.raw({ query: ` query { users( - where: { name: "Nope" }, - first: 100000 + where: { name: { equals: "Nope" } }, + take: 100000 ) { name } @@ -165,7 +165,7 @@ describe('maxResults Limit', () => { context.totalResults = 0; // A basic query that should work let posts = await context.lists.Post.findMany({ - where: { title: 'One author' }, + where: { title: { equals: 'One author' } }, query: 'title author { name }', }); @@ -176,7 +176,7 @@ describe('maxResults Limit', () => { // Each subquery is within the limit (even though the total isn't) posts = await context.lists.Post.findMany({ where: { - OR: [{ title: 'One author' }, { title: 'Two authors' }], + OR: [{ title: { equals: 'One author' } }, { title: { equals: 'Two authors' } }], }, orderBy: { title: 'asc' }, query: 'title author(orderBy: { name: asc }) { name }', @@ -194,7 +194,7 @@ describe('maxResults Limit', () => { query: ` query { posts( - where: { title: "Three authors" }, + where: { title: { equals: "Three authors" } }, ) { title author { @@ -211,7 +211,7 @@ describe('maxResults Limit', () => { // Reset the count for each query context.totalResults = 0; posts = await context.lists.Post.findMany({ - where: { title: 'Three authors' }, + where: { title: { equals: 'Three authors' } }, query: 'title', }); @@ -241,7 +241,7 @@ describe('maxResults Limit', () => { ({ errors } = await context.graphql.raw({ query: ` query { - posts(where: { title: "Two authors" }) { + posts(where: { title: { equals: "Two authors" } }) { title author { posts { diff --git a/tests/api-tests/queries/relationships.test.ts b/tests/api-tests/queries/relationships.test.ts index c26f4370c85..a87d4960d3c 100644 --- a/tests/api-tests/queries/relationships.test.ts +++ b/tests/api-tests/queries/relationships.test.ts @@ -47,7 +47,7 @@ describe('Querying with relationship filters', () => { // Create an item that does the linking const allPosts = await context.lists.Post.findMany({ - where: { author: { name_contains: 'J' } }, + where: { author: { name: { contains: 'J' } } }, query: 'id title', }); expect(allPosts).toHaveLength(3); @@ -74,7 +74,7 @@ describe('Querying with relationship filters', () => { // Create an item that does the linking const _posts = await context.lists.Post.findMany({ - where: { author: { name_contains: 'J' } }, + where: { author: { name: { contains: 'J' } } }, query: 'id title author { id name }', }); expect(_posts).toMatchObject([{ id: posts[0].id, title: posts[0].title }]); @@ -110,7 +110,7 @@ describe('Querying with relationship filters', () => { }; test( - '_every condition', + 'every condition', runner(async ({ context }) => { const create = async (listKey: string, data: any) => context.lists[listKey].createOne({ data }); @@ -118,7 +118,7 @@ describe('Querying with relationship filters', () => { // EVERY const _users = await context.lists.User.findMany({ - where: { feed_every: { title_contains: 'J' } }, + where: { feed: { every: { title: { contains: 'J' } } } }, query: 'id name feed { id title }', }); @@ -127,7 +127,7 @@ describe('Querying with relationship filters', () => { ); test( - '_some condition', + 'some condition', runner(async ({ context }) => { const create = async (listKey: string, data: any) => context.lists[listKey].createOne({ data }); @@ -135,7 +135,7 @@ describe('Querying with relationship filters', () => { // SOME const _users = await context.lists.User.findMany({ - where: { feed_some: { title_contains: 'J' } }, + where: { feed: { some: { title: { contains: 'J' } } } }, query: 'id feed(orderBy: { title: asc }) { title }', }); @@ -150,7 +150,7 @@ describe('Querying with relationship filters', () => { ); test( - '_none condition', + 'none condition', runner(async ({ context }) => { const create = async (listKey: string, data: any) => context.lists[listKey].createOne({ data }); @@ -158,7 +158,7 @@ describe('Querying with relationship filters', () => { // NONE const _users = await context.lists.User.findMany({ - where: { feed_none: { title_contains: 'J' } }, + where: { feed: { none: { title: { contains: 'J' } } } }, query: 'id name feed { id title }', }); @@ -191,7 +191,7 @@ describe('Querying with relationship filters', () => { }; test( - '_every condition', + 'every condition', runner(async ({ context }) => { const create = async (listKey: string, data: any) => context.lists[listKey].createOne({ data }); @@ -199,7 +199,7 @@ describe('Querying with relationship filters', () => { // EVERY const _users = await context.lists.User.findMany({ - where: { feed_every: { title_contains: 'J' } }, + where: { feed: { every: { title: { contains: 'J' } } } }, query: 'id feed { id title }', }); @@ -210,7 +210,7 @@ describe('Querying with relationship filters', () => { ); test( - '_some condition', + 'some condition', runner(async ({ context }) => { const create = async (listKey: string, data: any) => context.lists[listKey].createOne({ data }); @@ -218,7 +218,7 @@ describe('Querying with relationship filters', () => { // SOME const _users = await context.lists.User.findMany({ - where: { feed_some: { title_contains: 'J' } }, + where: { feed: { some: { title: { contains: 'J' } } } }, query: 'id name feed(orderBy: { title: asc }) { id title }', }); @@ -230,7 +230,7 @@ describe('Querying with relationship filters', () => { ); test( - '_none condition', + 'none condition', runner(async ({ context }) => { const create = async (listKey: string, data: any) => context.lists[listKey].createOne({ data }); @@ -238,7 +238,7 @@ describe('Querying with relationship filters', () => { // NONE const _users = await context.lists.User.findMany({ - where: { feed_none: { title_contains: 'J' } }, + where: { feed: { none: { title: { contains: 'J' } } } }, query: 'id feed { title }', }); @@ -264,7 +264,7 @@ describe('Querying with relationship filters', () => { }; test( - '_every condition', + 'every condition', runner(async ({ context }) => { const create = async (listKey: string, data: any) => context.lists[listKey].createOne({ data }); @@ -272,7 +272,7 @@ describe('Querying with relationship filters', () => { // EVERY const _users = await context.lists.User.findMany({ - where: { feed_every: { title_contains: 'J' } }, + where: { feed: { every: { title: { contains: 'J' } } } }, query: 'id feed { id title }', }); @@ -286,7 +286,7 @@ describe('Querying with relationship filters', () => { ); test( - '_some condition', + 'some condition', runner(async ({ context }) => { const create = async (listKey: string, data: any) => context.lists[listKey].createOne({ data }); @@ -294,7 +294,7 @@ describe('Querying with relationship filters', () => { // SOME const _users = await context.lists.User.findMany({ - where: { feed_some: { author: { id: users[0].id } } }, + where: { feed: { some: { author: { id: { equals: users[0].id } } } } }, query: 'id name feed { id title }', }); expect(_users).toEqual([]); @@ -302,7 +302,7 @@ describe('Querying with relationship filters', () => { ); test( - '_none condition', + 'none condition', runner(async ({ context }) => { const create = async (listKey: string, data: any) => context.lists[listKey].createOne({ data }); @@ -310,7 +310,7 @@ describe('Querying with relationship filters', () => { // NONE const _users = await context.lists.User.findMany({ - where: { feed_none: { title_contains: 'J' } }, + where: { feed: { none: { title: { contains: 'J' } } } }, query: 'id feed { title }', }); diff --git a/tests/api-tests/relationships/crud-self-ref/many-to-many-one-sided.test.ts b/tests/api-tests/relationships/crud-self-ref/many-to-many-one-sided.test.ts index ca88814dfc9..62c85fb47ef 100644 --- a/tests/api-tests/relationships/crud-self-ref/many-to-many-one-sided.test.ts +++ b/tests/api-tests/relationships/crud-self-ref/many-to-many-one-sided.test.ts @@ -93,7 +93,7 @@ const runner = setupTestRunner({ describe(`Many-to-many relationships`, () => { describe('Read', () => { test( - '_some', + 'some', runner(async ({ context }) => { await createReadData(context); await Promise.all( @@ -104,7 +104,7 @@ describe(`Many-to-many relationships`, () => { ['D', 0], ].map(async ([name, count]) => { const users = await context.lists.User.findMany({ - where: { friends_some: { name } }, + where: { friends: { some: { name: { equals: name } } } }, }); expect(users.length).toEqual(count); }) @@ -112,7 +112,7 @@ describe(`Many-to-many relationships`, () => { }) ); test( - '_none', + 'none', runner(async ({ context }) => { await createReadData(context); await Promise.all( @@ -123,7 +123,7 @@ describe(`Many-to-many relationships`, () => { ['D', 9], ].map(async ([name, count]) => { const users = await context.lists.User.findMany({ - where: { friends_none: { name } }, + where: { friends: { none: { name: { equals: name } } } }, }); expect(users.length).toEqual(count); }) @@ -131,7 +131,7 @@ describe(`Many-to-many relationships`, () => { }) ); test( - '_every', + 'every', runner(async ({ context }) => { await createReadData(context); await Promise.all( @@ -142,7 +142,7 @@ describe(`Many-to-many relationships`, () => { ['D', 1], ].map(async ([name, count]) => { const users = await context.lists.User.findMany({ - where: { friends_every: { name } }, + where: { friends: { every: { name: { equals: name } } } }, }); expect(users.length).toEqual(count); }) diff --git a/tests/api-tests/relationships/crud-self-ref/many-to-many.test.ts b/tests/api-tests/relationships/crud-self-ref/many-to-many.test.ts index 1d7fa945071..6be81e702de 100644 --- a/tests/api-tests/relationships/crud-self-ref/many-to-many.test.ts +++ b/tests/api-tests/relationships/crud-self-ref/many-to-many.test.ts @@ -99,7 +99,7 @@ const runner = setupTestRunner({ describe(`Many-to-many relationships`, () => { describe('Read', () => { test( - '_some', + 'some', runner(async ({ context }) => { await createReadData(context); await Promise.all( @@ -110,7 +110,7 @@ describe(`Many-to-many relationships`, () => { ['D', 0], ].map(async ([name, count]) => { const _users = await context.lists.User.findMany({ - where: { friends_some: { name } }, + where: { friends: { some: { name: { equals: name } } } }, }); expect(_users.length).toEqual(count); }) @@ -118,7 +118,7 @@ describe(`Many-to-many relationships`, () => { }) ); test( - '_none', + 'none', runner(async ({ context }) => { await createReadData(context); await Promise.all( @@ -129,7 +129,7 @@ describe(`Many-to-many relationships`, () => { ['D', 9], ].map(async ([name, count]) => { const _users = await context.lists.User.findMany({ - where: { friends_none: { name } }, + where: { friends: { none: { name: { equals: name } } } }, }); expect(_users.length).toEqual(count); }) @@ -137,7 +137,7 @@ describe(`Many-to-many relationships`, () => { }) ); test( - '_every', + 'every', runner(async ({ context }) => { await createReadData(context); await Promise.all( @@ -148,7 +148,7 @@ describe(`Many-to-many relationships`, () => { ['D', 1], ].map(async ([name, count]) => { const users = await context.lists.User.findMany({ - where: { friends_every: { name } }, + where: { friends: { every: { name: { equals: name } } } }, }); expect(users.length).toEqual(count); }) diff --git a/tests/api-tests/relationships/crud-self-ref/one-to-many-one-sided.test.ts b/tests/api-tests/relationships/crud-self-ref/one-to-many-one-sided.test.ts index f664a582ac9..9d77cb502f1 100644 --- a/tests/api-tests/relationships/crud-self-ref/one-to-many-one-sided.test.ts +++ b/tests/api-tests/relationships/crud-self-ref/one-to-many-one-sided.test.ts @@ -104,7 +104,7 @@ describe(`One-to-many relationships`, () => { ['E', 0], ].map(async ([name, count]) => { const users = await context.lists.User.findMany({ - where: { friend: { name_contains: name } }, + where: { friend: { name: { contains: name } } }, }); expect(users.length).toEqual(count); }) @@ -112,18 +112,18 @@ describe(`One-to-many relationships`, () => { }) ); test( - 'is_null: true', + 'is null', runner(async ({ context }) => { await createComplexData(context); - const users = await context.lists.User.findMany({ where: { friend_is_null: true } }); + const users = await context.lists.User.findMany({ where: { friend: null } }); expect(users.length).toEqual(5); }) ); test( - 'is_null: false', + 'is not null', runner(async ({ context }) => { await createComplexData(context); - const users = await context.lists.User.findMany({ where: { friend_is_null: false } }); + const users = await context.lists.User.findMany({ where: { NOT: { friend: null } } }); expect(users.length).toEqual(4); }) ); diff --git a/tests/api-tests/relationships/crud-self-ref/one-to-many.test.ts b/tests/api-tests/relationships/crud-self-ref/one-to-many.test.ts index e48664dd30d..09d4ec8dae5 100644 --- a/tests/api-tests/relationships/crud-self-ref/one-to-many.test.ts +++ b/tests/api-tests/relationships/crud-self-ref/one-to-many.test.ts @@ -105,7 +105,7 @@ describe(`One-to-many relationships`, () => { ['D', 0], ].map(async ([name, count]) => { const users = await context.lists.User.findMany({ - where: { friendOf: { name_contains: name } }, + where: { friendOf: { name: { contains: name } } }, }); expect(users.length).toEqual(count); }) @@ -113,23 +113,23 @@ describe(`One-to-many relationships`, () => { }) ); test( - 'is_null: true', + 'is null', runner(async ({ context }) => { await createReadData(context); - const users = await context.lists.User.findMany({ where: { friendOf_is_null: true } }); + const users = await context.lists.User.findMany({ where: { friendOf: null } }); expect(users.length).toEqual(5); }) ); test( - 'is_null: false', + 'is not null', runner(async ({ context }) => { await createReadData(context); - const users = await context.lists.User.findMany({ where: { friendOf_is_null: false } }); + const users = await context.lists.User.findMany({ where: { NOT: { friendOf: null } } }); expect(users.length).toEqual(6); }) ); test( - '_some', + 'some', runner(async ({ context }) => { await createReadData(context); await Promise.all( @@ -140,7 +140,7 @@ describe(`One-to-many relationships`, () => { ['D', 0], ].map(async ([name, count]) => { const users = await context.lists.User.findMany({ - where: { friends_some: { name } }, + where: { friends: { some: { name: { equals: name } } } }, }); expect(users.length).toEqual(count); }) @@ -148,7 +148,7 @@ describe(`One-to-many relationships`, () => { }) ); test( - '_none', + 'none', runner(async ({ context }) => { await createReadData(context); await Promise.all( @@ -159,7 +159,7 @@ describe(`One-to-many relationships`, () => { ['D', 4 + 7], ].map(async ([name, count]) => { const users = await context.lists.User.findMany({ - where: { friends_none: { name } }, + where: { friends: { none: { name: { equals: name } } } }, }); expect(users.length).toEqual(count); }) @@ -167,7 +167,7 @@ describe(`One-to-many relationships`, () => { }) ); test( - '_every', + 'every', runner(async ({ context }) => { await createReadData(context); await Promise.all( @@ -178,7 +178,7 @@ describe(`One-to-many relationships`, () => { ['D', 1 + 7], ].map(async ([name, count]) => { const users = await context.lists.User.findMany({ - where: { friends_every: { name } }, + where: { friends: { every: { name: { equals: name } } } }, }); expect(users.length).toEqual(count); }) diff --git a/tests/api-tests/relationships/crud-self-ref/one-to-one.test.ts b/tests/api-tests/relationships/crud-self-ref/one-to-one.test.ts index bb04e20fe8d..3d0dc526ca7 100644 --- a/tests/api-tests/relationships/crud-self-ref/one-to-one.test.ts +++ b/tests/api-tests/relationships/crud-self-ref/one-to-one.test.ts @@ -79,7 +79,7 @@ describe(`One-to-one relationships`, () => { await createInitialData(context); const { user, friend } = await createUserAndFriend(context); const users = await context.lists.User.findMany({ - where: { friend: { name: friend.name } }, + where: { friend: { name: { equals: friend.name } } }, }); expect(users.length).toEqual(1); expect(users[0].id).toEqual(user.id); @@ -92,45 +92,45 @@ describe(`One-to-one relationships`, () => { await createInitialData(context); const { user, friend } = await createUserAndFriend(context); const users = await context.lists.User.findMany({ - where: { friendOf: { name: user.name } }, + where: { friendOf: { name: { equals: user.name } } }, }); expect(users.length).toEqual(1); expect(users[0].id).toEqual(friend.id); }) ); test( - 'Where friend: is_null: true', + 'Where friend: is null', runner(async ({ context }) => { await createInitialData(context); await createUserAndFriend(context); - const users = await context.lists.User.findMany({ where: { friend_is_null: true } }); + const users = await context.lists.User.findMany({ where: { friend: null } }); expect(users.length).toEqual(4); }) ); test( - 'Where friendOf: is_null: true', + 'Where friendOf: is null', runner(async ({ context }) => { await createInitialData(context); await createUserAndFriend(context); - const users = await context.lists.User.findMany({ where: { friendOf_is_null: true } }); + const users = await context.lists.User.findMany({ where: { friendOf: null } }); expect(users.length).toEqual(4); }) ); test( - 'Where friend: is_null: false', + 'Where friend: is not null', runner(async ({ context }) => { await createInitialData(context); await createUserAndFriend(context); - const users = await context.lists.User.findMany({ where: { friend_is_null: false } }); + const users = await context.lists.User.findMany({ where: { NOT: { friend: null } } }); expect(users.length).toEqual(1); }) ); test( - 'Where friendOf: is_null: false', + 'Where friendOf: is not null', runner(async ({ context }) => { await createInitialData(context); await createUserAndFriend(context); - const users = await context.lists.User.findMany({ where: { friendOf_is_null: false } }); + const users = await context.lists.User.findMany({ where: { NOT: { friendOf: null } } }); expect(users.length).toEqual(1); }) ); @@ -150,7 +150,7 @@ describe(`One-to-one relationships`, () => { await createInitialData(context); const { friend } = await createUserAndFriend(context); const count = await context.lists.User.count({ - where: { friend: { name: friend.name } }, + where: { friend: { name: { equals: friend.name } } }, }); expect(count).toEqual(1); }) @@ -162,7 +162,7 @@ describe(`One-to-one relationships`, () => { await createInitialData(context); const { user } = await createUserAndFriend(context); const count = await context.lists.User.count({ - where: { friendOf: { name: user.name } }, + where: { friendOf: { name: { equals: user.name } } }, }); expect(count).toEqual(1); }) @@ -172,7 +172,7 @@ describe(`One-to-one relationships`, () => { runner(async ({ context }) => { await createInitialData(context); await createUserAndFriend(context); - const count = await context.lists.User.count({ where: { friend_is_null: true } }); + const count = await context.lists.User.count({ where: { friend: null } }); expect(count).toEqual(4); }) ); @@ -182,7 +182,7 @@ describe(`One-to-one relationships`, () => { runner(async ({ context }) => { await createInitialData(context); await createUserAndFriend(context); - const count = await context.lists.User.count({ where: { friendOf_is_null: true } }); + const count = await context.lists.User.count({ where: { friendOf: null } }); expect(count).toEqual(4); }) ); diff --git a/tests/api-tests/relationships/crud/many-to-many-one-sided.test.ts b/tests/api-tests/relationships/crud/many-to-many-one-sided.test.ts index 446779b4dc4..fb9ca10d78f 100644 --- a/tests/api-tests/relationships/crud/many-to-many-one-sided.test.ts +++ b/tests/api-tests/relationships/crud/many-to-many-one-sided.test.ts @@ -100,7 +100,7 @@ const runner = setupTestRunner({ describe(`Many-to-many relationships`, () => { describe('Read', () => { test( - '_some', + 'some', runner(async ({ context }) => { await createReadData(context); await Promise.all( @@ -111,7 +111,7 @@ describe(`Many-to-many relationships`, () => { ['D', 0], ].map(async ([name, count]) => { const companies = await context.lists.Company.findMany({ - where: { locations_some: { name } }, + where: { locations: { some: { name: { equals: name } } } }, }); expect(companies.length).toEqual(count); }) @@ -119,7 +119,7 @@ describe(`Many-to-many relationships`, () => { }) ); test( - '_none', + 'none', runner(async ({ context }) => { await createReadData(context); await Promise.all( @@ -130,7 +130,7 @@ describe(`Many-to-many relationships`, () => { ['D', 9], ].map(async ([name, count]) => { const companies = await context.lists.Company.findMany({ - where: { locations_none: { name } }, + where: { locations: { none: { name: { equals: name } } } }, }); expect(companies.length).toEqual(count); }) @@ -138,7 +138,7 @@ describe(`Many-to-many relationships`, () => { }) ); test( - '_every', + 'every', runner(async ({ context }) => { await createReadData(context); await Promise.all( @@ -149,7 +149,7 @@ describe(`Many-to-many relationships`, () => { ['D', 1], ].map(async ([name, count]) => { const companies = await context.lists.Company.findMany({ - where: { locations_every: { name } }, + where: { locations: { every: { name: { equals: name } } } }, }); expect(companies.length).toEqual(count); }) @@ -171,7 +171,7 @@ describe(`Many-to-many relationships`, () => { ); test( - '_some', + 'some', runner(async ({ context }) => { await createReadData(context); await Promise.all( @@ -182,7 +182,7 @@ describe(`Many-to-many relationships`, () => { ['D', 0], ].map(async ([name, count]) => { const _count = await context.lists.Company.count({ - where: { locations_some: { name } }, + where: { locations: { some: { name: { equals: name } } } }, }); expect(_count).toEqual(count); }) @@ -190,7 +190,7 @@ describe(`Many-to-many relationships`, () => { }) ); test( - '_none', + 'none', runner(async ({ context }) => { await createReadData(context); await Promise.all( @@ -201,7 +201,7 @@ describe(`Many-to-many relationships`, () => { ['D', 9], ].map(async ([name, count]) => { const _count = await context.lists.Company.count({ - where: { locations_none: { name } }, + where: { locations: { none: { name: { equals: name } } } }, }); expect(_count).toEqual(count); }) @@ -209,7 +209,7 @@ describe(`Many-to-many relationships`, () => { }) ); test( - '_every', + 'every', runner(async ({ context }) => { await createReadData(context); await Promise.all( @@ -220,7 +220,7 @@ describe(`Many-to-many relationships`, () => { ['D', 1], ].map(async ([name, count]) => { const _count = await context.lists.Company.count({ - where: { locations_every: { name } }, + where: { locations: { every: { name: { equals: name } } } }, }); expect(_count).toEqual(count); }) diff --git a/tests/api-tests/relationships/crud/many-to-many.test.ts b/tests/api-tests/relationships/crud/many-to-many.test.ts index d7e00b5d4e9..5f9309524e3 100644 --- a/tests/api-tests/relationships/crud/many-to-many.test.ts +++ b/tests/api-tests/relationships/crud/many-to-many.test.ts @@ -114,7 +114,7 @@ const runner = setupTestRunner({ describe(`Many-to-many relationships`, () => { describe('Read', () => { test( - '_some', + 'some', runner(async ({ context }) => { await createReadData(context); await Promise.all( @@ -125,7 +125,7 @@ describe(`Many-to-many relationships`, () => { ['D', 0], ].map(async ([name, count]) => { const companies = await context.lists.Company.findMany({ - where: { locations_some: { name } }, + where: { locations: { some: { name: { equals: name } } } }, }); expect(companies.length).toEqual(count); }) @@ -133,7 +133,7 @@ describe(`Many-to-many relationships`, () => { }) ); test( - '_none', + 'none', runner(async ({ context }) => { await createReadData(context); await Promise.all( @@ -144,7 +144,7 @@ describe(`Many-to-many relationships`, () => { ['D', 9], ].map(async ([name, count]) => { const companies = await context.lists.Company.findMany({ - where: { locations_none: { name } }, + where: { locations: { none: { name: { equals: name } } } }, }); expect(companies.length).toEqual(count); }) @@ -152,7 +152,7 @@ describe(`Many-to-many relationships`, () => { }) ); test( - '_every', + 'every', runner(async ({ context }) => { await createReadData(context); await Promise.all( @@ -163,7 +163,7 @@ describe(`Many-to-many relationships`, () => { ['D', 1], ].map(async ([name, count]) => { const companies = await context.lists.Company.findMany({ - where: { locations_every: { name } }, + where: { locations: { every: { name: { equals: name } } } }, }); expect(companies.length).toEqual(count); }) @@ -184,7 +184,7 @@ describe(`Many-to-many relationships`, () => { }) ); test( - '_some', + 'some', runner(async ({ context }) => { await createReadData(context); await Promise.all( @@ -195,7 +195,7 @@ describe(`Many-to-many relationships`, () => { ['D', 0], ].map(async ([name, count]) => { const _count = await context.lists.Company.count({ - where: { locations_some: { name } }, + where: { locations: { some: { name: { equals: name } } } }, }); expect(_count).toEqual(count); }) @@ -203,7 +203,7 @@ describe(`Many-to-many relationships`, () => { }) ); test( - '_none', + 'none', runner(async ({ context }) => { await createReadData(context); await Promise.all( @@ -214,7 +214,7 @@ describe(`Many-to-many relationships`, () => { ['D', 9], ].map(async ([name, count]) => { const _count = await context.lists.Company.count({ - where: { locations_none: { name } }, + where: { locations: { none: { name: { equals: name } } } }, }); expect(_count).toEqual(count); }) @@ -222,7 +222,7 @@ describe(`Many-to-many relationships`, () => { }) ); test( - '_every', + 'every', runner(async ({ context }) => { await createReadData(context); await Promise.all( @@ -233,7 +233,7 @@ describe(`Many-to-many relationships`, () => { ['D', 1], ].map(async ([name, count]) => { const _count = await context.lists.Company.count({ - where: { locations_every: { name } }, + where: { locations: { every: { name: { equals: name } } } }, }); expect(_count).toEqual(count); }) diff --git a/tests/api-tests/relationships/crud/one-to-many-one-sided.test.ts b/tests/api-tests/relationships/crud/one-to-many-one-sided.test.ts index 5421134c607..d7b96de0065 100644 --- a/tests/api-tests/relationships/crud/one-to-many-one-sided.test.ts +++ b/tests/api-tests/relationships/crud/one-to-many-one-sided.test.ts @@ -131,7 +131,7 @@ describe(`One-to-many relationships`, () => { ['E', 0], ].map(async ([name, count]) => { const companies = await context.lists.Company.findMany({ - where: { location: { name_contains: name } }, + where: { location: { name: { contains: name } } }, }); expect(companies.length).toEqual(count); }) @@ -139,21 +139,21 @@ describe(`One-to-many relationships`, () => { }) ); test( - 'is_null: true', + 'is null', runner(async ({ context }) => { await createComplexData(context); const companies = await context.lists.Company.findMany({ - where: { location_is_null: true }, + where: { location: null }, }); expect(companies.length).toEqual(1); }) ); test( - 'is_null: false', + 'is not null', runner(async ({ context }) => { await createComplexData(context); const companies = await context.lists.Company.findMany({ - where: { location_is_null: false }, + where: { NOT: { location: null } }, }); expect(companies.length).toEqual(4); }) diff --git a/tests/api-tests/relationships/crud/one-to-many.test.ts b/tests/api-tests/relationships/crud/one-to-many.test.ts index bc780b80485..6585dbe2f75 100644 --- a/tests/api-tests/relationships/crud/one-to-many.test.ts +++ b/tests/api-tests/relationships/crud/one-to-many.test.ts @@ -118,7 +118,7 @@ describe(`One-to-many relationships`, () => { ['D', 0], ].map(async ([name, count]) => { const locations = await context.lists.Location.findMany({ - where: { company: { name_contains: name } }, + where: { company: { name: { contains: name } } }, }); expect(locations.length).toEqual(count); }) @@ -126,27 +126,27 @@ describe(`One-to-many relationships`, () => { }) ); test( - 'is_null: true', + 'is null', runner(async ({ context }) => { await createReadData(context); const locations = await context.lists.Location.findMany({ - where: { company_is_null: true }, + where: { company: null }, }); expect(locations.length).toEqual(1); }) ); test( - 'is_null: false', + 'is not null', runner(async ({ context }) => { await createReadData(context); const locations = await context.lists.Location.findMany({ - where: { company_is_null: false }, + where: { NOT: { company: null } }, }); expect(locations.length).toEqual(6); }) ); test( - '_some', + 'some', runner(async ({ context }) => { await createReadData(context); await Promise.all( @@ -157,7 +157,7 @@ describe(`One-to-many relationships`, () => { ['D', 0], ].map(async ([name, count]) => { const companies = await context.lists.Company.findMany({ - where: { locations_some: { name } }, + where: { locations: { some: { name: { equals: name } } } }, }); expect(companies.length).toEqual(count); }) @@ -165,7 +165,7 @@ describe(`One-to-many relationships`, () => { }) ); test( - '_none', + 'none', runner(async ({ context }) => { await createReadData(context); await Promise.all( @@ -176,7 +176,7 @@ describe(`One-to-many relationships`, () => { ['D', 4], ].map(async ([name, count]) => { const companies = await context.lists.Company.findMany({ - where: { locations_none: { name } }, + where: { locations: { none: { name: { equals: name } } } }, }); expect(companies.length).toEqual(count); }) @@ -184,7 +184,7 @@ describe(`One-to-many relationships`, () => { }) ); test( - '_every', + 'every', runner(async ({ context }) => { await createReadData(context); await Promise.all( @@ -195,7 +195,7 @@ describe(`One-to-many relationships`, () => { ['D', 1], ].map(async ([name, count]) => { const companies = await context.lists.Company.findMany({ - where: { locations_every: { name } }, + where: { locations: { every: { name: { equals: name } } } }, }); expect(companies.length).toEqual(count); }) diff --git a/tests/api-tests/relationships/crud/one-to-one.test.ts b/tests/api-tests/relationships/crud/one-to-one.test.ts index e914749cbf4..b4117a0c4b1 100644 --- a/tests/api-tests/relationships/crud/one-to-one.test.ts +++ b/tests/api-tests/relationships/crud/one-to-one.test.ts @@ -118,10 +118,10 @@ describe(`One-to-one relationships`, () => { await createInitialData(context); const { location, company } = await createCompanyAndLocation(context); const locations = await context.lists.Location.findMany({ - where: { company: { name: company.name } }, + where: { company: { name: { equals: company.name } } }, }); const companies = await context.lists.Company.findMany({ - where: { location: { name: location.name } }, + where: { location: { name: { equals: location.name } } }, }); expect(locations.length).toEqual(1); expect(locations[0].id).toEqual(location.id); @@ -135,10 +135,10 @@ describe(`One-to-one relationships`, () => { await createInitialData(context); const { location, company } = await createLocationAndCompany(context); const locations = await context.lists.Location.findMany({ - where: { company: { name: company.name } }, + where: { company: { name: { equals: company.name } } }, }); const companies = await context.lists.Company.findMany({ - where: { location: { name: location.name } }, + where: { location: { name: { equals: location.name } } }, }); expect(locations.length).toEqual(1); expect(locations[0].id).toEqual(location.id); @@ -147,60 +147,60 @@ describe(`One-to-one relationships`, () => { }) ); test( - 'Where A: is_null: true', + 'Where A: is null', runner(async ({ context }) => { await createInitialData(context); await createCompanyAndLocation(context); const locations = await context.lists.Location.findMany({ - where: { company_is_null: true }, + where: { company: null }, }); const companies = await context.lists.Company.findMany({ - where: { location_is_null: true }, + where: { location: null }, }); expect(locations.length).toEqual(4); expect(companies.length).toEqual(3); }) ); test( - 'Where B: is_null: true', + 'Where B: is null', runner(async ({ context }) => { await createInitialData(context); await createLocationAndCompany(context); const locations = await context.lists.Location.findMany({ - where: { company_is_null: true }, + where: { company: null }, }); const companies = await context.lists.Company.findMany({ - where: { location_is_null: true }, + where: { location: null }, }); expect(locations.length).toEqual(4); expect(companies.length).toEqual(3); }) ); test( - 'Where A: is_null: false', + 'Where A: is not null', runner(async ({ context }) => { await createInitialData(context); await createCompanyAndLocation(context); const locations = await context.lists.Location.findMany({ - where: { company_is_null: false }, + where: { NOT: { company: null } }, }); const companies = await context.lists.Company.findMany({ - where: { location_is_null: false }, + where: { NOT: { location: null } }, }); expect(locations.length).toEqual(1); expect(companies.length).toEqual(1); }) ); test( - 'Where B: is_null: false', + 'Where B: is not null', runner(async ({ context }) => { await createInitialData(context); await createLocationAndCompany(context); const locations = await context.lists.Location.findMany({ - where: { company_is_null: false }, + where: { NOT: { company: null } }, }); const companies = await context.lists.Company.findMany({ - where: { location_is_null: false }, + where: { NOT: { location: null } }, }); expect(locations.length).toEqual(1); expect(companies.length).toEqual(1); @@ -224,10 +224,10 @@ describe(`One-to-one relationships`, () => { await createInitialData(context); const { location, company } = await createCompanyAndLocation(context); const locationsCount = await context.lists.Location.count({ - where: { company: { name: company.name } }, + where: { company: { name: { equals: company.name } } }, }); const companiesCount = await context.lists.Company.count({ - where: { location: { name: location.name } }, + where: { location: { name: { equals: location.name } } }, }); expect(companiesCount).toEqual(1); expect(locationsCount).toEqual(1); @@ -239,10 +239,10 @@ describe(`One-to-one relationships`, () => { await createInitialData(context); const { location, company } = await createLocationAndCompany(context); const locationsCount = await context.lists.Location.count({ - where: { company: { name: company.name } }, + where: { company: { name: { equals: company.name } } }, }); const companiesCount = await context.lists.Company.count({ - where: { location: { name: location.name } }, + where: { location: { name: { equals: location.name } } }, }); expect(companiesCount).toEqual(1); expect(locationsCount).toEqual(1); @@ -254,10 +254,10 @@ describe(`One-to-one relationships`, () => { await createInitialData(context); await createCompanyAndLocation(context); const locationsCount = await context.lists.Location.count({ - where: { company_is_null: true }, + where: { company: null }, }); const companiesCount = await context.lists.Company.count({ - where: { location_is_null: true }, + where: { location: null }, }); expect(companiesCount).toEqual(3); expect(locationsCount).toEqual(4); @@ -269,10 +269,10 @@ describe(`One-to-one relationships`, () => { await createInitialData(context); await createLocationAndCompany(context); const locationsCount = await context.lists.Location.count({ - where: { company_is_null: true }, + where: { company: null }, }); const companiesCount = await context.lists.Company.count({ - where: { location_is_null: true }, + where: { location: null }, }); expect(companiesCount).toEqual(3); expect(locationsCount).toEqual(4); diff --git a/tests/api-tests/relationships/filtering/access-control.test.ts b/tests/api-tests/relationships/filtering/access-control.test.ts index e49208685d5..df0b3715ba7 100644 --- a/tests/api-tests/relationships/filtering/access-control.test.ts +++ b/tests/api-tests/relationships/filtering/access-control.test.ts @@ -24,7 +24,7 @@ const runner = setupTestRunner({ }, access: { // Limit read access to the first post only - read: { name_in: [postNames[1]] }, + read: { name: { in: [postNames[1]] } }, }, }), }), @@ -97,7 +97,7 @@ describe('relationship filtering with access control', () => { where: { id: user.id }, // Knowingly filter to an ID I don't have read access to // to see if the filter is correctly "AND"d with the access control - query: `id username posts(where: { id_in: ["${postIds[2]}"] }) { id }`, + query: `id username posts(where: { id: { in: ["${postIds[2]}"] } }) { id }`, }); expect(item).toMatchObject({ id: expect.any(String), username, posts: [] }); diff --git a/tests/api-tests/relationships/filtering/filtering.test.ts b/tests/api-tests/relationships/filtering/filtering.test.ts index 3caff8d17b8..32224aea55a 100644 --- a/tests/api-tests/relationships/filtering/filtering.test.ts +++ b/tests/api-tests/relationships/filtering/filtering.test.ts @@ -36,7 +36,10 @@ describe('relationship filtering', () => { const users = await context.lists.User.findMany({ where: { - AND: [{ company: { name_contains: 'in' } }, { company: { name_contains: 'll' } }], + AND: [ + { company: { name: { contains: 'in' } } }, + { company: { name: { contains: 'll' } } }, + ], }, query: 'id company { id name }', }); @@ -63,7 +66,10 @@ describe('relationship filtering', () => { const users = await context.lists.User.findMany({ where: { - OR: [{ company: { name_contains: 'in' } }, { company: { name_contains: 'xx' } }], + OR: [ + { company: { name: { contains: 'in' } } }, + { company: { name: { contains: 'xx' } } }, + ], }, query: 'id company { id name }', }); @@ -93,8 +99,8 @@ describe('relationship filtering', () => { const users = (await context.lists.User.findMany({ where: { AND: [ - { posts_some: { content_contains: 'hi' } }, - { posts_some: { content_contains: 'lo' } }, + { posts: { some: { content: { contains: 'hi' } } } }, + { posts: { some: { content: { contains: 'lo' } } } }, ], }, query: 'id posts { id content }', @@ -125,8 +131,8 @@ describe('relationship filtering', () => { const users = (await context.lists.User.findMany({ where: { OR: [ - { posts_some: { content_contains: 'o w' } }, - { posts_some: { content_contains: '? O' } }, + { posts: { some: { content: { contains: 'o w' } } } }, + { posts: { some: { content: { contains: '? O' } } } }, ], }, query: 'id posts { id content }', @@ -199,7 +205,10 @@ describe('relationship filtering', () => { posts: { content: string }[]; }[]; const users = (await context.lists.User.findMany({ - where: { company: { name: adsCompany.name }, posts_every: { content: 'spam' } }, + where: { + company: { name: { equals: adsCompany.name } }, + posts: { every: { content: { equals: 'spam' } } }, + }, query: 'id company { id name } posts { content }', })) as T; expect(users).toHaveLength(2); @@ -209,7 +218,10 @@ describe('relationship filtering', () => { // adsCompany users with no spam const users2 = (await context.lists.User.findMany({ - where: { company: { name: adsCompany.name }, posts_none: { content: 'spam' } }, + where: { + company: { name: { equals: adsCompany.name } }, + posts: { none: { content: { equals: 'spam' } } }, + }, query: 'id company { id name } posts { content }', })) as T; @@ -220,7 +232,10 @@ describe('relationship filtering', () => { // adsCompany users with some spam const users3 = (await context.lists.User.findMany({ - where: { company: { name: adsCompany.name }, posts_some: { content: 'spam' } }, + where: { + company: { name: { equals: adsCompany.name } }, + posts: { some: { content: { equals: 'spam' } } }, + }, query: 'id company { id name } posts { content }', })) as T; diff --git a/tests/api-tests/relationships/filtering/nested.test.ts b/tests/api-tests/relationships/filtering/nested.test.ts index 9679c5122b8..daf5829477b 100644 --- a/tests/api-tests/relationships/filtering/nested.test.ts +++ b/tests/api-tests/relationships/filtering/nested.test.ts @@ -36,7 +36,7 @@ describe('relationship filtering', () => { }); const users = (await context.lists.User.findMany({ - query: `id posts (where: { content_contains: "hi" }){ id content }`, + query: `id posts (where: { content: { contains: "hi" } }){ id content }`, })) as { id: IdType; posts: { id: IdType; content: string }[] }[]; expect(users).toHaveLength(2); users[0].posts = users[0].posts.map(({ id }) => id).sort(); @@ -63,7 +63,7 @@ describe('relationship filtering', () => { }); const users = await context.lists.User.findMany({ - query: 'id posts(first: 1, orderBy: { content: asc }) { id }', + query: 'id posts(take: 1, orderBy: { content: asc }) { id }', }); expect(users).toContainEqual({ id: user.id, posts: [ids[0]] }); expect(users).toContainEqual({ id: user2.id, posts: [ids[0]] }); @@ -86,7 +86,7 @@ describe('relationship filtering', () => { const users = await context.lists.User.findMany({ query: - 'id posts(where: { AND: [{ content_contains: "hi" }, { content_contains: "lo" }] }){ id }', + 'id posts(where: { AND: [{ content: { contains: "hi" } }, { content: { contains: "lo" } }] }){ id }', }); expect(users).toContainEqual({ id: user.id, posts: [ids[2]] }); @@ -110,7 +110,7 @@ describe('relationship filtering', () => { const users = await context.lists.User.findMany({ query: - 'id posts(where: { OR: [{ content_contains: "i w" }, { content_contains: "? O" }] }){ id content }', + 'id posts(where: { OR: [{ content: { contains: "i w" } }, { content: { contains: "? O" } }] }){ id content }', }); expect(users).toContainEqual({ id: user.id, @@ -129,7 +129,7 @@ describe('relationship filtering', () => { await context.lists.User.createOne({ data: {} }); const users = await context.lists.User.findMany({ - where: { posts_some: { content_contains: 'foo' } }, + where: { posts: { some: { content: { contains: 'foo' } } } }, query: 'posts { id }', }); expect(users).toHaveLength(0); @@ -174,7 +174,7 @@ describe('relationship meta filtering', () => { }); const users = await context.lists.User.findMany({ - query: 'id postsCount(where: { content_contains: "hi" })', + query: 'id postsCount(where: { content: { contains: "hi" } })', }); expect(users).toHaveLength(2); expect(users).toContainEqual({ id: user.id, postsCount: 2 }); @@ -197,7 +197,7 @@ describe('relationship meta filtering', () => { }); const users = await context.lists.User.findMany({ - query: `id postsCount(where: { AND: [{ content_contains: "hi" }, { content_contains: "lo" }] })`, + query: `id postsCount(where: { AND: [{ content: { contains: "hi" } }, { content: { contains: "lo" } }] })`, }); expect(users).toHaveLength(2); @@ -222,7 +222,7 @@ describe('relationship meta filtering', () => { const users = await context.lists.User.findMany({ query: - 'id postsCount(where: { OR: [{ content_contains: "i w" }, { content_contains: "? O" }] })', + 'id postsCount(where: { OR: [{ content: { contains: "i w" } }, { content: { contains: "? O" } }] })', }); expect(users).toHaveLength(2); expect(users).toContainEqual({ id: user.id, postsCount: 2 }); diff --git a/tests/api-tests/relationships/many-to-one-to-one.test.ts b/tests/api-tests/relationships/many-to-one-to-one.test.ts index 0bbf84d21ab..b56821167b4 100644 --- a/tests/api-tests/relationships/many-to-one-to-one.test.ts +++ b/tests/api-tests/relationships/many-to-one-to-one.test.ts @@ -123,7 +123,11 @@ describe(`One-to-one relationships`, () => { const owner = await createCompanyAndLocation(context); const name1 = owner.companies[0].location.custodians[0].name; const owners = await context.lists.Owner.findMany({ - where: { companies_some: { location: { custodians_some: { name: name1 } } } }, + where: { + companies: { + some: { location: { custodians: { some: { name: { equals: name1 } } } } }, + }, + }, query: 'id companies { location { custodians { name } } }', }); expect(owners.length).toEqual(1); @@ -137,7 +141,9 @@ describe(`One-to-one relationships`, () => { const owner = await createCompanyAndLocation(context); const name1 = owner.name; const custodians = await context.lists.Custodian.findMany({ - where: { locations_some: { company: { owners_some: { name: name1 } } } }, + where: { + locations: { some: { company: { owners: { some: { name: { equals: name1 } } } } } }, + }, query: 'id locations { company { owners { name } } }', }); expect(custodians.length).toEqual(2); @@ -151,10 +157,16 @@ describe(`One-to-one relationships`, () => { const name1 = owner.name; const owners = await context.lists.Owner.findMany({ where: { - companies_some: { - location: { - custodians_some: { - locations_some: { company: { owners_some: { name: name1 } } }, + companies: { + some: { + location: { + custodians: { + some: { + locations: { + some: { company: { owners: { some: { name: { equals: name1 } } } } }, + }, + }, + }, }, }, }, @@ -174,10 +186,16 @@ describe(`One-to-one relationships`, () => { const custodians = await context.lists.Custodian.findMany({ where: { - locations_some: { - company: { - owners_some: { - companies_some: { location: { custodians_some: { name: name1 } } }, + locations: { + some: { + company: { + owners: { + some: { + companies: { + some: { location: { custodians: { some: { name: { equals: name1 } } } } }, + }, + }, + }, }, }, }, diff --git a/tests/api-tests/relationships/nested-mutations/create-and-connect-many.test.ts b/tests/api-tests/relationships/nested-mutations/create-and-connect-many.test.ts index a1929770098..f0e5bcdfb62 100644 --- a/tests/api-tests/relationships/nested-mutations/create-and-connect-many.test.ts +++ b/tests/api-tests/relationships/nested-mutations/create-and-connect-many.test.ts @@ -84,7 +84,7 @@ describe('no access control', () => { // Sanity check that the items are actually created const allNotes = await context.lists.Note.findMany({ - where: { id_in: user.notes.map(({ id }) => id) }, + where: { id: { in: user.notes.map(({ id }) => id) } }, query: 'id content', }); @@ -125,7 +125,7 @@ describe('no access control', () => { // Sanity check that the items are actually created const allNotes = await context.lists.Note.findMany({ - where: { id_in: user.notes.map(({ id }) => id) }, + where: { id: { in: user.notes.map(({ id }) => id) } }, query: 'id content', }); diff --git a/tests/api-tests/relationships/nested-mutations/create-many.test.ts b/tests/api-tests/relationships/nested-mutations/create-many.test.ts index 92b0dcb2226..0440365f3aa 100644 --- a/tests/api-tests/relationships/nested-mutations/create-many.test.ts +++ b/tests/api-tests/relationships/nested-mutations/create-many.test.ts @@ -131,7 +131,7 @@ describe('no access control', () => { // Sanity check that the items are actually created const notes = await context.lists.Note.findMany({ - where: { id_in: user1.notes.map(({ id }) => id) }, + where: { id: { in: user1.notes.map(({ id }) => id) } }, }); expect(notes).toHaveLength(user1.notes.length); @@ -187,7 +187,7 @@ describe('no access control', () => { // Sanity check that the items are actually created const notes = await context.lists.Note.findMany({ - where: { id_in: _user.notes.map(({ id }) => id) }, + where: { id: { in: _user.notes.map(({ id }) => id) } }, }); expect(notes).toHaveLength(_user.notes.length); }) @@ -218,7 +218,9 @@ describe('with access control', () => { }); expect(data).toEqual({ createUserToNotesNoRead: { id: expect.any(String), notes: null } }); - expectAccessDenied(errors, [{ path: ['createUserToNotesNoRead', 'notes'] }]); + expectAccessDenied('dev', false, undefined, errors, [ + { path: ['createUserToNotesNoRead', 'notes'] }, + ]); }) ); @@ -307,10 +309,10 @@ describe('with access control', () => { // Confirm it didn't insert either of the records anyway const allNoteNoCreates = await context.lists.NoteNoCreate.findMany({ - where: { content: noteContent }, + where: { content: { equals: noteContent } }, }); const allUserToNotesNoCreates = await context.lists.UserToNotesNoCreate.findMany({ - where: { username: userName }, + where: { username: { equals: userName } }, }); expect(allNoteNoCreates).toMatchObject([]); expect(allUserToNotesNoCreates).toMatchObject([]); @@ -355,7 +357,7 @@ describe('with access control', () => { // Confirm it didn't insert the record anyway const items = await context.lists.NoteNoCreate.findMany({ - where: { content: noteContent }, + where: { content: { equals: noteContent } }, }); expect(items).toMatchObject([]); }) diff --git a/tests/api-tests/relationships/nested-mutations/create-singular.test.ts b/tests/api-tests/relationships/nested-mutations/create-singular.test.ts index 5126d0e0c9a..feedce7adc8 100644 --- a/tests/api-tests/relationships/nested-mutations/create-singular.test.ts +++ b/tests/api-tests/relationships/nested-mutations/create-singular.test.ts @@ -265,14 +265,14 @@ describe('with access control', () => { } // Confirm it didn't insert either of the records anyway const data1 = await context.lists[group.name].findMany({ - where: { name: groupName }, + where: { name: { equals: groupName } }, query: 'id name', }); expect(data1).toMatchObject([]); // Confirm it didn't insert either of the records anyway const data2 = await context.lists[`EventTo${group.name}`].findMany({ - where: { title: eventName }, + where: { title: { equals: eventName } }, query: 'id title', }); expect(data2).toMatchObject([]); @@ -326,7 +326,7 @@ describe('with access control', () => { // Confirm it didn't insert the record anyway const groups = await context.lists[group.name].findMany({ - where: { name: groupName }, + where: { name: { equals: groupName } }, query: 'id name', }); expect(groups).toMatchObject([]); diff --git a/tests/api-tests/relationships/shared-names.test.ts b/tests/api-tests/relationships/shared-names.test.ts index 11e4724c4f0..2d058c296c8 100644 --- a/tests/api-tests/relationships/shared-names.test.ts +++ b/tests/api-tests/relationships/shared-names.test.ts @@ -129,7 +129,7 @@ test( runner(async ({ context }) => { await createInitialData(context); const employees = await context.lists.Employee.findMany({ - where: { company: { employees_some: { role: { name: 'RoleA' } } } }, + where: { company: { employees: { some: { role: { name: { equals: 'RoleA' } } } } } }, query: 'id name', }); expect(employees).toHaveLength(1); diff --git a/tests/api-tests/utils.ts b/tests/api-tests/utils.ts index 9b824b50bf2..5b85916b4cc 100644 --- a/tests/api-tests/utils.ts +++ b/tests/api-tests/utils.ts @@ -17,21 +17,24 @@ export const apiTestConfig = ( }); const unpackErrors = (errors: readonly any[] | undefined) => - (errors || []).map(({ locations, extensions: { exception, ...extensions }, ...unpacked }) => ({ - extensions, - ...unpacked, - })); + (errors || []).map(({ locations, ...unpacked }) => unpacked); const j = (messages: string[]) => messages.map(m => ` - ${m}`).join('\n'); +// FIXME: It's not clear to me right now why sometimes +// we get an expcetion, and other times we don't - TL export const expectInternalServerError = ( errors: readonly any[] | undefined, + expectException: boolean, args: { path: any[]; message: string }[] ) => { const unpackedErrors = unpackErrors(errors); expect(unpackedErrors).toEqual( args.map(({ path, message }) => ({ - extensions: { code: 'INTERNAL_SERVER_ERROR' }, + extensions: { + code: 'INTERNAL_SERVER_ERROR', + ...(expectException ? { exception: { locations: [expect.any(Object)], message } } : {}), + }, path, message, })) @@ -52,17 +55,36 @@ export const expectGraphQLValidationError = ( }; export const expectAccessDenied = ( + mode: 'dev' | 'production', + httpQuery: boolean, + _debug: boolean | undefined, errors: readonly any[] | undefined, args: { path: (string | number)[] }[] ) => { const unpackedErrors = (errors || []).map(({ locations, ...unpacked }) => ({ ...unpacked, })); + const message = 'You do not have access to this resource'; + // We expect to see debug details if: + // - httpQuery is false + // - graphql.debug is true or + // - graphql.debug is undefined and mode !== production or + const expectDebug = + _debug === true || (_debug === undefined && mode !== 'production') || !httpQuery; + // We expect to see the Apollo exception under the same conditions, but only if + // httpQuery is also true. + const expectException = httpQuery && expectDebug; + expect(unpackedErrors).toEqual( args.map(({ path }) => ({ - extensions: { code: undefined }, + extensions: { + code: httpQuery ? 'INTERNAL_SERVER_ERROR' : undefined, + ...(expectException + ? { exception: { stacktrace: expect.arrayContaining([`Error: ${message}`]) } } + : {}), + }, path, - message: 'You do not have access to this resource', + message, })) ); }; @@ -84,28 +106,56 @@ export const expectValidationError = ( }; export const expectExtensionError = ( + mode: 'dev' | 'production', + httpQuery: boolean, + _debug: boolean | undefined, errors: readonly any[] | undefined, extensionName: string, - args: { path: (string | number)[]; messages: string[] }[] + args: { path: (string | number)[]; messages: string[]; debug: any[] }[] ) => { const unpackedErrors = unpackErrors(errors); expect(unpackedErrors).toEqual( - args.map(({ path, messages }) => ({ - extensions: { code: undefined }, - path, - message: `An error occured while running "${extensionName}".\n${j(messages)}`, - })) + args.map(({ path, messages, debug }) => { + const message = `An error occured while running "${extensionName}".\n${j(messages)}`; + const stacktrace = message.split('\n'); + stacktrace[0] = `Error: ${stacktrace[0]}`; + + // We expect to see debug details if: + // - httpQuery is false + // - graphql.debug is true or + // - graphql.debug is undefined and mode !== production or + const expectDebug = + _debug === true || (_debug === undefined && mode !== 'production') || !httpQuery; + // We expect to see the Apollo exception under the same conditions, but only if + // httpQuery is also true. + const expectException = httpQuery && expectDebug; + + return { + extensions: { + code: 'INTERNAL_SERVER_ERROR', + ...(expectException + ? { exception: { debug, stacktrace: expect.arrayContaining(stacktrace) } } + : {}), + ...(expectDebug ? { debug } : {}), + }, + path, + message, + }; + }) ); }; export const expectPrismaError = ( errors: readonly any[] | undefined, - args: { path: any[]; message: string }[] + args: { path: any[]; message: string; code: string; target: string[] }[] ) => { const unpackedErrors = unpackErrors(errors); expect(unpackedErrors).toEqual( - args.map(({ path, message }) => ({ - extensions: { code: 'INTERNAL_SERVER_ERROR' }, + args.map(({ path, message, code, target }) => ({ + extensions: { + code: 'INTERNAL_SERVER_ERROR', + exception: { clientVersion: '2.29.1', code, meta: { target } }, + }, path, message, })) diff --git a/tests/benchmarks/CHANGELOG.md b/tests/benchmarks/CHANGELOG.md index 562a52338c1..5af1efc132f 100644 --- a/tests/benchmarks/CHANGELOG.md +++ b/tests/benchmarks/CHANGELOG.md @@ -1,5 +1,14 @@ # @keystonejs/benchmarks +## 7.0.7 + +### Patch Changes + +- Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 + - @keystone-next/testing@1.1.1 + ## 7.0.6 ### Patch Changes diff --git a/tests/benchmarks/package.json b/tests/benchmarks/package.json index 2899ace5a3a..0d27253703b 100644 --- a/tests/benchmarks/package.json +++ b/tests/benchmarks/package.json @@ -2,7 +2,7 @@ "name": "@keystone-next/benchmarks-legacy", "description": "A set of benchmarks for running against the KeystoneJS API.", "private": true, - "version": "7.0.6", + "version": "7.0.7", "author": "The KeystoneJS Development Team", "license": "MIT", "engines": { @@ -14,9 +14,9 @@ "repository": "https://github.com/keystonejs/keystone/tree/master/tests/benchmarks", "homepage": "https://github.com/keystonejs/keystone", "dependencies": { - "@keystone-next/fields": "^13.0.0", - "@keystone-next/keystone": "^23.0.0", - "@keystone-next/testing": "^1.1.0", + "@keystone-next/fields": "^14.0.0", + "@keystone-next/keystone": "^24.0.0", + "@keystone-next/testing": "^1.1.1", "cookie-signature": "^1.1.0", "testcheck": "^1.0.0-rc.2" } diff --git a/tests/examples-smoke-tests/custom-admin-ui-pages.test.ts b/tests/examples-smoke-tests/custom-admin-ui-pages.test.ts index 408baf40399..8b3dd98613a 100644 --- a/tests/examples-smoke-tests/custom-admin-ui-pages.test.ts +++ b/tests/examples-smoke-tests/custom-admin-ui-pages.test.ts @@ -11,8 +11,7 @@ exampleProjectTests('custom-admin-ui-pages', browserType => { }); test('Load list', async () => { await page.goto('http://localhost:3000/custom-page'); - const content = await page.textContent('body h1'); - expect(content).toBe('Hello this is a custom page'); + await page.waitForSelector('main h1:has-text("This is a custom Admin UI page")'); }); afterAll(async () => { await browser.close(); diff --git a/tests/examples-smoke-tests/package.json b/tests/examples-smoke-tests/package.json index e043d17e77d..55098b68602 100644 --- a/tests/examples-smoke-tests/package.json +++ b/tests/examples-smoke-tests/package.json @@ -14,7 +14,7 @@ "@types/tough-cookie": "^4.0.1", "execa": "^5.1.1", "node-fetch": "^2.6.1", - "playwright": "^1.13.1", + "playwright": "^1.14.0", "tree-kill": "^1.2.2" } } diff --git a/tests/test-projects/basic/CHANGELOG.md b/tests/test-projects/basic/CHANGELOG.md index bb5b655a22f..49f6ad1855c 100644 --- a/tests/test-projects/basic/CHANGELOG.md +++ b/tests/test-projects/basic/CHANGELOG.md @@ -1,5 +1,13 @@ # @keystone-next/test-projects-basic +## 0.0.3 + +### Patch Changes + +- Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 + ## 0.0.2 ### Patch Changes diff --git a/tests/test-projects/basic/package.json b/tests/test-projects/basic/package.json index ef134c60847..034d10a328c 100644 --- a/tests/test-projects/basic/package.json +++ b/tests/test-projects/basic/package.json @@ -1,6 +1,6 @@ { "name": "@keystone-next/test-projects-basic", - "version": "0.0.2", + "version": "0.0.3", "private": true, "license": "MIT", "scripts": { @@ -9,8 +9,8 @@ "build": "keystone-next build" }, "dependencies": { - "@keystone-next/fields": "^13.0.0", - "@keystone-next/keystone": "^23.0.0" + "@keystone-next/fields": "^14.0.0", + "@keystone-next/keystone": "^24.0.0" }, "devDependencies": { "typescript": "^4.3.5" diff --git a/tests/test-projects/basic/schema.graphql b/tests/test-projects/basic/schema.graphql index 49a0f225167..e194b7cb406 100644 --- a/tests/test-projects/basic/schema.graphql +++ b/tests/test-projects/basic/schema.graphql @@ -16,36 +16,75 @@ enum TaskPriorityType { input TaskWhereInput { AND: [TaskWhereInput!] OR: [TaskWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - label: String - label_not: String - label_contains: String - label_not_contains: String - label_in: [String] - label_not_in: [String] - priority: TaskPriorityType - priority_not: TaskPriorityType - priority_in: [TaskPriorityType] - priority_not_in: [TaskPriorityType] - isComplete: Boolean - isComplete_not: Boolean + NOT: [TaskWhereInput!] + id: IDFilter + label: StringNullableFilter + priority: TaskPriorityTypeNullableFilter + isComplete: BooleanNullableFilter assignedTo: PersonWhereInput - assignedTo_is_null: Boolean - finishBy: String - finishBy_not: String - finishBy_lt: String - finishBy_lte: String - finishBy_gt: String - finishBy_gte: String - finishBy_in: [String] - finishBy_not_in: [String] + finishBy: DateTimeNullableFilter +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input TaskPriorityTypeNullableFilter { + equals: TaskPriorityType + in: [TaskPriorityType!] + notIn: [TaskPriorityType!] + not: TaskPriorityTypeNullableFilter +} + +input BooleanNullableFilter { + equals: Boolean + not: BooleanNullableFilter +} + +input DateTimeNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + not: DateTimeNullableFilter } input TaskWhereUniqueInput { @@ -103,7 +142,7 @@ type Person { tasks( where: TaskWhereInput! = {} orderBy: [TaskOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Task!] tasksCount(where: TaskWhereInput! = {}): Int @@ -112,23 +151,16 @@ type Person { input PersonWhereInput { AND: [PersonWhereInput!] OR: [PersonWhereInput!] - id: ID - id_not: ID - id_lt: ID - id_lte: ID - id_gt: ID - id_gte: ID - id_in: [ID!] - id_not_in: [ID!] - name: String - name_not: String - name_contains: String - name_not_contains: String - name_in: [String] - name_not_in: [String] - tasks_every: TaskWhereInput - tasks_some: TaskWhereInput - tasks_none: TaskWhereInput + NOT: [PersonWhereInput!] + id: IDFilter + name: StringNullableFilter + tasks: TaskManyRelationFilter +} + +input TaskManyRelationFilter { + every: TaskWhereInput + some: TaskWhereInput + none: TaskWhereInput } input PersonWhereUniqueInput { @@ -194,7 +226,7 @@ type Query { tasks( where: TaskWhereInput! = {} orderBy: [TaskOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Task!] task(where: TaskWhereUniqueInput!): Task @@ -202,7 +234,7 @@ type Query { people( where: PersonWhereInput! = {} orderBy: [PersonOrderByInput!]! = [] - first: Int + take: Int skip: Int! = 0 ): [Person!] person(where: PersonWhereUniqueInput!): Person diff --git a/tests/test-projects/crud-notifications/CHANGELOG.md b/tests/test-projects/crud-notifications/CHANGELOG.md new file mode 100644 index 00000000000..4315359a821 --- /dev/null +++ b/tests/test-projects/crud-notifications/CHANGELOG.md @@ -0,0 +1,8 @@ +# @keystone-next/test-projects-crud-notifications + +## 0.0.3 +### Patch Changes + +- Updated dependencies [[`e9f3c42d5`](https://github.com/keystonejs/keystone/commit/e9f3c42d5b9d42872cecbd18fbe9bf9d7d53ed82), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`1cbcf54cb`](https://github.com/keystonejs/keystone/commit/1cbcf54cb1206461866b582865e3b1a8fc728f18), [`a92169d04`](https://github.com/keystonejs/keystone/commit/a92169d04e5a1a98deb8e757b8eae3b06fc66450), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`b696a9579`](https://github.com/keystonejs/keystone/commit/b696a9579b503db86f42776381e247c4e1a7409f), [`f3014a627`](https://github.com/keystonejs/keystone/commit/f3014a627060c7cd86440a6937da5caecfd023a0), [`092df6678`](https://github.com/keystonejs/keystone/commit/092df6678cea18d639be16ad250ec4ecc9250f5a), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`6da56b80e`](https://github.com/keystonejs/keystone/commit/6da56b80e03c748a621afcca6c1ec2887fef7271), [`4f4f0351a`](https://github.com/keystonejs/keystone/commit/4f4f0351a056dea9d1614aa2a3a4789d66bb402d), [`697efa354`](https://github.com/keystonejs/keystone/commit/697efa354b1066b3d4b6eb757ca704b458f45e93), [`c7e331d90`](https://github.com/keystonejs/keystone/commit/c7e331d90a28b2ed8236100097cb8d34a11fabe2), [`3a7a06b2c`](https://github.com/keystonejs/keystone/commit/3a7a06b2cc6b5ea157d34d925b15494b471899eb), [`272b97b3a`](https://github.com/keystonejs/keystone/commit/272b97b3a10c0dfada782171d55ef7ac6f47c98f), [`78dac764e`](https://github.com/keystonejs/keystone/commit/78dac764e1860b33f9e2bd8cee6015abeaaa5ec4), [`399561b27`](https://github.com/keystonejs/keystone/commit/399561b2769ddd8f3d3fdf29838f5784404bb053), [`9d361c1c8`](https://github.com/keystonejs/keystone/commit/9d361c1c8625e1390f837b7318b63547d686a63b), [`0dcb1c95b`](https://github.com/keystonejs/keystone/commit/0dcb1c95b5200750cc8649485425f2ae40d023a3), [`94435ffee`](https://github.com/keystonejs/keystone/commit/94435ffee765824091899242e4a2f73c7356b524), [`5cd8ffd6c`](https://github.com/keystonejs/keystone/commit/5cd8ffd6cb822dbee8555b47846a5019c4d2b1c3), [`56044e2a4`](https://github.com/keystonejs/keystone/commit/56044e2a425f4256b66475fd3b1a6342cd6c3bf9), [`f46fd32b7`](https://github.com/keystonejs/keystone/commit/f46fd32b7047dbb5ea2566859f7ecee8db5b0b15), [`874f2c405`](https://github.com/keystonejs/keystone/commit/874f2c4058c9cf006213e84b9ffcf39c5bf144e8), [`8ea4eed55`](https://github.com/keystonejs/keystone/commit/8ea4eed55367aaa213f6b4ffb7473087498e39ae), [`e3fe6498d`](https://github.com/keystonejs/keystone/commit/e3fe6498dc36203d8080dff3c2e0c25f6c98733e), [`1030296d1`](https://github.com/keystonejs/keystone/commit/1030296d1f304dc44246e895089ac1f992e80590), [`3564b342d`](https://github.com/keystonejs/keystone/commit/3564b342d6dc2127ae591d7ac055af9eae90543c), [`8b2d179b2`](https://github.com/keystonejs/keystone/commit/8b2d179b2463d78b082182ca9afa8233109e0ba3), [`e3fefafcc`](https://github.com/keystonejs/keystone/commit/e3fefafcce6f8bf836c9bf0f4d931b8200ba41c7), [`4d9f89f88`](https://github.com/keystonejs/keystone/commit/4d9f89f884e2bf984fdd74ca2cbb7874b25b9cda), [`686c0f1c4`](https://github.com/keystonejs/keystone/commit/686c0f1c4a1feb609e1584aa71738709bbbf984e), [`d214e2f72`](https://github.com/keystonejs/keystone/commit/d214e2f72bae1c798e2415a38410d6063c333e2e), [`f5e64af37`](https://github.com/keystonejs/keystone/commit/f5e64af37df2eb460c89d89fa3c8924fb34970ed)]: + - @keystone-next/fields@14.0.0 + - @keystone-next/keystone@24.0.0 diff --git a/tests/test-projects/crud-notifications/README.md b/tests/test-projects/crud-notifications/README.md new file mode 100644 index 00000000000..60e641288cb --- /dev/null +++ b/tests/test-projects/crud-notifications/README.md @@ -0,0 +1,4 @@ +## THIS IS A TEST PROJECT + +The sole purpose of this project is to act as a fixture through which we run our admin-ui integration tests. +For useful and applicable examples of how to use keystone, please visit the [examples directory](https://github.com/keystonejs/keystone/tree/master/examples/) or visit our [docs](https://next.keystonejs.com). diff --git a/tests/test-projects/crud-notifications/keystone.ts b/tests/test-projects/crud-notifications/keystone.ts new file mode 100644 index 00000000000..87ce93e9453 --- /dev/null +++ b/tests/test-projects/crud-notifications/keystone.ts @@ -0,0 +1,23 @@ +import { config } from '@keystone-next/keystone/schema'; +import { lists } from './schema'; + +export default config({ + db: { + provider: 'sqlite', + url: process.env.DATABASE_URL || 'file:./test.db', + async onConnect(context) { + await context.lists.Task.createMany({ + data: [...Array.from(Array(50).keys())].map(key => { + return { label: `do not delete ${key}` }; + }), + }); + + await context.lists.Task.createMany({ + data: [...Array.from(Array(25).keys())].map(key => { + return { label: `deletable ${key}` }; + }), + }); + }, + }, + lists, +}); diff --git a/tests/test-projects/crud-notifications/package.json b/tests/test-projects/crud-notifications/package.json new file mode 100644 index 00000000000..585846b3c43 --- /dev/null +++ b/tests/test-projects/crud-notifications/package.json @@ -0,0 +1,22 @@ +{ + "name": "@keystone-next/test-projects-crud-notifications", + "version": "0.0.3", + "private": true, + "license": "MIT", + "scripts": { + "dev": "keystone-next dev", + "start": "keystone-next start", + "build": "keystone-next build" + }, + "dependencies": { + "@keystone-next/fields": "^14.0.0", + "@keystone-next/keystone": "^24.0.0" + }, + "devDependencies": { + "typescript": "^4.3.5" + }, + "engines": { + "node": "^12.20 || >= 14.13" + }, + "repository": "https://github.com/keystonejs/keystone/tree/master/tests/test-projects/crud-notifications" +} diff --git a/tests/test-projects/crud-notifications/schema.graphql b/tests/test-projects/crud-notifications/schema.graphql new file mode 100644 index 00000000000..e194b7cb406 --- /dev/null +++ b/tests/test-projects/crud-notifications/schema.graphql @@ -0,0 +1,329 @@ +type Task { + id: ID! + label: String + priority: TaskPriorityType + isComplete: Boolean + assignedTo: Person + finishBy: String +} + +enum TaskPriorityType { + low + medium + high +} + +input TaskWhereInput { + AND: [TaskWhereInput!] + OR: [TaskWhereInput!] + NOT: [TaskWhereInput!] + id: IDFilter + label: StringNullableFilter + priority: TaskPriorityTypeNullableFilter + isComplete: BooleanNullableFilter + assignedTo: PersonWhereInput + finishBy: DateTimeNullableFilter +} + +input IDFilter { + equals: ID + in: [ID!] + notIn: [ID!] + lt: ID + lte: ID + gt: ID + gte: ID + not: IDFilter +} + +input StringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input NestedStringNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + contains: String + startsWith: String + endsWith: String + not: NestedStringNullableFilter +} + +input TaskPriorityTypeNullableFilter { + equals: TaskPriorityType + in: [TaskPriorityType!] + notIn: [TaskPriorityType!] + not: TaskPriorityTypeNullableFilter +} + +input BooleanNullableFilter { + equals: Boolean + not: BooleanNullableFilter +} + +input DateTimeNullableFilter { + equals: String + in: [String!] + notIn: [String!] + lt: String + lte: String + gt: String + gte: String + not: DateTimeNullableFilter +} + +input TaskWhereUniqueInput { + id: ID +} + +input TaskOrderByInput { + id: OrderDirection + label: OrderDirection + priority: OrderDirection + isComplete: OrderDirection + finishBy: OrderDirection +} + +enum OrderDirection { + asc + desc +} + +input TaskUpdateInput { + label: String + priority: TaskPriorityType + isComplete: Boolean + assignedTo: PersonRelateToOneForUpdateInput + finishBy: String +} + +input PersonRelateToOneForUpdateInput { + create: PersonCreateInput + connect: PersonWhereUniqueInput + disconnect: Boolean +} + +input TaskUpdateArgs { + where: TaskWhereUniqueInput! + data: TaskUpdateInput! +} + +input TaskCreateInput { + label: String + priority: TaskPriorityType + isComplete: Boolean + assignedTo: PersonRelateToOneForCreateInput + finishBy: String +} + +input PersonRelateToOneForCreateInput { + create: PersonCreateInput + connect: PersonWhereUniqueInput +} + +type Person { + id: ID! + name: String + tasks( + where: TaskWhereInput! = {} + orderBy: [TaskOrderByInput!]! = [] + take: Int + skip: Int! = 0 + ): [Task!] + tasksCount(where: TaskWhereInput! = {}): Int +} + +input PersonWhereInput { + AND: [PersonWhereInput!] + OR: [PersonWhereInput!] + NOT: [PersonWhereInput!] + id: IDFilter + name: StringNullableFilter + tasks: TaskManyRelationFilter +} + +input TaskManyRelationFilter { + every: TaskWhereInput + some: TaskWhereInput + none: TaskWhereInput +} + +input PersonWhereUniqueInput { + id: ID +} + +input PersonOrderByInput { + id: OrderDirection + name: OrderDirection +} + +input PersonUpdateInput { + name: String + tasks: TaskRelateToManyForUpdateInput +} + +input TaskRelateToManyForUpdateInput { + disconnect: [TaskWhereUniqueInput!] + set: [TaskWhereUniqueInput!] + create: [TaskCreateInput!] + connect: [TaskWhereUniqueInput!] +} + +input PersonUpdateArgs { + where: PersonWhereUniqueInput! + data: PersonUpdateInput! +} + +input PersonCreateInput { + name: String + tasks: TaskRelateToManyForCreateInput +} + +input TaskRelateToManyForCreateInput { + create: [TaskCreateInput!] + connect: [TaskWhereUniqueInput!] +} + +""" +The `JSON` scalar type represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf). +""" +scalar JSON + @specifiedBy( + url: "http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf" + ) + +type Mutation { + createTask(data: TaskCreateInput!): Task + createTasks(data: [TaskCreateInput!]!): [Task] + updateTask(where: TaskWhereUniqueInput!, data: TaskUpdateInput!): Task + updateTasks(data: [TaskUpdateArgs!]!): [Task] + deleteTask(where: TaskWhereUniqueInput!): Task + deleteTasks(where: [TaskWhereUniqueInput!]!): [Task] + createPerson(data: PersonCreateInput!): Person + createPeople(data: [PersonCreateInput!]!): [Person] + updatePerson(where: PersonWhereUniqueInput!, data: PersonUpdateInput!): Person + updatePeople(data: [PersonUpdateArgs!]!): [Person] + deletePerson(where: PersonWhereUniqueInput!): Person + deletePeople(where: [PersonWhereUniqueInput!]!): [Person] +} + +type Query { + tasks( + where: TaskWhereInput! = {} + orderBy: [TaskOrderByInput!]! = [] + take: Int + skip: Int! = 0 + ): [Task!] + task(where: TaskWhereUniqueInput!): Task + tasksCount(where: TaskWhereInput! = {}): Int + people( + where: PersonWhereInput! = {} + orderBy: [PersonOrderByInput!]! = [] + take: Int + skip: Int! = 0 + ): [Person!] + person(where: PersonWhereUniqueInput!): Person + peopleCount(where: PersonWhereInput! = {}): Int + keystone: KeystoneMeta! +} + +type KeystoneMeta { + adminMeta: KeystoneAdminMeta! +} + +type KeystoneAdminMeta { + enableSignout: Boolean! + enableSessionItem: Boolean! + lists: [KeystoneAdminUIListMeta!]! + list(key: String!): KeystoneAdminUIListMeta +} + +type KeystoneAdminUIListMeta { + key: String! + itemQueryName: String! + listQueryName: String! + hideCreate: Boolean! + hideDelete: Boolean! + path: String! + label: String! + singular: String! + plural: String! + description: String + initialColumns: [String!]! + pageSize: Int! + labelField: String! + fields: [KeystoneAdminUIFieldMeta!]! + initialSort: KeystoneAdminUISort + isHidden: Boolean! +} + +type KeystoneAdminUIFieldMeta { + path: String! + label: String! + isOrderable: Boolean! + fieldMeta: JSON + viewsIndex: Int! + customViewsIndex: Int + createView: KeystoneAdminUIFieldMetaCreateView! + listView: KeystoneAdminUIFieldMetaListView! + itemView(id: ID!): KeystoneAdminUIFieldMetaItemView + search: QueryMode +} + +type KeystoneAdminUIFieldMetaCreateView { + fieldMode: KeystoneAdminUIFieldMetaCreateViewFieldMode! +} + +enum KeystoneAdminUIFieldMetaCreateViewFieldMode { + edit + hidden +} + +type KeystoneAdminUIFieldMetaListView { + fieldMode: KeystoneAdminUIFieldMetaListViewFieldMode! +} + +enum KeystoneAdminUIFieldMetaListViewFieldMode { + read + hidden +} + +type KeystoneAdminUIFieldMetaItemView { + fieldMode: KeystoneAdminUIFieldMetaItemViewFieldMode! +} + +enum KeystoneAdminUIFieldMetaItemViewFieldMode { + edit + read + hidden +} + +enum QueryMode { + default + insensitive +} + +type KeystoneAdminUISort { + field: String! + direction: KeystoneAdminUISortDirection! +} + +enum KeystoneAdminUISortDirection { + ASC + DESC +} diff --git a/tests/test-projects/crud-notifications/schema.prisma b/tests/test-projects/crud-notifications/schema.prisma new file mode 100644 index 00000000000..a1efaced2f7 --- /dev/null +++ b/tests/test-projects/crud-notifications/schema.prisma @@ -0,0 +1,27 @@ +datasource sqlite { + url = env("DATABASE_URL") + provider = "sqlite" +} + +generator client { + provider = "prisma-client-js" + output = "node_modules/.prisma/client" +} + +model Task { + id String @id @default(cuid()) + label String? + priority String? + isComplete Boolean? + assignedTo Person? @relation("Task_assignedTo", fields: [assignedToId], references: [id]) + assignedToId String? @map("assignedTo") + finishBy DateTime? + + @@index([assignedToId]) +} + +model Person { + id String @id @default(cuid()) + name String? + tasks Task[] @relation("Task_assignedTo") +} \ No newline at end of file diff --git a/tests/test-projects/crud-notifications/schema.ts b/tests/test-projects/crud-notifications/schema.ts new file mode 100644 index 00000000000..8cc4f22288c --- /dev/null +++ b/tests/test-projects/crud-notifications/schema.ts @@ -0,0 +1,38 @@ +import { createSchema, list } from '@keystone-next/keystone/schema'; +import { checkbox, relationship, text, timestamp } from '@keystone-next/fields'; +import { select } from '@keystone-next/fields'; + +export const lists = createSchema({ + Task: list({ + access: { + delete: async ({ itemId, context }) => { + const item: any = await context.lists.Task.findOne({ + where: { id: itemId }, + query: 'label', + }); + const matchString = item.label.replace(/([\d])+/g, '').trim(); + return !['do not delete', 'do not destroy', 'do not kill'].includes(matchString); + }, + }, + fields: { + label: text({ isRequired: true }), + priority: select({ + dataType: 'enum', + options: [ + { label: 'Low', value: 'low' }, + { label: 'Medium', value: 'medium' }, + { label: 'High', value: 'high' }, + ], + }), + isComplete: checkbox(), + assignedTo: relationship({ ref: 'Person.tasks', many: false }), + finishBy: timestamp(), + }, + }), + Person: list({ + fields: { + name: text({ isRequired: true }), + tasks: relationship({ ref: 'Task.assignedTo', many: true }), + }, + }), +}); diff --git a/yarn.lock b/yarn.lock index 034e47534e3..0bebeff4aac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,24 +2,23 @@ # yarn lockfile v1 -"@apollo/client@3.3.21", "@apollo/client@^3.1.3": - version "3.3.21" - resolved "https://registry.yarnpkg.com/@apollo/client/-/client-3.3.21.tgz#2862baa4e1ced8c5e89ebe6fc52877fc64a726aa" - integrity sha512-RAmZReFuKCKx0Rs5C0nVJwKomAHUHn+gGP/YvbEsXQWu0sXoncEUZa71UqlfCPVXa/0MkYOIbCXSQdOcuRrHgw== +"@apollo/client@^3.1.3", "@apollo/client@^3.4.8": + version "3.4.8" + resolved "https://registry.yarnpkg.com/@apollo/client/-/client-3.4.8.tgz#66d06dc1784d07d46731b3bda546046f8c280b74" + integrity sha512-/cNqTSwc2Dw8q6FDDjdd30+yvhP7rI0Fvl3Hbro0lTtFuhzkevfNyQaI2jAiOrjU6Jc0RbanxULaNrX7UmvjSQ== dependencies: "@graphql-typed-document-node/core" "^3.0.0" - "@types/zen-observable" "^0.8.0" "@wry/context" "^0.6.0" "@wry/equality" "^0.5.0" - fast-json-stable-stringify "^2.0.0" - graphql-tag "^2.12.0" + "@wry/trie" "^0.3.0" + graphql-tag "^2.12.3" hoist-non-react-statics "^3.3.2" - optimism "^0.16.0" + optimism "^0.16.1" prop-types "^15.7.2" symbol-observable "^4.0.0" - ts-invariant "^0.8.0" - tslib "^1.10.0" - zen-observable "^0.8.14" + ts-invariant "^0.9.0" + tslib "^2.3.0" + zen-observable-ts "^1.1.0" "@apollo/protobufjs@1.2.2": version "1.2.2" @@ -79,25 +78,25 @@ dependencies: "@babel/highlight" "^7.14.5" -"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.14.5", "@babel/compat-data@^7.14.7", "@babel/compat-data@^7.14.9": - version "7.14.9" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.9.tgz#ac7996ceaafcf8f410119c8af0d1db4cf914a210" - integrity sha512-p3QjZmMGHDGdpcwEYYWu7i7oJShJvtgMjJeb0W95PPhSm++3lm8YXYOh45Y6iCN9PkZLTZ7CIX5nFrp7pw7TXw== +"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.14.7", "@babel/compat-data@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.15.0.tgz#2dbaf8b85334796cafbb0f5793a90a2fc010b176" + integrity sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA== -"@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.14.8", "@babel/core@^7.7.2", "@babel/core@^7.7.5", "@babel/core@^7.7.7": - version "7.14.8" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.8.tgz#20cdf7c84b5d86d83fac8710a8bc605a7ba3f010" - integrity sha512-/AtaeEhT6ErpDhInbXmjHcUQXH0L0TEgscfcxk1qbOvLuKCa5aZT0SOOtDKFY96/CLROwbLSKyFor6idgNaU4Q== +"@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.15.0", "@babel/core@^7.7.2", "@babel/core@^7.7.5", "@babel/core@^7.7.7": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.15.0.tgz#749e57c68778b73ad8082775561f67f5196aafa8" + integrity sha512-tXtmTminrze5HEUPn/a0JtOzzfp0nk+UEXQ/tqIJo3WDGypl/2OFQEMll/zSFU8f/lfmfLXvTaORHF3cfXIQMw== dependencies: "@babel/code-frame" "^7.14.5" - "@babel/generator" "^7.14.8" - "@babel/helper-compilation-targets" "^7.14.5" - "@babel/helper-module-transforms" "^7.14.8" + "@babel/generator" "^7.15.0" + "@babel/helper-compilation-targets" "^7.15.0" + "@babel/helper-module-transforms" "^7.15.0" "@babel/helpers" "^7.14.8" - "@babel/parser" "^7.14.8" + "@babel/parser" "^7.15.0" "@babel/template" "^7.14.5" - "@babel/traverse" "^7.14.8" - "@babel/types" "^7.14.8" + "@babel/traverse" "^7.15.0" + "@babel/types" "^7.15.0" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" @@ -105,12 +104,12 @@ semver "^6.3.0" source-map "^0.5.0" -"@babel/generator@^7.14.8", "@babel/generator@^7.14.9", "@babel/generator@^7.7.2": - version "7.14.9" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.9.tgz#23b19c597d38b4f7dc2e3fe42a69c88d9ecfaa16" - integrity sha512-4yoHbhDYzFa0GLfCzLp5GxH7vPPMAHdZjyE7M/OajM9037zhx0rf+iNsJwp4PT0MSFpwjG7BsHEbPkBQpZ6cYA== +"@babel/generator@^7.15.0", "@babel/generator@^7.7.2": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.15.0.tgz#a7d0c172e0d814974bad5aa77ace543b97917f15" + integrity sha512-eKl4XdMrbpYvuB505KTta4AV9g+wWzmVBW69tX0H2NwKVKd2YJbKgyK6M8j/rgLbmHOYJn6rUklV677nOyJrEQ== dependencies: - "@babel/types" "^7.14.9" + "@babel/types" "^7.15.0" jsesc "^2.5.1" source-map "^0.5.0" @@ -129,26 +128,26 @@ "@babel/helper-explode-assignable-expression" "^7.14.5" "@babel/types" "^7.14.5" -"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz#7a99c5d0967911e972fe2c3411f7d5b498498ecf" - integrity sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw== +"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.14.5", "@babel/helper-compilation-targets@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.0.tgz#973df8cbd025515f3ff25db0c05efc704fa79818" + integrity sha512-h+/9t0ncd4jfZ8wsdAsoIxSa61qhBYlycXiHWqJaQBCXAhDCMbPRSMTGnZIkkmt1u4ag+UQmuqcILwqKzZ4N2A== dependencies: - "@babel/compat-data" "^7.14.5" + "@babel/compat-data" "^7.15.0" "@babel/helper-validator-option" "^7.14.5" browserslist "^4.16.6" semver "^6.3.0" -"@babel/helper-create-class-features-plugin@^7.14.5", "@babel/helper-create-class-features-plugin@^7.14.6": - version "7.14.8" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.8.tgz#a6f8c3de208b1e5629424a9a63567f56501955fc" - integrity sha512-bpYvH8zJBWzeqi1o+co8qOrw+EXzQ/0c74gVmY205AWXy9nifHrOg77y+1zwxX5lXE7Icq4sPlSQ4O2kWBrteQ== +"@babel/helper-create-class-features-plugin@^7.14.5", "@babel/helper-create-class-features-plugin@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.15.0.tgz#c9a137a4d137b2d0e2c649acf536d7ba1a76c0f7" + integrity sha512-MdmDXgvTIi4heDVX/e9EFfeGpugqm9fobBVg/iioE8kueXrOHdRDe36FAY7SnE9xXLVeYCoJR/gdrBEIHRC83Q== dependencies: "@babel/helper-annotate-as-pure" "^7.14.5" "@babel/helper-function-name" "^7.14.5" - "@babel/helper-member-expression-to-functions" "^7.14.7" + "@babel/helper-member-expression-to-functions" "^7.15.0" "@babel/helper-optimise-call-expression" "^7.14.5" - "@babel/helper-replace-supers" "^7.14.5" + "@babel/helper-replace-supers" "^7.15.0" "@babel/helper-split-export-declaration" "^7.14.5" "@babel/helper-create-regexp-features-plugin@^7.14.5": @@ -203,12 +202,12 @@ dependencies: "@babel/types" "^7.14.5" -"@babel/helper-member-expression-to-functions@^7.14.5", "@babel/helper-member-expression-to-functions@^7.14.7": - version "7.14.7" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz#97e56244beb94211fe277bd818e3a329c66f7970" - integrity sha512-TMUt4xKxJn6ccjcOW7c4hlwyJArizskAhoSTOCkA0uZ+KghIaci0Qg9R043kUMWI9mtQfgny+NQ5QATnZ+paaA== +"@babel/helper-member-expression-to-functions@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.0.tgz#0ddaf5299c8179f27f37327936553e9bba60990b" + integrity sha512-Jq8H8U2kYiafuj2xMTPQwkTBnEEdGKpT35lJEQsRRjnG0LW3neucsaMWLgKcwu3OHKNeYugfw+Z20BXBSEs2Lg== dependencies: - "@babel/types" "^7.14.5" + "@babel/types" "^7.15.0" "@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.14.5": version "7.14.5" @@ -217,19 +216,19 @@ dependencies: "@babel/types" "^7.14.5" -"@babel/helper-module-transforms@^7.14.5", "@babel/helper-module-transforms@^7.14.8": - version "7.14.8" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.14.8.tgz#d4279f7e3fd5f4d5d342d833af36d4dd87d7dc49" - integrity sha512-RyE+NFOjXn5A9YU1dkpeBaduagTlZ0+fccnIcAGbv1KGUlReBj7utF7oEth8IdIBQPcux0DDgW5MFBH2xu9KcA== +"@babel/helper-module-transforms@^7.14.5", "@babel/helper-module-transforms@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.15.0.tgz#679275581ea056373eddbe360e1419ef23783b08" + integrity sha512-RkGiW5Rer7fpXv9m1B3iHIFDZdItnO2/BLfWVW/9q7+KqQSDY5kUfQEbzdXM1MVhJGcugKV7kRrNVzNxmk7NBg== dependencies: "@babel/helper-module-imports" "^7.14.5" - "@babel/helper-replace-supers" "^7.14.5" + "@babel/helper-replace-supers" "^7.15.0" "@babel/helper-simple-access" "^7.14.8" "@babel/helper-split-export-declaration" "^7.14.5" - "@babel/helper-validator-identifier" "^7.14.8" + "@babel/helper-validator-identifier" "^7.14.9" "@babel/template" "^7.14.5" - "@babel/traverse" "^7.14.8" - "@babel/types" "^7.14.8" + "@babel/traverse" "^7.15.0" + "@babel/types" "^7.15.0" "@babel/helper-optimise-call-expression@^7.14.5": version "7.14.5" @@ -252,17 +251,17 @@ "@babel/helper-wrap-function" "^7.14.5" "@babel/types" "^7.14.5" -"@babel/helper-replace-supers@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz#0ecc0b03c41cd567b4024ea016134c28414abb94" - integrity sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow== +"@babel/helper-replace-supers@^7.14.5", "@babel/helper-replace-supers@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.15.0.tgz#ace07708f5bf746bf2e6ba99572cce79b5d4e7f4" + integrity sha512-6O+eWrhx+HEra/uJnifCwhwMd6Bp5+ZfZeJwbqUTuqkhIT6YcRhiZCOOFChRypOIe0cV46kFrRBlm+t5vHCEaA== dependencies: - "@babel/helper-member-expression-to-functions" "^7.14.5" + "@babel/helper-member-expression-to-functions" "^7.15.0" "@babel/helper-optimise-call-expression" "^7.14.5" - "@babel/traverse" "^7.14.5" - "@babel/types" "^7.14.5" + "@babel/traverse" "^7.15.0" + "@babel/types" "^7.15.0" -"@babel/helper-simple-access@^7.14.5", "@babel/helper-simple-access@^7.14.8": +"@babel/helper-simple-access@^7.14.8": version "7.14.8" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.14.8.tgz#82e1fec0644a7e775c74d305f212c39f8fe73924" integrity sha512-TrFN4RHh9gnWEU+s7JloIho2T76GPwRHhdzOWLqTrMnlas8T9O7ec+oEDNsRXndOmru9ymH9DFrEOxpzPoSbdg== @@ -283,7 +282,7 @@ dependencies: "@babel/types" "^7.14.5" -"@babel/helper-validator-identifier@^7.14.5", "@babel/helper-validator-identifier@^7.14.8", "@babel/helper-validator-identifier@^7.14.9": +"@babel/helper-validator-identifier@^7.14.5", "@babel/helper-validator-identifier@^7.14.9": version "7.14.9" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz#6654d171b2024f6d8ee151bf2509699919131d48" integrity sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g== @@ -304,13 +303,13 @@ "@babel/types" "^7.14.5" "@babel/helpers@^7.14.8": - version "7.14.8" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.14.8.tgz#839f88f463025886cff7f85a35297007e2da1b77" - integrity sha512-ZRDmI56pnV+p1dH6d+UN6GINGz7Krps3+270qqI9UJ4wxYThfAIcI5i7j5vXC4FJ3Wap+S9qcebxeYiqn87DZw== + version "7.15.3" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.15.3.tgz#c96838b752b95dcd525b4e741ed40bb1dc2a1357" + integrity sha512-HwJiz52XaS96lX+28Tnbu31VeFSQJGOeKHJeaEPQlTl7PnlhFElWPj8tUXtqFIzeN86XxXoBr+WFAyK2PPVz6g== dependencies: "@babel/template" "^7.14.5" - "@babel/traverse" "^7.14.8" - "@babel/types" "^7.14.8" + "@babel/traverse" "^7.15.0" + "@babel/types" "^7.15.0" "@babel/highlight@^7.10.4", "@babel/highlight@^7.14.5": version "7.14.5" @@ -321,10 +320,10 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.5", "@babel/parser@^7.14.8", "@babel/parser@^7.14.9", "@babel/parser@^7.7.2": - version "7.14.9" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.9.tgz#596c1ad67608070058ebf8df50c1eaf65db895a4" - integrity sha512-RdUTOseXJ8POjjOeEBEvNMIZU/nm4yu2rufRkcibzkkg7DmQvXU8v3M4Xk9G7uuI86CDGkKcuDWgioqZm+mScQ== +"@babel/parser@^7.1.0", "@babel/parser@^7.14.5", "@babel/parser@^7.15.0", "@babel/parser@^7.7.2": + version "7.15.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.3.tgz#3416d9bea748052cfcb63dbcc27368105b1ed862" + integrity sha512-O0L6v/HvqbdJawj0iBEfVQMc3/6WP+AeOsovsIgBFyJaG+W2w7eqvZB7puddATmWuARlm1SX7DwxJ/JJUnDpEA== "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.14.5": version "7.14.5" @@ -519,7 +518,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.12.13", "@babel/plugin-syntax-jsx@^7.14.5": +"@babel/plugin-syntax-jsx@7.14.5", "@babel/plugin-syntax-jsx@^7.12.13", "@babel/plugin-syntax-jsx@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.14.5.tgz#000e2e25d8673cce49300517a3eda44c263e4201" integrity sha512-ohuFIsOMXJnbOMRfX7/w7LocdR6R7whhuRD4ax8IipLcLPlZGJKkBxgHp++U4N/vKyU16/YDQr2f5seajD3jIw== @@ -613,9 +612,9 @@ "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-transform-block-scoping@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.5.tgz#8cc63e61e50f42e078e6f09be775a75f23ef9939" - integrity sha512-LBYm4ZocNgoCqyxMLoOnwpsmQ18HWTQvql64t3GvMUzLQrNoV1BDG0lNftC8QKYERkZgCCT/7J5xWGObGAyHDw== + version "7.15.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.15.3.tgz#94c81a6e2fc230bcce6ef537ac96a1e4d2b3afaf" + integrity sha512-nBAzfZwZb4DkaGtOes1Up1nOAp9TDRRFw4XBzBBSG9QK7KVFmYzgj9o9sbPv7TX5ofL4Auq4wZnxCoPnI/lz2Q== dependencies: "@babel/helper-plugin-utils" "^7.14.5" @@ -707,14 +706,14 @@ "@babel/helper-plugin-utils" "^7.14.5" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-commonjs@^7.14.5", "@babel/plugin-transform-modules-commonjs@^7.7.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.14.5.tgz#7aaee0ea98283de94da98b28f8c35701429dad97" - integrity sha512-en8GfBtgnydoao2PS+87mKyw62k02k7kJ9ltbKe0fXTHrQmG6QZZflYuGI1VVG7sVpx4E1n7KBpNlPb8m78J+A== +"@babel/plugin-transform-modules-commonjs@^7.15.0", "@babel/plugin-transform-modules-commonjs@^7.7.5": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.15.0.tgz#3305896e5835f953b5cdb363acd9e8c2219a5281" + integrity sha512-3H/R9s8cXcOGE8kgMlmjYYC9nqr5ELiPkJn4q0mypBrjhYQoc+5/Maq69vV4xRPWnkzZuwJPf5rArxpB/35Cig== dependencies: - "@babel/helper-module-transforms" "^7.14.5" + "@babel/helper-module-transforms" "^7.15.0" "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-simple-access" "^7.14.5" + "@babel/helper-simple-access" "^7.14.8" babel-plugin-dynamic-import-node "^2.3.3" "@babel/plugin-transform-modules-systemjs@^7.14.5": @@ -773,9 +772,9 @@ "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-transform-react-display-name@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.14.5.tgz#baa92d15c4570411301a85a74c13534873885b65" - integrity sha512-07aqY1ChoPgIxsuDviptRpVkWCSbXWmzQqcgy65C6YSFOfPFvb/DX3bBRHh7pCd/PMEEYHYWUTSVkCbkVainYQ== + version "7.15.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.15.1.tgz#6aaac6099f1fcf6589d35ae6be1b6e10c8c602b9" + integrity sha512-yQZ/i/pUCJAHI/LbtZr413S3VT26qNrEm0M5RRxQJA947/YNYwbZbBaXGDrq6CG5QsZycI1VIP6d7pQaBfP+8Q== dependencies: "@babel/helper-plugin-utils" "^7.14.5" @@ -819,10 +818,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-runtime@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.14.5.tgz#30491dad49c6059f8f8fa5ee8896a0089e987523" - integrity sha512-fPMBhh1AV8ZyneiCIA+wYYUH1arzlXR1UMcApjvchDhfKxhy2r2lReJv8uHEyihi4IFIGlr1Pdx7S5fkESDQsg== +"@babel/plugin-transform-runtime@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.15.0.tgz#d3aa650d11678ca76ce294071fda53d7804183b3" + integrity sha512-sfHYkLGjhzWTq6xsuQ01oEsUYjkHRux9fW1iUA68dC7Qd8BS1Unq4aZ8itmQp95zUzIcyR2EbNMTzAicFj+guw== dependencies: "@babel/helper-module-imports" "^7.14.5" "@babel/helper-plugin-utils" "^7.14.5" @@ -867,12 +866,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-typescript@^7.14.5": - version "7.14.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.14.6.tgz#6e9c2d98da2507ebe0a883b100cde3c7279df36c" - integrity sha512-XlTdBq7Awr4FYIzqhmYY80WN0V0azF74DMPyFqVHBvf81ZUgc4X7ZOpx6O8eLDK6iM5cCQzeyJw0ynTaefixRA== +"@babel/plugin-transform-typescript@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.15.0.tgz#553f230b9d5385018716586fc48db10dd228eb7e" + integrity sha512-WIIEazmngMEEHDaPTx0IZY48SaAmjVWe3TRSX7cmJXn0bEv9midFzAjxiruOWYIVf5iQ10vFx7ASDpgEO08L5w== dependencies: - "@babel/helper-create-class-features-plugin" "^7.14.6" + "@babel/helper-create-class-features-plugin" "^7.15.0" "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-typescript" "^7.14.5" @@ -891,13 +890,13 @@ "@babel/helper-create-regexp-features-plugin" "^7.14.5" "@babel/helper-plugin-utils" "^7.14.5" -"@babel/preset-env@^7.14.9": - version "7.14.9" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.14.9.tgz#4a3bbbd745f20e9121d5925170bef040a21b7819" - integrity sha512-BV5JvCwBDebkyh67bPKBYVCC6gGw0MCzU6HfKe5Pm3upFpPVqiC/hB33zkOe0tVdAzaMywah0LSXQeD9v/BYdQ== +"@babel/preset-env@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.15.0.tgz#e2165bf16594c9c05e52517a194bf6187d6fe464" + integrity sha512-FhEpCNFCcWW3iZLg0L2NPE9UerdtsCR6ZcsGHUX6Om6kbCQeL5QZDqFDmeNHC6/fy6UH3jEge7K4qG5uC9In0Q== dependencies: - "@babel/compat-data" "^7.14.9" - "@babel/helper-compilation-targets" "^7.14.5" + "@babel/compat-data" "^7.15.0" + "@babel/helper-compilation-targets" "^7.15.0" "@babel/helper-plugin-utils" "^7.14.5" "@babel/helper-validator-option" "^7.14.5" "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.14.5" @@ -945,7 +944,7 @@ "@babel/plugin-transform-literals" "^7.14.5" "@babel/plugin-transform-member-expression-literals" "^7.14.5" "@babel/plugin-transform-modules-amd" "^7.14.5" - "@babel/plugin-transform-modules-commonjs" "^7.14.5" + "@babel/plugin-transform-modules-commonjs" "^7.15.0" "@babel/plugin-transform-modules-systemjs" "^7.14.5" "@babel/plugin-transform-modules-umd" "^7.14.5" "@babel/plugin-transform-named-capturing-groups-regex" "^7.14.9" @@ -963,7 +962,7 @@ "@babel/plugin-transform-unicode-escapes" "^7.14.5" "@babel/plugin-transform-unicode-regex" "^7.14.5" "@babel/preset-modules" "^0.1.4" - "@babel/types" "^7.14.9" + "@babel/types" "^7.15.0" babel-plugin-polyfill-corejs2 "^0.2.2" babel-plugin-polyfill-corejs3 "^0.2.2" babel-plugin-polyfill-regenerator "^0.2.2" @@ -993,19 +992,19 @@ "@babel/plugin-transform-react-jsx-development" "^7.14.5" "@babel/plugin-transform-react-pure-annotations" "^7.14.5" -"@babel/preset-typescript@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.14.5.tgz#aa98de119cf9852b79511f19e7f44a2d379bcce0" - integrity sha512-u4zO6CdbRKbS9TypMqrlGH7sd2TAJppZwn3c/ZRLeO/wGsbddxgbPDUZVNrie3JWYLQ9vpineKlsrWFvO6Pwkw== +"@babel/preset-typescript@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.15.0.tgz#e8fca638a1a0f64f14e1119f7fe4500277840945" + integrity sha512-lt0Y/8V3y06Wq/8H/u0WakrqciZ7Fz7mwPDHWUJAXlABL5hiUG42BNlRXiELNjeWjO5rWmnNKlx+yzJvxezHow== dependencies: "@babel/helper-plugin-utils" "^7.14.5" "@babel/helper-validator-option" "^7.14.5" - "@babel/plugin-transform-typescript" "^7.14.5" + "@babel/plugin-transform-typescript" "^7.15.0" "@babel/runtime-corejs3@^7.10.2": - version "7.14.9" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.14.9.tgz#fb21b1cf11650dcb8fcf4de2e6b3b8cf411da3f3" - integrity sha512-64RiH2ON4/y8qYtoa8rUiyam/tUVyGqRyNYhe+vCRGmjnV4bUlZvY+mwd0RrmLoCpJpdq3RsrNqKb7SJdw/4kw== + version "7.15.3" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.15.3.tgz#28754263988198f2a928c09733ade2fb4d28089d" + integrity sha512-30A3lP+sRL6ml8uhoJSs+8jwpKzbw8CqBvDc1laeptxPm5FahumJxirigcbD2qTs71Sonvj1cyZB0OKGAmxQ+A== dependencies: core-js-pure "^3.16.0" regenerator-runtime "^0.13.4" @@ -1017,10 +1016,10 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.14.8", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.7", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": - version "7.14.8" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.8.tgz#7119a56f421018852694290b9f9148097391b446" - integrity sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg== +"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.15.3", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.7", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": + version "7.15.3" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.3.tgz#2e1c2880ca118e5b2f9988322bd8a7656a32502b" + integrity sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA== dependencies: regenerator-runtime "^0.13.4" @@ -1033,21 +1032,29 @@ "@babel/parser" "^7.14.5" "@babel/types" "^7.14.5" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.13.0", "@babel/traverse@^7.14.5", "@babel/traverse@^7.14.8", "@babel/traverse@^7.7.2": - version "7.14.9" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.9.tgz#016126b331210bf06fff29d52971eef8383e556f" - integrity sha512-bldh6dtB49L8q9bUyB7bC20UKgU+EFDwKJylwl234Kv+ySZeMD31Xeht6URyueQ6LrRRpF2tmkfcZooZR9/e8g== +"@babel/traverse@^7.1.0", "@babel/traverse@^7.13.0", "@babel/traverse@^7.14.5", "@babel/traverse@^7.15.0", "@babel/traverse@^7.7.2": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.15.0.tgz#4cca838fd1b2a03283c1f38e141f639d60b3fc98" + integrity sha512-392d8BN0C9eVxVWd8H6x9WfipgVH5IaIoLp23334Sc1vbKKWINnvwRpb4us0xtPaCumlwbTtIYNA0Dv/32sVFw== dependencies: "@babel/code-frame" "^7.14.5" - "@babel/generator" "^7.14.9" + "@babel/generator" "^7.15.0" "@babel/helper-function-name" "^7.14.5" "@babel/helper-hoist-variables" "^7.14.5" "@babel/helper-split-export-declaration" "^7.14.5" - "@babel/parser" "^7.14.9" - "@babel/types" "^7.14.9" + "@babel/parser" "^7.15.0" + "@babel/types" "^7.15.0" debug "^4.1.0" globals "^11.1.0" +"@babel/types@7.15.0", "@babel/types@^7.0.0", "@babel/types@^7.12.6", "@babel/types@^7.14.5", "@babel/types@^7.14.8", "@babel/types@^7.14.9", "@babel/types@^7.15.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.0.tgz#61af11f2286c4e9c69ca8deb5f4375a73c72dcbd" + integrity sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ== + dependencies: + "@babel/helper-validator-identifier" "^7.14.9" + to-fast-properties "^2.0.0" + "@babel/types@7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.3.tgz#5a383dffa5416db1b73dedffd311ffd0788fb31c" @@ -1057,14 +1064,6 @@ lodash "^4.17.13" to-fast-properties "^2.0.0" -"@babel/types@^7.0.0", "@babel/types@^7.12.6", "@babel/types@^7.14.5", "@babel/types@^7.14.8", "@babel/types@^7.14.9", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": - version "7.14.9" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.9.tgz#f2b19c3f2f77c5708d67fe8f6046e9cea2b5036d" - integrity sha512-u0bLTnv3DFHeaQLYzb7oRJ1JHr1sv/SYDM7JSqHFFLwXG1wTZRughxFI5NCP8qBEo1rVVsn7Yg2Lvw49nne/Ow== - dependencies: - "@babel/helper-validator-identifier" "^7.14.9" - to-fast-properties "^2.0.0" - "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -1282,9 +1281,9 @@ prettier "^1.19.1" "@corex/deepmerge@^2.6.20": - version "2.6.20" - resolved "https://registry.yarnpkg.com/@corex/deepmerge/-/deepmerge-2.6.20.tgz#a72d1cb5a101fd11160815b96f499a588362ba5b" - integrity sha512-oZZxwDtV0bf8VPcSIhZPvdBFUkVIC8zRblUjrrVAsbGRiqUuZJfoXw2M6NDiIXWcUCfOqbkFND6Yf3b9ej9AjA== + version "2.6.34" + resolved "https://registry.yarnpkg.com/@corex/deepmerge/-/deepmerge-2.6.34.tgz#8dd084f2bcc9cf54f6b1210a1aebd25206de2a84" + integrity sha512-5l3bQRGOoCJ1nYTxEaOW/MRuwNDq32KYatWO5rwOlOzxY4beVCrxDBaDBX5wpDn0PYm0QAul/vAC9GDHShEbTw== "@cypress/listr-verbose-renderer@^0.4.1": version "0.4.1" @@ -1416,15 +1415,15 @@ resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.5.tgz#2c40f81449a4e554e9fc6396910ed4843ec2be50" integrity sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ== -"@emotion/react@^11.1.1", "@emotion/react@^11.4.0": - version "11.4.0" - resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.4.0.tgz#2465ad7b073a691409b88dfd96dc17097ddad9b7" - integrity sha512-4XklWsl9BdtatLoJpSjusXhpKv9YVteYKh9hPKP1Sxl+mswEFoUe0WtmtWjxEjkA51DQ2QRMCNOvKcSlCQ7ivg== +"@emotion/react@^11.1.1", "@emotion/react@^11.4.1": + version "11.4.1" + resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.4.1.tgz#a1b0b767b5bad57515ffb0cad9349614d27f4d57" + integrity sha512-pRegcsuGYj4FCdZN6j5vqCALkNytdrKw3TZMekTzNXixRg4wkLsU5QEaBG5LC6l01Vppxlp7FE3aTHpIG5phLg== dependencies: "@babel/runtime" "^7.13.10" "@emotion/cache" "^11.4.0" "@emotion/serialize" "^1.0.2" - "@emotion/sheet" "^1.0.1" + "@emotion/sheet" "^1.0.2" "@emotion/utils" "^1.0.0" "@emotion/weak-memoize" "^0.2.5" hoist-non-react-statics "^3.3.1" @@ -1466,10 +1465,10 @@ resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-0.9.4.tgz#894374bea39ec30f489bbfc3438192b9774d32e5" integrity sha512-zM9PFmgVSqBw4zL101Q0HrBVTGmpAxFZH/pYx/cjJT5advXguvcgjHFTCaIO3enL/xr89vK2bh0Mfyj9aa0ANA== -"@emotion/sheet@^1.0.0", "@emotion/sheet@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.0.1.tgz#245f54abb02dfd82326e28689f34c27aa9b2a698" - integrity sha512-GbIvVMe4U+Zc+929N1V7nW6YYJtidj31lidSmdYcWozwoBIObXBnaJkKNDjZrLm9Nc0BR+ZyHNaRZxqNZbof5g== +"@emotion/sheet@^1.0.0", "@emotion/sheet@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.0.2.tgz#1d9ffde531714ba28e62dac6a996a8b1089719d0" + integrity sha512-QQPB1B70JEVUHuNtzjHftMGv6eC3Y9wqavyarj4x4lg47RACkeSfNo5pxIOKizwS9AEFLohsqoaxGQj4p0vSIw== "@emotion/stylis@0.8.5": version "0.8.5" @@ -1511,36 +1510,35 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" -"@graphql-tools/merge@6.2.16", "@graphql-tools/merge@^6.2.16": - version "6.2.16" - resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-6.2.16.tgz#5dd5f582075c21ef4d74ef84dfcc4e8d0c2db186" - integrity sha512-KjZ1pppzKcr2Uspgb53p8uw5yhWVuGIL+sEroar7vLsClSsuiGib8OKVICAGWjC9wrCxGaL9SjJGavfXpJMQIg== +"@graphql-tools/merge@8.0.1": + version "8.0.1" + resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-8.0.1.tgz#4cb94998e7c61abc6ebec54edca5c19f06c3330d" + integrity sha512-YAozogbjC2Oun+UcwG0LZFumhlCiHBmqe68OIf7bqtBdp4pbPAiVuK/J9oJqRVJmzvUqugo6RD9zz1qDTKZaiQ== dependencies: - "@graphql-tools/schema" "^8.0.1" - "@graphql-tools/utils" "8.0.1" + "@graphql-tools/utils" "8.1.1" tslib "~2.3.0" -"@graphql-tools/schema@^8.0.1": - version "8.0.1" - resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-8.0.1.tgz#178b734f3784e632a76bdd144ffa8a32169a6f4a" - integrity sha512-QG2HGLJjmsNc1wcj+rwZTEArgfMp7rsrb8iVq4P8ce1mDYAt6kRV6bLyPVb9q/j8Ik2zBc/B/Y1jPsnAVUHwdA== +"@graphql-tools/schema@^8.1.1": + version "8.1.1" + resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-8.1.1.tgz#5de95a8f6cedaf91fa2f9e9e7fa9fae1d27a7c4f" + integrity sha512-u+0kxPtuP+GcKnGNt459Ob7iIpzesIJeJTmPPailaG7ZhB5hkXIizl4uHrzEIAh2Ja1P/VA8sEBYpu1N0n6Mmg== dependencies: - "@graphql-tools/merge" "6.2.16" - "@graphql-tools/utils" "8.0.1" + "@graphql-tools/merge" "8.0.1" + "@graphql-tools/utils" "8.1.1" tslib "~2.3.0" value-or-promise "1.0.10" -"@graphql-tools/utils@8.0.1": - version "8.0.1" - resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-8.0.1.tgz#bf09e8d6d17c4a0830f0fbf2c69dd725de19058c" - integrity sha512-gjQk6sht4b0/hcG+QEVxfMyO8bn5tuU1nIOVhQ4whgFaUmrnb3hx2mwzz1EJzfIOAuHKE8tY0lu6jt3bGTD4yg== +"@graphql-tools/utils@8.1.1": + version "8.1.1" + resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-8.1.1.tgz#2ef056a1d6e1e909085e1115d3bb48f890c2a2b6" + integrity sha512-QbFNoBmBiZ+ej4y6mOv8Ba4lNhcrTEKXAhZ0f74AhdEXi7b9xbGUH/slO5JaSyp85sGQYIPmxjRPpXBjLklbmw== dependencies: tslib "~2.3.0" -"@graphql-ts/schema@0.1.2": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@graphql-ts/schema/-/schema-0.1.2.tgz#71b04cc88ff61f5c19a81ac70f878b1e36f617da" - integrity sha512-ZP4Nj70B18q1Y7B4WHeJR5gMyoH8oX9umnpmT9gu6kUD9rmTZfqHE9cGHRisw+ZOlWBnx6rPrx0BmUROFQFORA== +"@graphql-ts/schema@0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@graphql-ts/schema/-/schema-0.2.0.tgz#1fc11a985cd5b0534de6616abcf05b0b493b8252" + integrity sha512-4hLQW5RfJkSkqia3Tl/LRVjsIGziTN/fHsUEuSIg1quD0y3pPpQxisDAIt4nkevY53q+JuGSVG1isJz+v8Ym/g== dependencies: "@babel/runtime" "^7.9.2" @@ -1794,17 +1792,6 @@ source-map "^0.6.1" write-file-atomic "^3.0.0" -"@jest/types@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" - integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^15.0.0" - chalk "^4.0.0" - "@jest/types@^27.0.6": version "27.0.6" resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.0.6.tgz#9a992bc517e0c49f035938b8549719c2de40706b" @@ -1914,21 +1901,36 @@ call-me-maybe "^1.0.1" glob-to-regexp "^0.3.0" +"@napi-rs/triples@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@napi-rs/triples/-/triples-1.0.3.tgz#76d6d0c3f4d16013c61e45dfca5ff1e6c31ae53c" + integrity sha512-jDJTpta+P4p1NZTFVLHJ/TLFVYVcOqv6l8xwOeBKNPMgY/zDYH/YH7SJbvrr/h1RcS9GzbPcLKGzpuK9cV56UA== + "@next/env@10.2.3": version "10.2.3" resolved "https://registry.yarnpkg.com/@next/env/-/env-10.2.3.tgz#ede3bbe68cec9939c37168ea2077f9adbc68334e" integrity sha512-uBOjRBjsWC4C8X3DfmWWP6ekwLnf2JCCwQX9KVnJtJkqfDsv1yQPakdOEwvJzXQc3JC/v5KKffYPVmV2wHXCgQ== -"@next/mdx@^10.2.3": - version "10.2.3" - resolved "https://registry.yarnpkg.com/@next/mdx/-/mdx-10.2.3.tgz#226d25530e4b98af3a200be3e2616beebf81b56c" - integrity sha512-hseekptFqOCxLbdaNDS/yelaG2Q2uaNDilnRjq8Uv/LWHuZ9F2cp7ndwTolW9acJsbDedamKRMgdw4V2Fz0pUA== +"@next/env@11.1.0": + version "11.1.0" + resolved "https://registry.yarnpkg.com/@next/env/-/env-11.1.0.tgz#cae83d8e0a65aa9f2af3368f8269ffd9d911746a" + integrity sha512-zPJkMFRenSf7BLlVee8987G0qQXAhxy7k+Lb/5hLAGkPVHAHm+oFFeL+2ipbI2KTEFlazdmGY0M+AlLQn7pWaw== + +"@next/mdx@^11.1.0": + version "11.1.0" + resolved "https://registry.yarnpkg.com/@next/mdx/-/mdx-11.1.0.tgz#79d6d20e0906e81c07aed0f8286d58530d051be6" + integrity sha512-X+NwSByGr9HuPkGs1nrzhmJ5qqQbv6CpEA3dJKEYHaDe7YzEUCM00Y7abxOzowXhUXeDdAHJ7IeIV4GZMhdcpg== "@next/polyfill-module@10.2.3": version "10.2.3" resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-10.2.3.tgz#5a29f50c3ce3a56b8268d3b8331c691d8039467a" integrity sha512-OkeY4cLhzfYbXxM4fd+6V4s5pTPuyfKSlavItfNRA6PpS7t1/R6YjO7S7rB8tu1pbTGuDHGIdE1ioDv15bAbDQ== +"@next/polyfill-module@11.1.0": + version "11.1.0" + resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-11.1.0.tgz#ee6b9117a1f9bb137479dfa51d5a9e38e066a62f" + integrity sha512-64EgW8SzJRQls2yJ5DkuljRxgE24o2kYtX/ghTkPUJYsfidHMWzQGwg26IgRbb/uHqTd1G0W5UkKag+Nt8TWaQ== + "@next/react-dev-overlay@10.2.3": version "10.2.3" resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-10.2.3.tgz#95313d10a8848f6c7b9e31ae3bd2a3627d136841" @@ -1946,11 +1948,40 @@ stacktrace-parser "0.1.10" strip-ansi "6.0.0" +"@next/react-dev-overlay@11.1.0": + version "11.1.0" + resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-11.1.0.tgz#8d4e8020a4cbdacbca431a0bf40c4d28187083af" + integrity sha512-h+ry0sTk1W3mJw+TwEf91aqLbBJ5oqAsxfx+QryqEItNtfW6zLSSjxkyTYTqX8DkgSssQQutQfATkzBVgOR+qQ== + dependencies: + "@babel/code-frame" "7.12.11" + anser "1.4.9" + chalk "4.0.0" + classnames "2.2.6" + css.escape "1.5.1" + data-uri-to-buffer "3.0.1" + platform "1.3.6" + shell-quote "1.7.2" + source-map "0.8.0-beta.0" + stacktrace-parser "0.1.10" + strip-ansi "6.0.0" + "@next/react-refresh-utils@10.2.3": version "10.2.3" resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-10.2.3.tgz#2f3e42fe6680798f276e3621345c2886b231348b" integrity sha512-qtBF56vPC6d6a8p7LYd0iRjW89fhY80kAIzmj+VonvIGjK/nymBjcFUhbKiMFqlhsarCksnhwX+Zmn95Dw9qvA== +"@next/react-refresh-utils@11.1.0": + version "11.1.0" + resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-11.1.0.tgz#60c3c7b127a5dab8b0a2889a7dcf8a90d2c4e592" + integrity sha512-g5DtFTpLTGa36iy9DuZawtJeitI11gysFGKPQQqy+mNbSFazguArcJ10gAYFlbqpIi4boUamWNI5mAoSPx3kog== + +"@node-rs/helper@1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@node-rs/helper/-/helper-1.2.1.tgz#e079b05f21ff4329d82c4e1f71c0290e4ecdc70c" + integrity sha512-R5wEmm8nbuQU0YGGmYVjEc0OHtYsuXdpRG+Ut/3wZ9XAvQWyThN08bTh2cBJgoZxHQUPtvRfeQuxcAgLuiBISg== + dependencies: + "@napi-rs/triples" "^1.0.3" + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -1989,10 +2020,10 @@ resolved "https://registry.yarnpkg.com/@opentelemetry/context-base/-/context-base-0.14.0.tgz#c67fc20a4d891447ca1a855d7d70fa79a3533001" integrity sha512-sDOAZcYwynHFTbLo6n8kIbLiVF3a3BLkrmehJUyEbT9F+Smbi47kLGS2gG2g0fjBLR/Lr1InPD7kXL7FaTqEkw== -"@popperjs/core@^2.9.2": - version "2.9.2" - resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.9.2.tgz#adea7b6953cbb34651766b0548468e743c6a2353" - integrity sha512-VZMYa7+fXHdwIq1TDhSXoVmSPEGM/aa+6Aiq3nVVJ9bXr24zScr+NlKFKC3iPljA7ho/GAZr+d2jOf5GIRC30Q== +"@popperjs/core@^2.9.3": + version "2.9.3" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.9.3.tgz#8b68da1ebd7fc603999cf6ebee34a4899a14b88e" + integrity sha512-xDu17cEfh7Kid/d95kB6tZsLOmSWKCZKtprnhVepjsSaCij+lM3mItSJDuuHDMbCWTh8Ejmebwb+KONcCJ0eXQ== "@preconstruct/cli@2.1.0": version "2.1.0" @@ -2059,20 +2090,12 @@ resolved "https://registry.yarnpkg.com/@preconstruct/next/-/next-3.0.0.tgz#71781cbaecd011f43e456a149817094a43e4755f" integrity sha512-G90cyJX9w4Zr3Bt/j2fURgDhsJb5+agqf4YUgrvDe3Dyvbbssy9a6d0tzLH0ehfa2Osxw/EEhQb+W4X+v/x06A== -"@prisma/client@2.28.0": - version "2.28.0" - resolved "https://registry.yarnpkg.com/@prisma/client/-/client-2.28.0.tgz#6cd91a3c2757814a9454ea23d7e33cd2ff3952db" - integrity sha512-iwdxpy0Nz8N40MnhdlRvhZOBk8+GawpEsY5FU8Tfw1k9rvIeTAi+wBHrqhY8bXq6pneZkzrdQ1Hj3tqkrbRmoQ== - dependencies: - "@prisma/engines-version" "2.28.0-17.89facabd0366f63911d089156a7a70125bfbcd27" - -"@prisma/debug@2.27.0": - version "2.27.0" - resolved "https://registry.yarnpkg.com/@prisma/debug/-/debug-2.27.0.tgz#ae4c565813011c6e6d29fbe948672f39bc4899d3" - integrity sha512-Et01S4RoLnQP9u547dCp74aSnLWTu0akfBCzF4zQZsbEdw7wXLttrcvbcYKr+KhpfF5Xu291UP/Kaxg0aj8o4w== +"@prisma/client@2.29.1": + version "2.29.1" + resolved "https://registry.yarnpkg.com/@prisma/client/-/client-2.29.1.tgz#a7b91c9644800de4e00b2f7c3789ff4bae42b3d6" + integrity sha512-GhieSvHGPIV5IwRYIkJ4FrGSNfX18lPhFtlyVWxhvX0ocdy8oTnjNZVTFgGxB6qVmJIUpH1HsckAzIoAX689IA== dependencies: - debug "4.3.2" - ms "^2.1.3" + "@prisma/engines-version" "2.29.0-34.1be4cd60b89afa04b192acb1ef47758a39810f3a" "@prisma/debug@2.28.0": version "2.28.0" @@ -2082,41 +2105,50 @@ debug "4.3.2" ms "^2.1.3" -"@prisma/engine-core@2.28.0": - version "2.28.0" - resolved "https://registry.yarnpkg.com/@prisma/engine-core/-/engine-core-2.28.0.tgz#9e1dcd11b88c55e48af292c272258a10cba8391f" - integrity sha512-J8lbA85PFpcwm2+u6bQHLomnbsrEnsJkq1PFrplthvJDlOK/tOl9CDuxU2IriJ9KHd+0Y0qaqcGmO+xXfFu3HA== +"@prisma/debug@2.29.1": + version "2.29.1" + resolved "https://registry.yarnpkg.com/@prisma/debug/-/debug-2.29.1.tgz#f5a6b480ea063844c6b1b40974402be8bda05fad" + integrity sha512-8OAh4ozVCvlcZU1HaP7QTWIA6Aqzs98nYgTYrxjDLqXJcytIvpIjHxfgqKhuPQ8MTkUm9cI5TJGswwcjJt0/0g== dependencies: - "@prisma/debug" "2.28.0" - "@prisma/engines" "2.28.0-17.89facabd0366f63911d089156a7a70125bfbcd27" - "@prisma/generator-helper" "2.28.0" - "@prisma/get-platform" "2.28.0-17.89facabd0366f63911d089156a7a70125bfbcd27" - chalk "^4.0.0" - execa "^5.0.0" - get-stream "^6.0.0" - indent-string "^4.0.0" - new-github-issue-url "^0.2.1" - p-retry "^4.2.0" - terminal-link "^2.1.1" + "@types/debug" "4.1.7" + debug "4.3.2" + ms "2.1.3" + +"@prisma/engine-core@2.29.1": + version "2.29.1" + resolved "https://registry.yarnpkg.com/@prisma/engine-core/-/engine-core-2.29.1.tgz#9fdb1fddea6d650a97ae1d86e8264d4b95dbe364" + integrity sha512-vbZNry916sErWIagF62kASy665Pe9xDYdOQuJ9Njg90sApg4qHPAmDqRC5cf4wQzWOnhnenmWC7AjUfQKrrFiQ== + dependencies: + "@prisma/debug" "2.29.1" + "@prisma/engines" "2.29.0-34.1be4cd60b89afa04b192acb1ef47758a39810f3a" + "@prisma/generator-helper" "2.29.1" + "@prisma/get-platform" "2.29.0-34.1be4cd60b89afa04b192acb1ef47758a39810f3a" + chalk "4.1.2" + execa "5.1.1" + get-stream "6.0.1" + indent-string "4.0.0" + new-github-issue-url "0.2.1" + p-retry "4.6.1" + terminal-link "2.1.1" undici "3.3.6" -"@prisma/engines-version@2.28.0-17.89facabd0366f63911d089156a7a70125bfbcd27": - version "2.28.0-17.89facabd0366f63911d089156a7a70125bfbcd27" - resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-2.28.0-17.89facabd0366f63911d089156a7a70125bfbcd27.tgz#6dbccdce64f792dbc21c99daef80ec03020c110d" - integrity sha512-BWTvF1mGxjG8EtG215uhxdeW5Uf5aiH4xhfzcFPFC3Ux5BdEM1uEBrLIixX67mI+ZNhqNZSBPf0DSf2I1IsaZw== +"@prisma/engines-version@2.29.0-34.1be4cd60b89afa04b192acb1ef47758a39810f3a": + version "2.29.0-34.1be4cd60b89afa04b192acb1ef47758a39810f3a" + resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-2.29.0-34.1be4cd60b89afa04b192acb1ef47758a39810f3a.tgz#96db92f09714d4dd2a5e21054c28bd1c0820fa77" + integrity sha512-BU1DNNDhdzqjHtycpUzDrU8+jf6ZY+fbXvCV/rbqG+0JifljlIo4vbkHDMg97gBi1Do8pTLZGlTH16FlniKgAg== -"@prisma/engines@2.28.0-17.89facabd0366f63911d089156a7a70125bfbcd27": - version "2.28.0-17.89facabd0366f63911d089156a7a70125bfbcd27" - resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-2.28.0-17.89facabd0366f63911d089156a7a70125bfbcd27.tgz#5a563ead03405fc6ccb33fe48f8b3a8712be391e" - integrity sha512-r3/EnwKjbu2qz13I98hPQQdeFrOEcwdjlrB9CcoSoqRCjSHLnpdVMUvRfYuRKIoEF7p941R7/Fov0/CxOLF/MQ== +"@prisma/engines@2.29.0-34.1be4cd60b89afa04b192acb1ef47758a39810f3a": + version "2.29.0-34.1be4cd60b89afa04b192acb1ef47758a39810f3a" + resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-2.29.0-34.1be4cd60b89afa04b192acb1ef47758a39810f3a.tgz#0a44a6dcbee7e0a2850ea086675a8a4f4d627f9d" + integrity sha512-cgEoGK3dmKZkMp/sRbL8TsuVS50rHXYBHk2NY18DPUGr5//4ICno46EjzlayqAFVak8J6RtWZEs+8tE8j8frAQ== -"@prisma/fetch-engine@2.28.0-17.89facabd0366f63911d089156a7a70125bfbcd27": - version "2.28.0-17.89facabd0366f63911d089156a7a70125bfbcd27" - resolved "https://registry.yarnpkg.com/@prisma/fetch-engine/-/fetch-engine-2.28.0-17.89facabd0366f63911d089156a7a70125bfbcd27.tgz#41de37f756e59dab8d50ecb5c7cdd521da19a689" - integrity sha512-o30L0+IrnK8ncT5qypnMW0AagpdTGCDL9eitDp59PA4KTPcfyusgcjcIgPm0qfcsiOrbvriBYCDmjXhNKNfaMA== +"@prisma/fetch-engine@2.29.0-34.1be4cd60b89afa04b192acb1ef47758a39810f3a": + version "2.29.0-34.1be4cd60b89afa04b192acb1ef47758a39810f3a" + resolved "https://registry.yarnpkg.com/@prisma/fetch-engine/-/fetch-engine-2.29.0-34.1be4cd60b89afa04b192acb1ef47758a39810f3a.tgz#de40f3bd761f3da1f2e0e0af027514c845f58264" + integrity sha512-HsTHffo2xg0rZchdqWJHDvl7JaOi2U1rDockKYAYPf3grGZ14AnJ/ZVP292xMm0IiGLkb5YE3qkI5SKoGEUqMw== dependencies: - "@prisma/debug" "2.27.0" - "@prisma/get-platform" "2.28.0-17.89facabd0366f63911d089156a7a70125bfbcd27" + "@prisma/debug" "2.28.0" + "@prisma/get-platform" "2.29.0-34.1be4cd60b89afa04b192acb1ef47758a39810f3a" chalk "^4.0.0" execa "^5.0.0" find-cache-dir "^3.3.1" @@ -2133,83 +2165,83 @@ temp-dir "^2.0.0" tempy "^1.0.0" -"@prisma/generator-helper@2.28.0": - version "2.28.0" - resolved "https://registry.yarnpkg.com/@prisma/generator-helper/-/generator-helper-2.28.0.tgz#5444f3c5bf8334f234ba25ca3c2360408e7a1495" - integrity sha512-KaDFroGSVfDJBQRoKdXmDvP93Ukj3gI9DVjtABlQFl5FII4VCtsOix76VK+h/Hej4p0yrU6LCCU24Jmw4Enksg== - dependencies: - "@prisma/debug" "2.28.0" - "@types/cross-spawn" "^6.0.1" - chalk "^4.0.0" - cross-spawn "^7.0.2" - -"@prisma/get-platform@2.28.0-17.89facabd0366f63911d089156a7a70125bfbcd27": - version "2.28.0-17.89facabd0366f63911d089156a7a70125bfbcd27" - resolved "https://registry.yarnpkg.com/@prisma/get-platform/-/get-platform-2.28.0-17.89facabd0366f63911d089156a7a70125bfbcd27.tgz#52904ae6b982fa162202220f7e03554daeacabca" - integrity sha512-OdTubLy4lVRYNvF3N9eODWxLxUhgh2oapDVvdMO3YmHQSeYQzzHHhYHBKoUY9zpCCAbAPBik+YIXgimJp3lqQQ== +"@prisma/generator-helper@2.29.1": + version "2.29.1" + resolved "https://registry.yarnpkg.com/@prisma/generator-helper/-/generator-helper-2.29.1.tgz#7bd984f649ba830d11fdd514f8781c92a2782e41" + integrity sha512-rba/mfxv1JtbAm51yXipYY7DVYB4L2DVVnnXOvSAhAqDLUVylT68WxLXQKiSBxNAlks5ngD2DeaH6qpGi+XnYw== dependencies: - "@prisma/debug" "2.27.0" + "@prisma/debug" "2.29.1" + "@types/cross-spawn" "6.0.2" + chalk "4.1.2" + cross-spawn "7.0.3" -"@prisma/migrate@2.28.0": - version "2.28.0" - resolved "https://registry.yarnpkg.com/@prisma/migrate/-/migrate-2.28.0.tgz#7923a463cb58ac1eb32d93cf0a828da3744c81a2" - integrity sha512-vWE8OSKDPIlfW8bJU98xm11s8nKtve77M7N8oJlktYL8pENHnSYoWcDynq/RZcZlf0Zb74OOmOJ7Qh6/WBO3DA== +"@prisma/get-platform@2.29.0-34.1be4cd60b89afa04b192acb1ef47758a39810f3a": + version "2.29.0-34.1be4cd60b89afa04b192acb1ef47758a39810f3a" + resolved "https://registry.yarnpkg.com/@prisma/get-platform/-/get-platform-2.29.0-34.1be4cd60b89afa04b192acb1ef47758a39810f3a.tgz#78e9200abdfa15446d4830c101e5b2d692bef7ab" + integrity sha512-eEuXFcELlo8bAszQOz3YOyVpoKMjD/RSml29P51WFaDaHZaudfqV6OkSpMV2Qchcyg6neI1mvT+0acutBpNXTw== dependencies: "@prisma/debug" "2.28.0" - "@prisma/get-platform" "2.28.0-17.89facabd0366f63911d089156a7a70125bfbcd27" - "@sindresorhus/slugify" "^1.1.0" - execa "^5.0.0" - global-dirs "^3.0.0" - has-yarn "^2.1.0" - indent-string "^4.0.0" - log-update "^4.0.0" - new-github-issue-url "^0.2.1" - open "^7.0.3" - pkg-up "^3.1.0" - prompts "^2.3.2" - resolve-pkg "^2.0.0" - strip-ansi "^6.0.0" - strip-indent "^3.0.0" -"@prisma/sdk@2.28.0": - version "2.28.0" - resolved "https://registry.yarnpkg.com/@prisma/sdk/-/sdk-2.28.0.tgz#8c2f3c3fbcc53bfb1eb68944fd023e8870a5be7c" - integrity sha512-JlZiuREFWoElZHbH4aJ5wqij1qQGQGnnu6h+hULX8ZQjzwreyfyQ36QTGNak6FPeR4cjjIpOsQqRxvKvhETalw== +"@prisma/migrate@2.29.1": + version "2.29.1" + resolved "https://registry.yarnpkg.com/@prisma/migrate/-/migrate-2.29.1.tgz#dc0be465ff89cdce4435c90938b25cd453b842c7" + integrity sha512-hIupZVHlHNByxCV+k7I5X3GaxV6pNYcQgPGbPphK8zOX0gDbRJIlJZ+L+uT5rz6GLIbCwzbW32sumxcWbk04WQ== dependencies: - "@prisma/debug" "2.28.0" - "@prisma/engine-core" "2.28.0" - "@prisma/engines" "2.28.0-17.89facabd0366f63911d089156a7a70125bfbcd27" - "@prisma/fetch-engine" "2.28.0-17.89facabd0366f63911d089156a7a70125bfbcd27" - "@prisma/generator-helper" "2.28.0" - "@prisma/get-platform" "2.28.0-17.89facabd0366f63911d089156a7a70125bfbcd27" - "@timsuchanek/copy" "^1.4.5" - archiver "^4.0.0" - arg "^5.0.0" - chalk "4.1.1" + "@prisma/debug" "2.29.1" + "@prisma/get-platform" "2.29.0-34.1be4cd60b89afa04b192acb1ef47758a39810f3a" + "@sindresorhus/slugify" "1.1.2" + execa "5.1.1" + global-dirs "3.0.0" + has-yarn "2.1.0" + indent-string "4.0.0" + log-update "4.0.0" + new-github-issue-url "0.2.1" + open "7.4.2" + pkg-up "3.1.0" + prompts "2.4.1" + resolve-pkg "2.0.0" + strip-ansi "6.0.0" + strip-indent "3.0.0" + +"@prisma/sdk@2.29.1": + version "2.29.1" + resolved "https://registry.yarnpkg.com/@prisma/sdk/-/sdk-2.29.1.tgz#1619f4f20847caa408c75b9e8175e6a2913c4184" + integrity sha512-vtcF5jdUskjalL5Q9iagbcc+vfwUa+DAQnNdYg0PtmpaS2llWezptvEJd2ihMR7O5m2sAmI87QDiCn9Y5FxNjQ== + dependencies: + "@prisma/debug" "2.29.1" + "@prisma/engine-core" "2.29.1" + "@prisma/engines" "2.29.0-34.1be4cd60b89afa04b192acb1ef47758a39810f3a" + "@prisma/fetch-engine" "2.29.0-34.1be4cd60b89afa04b192acb1ef47758a39810f3a" + "@prisma/generator-helper" "2.29.1" + "@prisma/get-platform" "2.29.0-34.1be4cd60b89afa04b192acb1ef47758a39810f3a" + "@timsuchanek/copy" "1.4.5" + archiver "4.0.2" + arg "5.0.0" + chalk "4.1.2" checkpoint-client "1.1.20" - cli-truncate "^2.1.0" - dotenv "^10.0.0" - execa "^5.0.0" + cli-truncate "2.1.0" + dotenv "10.0.0" + execa "5.1.1" find-up "5.0.0" - global-dirs "^3.0.0" - globby "^11.0.0" - has-yarn "^2.1.0" - is-ci "^3.0.0" - make-dir "^3.0.2" + global-dirs "3.0.0" + globby "11.0.4" + has-yarn "2.1.0" + is-ci "3.0.0" + make-dir "3.1.0" node-fetch "2.6.1" - p-map "^4.0.0" - read-pkg-up "^7.0.1" - resolve "^1.2.0" - rimraf "^3.0.2" - shell-quote "^1.7.2" - string-width "^4.2.0" + p-map "4.0.0" + read-pkg-up "7.0.1" + resolve "1.20.0" + rimraf "3.0.2" + shell-quote "1.7.2" + string-width "4.2.2" strip-ansi "6.0.0" strip-indent "3.0.0" - tar "^6.0.1" - temp-dir "^2.0.0" - temp-write "^4.0.0" - tempy "^1.0.0" - terminal-link "^2.1.1" + tar "6.1.6" + temp-dir "2.0.0" + temp-write "4.0.0" + tempy "1.0.1" + terminal-link "2.1.1" tmp "0.2.1" "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": @@ -2350,7 +2382,7 @@ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== -"@sindresorhus/slugify@^1.1.0", "@sindresorhus/slugify@^1.1.2": +"@sindresorhus/slugify@1.1.2", "@sindresorhus/slugify@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@sindresorhus/slugify/-/slugify-1.1.2.tgz#c2c0129298b8caace2d9156176fe244d0e83156c" integrity sha512-V9nR/W0Xd9TSGXpZ4iFUcFGhuOJtZX82Fzxj1YISlbSgKvIiNa7eLEZrT0vAraPOt++KHauIVNYgGRgjc13dXA== @@ -2528,7 +2560,7 @@ dependencies: "@babel/runtime" "^7.12.5" -"@timsuchanek/copy@^1.4.5": +"@timsuchanek/copy@1.4.5": version "1.4.5" resolved "https://registry.yarnpkg.com/@timsuchanek/copy/-/copy-1.4.5.tgz#8e9658c056e24e1928a88bed45f9eac6a72b7c40" integrity sha512-N4+2/DvfwzQqHYL/scq07fv8yXbZc6RyUxKJoE8Clm14JpLOf9yNI4VB4D6RsV3h9zgzZ4loJUydHKM7pp3blw== @@ -2665,13 +2697,20 @@ resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.10.tgz#61cc8469849e5bcdd0c7044122265c39cec10cf4" integrity sha512-C7srjHiVG3Ey1nR6d511dtDkCEjxuN9W1HWAEjGq8kpcwmNM6JJkpC0xvabM7BXTG2wDq8Eu33iH9aQKa7IvLQ== -"@types/cross-spawn@^6.0.1": +"@types/cross-spawn@6.0.2": version "6.0.2" resolved "https://registry.yarnpkg.com/@types/cross-spawn/-/cross-spawn-6.0.2.tgz#168309de311cd30a2b8ae720de6475c2fbf33ac7" integrity sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw== dependencies: "@types/node" "*" +"@types/debug@4.1.7": + version "4.1.7" + resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82" + integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg== + dependencies: + "@types/ms" "*" + "@types/esrever@^0.2.0": version "0.2.0" resolved "https://registry.yarnpkg.com/@types/esrever/-/esrever-0.2.0.tgz#96404a2284b2c7527f08a1e957f8a31705f9880f" @@ -2768,9 +2807,9 @@ integrity sha512-Kl5beBoB0OXw7WeFgHHpLEchvC7HyIu3v1AksNNTemAF6jmEmQGqhZQSHcG6BOU/Lq0xsByQNqLzicLPjVkxYQ== "@types/http-assert@*": - version "1.5.1" - resolved "https://registry.yarnpkg.com/@types/http-assert/-/http-assert-1.5.1.tgz#d775e93630c2469c2f980fc27e3143240335db3b" - integrity sha512-PGAK759pxyfXE78NbKxyfRcWYA/KwW17X290cNev/qAsn9eQIxkH4shoNBafH37wewhDG/0p1cHPbK6+SzZjWQ== + version "1.5.2" + resolved "https://registry.yarnpkg.com/@types/http-assert/-/http-assert-1.5.2.tgz#a7fb59a7ca366e141789a084555a633801b9af3b" + integrity sha512-Ddzuzv/bB2prZnJKlS1sEYhaeT50wfJjhcTTTQLjEsEZJlk3XB4Xohieyq+P4VXIzg7lrQ1Spd/PfRnBpQsdqA== "@types/http-errors@*": version "1.8.1" @@ -2801,18 +2840,18 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@*", "@types/jest@^26.0.24": - version "26.0.24" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.24.tgz#943d11976b16739185913a1936e0de0c4a7d595a" - integrity sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w== +"@types/jest@*", "@types/jest@^27.0.1": + version "27.0.1" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.0.1.tgz#fafcc997da0135865311bb1215ba16dba6bdf4ca" + integrity sha512-HTLpVXHrY69556ozYkcq47TtQJXpcWAWfkoqz+ZGz2JnmZhzlRjprCIyFnetSy8gpDWwTTGBcRVv1J1I1vBrHw== dependencies: - jest-diff "^26.0.0" - pretty-format "^26.0.0" + jest-diff "^27.0.0" + pretty-format "^27.0.0" -"@types/json-schema@^7.0.7", "@types/json-schema@^7.0.8": - version "7.0.8" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.8.tgz#edf1bf1dbf4e04413ca8e5b17b3b7d7d54b59818" - integrity sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg== +"@types/json-schema@^7.0.7": + version "7.0.9" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" + integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== "@types/keygrip@*": version "1.0.2" @@ -2841,9 +2880,9 @@ "@types/node" "*" "@types/lodash@^4.14.149": - version "4.14.171" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.171.tgz#f01b3a5fe3499e34b622c362a46a609fdb23573b" - integrity sha512-7eQ2xYLLI/LsicL2nejW9Wyko3lcpN6O/z0ZLHrEQsg280zIdCv1t/0m6UtBjUHokCGBQ3gYTbHzDkZ1xOBwwg== + version "4.14.172" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.172.tgz#aad774c28e7bfd7a67de25408e03ee5a8c3d028a" + integrity sha512-/BHF5HAx3em7/KkzVKm3LrsD6HZAXuXO1AJZQ3cRRBZj4oHZDviWPYu0aEplAqDFNHZPW6d3G7KN+ONcCCC7pw== "@types/long@^4.0.0": version "4.0.1" @@ -2879,6 +2918,11 @@ resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== +"@types/ms@*": + version "0.7.31" + resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" + integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== + "@types/node-fetch@^2.5.12": version "2.5.12" resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.12.tgz#8a6f779b1d4e60b7a57fb6fd48d84fb545b9cc66" @@ -2898,9 +2942,9 @@ integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw== "@types/node@^12.7.1": - version "12.20.18" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.18.tgz#37a0aab0560d1186da54ee5d62ff6a78cacb8c75" - integrity sha512-YoTiIwdKxM3VLiY2sM05x4iGuTveYiCcDaUVmo1L5ndrXxPGW/NEoZu+pGcBirziomizcZsnsQoemikKcB2fRA== + version "12.20.19" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.19.tgz#538e61fc220f77ae4a4663c3d8c3cb391365c209" + integrity sha512-niAuZrwrjKck4+XhoCw6AAVQBENHftpXw9F4ryk66fTgYaKQ53R4FI7c9vUGGw5vQis1HKBHDR1gcYI/Bq1xvw== "@types/nodemailer@^6.4.4": version "6.4.4" @@ -2980,10 +3024,10 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@^17.0.15": - version "17.0.15" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.15.tgz#c7533dc38025677e312606502df7656a6ea626d0" - integrity sha512-uTKHDK9STXFHLaKv6IMnwp52fm0hwU+N89w/p9grdUqcFA6WuqDyPhaWopbNyE1k/VhgzmHl8pu1L4wITtmlLw== +"@types/react@*", "@types/react@^17.0.18": + version "17.0.18" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.18.tgz#4109cbbd901be9582e5e39e3d77acd7b66bb7fbe" + integrity sha512-YTLgu7oS5zvSqq49X5Iue5oAbVGhgPc5Au29SJC4VeE17V6gASoOxVkUDy9pXFMRFxCWCD9fLeweNFizo3UzOg== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" @@ -3129,9 +3173,9 @@ "@types/vfile-message" "*" "@types/webpack-sources@*": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-2.1.1.tgz#6af17e3a3ded71eec2b98008d7c12f498a0a4506" - integrity sha512-MjM1R6iuw8XaVbtkCBz0N349cyqBjJHCbQiOeppe3VBeFvxqs74RKHAVt9LkxTnUWc7YLZOEsUfPUnmK6SBPKQ== + version "3.2.0" + resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-3.2.0.tgz#16d759ba096c289034b26553d2df1bf45248d38b" + integrity sha512-Ft7YH3lEVRQ6ls8k4Ff1oB4jN6oy/XmU6tQISKdhfh+1mR+viZFphS6WL0IrtDOzvefmJg5a0s7ZQoRXwqTEFg== dependencies: "@types/node" "*" "@types/source-list-map" "*" @@ -3161,13 +3205,6 @@ resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.1.tgz#3b9ce2489919d9e4fea439b76916abc34b2df129" integrity sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw== -"@types/yargs@^15.0.0": - version "15.0.14" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.14.tgz#26d821ddb89e70492160b66d10a0eb6df8f6fb06" - integrity sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ== - dependencies: - "@types/yargs-parser" "*" - "@types/yargs@^16.0.0": version "16.0.4" resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.4.tgz#26aad98dd2c2a38e421086ea9ad42b9e51642977" @@ -3182,86 +3219,86 @@ dependencies: "@types/node" "*" -"@types/zen-observable@^0.8.0": +"@types/zen-observable@0.8.3": version "0.8.3" resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.3.tgz#781d360c282436494b32fe7d9f7f8e64b3118aa3" integrity sha512-fbF6oTd4sGGy0xjHPKAt+eS2CrxJ3+6gQ3FGcBoIJR2TLAyCkCyI8JqZNy+FeON0AhVgNJoUumVoZQjBFUqHkw== -"@typescript-eslint/eslint-plugin@^4.29.0": - version "4.29.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.0.tgz#b866c9cd193bfaba5e89bade0015629ebeb27996" - integrity sha512-eiREtqWRZ8aVJcNru7cT/AMVnYd9a2UHsfZT8MR1dW3UUEg6jDv9EQ9Cq4CUPZesyQ58YUpoAADGv71jY8RwgA== +"@typescript-eslint/eslint-plugin@^4.29.2": + version "4.29.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.2.tgz#f54dc0a32b8f61c6024ab8755da05363b733838d" + integrity sha512-x4EMgn4BTfVd9+Z+r+6rmWxoAzBaapt4QFqE+d8L8sUtYZYLDTK6VG/y/SMMWA5t1/BVU5Kf+20rX4PtWzUYZg== dependencies: - "@typescript-eslint/experimental-utils" "4.29.0" - "@typescript-eslint/scope-manager" "4.29.0" + "@typescript-eslint/experimental-utils" "4.29.2" + "@typescript-eslint/scope-manager" "4.29.2" debug "^4.3.1" functional-red-black-tree "^1.0.1" regexpp "^3.1.0" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/experimental-utils@4.29.0", "@typescript-eslint/experimental-utils@^4.0.1", "@typescript-eslint/experimental-utils@^4.2.0": - version "4.29.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.29.0.tgz#19b1417602d0e1ef325b3312ee95f61220542df5" - integrity sha512-FpNVKykfeaIxlArLUP/yQfv/5/3rhl1ov6RWgud4OgbqWLkEq7lqgQU9iiavZRzpzCRQV4XddyFz3wFXdkiX9w== +"@typescript-eslint/experimental-utils@4.29.2", "@typescript-eslint/experimental-utils@^4.0.1", "@typescript-eslint/experimental-utils@^4.2.0": + version "4.29.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.29.2.tgz#5f67fb5c5757ef2cb3be64817468ba35c9d4e3b7" + integrity sha512-P6mn4pqObhftBBPAv4GQtEK7Yos1fz/MlpT7+YjH9fTxZcALbiiPKuSIfYP/j13CeOjfq8/fr9Thr2glM9ub7A== dependencies: "@types/json-schema" "^7.0.7" - "@typescript-eslint/scope-manager" "4.29.0" - "@typescript-eslint/types" "4.29.0" - "@typescript-eslint/typescript-estree" "4.29.0" + "@typescript-eslint/scope-manager" "4.29.2" + "@typescript-eslint/types" "4.29.2" + "@typescript-eslint/typescript-estree" "4.29.2" eslint-scope "^5.1.1" eslint-utils "^3.0.0" -"@typescript-eslint/parser@^4.29.0": - version "4.29.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.29.0.tgz#e5367ca3c63636bb5d8e0748fcbab7a4f4a04289" - integrity sha512-+92YRNHFdXgq+GhWQPT2bmjX09X7EH36JfgN2/4wmhtwV/HPxozpCNst8jrWcngLtEVd/4zAwA6BKojAlf+YqA== +"@typescript-eslint/parser@^4.29.2": + version "4.29.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.29.2.tgz#1c7744f4c27aeb74610c955d3dce9250e95c370a" + integrity sha512-WQ6BPf+lNuwteUuyk1jD/aHKqMQ9jrdCn7Gxt9vvBnzbpj7aWEf+aZsJ1zvTjx5zFxGCt000lsbD9tQPEL8u6g== dependencies: - "@typescript-eslint/scope-manager" "4.29.0" - "@typescript-eslint/types" "4.29.0" - "@typescript-eslint/typescript-estree" "4.29.0" + "@typescript-eslint/scope-manager" "4.29.2" + "@typescript-eslint/types" "4.29.2" + "@typescript-eslint/typescript-estree" "4.29.2" debug "^4.3.1" -"@typescript-eslint/scope-manager@4.29.0": - version "4.29.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.29.0.tgz#cf5474f87321bedf416ef65839b693bddd838599" - integrity sha512-HPq7XAaDMM3DpmuijxLV9Io8/6pQnliiXMQUcAdjpJJSR+fdmbD/zHCd7hMkjJn04UQtCQBtshgxClzg6NIS2w== +"@typescript-eslint/scope-manager@4.29.2": + version "4.29.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.29.2.tgz#442b0f029d981fa402942715b1718ac7fcd5aa1b" + integrity sha512-mfHmvlQxmfkU8D55CkZO2sQOueTxLqGvzV+mG6S/6fIunDiD2ouwsAoiYCZYDDK73QCibYjIZmGhpvKwAB5BOA== dependencies: - "@typescript-eslint/types" "4.29.0" - "@typescript-eslint/visitor-keys" "4.29.0" + "@typescript-eslint/types" "4.29.2" + "@typescript-eslint/visitor-keys" "4.29.2" -"@typescript-eslint/types@4.29.0": - version "4.29.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.29.0.tgz#c8f1a1e4441ea4aca9b3109241adbc145f7f8a4e" - integrity sha512-2YJM6XfWfi8pgU2HRhTp7WgRw78TCRO3dOmSpAvIQ8MOv4B46JD2chnhpNT7Jq8j0APlIbzO1Bach734xxUl4A== +"@typescript-eslint/types@4.29.2": + version "4.29.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.29.2.tgz#fc0489c6b89773f99109fb0aa0aaddff21f52fcd" + integrity sha512-K6ApnEXId+WTGxqnda8z4LhNMa/pZmbTFkDxEBLQAbhLZL50DjeY0VIDCml/0Y3FlcbqXZrABqrcKxq+n0LwzQ== -"@typescript-eslint/typescript-estree@4.29.0": - version "4.29.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.0.tgz#af7ab547757b86c91bfdbc54ff86845410856256" - integrity sha512-8ZpNHDIOyqzzgZrQW9+xQ4k5hM62Xy2R4RPO3DQxMc5Rq5QkCdSpk/drka+DL9w6sXNzV5nrdlBmf8+x495QXQ== +"@typescript-eslint/typescript-estree@4.29.2": + version "4.29.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.2.tgz#a0ea8b98b274adbb2577100ba545ddf8bf7dc219" + integrity sha512-TJ0/hEnYxapYn9SGn3dCnETO0r+MjaxtlWZ2xU+EvytF0g4CqTpZL48SqSNn2hXsPolnewF30pdzR9a5Lj3DNg== dependencies: - "@typescript-eslint/types" "4.29.0" - "@typescript-eslint/visitor-keys" "4.29.0" + "@typescript-eslint/types" "4.29.2" + "@typescript-eslint/visitor-keys" "4.29.2" debug "^4.3.1" globby "^11.0.3" is-glob "^4.0.1" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/visitor-keys@4.29.0": - version "4.29.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.0.tgz#1ff60f240def4d85ea68d4fd2e4e9759b7850c04" - integrity sha512-LoaofO1C/jAJYs0uEpYMXfHboGXzOJeV118X4OsZu9f7rG7Pr9B3+4HTU8+err81rADa4xfQmAxnRnPAI2jp+Q== +"@typescript-eslint/visitor-keys@4.29.2": + version "4.29.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.2.tgz#d2da7341f3519486f50655159f4e5ecdcb2cd1df" + integrity sha512-bDgJLQ86oWHJoZ1ai4TZdgXzJxsea3Ee9u9wsTAvjChdj2WLcVsgWYAPeY7RQMn16tKrlQaBnpKv7KBfs4EQag== dependencies: - "@typescript-eslint/types" "4.29.0" + "@typescript-eslint/types" "4.29.2" eslint-visitor-keys "^2.0.0" "@wry/context@^0.6.0": - version "0.6.0" - resolved "https://registry.yarnpkg.com/@wry/context/-/context-0.6.0.tgz#f903eceb89d238ef7e8168ed30f4511f92d83e06" - integrity sha512-sAgendOXR8dM7stJw3FusRxFHF/ZinU0lffsA2YTyyIOfic86JX02qlPqPVqJNZJPAxFt+2EE8bvq6ZlS0Kf+Q== + version "0.6.1" + resolved "https://registry.yarnpkg.com/@wry/context/-/context-0.6.1.tgz#c3c29c0ad622adb00f6a53303c4f965ee06ebeb2" + integrity sha512-LOmVnY1iTU2D8tv4Xf6MVMZZ+juIJ87Kt/plMijjN20NMAXGmH4u8bS1t0uT74cZ5gwpocYueV58YwyI8y+GKw== dependencies: - tslib "^2.1.0" + tslib "^2.3.0" "@wry/equality@^0.1.2": version "0.1.11" @@ -3271,18 +3308,18 @@ tslib "^1.9.3" "@wry/equality@^0.5.0": - version "0.5.1" - resolved "https://registry.yarnpkg.com/@wry/equality/-/equality-0.5.1.tgz#b22e4e1674d7bf1439f8ccdccfd6a785f6de68b0" - integrity sha512-FZKbdpbcVcbDxQrKcaBClNsQaMg9nof1RKM7mReJe5DKUzM5u8S7T+PqwNqvib5O2j2xxF1R4p5O3+b6baTrbw== + version "0.5.2" + resolved "https://registry.yarnpkg.com/@wry/equality/-/equality-0.5.2.tgz#72c8a7a7d884dff30b612f4f8464eba26c080e73" + integrity sha512-oVMxbUXL48EV/C0/M7gLVsoK6qRHPS85x8zECofEZOVvxGmIPLA9o5Z27cc2PoAyZz1S2VoM2A7FLAnpfGlneA== dependencies: - tslib "^2.1.0" + tslib "^2.3.0" "@wry/trie@^0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@wry/trie/-/trie-0.3.0.tgz#3245e74988c4e3033299e479a1bf004430752463" - integrity sha512-Yw1akIogPhAT6XPYsRHlZZIS0tIGmAl9EYXHi2scf7LPKKqdqmow/Hu4kEqP2cJR3EjaU/9L0ZlAjFf3hFxmug== + version "0.3.1" + resolved "https://registry.yarnpkg.com/@wry/trie/-/trie-0.3.1.tgz#2279b790f15032f8bcea7fc944d27988e5b3b139" + integrity sha512-WwB53ikYudh9pIorgxrkHKrQZcCqNM/Q/bDzZBffEaGUKGuHrRb3zZUT9Sh2qw9yogC7SsdRmQ1ER0pqvd3bfw== dependencies: - tslib "^2.1.0" + tslib "^2.3.0" abab@^2.0.3, abab@^2.0.5: version "2.0.5" @@ -3348,12 +3385,7 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" -ajv-keywords@^3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" - integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== - -ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5: +ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -3663,7 +3695,7 @@ archiver-utils@^2.1.0: normalize-path "^3.0.0" readable-stream "^2.0.0" -archiver@^4.0.0: +archiver@4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/archiver/-/archiver-4.0.2.tgz#43c72865eadb4ddaaa2fb74852527b6a450d927c" integrity sha512-B9IZjlGwaxF33UN4oPbfBkyA4V1SxNLeIhR1qY8sRXSsbdUkEHrrOvwlYFPx+8uQeCe9M+FG6KgO+imDmQ79CQ== @@ -3681,7 +3713,7 @@ arg@4.1.0: resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.0.tgz#583c518199419e0037abb74062c37f8519e575f0" integrity sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg== -arg@^5.0.0: +arg@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.0.tgz#a20e2bb5710e82950a516b3f933fee5ed478be90" integrity sha512-4P8Zm2H+BRS+c/xX1LrHw0qKpEhdlZjLCgWy+d78T9vqa2Z2SiD2wMrYuWIAFy5IZUD7nnNXroRttz+0RzlrzQ== @@ -3856,9 +3888,9 @@ async-retry@^1.2.1: retry "0.12.0" async@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" - integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw== + version "3.2.1" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.1.tgz#d3274ec66d107a47476a4c49136aacdb00665fc8" + integrity sha512-XdD5lRO/87udXCMC9meWdYiR+Nq6ZjUfXidViUZGu2F1MO4T3XwZ1et0hb2++BgLfhyJwy44BGB/yx80ABx8hg== asynckit@^0.4.0: version "0.4.0" @@ -3875,7 +3907,7 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -available-typed-arrays@^1.0.2: +available-typed-arrays@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.4.tgz#9e0ae84ecff20caae6a94a1c3bc39b955649b7a9" integrity sha512-SA5mXJWrId1TaQjfxUYghbqQ/hYioKmLJvPJyDuYRtXXenFNMjj4hSSt1Cf1xsuXSXrtxrVC5Ot4eU6cOtBDdA== @@ -4277,7 +4309,7 @@ browserify-zlib@0.2.0, browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist@4.16.6, browserslist@^4.16.6: +browserslist@4.16.6: version "4.16.6" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2" integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ== @@ -4288,6 +4320,17 @@ browserslist@4.16.6, browserslist@^4.16.6: escalade "^3.1.1" node-releases "^1.1.71" +browserslist@^4.16.6, browserslist@^4.16.7: + version "4.16.7" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.7.tgz#108b0d1ef33c4af1b587c54f390e7041178e4335" + integrity sha512-7I4qVwqZltJ7j37wObBe3SoTz+nS8APaNcrBOlgoirb6/HbEU2XxW/LpUDTCngM6iauwFqmRTuOMfyKnFGY5JA== + dependencies: + caniuse-lite "^1.0.30001248" + colorette "^1.2.2" + electron-to-chromium "^1.3.793" + escalade "^3.1.1" + node-releases "^1.1.73" + bser@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" @@ -4456,10 +4499,10 @@ camelcase@^6.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== -caniuse-lite@^1.0.30001202, caniuse-lite@^1.0.30001219, caniuse-lite@^1.0.30001228: - version "1.0.30001248" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001248.tgz#26ab45e340f155ea5da2920dadb76a533cb8ebce" - integrity sha512-NwlQbJkxUFJ8nMErnGtT0QTM2TJ33xgz4KXJSMIrjXIbDVdaYueGyjOrLKRtJC+rTiWfi6j5cnZN1NBiSBJGNw== +caniuse-lite@^1.0.30001202, caniuse-lite@^1.0.30001219, caniuse-lite@^1.0.30001228, caniuse-lite@^1.0.30001248: + version "1.0.30001251" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001251.tgz#6853a606ec50893115db660f82c094d18f096d85" + integrity sha512-HOe1r+9VkU4TFmnU70z+r7OLmtR+/chB1rdcJUeQlAinjEeb0cKL20tlAtOagNZhbrtLnCvV19B4FmF1rgzl6A== caseless@~0.12.0: version "0.12.0" @@ -4499,10 +4542,10 @@ chalk@4.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" - integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== +chalk@4.1.2, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== dependencies: ansi-styles "^4.1.0" supports-color "^7.1.0" @@ -4526,14 +4569,6 @@ chalk@^3.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - char-regex@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" @@ -4710,6 +4745,14 @@ cli-table3@~0.6.0: optionalDependencies: colors "^1.1.2" +cli-truncate@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" + integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== + dependencies: + slice-ansi "^3.0.0" + string-width "^4.2.0" + cli-truncate@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" @@ -4718,14 +4761,6 @@ cli-truncate@^0.2.1: slice-ansi "0.0.4" string-width "^1.0.1" -cli-truncate@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" - integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== - dependencies: - slice-ansi "^3.0.0" - string-width "^4.2.0" - clipboard-copy@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/clipboard-copy/-/clipboard-copy-4.0.1.tgz#326ef9726d4ffe72d9a82a7bbe19379de692017d" @@ -4838,9 +4873,9 @@ color-name@~1.1.4: integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== colorette@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" - integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== + version "1.3.0" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.3.0.tgz#ff45d2f0edb244069d3b772adeb04fed38d0a0af" + integrity sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w== colors@^1.1.2: version "1.4.0" @@ -4993,17 +5028,17 @@ copy-to-clipboard@^3.3.1: toggle-selection "^1.0.6" core-js-compat@^3.14.0, core-js-compat@^3.16.0: - version "3.16.0" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.16.0.tgz#fced4a0a534e7e02f7e084bff66c701f8281805f" - integrity sha512-5D9sPHCdewoUK7pSUPfTF7ZhLh8k9/CoJXWUEo+F1dZT5Z1DVgcuRqUKhjeKW+YLb8f21rTFgWwQJiNw1hoZ5Q== + version "3.16.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.16.1.tgz#c44b7caa2dcb94b673a98f27eee1c8312f55bc2d" + integrity sha512-NHXQXvRbd4nxp9TEmooTJLUf94ySUG6+DSsscBpTftN1lQLQ4LjnWvc7AoIo4UjDsFF3hB8Uh5LLCRRdaiT5MQ== dependencies: - browserslist "^4.16.6" + browserslist "^4.16.7" semver "7.0.0" core-js-pure@^3.10.2, core-js-pure@^3.16.0: - version "3.16.0" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.16.0.tgz#218e07add3f1844e53fab195c47871fc5ba18de8" - integrity sha512-wzlhZNepF/QA9yvx3ePDgNGudU5KDB8lu/TRPKelYA/QtSnkS/cLl2W+TIdEX1FAFcBr0YpY7tPDlcmXJ7AyiQ== + version "3.16.1" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.16.1.tgz#b997df2669c957a5b29f06e95813a171f993592e" + integrity sha512-TyofCdMzx0KMhi84mVRS8rL1XsRk2SPUNz2azmth53iRN0/08Uim9fdhQTaZTG1LqaXHYVci4RDHka6WrXfnvg== core-js@3.6.5: version "3.6.5" @@ -5011,9 +5046,9 @@ core-js@3.6.5: integrity sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA== core-js@^3.1.3: - version "3.16.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.16.0.tgz#1d46fb33720bc1fa7f90d20431f36a5540858986" - integrity sha512-5+5VxRFmSf97nM8Jr2wzOwLqRo6zphH2aX+7KsAUONObyzakDNq2G/bgbhinxB4PoV9L3aXQYhiDKyIKWd2c8g== + version "3.16.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.16.1.tgz#f4485ce5c9f3c6a7cb18fa80488e08d362097249" + integrity sha512-AAkP8i35EbefU+JddyWi12AWE9f2N/qr/pwnDtWz4nyUIBGMJPX99ANFFRSw6FefM374lDujdtLDyhN2A/btHw== core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" @@ -5110,6 +5145,15 @@ cross-fetch@^3.1.4: dependencies: node-fetch "2.6.1" +cross-spawn@7.0.3, cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + cross-spawn@^5.0.1, cross-spawn@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" @@ -5119,15 +5163,6 @@ cross-spawn@^5.0.1, cross-spawn@^5.1.0: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - crypto-browserify@3.12.0, crypto-browserify@^3.11.0: version "3.12.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" @@ -5217,6 +5252,13 @@ cssnano-preset-simple@^2.0.0: dependencies: caniuse-lite "^1.0.30001202" +cssnano-preset-simple@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssnano-preset-simple/-/cssnano-preset-simple-3.0.0.tgz#e95d0012699ca2c741306e9a3b8eeb495a348dbe" + integrity sha512-vxQPeoMRqUT3c/9f0vWeVa2nKQIHFpogtoBvFdW4GQ3IvEJ6uauCP6p3Y5zQDLFcI7/+40FTgX12o7XUL0Ko+w== + dependencies: + caniuse-lite "^1.0.30001202" + cssnano-simple@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/cssnano-simple/-/cssnano-simple-2.0.0.tgz#930d9dcd8ba105c5a62ce719cb00854da58b5c05" @@ -5224,6 +5266,13 @@ cssnano-simple@2.0.0: dependencies: cssnano-preset-simple "^2.0.0" +cssnano-simple@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssnano-simple/-/cssnano-simple-3.0.0.tgz#a4b8ccdef4c7084af97e19bc5b93b4ecf211e90f" + integrity sha512-oU3ueli5Dtwgh0DyeohcIEE00QVfbPR3HzyXdAl89SfnQG3y0/qcpfLVW+jPIh3/rgMZGwuW96rejZGaYE9eUg== + dependencies: + cssnano-preset-simple "^3.0.0" + csso@^4.0.2: version "4.2.0" resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" @@ -5573,11 +5622,6 @@ dicer@0.3.0: dependencies: streamsearch "0.1.2" -diff-sequences@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" - integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q== - diff-sequences@^27.0.6: version "27.0.6" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.0.6.tgz#3305cb2e55a033924054695cc66019fd7f8e5723" @@ -5626,9 +5670,9 @@ doctrine@^3.0.0: esutils "^2.0.2" dom-accessibility-api@^0.5.6: - version "0.5.6" - resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.6.tgz#3f5d43b52c7a3bd68b5fb63fa47b4e4c1fdf65a9" - integrity sha512-DplGLZd8L1lN64jlT27N9TVSESFR5STaEJvX+thCby7fuCHonfPpAlodYc3vuUYbDuDec5w8AMP7oCM5TWFsqw== + version "0.5.7" + resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.7.tgz#8c2aa6325968f2933160a0b7dbb380893ddf3e7d" + integrity sha512-ml3lJIq9YjUfM9TUnEPvEYWFSwivwIGBPKpewX7tii7fwCazA8yCioGdqQcNsItPpfFvSJ3VIdMQPj60LJhcQA== dom-helpers@^5.0.1: version "5.2.1" @@ -5688,7 +5732,7 @@ dot-prop@^3.0.0: dependencies: is-obj "^1.0.0" -dotenv@^10.0.0: +dotenv@10.0.0, dotenv@^10.0.0: version "10.0.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== @@ -5733,10 +5777,10 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -electron-to-chromium@^1.3.723: - version "1.3.793" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.793.tgz#c10dff5f3126238004de344db458f1da3641d554" - integrity sha512-l9NrGV6Mr4ov5mayYPvIWcwklNw5ROmy6rllzz9dCACw9nKE5y+s5uQk+CBJMetxrWZ6QJFsvEfG6WDcH2IGUg== +electron-to-chromium@^1.3.723, electron-to-chromium@^1.3.793: + version "1.3.806" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.806.tgz#21502100f11aead6c501d1cd7f2504f16c936642" + integrity sha512-AH/otJLAAecgyrYp0XK1DPiGVWcOgwPeJBOLeuFQ5l//vhQhwC9u6d+GijClqJAmsHG4XDue81ndSQPohUu0xA== elegant-spinner@^1.0.1: version "1.0.1" @@ -5824,7 +5868,7 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.17.2, es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2, es-abstract@^1.18.2: +es-abstract@^1.17.2, es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2, es-abstract@^1.18.2, es-abstract@^1.18.5: version "1.18.5" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.5.tgz#9b10de7d4c206a3581fd5b2124233e04db49ae19" integrity sha512-DDggyJLoS91CkJjgauM5c0yZMjiD1uK3KcaCeAmffGwZ+ODWzOkPN4QwRbsK5DOFf06fywmyLci3ZD8jLGhVYA== @@ -5898,18 +5942,18 @@ escodegen@^2.0.0: optionalDependencies: source-map "~0.6.1" -eslint-import-resolver-node@^0.3.4: - version "0.3.4" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz#85ffa81942c25012d8231096ddf679c03042c717" - integrity sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA== +eslint-import-resolver-node@^0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.5.tgz#939bbb0f74e179e757ca87f7a4a890dabed18ac4" + integrity sha512-XMoPKjSpXbkeJ7ZZ9icLnJMTY5Mc1kZbCakHquaFsXPpyWOwK0TK6CODO+0ca54UoM9LKOxyUNnoVZRl8TeaAg== dependencies: - debug "^2.6.9" - resolve "^1.13.1" + debug "^3.2.7" + resolve "^1.20.0" -eslint-module-utils@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz#b51be1e473dd0de1c5ea638e22429c2490ea8233" - integrity sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A== +eslint-module-utils@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz#94e5540dd15fe1522e8ffa3ec8db3b7fa7e7a534" + integrity sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q== dependencies: debug "^3.2.7" pkg-dir "^2.0.0" @@ -5921,17 +5965,17 @@ eslint-plugin-cypress@^2.11.3: dependencies: globals "^11.12.0" -eslint-plugin-import@^2.23.3: - version "2.23.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.23.3.tgz#8a1b073289fff03c4af0f04b6df956b7d463e191" - integrity sha512-wDxdYbSB55F7T5CC7ucDjY641VvKmlRwT0Vxh7PkY1mI4rclVRFWYfsrjDgZvwYYDZ5ee0ZtfFKXowWjqvEoRQ== +eslint-plugin-import@^2.24.0: + version "2.24.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.24.0.tgz#697ffd263e24da5e84e03b282f5fb62251777177" + integrity sha512-Kc6xqT9hiYi2cgybOc0I2vC9OgAYga5o/rAFinam/yF/t5uBqxQbauNPMC6fgb640T/89P0gFoO27FOilJ/Cqg== dependencies: array-includes "^3.1.3" array.prototype.flat "^1.2.4" debug "^2.6.9" doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.4" - eslint-module-utils "^2.6.1" + eslint-import-resolver-node "^0.3.5" + eslint-module-utils "^2.6.2" find-up "^2.0.0" has "^1.0.3" is-core-module "^2.4.0" @@ -6480,14 +6524,6 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" -file-loader@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" - integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== - dependencies: - loader-utils "^2.0.0" - schema-utils "^3.0.0" - file-type@^10.10.0: version "10.11.0" resolved "https://registry.yarnpkg.com/file-type/-/file-type-10.11.0.tgz#2961d09e4675b9fb9a3ee6b69e9cd23f43fd1890" @@ -6629,12 +6665,12 @@ focus-lock@^0.9.1: dependencies: tslib "^2.0.3" -focus-trap@^6.6.0: - version "6.6.0" - resolved "https://registry.yarnpkg.com/focus-trap/-/focus-trap-6.6.0.tgz#7fb37679926ec1bd762d0748b056c68a64a9e8cf" - integrity sha512-2hWVR3XbBejn5v8wDW9DFzLWXcxMNaSJ/CtE3E+FJjjBCLwIYbZJwjUi2RDBfQPM58gHEt5hck0jrJgHR9/s+A== +focus-trap@^6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/focus-trap/-/focus-trap-6.6.1.tgz#761ce2c82ddd72beeb049e968bc8414e25b704aa" + integrity sha512-x9BWuAeF5UrfWuYKJ3jYrjcVYSYptS9CqtxH5IH7lPlZrMsaugKeAa0HtoZSBZe5DmeTMx2m0qY464ZMzqarzw== dependencies: - tabbable "^5.2.0" + tabbable "^5.2.1" follow-redirects@^1.10.0: version "1.14.1" @@ -6864,6 +6900,11 @@ get-stdin@^6.0.0: resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g== +get-stream@6.0.1, get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" @@ -6883,11 +6924,6 @@ get-stream@^5.0.0, get-stream@^5.1.0: dependencies: pump "^3.0.0" -get-stream@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -6976,6 +7012,13 @@ glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" +global-dirs@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.0.tgz#70a76fe84ea315ab37b1f5576cbde7d48ef72686" + integrity sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA== + dependencies: + ini "2.0.0" + global-dirs@^2.0.1: version "2.1.0" resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-2.1.0.tgz#e9046a49c806ff04d6c1825e196c8f0091e8df4d" @@ -6983,26 +7026,19 @@ global-dirs@^2.0.1: dependencies: ini "1.3.7" -global-dirs@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.0.tgz#70a76fe84ea315ab37b1f5576cbde7d48ef72686" - integrity sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA== - dependencies: - ini "2.0.0" - globals@^11.1.0, globals@^11.12.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== globals@^13.6.0, globals@^13.9.0: - version "13.10.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.10.0.tgz#60ba56c3ac2ca845cfbf4faeca727ad9dd204676" - integrity sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g== + version "13.11.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.11.0.tgz#40ef678da117fe7bd2e28f1fab24951bd0255be7" + integrity sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g== dependencies: type-fest "^0.20.2" -globby@^11.0.0, globby@^11.0.1, globby@^11.0.3, globby@^11.0.4: +globby@11.0.4, globby@^11.0.0, globby@^11.0.1, globby@^11.0.3, globby@^11.0.4: version "11.0.4" resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== @@ -7058,9 +7094,9 @@ got@^9.6.0: url-parse-lax "^3.0.0" graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.5, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4: - version "4.2.6" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" - integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== + version "4.2.8" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" + integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== grapheme-splitter@^1.0.4: version "1.0.4" @@ -7083,7 +7119,7 @@ graphql-subscriptions@^1.0.0: dependencies: iterall "^1.3.0" -graphql-tag@^2.11.0, graphql-tag@^2.12.0, graphql-tag@^2.12.5: +graphql-tag@^2.11.0, graphql-tag@^2.12.3, graphql-tag@^2.12.5: version "2.12.5" resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.12.5.tgz#5cff974a67b417747d05c8d9f5f3cb4495d0db8f" integrity sha512-5xNhP4063d16Pz3HBtKprutsPrmHZi5IdUGOWRxA2B6VF7BIRGOHZ5WQvDmJXZuPcBg7rYwaFxvQYjqkSdR3TQ== @@ -7167,6 +7203,13 @@ has-symbols@^1.0.1, has-symbols@^1.0.2: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + has-value@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" @@ -7198,7 +7241,7 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" -has-yarn@^2.1.0: +has-yarn@2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77" integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw== @@ -7468,7 +7511,7 @@ ignore@^5.1.4: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== -image-size@^1.0.0: +image-size@1.0.0, image-size@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/image-size/-/image-size-1.0.0.tgz#58b31fe4743b1cec0a0ac26f5c914d3c5b2f0750" integrity sha512-JLJ6OwBfO1KcA+TvJT+v8gbE6iWbj24LyDNFgFEN0lzegn6cC6a/p3NIDaepMsJjQjlUWqIC7wJv8lBFxPNjcw== @@ -7508,16 +7551,16 @@ imurmurhash@^0.1.4: resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= +indent-string@4.0.0, indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + indent-string@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok= -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" - integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== - inflection@^1.13.1: version "1.13.1" resolved "https://registry.yarnpkg.com/inflection/-/inflection-1.13.1.tgz#c5cadd80888a90cf84c2e96e340d7edc85d5f0cb" @@ -7637,11 +7680,12 @@ is-alphanumerical@^1.0.0: is-decimal "^1.0.0" is-arguments@^1.0.4: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9" - integrity sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg== + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== dependencies: - call-bind "^1.0.0" + call-bind "^1.0.2" + has-tostringtag "^1.0.0" is-arrayish@^0.2.1: version "0.2.1" @@ -7649,9 +7693,11 @@ is-arrayish@^0.2.1: integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= is-bigint@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.2.tgz#ffb381442503235ad245ea89e45b3dbff040ee5a" - integrity sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA== + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" is-binary-path@^1.0.0: version "1.0.1" @@ -7668,11 +7714,12 @@ is-binary-path@~2.1.0: binary-extensions "^2.0.0" is-boolean-object@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.1.tgz#3c0878f035cb821228d350d2e1e36719716a3de8" - integrity sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng== + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== dependencies: call-bind "^1.0.2" + has-tostringtag "^1.0.0" is-buffer@^1.1.5: version "1.1.6" @@ -7685,9 +7732,16 @@ is-buffer@^2.0.0: integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e" - integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" + integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== + +is-ci@3.0.0, is-ci@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.0.tgz#c7e7be3c9d8eef7d0fa144390bd1e4b88dc4c994" + integrity sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ== + dependencies: + ci-info "^3.1.1" is-ci@^2.0.0: version "2.0.0" @@ -7696,13 +7750,6 @@ is-ci@^2.0.0: dependencies: ci-info "^2.0.0" -is-ci@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.0.tgz#c7e7be3c9d8eef7d0fa144390bd1e4b88dc4c994" - integrity sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ== - dependencies: - ci-info "^3.1.1" - is-core-module@^2.2.0, is-core-module@^2.4.0: version "2.5.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.5.0.tgz#f754843617c70bfd29b7bd87327400cda5c18491" @@ -7725,9 +7772,11 @@ is-data-descriptor@^1.0.0: kind-of "^6.0.0" is-date-object@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.4.tgz#550cfcc03afada05eea3dd30981c7b09551f73e5" - integrity sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A== + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" is-decimal@^1.0.0: version "1.0.4" @@ -7812,9 +7861,11 @@ is-generator-fn@^2.0.0: integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== is-generator-function@^1.0.7: - version "1.0.9" - resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.9.tgz#e5f82c2323673e7fcad3d12858c83c4039f6399c" - integrity sha512-ZJ34p1uvIfptHCN7sFTjGibB9/oBg17sHqzDLfuwhvmN/qLVvIQXRQ8licZQ35WJ8KuEQt/etnnzQFI9C9Ue/A== + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" is-glob@^2.0.0: version "2.0.1" @@ -7884,9 +7935,11 @@ is-negative-zero@^2.0.1: integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== is-number-object@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.5.tgz#6edfaeed7950cff19afedce9fbfca9ee6dd289eb" - integrity sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw== + version "1.0.6" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0" + integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g== + dependencies: + has-tostringtag "^1.0.0" is-number@^3.0.0: version "3.0.0" @@ -7967,12 +8020,12 @@ is-reference@^1.1.4, is-reference@^1.2.1: "@types/estree" "*" is-regex@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.3.tgz#d029f9aff6448b93ebbe3f33dac71511fdcbef9f" - integrity sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ== + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== dependencies: call-bind "^1.0.2" - has-symbols "^1.0.2" + has-tostringtag "^1.0.0" is-stream@1.1.0, is-stream@^1.1.0: version "1.1.0" @@ -7985,9 +8038,11 @@ is-stream@^2.0.0: integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== is-string@^1.0.5, is-string@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.6.tgz#3fe5d5992fb0d93404f32584d4b0179a71b54a5f" - integrity sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w== + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" is-subdir@^1.1.1: version "1.2.0" @@ -8003,16 +8058,16 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: dependencies: has-symbols "^1.0.2" -is-typed-array@^1.1.3: - version "1.1.5" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.5.tgz#f32e6e096455e329eb7b423862456aa213f0eb4e" - integrity sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug== +is-typed-array@^1.1.3, is-typed-array@^1.1.6: + version "1.1.7" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.7.tgz#881ddc660b13cb8423b2090fa88c0fe37a83eb2f" + integrity sha512-VxlpTBGknhQ3o7YiVjIhdLU6+oD8dPz/79vvvH4F+S/c8608UCVa9fgDpa1kZgFoUST2DCgacc70UszKgzKuvA== dependencies: - available-typed-arrays "^1.0.2" + available-typed-arrays "^1.0.4" call-bind "^1.0.2" - es-abstract "^1.18.0-next.2" + es-abstract "^1.18.5" foreach "^2.0.5" - has-symbols "^1.0.1" + has-tostringtag "^1.0.0" is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" @@ -8208,17 +8263,7 @@ jest-config@^27.0.6: micromatch "^4.0.4" pretty-format "^27.0.6" -jest-diff@^26.0.0: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-26.6.2.tgz#1aa7468b52c3a68d7d5c5fdcdfcd5e49bd164394" - integrity sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA== - dependencies: - chalk "^4.0.0" - diff-sequences "^26.6.2" - jest-get-type "^26.3.0" - pretty-format "^26.6.2" - -jest-diff@^27.0.6: +jest-diff@^27.0.0, jest-diff@^27.0.6: version "27.0.6" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.0.6.tgz#4a7a19ee6f04ad70e0e3388f35829394a44c7b5e" integrity sha512-Z1mqgkTCSYaFgwTlP/NUiRzdqgxmmhzHY1Tq17zL94morOHfHu3K4bgSgl+CR4GLhpV8VxkuOYuIWnQ9LnFqmg== @@ -8271,11 +8316,6 @@ jest-environment-node@^27.0.6: jest-mock "^27.0.6" jest-util "^27.0.6" -jest-get-type@^26.3.0: - version "26.3.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0" - integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig== - jest-get-type@^27.0.6: version "27.0.6" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.0.6.tgz#0eb5c7f755854279ce9b68a9f1a4122f69047cfe" @@ -9015,16 +9055,7 @@ log-symbols@^4.0.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" -log-update@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708" - integrity sha1-iDKP19HOeTiykoN0bwsbwSayRwg= - dependencies: - ansi-escapes "^3.0.0" - cli-cursor "^2.0.0" - wrap-ansi "^3.0.1" - -log-update@^4.0.0: +log-update@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== @@ -9034,6 +9065,15 @@ log-update@^4.0.0: slice-ansi "^4.0.0" wrap-ansi "^6.2.0" +log-update@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708" + integrity sha1-iDKP19HOeTiykoN0bwsbwSayRwg= + dependencies: + ansi-escapes "^3.0.0" + cli-cursor "^2.0.0" + wrap-ansi "^3.0.1" + loglevel@^1.6.7: version "1.7.1" resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197" @@ -9626,7 +9666,7 @@ mime-db@1.49.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.49.0.tgz#f3dfde60c99e9cf3bc9701d687778f537001cbed" integrity sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA== -mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.19, mime-types@~2.1.24: +mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24: version "2.1.32" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.32.tgz#1d00e89e7de7fe02008db61001d9e02852670fd5" integrity sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A== @@ -9776,14 +9816,14 @@ multipipe@^1.0.2: object-assign "^4.1.0" nan@^2.12.1: - version "2.14.2" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" - integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== + version "2.15.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee" + integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ== -nanoid@^3.1.22: - version "3.1.23" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81" - integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw== +nanoid@^3.1.22, nanoid@^3.1.23: + version "3.1.25" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.25.tgz#09ca32747c0e543f0e1814b7d3793477f9c8e152" + integrity sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q== nanomatch@^1.2.9: version "1.2.13" @@ -9819,7 +9859,7 @@ negotiator@0.6.2: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== -new-github-issue-url@^0.2.1: +new-github-issue-url@0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/new-github-issue-url/-/new-github-issue-url-0.2.1.tgz#e17be1f665a92de465926603e44b9f8685630c1d" integrity sha512-md4cGoxuT4T4d/HDOXbrUHkTKrp/vp+m3aOA7XXVYwNsUNMK49g3SQicTSeV5GIz/5QVGAeYRAOlyp9OvlgsYA== @@ -9829,18 +9869,10 @@ next-compose-plugins@^2.2.1: resolved "https://registry.yarnpkg.com/next-compose-plugins/-/next-compose-plugins-2.2.1.tgz#020fc53f275a7e719d62521bef4300fbb6fde5ab" integrity sha512-OjJ+fV15FXO2uQXQagLD4C0abYErBjyjE0I0FHpOEIB8upw0hg1ldFP6cqHTJBH1cZqy96OeR3u1dJ+Ez2D4Bg== -next-images@^1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/next-images/-/next-images-1.8.1.tgz#adea0c46a2e837cb49b6f95b478500a7ed4eea4f" - integrity sha512-/DoXucQKWkEBT2rCQKtm9bb+KTAnd1vVTLO12lX4oxdiBQa2uqn5vhcMPwKsdJlxNBzwg6EVnddFs3aqcwiiGA== - dependencies: - file-loader "^6.2.0" - url-loader "^4.1.0" - -next-sitemap@^1.6.140: - version "1.6.140" - resolved "https://registry.yarnpkg.com/next-sitemap/-/next-sitemap-1.6.140.tgz#b391633596f4845ec9ceb54a51da8c1f6f97ae43" - integrity sha512-VTOQMae/nDLBRGBHnkmGoIsArymlOpJWkZUDvPapktF4QX2U7yvwHIHe7V7amqV2gE2xiDYgd0ayXOBBGuFHog== +next-sitemap@^1.6.157: + version "1.6.157" + resolved "https://registry.yarnpkg.com/next-sitemap/-/next-sitemap-1.6.157.tgz#9e894188217ec94a00d4e10ddebb92393a3ea14a" + integrity sha512-5aIGplbGj0vRsetVla1ZW+0CaRtFnDY9ffW8qqii/nAfOyFuBgaHgKS92TsuBPNzz7O0/7vz4x8jZXEoR9tg2w== dependencies: "@corex/deepmerge" "^2.6.20" matcher "^4.0.0" @@ -9902,6 +9934,62 @@ next@^10.2.3: vm-browserify "1.1.2" watchpack "2.1.1" +"next@npm:next@^11.1.0": + version "11.1.0" + resolved "https://registry.yarnpkg.com/next/-/next-11.1.0.tgz#767d4c4fa0b9b0c768cdbd6c9f03dd86b5d701c0" + integrity sha512-GHBk/c7Wyr6YbFRFZF37I0X7HKzkHHI8pur/loyXo5AIE8wdkbGPGO0ds3vNAO6f8AxZAKGCRYtAzoGlVLoifA== + dependencies: + "@babel/runtime" "7.12.5" + "@hapi/accept" "5.0.2" + "@next/env" "11.1.0" + "@next/polyfill-module" "11.1.0" + "@next/react-dev-overlay" "11.1.0" + "@next/react-refresh-utils" "11.1.0" + "@node-rs/helper" "1.2.1" + assert "2.0.0" + ast-types "0.13.2" + browserify-zlib "0.2.0" + browserslist "4.16.6" + buffer "5.6.0" + caniuse-lite "^1.0.30001228" + chalk "2.4.2" + chokidar "3.5.1" + constants-browserify "1.0.0" + crypto-browserify "3.12.0" + cssnano-simple "3.0.0" + domain-browser "4.19.0" + encoding "0.1.13" + etag "1.8.1" + find-cache-dir "3.3.1" + get-orientation "1.1.2" + https-browserify "1.0.0" + image-size "1.0.0" + jest-worker "27.0.0-next.5" + native-url "0.3.4" + node-fetch "2.6.1" + node-html-parser "1.4.9" + node-libs-browser "^2.2.1" + os-browserify "0.3.0" + p-limit "3.1.0" + path-browserify "1.0.1" + pnp-webpack-plugin "1.6.4" + postcss "8.2.15" + process "0.11.10" + querystring-es3 "0.2.1" + raw-body "2.4.1" + react-is "17.0.2" + react-refresh "0.8.3" + stream-browserify "3.0.0" + stream-http "3.1.1" + string_decoder "1.3.0" + styled-jsx "4.0.0" + timers-browserify "2.0.12" + tty-browserify "0.0.1" + use-subscription "1.5.1" + util "0.12.3" + vm-browserify "1.1.2" + watchpack "2.1.1" + node-fetch@2.6.1, node-fetch@^2.5.0, node-fetch@^2.6.0, node-fetch@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" @@ -9953,10 +10041,10 @@ node-modules-regexp@^1.0.0: resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= -node-releases@^1.1.71: - version "1.1.73" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.73.tgz#dd4e81ddd5277ff846b80b52bb40c49edf7a7b20" - integrity sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg== +node-releases@^1.1.71, node-releases@^1.1.73: + version "1.1.74" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.74.tgz#e5866488080ebaa70a93b91144ccde06f3c3463e" + integrity sha512-caJBVempXZPepZoZAPCWRTNxYQ+xtG/KAi4ozTA5A+nJ7IU+kLQCbqaUjb5Rwy14M9upBWiQ4NutcmW04LJSRw== nodemailer@^6.6.3: version "6.6.3" @@ -10208,7 +10296,7 @@ onetime@^5.1.0, onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" -open@^7.0.3: +open@7.4.2: version "7.4.2" resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== @@ -10216,7 +10304,7 @@ open@^7.0.3: is-docker "^2.0.0" is-wsl "^2.1.1" -optimism@^0.16.0: +optimism@^0.16.1: version "0.16.1" resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.16.1.tgz#7c8efc1f3179f18307b887e18c15c5b7133f6e7d" integrity sha512-64i+Uw3otrndfq5kaoGNoY7pvOhSsjFEN4bdEFh80MWVk/dbgJfMv7VFDeCT8LxNAlEVhQmdVEbfE7X2nWNIIg== @@ -10349,19 +10437,19 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" -p-map@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" - integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== - -p-map@^4.0.0: +p-map@4.0.0, p-map@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== dependencies: aggregate-error "^3.0.0" -p-retry@^4.2.0: +p-map@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" + integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== + +p-retry@4.6.1, p-retry@^4.2.0: version "4.6.1" resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.1.tgz#8fcddd5cdf7a67a0911a9cf2ef0e5df7f602316c" integrity sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA== @@ -10623,6 +10711,13 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" +pkg-up@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" + integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA== + dependencies: + find-up "^3.0.0" + pkg-up@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" @@ -10630,22 +10725,15 @@ pkg-up@^2.0.0: dependencies: find-up "^2.1.0" -pkg-up@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" - integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA== - dependencies: - find-up "^3.0.0" - platform@1.3.6: version "1.3.6" resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.6.tgz#48b4ce983164b209c2d45a107adb31f473a6e7a7" integrity sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg== -playwright@^1.13.1: - version "1.13.1" - resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.13.1.tgz#53c49244ffa7fc2d5d8bf7ce87739393206eda5e" - integrity sha512-pGbILcUV1+Yx0fcRJZBEIsqTDjQSwGYkJ4tVUQUtuAyMuHg5B++Nasl+pIeIJRMqKSWTyvZfPxJuPIGsLJgiFg== +playwright@^1.14.0: + version "1.14.0" + resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.14.0.tgz#18301b11f5278a446d36b5cf96f67db36ce2cd20" + integrity sha512-aR5oZ1iVsjQkGfYCjgYAmyMAVu0MQ0i8MgdnfdqDu9EVLfbnpuuFmTv/Rb7/Yjno1kOrDUP9+RyNC+zfG3wozA== dependencies: commander "^6.1.0" debug "^4.1.1" @@ -10693,6 +10781,15 @@ postcss@8.2.13: nanoid "^3.1.22" source-map "^0.6.1" +postcss@8.2.15: + version "8.2.15" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.15.tgz#9e66ccf07292817d226fc315cbbf9bc148fbca65" + integrity sha512-2zO3b26eJD/8rb106Qu2o7Qgg52ND5HPjcyQiK2B98O388h43A448LCslC0dI2P97wCAQRJsFvwTRcXxTKds+Q== + dependencies: + colorette "^1.2.2" + nanoid "^3.1.23" + source-map "^0.6.1" + preferred-pm@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/preferred-pm/-/preferred-pm-3.0.3.tgz#1b6338000371e3edbce52ef2e4f65eb2e73586d6" @@ -10733,17 +10830,7 @@ pretty-bytes@^5.4.1: resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== -pretty-format@^26.0.0, pretty-format@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93" - integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg== - dependencies: - "@jest/types" "^26.6.2" - ansi-regex "^5.0.0" - ansi-styles "^4.0.0" - react-is "^17.0.1" - -pretty-format@^27.0.2, pretty-format@^27.0.6: +pretty-format@^27.0.0, pretty-format@^27.0.2, pretty-format@^27.0.6: version "27.0.6" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.0.6.tgz#ab770c47b2c6f893a21aefc57b75da63ef49a11f" integrity sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ== @@ -10763,12 +10850,12 @@ prism-react-renderer@^1.2.1: resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-1.2.1.tgz#392460acf63540960e5e3caa699d851264e99b89" integrity sha512-w23ch4f75V1Tnz8DajsYKvY5lF7H1+WvzvLUcF0paFxkTHSp42RS0H5CttdN2Q8RR3DRGZ9v5xD/h3n8C8kGmg== -prisma@2.28.0: - version "2.28.0" - resolved "https://registry.yarnpkg.com/prisma/-/prisma-2.28.0.tgz#33adb56e336d4c4569ec2f49df9b606771df15d0" - integrity sha512-f83KPLy3xk07KMY4e5otNwP2I+GsdftjOfu3e8snXylnyAC1oEpRZNe7rmONr0vAI+Qgz3LFRArhWUE/dFjKIA== +prisma@2.29.1: + version "2.29.1" + resolved "https://registry.yarnpkg.com/prisma/-/prisma-2.29.1.tgz#7845f55c7f09955b01f973c6a4b1f330cb212e7d" + integrity sha512-fRGh90+z0m3Jw3D6KBE6wyVCRR0w6M6QD93jh+em8IOQycmC48zB8hho8zeri3J9//C0k8fkDeQrRLJUosXROw== dependencies: - "@prisma/engines" "2.28.0-17.89facabd0366f63911d089156a7a70125bfbcd27" + "@prisma/engines" "2.29.0-34.1be4cd60b89afa04b192acb1ef47758a39810f3a" process-nextick-args@~2.0.0: version "2.0.1" @@ -10785,7 +10872,7 @@ progress@^2.0.0, progress@^2.0.3: resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== -prompts@^2.0.1, prompts@^2.3.2, prompts@^2.4.1: +prompts@2.4.1, prompts@^2.0.1, prompts@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.1.tgz#befd3b1195ba052f9fd2fde8a486c4e82ee77f61" integrity sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ== @@ -11069,7 +11156,7 @@ react-is@16.13.1, react-is@^16.7.0, react-is@^16.8.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react-is@^17.0.1: +react-is@17.0.2, react-is@^17.0.1: version "17.0.2" resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== @@ -11154,15 +11241,7 @@ react@^17.0.2: loose-envify "^1.1.0" object-assign "^4.1.1" -read-pkg-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" - integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= - dependencies: - find-up "^2.0.0" - read-pkg "^3.0.0" - -read-pkg-up@^7.0.1: +read-pkg-up@7.0.1, read-pkg-up@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== @@ -11171,6 +11250,14 @@ read-pkg-up@^7.0.1: read-pkg "^5.2.0" type-fest "^0.8.1" +read-pkg-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" + integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= + dependencies: + find-up "^2.0.0" + read-pkg "^3.0.0" + read-pkg@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" @@ -11570,7 +11657,7 @@ resolve-from@^5.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== -resolve-pkg@^2.0.0: +resolve-pkg@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-pkg/-/resolve-pkg-2.0.0.tgz#ac06991418a7623edc119084edc98b0e6bf05a41" integrity sha512-+1lzwXehGCXSeryaISr6WujZzowloigEofRB+dj75y9RRa/obVcYgbHJd53tdYw8pvZj8GojXaaENws8Ktw/hQ== @@ -11582,7 +11669,7 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.2.0, resolve@^1.20.0: +resolve@1.20.0, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.20.0: version "1.20.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== @@ -11649,7 +11736,7 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rimraf@^3.0.0, rimraf@^3.0.2: +rimraf@3.0.2, rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== @@ -11665,9 +11752,9 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: inherits "^2.0.1" rollup@^2.32.0: - version "2.55.1" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.55.1.tgz#66a444648e2fb603d8e329e77a61c608a6510fda" - integrity sha512-1P9w5fpb6b4qroePh8vHKGIvPNxwoCQhjJpIqfZGHLKpZ0xcU2/XBmFxFbc9697/6bmHpmFTLk5R1dAQhFSo0g== + version "2.56.2" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.56.2.tgz#a045ff3f6af53ee009b5f5016ca3da0329e5470f" + integrity sha512-s8H00ZsRi29M2/lGdm1u8DJpJ9ML8SUOpVVBd33XNeEeL3NVaTiUcSBHzBdF3eAyR0l7VSpsuoVUGrRHq7aPwQ== optionalDependencies: fsevents "~2.3.2" @@ -11734,15 +11821,6 @@ scheduler@^0.20.2: loose-envify "^1.1.0" object-assign "^4.1.1" -schema-utils@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" - integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== - dependencies: - "@types/json-schema" "^7.0.8" - ajv "^6.12.5" - ajv-keywords "^3.5.2" - scroll-into-view-if-needed@^2.2.20, scroll-into-view-if-needed@^2.2.28: version "2.2.28" resolved "https://registry.yarnpkg.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.28.tgz#5a15b2f58a52642c88c8eca584644e01703d645a" @@ -11876,7 +11954,7 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shell-quote@1.7.2, shell-quote@^1.7.2: +shell-quote@1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== @@ -12117,9 +12195,9 @@ spdx-expression-parse@^3.0.0: spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.9" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz#8a595135def9592bda69709474f1cbeea7c2467f" - integrity sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ== + version "3.0.10" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz#0d9becccde7003d6c658d487dd48a32f0bf3014b" + integrity sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA== split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" @@ -12286,6 +12364,15 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" +string-width@4.2.2, string-width@^4.1.0, string-width@^4.2.0: + version "4.2.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" + integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -12303,15 +12390,6 @@ string-width@^2.0.0, string-width@^2.1.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -string-width@^4.1.0, string-width@^4.2.0: - version "4.2.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" - integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.0" - string.prototype.matchall@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz#59370644e1db7e4c0c045277690cf7b01203c4da" @@ -12450,10 +12528,10 @@ strip-outer@^1.0.1: dependencies: escape-string-regexp "^1.0.2" -stripe@^8.167.0: - version "8.167.0" - resolved "https://registry.yarnpkg.com/stripe/-/stripe-8.167.0.tgz#a7d7bd3828fa34210f9101b061b10f56b3a45b18" - integrity sha512-iWrof4zc/TRjzKr181Tj5Tz/RaxpNQjqkkVjjfqmzXuSY1tNV4HTbS26ucsBNkw2MJZr/q1Hx8gWDRdhZ8FG2g== +stripe@^8.169.0: + version "8.169.0" + resolved "https://registry.yarnpkg.com/stripe/-/stripe-8.169.0.tgz#5970cc055872fccbc49713f6428a682ece7f3e76" + integrity sha512-h4JVMGnhYwkEu8dFHX0MewtTFEWcjJQ2zTiFcvhW5toa/2JcEeObfwH27Z29A6t/6s2vnXrXxEnuyL7gBBAXqA== dependencies: "@types/node" ">=8.1.0" qs "^6.6.0" @@ -12479,6 +12557,20 @@ styled-jsx@3.3.2: stylis "3.5.4" stylis-rule-sheet "0.0.10" +styled-jsx@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-4.0.0.tgz#f7b90e7889d0a4f4635f8d1ae9ac32f3acaedc57" + integrity sha512-2USeoWMoJ/Lx5s2y1PxuvLy/cz2Yrr8cTySV3ILHU1Vmaw1bnV7suKdblLPjnyhMD+qzN7B1SWyh4UZTARn/WA== + dependencies: + "@babel/plugin-syntax-jsx" "7.14.5" + "@babel/types" "7.15.0" + convert-source-map "1.7.0" + loader-utils "1.2.3" + source-map "0.7.3" + string-hash "1.1.3" + stylis "3.5.4" + stylis-rule-sheet "0.0.10" + stylis-rule-sheet@0.0.10: version "0.0.10" resolved "https://registry.yarnpkg.com/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz#44e64a2b076643f4b52e5ff71efc04d8c3c4a430" @@ -12522,10 +12614,10 @@ superagent@^6.1.0: readable-stream "^3.6.0" semver "^7.3.2" -supertest@^6.1.4: - version "6.1.4" - resolved "https://registry.yarnpkg.com/supertest/-/supertest-6.1.4.tgz#ea8953343e0ca316e80e975b39340934f754eb06" - integrity sha512-giC9Zm+Bf1CZP09ciPdUyl+XlMAu6rbch79KYiYKOGcbK2R1wH8h+APul1i/3wN6RF1XfWOIF+8X1ga+7SBrug== +supertest@^6.1.5: + version "6.1.5" + resolved "https://registry.yarnpkg.com/supertest/-/supertest-6.1.5.tgz#b011c8465281b30c64e9d4be4cb3808b91cd1ec0" + integrity sha512-Is3pFB2TxSFPohDS2tIM8h2JOMvUQwbJ9TvTfsWAm89ZZv1CF4VTLAsQz+5+5S1wOgaMqFqSpFriU15L3e2AXQ== dependencies: methods "^1.1.2" superagent "^6.1.0" @@ -12603,10 +12695,10 @@ symbol-tree@^3.2.4: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== -tabbable@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-5.2.0.tgz#4fba60991d8bb89d06e5d9455c92b453acf88fb2" - integrity sha512-0uyt8wbP0P3T4rrsfYg/5Rg3cIJ8Shl1RJ54QMqYxm1TLdWqJD1u6+RQjr2Lor3wmfT7JRHkirIwy99ydBsyPg== +tabbable@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-5.2.1.tgz#e3fda7367ddbb172dcda9f871c0fdb36d1c4cd9c" + integrity sha512-40pEZ2mhjaZzK0BnI+QGNjJO8UYx9pP5v7BGe17SORTO0OEuuaAwQTkAp8whcZvqon44wKFOikD+Al11K3JICQ== table@^6.0.9: version "6.7.1" @@ -12631,10 +12723,10 @@ tar-stream@^2.1.2: inherits "^2.0.3" readable-stream "^3.1.1" -tar@^6.0.1: - version "6.1.3" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.3.tgz#e44b97ee7d6cc7a4c574e8b01174614538291825" - integrity sha512-3rUqwucgVZXTeyJyL2jqtUau8/8r54SioM1xj3AmTX3HnWQdj2AydfJ2qYYayPyIIznSplcvU9mhBb7dR2XF3w== +tar@6.1.6: + version "6.1.6" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.6.tgz#c23d797b0a1efe5d479b1490805c5443f3560c5d" + integrity sha512-oaWyu5dQbHaYcyZCTfyPpC+VmI62/OM2RTUYavTk1MDr1cwW5Boi3baeYQKiZbY2uSQJGr+iMOzb/JFxLrft+g== dependencies: chownr "^2.0.0" fs-minipass "^2.0.0" @@ -12643,17 +12735,17 @@ tar@^6.0.1: mkdirp "^1.0.3" yallist "^4.0.0" +temp-dir@2.0.0, temp-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-2.0.0.tgz#bde92b05bdfeb1516e804c9c00ad45177f31321e" + integrity sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg== + temp-dir@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" integrity sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0= -temp-dir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-2.0.0.tgz#bde92b05bdfeb1516e804c9c00ad45177f31321e" - integrity sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg== - -temp-write@^4.0.0: +temp-write@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/temp-write/-/temp-write-4.0.0.tgz#cd2e0825fc826ae72d201dc26eef3bf7e6fc9320" integrity sha512-HIeWmj77uOOHb0QX7siN3OtwV3CTntquin6TNVg6SHOqCP3hYKmox90eeFOGaY1MqJ9WYDDjkyZrW6qS5AWpbw== @@ -12664,15 +12756,7 @@ temp-write@^4.0.0: temp-dir "^1.0.0" uuid "^3.3.2" -tempy@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/tempy/-/tempy-0.2.1.tgz#9038e4dbd1c201b74472214179bc2c6f7776e54c" - integrity sha512-LB83o9bfZGrntdqPuRdanIVCPReam9SOZKW0fOy5I9X3A854GGWi0tjCqoXEk84XIEYBc/x9Hq3EFop/H5wJaw== - dependencies: - temp-dir "^1.0.0" - unique-string "^1.0.0" - -tempy@^1.0.0: +tempy@1.0.1, tempy@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/tempy/-/tempy-1.0.1.tgz#30fe901fd869cfb36ee2bd999805aa72fbb035de" integrity sha512-biM9brNqxSc04Ee71hzFbryD11nX7VPhQQY32AdDmjFvodsRFz/3ufeoTZ6uYkRFfGo188tENcASNs3vTdsM0w== @@ -12683,6 +12767,14 @@ tempy@^1.0.0: type-fest "^0.16.0" unique-string "^2.0.0" +tempy@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tempy/-/tempy-0.2.1.tgz#9038e4dbd1c201b74472214179bc2c6f7776e54c" + integrity sha512-LB83o9bfZGrntdqPuRdanIVCPReam9SOZKW0fOy5I9X3A854GGWi0tjCqoXEk84XIEYBc/x9Hq3EFop/H5wJaw== + dependencies: + temp-dir "^1.0.0" + unique-string "^1.0.0" + term-size@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" @@ -12703,7 +12795,7 @@ terminal-link-cli@^3.0.0: meow "^9.0.0" terminal-link "^3.0.0" -terminal-link@^2.0.0, terminal-link@^2.1.1: +terminal-link@2.1.1, terminal-link@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== @@ -12970,10 +13062,10 @@ ts-invariant@^0.4.0: dependencies: tslib "^1.9.3" -ts-invariant@^0.8.0: - version "0.8.2" - resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.8.2.tgz#62af654ebfb8b1eeb55bc9adc2f40c6b93b0ff7e" - integrity sha512-VI1ZSMW8soizP5dU8DsMbj/TncHf7bIUqavuE7FTeYeQat454HHurJ8wbfCnVWcDOMkyiBUWOW2ytew3xUxlRw== +ts-invariant@^0.9.0: + version "0.9.1" + resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.9.1.tgz#87dfde9894a4ce3c7711b02b1b449e7fd7384b13" + integrity sha512-hSeYibh29ULlHkuEfukcoiyTct+s2RzczMLTv4x3NWC/YrBy7x7ps5eYq/b4Y3Sb9/uAlf54+/5CAEMVxPhuQw== dependencies: tslib "^2.1.0" @@ -12996,10 +13088,10 @@ tslib@^1.0.0, tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.3, tslib@^2.1.0, tslib@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e" - integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== +tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.0, tslib@~2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" + integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== tslib@~2.1.0: version "2.1.0" @@ -13107,9 +13199,9 @@ type-fest@^0.8.0, type-fest@^0.8.1: integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== type-fest@^1.0.2: - version "1.3.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.3.0.tgz#6be848243853df1173fa95530112e1358ab0810b" - integrity sha512-mYUYkAy6fPatVWtUeCV/qGeGL3IVucmdJOzeAEfwgCJDx8gP0JaW8jn6KQ5xDfPec31e0KXWn5EUOZMhquR1zA== + version "1.4.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1" + integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA== type-is@^1.6.16, type-is@~1.6.17, type-is@~1.6.18: version "1.6.18" @@ -13443,15 +13535,6 @@ urix@^0.1.0: resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= -url-loader@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-4.1.1.tgz#28505e905cae158cf07c92ca622d7f237e70a4e2" - integrity sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA== - dependencies: - loader-utils "^2.0.0" - mime-types "^2.1.27" - schema-utils "^3.0.0" - url-parse-lax@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" @@ -13625,9 +13708,9 @@ vfile-location@^2.0.0: integrity sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA== vfile-message@*: - version "3.0.1" - resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-3.0.1.tgz#b9bcf87cb5525e61777e0c6df07e816a577588a3" - integrity sha512-gYmSHcZZUEtYpTmaWaFJwsuUD70/rTY4v09COp8TGtOkix6gGxb/a8iTQByIY9ciTk9GwAwIXd/J9OPfM4Bvaw== + version "3.0.2" + resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-3.0.2.tgz#db7eaebe7fecb853010f2ef1664427f52baf8f74" + integrity sha512-UUjZYIOg9lDRwwiBAuezLIsu9KlXntdxwG+nXnjuQAHvBpcX3x0eN8h+I7TkY5nkCXj+cWVp4ZqebtGBvok8ww== dependencies: "@types/unist" "^2.0.0" unist-util-stringify-position "^3.0.0" @@ -13818,17 +13901,16 @@ which-pm@2.0.0: path-exists "^4.0.0" which-typed-array@^1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.4.tgz#8fcb7d3ee5adf2d771066fba7cf37e32fe8711ff" - integrity sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA== + version "1.1.6" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.6.tgz#f3713d801da0720a7f26f50c596980a9f5c8b383" + integrity sha512-DdY984dGD5sQ7Tf+x1CkXzdg85b9uEel6nr4UkFg1LoE9OXv3uRuZhe5CoWdawhGACeFpEZXH8fFLQnDhbpm/Q== dependencies: - available-typed-arrays "^1.0.2" - call-bind "^1.0.0" - es-abstract "^1.18.0-next.1" + available-typed-arrays "^1.0.4" + call-bind "^1.0.2" + es-abstract "^1.18.5" foreach "^2.0.5" - function-bind "^1.1.1" - has-symbols "^1.0.1" - is-typed-array "^1.1.3" + has-tostringtag "^1.0.0" + is-typed-array "^1.1.6" which@^1.2.9: version "1.3.1" @@ -14040,7 +14122,15 @@ zen-observable-ts@^0.8.21: tslib "^1.9.3" zen-observable "^0.8.0" -zen-observable@^0.8.0, zen-observable@^0.8.14: +zen-observable-ts@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-1.1.0.tgz#2d1aa9d79b87058e9b75698b92791c1838551f83" + integrity sha512-1h4zlLSqI2cRLPJUHJFL8bCWHhkpuXkF+dbGkRaWjgDIG26DmzyshUMrdV/rL3UnR+mhaX4fRq8LPouq0MYYIA== + dependencies: + "@types/zen-observable" "0.8.3" + zen-observable "0.8.15" + +zen-observable@0.8.15, zen-observable@^0.8.0: version "0.8.15" resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.15.tgz#96415c512d8e3ffd920afd3889604e30b9eaac15" integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==