From fa6a7e4081b2faa9ab23ed63f2b5465479546b07 Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Thu, 16 Jun 2022 02:12:36 +0200 Subject: [PATCH 1/9] nextra setup move getting-started/index.mdx move getting-started/installation.mdx move getting-started/development-workflow move guides/further-reading getting-started/index.mdx move to src/pages/docs getting-started/installation.mdx guides/react getting-started/vue.mdx getting-started/angular.mdx getting-started/svelte.mdx getting-started/front-end-typescript-only.mdx getting-started/apollo getting-started/graphqlmodules.mdx getting-started/angular.mdx move config-reference docs/config-reference/codegen-config getting-started/schema-field.mdx getting-started/documents.mdx getting-started/config-field.mdx getting-started/require-field.mdx getting-started/naming-convention.mdx getting-started/lifecycle-hooks move advanced advanced/generated-files-colocation remove isDev advanced/programmatic advanced/how-does-it-work advanced/profiler move integrations all integrations custom codegen custom-codegen migration setup plugins page fixes fixes fixes patch temp-styles ok, styles works react-apollo, react-query, resolvers operations, oclif new plugins migrated migrate new plugins new plugins migrate plugins migrate plugins migrate plugins migrate plugins migrate apollo-angular and client-helpers to typescript folder c-sharp migrate flow in folder move presets move other migrate java move typescripts move typescripts move typescripts add plugin hub page, fix layout: raw ok it's works remove unused deps generate config schema add legacy redirects add patches for nextra fix deploy yet another fix remove enhance code-blocks with filename prettier use latest next and guild-components --- .gitignore | 17 +- .prettierignore | 5 - .../plugins/flow/operations/src/config.ts | 6 +- .../other/fragment-matcher/src/index.ts | 8 +- .../plugins/other/introspection/src/index.ts | 2 +- .../plugins/other/schema-ast/src/index.ts | 6 +- packages/plugins/other/time/src/config.ts | 4 +- .../other/urql-introspection/src/index.ts | 2 +- .../src/base-resolvers-visitor.ts | 2 +- .../src/base-types-visitor.ts | 2 +- .../visitor-plugin-common/src/base-visitor.ts | 12 +- .../typescript/typescript/src/config.ts | 2 +- .../presets/gql-tag-operations/src/index.ts | 4 +- packages/presets/import-types/src/index.ts | 4 +- .../presets/near-operation-file/src/index.ts | 12 +- patches/nextra+2.0.0-alpha.56.patch | 892 ++++++++++++++++++ .../nextra-theme-docs+2.0.0-alpha.59.patch | 745 +++++++++++++++ prettier.config.cjs | 3 + website/.babelrc.js | 14 - website/.eslintrc.js | 11 - website/docs-templates/client-note.md | 5 - website/docs-templates/flow-operations.md | 7 - website/docs-templates/import-types-preset.md | 7 - website/docs-templates/introspection.md | 5 - website/docs-templates/java-resolvers.md | 27 - website/docs-templates/java.md | 42 - website/docs-templates/jsdoc.md | 7 - website/docs-templates/schema-ast.md | 19 - website/docs-templates/time.md | 5 - .../docs-templates/typescript-generic-sdk.md | 13 - .../docs-templates/typescript-operations.md | 7 - website/docs-templates/typescript.md | 5 - website/docs-templates/urql-introspection.md | 15 - website/docs/integrations/gatsby.mdx | 14 - website/next-i18next.config.js | 4 - website/next.config.mjs | 59 +- website/package.json | 30 +- website/postcss.config.js | 7 + website/public/config.schema.json | 34 +- website/public/locales/en/common.json | 3 - website/public/style.css | 61 +- website/routes.ts | 87 -- website/src/category-to-packages.mjs | 49 + website/src/components/MDXTabs/MDXTab.tsx | 16 - website/src/components/MDXTabs/MDXTabs.tsx | 101 -- .../components/MDXTabsCurrentTabContext.tsx | 28 - website/src/components/MDXWarning.tsx | 17 - website/src/components/index.ts | 2 + .../components/live-demo/CodegenOutput.tsx | 6 +- website/src/components/live-demo/Editor.tsx | 15 +- website/src/components/live-demo/LiveDemo.tsx | 13 +- website/src/components/live-demo/examples.ts | 8 +- website/src/components/live-demo/generate.ts | 6 +- .../components/live-demo/styles.module.css | 10 - website/src/components/package-api-docs.tsx | 89 ++ website/src/components/package-cmd.tsx | 87 ++ website/src/components/plugin-hub.tsx | 97 ++ website/src/components/ui/Markdown.tsx | 5 +- website/src/lib/docs-generator.ts | 3 +- website/src/lib/get-npm-info.tsx | 39 + website/src/lib/plugins.ts | 331 +++---- website/src/lib/transform.ts | 2 +- website/src/pages/_app.tsx | 184 +--- website/src/pages/_document.tsx | 7 +- website/src/pages/docs/[[...slug]].tsx | 34 - .../advanced/generated-files-colocation.mdx | 77 +- .../pages}/docs/advanced/how-does-it-work.mdx | 20 +- website/src/pages/docs/advanced/meta.json | 6 + .../pages}/docs/advanced/profiler.mdx | 9 +- .../docs/advanced/programmatic-usage.mdx | 45 +- .../docs/config-reference/codegen-config.mdx | 53 +- .../docs/config-reference/config-field.mdx | 17 +- .../docs/config-reference/documents-field.mdx | 43 +- .../docs/config-reference/lifecycle-hooks.mdx | 14 +- .../src/pages/docs/config-reference/meta.json | 9 + .../config-reference/multiproject-config.mdx | 0 .../config-reference/naming-convention.mdx | 10 +- .../docs/config-reference/require-field.mdx | 21 +- .../docs/config-reference/schema-field.mdx | 70 +- .../docs/custom-codegen/contributing.mdx | 70 +- .../docs/custom-codegen/extend-schema.mdx | 27 +- .../pages}/docs/custom-codegen/index.mdx | 5 +- .../src/pages/docs/custom-codegen/meta.json | 8 + .../docs/custom-codegen/plugin-structure.mdx | 36 +- .../docs/custom-codegen/using-visitor.mdx | 21 +- .../custom-codegen/validate-configuration.mdx | 23 +- .../getting-started/development-workflow.mdx | 20 +- .../pages}/docs/getting-started/index.mdx | 192 ++-- .../docs/getting-started/installation.mdx | 51 +- .../src/pages/docs/getting-started/meta.json | 5 + .../{ => src/pages}/docs/guides/angular.mdx | 60 +- .../docs/guides/front-end-typescript-only.mdx | 44 +- .../pages}/docs/guides/further-reading.mdx | 24 +- .../pages}/docs/guides/graphql-modules.mdx | 43 +- .../guides/graphql-server-apollo-yoga.mdx | 112 +-- website/src/pages/docs/guides/meta.json | 10 + website/{ => src/pages}/docs/guides/react.mdx | 312 ++---- .../{ => src/pages}/docs/guides/svelte.mdx | 88 +- website/{ => src/pages}/docs/guides/vue.mdx | 99 +- .../docs/integrations/apollo-local-state.mdx | 7 +- .../docs/integrations/create-react-app.mdx | 5 +- .../pages}/docs/integrations/federation.mdx | 7 +- .../src/pages/docs/integrations/gatsby.mdx | 13 + website/src/pages/docs/integrations/meta.json | 8 + .../pages}/docs/integrations/prettier.mdx | 5 +- .../pages}/docs/integrations/vscode.mdx | 5 +- website/src/pages/docs/meta.json | 9 + .../pages}/docs/migration/from-0-13.mdx | 25 +- .../pages}/docs/migration/from-0-18.mdx | 78 +- website/src/pages/docs/migration/meta.json | 4 + website/src/pages/index.mdx | 42 + website/src/pages/index.tsx | 59 -- website/src/pages/meta.json | 29 + website/src/pages/plugin-hub/[name].tsx.old | 225 +++++ .../c-sharp/c-sharp-operations.mdx} | 13 +- .../src/pages/plugin-hub/c-sharp/meta.json | 3 + .../pages/plugin-hub/flow/flow-operations.mdx | 7 + .../pages/plugin-hub/flow/flow-resolvers.mdx} | 31 +- website/src/pages/plugin-hub/flow/meta.json | 4 + website/src/pages/plugin-hub/index.mdx | 35 + .../plugin-hub/java/java-apollo-android.mdx} | 27 +- .../pages/plugin-hub/java/java-resolvers.mdx | 83 ++ .../pages/plugin-hub/java/java.mdx} | 55 +- .../pages/plugin-hub/java/kotlin.mdx} | 21 +- website/src/pages/plugin-hub/java/meta.json | 6 + website/src/pages/plugin-hub/meta.json | 13 + .../pages/plugin-hub/other/add.mdx} | 21 +- .../plugin-hub/other/fragment-matcher.mdx} | 30 +- .../plugin-hub/other/hasura-allow-list.mdx} | 21 +- .../pages/plugin-hub/other/introspection.mdx | 7 + website/src/pages/plugin-hub/other/jsdoc.mdx | 10 + website/src/pages/plugin-hub/other/meta.json | 11 + .../pages/plugin-hub/other/reason-client.mdx} | 13 +- .../src/pages/plugin-hub/other/schema-ast.mdx | 22 + website/src/pages/plugin-hub/other/time.mdx | 7 + .../plugin-hub/other/urql-introspection.mdx | 21 + .../presets/gql-tag-operations-preset.mdx} | 68 +- .../presets/graphql-modules-preset.mdx} | 33 +- .../presets/import-types-preset.mdx | 11 + .../src/pages/plugin-hub/presets/meta.json | 6 + .../presets/near-operation-file-preset.mdx} | 18 +- .../src/pages/plugin-hub/typescript/meta.json | 29 + .../typescript/named-operations-object.mdx} | 13 +- .../typescript/relay-operation-optimizer.mdx} | 23 +- .../typescript/typed-document-node.mdx} | 25 +- .../typescript/typescript-apollo-angular.mdx} | 21 +- .../typescript-apollo-client-helpers.mdx} | 23 +- .../typescript/typescript-apollo-next.mdx} | 43 +- .../typescript/typescript-document-nodes.mdx} | 10 +- .../typescript/typescript-generic-sdk.mdx | 15 + .../typescript-graphql-files-modules.mdx} | 19 +- .../typescript-graphql-request.mdx} | 14 +- .../typescript/typescript-mongodb.mdx} | 26 +- .../plugin-hub/typescript/typescript-msw.mdx} | 16 +- .../typescript/typescript-oclif.mdx} | 20 +- .../typescript/typescript-operations.mdx | 7 + .../typescript/typescript-react-apollo.mdx} | 26 +- .../typescript/typescript-react-query.mdx} | 40 +- .../typescript/typescript-resolvers.mdx} | 45 +- .../typescript/typescript-rtk-query.mdx} | 36 +- .../typescript/typescript-stencil-apollo.mdx} | 12 +- .../typescript/typescript-svelte-apollo.mdx} | 15 +- .../typescript/typescript-type-graphql.mdx} | 11 +- .../typescript/typescript-urql.mdx} | 16 +- .../typescript-validation-schema.mdx} | 15 +- .../typescript-vue-apollo-smart-ops.mdx} | 12 +- .../typescript/typescript-vue-apollo.mdx} | 24 +- .../typescript/typescript-vue-urql.mdx} | 12 +- .../plugin-hub/typescript/typescript.mdx | 7 + website/src/pages/plugins/[name].tsx | 200 ---- website/src/pages/plugins/index.tsx | 130 --- website/src/theme/Root.tsx | 15 - website/tailwind.config.cjs | 21 + website/theme.config.tsx | 38 + website/tsconfig.json | 5 +- website/twin.d.ts | 30 - 176 files changed, 4231 insertions(+), 2910 deletions(-) create mode 100644 patches/nextra+2.0.0-alpha.56.patch create mode 100644 patches/nextra-theme-docs+2.0.0-alpha.59.patch delete mode 100644 website/.babelrc.js delete mode 100644 website/docs-templates/client-note.md delete mode 100644 website/docs-templates/flow-operations.md delete mode 100644 website/docs-templates/import-types-preset.md delete mode 100644 website/docs-templates/introspection.md delete mode 100644 website/docs-templates/java-resolvers.md delete mode 100644 website/docs-templates/java.md delete mode 100644 website/docs-templates/jsdoc.md delete mode 100644 website/docs-templates/schema-ast.md delete mode 100644 website/docs-templates/time.md delete mode 100644 website/docs-templates/typescript-generic-sdk.md delete mode 100644 website/docs-templates/typescript-operations.md delete mode 100644 website/docs-templates/typescript.md delete mode 100644 website/docs-templates/urql-introspection.md delete mode 100644 website/docs/integrations/gatsby.mdx delete mode 100644 website/next-i18next.config.js create mode 100644 website/postcss.config.js delete mode 100644 website/public/locales/en/common.json create mode 100644 website/src/category-to-packages.mjs delete mode 100644 website/src/components/MDXTabs/MDXTab.tsx delete mode 100644 website/src/components/MDXTabs/MDXTabs.tsx delete mode 100644 website/src/components/MDXTabsCurrentTabContext.tsx delete mode 100644 website/src/components/MDXWarning.tsx create mode 100644 website/src/components/index.ts create mode 100644 website/src/components/package-api-docs.tsx create mode 100644 website/src/components/package-cmd.tsx create mode 100644 website/src/components/plugin-hub.tsx create mode 100644 website/src/lib/get-npm-info.tsx delete mode 100644 website/src/pages/docs/[[...slug]].tsx rename website/{ => src/pages}/docs/advanced/generated-files-colocation.mdx (56%) rename website/{ => src/pages}/docs/advanced/how-does-it-work.mdx (95%) create mode 100644 website/src/pages/docs/advanced/meta.json rename website/{ => src/pages}/docs/advanced/profiler.mdx (82%) rename website/{ => src/pages}/docs/advanced/programmatic-usage.mdx (66%) rename website/{ => src/pages}/docs/config-reference/codegen-config.mdx (93%) rename website/{ => src/pages}/docs/config-reference/config-field.mdx (75%) rename website/{ => src/pages}/docs/config-reference/documents-field.mdx (82%) rename website/{ => src/pages}/docs/config-reference/lifecycle-hooks.mdx (86%) create mode 100644 website/src/pages/docs/config-reference/meta.json rename website/{ => src/pages}/docs/config-reference/multiproject-config.mdx (100%) rename website/{ => src/pages}/docs/config-reference/naming-convention.mdx (96%) rename website/{ => src/pages}/docs/config-reference/require-field.mdx (88%) rename website/{ => src/pages}/docs/config-reference/schema-field.mdx (83%) rename website/{ => src/pages}/docs/custom-codegen/contributing.mdx (76%) rename website/{ => src/pages}/docs/custom-codegen/extend-schema.mdx (72%) rename website/{ => src/pages}/docs/custom-codegen/index.mdx (95%) create mode 100644 website/src/pages/docs/custom-codegen/meta.json rename website/{ => src/pages}/docs/custom-codegen/plugin-structure.mdx (85%) rename website/{ => src/pages}/docs/custom-codegen/using-visitor.mdx (92%) rename website/{ => src/pages}/docs/custom-codegen/validate-configuration.mdx (70%) rename website/{ => src/pages}/docs/getting-started/development-workflow.mdx (91%) rename website/{ => src/pages}/docs/getting-started/index.mdx (82%) rename website/{ => src/pages}/docs/getting-started/installation.mdx (61%) create mode 100644 website/src/pages/docs/getting-started/meta.json rename website/{ => src/pages}/docs/guides/angular.mdx (77%) rename website/{ => src/pages}/docs/guides/front-end-typescript-only.mdx (71%) rename website/{ => src/pages}/docs/guides/further-reading.mdx (76%) rename website/{ => src/pages}/docs/guides/graphql-modules.mdx (73%) rename website/{ => src/pages}/docs/guides/graphql-server-apollo-yoga.mdx (70%) create mode 100644 website/src/pages/docs/guides/meta.json rename website/{ => src/pages}/docs/guides/react.mdx (78%) rename website/{ => src/pages}/docs/guides/svelte.mdx (83%) rename website/{ => src/pages}/docs/guides/vue.mdx (82%) rename website/{ => src/pages}/docs/integrations/apollo-local-state.mdx (95%) rename website/{ => src/pages}/docs/integrations/create-react-app.mdx (87%) rename website/{ => src/pages}/docs/integrations/federation.mdx (89%) create mode 100644 website/src/pages/docs/integrations/gatsby.mdx create mode 100644 website/src/pages/docs/integrations/meta.json rename website/{ => src/pages}/docs/integrations/prettier.mdx (96%) rename website/{ => src/pages}/docs/integrations/vscode.mdx (92%) create mode 100644 website/src/pages/docs/meta.json rename website/{ => src/pages}/docs/migration/from-0-13.mdx (57%) rename website/{ => src/pages}/docs/migration/from-0-18.mdx (73%) create mode 100644 website/src/pages/docs/migration/meta.json create mode 100644 website/src/pages/index.mdx delete mode 100644 website/src/pages/index.tsx create mode 100644 website/src/pages/meta.json create mode 100644 website/src/pages/plugin-hub/[name].tsx.old rename website/{docs-templates/c-sharp-operations.md => src/pages/plugin-hub/c-sharp/c-sharp-operations.mdx} (69%) create mode 100644 website/src/pages/plugin-hub/c-sharp/meta.json create mode 100644 website/src/pages/plugin-hub/flow/flow-operations.mdx rename website/{docs-templates/flow-resolvers.md => src/pages/plugin-hub/flow/flow-resolvers.mdx} (72%) create mode 100644 website/src/pages/plugin-hub/flow/meta.json create mode 100644 website/src/pages/plugin-hub/index.mdx rename website/{docs-templates/java-apollo-android.md => src/pages/plugin-hub/java/java-apollo-android.mdx} (60%) create mode 100644 website/src/pages/plugin-hub/java/java-resolvers.mdx rename website/{docs-templates/java-installation.md => src/pages/plugin-hub/java/java.mdx} (56%) rename website/{docs-templates/kotlin.md => src/pages/plugin-hub/java/kotlin.mdx} (56%) create mode 100644 website/src/pages/plugin-hub/java/meta.json create mode 100644 website/src/pages/plugin-hub/meta.json rename website/{docs-templates/add.md => src/pages/plugin-hub/other/add.mdx} (67%) rename website/{docs-templates/fragment-matcher.md => src/pages/plugin-hub/other/fragment-matcher.mdx} (54%) rename website/{docs-templates/hasura-allow-list.md => src/pages/plugin-hub/other/hasura-allow-list.mdx} (53%) create mode 100644 website/src/pages/plugin-hub/other/introspection.mdx create mode 100644 website/src/pages/plugin-hub/other/jsdoc.mdx create mode 100644 website/src/pages/plugin-hub/other/meta.json rename website/{docs-templates/reason-client.md => src/pages/plugin-hub/other/reason-client.mdx} (63%) create mode 100644 website/src/pages/plugin-hub/other/schema-ast.mdx create mode 100644 website/src/pages/plugin-hub/other/time.mdx create mode 100644 website/src/pages/plugin-hub/other/urql-introspection.mdx rename website/{docs-templates/gql-tag-operations-preset.md => src/pages/plugin-hub/presets/gql-tag-operations-preset.mdx} (85%) rename website/{docs-templates/graphql-modules-preset.md => src/pages/plugin-hub/presets/graphql-modules-preset.mdx} (72%) create mode 100644 website/src/pages/plugin-hub/presets/import-types-preset.mdx create mode 100644 website/src/pages/plugin-hub/presets/meta.json rename website/{docs-templates/near-operation-file-preset.md => src/pages/plugin-hub/presets/near-operation-file-preset.mdx} (70%) create mode 100644 website/src/pages/plugin-hub/typescript/meta.json rename website/{docs-templates/named-operations-object.md => src/pages/plugin-hub/typescript/named-operations-object.mdx} (86%) rename website/{docs-templates/relay-operation-optimizer.md => src/pages/plugin-hub/typescript/relay-operation-optimizer.mdx} (68%) rename website/{docs-templates/typed-document-node.md => src/pages/plugin-hub/typescript/typed-document-node.mdx} (76%) rename website/{docs-templates/typescript-apollo-angular.md => src/pages/plugin-hub/typescript/typescript-apollo-angular.mdx} (63%) rename website/{docs-templates/typescript-apollo-client-helpers.md => src/pages/plugin-hub/typescript/typescript-apollo-client-helpers.mdx} (63%) rename website/{docs-templates/typescript-apollo-next.md => src/pages/plugin-hub/typescript/typescript-apollo-next.mdx} (90%) rename website/{docs-templates/typescript-document-nodes.md => src/pages/plugin-hub/typescript/typescript-document-nodes.mdx} (65%) create mode 100644 website/src/pages/plugin-hub/typescript/typescript-generic-sdk.mdx rename website/{docs-templates/typescript-graphql-files-modules.md => src/pages/plugin-hub/typescript/typescript-graphql-files-modules.mdx} (73%) rename website/{docs-templates/typescript-graphql-request.md => src/pages/plugin-hub/typescript/typescript-graphql-request.mdx} (86%) rename website/{docs-templates/typescript-mongodb.md => src/pages/plugin-hub/typescript/typescript-mongodb.mdx} (91%) rename website/{docs-templates/typescript-msw.md => src/pages/plugin-hub/typescript/typescript-msw.mdx} (53%) rename website/{docs-templates/typescript-oclif.md => src/pages/plugin-hub/typescript/typescript-oclif.mdx} (94%) create mode 100644 website/src/pages/plugin-hub/typescript/typescript-operations.mdx rename website/{docs-templates/typescript-react-apollo.md => src/pages/plugin-hub/typescript/typescript-react-apollo.mdx} (69%) rename website/{docs-templates/typescript-react-query.md => src/pages/plugin-hub/typescript/typescript-react-query.mdx} (88%) rename website/{docs-templates/typescript-resolvers.md => src/pages/plugin-hub/typescript/typescript-resolvers.mdx} (76%) rename website/{docs-templates/typescript-rtk-query.md => src/pages/plugin-hub/typescript/typescript-rtk-query.mdx} (72%) rename website/{docs-templates/typescript-stencil-apollo.md => src/pages/plugin-hub/typescript/typescript-stencil-apollo.mdx} (56%) rename website/{docs-templates/typescript-svelte-apollo.md => src/pages/plugin-hub/typescript/typescript-svelte-apollo.mdx} (94%) rename website/{docs-templates/typescript-type-graphql.md => src/pages/plugin-hub/typescript/typescript-type-graphql.mdx} (77%) rename website/{docs-templates/typescript-urql.md => src/pages/plugin-hub/typescript/typescript-urql.mdx} (60%) rename website/{docs-templates/typescript-validation-schema.md => src/pages/plugin-hub/typescript/typescript-validation-schema.mdx} (70%) rename website/{docs-templates/typescript-vue-apollo-smart-ops.md => src/pages/plugin-hub/typescript/typescript-vue-apollo-smart-ops.mdx} (84%) rename website/{docs-templates/typescript-vue-apollo.md => src/pages/plugin-hub/typescript/typescript-vue-apollo.mdx} (86%) rename website/{docs-templates/typescript-vue-urql.md => src/pages/plugin-hub/typescript/typescript-vue-urql.mdx} (56%) create mode 100644 website/src/pages/plugin-hub/typescript/typescript.mdx delete mode 100644 website/src/pages/plugins/[name].tsx delete mode 100644 website/src/pages/plugins/index.tsx delete mode 100644 website/src/theme/Root.tsx create mode 100644 website/tailwind.config.cjs create mode 100644 website/theme.config.tsx delete mode 100644 website/twin.d.ts diff --git a/.gitignore b/.gitignore index dc97019a8ee..c82ce923f03 100644 --- a/.gitignore +++ b/.gitignore @@ -1,21 +1,14 @@ -.idea +.idea/ .npmrc .yarnclean .DS_Store coverage -npm-debug.log -lerna-debug.log -yarn-error.log -node_modules -website/build -website/functions -website/i18n -website/static/live-demo +*.log +node_modules/ temp -test-results/ junit.xml -dist -.bob +dist/ +.bob/ out.txt .cache tsconfig.tsbuildinfo diff --git a/.prettierignore b/.prettierignore index cde3a27fbfe..6a8f6f6f56e 100644 --- a/.prettierignore +++ b/.prettierignore @@ -8,8 +8,3 @@ dist/ CHANGELOG.md .husky/_/ .changeset/*.md - -# temporarly ignore follow files because prettier-ignore comments don't work in mdx2 -# see https://github.com/prettier/prettier/pull/12208 -website/docs/advanced/how-does-it-work.mdx -website/docs/getting-started/development-workflow.mdx diff --git a/packages/plugins/flow/operations/src/config.ts b/packages/plugins/flow/operations/src/config.ts index 6fba0784203..54f2562836d 100644 --- a/packages/plugins/flow/operations/src/config.ts +++ b/packages/plugins/flow/operations/src/config.ts @@ -13,7 +13,7 @@ export interface FlowDocumentsPluginConfig extends RawDocumentsConfig { * @default true * * @exampleMarkdown - * ```yaml + * ```yaml {6} * generates: * path/to/file.ts: * plugins: @@ -28,7 +28,7 @@ export interface FlowDocumentsPluginConfig extends RawDocumentsConfig { * @default false * * @exampleMarkdown - * ```yaml + * ```yaml {6} * generates: * path/to/file.ts: * plugins: @@ -43,7 +43,7 @@ export interface FlowDocumentsPluginConfig extends RawDocumentsConfig { * @default false * * @exampleMarkdown - * ```yaml + * ```yaml {7} * generates: * path/to/file.ts: * plugins: diff --git a/packages/plugins/other/fragment-matcher/src/index.ts b/packages/plugins/other/fragment-matcher/src/index.ts index 0af78169189..32122a9d94f 100644 --- a/packages/plugins/other/fragment-matcher/src/index.ts +++ b/packages/plugins/other/fragment-matcher/src/index.ts @@ -28,7 +28,7 @@ interface PossibleTypesResultData { * * If you are using `apollo-client` and your schema contains `interface` or `union` declaration, it's recommended to use Apollo's Fragment Matcher and the result generated by the plugin. * - * You can read more about it in `apollo-client` documentation: https://www.apollographql.com/docs/react/data/fragments/#fragments-on-unions-and-interfaces. + * You can read more about it in [`apollo-client` documentation](https://apollographql.com/docs/react/data/fragments/#fragments-on-unions-and-interfaces). * * Fragment Matcher plugin accepts a TypeScript / JavaScript or a JSON file as an output _(`.ts, .tsx, .js, .jsx, .json`)_. * @@ -42,7 +42,7 @@ export interface FragmentMatcherConfig { * @default es2015 * * @exampleMarkdown - * ```yaml + * ```yaml {6} * generates: * path/to/file.json: * plugins: @@ -57,7 +57,7 @@ export interface FragmentMatcherConfig { * @default 3 * * @exampleMarkdown - * ```yaml + * ```yaml {6} * generates: * path/to/file.ts: * plugins: @@ -72,7 +72,7 @@ export interface FragmentMatcherConfig { * @default false * * @exampleMarkdown - * ```yaml + * ```yaml {6} * generates: * path/to/file.ts: * plugins: diff --git a/packages/plugins/other/introspection/src/index.ts b/packages/plugins/other/introspection/src/index.ts index e4945655489..a34c672e8ce 100644 --- a/packages/plugins/other/introspection/src/index.ts +++ b/packages/plugins/other/introspection/src/index.ts @@ -12,7 +12,7 @@ export interface IntrospectionPluginConfig { * @default false * * @exampleMarkdown - * ```yaml + * ```yaml {6} * generates: * introspection.json: * plugins: diff --git a/packages/plugins/other/schema-ast/src/index.ts b/packages/plugins/other/schema-ast/src/index.ts index c929f3d1010..9fe369fdd56 100644 --- a/packages/plugins/other/schema-ast/src/index.ts +++ b/packages/plugins/other/schema-ast/src/index.ts @@ -26,7 +26,7 @@ export interface SchemaASTConfig { * @default false * * @exampleMarkdown - * ```yaml + * ```yaml {8} * schema: * - './src/schema.graphql' * generates: @@ -43,7 +43,7 @@ export interface SchemaASTConfig { * @default false * * @exampleMarkdown - * ```yaml + * ```yaml {8} * schema: * - './src/schema.graphql' * generates: @@ -60,7 +60,7 @@ export interface SchemaASTConfig { * @default false * * @exampleMarkdown - * ```yaml + * ```yaml {7} * schema: http://localhost:3000/graphql * generates: * schema.graphql: diff --git a/packages/plugins/other/time/src/config.ts b/packages/plugins/other/time/src/config.ts index 2632c5e5298..ffb70412298 100644 --- a/packages/plugins/other/time/src/config.ts +++ b/packages/plugins/other/time/src/config.ts @@ -4,7 +4,7 @@ export interface TimePluginConfig { * @default YYYY-MM-DDTHH:mm:ssZ * * @exampleMarkdown - * ```yaml + * ```yaml {4-5} * generates: * path/to/file.ts: * plugins: @@ -18,7 +18,7 @@ export interface TimePluginConfig { * @default 'Generated on' * * @exampleMarkdown - * ```yaml + * ```yaml {4-5} * generates: * path/to/file.ts: * plugins: diff --git a/packages/plugins/other/urql-introspection/src/index.ts b/packages/plugins/other/urql-introspection/src/index.ts index 24e9696d245..81623be69ba 100644 --- a/packages/plugins/other/urql-introspection/src/index.ts +++ b/packages/plugins/other/urql-introspection/src/index.ts @@ -21,7 +21,7 @@ export interface UrqlIntrospectionConfig { * @default es2015 * * @exampleMarkdown - * ```yaml + * ```yaml {6} * generates: * path/to/file.json: * plugins: diff --git a/packages/plugins/other/visitor-plugin-common/src/base-resolvers-visitor.ts b/packages/plugins/other/visitor-plugin-common/src/base-resolvers-visitor.ts index e03b85c77be..05d3fc349ba 100644 --- a/packages/plugins/other/visitor-plugin-common/src/base-resolvers-visitor.ts +++ b/packages/plugins/other/visitor-plugin-common/src/base-resolvers-visitor.ts @@ -81,7 +81,7 @@ export interface RawResolversConfig extends RawConfig { * @description Adds `_` to generated `Args` types in order to avoid duplicate identifiers. * * @exampleMarkdown - * ```yaml + * ```yaml {2} * config: * addUnderscoreToArgsType: true * ``` diff --git a/packages/plugins/other/visitor-plugin-common/src/base-types-visitor.ts b/packages/plugins/other/visitor-plugin-common/src/base-types-visitor.ts index fa6326fec64..2b9731dff8b 100644 --- a/packages/plugins/other/visitor-plugin-common/src/base-types-visitor.ts +++ b/packages/plugins/other/visitor-plugin-common/src/base-types-visitor.ts @@ -179,7 +179,7 @@ export interface RawTypesConfig extends RawConfig { * @exampleMarkdown * ## Override all definition types * - * ```yml + * ```yaml * generates: * path/to/file.ts: * plugins: diff --git a/packages/plugins/other/visitor-plugin-common/src/base-visitor.ts b/packages/plugins/other/visitor-plugin-common/src/base-visitor.ts index eb88c650973..110a26dc194 100644 --- a/packages/plugins/other/visitor-plugin-common/src/base-visitor.ts +++ b/packages/plugins/other/visitor-plugin-common/src/base-visitor.ts @@ -46,7 +46,7 @@ export interface RawConfig { * @default false * * @exampleMarkdown - * ```yaml + * ```yaml {2} * config: * strictScalars: true * ``` @@ -57,7 +57,7 @@ export interface RawConfig { * @default any * * @exampleMarkdown - * ```yaml + * ```yaml {2} * config: * defaultScalarType: unknown * ``` @@ -123,7 +123,7 @@ export interface RawConfig { * @description Prefixes all the generated types. * * @exampleMarkdown - * ```yaml + * ```yaml {2} * config: * typesPrefix: I * ``` @@ -134,7 +134,7 @@ export interface RawConfig { * @description Suffixes all the generated types. * * @exampleMarkdown - * ```yaml + * ```yaml {2} * config: * typesSuffix: I * ``` @@ -157,7 +157,7 @@ export interface RawConfig { * in the selection set, and makes it non-optional * * @exampleMarkdown - * ```yaml + * ```yaml {2} * config: * nonOptionalTypename: true * ``` @@ -171,7 +171,7 @@ export interface RawConfig { * compatibility with TypeScript's "importsNotUsedAsValues": "error" option * * @example - * ```yaml + * ```yaml {2} * config: * useTypeImports: true * ``` diff --git a/packages/plugins/typescript/typescript/src/config.ts b/packages/plugins/typescript/typescript/src/config.ts index cfdb21dbc3d..5f09a235dcb 100644 --- a/packages/plugins/typescript/typescript/src/config.ts +++ b/packages/plugins/typescript/typescript/src/config.ts @@ -138,7 +138,7 @@ export interface TypeScriptPluginConfig extends RawTypesConfig { * @default false * * @exampleMarkdown Override all definition types - * ```yml + * ```yaml * generates: * path/to/file.ts: * plugins: diff --git a/packages/presets/gql-tag-operations/src/index.ts b/packages/presets/gql-tag-operations/src/index.ts index 61bbc54457b..dd16e3dedff 100644 --- a/packages/presets/gql-tag-operations/src/index.ts +++ b/packages/presets/gql-tag-operations/src/index.ts @@ -28,7 +28,7 @@ export type GqlTagConfig = { * E.g. `graphql-tag` or `@urql/core`. * * @exampleMarkdown - * ```yaml + * ```yaml {5} * generates: * gql/: * preset: gql-tag-operations-preset @@ -50,7 +50,7 @@ export type GqlTagConfig = { * * When using the `augmentedModuleName` option, the unmask function will by default NOT be imported from the same module. It will still be generated to a `index.ts` file. You can, however, specify to resolve the unmasking function from an an augmented module by using the `augmentedModuleName` object sub-config. * @exampleMarkdown - * ```yaml + * ```yaml {6-7} * generates: * gql/: * preset: gql-tag-operations-preset diff --git a/packages/presets/import-types/src/index.ts b/packages/presets/import-types/src/index.ts index 9ce2030f24d..de759652977 100644 --- a/packages/presets/import-types/src/index.ts +++ b/packages/presets/import-types/src/index.ts @@ -8,7 +8,7 @@ export type ImportTypesConfig = { * The key of the output is used a the base path for this file. * * @exampleMarkdown - * ```yaml + * ```yaml {5} * generates: * path/to/file.ts: * preset: import-types @@ -24,7 +24,7 @@ export type ImportTypesConfig = { * @default Types * * @exampleMarkdown - * ```yaml + * ```yaml {6} * generates: * src/: * preset: import-types diff --git a/packages/presets/near-operation-file/src/index.ts b/packages/presets/near-operation-file/src/index.ts index 2b66a9cf779..1661918afab 100644 --- a/packages/presets/near-operation-file/src/index.ts +++ b/packages/presets/near-operation-file/src/index.ts @@ -28,7 +28,7 @@ export type NearOperationFileConfig = { * If you wish to use an NPM package or a local workspace package, make sure to prefix the package name with `~`. * * @exampleMarkdown - * ```yaml + * ```yaml {5} * generates: * src/: * preset: near-operation-file @@ -45,7 +45,7 @@ export type NearOperationFileConfig = { * If you wish to use an NPM package or a local workspace package, make sure to prefix the package name with `~`. * * @exampleMarkdown - * ```yaml + * ```yaml {6} * generates: * src/: * preset: near-operation-file @@ -62,7 +62,7 @@ export type NearOperationFileConfig = { * @default .generated.ts * * @exampleMarkdown - * ```yaml + * ```yaml {6} * generates: * src/: * preset: near-operation-file @@ -80,7 +80,7 @@ export type NearOperationFileConfig = { * @default process.cwd() * * @exampleMarkdown - * ```yaml + * ```yaml {6} * generates: * src/: * preset: near-operation-file @@ -97,7 +97,7 @@ export type NearOperationFileConfig = { * @default '' * * @exampleMarkdown - * ```yaml + * ```yaml {6} * generates: * src/: * preset: near-operation-file @@ -114,7 +114,7 @@ export type NearOperationFileConfig = { * @default Types * * @exampleMarkdown - * ```yaml + * ```yaml {6} * generates: * src/: * preset: near-operation-file diff --git a/patches/nextra+2.0.0-alpha.56.patch b/patches/nextra+2.0.0-alpha.56.patch new file mode 100644 index 00000000000..e2ba8815d4a --- /dev/null +++ b/patches/nextra+2.0.0-alpha.56.patch @@ -0,0 +1,892 @@ +diff --git a/node_modules/nextra/context.js b/node_modules/nextra/context.js +deleted file mode 100644 +index 77e9dd1..0000000 +--- a/node_modules/nextra/context.js ++++ /dev/null +@@ -1 +0,0 @@ +-module.exports = require('./dist/context') +diff --git a/node_modules/nextra/data.js b/node_modules/nextra/data.js +deleted file mode 100755 +index 9016f08..0000000 +--- a/node_modules/nextra/data.js ++++ /dev/null +@@ -1 +0,0 @@ +-module.exports = require('./dist/ssg') +diff --git a/node_modules/nextra/dist/compile.mjs b/node_modules/nextra/dist/compile.mjs +new file mode 100644 +index 0000000..e6ae1da +--- /dev/null ++++ b/node_modules/nextra/dist/compile.mjs +@@ -0,0 +1,565 @@ ++var __defProp = Object.defineProperty; ++var __defProps = Object.defineProperties; ++var __getOwnPropDescs = Object.getOwnPropertyDescriptors; ++var __getOwnPropSymbols = Object.getOwnPropertySymbols; ++var __hasOwnProp = Object.prototype.hasOwnProperty; ++var __propIsEnum = Object.prototype.propertyIsEnumerable; ++var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; ++var __spreadValues = (a, b) => { ++ for (var prop in b || (b = {})) ++ if (__hasOwnProp.call(b, prop)) ++ __defNormalProp(a, prop, b[prop]); ++ if (__getOwnPropSymbols) ++ for (var prop of __getOwnPropSymbols(b)) { ++ if (__propIsEnum.call(b, prop)) ++ __defNormalProp(a, prop, b[prop]); ++ } ++ return a; ++}; ++var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); ++var __async = (__this, __arguments, generator) => { ++ return new Promise((resolve, reject) => { ++ var fulfilled = (value) => { ++ try { ++ step(generator.next(value)); ++ } catch (e) { ++ reject(e); ++ } ++ }; ++ var rejected = (value) => { ++ try { ++ step(generator.throw(value)); ++ } catch (e) { ++ reject(e); ++ } ++ }; ++ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); ++ step((generator = generator.apply(__this, __arguments)).next()); ++ }); ++}; ++ ++// src/compile.ts ++import { createProcessor } from "@mdx-js/mdx"; ++import remarkGfm from "remark-gfm"; ++import rehypePrettyCode from "rehype-pretty-code"; ++ ++// src/mdx-plugins/static-image.js ++var relative = /^\.{1,2}\//; ++function visit(node, type2, handler) { ++ if (node.type === type2) { ++ handler(node); ++ } ++ if (node.children) { ++ node.children.forEach((n) => visit(n, type2, handler)); ++ } ++} ++function ASTNodeImport(name2, from) { ++ return { ++ type: "mdxjsEsm", ++ value: `import ${name2} from "${from}"`, ++ data: { ++ estree: { ++ type: "Program", ++ body: [ ++ { ++ type: "ImportDeclaration", ++ specifiers: [ ++ { ++ type: "ImportDefaultSpecifier", ++ local: { type: "Identifier", name: name2 } ++ } ++ ], ++ source: { ++ type: "Literal", ++ value: from, ++ raw: `"${from}"` ++ } ++ } ++ ], ++ sourceType: "module" ++ } ++ } ++ }; ++} ++function remarkStaticImage() { ++ return (tree, _file, done) => { ++ const importsToInject = []; ++ visit(tree, "image", visitor); ++ tree.children.unshift(...importsToInject); ++ tree.children.unshift(ASTNodeImport("$NextImageNextra", "next/image")); ++ done(); ++ function visitor(node) { ++ const url = node.url; ++ if (url && relative.test(url)) { ++ const tempVariableName = `$nextraImage${importsToInject.length}`; ++ Object.assign(node, { ++ type: "mdxJsxFlowElement", ++ name: "$NextImageNextra", ++ attributes: [ ++ { ++ type: "mdxJsxAttribute", ++ name: "alt", ++ value: node.alt || "" ++ }, ++ { ++ type: "mdxJsxAttribute", ++ name: "placeholder", ++ value: "blur" ++ }, ++ { ++ type: "mdxJsxAttribute", ++ name: "src", ++ value: { ++ type: "mdxJsxAttributeValueExpression", ++ value: tempVariableName, ++ data: { ++ estree: { ++ type: "Program", ++ body: [ ++ { ++ type: "ExpressionStatement", ++ expression: { ++ type: "Identifier", ++ name: tempVariableName ++ } ++ } ++ ], ++ sourceType: "module" ++ } ++ } ++ } ++ } ++ ], ++ children: [] ++ }); ++ importsToInject.push(ASTNodeImport(tempVariableName, url)); ++ } ++ } ++ }; ++} ++ ++// src/mdx-plugins/remark.ts ++function visit2(node, tester, handler) { ++ if (tester(node)) { ++ handler(node); ++ } ++ if (node.children) { ++ node.children.forEach((n) => visit2(n, tester, handler)); ++ } ++} ++function getFlattenedValue(node) { ++ return node.children.map((child) => "children" in child ? getFlattenedValue(child) : "value" in child ? child.value : "").join(""); ++} ++function remarkHeadings() { ++ const data = this.data(); ++ return (tree, _file, done) => { ++ visit2(tree, (node) => { ++ return node.type === "heading" || node.name === "summary" || node.name === "details"; ++ }, (node) => { ++ if (node.type === "heading") { ++ const heading = __spreadProps(__spreadValues({}, node), { ++ value: getFlattenedValue(node) ++ }); ++ const headingMeta = data.headingMeta; ++ if (node.depth === 1) { ++ headingMeta.hasH1 = true; ++ if (Array.isArray(node.children) && node.children.length === 1) { ++ const child = node.children[0]; ++ if (child.type === "text") { ++ headingMeta.titleText = child.value; ++ } ++ } ++ } ++ headingMeta.headings.push(heading); ++ } else if (node.name === "summary" || node.name === "details") { ++ if (node.data) { ++ delete node.data._mdxExplicitJsx; ++ } ++ } ++ }); ++ done(); ++ }; ++} ++ ++// src/mdx-plugins/structurize.js ++import Slugger from "github-slugger"; ++function cleanup(content) { ++ return content.trim().split("\n").map((line) => line.trim()).join("\n"); ++} ++var structurize_default = (structurizedData, options) => { ++ if (typeof options === "boolean") ++ options = {}; ++ options = Object.assign({ codeblocks: true }, options); ++ const slugger = new Slugger(); ++ let activeSlug = ""; ++ let skip = false; ++ let content = ""; ++ return function stripMarkdown() { ++ return (node) => { ++ walk(node); ++ structurizedData[activeSlug] = cleanup(content); ++ return node; ++ }; ++ function walk(node) { ++ let result = ""; ++ const type2 = node.type; ++ if (type2 === "heading") ++ skip = true; ++ if (["code", "table", "blockquote", "list", "mdxJsxFlowElement"].includes(type2)) { ++ result += "\n"; ++ if (!skip) ++ content += "\n"; ++ } ++ if ("children" in node) { ++ for (let i = 0; i < node.children.length; i++) { ++ result += walk(node.children[i]); ++ } ++ } else if ([ ++ options.codeblocks ? "code" : "", ++ "text", ++ "inlineCode", ++ "tableCell" ++ ].includes(type2)) { ++ result += node.value; ++ if (!skip) ++ content += node.value; ++ } ++ if ([ ++ "code", ++ "table", ++ "blockquote", ++ "list", ++ "listItem", ++ "break", ++ "mdxJsxFlowElement" ++ ].includes(type2)) { ++ result += "\n"; ++ if (!skip) ++ content += "\n"; ++ } ++ if (["tableCell"].includes(type2)) { ++ result += " "; ++ if (!skip) ++ content += " "; ++ } ++ if (type2 === "heading") ++ skip = false; ++ if (type2 === "heading" && node.depth > 1) { ++ structurizedData[activeSlug] = cleanup(content); ++ content = ""; ++ activeSlug = slugger.slug(result) + "#" + result; ++ } ++ return result; ++ } ++ }; ++}; ++ ++// src/mdx-plugins/rehype-handler.js ++import Slugger2 from "github-slugger"; ++function visit3(node, tagNames, handler) { ++ if (tagNames.includes(node.tagName)) { ++ handler(node); ++ return; ++ } ++ if (node.children) { ++ node.children.forEach((n) => visit3(n, tagNames, handler)); ++ } ++} ++function parseMeta() { ++ return (tree) => { ++ visit3(tree, ["pre"], (node) => { ++ var _a, _b, _c; ++ if (Array.isArray(node.children) && node.children.length === 1 && node.children[0].tagName === "code" && typeof node.children[0].properties === "object") { ++ const meta = (_b = (_a = node.children[0].data) == null ? void 0 : _a.meta) != null ? _b : node.children[0].properties.metastring; ++ if (meta) { ++ const filename = (_c = meta.match(/filename="([^"]+)"/)) == null ? void 0 : _c[1]; ++ if (filename) { ++ node.__nextra_filename__ = filename; ++ } ++ } ++ } ++ }); ++ }; ++} ++function attachMeta() { ++ return (tree) => { ++ const slugger = new Slugger2(); ++ visit3(tree, ["div", "h2", "h3", "h4", "h5", "h6"], (node) => { ++ if (node.tagName === "div") { ++ if (!("data-rehype-pretty-code-fragment" in node.properties)) ++ return; ++ node.properties["data-nextra-code"] = ""; ++ if ("__nextra_filename__" in node) { ++ node.properties["data-filename"] = node.__nextra_filename__; ++ } ++ } else { ++ node.properties.id = node.properties.id || slugger.slug(getFlattenedValue(node)); ++ } ++ }); ++ }; ++} ++ ++// src/theme.json ++var name = "css-variables"; ++var type = "light"; ++var colors = { ++ "editor.foreground": "#000001", ++ "editor.background": "#000002" ++}; ++var tokenColors = [ ++ { ++ settings: { ++ foreground: "#000001" ++ } ++ }, ++ { ++ scope: [ ++ "markup.deleted", ++ "meta.diff.header.from-file", ++ "punctuation.definition.deleted" ++ ], ++ settings: { ++ foreground: "#ef6270" ++ } ++ }, ++ { ++ scope: [ ++ "markup.inserted", ++ "meta.diff.header.to-file", ++ "punctuation.definition.inserted" ++ ], ++ settings: { ++ foreground: "#4bb74a" ++ } ++ }, ++ { ++ scope: [ ++ "keyword.operator.accessor", ++ "meta.group.braces.round.function.arguments", ++ "meta.template.expression", ++ "markup.fenced_code meta.embedded.block" ++ ], ++ settings: { ++ foreground: "#000001" ++ } ++ }, ++ { ++ scope: "emphasis", ++ settings: { ++ fontStyle: "italic" ++ } ++ }, ++ { ++ scope: ["strong", "markup.heading.markdown", "markup.bold.markdown"], ++ settings: { ++ fontStyle: "bold" ++ } ++ }, ++ { ++ scope: ["markup.italic.markdown"], ++ settings: { ++ fontStyle: "italic" ++ } ++ }, ++ { ++ scope: "meta.link.inline.markdown", ++ settings: { ++ fontStyle: "underline", ++ foreground: "#000004" ++ } ++ }, ++ { ++ scope: ["string", "markup.fenced_code", "markup.inline"], ++ settings: { ++ foreground: "#000005" ++ } ++ }, ++ { ++ scope: ["comment", "string.quoted.docstring.multi"], ++ settings: { ++ foreground: "#000006" ++ } ++ }, ++ { ++ scope: [ ++ "constant.numeric", ++ "constant.language", ++ "constant.other.placeholder", ++ "constant.character.format.placeholder", ++ "variable.language.this", ++ "variable.other.object", ++ "variable.other.class", ++ "variable.other.constant", ++ "meta.property-name", ++ "meta.property-value", ++ "support" ++ ], ++ settings: { ++ foreground: "#000004" ++ } ++ }, ++ { ++ scope: [ ++ "keyword", ++ "storage.modifier", ++ "storage.type", ++ "storage.control.clojure", ++ "entity.name.function.clojure", ++ "entity.name.tag.yaml", ++ "support.function.node", ++ "support.type.property-name.json", ++ "punctuation.separator.key-value", ++ "punctuation.definition.template-expression" ++ ], ++ settings: { ++ foreground: "#000007" ++ } ++ }, ++ { ++ scope: "variable.parameter.function", ++ settings: { ++ foreground: "#000008" ++ } ++ }, ++ { ++ scope: [ ++ "support.function", ++ "entity.name.type", ++ "entity.other.inherited-class", ++ "meta.function-call", ++ "meta.instance.constructor", ++ "entity.other.attribute-name", ++ "entity.name.function", ++ "constant.keyword.clojure" ++ ], ++ settings: { ++ foreground: "#000009" ++ } ++ }, ++ { ++ scope: [ ++ "entity.name.tag", ++ "string.quoted", ++ "string.regexp", ++ "string.interpolated", ++ "string.template", ++ "string.unquoted.plain.out.yaml", ++ "keyword.other.template" ++ ], ++ settings: { ++ foreground: "#000010" ++ } ++ }, ++ { ++ scope: [ ++ "punctuation.definition.arguments", ++ "punctuation.definition.dict", ++ "punctuation.separator", ++ "meta.function-call.arguments" ++ ], ++ settings: { ++ foreground: "#000011" ++ } ++ }, ++ { ++ name: "[Custom] Markdown links", ++ scope: [ ++ "markup.underline.link", ++ "punctuation.definition.metadata.markdown" ++ ], ++ settings: { ++ foreground: "#000012" ++ } ++ }, ++ { ++ name: "[Custom] Markdown list", ++ scope: ["beginning.punctuation.definition.list.markdown"], ++ settings: { ++ foreground: "#000005" ++ } ++ }, ++ { ++ name: "[Custom] Markdown punctuation definition brackets", ++ scope: [ ++ "punctuation.definition.string.begin.markdown", ++ "punctuation.definition.string.end.markdown", ++ "string.other.link.title.markdown", ++ "string.other.link.description.markdown" ++ ], ++ settings: { ++ foreground: "#000007" ++ } ++ } ++]; ++var theme_default = { ++ name, ++ type, ++ colors, ++ tokenColors ++}; ++ ++// src/compile.ts ++var createCompiler = (mdxOptions) => { ++ const compiler = createProcessor(mdxOptions); ++ compiler.data("headingMeta", { ++ hasH1: false, ++ headings: [] ++ }); ++ return compiler; ++}; ++var addHighlightedClass = (node) => { ++ var _a; ++ (_a = node.properties).className || (_a.className = []); ++ node.properties.className.push("highlighted"); ++}; ++function compileMdx(_0) { ++ return __async(this, arguments, function* (source, mdxOptions = {}, nextraOptions = { ++ unstable_staticImage: false, ++ unstable_flexsearch: false ++ }, resourcePath) { ++ var _a; ++ let structurizedData = {}; ++ const compiler = createCompiler({ ++ jsx: (_a = mdxOptions.jsx) != null ? _a : true, ++ outputFormat: mdxOptions.outputFormat, ++ providerImportSource: "@mdx-js/react", ++ remarkPlugins: [ ++ ...mdxOptions.remarkPlugins || [], ++ remarkGfm, ++ remarkHeadings, ++ ...nextraOptions.unstable_staticImage ? [remarkStaticImage] : [], ++ ...nextraOptions.unstable_flexsearch ? [structurize_default(structurizedData, nextraOptions.unstable_flexsearch)] : [] ++ ].filter(Boolean), ++ rehypePlugins: [ ++ ...mdxOptions.rehypePlugins || [], ++ parseMeta, ++ [ ++ rehypePrettyCode, ++ { ++ theme: theme_default, ++ onVisitHighlightedLine: addHighlightedClass, ++ onVisitHighlightedWord: addHighlightedClass ++ } ++ ], ++ attachMeta ++ ].filter(Boolean) ++ }); ++ try { ++ const result = yield compiler.process(source); ++ return __spreadProps(__spreadValues({ ++ result: String(result) ++ }, compiler.data("headingMeta")), { ++ structurizedData ++ }); ++ } catch (err) { ++ console.error(` ++Error compiling ${resourcePath} ++${err} ++`); ++ throw err; ++ } ++ }); ++} ++export { ++ compileMdx ++}; +diff --git a/node_modules/nextra/dist/context.js b/node_modules/nextra/dist/context.cjs +similarity index 100% +rename from node_modules/nextra/dist/context.js +rename to node_modules/nextra/dist/context.cjs +diff --git a/node_modules/nextra/dist/index.js b/node_modules/nextra/dist/index.cjs +similarity index 93% +rename from node_modules/nextra/dist/index.js +rename to node_modules/nextra/dist/index.cjs +index d288128..71aacee 100644 +--- a/node_modules/nextra/dist/index.js ++++ b/node_modules/nextra/dist/index.cjs +@@ -231,34 +231,30 @@ var NextraPlugin = class { + } + }; + +-// src/index.js +-var defaultExtensions = ["js", "jsx", "ts", "tsx"]; +-var markdownExtensions = ["md", "mdx"]; +-var markdownExtensionTest = /\.mdx?$/; +-module.exports = (...args) => (nextConfig = {}) => { ++// src/index.ts ++var DEFAULT_EXTENSIONS = ["js", "jsx", "ts", "tsx"]; ++var MARKDOWN_EXTENSIONS = ["md", "mdx"]; ++var MARKDOWN_EXTENSION_TEST = /\.mdx?$/; ++var nextra = (...args) => function withNextra(nextConfig) { + var _a, _b; + const nextraConfig = typeof args[0] === "string" ? { + theme: args[0], + themeConfig: args[1] + } : args[0]; ++ const nextraPlugin = new NextraPlugin(nextraConfig); + const locales = ((_a = nextConfig.i18n) == null ? void 0 : _a.locales) || null; + const defaultLocale = ((_b = nextConfig.i18n) == null ? void 0 : _b.defaultLocale) || null; +- let pageExtensions = nextConfig.pageExtensions || [...defaultExtensions]; +- pageExtensions = pageExtensions.concat(markdownExtensions); ++ const pageExtensions = nextConfig.pageExtensions || DEFAULT_EXTENSIONS; + if (locales) { + console.log("[Nextra] You have Next.js i18n enabled, read here (TODO: link) for the docs."); + } +- return Object.assign({}, nextConfig, { +- pageExtensions, ++ return __spreadProps(__spreadValues({}, nextConfig), { ++ pageExtensions: [...pageExtensions, ...MARKDOWN_EXTENSIONS], + webpack(config, options) { +- const nextra = new NextraPlugin(nextraConfig); +- if (!config.plugins) { +- config.plugins = [nextra]; +- } else { +- config.plugins.push(nextra); +- } ++ config.plugins || (config.plugins = []); ++ config.plugins.push(nextraPlugin); + config.module.rules.push({ +- test: markdownExtensionTest, ++ test: MARKDOWN_EXTENSION_TEST, + use: [ + options.defaultLoaders.babel, + { +@@ -274,3 +270,4 @@ module.exports = (...args) => (nextConfig = {}) => { + } + }); + }; ++module.exports = nextra; +diff --git a/node_modules/nextra/dist/loader.mjs b/node_modules/nextra/dist/loader.mjs +index 486c1fb..208fa21 100644 +--- a/node_modules/nextra/dist/loader.mjs ++++ b/node_modules/nextra/dist/loader.mjs +@@ -599,29 +599,21 @@ var createCompiler = (mdxOptions) => { + }); + return compiler; + }; +-var rehypePrettyCodeOptions = { +- theme: theme_default, +- onVisitHighlightedLine(node) { +- if (!node.properties.className) { +- node.properties.className = []; +- } +- node.properties.className.push("highlighted"); +- }, +- onVisitHighlightedWord(node) { +- if (!node.properties.className) { +- node.properties.className = []; +- } +- node.properties.className.push("highlighted"); +- } ++var addHighlightedClass = (node) => { ++ var _a; ++ (_a = node.properties).className || (_a.className = []); ++ node.properties.className.push("highlighted"); + }; + function compileMdx(_0) { + return __async(this, arguments, function* (source, mdxOptions = {}, nextraOptions = { + unstable_staticImage: false, + unstable_flexsearch: false + }, resourcePath) { ++ var _a; + let structurizedData = {}; + const compiler = createCompiler({ +- jsx: true, ++ jsx: (_a = mdxOptions.jsx) != null ? _a : true, ++ outputFormat: mdxOptions.outputFormat, + providerImportSource: "@mdx-js/react", + remarkPlugins: [ + ...mdxOptions.remarkPlugins || [], +@@ -633,7 +625,14 @@ function compileMdx(_0) { + rehypePlugins: [ + ...mdxOptions.rehypePlugins || [], + parseMeta, +- [rehypePrettyCode, rehypePrettyCodeOptions], ++ [ ++ rehypePrettyCode, ++ { ++ theme: theme_default, ++ onVisitHighlightedLine: addHighlightedClass, ++ onVisitHighlightedWord: addHighlightedClass ++ } ++ ], + attachMeta + ].filter(Boolean) + }); +@@ -646,8 +645,8 @@ function compileMdx(_0) { + }); + } catch (err) { + console.error(` +-Error compiling ${resourcePath}`); +- console.error(`${err} ++Error compiling ${resourcePath} ++${err} + `); + throw err; + } +@@ -827,16 +826,7 @@ function loader(context, source) { + if (!theme) { + throw new Error("No Nextra theme found!"); + } +- let pageMapResult, fileMap; +- if (isProductionBuild) { +- const data2 = pageMapCache2.get(); +- pageMapResult = data2.items; +- fileMap = data2.fileMap; +- } else { +- const data2 = yield collectFiles(pagesDir, "/"); +- pageMapResult = data2.items; +- fileMap = data2.fileMap; +- } ++ const { items: pageMapResult, fileMap } = isProductionBuild ? pageMapCache2.get() : yield collectFiles(pagesDir, "/"); + const [pageMap, route, title] = getPageMap(resourcePath, pageMapResult, fileMap, defaultLocale); + if (!isProductionBuild) { + context.addContextDependency(pagesDir); +@@ -867,7 +857,7 @@ function loader(context, source) { + content = content.replace("export default MDXContent;", ""); + if (unstable_flexsearch) { + if (extension2.test(filename) && data.searchable !== false) { +- yield addPage({ ++ addPage({ + fileLocale: fileLocale || "default", + route, + title, +@@ -893,34 +883,45 @@ function loader(context, source) { + } catch (e) { + } + } +- const prefix = `import __nextra_withLayout__ from '${layout}' ++ const layoutConfigImport = layoutConfig ? `import __nextra_layoutConfig__ from '${layoutConfig}'` : ""; ++ return ` ++import __nextra_withLayout__ from '${layout}' + import { withSSG as __nextra_withSSG__ } from 'nextra/ssg' +-${layoutConfig ? `import __nextra_layoutConfig__ from '${layoutConfig}'` : ""} ++${layoutConfigImport} + + const __nextra_pageMap__ = ${JSON.stringify(pageMap)} ++ + globalThis.__nextra_internal__ = { + pageMap: __nextra_pageMap__, +- route: ${JSON.stringify(route)}, ++ route: ${JSON.stringify(route)} + } + +- const __nextra_content__ = +- const NextraLayout = __nextra_withSSG__(__nextra_withLayout__({ +- filename: "${slash2(filename)}", +- route: "${slash2(route)}", +- meta: ${JSON.stringify(data)}, +- pageMap: __nextra_pageMap__, +- titleText: ${JSON.stringify(titleText)}, +- headings: ${JSON.stringify(headings)}, +- hasH1: ${JSON.stringify(hasH1)}, +- ${timestamp ? `timestamp: ${timestamp}, ++const NextraLayout = __nextra_withSSG__(__nextra_withLayout__({ ++ filename: "${slash2(filename)}", ++ route: "${slash2(route)}", ++ meta: ${JSON.stringify(data)}, ++ pageMap: __nextra_pageMap__, ++ titleText: ${JSON.stringify(titleText)}, ++ headings: ${JSON.stringify(headings)}, ++ hasH1: ${JSON.stringify(hasH1)}, ++ ${timestamp ? `timestamp: ${timestamp}, + ` : ""} +- }, ${layoutConfig ? "__nextra_layoutConfig__" : "null"})) +- `; +- const suffix = `export default function NextraPage (props) { +- return {__nextra_content__} ++}, ${layoutConfig ? "__nextra_layoutConfig__" : "null"} ++)) ++ ++${content} ++ ++function NextraPage(props) { ++ return ( ++ ++ ++ ++ ) + } +-NextraPage.getLayout = NextraLayout.getLayout`; +- return prefix + "\n\n" + content + "\n\n" + suffix; ++NextraPage.getLayout = NextraLayout.getLayout ++ ++export default NextraPage ++`.trimStart(); + }); + } + function syncLoader(source, callback) { +diff --git a/node_modules/nextra/dist/locales.js b/node_modules/nextra/dist/locales.cjs +similarity index 100% +rename from node_modules/nextra/dist/locales.js +rename to node_modules/nextra/dist/locales.cjs +diff --git a/node_modules/nextra/dist/ssg.js b/node_modules/nextra/dist/ssg.cjs +similarity index 100% +rename from node_modules/nextra/dist/ssg.js +rename to node_modules/nextra/dist/ssg.cjs +diff --git a/node_modules/nextra/dist/types.d.ts b/node_modules/nextra/dist/types.d.ts +index 9a63bef..3c6ecb6 100644 +--- a/node_modules/nextra/dist/types.d.ts ++++ b/node_modules/nextra/dist/types.d.ts +@@ -1,6 +1,7 @@ + import { Heading as MDASTHeading } from 'mdast'; + import { ProcessorOptions } from '@mdx-js/mdx'; + import { PageMapCache } from './plugin'; ++import { NextConfig } from 'next'; + export interface LoaderOptions { + theme: Theme; + themeConfig: string; +@@ -8,7 +9,7 @@ export interface LoaderOptions { + defaultLocale: string; + unstable_staticImage: boolean; + unstable_flexsearch: boolean; +- mdxOptions: Pick; ++ mdxOptions: Pick; + pageMapCache: PageMapCache; + } + export interface PageMapItem { +@@ -45,5 +46,5 @@ export declare type NextraConfig = { + unstable_flexsearch: boolean; + unstable_staticImage?: boolean; + }; +-export declare type withNextra = (...args: [NextraConfig] | [theme: Theme, themeConfig: string]) => (nextConfig: Record) => {}; +-export default withNextra; ++export declare type Nextra = (...args: [NextraConfig] | [theme: Theme, themeConfig: string]) => (nextConfig: NextConfig) => NextConfig; ++export {}; +diff --git a/node_modules/nextra/index.js b/node_modules/nextra/index.js +deleted file mode 100755 +index aae5903..0000000 +--- a/node_modules/nextra/index.js ++++ /dev/null +@@ -1 +0,0 @@ +-module.exports = require('./dist/index') +diff --git a/node_modules/nextra/locales.js b/node_modules/nextra/locales.js +deleted file mode 100644 +index 0adc2a7..0000000 +--- a/node_modules/nextra/locales.js ++++ /dev/null +@@ -1 +0,0 @@ +-module.exports = require('./dist/locales') +diff --git a/node_modules/nextra/package.json b/node_modules/nextra/package.json +index 47e2096..514f442 100644 +--- a/node_modules/nextra/package.json ++++ b/node_modules/nextra/package.json +@@ -3,15 +3,12 @@ + "version": "2.0.0-alpha.56", + "description": "Next.js and MDX based site generator.", + "main": "index.js", +- "files": [ +- "dist/*", +- "index.js", +- "ssg.js", +- "data.js", +- "loader.js", +- "locales.js", +- "context.js" +- ], ++ "exports": { ++ ".": "./dist/index.cjs", ++ "./loader": "./loader.js", ++ "./compile": "./dist/compile.mjs", ++ "./ssg": "./dist/ssg.cjs" ++ }, + "types": "./dist/types.d.ts", + "repository": "https://github.com/shuding/nextra", + "license": "MIT", +diff --git a/node_modules/nextra/ssg.js b/node_modules/nextra/ssg.js +deleted file mode 100755 +index 9016f08..0000000 +--- a/node_modules/nextra/ssg.js ++++ /dev/null +@@ -1 +0,0 @@ +-module.exports = require('./dist/ssg') diff --git a/patches/nextra-theme-docs+2.0.0-alpha.59.patch b/patches/nextra-theme-docs+2.0.0-alpha.59.patch new file mode 100644 index 00000000000..7815568fc63 --- /dev/null +++ b/patches/nextra-theme-docs+2.0.0-alpha.59.patch @@ -0,0 +1,745 @@ +diff --git a/node_modules/nextra-theme-docs/dist/index.js b/node_modules/nextra-theme-docs/dist/index.js +index 0f5435d..6c71595 100644 +--- a/node_modules/nextra-theme-docs/dist/index.js ++++ b/node_modules/nextra-theme-docs/dist/index.js +@@ -1024,7 +1024,7 @@ var Footer = ({ menu }) => { + var footer_default = Footer; + + // src/misc/theme.tsx +-import Link5 from "next/link"; ++import NextLink2 from "next/link"; + import React23, { + useEffect as useEffect4, + useRef as useRef4, +@@ -1200,8 +1200,7 @@ var slugs = /* @__PURE__ */ new WeakMap(); + if (typeof window !== "undefined") { + observer = observer || new IntersectionObserver((entries) => { + const headers = []; +- for (let i = 0; i < entries.length; i++) { +- const entry = entries[i]; ++ for (const entry of entries) { + if (entry && entry.rootBounds && slugs.has(entry.target)) { + const [slug, index] = slugs.get(entry.target); + const aboveHalfViewport = entry.boundingClientRect.y + entry.boundingClientRect.height <= entry.rootBounds.y + entry.rootBounds.height; +@@ -1241,34 +1240,21 @@ if (typeof window !== "undefined") { + threshold: [0, 1] + }); + } +-var HeaderLink = (_a) => { ++var createHeaderLink = (Tag) => function HeaderLink(_a) { + var _b = _a, { +- tag: Tag, + children, +- id, +- context, +- withObserver = true ++ id: slug + } = _b, props = __objRest(_b, [ +- "tag", + "children", +- "id", +- "context", +- "withObserver" ++ "id" + ]); + setActiveAnchor = useActiveAnchorSet(); + const obRef = useRef4(null); +- const slug = id; +- const anchor = /* @__PURE__ */ React23.createElement("span", { +- className: "subheading-anchor", +- id: slug, +- ref: obRef +- }); +- const index = context.index++; + useEffect4(() => { + const ref = obRef; + if (!ref.current) + return; +- slugs.set(ref.current, [slug, index]); ++ slugs.set(ref.current, [slug, Number(Tag[1]) - 1]); + if (ref.current) + observer.observe(ref.current); + return () => { +@@ -1281,7 +1267,11 @@ var HeaderLink = (_a) => { + }); + }; + }, []); +- return /* @__PURE__ */ React23.createElement(Tag, __spreadValues({}, props), anchor, /* @__PURE__ */ React23.createElement("a", { ++ return /* @__PURE__ */ React23.createElement(Tag, __spreadValues({}, props), /* @__PURE__ */ React23.createElement("span", { ++ className: "subheading-anchor", ++ id: slug, ++ ref: obRef ++ }), /* @__PURE__ */ React23.createElement("a", { + href: "#" + slug, + className: "anchor text-current no-underline no-outline" + }, children, /* @__PURE__ */ React23.createElement("span", { +@@ -1289,57 +1279,26 @@ var HeaderLink = (_a) => { + "aria-hidden": true + }, "#"))); + }; +-var H2 = (context) => (_a) => { +- var _b = _a, { children } = _b, props = __objRest(_b, ["children"]); +- return /* @__PURE__ */ React23.createElement(HeaderLink, __spreadValues({ +- tag: "h2", +- context +- }, props), children); +-}; +-var H3 = (context) => (_a) => { +- var _b = _a, { children } = _b, props = __objRest(_b, ["children"]); +- return /* @__PURE__ */ React23.createElement(HeaderLink, __spreadValues({ +- tag: "h3", +- context +- }, props), children); +-}; +-var H4 = (context) => (_a) => { +- var _b = _a, { children } = _b, props = __objRest(_b, ["children"]); +- return /* @__PURE__ */ React23.createElement(HeaderLink, __spreadValues({ +- tag: "h4", +- context +- }, props), children); +-}; +-var H5 = (context) => (_a) => { +- var _b = _a, { children } = _b, props = __objRest(_b, ["children"]); +- return /* @__PURE__ */ React23.createElement(HeaderLink, __spreadValues({ +- tag: "h5", +- context +- }, props), children); +-}; +-var H6 = (context) => (_a) => { +- var _b = _a, { children } = _b, props = __objRest(_b, ["children"]); +- return /* @__PURE__ */ React23.createElement(HeaderLink, __spreadValues({ +- tag: "h6", +- context +- }, props), children); +-}; + var A = (_a) => { + var _b = _a, { +- children ++ children, ++ href + } = _b, props = __objRest(_b, [ +- "children" ++ "children", ++ "href" + ]); +- const isExternal = props.href && props.href.startsWith("https://"); +- if (isExternal) { +- return /* @__PURE__ */ React23.createElement("a", __spreadValues({ +- target: "_blank", +- rel: "noreferrer" +- }, props), children); ++ if (!href) { ++ return null; + } +- return props.href ? /* @__PURE__ */ React23.createElement(Link5, { +- href: props.href +- }, /* @__PURE__ */ React23.createElement("a", __spreadValues({}, props), children)) : /* @__PURE__ */ React23.createElement(React23.Fragment, null); ++ const isExternal = href.startsWith("https://"); ++ return isExternal ? /* @__PURE__ */ React23.createElement("a", __spreadValues({ ++ target: "_blank", ++ rel: "noreferrer", ++ href ++ }, props), children) : /* @__PURE__ */ React23.createElement(NextLink2, { ++ href, ++ passHref: true ++ }, /* @__PURE__ */ React23.createElement("a", __spreadValues({}, props), children)); + }; + var Table = ({ children }) => { + return /* @__PURE__ */ React23.createElement("div", { +@@ -1355,18 +1314,18 @@ var findSummary = (children) => { + var _a; + if (child && child.type === Summary) { + summary = summary || child; +- } else { +- let c = child; +- if (!summary && typeof child === "object" && child && child.type !== Details && "props" in child && child.props) { +- const result = findSummary(child.props.children); +- summary = summary || result[0]; +- c = React23.cloneElement(child, __spreadProps(__spreadValues({}, child.props), { +- children: ((_a = result[1]) == null ? void 0 : _a.length) ? result[1] : void 0, +- key: index +- })); +- } +- restChildren.push(c); ++ return; + } ++ let c = child; ++ if (!summary && typeof child === "object" && child && child.type !== Details && "props" in child && child.props) { ++ const result = findSummary(child.props.children); ++ summary = summary || result[0]; ++ c = React23.cloneElement(child, __spreadProps(__spreadValues({}, child.props), { ++ children: ((_a = result[1]) == null ? void 0 : _a.length) ? result[1] : void 0, ++ key: index ++ })); ++ } ++ restChildren.push(c); + }); + return [summary, restChildren]; + }; +@@ -1384,14 +1343,18 @@ var Details = (_a) => { + return /* @__PURE__ */ React23.createElement("details", __spreadValues(__spreadProps(__spreadValues({}, props), { + ref, + open: true +- }), openState ? { "data-open": "" } : null), /* @__PURE__ */ React23.createElement(DetailsContext.Provider, { ++ }), openState && { "data-open": "" }), /* @__PURE__ */ React23.createElement(DetailsContext.Provider, { + value: setOpen + }, summary), /* @__PURE__ */ React23.createElement(Collapse, { + open: openState + }, restChildren)); + }; + var Summary = (_a) => { +- var _b = _a, { children } = _b, props = __objRest(_b, ["children"]); ++ var _b = _a, { ++ children ++ } = _b, props = __objRest(_b, [ ++ "children" ++ ]); + const setOpen = useContext3(DetailsContext); + return /* @__PURE__ */ React23.createElement("summary", __spreadProps(__spreadValues({}, props), { + onClick: (e) => { +@@ -1400,12 +1363,12 @@ var Summary = (_a) => { + } + }), children); + }; +-var getComponents = (context) => ({ +- h2: H2(context), +- h3: H3(context), +- h4: H4(context), +- h5: H5(context), +- h6: H6(context), ++var components = { ++ h2: createHeaderLink("h2"), ++ h3: createHeaderLink("h3"), ++ h4: createHeaderLink("h4"), ++ h5: createHeaderLink("h5"), ++ h6: createHeaderLink("h6"), + a: A, + table: Table, + details: Details, +@@ -1416,10 +1379,12 @@ var getComponents = (context) => ({ + Tabs, + Tab + } +-}); +-var MDXTheme = ({ children }) => { ++}; ++var MDXTheme = ({ ++ children ++}) => { + return /* @__PURE__ */ React23.createElement(MDXProvider, { +- components: getComponents({ index: 0 }) ++ components + }, children); + }; + +@@ -1428,7 +1393,7 @@ import React24, { useState as useState5, useEffect as useEffect5, useMemo as use + import cn8 from "classnames"; + import Slugger from "github-slugger"; + import { useRouter as useRouter6 } from "next/router"; +-import Link6 from "next/link"; ++import Link5 from "next/link"; + import scrollIntoView from "scroll-into-view-if-needed"; + + // src/utils/get-heading-text.ts +@@ -1487,7 +1452,7 @@ function FolderImpl({ item, anchors }) { + }))); + return /* @__PURE__ */ React24.createElement("li", { + className: cn8({ open, active }) +- }, item.withIndexPage ? /* @__PURE__ */ React24.createElement(Link6, { ++ }, item.withIndexPage ? /* @__PURE__ */ React24.createElement(Link5, { + href: item.route + }, link) : link, /* @__PURE__ */ React24.createElement(Collapse, { + open +@@ -1536,7 +1501,7 @@ function File({ item, anchors, topLevel }) { + }); + return /* @__PURE__ */ React24.createElement("li", { + className: active ? "active" : "" +- }, /* @__PURE__ */ React24.createElement(Link6, { ++ }, /* @__PURE__ */ React24.createElement(Link5, { + href: item.href || item.route + }, /* @__PURE__ */ React24.createElement("a", __spreadProps(__spreadValues({}, item.newWindow ? { target: "_blank", rel: "noopener noreferrer" } : {}), { + onClick: () => { +@@ -1567,7 +1532,7 @@ function File({ item, anchors, topLevel }) { + } + return /* @__PURE__ */ React24.createElement("li", { + className: active ? "active" : "" +- }, /* @__PURE__ */ React24.createElement(Link6, { ++ }, /* @__PURE__ */ React24.createElement(Link5, { + href: item.href || item.route + }, /* @__PURE__ */ React24.createElement("a", __spreadProps(__spreadValues({}, item.newWindow ? { target: "_blank", rel: "noopener noreferrer" } : {}), { + onClick: () => { +@@ -1901,7 +1866,7 @@ var default_config_default = defaultTheme; + // src/utils/normalize-pages.tsx + import getTitle from "title"; + +-// src/misc/theme-context.tsx ++// src/misc/theme-context.ts + var theme_context_default = { + navbar: true, + sidebar: true, +@@ -2164,7 +2129,7 @@ if (typeof window !== "undefined") { + + // src/breadcrumb.tsx + import React27 from "react"; +-import Link7 from "next/link"; ++import Link6 from "next/link"; + import cn10 from "classnames"; + function Breadcrumb({ activePath }) { + return /* @__PURE__ */ React27.createElement("div", { +@@ -2183,7 +2148,7 @@ function Breadcrumb({ activePath }) { + "text-gray-600 dark:text-gray-400 active": isActive, + "text-ellipsis whitespace-nowrap overflow-hidden min-w-[24px]": !isActive + }) +- }, isLink && !isActive ? /* @__PURE__ */ React27.createElement(Link7, { ++ }, isLink && !isActive ? /* @__PURE__ */ React27.createElement(Link6, { + href: item.route + }, /* @__PURE__ */ React27.createElement("a", { + className: "text-current no-underline" +@@ -2270,7 +2235,6 @@ var Content = ({ + directories + } = useDirectoryInfo(pageMap); + const filepath = route.slice(0, route.lastIndexOf("/") + 1); +- const filepathWithName = filepath + filename; + const title = meta.title || titleText || "Untitled"; + const isRTL = useMemo3(() => { + if (!config.i18n) +@@ -2318,21 +2282,21 @@ var Content = ({ + className: "nextra-toc w-64 hidden xl:block text-sm px-4 order-last flex-shrink-0" + }) : /* @__PURE__ */ React28.createElement(ToC, { + headings: config.floatTOC ? headingArr : null, +- filepathWithName ++ filepathWithName: filepath + filename + }), /* @__PURE__ */ React28.createElement(Body, { + themeContext, +- breadcrumb: activeType === "page" ? null : themeContext.breadcrumb ? /* @__PURE__ */ React28.createElement(Breadcrumb, { ++ breadcrumb: activeType !== "page" && themeContext.breadcrumb && /* @__PURE__ */ React28.createElement(Breadcrumb, { + activePath +- }) : null, +- navLinks: activeType === "page" ? null : themeContext.pagination ? /* @__PURE__ */ React28.createElement(NavLinks, { ++ }), ++ navLinks: activeType !== "page" && themeContext.pagination && /* @__PURE__ */ React28.createElement(NavLinks, { + flatDirectories: flatDocsDirectories, + currentIndex: activeIndex, + isRTL +- }) : null, ++ }), + timestamp +- }, children)))), themeContext.footer && config.footer ? /* @__PURE__ */ React28.createElement(footer_default, { ++ }, children)))), themeContext.footer && config.footer && /* @__PURE__ */ React28.createElement(footer_default, { + menu: activeType === "page" || hideSidebar +- }) : null))); ++ })))); + }; + var createLayout = (opts, _config) => { + const extendedConfig = Object.assign({}, default_config_default, _config); +diff --git a/node_modules/nextra-theme-docs/dist/misc/theme.js b/node_modules/nextra-theme-docs/dist/misc/theme.js +new file mode 100644 +index 0000000..945daa5 +--- /dev/null ++++ b/node_modules/nextra-theme-docs/dist/misc/theme.js +@@ -0,0 +1,391 @@ ++var __defProp = Object.defineProperty; ++var __defProps = Object.defineProperties; ++var __getOwnPropDescs = Object.getOwnPropertyDescriptors; ++var __getOwnPropSymbols = Object.getOwnPropertySymbols; ++var __hasOwnProp = Object.prototype.hasOwnProperty; ++var __propIsEnum = Object.prototype.propertyIsEnumerable; ++var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; ++var __spreadValues = (a, b) => { ++ for (var prop in b || (b = {})) ++ if (__hasOwnProp.call(b, prop)) ++ __defNormalProp(a, prop, b[prop]); ++ if (__getOwnPropSymbols) ++ for (var prop of __getOwnPropSymbols(b)) { ++ if (__propIsEnum.call(b, prop)) ++ __defNormalProp(a, prop, b[prop]); ++ } ++ return a; ++}; ++var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); ++var __objRest = (source, exclude) => { ++ var target = {}; ++ for (var prop in source) ++ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0) ++ target[prop] = source[prop]; ++ if (source != null && __getOwnPropSymbols) ++ for (var prop of __getOwnPropSymbols(source)) { ++ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop)) ++ target[prop] = source[prop]; ++ } ++ return target; ++}; ++ ++// src/misc/theme.tsx ++import NextLink from "next/link"; ++import React6, { ++ useEffect as useEffect2, ++ useRef as useRef2, ++ useState as useState2, ++ useContext as useContext2 ++} from "react"; ++import "intersection-observer"; ++ ++// src/misc/active-anchor.tsx ++import React, { createContext, useContext, useState } from "react"; ++var ActiveAnchorContext = createContext({}); ++var ActiveAnchorSetterContext = createContext((s) => s); ++var useActiveAnchorSet = () => useContext(ActiveAnchorSetterContext); ++ ++// src/misc/theme.tsx ++import { MDXProvider } from "@mdx-js/react"; ++ ++// src/components/collapse.tsx ++import React2, { useRef, useEffect } from "react"; ++function Collapse({ ++ children, ++ open ++}) { ++ const containerRef = useRef(null); ++ const innerRef = useRef(null); ++ const animationRef = useRef(); ++ const initialRender = useRef(true); ++ const initialState = useRef(open); ++ useEffect(() => { ++ if (initialRender.current) ++ return; ++ if (animationRef.current) { ++ clearTimeout(animationRef.current); ++ } ++ if (open) { ++ const container = containerRef.current; ++ const inner = innerRef.current; ++ if (container && inner) { ++ const contentHeight = innerRef.current.clientHeight; ++ container.style.maxHeight = contentHeight + "px"; ++ container.classList.remove("duration-500"); ++ container.classList.add("duration-300"); ++ inner.style.opacity = "1"; ++ animationRef.current = setTimeout(() => { ++ const container2 = containerRef.current; ++ if (container2) { ++ container2.style.removeProperty("max-height"); ++ } ++ }, 300); ++ } ++ } else { ++ const container = containerRef.current; ++ const inner = innerRef.current; ++ if (container && inner) { ++ const contentHeight = innerRef.current.clientHeight; ++ container.style.maxHeight = contentHeight + "px"; ++ container.classList.remove("duration-300"); ++ container.classList.add("duration-500"); ++ inner.style.opacity = "0"; ++ setTimeout(() => { ++ const container2 = containerRef.current; ++ if (container2) { ++ container2.style.maxHeight = "0px"; ++ } ++ }); ++ } ++ } ++ }, [open]); ++ useEffect(() => { ++ initialRender.current = false; ++ }, []); ++ return /* @__PURE__ */ React2.createElement("div", { ++ ref: containerRef, ++ className: "transition-all ease-in-out duration-300 overflow-hidden transform-gpu motion-reduce:transition-none", ++ style: { ++ maxHeight: initialState.current ? void 0 : 0 ++ } ++ }, /* @__PURE__ */ React2.createElement("div", { ++ ref: innerRef, ++ className: "nextra-collapse-content transition-opacity ease-in-out duration-500 overflow-hidden transform-gpu motion-reduce:transition-none", ++ style: { ++ opacity: initialState.current ? 1 : 0 ++ } ++ }, children)); ++} ++ ++// src/components/tabs.tsx ++import React3 from "react"; ++import cn from "classnames"; ++import { Tab as HeadlessTab } from "@headlessui/react"; ++function Tabs({ ++ items, ++ selectedIndex, ++ defaultIndex, ++ onChange, ++ children ++}) { ++ return /* @__PURE__ */ React3.createElement(HeadlessTab.Group, { ++ selectedIndex, ++ defaultIndex, ++ onChange ++ }, /* @__PURE__ */ React3.createElement("div", { ++ className: "p-2 -m-2 overscroll-x-contain overflow-x-auto overflow-y-hidden no-scrollbar" ++ }, /* @__PURE__ */ React3.createElement(HeadlessTab.List, { ++ className: "flex mt-4 pb-[1px] border-b border-gray-200 dark:border-neutral-800 w-max min-w-full" ++ }, items.map((item, index) => { ++ const disabled = !!(item && typeof item === "object" && "disabled" in item && item.disabled); ++ return /* @__PURE__ */ React3.createElement(HeadlessTab, { ++ key: index, ++ disabled, ++ className: ({ selected }) => cn("p-2 mr-2 leading-5 font-medium text-md transition-colors", "select-none border-b-2 mb-[-2px] focus:outline-none focus-visible:ring ring-offset-2 rounded-[1px]", selected ? "text-primary-500 border-primary-500" : "text-gray-600 dark:text-gray-200 hover:border-gray-200 dark:hover:border-neutral-800 border-transparent hover:text-black dark:hover:text-white", disabled ? "pointer-events-none text-gray-400 dark:text-neutral-600" : "") ++ }, item && typeof item === "object" && "label" in item ? item.label : item); ++ }))), /* @__PURE__ */ React3.createElement(HeadlessTab.Panels, null, children)); ++} ++function Tab({ children }) { ++ return /* @__PURE__ */ React3.createElement(HeadlessTab.Panel, { ++ className: "focus:outline-none focus-visible:ring" ++ }, children); ++} ++ ++// src/bleed.tsx ++import React4 from "react"; ++import cn2 from "classnames"; ++var Bleed = ({ ++ full, ++ children ++}) => { ++ return /* @__PURE__ */ React4.createElement("div", { ++ className: cn2("bleed relative mt-6 -mx-6 md:-mx-8 2xl:-mx-24", { full }) ++ }, children); ++}; ++var bleed_default = Bleed; ++ ++// src/callout.tsx ++import React5 from "react"; ++var themes = { ++ default: "bg-orange-50 border border-orange-100 text-orange-800 dark:text-orange-300 dark:bg-orange-400 dark:border-orange-400 dark:bg-opacity-20 dark:border-opacity-30", ++ error: "bg-red-100 border border-red-200 text-red-900 dark:text-red-200 dark:bg-red-900 dark:bg-opacity-30 dark:border-opacity-30", ++ info: "bg-blue-100 border border-blue-200 text-blue-900 dark:text-blue-200 dark:bg-blue-900 dark:bg-opacity-30 dark:border-opacity-30", ++ warning: "bg-yellow-50 border border-yellow-100 text-yellow-900 dark:text-yellow-200 dark:bg-yellow-700 dark:bg-opacity-30" ++}; ++var Callout = ({ ++ children, ++ type = "default", ++ emoji = "\u{1F4A1}" ++}) => { ++ return /* @__PURE__ */ React5.createElement("div", { ++ className: `${themes[type]} flex rounded-lg nextra-callout mt-6` ++ }, /* @__PURE__ */ React5.createElement("div", { ++ className: "pl-3 pr-2 py-2 select-none text-xl", ++ style: { ++ fontFamily: '"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"' ++ } ++ }, emoji), /* @__PURE__ */ React5.createElement("div", { ++ className: "pr-4 py-2" ++ }, children)); ++}; ++var callout_default = Callout; ++ ++// src/misc/theme.tsx ++var observer; ++var setActiveAnchor; ++var slugs = /* @__PURE__ */ new WeakMap(); ++if (typeof window !== "undefined") { ++ observer = observer || new IntersectionObserver((entries) => { ++ const headers = []; ++ for (const entry of entries) { ++ if (entry && entry.rootBounds && slugs.has(entry.target)) { ++ const [slug, index] = slugs.get(entry.target); ++ const aboveHalfViewport = entry.boundingClientRect.y + entry.boundingClientRect.height <= entry.rootBounds.y + entry.rootBounds.height; ++ const insideHalfViewport = entry.intersectionRatio > 0; ++ headers.push([slug, index, aboveHalfViewport, insideHalfViewport]); ++ } ++ } ++ setActiveAnchor((f) => { ++ const ret = __spreadValues({}, f); ++ for (const header of headers) { ++ ret[header[0]] = { ++ index: header[1], ++ aboveHalfViewport: header[2], ++ insideHalfViewport: header[3] ++ }; ++ } ++ let activeSlug = ""; ++ let smallestIndexInViewport = Infinity; ++ let largestIndexAboveViewport = -1; ++ for (let s in ret) { ++ ret[s].isActive = false; ++ if (ret[s].insideHalfViewport && ret[s].index < smallestIndexInViewport) { ++ smallestIndexInViewport = ret[s].index; ++ activeSlug = s; ++ } ++ if (smallestIndexInViewport === Infinity && ret[s].aboveHalfViewport && ret[s].index > largestIndexAboveViewport) { ++ largestIndexAboveViewport = ret[s].index; ++ activeSlug = s; ++ } ++ } ++ if (ret[activeSlug]) ++ ret[activeSlug].isActive = true; ++ return ret; ++ }); ++ }, { ++ rootMargin: "0px 0px -50%", ++ threshold: [0, 1] ++ }); ++} ++var createHeaderLink = (Tag) => function HeaderLink(_a) { ++ var _b = _a, { ++ children, ++ id: slug ++ } = _b, props = __objRest(_b, [ ++ "children", ++ "id" ++ ]); ++ setActiveAnchor = useActiveAnchorSet(); ++ const obRef = useRef2(null); ++ useEffect2(() => { ++ const ref = obRef; ++ if (!ref.current) ++ return; ++ slugs.set(ref.current, [slug, Number(Tag[1]) - 1]); ++ if (ref.current) ++ observer.observe(ref.current); ++ return () => { ++ observer.disconnect(); ++ slugs.delete(ref.current); ++ setActiveAnchor((f) => { ++ const ret = __spreadValues({}, f); ++ delete ret[slug]; ++ return ret; ++ }); ++ }; ++ }, []); ++ return /* @__PURE__ */ React6.createElement(Tag, __spreadValues({}, props), /* @__PURE__ */ React6.createElement("span", { ++ className: "subheading-anchor", ++ id: slug, ++ ref: obRef ++ }), /* @__PURE__ */ React6.createElement("a", { ++ href: "#" + slug, ++ className: "anchor text-current no-underline no-outline" ++ }, children, /* @__PURE__ */ React6.createElement("span", { ++ className: "anchor-icon", ++ "aria-hidden": true ++ }, "#"))); ++}; ++var A = (_a) => { ++ var _b = _a, { ++ children, ++ href ++ } = _b, props = __objRest(_b, [ ++ "children", ++ "href" ++ ]); ++ if (!href) { ++ return null; ++ } ++ const isExternal = href.startsWith("https://"); ++ return isExternal ? /* @__PURE__ */ React6.createElement("a", __spreadValues({ ++ target: "_blank", ++ rel: "noreferrer", ++ href ++ }, props), children) : /* @__PURE__ */ React6.createElement(NextLink, { ++ href, ++ passHref: true ++ }, /* @__PURE__ */ React6.createElement("a", __spreadValues({}, props), children)); ++}; ++var Table = ({ children }) => { ++ return /* @__PURE__ */ React6.createElement("div", { ++ className: "table-container" ++ }, /* @__PURE__ */ React6.createElement("table", null, children)); ++}; ++var DetailsContext = React6.createContext(() => { ++}); ++var findSummary = (children) => { ++ let summary = null; ++ let restChildren = []; ++ React6.Children.forEach(children, (child, index) => { ++ var _a; ++ if (child && child.type === Summary) { ++ summary = summary || child; ++ return; ++ } ++ let c = child; ++ if (!summary && typeof child === "object" && child && child.type !== Details && "props" in child && child.props) { ++ const result = findSummary(child.props.children); ++ summary = summary || result[0]; ++ c = React6.cloneElement(child, __spreadProps(__spreadValues({}, child.props), { ++ children: ((_a = result[1]) == null ? void 0 : _a.length) ? result[1] : void 0, ++ key: index ++ })); ++ } ++ restChildren.push(c); ++ }); ++ return [summary, restChildren]; ++}; ++var Details = (_a) => { ++ var _b = _a, { ++ children, ++ open ++ } = _b, props = __objRest(_b, [ ++ "children", ++ "open" ++ ]); ++ const [openState, setOpen] = useState2(!!open); ++ const ref = useRef2(null); ++ const [summary, restChildren] = findSummary(children); ++ return /* @__PURE__ */ React6.createElement("details", __spreadValues(__spreadProps(__spreadValues({}, props), { ++ ref, ++ open: true ++ }), openState && { "data-open": "" }), /* @__PURE__ */ React6.createElement(DetailsContext.Provider, { ++ value: setOpen ++ }, summary), /* @__PURE__ */ React6.createElement(Collapse, { ++ open: openState ++ }, restChildren)); ++}; ++var Summary = (_a) => { ++ var _b = _a, { ++ children ++ } = _b, props = __objRest(_b, [ ++ "children" ++ ]); ++ const setOpen = useContext2(DetailsContext); ++ return /* @__PURE__ */ React6.createElement("summary", __spreadProps(__spreadValues({}, props), { ++ onClick: (e) => { ++ e.preventDefault(); ++ setOpen((v) => !v); ++ } ++ }), children); ++}; ++var components = { ++ h2: createHeaderLink("h2"), ++ h3: createHeaderLink("h3"), ++ h4: createHeaderLink("h4"), ++ h5: createHeaderLink("h5"), ++ h6: createHeaderLink("h6"), ++ a: A, ++ table: Table, ++ details: Details, ++ summary: Summary, ++ Nextra: { ++ Bleed: bleed_default, ++ Callout: callout_default, ++ Tabs, ++ Tab ++ } ++}; ++var MDXTheme = ({ ++ children ++}) => { ++ return /* @__PURE__ */ React6.createElement(MDXProvider, { ++ components ++ }, children); ++}; ++export { ++ MDXTheme, ++ components ++}; +diff --git a/node_modules/nextra-theme-docs/package.json b/node_modules/nextra-theme-docs/package.json +index 98b2f56..7b4a40b 100644 +--- a/node_modules/nextra-theme-docs/package.json ++++ b/node_modules/nextra-theme-docs/package.json +@@ -25,6 +25,9 @@ + }, + "./tabs": { + "import": "./dist/components/tabs.js" ++ }, ++ "./theme": { ++ "import":"./dist/misc/theme.js" + } + }, + "scripts": { diff --git a/prettier.config.cjs b/prettier.config.cjs index cd056fbdf20..f7673363809 100644 --- a/prettier.config.cjs +++ b/prettier.config.cjs @@ -6,5 +6,8 @@ module.exports = { ...plugins, // `prettier-plugin-svelte` and `svelte` packages used for formatting ```svelte code blocks in md/mdx files 'prettier-plugin-svelte', + // Sort classes in website + 'prettier-plugin-tailwindcss', ], + tailwindConfig: './website/tailwind.config.cjs', }; diff --git a/website/.babelrc.js b/website/.babelrc.js deleted file mode 100644 index b88126e4470..00000000000 --- a/website/.babelrc.js +++ /dev/null @@ -1,14 +0,0 @@ -module.exports = { - presets: [ - [ - 'next/babel', - { - 'preset-react': { - runtime: 'automatic', - importSource: '@emotion/react', - }, - }, - ], - ], - plugins: ['@emotion/babel-plugin', 'babel-plugin-macros'], -}; diff --git a/website/.eslintrc.js b/website/.eslintrc.js index 08471cc08f7..567ae9fbab6 100644 --- a/website/.eslintrc.js +++ b/website/.eslintrc.js @@ -13,15 +13,4 @@ module.exports = { 'react/jsx-curly-brace-presence': ['error', 'never'], 'react/jsx-filename-extension': ['error', { extensions: ['.tsx'] }], }, - overrides: [ - { - files: ['.babelrc.js', '.eslintrc.js', 'next-i18next.config.js', 'next.config.js'], - env: { - node: true, - }, - rules: { - '@typescript-eslint/no-var-requires': 'off', - }, - }, - ], }; diff --git a/website/docs-templates/client-note.md b/website/docs-templates/client-note.md deleted file mode 100644 index 5a7088afd70..00000000000 --- a/website/docs-templates/client-note.md +++ /dev/null @@ -1,5 +0,0 @@ - -In order to use this GraphQL Codegen plugin, please make sure that you have GraphQL operations (`query` / `mutation` / `subscription` and `fragment`) set as `documents: ...` in your `codegen.yml`. - -Without loading your GraphQL operations (`query`, `mutation`, `subscription` and `fragment`), you won't see any change in the generated output. - diff --git a/website/docs-templates/flow-operations.md b/website/docs-templates/flow-operations.md deleted file mode 100644 index 7f53056e1dd..00000000000 --- a/website/docs-templates/flow-operations.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -id: flow-operations ---- - -{@operationsNote} - -{@apiDocs} diff --git a/website/docs-templates/import-types-preset.md b/website/docs-templates/import-types-preset.md deleted file mode 100644 index bef2a14dcd1..00000000000 --- a/website/docs-templates/import-types-preset.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -id: import-types ---- - -This preset generates a file per each operation file, and allow to import types from another file. - -{@apiDocs} diff --git a/website/docs-templates/introspection.md b/website/docs-templates/introspection.md deleted file mode 100644 index 3ea7da20b81..00000000000 --- a/website/docs-templates/introspection.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -id: introspection ---- - -{@apiDocs} diff --git a/website/docs-templates/java-resolvers.md b/website/docs-templates/java-resolvers.md deleted file mode 100644 index f03403fd2f5..00000000000 --- a/website/docs-templates/java-resolvers.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -id: java-resolvers ---- - -The `java-resolvers` plugin creates Java `interface`s for the resolvers' signature. - -It works with `graphql-java` library, and it uses it's `DataFetcher` API. - -You can use this plugin to generate interfaces and later implement them, this way you can always tell if one of the fields is missing a resolvers: - -```java -import com.my.app.generated.Resolvers; -import com.my.app.models.User; -import graphql.schema.DataFetcher; - -export class QueryResolvers implements Resolvers.Query { - public DataFetcher id() { - return environment -> environment.getSource().getId(); - } -} -``` - -## Prepare your environment - -{@javaInstallation} - -{@apiDocs} diff --git a/website/docs-templates/java.md b/website/docs-templates/java.md deleted file mode 100644 index d040e44324a..00000000000 --- a/website/docs-templates/java.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -id: java ---- - -## Prepare your environment - -{@javaInstallation} - -{@apiDocs} - -## How to use - -You can use it directly to transform your `input` in your resolvers: - -```graphql -type Query { - user(id: ID!): User! -} - -type User { - id: ID -} -``` - -Then, in your resolver: - -```java -import com.my.app.generated.Types; -import com.my.app.models.User; -import graphql.schema.DataFetcher; - -export class QueryResolvers { - public DataFetcher user() { - return env -> { - Types.QueryUserArgs args = new Types.QueryUserArgs(env.getArguments()); - String userId = args.getId(); - - // rest of the code - }; - } -} -``` diff --git a/website/docs-templates/jsdoc.md b/website/docs-templates/jsdoc.md deleted file mode 100644 index 96ac121a3a9..00000000000 --- a/website/docs-templates/jsdoc.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -id: jsdoc ---- - -> developed by [`CarloPalinckx`](https://github.com/CarloPalinckx) - -This plugin generates types in the form of JSDoc comments based on your GraphQLSchema. diff --git a/website/docs-templates/schema-ast.md b/website/docs-templates/schema-ast.md deleted file mode 100644 index 0b78517e690..00000000000 --- a/website/docs-templates/schema-ast.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -id: schema-ast ---- - -{@apiDocs} - -## Examples - -```yaml -# ... -schema: - - 'http://localhost:3000/graphql' - - './src/**/*.graphql' - - 'scalar MyCustomScalar' -generates: - path/to/file.graphql: - plugins: - - schema-ast -``` diff --git a/website/docs-templates/time.md b/website/docs-templates/time.md deleted file mode 100644 index 0e5947ceed6..00000000000 --- a/website/docs-templates/time.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -id: time ---- - -{@apiDocs} diff --git a/website/docs-templates/typescript-generic-sdk.md b/website/docs-templates/typescript-generic-sdk.md deleted file mode 100644 index b07b7f891ab..00000000000 --- a/website/docs-templates/typescript-generic-sdk.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -id: typescript-generic-sdk ---- - -{@operationsNote} - -> Make sure you have `typescript` plugin and `typescript-operations` as well in your configuration: - -{@apiDocs} - -## Usage - -You can find a usage [example for Apollo-Client here](https://gist.github.com/akozhemiakin/731b0c1e99eb89b01f80f08f9146b6b6). diff --git a/website/docs-templates/typescript-operations.md b/website/docs-templates/typescript-operations.md deleted file mode 100644 index 6b1f0c754c1..00000000000 --- a/website/docs-templates/typescript-operations.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -id: typescript-operations ---- - -{@operationsNote} - -{@apiDocs} diff --git a/website/docs-templates/typescript.md b/website/docs-templates/typescript.md deleted file mode 100644 index 1a7a54f5918..00000000000 --- a/website/docs-templates/typescript.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -id: typescript ---- - -{@apiDocs} diff --git a/website/docs-templates/urql-introspection.md b/website/docs-templates/urql-introspection.md deleted file mode 100644 index db365bac994..00000000000 --- a/website/docs-templates/urql-introspection.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -id: urql-introspection ---- - -{@apiDocs} - -## How to use? - -```ts -// generated by the plugin -import schema from './generated-introspection.json' -const cache = cacheExchange({ schema }) -``` - -> [Read more about Schema Awareness](https://formidable.com/open-source/urql/docs/graphcache/schema-awareness) diff --git a/website/docs/integrations/gatsby.mdx b/website/docs/integrations/gatsby.mdx deleted file mode 100644 index 45a64e3b4e3..00000000000 --- a/website/docs/integrations/gatsby.mdx +++ /dev/null @@ -1,14 +0,0 @@ ---- -id: gatsby -title: Gatsby ---- - -If you build apps using [Gatsby](https://gatsbyjs.com), you can use its built-in feature called [GraphQL Typegen](https://www.gatsbyjs.com/docs/how-to/local-development/graphql-typegen/). Under the hood it uses the GraphQL Code Generator to generate TypeScript types but you don't need to set anything up other than enabling an option. - -It also sets up everything needed for [GraphQL Config](https://www.graphql-config.com/). - -## Community Plugins - -Gatsby's GraphQL Typegen feature is solving most common use cases. If you find yourself limited by its features you should open a feature request or trying using one of these community plugins: - -- [gatsby-plugin-typegen](https://github.com/cometkim/gatsby-plugin-typegen) diff --git a/website/next-i18next.config.js b/website/next-i18next.config.js deleted file mode 100644 index fe5519f5669..00000000000 --- a/website/next-i18next.config.js +++ /dev/null @@ -1,4 +0,0 @@ -exports.i18n = { - defaultLocale: 'en', - locales: ['en'], -}; diff --git a/website/next.config.mjs b/website/next.config.mjs index 0dcc79bce3c..50e64565506 100644 --- a/website/next.config.mjs +++ b/website/next.config.mjs @@ -1,17 +1,20 @@ -import { createRequire } from 'module'; -import { withGuildDocs } from '@guild-docs/server'; -import { register } from 'esbuild-register/dist/node.js'; -import { i18n } from './next-i18next.config.js'; +import nextra from 'nextra'; +import { CategoryToPackages } from './src/category-to-packages.mjs'; -const require = createRequire(import.meta.url); - -register({ extensions: ['.ts', '.tsx'] }); +const withNextra = nextra({ + theme: 'nextra-theme-docs', + themeConfig: './theme.config.tsx', + unstable_staticImage: true, +}); -const { getRoutes } = require('./routes.ts'); +const PLUGINS_REDIRECTS = Object.entries(CategoryToPackages).flatMap(([category, packageNames]) => + packageNames.map(packageName => ({ + source: `/plugins/${packageName}`, + destination: `/plugin-hub/${category}/${packageName}`, + })) +); -export default withGuildDocs({ - i18n, - getRoutes, +export default withNextra({ eslint: { ignoreDuringBuilds: true, }, @@ -19,74 +22,68 @@ export default withGuildDocs({ // Todo: remove it before merge to master ignoreBuildErrors: true, }, + swcMinify: true, + reactStrictMode: true, + experimental: { + concurrentFeatures: false, + // serverComponents: true, + }, webpack(config) { config.resolve.fallback = { ...config.resolve.fallback, - module: false, // Fix error - Module not found: Can't resolve 'module' - fs: false, - repl: false, - console: false, + module: false, }; return config; }, - swcMinify: false, - async redirects() { - return [ + redirects: () => + [ { source: '/docs/presets/:presetName', destination: '/plugins/:presetName-preset', - permanent: true, }, { source: '/docs/plugins/:pluginName', destination: '/plugins/:pluginName', - permanent: true, }, { source: '/docs/getting-started/config-reference/codegen-config', destination: '/docs/config-reference/codegen-config', - permanent: true, }, { source: '/docs/getting-started/codegen-config', destination: '/docs/config-reference/codegen-config', - permanent: true, }, { source: '/docs/getting-started/documents-field', destination: '/docs/config-reference/documents-field', - permanent: true, }, { source: '/docs/getting-started/schema-field', destination: '/docs/config-reference/schema-field', - permanent: true, }, { source: '/docs/getting-started/config-field', destination: '/docs/config-reference/config-field', - permanent: true, }, { source: '/docs/getting-started/lifecycle-hooks', destination: '/docs/config-reference/lifecycle-hooks', - permanent: true, }, { source: '/docs/getting-started/require-field', destination: '/docs/config-reference/require-field', - permanent: true, }, { source: '/docs/getting-started/naming-convention', destination: '/docs/config-reference/naming-convention', - permanent: true, }, { source: '/docs/getting-started/how-does-it-work', destination: '/docs/advanced/how-does-it-work', - permanent: true, }, - ]; - }, + ...PLUGINS_REDIRECTS, + ].map(redirect => ({ + ...redirect, + permanent: true, + })), }); diff --git a/website/package.json b/website/package.json index d46c5c017b2..f4c8801e680 100644 --- a/website/package.json +++ b/website/package.json @@ -6,7 +6,7 @@ "algolia-sync": "node scripts/algolia-ci.mjs", "start": "yarn generate-json-config && next start", "build": "yarn generate-json-config && next build", - "dev": "concurrently -r 'next-remote-watch ./docs ./src/pages/_app.tsx' 'wait-on -s 1 http://localhost:3000'", + "dev": "next dev", "lint": "eslint --ignore-path .gitignore --ext js,jsx,cjs,mjs,ts,tsx,cts,mts .", "next": "next", "generate-json-config": "ts-node generate-config-json-schema.ts" @@ -18,13 +18,13 @@ "@types/jsonpath": "0.2.0", "@types/node": "16.11.43", "@types/react": "18.0.15", - "@types/react-dom": "18.0.6", - "concurrently": "7.2.2", - "esbuild-register": "3.3.3", + "autoprefixer": "10.4.7", + "cssnano": "5.1.12", "eslint-config-next": "12.2.2", "jsonpath": "1.1.1", - "typescript": "4.7.4", - "wait-on": "6.0.1" + "postcss": "8.4.14", + "prettier-plugin-tailwindcss": "0.1.11", + "tailwindcss": "3.1.4" }, "dependencies": { "@chakra-ui/icons": "1.1.7", @@ -74,9 +74,8 @@ "@graphql-codegen/typescript-vue-urql": "2.3.1", "@guild-docs/client": "3.1.0", "@guild-docs/server": "4.0.0", - "@mdx-js/react": "2.1.2", "@monaco-editor/react": "4.4.5", - "@theguild/components": "1.11.8", + "@theguild/components": "2.0.0-alpha-7788278.0", "classnames": "2.3.1", "date-fns": "2.28.0", "dedent": "0.7.0", @@ -85,24 +84,17 @@ "js-yaml": "4.1.0", "next": "12.2.2", "next-i18next": "11.0.0", - "next-remote-watch": "1.0.0", + "next-mdx-remote": "4.0.3", "next-seo": "5.4.0", - "node-polyfill-webpack-plugin": "2.0.0", + "nextra": "2.0.0-alpha.56", + "nextra-theme-docs": "2.0.0-alpha.59", "react": "17.0.2", "react-dom": "17.0.2", - "react-markdown": "8.0.3", - "react-select": "5.4.0", "react-icons": "4.4.0", + "react-select": "5.4.0", "react-use": "17.4.0", - "remark-admonitions": "1.2.1", - "shiki": "0.10.1", "typescript-json-schema": "0.54.0" }, - "babelMacros": { - "twin": { - "preset": "emotion" - } - }, "browserslist": { "production": [ ">0.2%", diff --git a/website/postcss.config.js b/website/postcss.config.js new file mode 100644 index 00000000000..5825d8b7d83 --- /dev/null +++ b/website/postcss.config.js @@ -0,0 +1,7 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + ...(process.env.NODE_ENV === 'production' && { cssnano: {} }), + }, +}; diff --git a/website/public/config.schema.json b/website/public/config.schema.json index d05315f1049..9a68862c569 100644 --- a/website/public/config.schema.json +++ b/website/public/config.schema.json @@ -415,6 +415,10 @@ "description": "Generates enum as TypeScript `const assertions` instead of `enum`. This can even be used to enable enum-like patterns in plain JavaScript code if you choose not to use TypeScript’s enum construct.\nDefault value: \"false\"", "type": "boolean" }, + "onlyEnums": { + "description": "This will cause the generator to emit types for enums only.\nDefault value: \"false\"", + "type": "boolean" + }, "onlyOperationTypes": { "description": "This will cause the generator to emit types for operations only (basically only enums and scalars).\nInteracts well with `preResolveTypes: true`\nDefault value: \"false\"", "type": "boolean" @@ -596,6 +600,10 @@ "description": "If set to true, it will enable support for parsing variables on fragments.\nDefault value: \"false\"", "type": "boolean" }, + "mergeFragmentTypes": { + "description": "If set to true, merge equal fragment interfaces.\nDefault value: \"false\"", + "type": "boolean" + }, "addUnderscoreToArgsType": { "description": "Adds `_` to generated `Args` types in order to avoid duplicate identifiers.", "type": "boolean" @@ -623,6 +631,10 @@ "description": "Set to `true` in order to wrap field definitions with `FieldWrapper`.\nThis is useful to allow return types such as Promises and functions.\nDefault value: \"false\"", "type": "boolean" }, + "onlyEnums": { + "description": "This will cause the generator to emit types for enums only\nDefault value: \"false\"", + "type": "boolean" + }, "onlyOperationTypes": { "description": "This will cause the generator to emit types for operations only (basically only enums and scalars)\nDefault value: \"false\"", "type": "boolean" @@ -951,6 +963,10 @@ "description": "Generates enum as TypeScript `const assertions` instead of `enum`. This can even be used to enable enum-like patterns in plain JavaScript code if you choose not to use TypeScript’s enum construct.\nDefault value: \"false\"", "type": "boolean" }, + "onlyEnums": { + "description": "This will cause the generator to emit types for enums only.\nDefault value: \"false\"", + "type": "boolean" + }, "onlyOperationTypes": { "description": "This will cause the generator to emit types for operations only (basically only enums and scalars).\nInteracts well with `preResolveTypes: true`\nDefault value: \"false\"", "type": "boolean" @@ -2765,6 +2781,10 @@ "description": "Set to `true` in order to wrap field definitions with `FieldWrapper`.\nThis is useful to allow return types such as Promises and functions.\nDefault value: \"false\"", "type": "boolean" }, + "onlyEnums": { + "description": "This will cause the generator to emit types for enums only\nDefault value: \"false\"", + "type": "boolean" + }, "onlyOperationTypes": { "description": "This will cause the generator to emit types for operations only (basically only enums and scalars)\nDefault value: \"false\"", "type": "boolean" @@ -3003,6 +3023,10 @@ "description": "If set to true, it will enable support for parsing variables on fragments.\nDefault value: \"false\"", "type": "boolean" }, + "mergeFragmentTypes": { + "description": "If set to true, merge equal fragment interfaces.\nDefault value: \"false\"", + "type": "boolean" + }, "addUnderscoreToArgsType": { "description": "Adds `_` to generated `Args` types in order to avoid duplicate identifiers.", "type": "boolean" @@ -3030,6 +3054,10 @@ "description": "Set to `true` in order to wrap field definitions with `FieldWrapper`.\nThis is useful to allow return types such as Promises and functions.\nDefault value: \"false\"", "type": "boolean" }, + "onlyEnums": { + "description": "This will cause the generator to emit types for enums only\nDefault value: \"false\"", + "type": "boolean" + }, "onlyOperationTypes": { "description": "This will cause the generator to emit types for operations only (basically only enums and scalars)\nDefault value: \"false\"", "type": "boolean" @@ -3122,7 +3150,7 @@ } }, "FragmentMatcherConfig": { - "description": "This plugin generates an introspection file but only with Interfaces and Unions, based on your GraphQLSchema.\n\nIf you are using `apollo-client` and your schema contains `interface` or `union` declaration, it's recommended to use Apollo's Fragment Matcher and the result generated by the plugin.\n\nYou can read more about it in `apollo-client` documentation: https://www.apollographql.com/docs/react/data/fragments/#fragments-on-unions-and-interfaces.\n\nFragment Matcher plugin accepts a TypeScript / JavaScript or a JSON file as an output _(`.ts, .tsx, .js, .jsx, .json`)_.\n\nBoth in TypeScript and JavaScript a default export is being used.\n\n> The output is based on the output you choose for the output file name.", + "description": "This plugin generates an introspection file but only with Interfaces and Unions, based on your GraphQLSchema.\n\nIf you are using `apollo-client` and your schema contains `interface` or `union` declaration, it's recommended to use Apollo's Fragment Matcher and the result generated by the plugin.\n\nYou can read more about it in [`apollo-client` documentation](https://apollographql.com/docs/react/data/fragments/#fragments-on-unions-and-interfaces).\n\nFragment Matcher plugin accepts a TypeScript / JavaScript or a JSON file as an output _(`.ts, .tsx, .js, .jsx, .json`)_.\n\nBoth in TypeScript and JavaScript a default export is being used.\n\n> The output is based on the output you choose for the output file name.", "type": "object", "properties": { "module": { @@ -4349,11 +4377,11 @@ }, { "const": "fragment-matcher", - "description": "This plugin generates an introspection file but only with Interfaces and Unions, based on your GraphQLSchema.\n\nIf you are using `apollo-client` and your schema contains `interface` or `union` declaration, it's recommended to use Apollo's Fragment Matcher and the result generated by the plugin.\n\nYou can read more about it in `apollo-client` documentation: https://www.apollographql.com/docs/react/data/fragments/#fragments-on-unions-and-interfaces.\n\nFragment Matcher plugin accepts a TypeScript / JavaScript or a JSON file as an output _(`.ts, .tsx, .js, .jsx, .json`)_.\n\nBoth in TypeScript and JavaScript a default export is being used.\n\n> The output is based on the output you choose for the output file name.\n\nFor more details and documentation: https://graphql-code-generator.com/docs/plugins/fragment-matcher\n\n=> Make sure to include \"@graphql-codegen/fragment-matcher\" in your package.json file and install your dependencies.\n\n" + "description": "This plugin generates an introspection file but only with Interfaces and Unions, based on your GraphQLSchema.\n\nIf you are using `apollo-client` and your schema contains `interface` or `union` declaration, it's recommended to use Apollo's Fragment Matcher and the result generated by the plugin.\n\nYou can read more about it in [`apollo-client` documentation](https://apollographql.com/docs/react/data/fragments/#fragments-on-unions-and-interfaces).\n\nFragment Matcher plugin accepts a TypeScript / JavaScript or a JSON file as an output _(`.ts, .tsx, .js, .jsx, .json`)_.\n\nBoth in TypeScript and JavaScript a default export is being used.\n\n> The output is based on the output you choose for the output file name.\n\nFor more details and documentation: https://graphql-code-generator.com/docs/plugins/fragment-matcher\n\n=> Make sure to include \"@graphql-codegen/fragment-matcher\" in your package.json file and install your dependencies.\n\n" }, { "const": "@graphql-codegen/fragment-matcher", - "description": "This plugin generates an introspection file but only with Interfaces and Unions, based on your GraphQLSchema.\n\nIf you are using `apollo-client` and your schema contains `interface` or `union` declaration, it's recommended to use Apollo's Fragment Matcher and the result generated by the plugin.\n\nYou can read more about it in `apollo-client` documentation: https://www.apollographql.com/docs/react/data/fragments/#fragments-on-unions-and-interfaces.\n\nFragment Matcher plugin accepts a TypeScript / JavaScript or a JSON file as an output _(`.ts, .tsx, .js, .jsx, .json`)_.\n\nBoth in TypeScript and JavaScript a default export is being used.\n\n> The output is based on the output you choose for the output file name.\n\nFor more details and documentation: https://graphql-code-generator.com/docs/plugins/fragment-matcher\n\n=> Make sure to include \"@graphql-codegen/fragment-matcher\" in your package.json file and install your dependencies.\n\n" + "description": "This plugin generates an introspection file but only with Interfaces and Unions, based on your GraphQLSchema.\n\nIf you are using `apollo-client` and your schema contains `interface` or `union` declaration, it's recommended to use Apollo's Fragment Matcher and the result generated by the plugin.\n\nYou can read more about it in [`apollo-client` documentation](https://apollographql.com/docs/react/data/fragments/#fragments-on-unions-and-interfaces).\n\nFragment Matcher plugin accepts a TypeScript / JavaScript or a JSON file as an output _(`.ts, .tsx, .js, .jsx, .json`)_.\n\nBoth in TypeScript and JavaScript a default export is being used.\n\n> The output is based on the output you choose for the output file name.\n\nFor more details and documentation: https://graphql-code-generator.com/docs/plugins/fragment-matcher\n\n=> Make sure to include \"@graphql-codegen/fragment-matcher\" in your package.json file and install your dependencies.\n\n" }, { "const": "urql-introspection", diff --git a/website/public/locales/en/common.json b/website/public/locales/en/common.json deleted file mode 100644 index 1dd64c715b3..00000000000 --- a/website/public/locales/en/common.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "greeting": "Hello!" -} diff --git a/website/public/style.css b/website/public/style.css index 677c6c186ec..b5c61c95671 100644 --- a/website/public/style.css +++ b/website/public/style.css @@ -1,58 +1,3 @@ -code[class*='language-'], -pre[class*='language-'] { - white-space: pre-wrap !important; - word-break: break-word !important; -} - -code, -code * { - font-family: 'SF Mono', 'Source Code Pro', Menlo, monospace !important; - - margin-top: 0.2em; - margin-bottom: 0.2em; -} - -article { - width: 100%; - overflow-x: auto; -} - -#__next { - font-family: TGCFont, sans-serif; -} - -.admonition-heading .chakra-heading { - padding-top: 0; -} - -.collapse-title { - font-weight: bold; - margin-bottom: 0.5rem; - cursor: pointer; - font-family: 'SF Mono', 'Source Code Pro', Menlo, monospace !important; -} - -.collapse-title > p { - display: inline-block; -} - -details > *:last-child { - padding-bottom: 2rem; -} - -.admonition { - margin-top: 10px; -} - -.admonition-heading h5 { - text-transform: none; -} - -.chakra-link { - color: #0070f3; - text-decoration: none; -} - -.chakra-collapse a { - border-left-width: 0 !important; -} +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/website/routes.ts b/website/routes.ts index b80b1460935..e69de29bb2d 100644 --- a/website/routes.ts +++ b/website/routes.ts @@ -1,87 +0,0 @@ -import type { IRoutes } from '@guild-docs/server'; -import { GenerateRoutes } from '@guild-docs/server'; - -export function getRoutes(): IRoutes { - const Routes: IRoutes = { - _: { - 'docs/getting-started': { - $name: 'Getting Started', - $routes: [ - ['index', 'Introduction'], - ['installation', 'Installation'], - ['development-workflow', 'Development workflow'], - ], - }, - 'docs/guides': { - $name: 'Guides', - $routes: [ - ['react', 'React'], - ['vue', 'Vue.js'], - ['angular', 'Angular'], - ['svelte', 'Svelte / Kit'], - ['front-end-typescript-only', 'TypeScript only (front-end)'], - ['graphql-server-apollo-yoga', 'Apollo Server / GraphQL Yoga'], - ['graphql-modules', 'GraphQL Modules'], - ['further-reading', 'Further Reading'], - ], - }, - 'docs/config-reference': { - $name: 'Config Reference', - $routes: [ - ['codegen-config', 'codegen.yml'], - ['schema-field', 'schema field'], - ['documents-field', 'documents field'], - ['config-field', 'plugin config'], - ['require-field', 'require field'], - ['naming-convention', 'Naming Convention'], - ['lifecycle-hooks', 'Lifecycle Hooks'], - ['multiproject-config', 'Multi Project'], - ], - }, - 'docs/advanced': { - $name: 'Advanced Usage', - $routes: [ - ['generated-files-colocation', 'Generated files colocation'], - ['programmatic-usage', 'Programmatic Usage'], - ['how-does-it-work', 'How does it work?'], - ['profiler', 'Profiler'], - ], - }, - 'docs/integrations': { - $name: 'Integrations', - $routes: [ - ['vscode', 'VSCode Extension'], - ['prettier', 'Prettier'], - ['federation', 'Apollo Federation'], - ['apollo-local-state', 'apollo-local-state'], - ['create-react-app', 'create-react-app'], - ['gatsby', 'Gatsby'], - ], - }, - 'docs/custom-codegen': { - $name: 'Writing Plugins', - $routes: [ - ['index', 'What are Plugins?'], - ['plugin-structure', 'Plugin structure'], - ['validate-configuration', 'Validate Configuration'], - ['extend-schema', 'Extend Schema'], - ['using-visitor', 'Using Visitor Pattern'], - ['contributing', 'Contributing'], - ], - }, - 'docs/migration': { - $name: 'Migration Guides', - $routes: [ - ['from-0-18', 'v0.18 -> v1.0'], - ['from-0-13', 'v0.13 -> v0.17'], - ], - }, - }, - }; - - GenerateRoutes({ - Routes, - }); - - return Routes; -} diff --git a/website/src/category-to-packages.mjs b/website/src/category-to-packages.mjs new file mode 100644 index 00000000000..5f250cfa311 --- /dev/null +++ b/website/src/category-to-packages.mjs @@ -0,0 +1,49 @@ +/* + Used to determine right category folder in plugin hub and for redirect legacy links in next.config#redirects + */ +export const CategoryToPackages = { + 'c-sharp': ['c-sharp-operations'], + flow: ['flow-operations', 'flow-resolvers'], + java: ['java', 'java-apollo-android', 'java-resolvers', 'kotlin'], + other: [ + 'urql-introspection', + 'time', + 'schema-ast', + 'reason-client', + 'jsdoc', + 'introspection', + 'hasura-allow-list', + 'fragment-matcher', + 'add', + ], + presets: ['near-operation-file-preset', 'import-types-preset', 'graphql-modules-preset', 'gql-tag-operations-preset'], + typescript: [ + 'named-operations-object', + 'relay-operation-optimizer', + 'typed-document-node', + 'typescript', + 'typescript-apollo-angular', + 'typescript-apollo-client-helpers', + 'typescript-apollo-next', + 'typescript-document-nodes', + 'typescript-generic-sdk', + 'typescript-graphql-files-modules', + 'typescript-graphql-request', + 'typescript-mongodb', + 'typescript-msw', + 'typescript-oclif', + 'typescript-operations', + 'typescript-react-apollo', + 'typescript-react-query', + 'typescript-resolvers', + 'typescript-rtk-query', + 'typescript-stencil-apollo', + 'typescript-svelte-apollo', + 'typescript-type-graphql', + 'typescript-urql', + 'typescript-validation-schema', + 'typescript-vue-apollo', + 'typescript-vue-apollo-smart-ops', + 'typescript-vue-urql', + ], +}; diff --git a/website/src/components/MDXTabs/MDXTab.tsx b/website/src/components/MDXTabs/MDXTab.tsx deleted file mode 100644 index ea727c2d66f..00000000000 --- a/website/src/components/MDXTabs/MDXTab.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import React, { ReactNode, useContext, useEffect } from 'react'; -import { MDXTabCurrentTabsContext } from './MDXTabs'; - -const MDXTab = ({ children, label }: { label: string; children?: ReactNode }) => { - const { addTab } = useContext(MDXTabCurrentTabsContext); - - // register the tab in the tabs parent - useEffect(() => { - addTab(label); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - return <>{children}; -}; - -export default MDXTab; diff --git a/website/src/components/MDXTabs/MDXTabs.tsx b/website/src/components/MDXTabs/MDXTabs.tsx deleted file mode 100644 index a7c38254b73..00000000000 --- a/website/src/components/MDXTabs/MDXTabs.tsx +++ /dev/null @@ -1,101 +0,0 @@ -import { Tab, TabList, TabPanel, TabPanels, Tabs } from '@chakra-ui/tabs'; -import { MDXTabsCurrentTabContext } from 'components/MDXTabsCurrentTabContext'; -import React, { Children, createContext, ReactNode, useCallback, useContext, useState } from 'react'; - -// fetch active tabIndex across all instances of sharing the same namespace -const useCurrentTab = (namespace: string): [number, (i: number) => void] => { - const { value, update } = useContext(MDXTabsCurrentTabContext); - - const setTab = useCallback( - (i: number) => { - update(namespace, i); - }, - [namespace, update] - ); - - return [value[namespace], setTab]; -}; - -interface MDXTabCurrentTabsContext { - value: string[]; - addTab: (value: string) => void; -} - -export const MDXTabCurrentTabsContext = createContext({ - value: [], - // eslint-disable-next-line @typescript-eslint/no-empty-function - addTab: () => {}, -}); -const MDXTabsCurrentTabsContextProvider: React.FunctionComponent = ({ children }) => { - const [value, updateValue] = useState([]); - - const addTab = useCallback( - (tab: string) => { - updateValue(prev => [...prev, tab]); - }, - [updateValue] - ); - - return {children}; -}; - -const MDXTabsRenderer = ({ children, namespace }: { namespace: string; children: ReactNode }) => { - const [index, setTabIndex] = useCurrentTab(namespace); - const { value: tabs } = useContext(MDXTabCurrentTabsContext); - - return ( - - - {tabs.map(tab => ( - {tab} - ))} - - - {Children.toArray(children).map((c, k) => ( - {c} - ))} - - {/* */} - - ); -}; -/** - * Tab component that can contain MDX markup (ex: code snippet) - * - * @component - * @example - * - * - * - * - * Apollo code example here - * - * - * - * - * - * - * Yoga code example here - * - * - * - * - * ) - */ -const MDXTabs = ({ children, namespace }: { namespace: string; children: ReactNode }) => ( - - {children} - -); - -export default MDXTabs; diff --git a/website/src/components/MDXTabsCurrentTabContext.tsx b/website/src/components/MDXTabsCurrentTabContext.tsx deleted file mode 100644 index 215e373928f..00000000000 --- a/website/src/components/MDXTabsCurrentTabContext.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { createContext, useCallback, useState } from 'react'; - -interface Context { - value: { [k: string]: number }; - update: (ns: string, value: number) => void; -} - -export const MDXTabsCurrentTabContext = createContext({ - value: {}, - // eslint-disable-next-line @typescript-eslint/no-empty-function - update: () => {}, -}); - -export const Provider: React.FunctionComponent = ({ children }) => { - const [value, updateValue] = useState<{ [k: string]: number }>({}); - - const update = useCallback( - (ns: string, val: number) => { - updateValue({ - ...value, - [ns]: val, - }); - }, - [updateValue, value] - ); - - return {children}; -}; diff --git a/website/src/components/MDXWarning.tsx b/website/src/components/MDXWarning.tsx deleted file mode 100644 index 69071a96b15..00000000000 --- a/website/src/components/MDXWarning.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import React from 'react'; -import type { FC } from 'react'; -import { Flex, Alert, AlertIcon, AlertTitle, AlertDescription } from '@chakra-ui/react'; - -export const MDXWarning: FC<{ - title: string; -}> = props => { - return ( - - - - {props.title} - - {props.children} - - ); -}; diff --git a/website/src/components/index.ts b/website/src/components/index.ts new file mode 100644 index 00000000000..1a902c11384 --- /dev/null +++ b/website/src/components/index.ts @@ -0,0 +1,2 @@ +export { PackageCmd } from './package-cmd'; +export { PackageApiDocs, PackageHeader } from './package-api-docs'; diff --git a/website/src/components/live-demo/CodegenOutput.tsx b/website/src/components/live-demo/CodegenOutput.tsx index b71a068d330..33431aa194c 100644 --- a/website/src/components/live-demo/CodegenOutput.tsx +++ b/website/src/components/live-demo/CodegenOutput.tsx @@ -1,13 +1,13 @@ -import { FC, useEffect, useState } from 'react'; +import { ReactElement, useEffect, useState } from 'react'; import Editor from './Editor'; import { basename } from 'path'; import classes from './styles.module.css'; import classnames from 'classnames'; -const CodegenOutput: FC = ({ outputArray, editorProps, error }) => { +const CodegenOutput = ({ outputArray, editorProps, error }): ReactElement => { const [index, setIndex] = useState(0); - const editorContent = error ? error : outputArray && outputArray[index] ? outputArray[index].content : ''; + const editorContent = error || outputArray?.[index].content || ''; useEffect(() => { setIndex(0); diff --git a/website/src/components/live-demo/Editor.tsx b/website/src/components/live-demo/Editor.tsx index aa8327ad4bc..63778f602ec 100644 --- a/website/src/components/live-demo/Editor.tsx +++ b/website/src/components/live-demo/Editor.tsx @@ -1,14 +1,19 @@ -import { FC } from 'react'; +import { ReactElement } from 'react'; import { useThemeContext } from '@theguild/components'; import MonacoEditor from '@monaco-editor/react'; -import { canUseDOM } from '../../utils'; +import { canUseDOM } from '@/utils'; -const Editor: FC<{ lang: string; value: string; readOnly?: boolean; onEdit: (value?: string) => void }> = ({ +const Editor = ({ value, lang, readOnly, onEdit, -}) => { +}: { + lang: string; + value: string; + readOnly?: boolean; + onEdit: (value?: string) => void; +}): ReactElement | null => { const { isDarkTheme } = useThemeContext(); if (!canUseDOM) { @@ -27,7 +32,7 @@ const Editor: FC<{ lang: string; value: string; readOnly?: boolean; onEdit: (val enabled: false, }, }} - onChange={newValue => onEdit(newValue)} + onChange={onEdit} /> ); }; diff --git a/website/src/components/live-demo/LiveDemo.tsx b/website/src/components/live-demo/LiveDemo.tsx index 9e3e4250ccf..da51dc096fe 100644 --- a/website/src/components/live-demo/LiveDemo.tsx +++ b/website/src/components/live-demo/LiveDemo.tsx @@ -1,9 +1,8 @@ -import { useState, useEffect, Suspense, Fragment } from 'react'; +import { useState, useEffect, Suspense, Fragment, ReactElement } from 'react'; import { load } from 'js-yaml'; import dynamic from 'next/dynamic'; import Image from 'next/image'; import Select from 'react-select'; -// import ReactMarkdown from 'react-markdown'; import { useThemeContext } from '@theguild/components'; import { EXAMPLES, EXAMPLES_ICONS } from './examples'; import { getMode } from './formatter'; @@ -49,7 +48,7 @@ const DEFAULT_EXAMPLE = { index: 0, } as const; -export const LiveDemo = () => { +export const LiveDemo = (): ReactElement => { const { isDarkTheme } = useThemeContext(); const [template, setTemplate] = useState(`${DEFAULT_EXAMPLE.catName}__${DEFAULT_EXAMPLE.index}`); const [schema, setSchema] = useState(EXAMPLES[DEFAULT_EXAMPLE.catName][DEFAULT_EXAMPLE.index].schema); @@ -82,7 +81,7 @@ export const LiveDemo = () => { // } return ( - <> +

Choose Live Example:

@@ -136,11 +135,9 @@ export const LiveDemo = () => { defaultValue={groupedExamples[0].options[0]} options={groupedExamples} /> - {/* TODO: Should I add this ? */} - {/*
{description && {description}}
*/}
-
+
}> {
- +
); }; diff --git a/website/src/components/live-demo/examples.ts b/website/src/components/live-demo/examples.ts index 9e35b16b8d3..bc9fc31e8d2 100644 --- a/website/src/components/live-demo/examples.ts +++ b/website/src/components/live-demo/examples.ts @@ -31,7 +31,7 @@ export const EXAMPLES_ICONS = { src: '/assets/img/icons/mongodb.png', }, nodejs: { - alt: 'NodeJS', + alt: 'Node.js', src: '/assets/img/icons/nodejs.svg', }, react: { @@ -181,7 +181,8 @@ export const EXAMPLES = { }, { name: 'TypedDocumentNode', - description: `This plugin generates a per-compiled version of \`DocumentNode\`, with the result and variables types bundled into the object, using this library: https://github.com/dotansimha/graphql-typed-document-node`, + description: + 'This plugin generates a per-compiled version of `DocumentNode`, with the result and variables types bundled into the object, using this library: https://github.com/dotansimha/graphql-typed-document-node', tags: ['typescript', 'frontend'], config: `generates: operations-types.ts: @@ -204,7 +205,8 @@ export const EXAMPLES = { }, { name: 'React-Query Hooks', - description: `This example uses types generated by \`typescript\` and \`typescript-operations\`, and creates a fully type-safe React Hooks, based on your GraphQL operations, that wraps "react-query" hooks.`, + description: + 'This example uses types generated by `typescript` and `typescript-operations`, and creates a fully type-safe React Hooks, based on your GraphQL operations, that wraps "react-query" hooks.', tags: ['typescript', 'react', 'react-query', 'frontend'], config: `generates: types-and-hooks.tsx: diff --git a/website/src/components/live-demo/generate.ts b/website/src/components/live-demo/generate.ts index 56da5cbbf23..27b53444188 100644 --- a/website/src/components/live-demo/generate.ts +++ b/website/src/components/live-demo/generate.ts @@ -3,7 +3,7 @@ import { codegen } from '@graphql-codegen/core'; import { parse } from 'graphql'; import { pluginLoaderMap, presetLoaderMap } from './plugins'; import { normalizeConfig } from './utils'; -import { canUseDOM } from '../../utils'; +import { canUseDOM } from '@/utils'; if (canUseDOM) { process.hrtime = () => [0, 0]; // Fix error - TypeError: process.hrtime is not a function @@ -18,14 +18,14 @@ export async function generate(config: string, schema: string, documents?: strin const runConfigurations = []; for (const [filename, outputOptions] of Object.entries(generates)) { - const hasPreset = !!outputOptions.preset; + const hasPreset = Boolean(outputOptions.preset); const plugins = normalizeConfig(outputOptions.plugins || outputOptions); const outputConfig = outputOptions.config; const pluginMap = {}; await Promise.all( plugins.map(async pluginElement => { - const pluginName = Object.keys(pluginElement)[0]; + const [pluginName] = Object.keys(pluginElement); try { pluginMap[pluginName] = await pluginLoaderMap[pluginName](); } catch (e) { diff --git a/website/src/components/live-demo/styles.module.css b/website/src/components/live-demo/styles.module.css index 7245ae76a61..7a222e9f191 100644 --- a/website/src/components/live-demo/styles.module.css +++ b/website/src/components/live-demo/styles.module.css @@ -38,16 +38,6 @@ display: flex; } -.container { - display: flex; - align-items: flex-start; - justify-content: stretch; - border-top: 1px solid #e5e5e5; - border-bottom: 1px solid #e5e5e5; - margin-top: 3px; - font-size: 12px; -} - .column { align-self: stretch; flex-flow: column; diff --git a/website/src/components/package-api-docs.tsx b/website/src/components/package-api-docs.tsx new file mode 100644 index 00000000000..55775e40361 --- /dev/null +++ b/website/src/components/package-api-docs.tsx @@ -0,0 +1,89 @@ +import { ReactElement } from 'react'; +import { useSSG } from 'nextra/ssg'; +import { components } from 'nextra-theme-docs/theme'; +import Callout from 'nextra-theme-docs/callout'; +import { MDXRemote } from 'next-mdx-remote'; +import { PackageCmd } from './package-cmd'; +import { format } from 'date-fns'; + +export const PackageApiDocs = (): ReactElement => { + // Get the data from SSG, and render it as a component. + const { pluginData } = useSSG(); + + return ; +}; + +export const PackageHeader = ({ + isDev = true, + hasOperationsNote = false, +}: { + isDev?: boolean; + hasOperationsNote?: boolean; +}): ReactElement => { + // Get the data from SSG, and render it as a component. + const { pluginData } = useSSG(); + + return ( + <> +

{pluginData.title}

+

Package Details

+ {/* Unfortunately Nextra doesn't support import `.mdx` files in `.mdx`, so I copied generated code + * and exported as React component + */} +
+ + + + + + + + + + + + + + + + + + + + + + + +
Package + + {pluginData.npmPackage} + +
Weekly Downloads + downloads +
Version + license +
License + license +
Updated{format(new Date(pluginData.stats.modifiedDate), 'MMM do, yyyy')}
+

Installation

+ + {hasOperationsNote && ( + +

+ Usage Requirements +

+

+ In order to use this GraphQL Codegen plugin, please make sure that you have GraphQL operations ( + query / mutation / subscription and fragment) set as{' '} + documents: … in your codegen.yml. +

+

+ Without loading your GraphQL operations (query, mutation,{' '} + subscription and fragment), you won't see any change in the generated output. +

+
+ )} +
+ + ); +}; diff --git a/website/src/components/package-cmd.tsx b/website/src/components/package-cmd.tsx new file mode 100644 index 00000000000..140a71b29b7 --- /dev/null +++ b/website/src/components/package-cmd.tsx @@ -0,0 +1,87 @@ +import { ReactElement, ReactNode } from 'react'; +import { Tabs, Tab } from 'nextra-theme-docs/tabs'; + +const CodeTab = ({ children }: { children: ReactNode }): ReactElement => { + return ( + + {/* Unfortunately Nextra doesn't support import `.mdx` files in `.mdx`, so I copied generated code + * and exported as React component + */} +
+        
+          
+            {children}
+          
+        
+      
+
+ ); +}; + +const PACKAGE_MANAGERS = ['yarn', 'npm', 'pnpm'] as const; + +type PackageMap = Record; + +const Add: PackageMap = { + yarn: 'yarn add', + npm: 'npm install', + pnpm: 'pnpm add', +}; + +const Run: PackageMap = { + yarn: 'yarn', + npm: 'npm run', + pnpm: 'pnpm', +}; + +const Install: PackageMap = { + yarn: 'yarn', + npm: 'npm install', + pnpm: 'pnpm install', +}; + +const Init: PackageMap = { + yarn: 'yarn init --yes', + npm: 'npm init --yes', + pnpm: 'pnpm init', +}; + +type Command = { + name: string; + cmd: 'add' | 'run' | 'install' | 'init'; + isNpx?: boolean; +}; + +export const PackageCmd = ({ packages }: { packages: (string | Command)[] }) => { + const pkgs = packages.map(pkg => + typeof pkg === 'string' + ? ({ + name: pkg, + cmd: 'add', + } as Command) + : pkg + ); + + return ( + + {PACKAGE_MANAGERS.map(pkgManager => ( + + {pkgs + .map(pkg => { + switch (pkg.cmd) { + case 'run': + return `${pkgManager === 'npm' && pkg.isNpx ? 'npx' : Run[pkgManager]} ${pkg.name}`; + case 'install': + return `${Install[pkgManager]}${pkg.name ? ` ${pkg.name}` : ''}`; + case 'init': + return Init[pkgManager]; + default: + return `${Add[pkgManager]} ${pkg.name}`; + } + }) + .join('\n')} + + ))} + + ); +}; diff --git a/website/src/components/plugin-hub.tsx b/website/src/components/plugin-hub.tsx new file mode 100644 index 00000000000..db96477bd1a --- /dev/null +++ b/website/src/components/plugin-hub.tsx @@ -0,0 +1,97 @@ +import { ReactElement, useMemo } from 'react'; +import { useSSG } from 'nextra/ssg'; +import { compareDesc } from 'date-fns'; +import { handlePushRoute } from '@guild-docs/client'; +import { CompiledMDX } from '@guild-docs/server'; +import { PackageWithStats } from '@guild-docs/server/npm'; +import { MarketplaceSearch } from '@theguild/components'; +import { IMarketplaceItemProps } from '@theguild/components/dist/types/components'; +import Markdown from '@/components/ui/Markdown'; +import { ALL_TAGS } from '@/lib/plugins'; +import { CategoryToPackages } from '@/category-to-packages.mjs'; + +type MarketplaceProps = { + data: (PackageWithStats & { + description: CompiledMDX; + content: CompiledMDX; + })[]; +}; + +const categoryEntries = Object.entries(CategoryToPackages); + +export const PluginHub = (): ReactElement => { + const { data } = useSSG() as MarketplaceProps; + + const marketplaceItems: (IMarketplaceItemProps & { raw: PackageWithStats })[] = useMemo( + () => + data.map(plugin => { + const [category] = categoryEntries.find(([, packageNames]) => packageNames.includes(plugin.identifier)) || []; + const linkHref = `/plugin-hub/${category}/${plugin.identifier}`; + return { + raw: plugin, + tags: plugin.tags, + title: plugin.title, + link: { + href: linkHref, + title: `${plugin.title} plugin details`, + onClick: ev => handlePushRoute(linkHref, ev), + }, + description: , + update: plugin.stats?.modifiedDate || new Date().toISOString(), + image: plugin.iconUrl + ? { + height: 60, + width: 60, + src: plugin.iconUrl, + alt: plugin.title, + } + : undefined, + }; + }), + [data] + ); + + const recentlyUpdatedItems = useMemo( + () => [...marketplaceItems].sort((a, b) => compareDesc(new Date(a.update), new Date(b.update))), + [marketplaceItems] + ); + + const trendingItems = useMemo( + () => + marketplaceItems + .filter(i => i.raw.stats?.weeklyNPMDownloads) + .sort((a, b) => { + const aMonthlyDownloads = a.raw.stats?.weeklyNPMDownloads || 0; + const bMonthlyDownloads = b.raw.stats?.weeklyNPMDownloads || 0; + + return bMonthlyDownloads - aMonthlyDownloads; + }), + [marketplaceItems] + ); + + return ( + + ); +}; diff --git a/website/src/components/ui/Markdown.tsx b/website/src/components/ui/Markdown.tsx index 45762ea9b62..416bde9d7d1 100644 --- a/website/src/components/ui/Markdown.tsx +++ b/website/src/components/ui/Markdown.tsx @@ -1,6 +1,5 @@ import type { CompiledMDX } from '@guild-docs/server'; -import type { ComponentProps } from 'react'; -import { FC } from 'react'; +import type { ComponentProps, ReactElement } from 'react'; import { Link } from '@chakra-ui/react'; import { MDX } from '@guild-docs/client'; @@ -20,7 +19,7 @@ const extraComponents = { }, }; -const Markdown: FC<{ content: CompiledMDX }> = ({ content }) => { +const Markdown = ({ content }: { content: CompiledMDX }): ReactElement => { return ; }; diff --git a/website/src/lib/docs-generator.ts b/website/src/lib/docs-generator.ts index 4528651e272..86cfc02f517 100644 --- a/website/src/lib/docs-generator.ts +++ b/website/src/lib/docs-generator.ts @@ -14,7 +14,6 @@ export function generateDocs(schema: TJS.Definition, types: (PluginConfig | Pres content += `${subSchema.description}\n\n`; } - content += ``; if (apiDocs) { content += `### Config API Reference\n\n${apiDocs}`; } @@ -31,7 +30,7 @@ function generateContentForSchema(schema: TJS.Definition): string { const prop = schema.properties![propName] as TJS.Definition; return `
- + ${propName} diff --git a/website/src/lib/get-npm-info.tsx b/website/src/lib/get-npm-info.tsx new file mode 100644 index 00000000000..589237f67e9 --- /dev/null +++ b/website/src/lib/get-npm-info.tsx @@ -0,0 +1,39 @@ +import { getPackagesData } from '@guild-docs/server/npm'; +import { PACKAGES } from './plugins'; +import { transformDocs } from './transform'; +import { compileMdx } from 'nextra/compile'; + +export const getNpmInfo = (packageName: string) => + // Passing packageName for `getStaticProps` of mdx files in plugins directory + async function getStaticProps() { + const [pluginData] = await getPackagesData({ + idSpecific: packageName, + packageList: PACKAGES, + }); + const generatedDocs = transformDocs(); + + const source = + generatedDocs.docs[packageName] || + pluginData.stats?.readme?.replace('ERROR: No README data found!', '').replaceAll('```yml', '```yaml') || + ''; + + const mdx = await compileMdx(source, { + outputFormat: 'function-body', + jsx: false, + }); + + return { + props: { + // We add an `ssg` field to the page props, + // which will be provided to the Nextra `useSSG` hook. + ssg: { + pluginData: { + ...pluginData, + compiledSource: mdx.result, + }, + }, + }, + // The page will be considered as stale and regenerated every 24 hours. + revalidate: 60 * 60 * 24, + }; + }; diff --git a/website/src/lib/plugins.ts b/website/src/lib/plugins.ts index 2e7cfa349d4..2684e2b2b27 100644 --- a/website/src/lib/plugins.ts +++ b/website/src/lib/plugins.ts @@ -1,7 +1,4 @@ import type { Package } from '@guild-docs/server/npm'; -import { existsSync, readFileSync } from 'fs'; -import { transformDocs } from './transform'; -import { canUseDOM } from '../utils'; export const ALL_TAGS = [ 'typescript', @@ -33,51 +30,63 @@ export const ALL_TAGS = [ export type Tags = typeof ALL_TAGS[number]; -let generatedDocs: ReturnType | null = null; -let staticMapping: Record | null = null; - -function loadGeneratedReadme(options: { templateFile: string; pluginIdentifier: string }): string { - if (!generatedDocs) { - generatedDocs = transformDocs(); - } - - if (!staticMapping) { - staticMapping = { - '{@operationsNote}': readFileSync(`docs-templates/client-note.md`, 'utf-8'), - '{@javaInstallation}': readFileSync(`docs-templates/java-installation.md`, 'utf-8'), - }; - } - - let templateBase = '{@apiDocs}'; - - if (existsSync(options.templateFile)) { - templateBase = readFileSync(options.templateFile, 'utf-8'); - } - - let out = templateBase.replace('{@apiDocs}', generatedDocs.docs[options.pluginIdentifier] || ''); - - Object.keys(staticMapping).forEach(key => { - out = out.replace(key, staticMapping![key]); - }); - - return out; -} - -const PACKAGES: Package[] = [ +export const PACKAGES: Package[] = [ { - identifier: 'near-operation-file-preset', - title: 'near-operation-file-preset', - npmPackage: '@graphql-codegen/near-operation-file-preset', + identifier: 'add', + title: 'Add', + npmPackage: '@graphql-codegen/add', + iconUrl: '/assets/img/icons/graphql.svg', + tags: ['plugin'], + }, + { + identifier: 'c-sharp-operations', + title: 'C# Operations', + npmPackage: '@graphql-codegen/c-sharp-operations', + iconUrl: '/assets/img/icons/csharp.svg', + tags: ['plugin', 'csharp'], + }, + { + identifier: 'flow-operations', + title: 'Flow Operations', + npmPackage: '@graphql-codegen/flow-operations', + iconUrl: '/assets/img/icons/flow.svg', + tags: ['plugin', 'flow'], + }, + { + identifier: 'flow-resolvers', + title: 'Flow Resolvers', + npmPackage: '@graphql-codegen/flow-resolvers', + iconUrl: '/assets/img/icons/flow.svg', + tags: ['plugin', 'flow'], + }, + { + identifier: 'fragment-matcher', + title: 'Fragment Matcher', + npmPackage: '@graphql-codegen/fragment-matcher', + iconUrl: '/assets/img/icons/graphql.svg', + tags: ['plugin', 'apollo'], + }, + { + identifier: 'gql-tag-operations-preset', + title: 'gql-tag-operations-preset', + npmPackage: '@graphql-codegen/gql-tag-operations-preset', iconUrl: '/assets/img/icons/codegen.svg', - tags: ['preset', 'utilities'], + tags: ['preset', 'utilities', 'typescript'], }, { identifier: 'graphql-modules-preset', title: 'graphql-modules-preset', npmPackage: '@graphql-codegen/graphql-modules-preset', - iconUrl: 'https://www.graphql-modules.com/img/just-logo.svg', + iconUrl: 'https://graphql-modules.com/img/just-logo.svg', tags: ['preset', 'utilities', 'resolvers'], }, + { + identifier: 'hasura-allow-list', + title: 'Hasura Allow List', + npmPackage: '@graphql-codegen/hasura-allow-list', + iconUrl: '/assets/img/icons/hasura.svg', + tags: ['plugin', 'utilities', 'hasura'], + }, { identifier: 'import-types-preset', title: 'import-types-preset', @@ -86,11 +95,46 @@ const PACKAGES: Package[] = [ tags: ['preset', 'utilities'], }, { - identifier: 'gql-tag-operations-preset', - title: 'gql-tag-operations-preset', - npmPackage: '@graphql-codegen/gql-tag-operations-preset', - iconUrl: '/assets/img/icons/codegen.svg', - tags: ['preset', 'utilities', 'typescript'], + identifier: 'introspection', + title: 'Introspection', + npmPackage: '@graphql-codegen/introspection', + iconUrl: '/assets/img/icons/graphql.svg', + tags: ['plugin', 'utilities'], + }, + { + identifier: 'java', + title: 'Java', + npmPackage: '@graphql-codegen/java', + iconUrl: '/assets/img/icons/java.svg', + tags: ['plugin', 'java'], + }, + { + identifier: 'java-apollo-android', + title: 'Java Apollo Android', + npmPackage: '@graphql-codegen/java-apollo-android', + iconUrl: '/assets/img/icons/java.svg', + tags: ['plugin', 'java', 'apollo', 'android'], + }, + { + identifier: 'java-resolvers', + title: 'Java Resolvers', + npmPackage: '@graphql-codegen/java-resolvers', + iconUrl: '/assets/img/icons/java.svg', + tags: ['plugin', 'java'], + }, + { + identifier: 'jsdoc', + title: 'JSDoc', + npmPackage: '@graphql-codegen/jsdoc', + iconUrl: '/assets/img/icons/graphql.svg', + tags: ['plugin', 'jsdoc'], + }, + { + identifier: 'kotlin', + title: 'Kotlin', + npmPackage: '@graphql-codegen/kotlin', + iconUrl: '/assets/img/icons/java.svg', + tags: ['plugin', 'java', 'kotlin'], }, { identifier: 'named-operations-object', @@ -99,6 +143,41 @@ const PACKAGES: Package[] = [ iconUrl: '/assets/img/icons/typescript.svg', tags: ['plugin', 'typescript'], }, + { + identifier: 'near-operation-file-preset', + title: 'near-operation-file-preset', + npmPackage: '@graphql-codegen/near-operation-file-preset', + iconUrl: '/assets/img/icons/codegen.svg', + tags: ['preset', 'utilities'], + }, + { + identifier: 'reason-client', + title: 'Reason Client', + npmPackage: 'graphql-codegen-reason-client', + iconUrl: 'https://pbs.twimg.com/profile_images/1004185780313395200/ImZxrDWf_400x400.jpg', + tags: ['plugin', 'reason'], + }, + { + identifier: 'relay-operation-optimizer', + title: 'Relay Operation Optimizer', + npmPackage: '@graphql-codegen/relay-operation-optimizer', + iconUrl: '/assets/img/icons/graphql.svg', + tags: ['plugin', 'relay'], + }, + { + identifier: 'schema-ast', + title: 'Schema AST', + npmPackage: '@graphql-codegen/schema-ast', + iconUrl: '/assets/img/icons/graphql.svg', + tags: ['plugin', 'utilities'], + }, + { + identifier: 'time', + title: 'Time', + npmPackage: '@graphql-codegen/time', + iconUrl: '/assets/img/icons/graphql.svg', + tags: ['plugin', 'utilities'], + }, { identifier: 'typed-document-node', title: 'TypedDocumentNode', @@ -106,6 +185,13 @@ const PACKAGES: Package[] = [ iconUrl: '/assets/img/icons/typescript.svg', tags: ['plugin', 'typescript'], }, + { + identifier: 'typescript', + title: 'TypeScript', + npmPackage: '@graphql-codegen/typescript', + iconUrl: '/assets/img/icons/typescript.svg', + tags: ['plugin', 'typescript'], + }, { identifier: 'typescript-apollo-angular', title: 'TypeScript Apollo Angular', @@ -113,13 +199,6 @@ const PACKAGES: Package[] = [ iconUrl: '/assets/img/icons/angular.svg', tags: ['plugin', 'typescript', 'apollo', 'angular'], }, - { - identifier: 'typescript-msw', - title: 'typescript-msw', - npmPackage: '@graphql-codegen/typescript-msw', - iconUrl: 'https://raw.githubusercontent.com/mswjs/msw/HEAD/media/msw-logo.svg', - tags: ['plugin', 'typescript', 'utilities'], - }, { identifier: 'typescript-apollo-client-helpers', title: 'Apollo-Client Helpers', @@ -169,6 +248,13 @@ const PACKAGES: Package[] = [ iconUrl: '/assets/img/icons/mongodb.png', tags: ['plugin', 'typescript', 'mongodb'], }, + { + identifier: 'typescript-msw', + title: 'typescript-msw', + npmPackage: '@graphql-codegen/typescript-msw', + iconUrl: 'https://raw.githubusercontent.com/mswjs/msw/HEAD/media/msw-logo.svg', + tags: ['plugin', 'typescript', 'utilities'], + }, { identifier: 'typescript-oclif', title: 'TypeScript oclif', @@ -183,13 +269,6 @@ const PACKAGES: Package[] = [ iconUrl: '/assets/img/icons/typescript.svg', tags: ['plugin', 'typescript'], }, - { - identifier: 'typescript', - title: 'TypeScript', - npmPackage: '@graphql-codegen/typescript', - iconUrl: '/assets/img/icons/typescript.svg', - tags: ['plugin', 'typescript'], - }, { identifier: 'typescript-react-apollo', title: 'TypeScript React Apollo', @@ -246,6 +325,13 @@ const PACKAGES: Package[] = [ iconUrl: '/assets/img/icons/typescript.svg', tags: ['plugin', 'typescript', 'urql', 'react'], }, + { + identifier: 'typescript-validation-schema', + title: 'TypeScript Validation Schema', + npmPackage: 'graphql-codegen-typescript-validation-schema', + iconUrl: '/assets/img/icons/graphql.svg', + tags: ['plugin', 'validation', 'yup', 'zod', 'typescript'], + }, { identifier: 'typescript-vue-apollo', title: 'TypeScript Vue Apollo Composition API', @@ -267,111 +353,6 @@ const PACKAGES: Package[] = [ iconUrl: '/assets/img/icons/vue.svg', tags: ['plugin', 'typescript', 'vue', 'urql'], }, - { - identifier: 'c-sharp-operations', - title: 'C# Operations', - npmPackage: '@graphql-codegen/c-sharp-operations', - iconUrl: '/assets/img/icons/csharp.svg', - tags: ['plugin', 'csharp'], - }, - { - identifier: 'flow-operations', - title: 'Flow Operations', - npmPackage: '@graphql-codegen/flow-operations', - iconUrl: '/assets/img/icons/flow.svg', - tags: ['plugin', 'flow'], - }, - { - identifier: 'flow-resolvers', - title: 'Flow Resolvers', - npmPackage: '@graphql-codegen/flow-resolvers', - iconUrl: '/assets/img/icons/flow.svg', - tags: ['plugin', 'flow'], - }, - { - identifier: 'java', - title: 'Java', - npmPackage: '@graphql-codegen/java', - iconUrl: '/assets/img/icons/java.svg', - tags: ['plugin', 'java'], - }, - { - identifier: 'java-apollo-android', - title: 'Java Apollo Android', - npmPackage: '@graphql-codegen/java-apollo-android', - iconUrl: '/assets/img/icons/java.svg', - tags: ['plugin', 'java', 'apollo', 'android'], - }, - { - identifier: 'java-resolvers', - title: 'Java Resolvers', - npmPackage: '@graphql-codegen/java-resolvers', - iconUrl: '/assets/img/icons/java.svg', - tags: ['plugin', 'java'], - }, - { - identifier: 'kotlin', - title: 'Kotlin', - npmPackage: '@graphql-codegen/kotlin', - iconUrl: '/assets/img/icons/java.svg', - tags: ['plugin', 'java', 'kotlin'], - }, - { - identifier: 'reason-client', - title: 'Reason Client', - npmPackage: 'graphql-codegen-reason-client', - iconUrl: 'https://pbs.twimg.com/profile_images/1004185780313395200/ImZxrDWf_400x400.jpg', - tags: ['plugin', 'reason'], - }, - { - identifier: 'add', - title: 'Add', - npmPackage: '@graphql-codegen/add', - iconUrl: '/assets/img/icons/graphql.svg', - tags: ['plugin'], - }, - { - identifier: 'fragment-matcher', - title: 'Fragment Matcher', - npmPackage: '@graphql-codegen/fragment-matcher', - iconUrl: '/assets/img/icons/graphql.svg', - tags: ['plugin', 'apollo'], - }, - { - identifier: 'introspection', - title: 'Introspection', - npmPackage: '@graphql-codegen/introspection', - iconUrl: '/assets/img/icons/graphql.svg', - tags: ['plugin', 'utilities'], - }, - { - identifier: 'jsdoc', - title: 'JSDoc', - npmPackage: '@graphql-codegen/jsdoc', - iconUrl: '/assets/img/icons/graphql.svg', - tags: ['plugin', 'jsdoc'], - }, - { - identifier: 'relay-operation-optimizer', - title: 'Relay Operation Optimizer', - npmPackage: '@graphql-codegen/relay-operation-optimizer', - iconUrl: '/assets/img/icons/graphql.svg', - tags: ['plugin', 'relay'], - }, - { - identifier: 'schema-ast', - title: 'Schema AST', - npmPackage: '@graphql-codegen/schema-ast', - iconUrl: '/assets/img/icons/graphql.svg', - tags: ['plugin', 'utilities'], - }, - { - identifier: 'time', - title: 'Time', - npmPackage: '@graphql-codegen/time', - iconUrl: '/assets/img/icons/graphql.svg', - tags: ['plugin', 'utilities'], - }, { identifier: 'urql-introspection', title: 'Urql Introspection for Schema Awareness', @@ -379,28 +360,4 @@ const PACKAGES: Package[] = [ iconUrl: '/assets/img/icons/graphql.svg', tags: ['plugin', 'urql', 'typescript'], }, - { - identifier: 'typescript-validation-schema', - title: 'TypeScript Validation Schema', - npmPackage: 'graphql-codegen-typescript-validation-schema', - iconUrl: '/assets/img/icons/graphql.svg', - tags: ['plugin', 'validation', 'yup', 'zod', 'typescript'], - }, - { - identifier: 'hasura-allow-list', - title: 'Hasura Allow List', - npmPackage: '@graphql-codegen/hasura-allow-list', - iconUrl: '/assets/img/icons/hasura.svg', - tags: ['plugin', 'utilities', 'hasura'], - }, ]; - -export const packageList = PACKAGES.map(p => ({ - ...p, - readme: canUseDOM - ? '' - : loadGeneratedReadme({ - pluginIdentifier: p.identifier, - templateFile: `docs-templates/${p.identifier}.md`, - }), -})); diff --git a/website/src/lib/transform.ts b/website/src/lib/transform.ts index 4e9d2d412b5..f28045befd9 100644 --- a/website/src/lib/transform.ts +++ b/website/src/lib/transform.ts @@ -43,7 +43,7 @@ export function transformDocs() { ); if (!schema.definitions) { - throw new Error(`Config-transform: "schema.definitions" is not defined`); + throw new Error('Config-transform: "schema.definitions" is not defined'); } // This will make sure to add a nice auto complete for all built-in plugins and their configuration mapped diff --git a/website/src/pages/_app.tsx b/website/src/pages/_app.tsx index f8eec953f0b..016548085b4 100644 --- a/website/src/pages/_app.tsx +++ b/website/src/pages/_app.tsx @@ -1,187 +1,29 @@ -import type { FC } from 'react'; -import type { AppProps } from 'next/app'; -import dynamic from 'next/dynamic'; - -import { appWithTranslation } from 'next-i18next'; -import { extendTheme, theme as chakraTheme } from '@chakra-ui/react'; -import { mode } from '@chakra-ui/theme-tools'; -import { - ExtendComponents, - handlePushRoute, - CombinedThemeProvider, - DocsPage, - AppSeoProps, - useGoogleAnalytics, -} from '@guild-docs/client'; -import { Header, Subheader, FooterExtended } from '@theguild/components'; -import 'remark-admonitions/styles/classic.css'; -import '../../public/style.css'; +import { ReactElement } from 'react'; import Script from 'next/script'; -import React from 'react'; -import { Provider as MDXTabsCurrentTabContextProvider } from 'components/MDXTabsCurrentTabContext'; -import { MDXWarning } from 'components/MDXWarning'; +import { AppProps } from 'next/app'; +import { useGoogleAnalytics } from '@guild-docs/client'; +import { Header, FooterExtended, ThemeProvider } from '@theguild/components'; +import 'nextra-theme-docs/style.css'; +import '../../public/style.css'; import '@algolia/autocomplete-theme-classic'; import '@theguild/components/dist/static/css/SearchBarV2.css'; -const MDXTabs = dynamic(() => import('components/MDXTabs/MDXTabs')); -const MDXTab = dynamic(() => import('components/MDXTabs/MDXTab')); - -ExtendComponents({ - HelloWorld() { - return

Hello World!

; - }, - MDXTabs, - MDXTab, - MDXWarning, -}); - -const styles: typeof chakraTheme['styles'] = { - global: props => ({ - body: { - bg: mode('white', 'gray.850')(props), - }, - }), -}; - const accentColor = '#0070f3'; -const theme = extendTheme({ - colors: { - gray: { - 50: '#fafafa', - 100: '#f5f5f5', - 200: '#e5e5e5', - 300: '#5c3a3a', - 400: '#a3a3a3', - 500: '#737373', - 600: '#525252', - 700: '#404040', - 800: '#262626', - 850: '#1b1b1b', - 900: '#171717', - }, - }, - accentColor, - fonts: { - heading: 'TGCFont, sans-serif', - body: 'TGCFont, sans-serif', - }, - config: { - initialColorMode: 'light', - useSystemColorMode: false, - }, - styles, -}); - -const serializedMdx = process.env.SERIALIZED_MDX_ROUTES; -const mdxRoutes = { data: serializedMdx && JSON.parse(serializedMdx) }; - -function AppContent(appProps: AppProps) { - const { Component, pageProps, router } = appProps; - const isDocs = router.asPath.startsWith('/docs'); +export default function App({ Component, pageProps, router }: AppProps): ReactElement { const analytics = useGoogleAnalytics({ router, trackingId: 'G-0SE4YQR4K3' }); + const { getLayout } = Component; + const childComponent = ; return ( - <> + ``` + - - - - + ```tsx const GET_POSTS = gql` query Posts { @@ -213,9 +189,7 @@ interface Post { } } -@Component({ - /* ... */ -}) +@Component({ /* … */ }) class PostsComponent implements OnInit, OnDestroy { posts: Post[] @@ -223,9 +197,7 @@ class PostsComponent implements OnInit, OnDestroy { ngOnInit() { this.querySubscription = this.apollo - .watchQuery({ - query: GET_POSTS - }) + .watchQuery({ query: GET_POSTS }) .valueChanges.subscribe(({ data }) => { this.posts = data.posts as Post[] }) @@ -235,11 +207,9 @@ class PostsComponent implements OnInit, OnDestroy { } } ``` + - - - - + ```svelte
    - +
``` - -
- - + + Manually maintaining the GraphQL operation types or the complete absence of types can lead to many issues: @@ -287,10 +255,8 @@ experience and stability of your stack. After [installing](/docs/getting-started/installation) and [configuring](/docs/config-reference/codegen-config) GraphQL Code Generator, our front-end code will be fully-typed and up-to-date as follows: - - - - + + ```tsx import { useQuery } from 'urql' import { postsQueryDocument } from './graphql/generated' @@ -299,14 +265,12 @@ const Posts = () => { const [result] = useQuery({ query: postsQueryDocument }) // `result` is fully typed! - // ... + // … } ``` + - - - - + ```tsx import { usePosts } from '../graphql/generated' @@ -314,18 +278,16 @@ const Posts = () => { const { data } = usePosts() // `data` is typed! - // ... + // … } ``` + - - - - + ```vue @@ -335,9 +297,7 @@ import { usePostQuery } from '../generated/graphql' export default { apollo: usePostQuery({ // `variables` is properly typed! - variables: { - id: 1 - } + variables: { id: 1 } }), data() { return { @@ -347,20 +307,16 @@ export default { } ``` + - - - - + ```tsx import { PostsGQL, PostsQuery } from './graphql' -//BE SURE TO USE Observable from `rxjs` and not from `@apollo/client/core` when using map +// BE SURE TO USE Observable from `rxjs` and not from `@apollo/client/core` when using map import { Observable } from 'rxjs' import { map } from 'rxjs/operators' -@Component({ - /* ... */ -}) +@Component({ /* … */ }) export class PostsComponent { posts: Observable @@ -369,11 +325,9 @@ export class PostsComponent { } } ``` + - - - - + ```svelte
    - +
``` - -
- -
+ + Now, with simple configuration and an npm/yarn script, a front-end developers benefits from: @@ -399,17 +351,11 @@ Now, with simple configuration and an npm/yarn script, a front-end developers be - **less boilerplate** (thanks to full code generation such as React hooks generation) -
- -> **How does GraphQL Code Generator work?** -> -> More details on the inner working of GraphQL Code Generator are available on [this page](/docs/advanced/how-does-it-work). + +**How does GraphQL Code Generator work?** -

 

- ---- - -

 

+More details on the inner working of GraphQL Code Generator are available on [this page](/docs/advanced/how-does-it-work). +
### To the back-end @@ -419,20 +365,15 @@ Most GraphQL API resolvers remain untyped or wrongly typed which, leads to multi - typos in the resolvers' function type signature -
- For this reason, GraphQL Code Generator provides multiple plugins that help you automate the generation of resolvers' typings. Here are an example of a GraphQL API leveraging GraphQL Code Generator resolvers typings (based on the `schema.graphql` above): - - - - + + ```ts +import { readFileSync } from 'node:fs' import { ApolloServer } from 'apollo-server' -import { readFileSync } from 'fs' - import { Resolvers } from './resolvers-types' const typeDefs = readFileSync('./schema.graphql', 'utf8') @@ -445,20 +386,17 @@ const resolvers: Resolvers = { const server = new ApolloServer({ typeDefs, resolvers }) -// The `listen` method launches a web server. +// The `listen` method launches a web server server.listen().then(({ url }) => { console.log(`🚀 Server ready at ${url}`) }) ``` + - - - - + ```ts +import { readFileSync } from 'node:fs' import { createServer } from '@graphql-yoga/node' -import { readFileSync } from 'fs' - import { Resolvers } from './resolvers-types' const typeDefs = readFileSync('./schema.graphql', 'utf8') @@ -469,18 +407,13 @@ const resolvers: Resolvers = { } } -const server = createServer({ - typeDefs, - resolvers -}) +const server = createServer({ typeDefs, resolvers }) server.start() ``` + - - - - + Given the following structure: ``` @@ -498,20 +431,15 @@ Given the following structure: The User module resolvers would be: -```tsx -// src/modules/user/resolvers.ts +```tsx filename="src/modules/user/resolvers.ts" import { UsersModule } from './generated-types/module-types' export const resolvers: UsersModule.Resolvers = { // Here, you can implement only the types and fields defined in your module! } ``` - - - - - -

 

+ + ## What's next? diff --git a/website/docs/getting-started/installation.mdx b/website/src/pages/docs/getting-started/installation.mdx similarity index 61% rename from website/docs/getting-started/installation.mdx rename to website/src/pages/docs/getting-started/installation.mdx index 27914f18c23..a77c5a5f909 100644 --- a/website/docs/getting-started/installation.mdx +++ b/website/src/pages/docs/getting-started/installation.mdx @@ -1,36 +1,33 @@ ---- -id: installation -title: Installation ---- +import Callout from 'nextra-theme-docs/callout' +import { PackageCmd } from '@/components' + +# Installation ## Installing Codegen Make sure that you add both the `graphql` and `@graphql-codegen/cli` packages in your project's dependencies: - + - - Please avoid installing `graphql`, `@graphql-codegen/cli`, and its plugins as global dependencies. This will cause - issues because of duplications of the `graphql` package. Install it only locally in your project. - +### Global Installation - -If you are using Monorepo setup (Lerna/Yarn Workspaces/anything else), please note that GraphQL Codegen is using `require` to load plugins and files. This might break and fail in case of hoisting. + +Please avoid installing `graphql`, `@graphql-codegen/cli`, and its plugins as global dependencies. This will cause issues because of duplications of the `graphql` package. Install it only locally in your project. -If you are having issues with loading GraphQL-Codegen plugins, make sure it's installed correctly, at the same level of `node_modules`, and make sure it's accessible and available for the Codegen CLI. + - +### Monorepo Project -GraphQL Code Generator comes with dozen plugins, from front-end to back-end, from web apps to mobile apps. -If you are not sure which plugins might be helpful for your GraphQL stack, give a try at the [_Initialization Wizard_](#initialization-wizard). + +If you are using Monorepo setup (Lerna/Yarn Workspaces/anything else), please note that GraphQL Codegen is using `require` to load plugins and files. This might break and fail in case of hoisting. -Otherwise, you can start exploring the [plugins](/plugins) and [setting up them manually](#manual-setup). +If you are having issues with loading GraphQL-Codegen plugins, make sure it's installed correctly, at the same level of `node_modules`, and make sure it's accessible and available for the Codegen CLI. -

 

+
---- +GraphQL Code Generator comes with dozen plugins, from front-end to back-end, from web apps to mobile apps. If you are not sure which plugins might be helpful for your GraphQL stack, give a try at the [_Initialization Wizard_](#initialization-wizard). -

 

+Otherwise, you can start exploring the [plugins](/plugins) and [setting up them manually](#manual-setup). ## Setup @@ -38,23 +35,21 @@ Otherwise, you can start exploring the [plugins](/plugins) and [setting up them Once installed, GraphQL Code Generator CLI can help you configure your project based on some popular flows: - + Question by question, it will guide you through the whole process of setting up a schema, selecting and installing plugins, picking a destination to where your files are generated, and a lot more. -> **npx** -> -> The init process above can also be run through `npx`. - ### Manual Setup Once GraphQL Code Generator is installed and added to your project's development workflow (scripts), you can start installing plugins and configuring them. If you are looking for the **best way to leverage GraphQL Code Generator on your stack**, you should read one of our _Guides_. -On top of each plugin documentation, we provide one Guide for the most famous framework such as [React](/docs/guides/react) or [Apollo Server](/docs/guides/graphql-server-apollo-yoga). -Each guide exposes the best plugins and configurations available for each framework and stack (React with Apollo / URQL / React Query, Angular with Apollo, ...). - -
+On top of each plugin documentation, we provide one Guide for the most famous framework such as [React](/docs/guides/react) or [Apollo Server](/docs/guides/graphql-server-apollo-yoga). Each guide exposes the best plugins and configurations available for each framework and stack (React with Apollo / URQL / React Query, Angular with Apollo, …). Otherwise, if you **prefer exploring plugins and skipping the high-level explanations**, the go-to resource will be the [plugins documentation](/plugins) and the [`codegen.yaml` API reference documentation](/docs/config-reference/codegen-config). diff --git a/website/src/pages/docs/getting-started/meta.json b/website/src/pages/docs/getting-started/meta.json new file mode 100644 index 00000000000..38219be95e3 --- /dev/null +++ b/website/src/pages/docs/getting-started/meta.json @@ -0,0 +1,5 @@ +{ + "index": "Introduction", + "installation": "Installation", + "development-workflow": "Development workflow" +} diff --git a/website/docs/guides/angular.mdx b/website/src/pages/docs/guides/angular.mdx similarity index 77% rename from website/docs/guides/angular.mdx rename to website/src/pages/docs/guides/angular.mdx index 23775311248..5568ce29f84 100644 --- a/website/docs/guides/angular.mdx +++ b/website/src/pages/docs/guides/angular.mdx @@ -1,16 +1,13 @@ ---- -id: angular -title: 'Guide: Angular' -type: Guide ---- +import Callout from 'nextra-theme-docs/callout' +import { PackageCmd } from '@/components' + +# Guide: Angular GraphQL Code Generator provides the `@graphql-codegen/typescript-apollo-angular` plugin that generates full-typed Apollo GraphQL services. Taking the following schema: -```graphql -# schema.graphql - +```graphql filename="schema.graphql" type Author { id: Int! firstName: String! @@ -57,7 +54,7 @@ interface Post { } @Component({ - /* ... */ + /* … */ }) class PostsComponent implements OnInit, OnDestroy { posts: Post[] @@ -89,23 +86,17 @@ Not typing or manually maintaining the data-types can lead to many issues: For this reason, GraphQL Code Generator provides a `@graphql-codegen/typescript-apollo-angular` plugin that generates typed Apollo services for each GraphQL operation. -
- Just a few configuration steps are required to get those Apollo services: -**1. Install the `@graphql-codegen/typescript-apollo-angular` plugin** +### Install - -
- -**2. Configure the plugin** +### Configure the plugin Create or update your `codegen.yaml` file as follows: @@ -120,19 +111,20 @@ generates: - typescript-apollo-angular ``` -> **`schema` and `documents` values** -> -> `schema` needs to be your target GraphQL API URL (`"/graphql"` included). -> -> `documents` is a glob expression to your `.graphql` or `.ts` files. + +**`schema` and `documents` values** + +`schema` needs to be your target GraphQL API URL (`"/graphql"` included). -
+`documents` is a glob expression to your `.graphql` or `.ts` files. -**3. Run the codegen and update your code** +
+ +### Run the codegen and update your code Assuming that, as recommended, your `package.json` has the following script: -```json +```json filename="package.json" { "scripts": { "generate": "graphql-codegen" @@ -140,24 +132,20 @@ Assuming that, as recommended, your `package.json` has the following script: } ``` -
- Running the following generates the `graphql/generated.ts` file. - - -
+ We can now update our code as follows: ```ts import { PostsGQL, PostsQuery } from './graphql' -//BE SURE TO USE Observable from `rxjs` and not from `@apollo/client/core` when using map +// BE SURE TO USE Observable from `rxjs` and not from `@apollo/client/core` when using map import { Observable } from 'rxjs' import { map } from 'rxjs/operators' @Component({ - /* ... */ + /* … */ }) export class PostsComponent { posts: Observable @@ -168,10 +156,6 @@ export class PostsComponent { } ``` -

 

- For more advanced configuration, please refer to the [plugin documentation](/plugins/typescript-apollo-angular). For a different organization of the generated files, please refer to the ["Generated files colocation"](/docs/advanced/generated-files-colocation) page. - -

 

diff --git a/website/docs/guides/front-end-typescript-only.mdx b/website/src/pages/docs/guides/front-end-typescript-only.mdx similarity index 71% rename from website/docs/guides/front-end-typescript-only.mdx rename to website/src/pages/docs/guides/front-end-typescript-only.mdx index 2a27c5d1ce5..a14f0c75cb5 100644 --- a/website/docs/guides/front-end-typescript-only.mdx +++ b/website/src/pages/docs/guides/front-end-typescript-only.mdx @@ -1,8 +1,7 @@ ---- -id: front-end-typescript-only -title: 'Guide: TypeScript-only for front-end' -type: Guide ---- +import Callout from 'nextra-theme-docs/callout' +import { PackageCmd } from '@/components' + +# Guide: TypeScript-only for front-end Even while using another GraphQL Client (not listed in our guides) or willing only to use generated TypeScript types, GraphQL Code Generator still got you covered! @@ -36,13 +35,11 @@ Using `@graphql-codegen/typescript-operations` would generate the TypeScript typ Just a few configuration steps are required to get those TypeScript types generated: -**1. Install the `@graphql-codegen/typescript-operations` plugin** - - +### Install -
+ -**2. Configure the plugin** +### Configure the plugin Create or update your `codegen.yaml` file as follows: @@ -56,19 +53,20 @@ generates: - typescript-operations ``` -> **`schema` and `documents` values** -> -> `schema` needs to be your target GraphQL API URL (`"/graphql"` included). -> -> `documents` is a glob expression to your `.graphql`, `.ts` or `.tsx` files. + +**`schema` and `documents` values** + +`schema` needs to be your target GraphQL API URL (`"/graphql"` included). + +`documents` is a glob expression to your `.graphql`, `.ts` or `.tsx` files. -
+
-**3. Run the codegen and update your code** +### Run the codegen and update your code Assuming that, as recommended, your `package.json` has the following script: -```json +```json filename="package.json" { "scripts": { "generate": "graphql-codegen" @@ -76,13 +74,9 @@ Assuming that, as recommended, your `package.json` has the following script: } ``` -
- Running the following generates the `graphql/generated.tsx` file. - - -
+ We can now use the generated types as follows: @@ -111,6 +105,4 @@ const Posts = () => { } ``` -

 

- -For more information on the `@graphql-codegen/typescript-operations` plugin configuration , please refer to its [documentation](/plugins/typescript-operations). +For more information on the `@graphql-codegen/typescript-operations` plugin configuration, please refer to its [documentation](/plugins/typescript-operations). diff --git a/website/docs/guides/further-reading.mdx b/website/src/pages/docs/guides/further-reading.mdx similarity index 76% rename from website/docs/guides/further-reading.mdx rename to website/src/pages/docs/guides/further-reading.mdx index 54d503355dd..94e8a91a817 100644 --- a/website/docs/guides/further-reading.mdx +++ b/website/src/pages/docs/guides/further-reading.mdx @@ -1,31 +1,25 @@ ---- -id: further-reading -title: Further Reading -type: Guide ---- +# Further Reading GraphQL Code Generator's community has written many articles over the years 🚀. The following articles are also excellent guides covering famous or lesser-known capabilities of GraphQL Code Generator. -
+## TypeScript -### TypeScript - -- [graphql.wtf](https://graphql.wtf/) by [Jamie Barton](https://twitter.com/notrab) is a set of video tutorials around GraphQL. -- [GraphQL Codegen For Effortless GraphQL and Typescript](https://www.youtube.com/watch?v=CtcjrPCwojQ) by [LevelUpTuts](https://leveluptutorials.com/) -- [GraphQL with TypeScript done right](https://the-guild.dev/blog/graphql-with-typescript-done-right) by [Charly Poly](https://charlypoly.com/) +- [graphql.wtf](https://graphql.wtf) by [Jamie Barton](https://twitter.com/notrab) is a set of video tutorials around GraphQL. +- [GraphQL Codegen For Effortless GraphQL and Typescript](https://youtube.com/watch?v=CtcjrPCwojQ) by [LevelUpTuts](https://leveluptutorials.com) +- [GraphQL with TypeScript done right](https://the-guild.dev/blog/graphql-with-typescript-done-right) by [Charly Poly](https://charlypoly.com) - [Best Practices for integrating GraphQL Code Generator in your frontend applications](https://the-guild.dev/blog/graphql-codegen-best-practices) - [Better Type Safety for your GraphQL resolvers with GraphQL Codegen](https://the-guild.dev/blog/better-type-safety-for-resolvers-with-graphql-codegen) - [Game Of Types: A Song Of GraphQL And TypeScript](https://formidable.com/blog/2019/strong-typing) - by Formidable. -### Integrations +## Integrations - [Setup Hasura with GraphQL Code Generator](https://codedaily.io/tutorials/Setup-Hasura-with-GraphQL-Code-Generator) by [Jason Brown](https://twitter.com/browniefed) - [Working with GraphQL Code Generator and GraphCMS](https://graphcms.com/blog/working-with-graphql-code-generator-and-graphcms) by Jamie Barton -- [GraphQL-Modules integration with GraphQL Code Generator](https://www.graphql-modules.com/docs/legacy/recipes/graphql-code-generator/) +- [GraphQL-Modules integration with GraphQL Code Generator](https://graphql-modules.com/docs/legacy/recipes/graphql-code-generator) - [GraphQL Code Generator for WPGraphQL](https://developers.wpengine.com/blog/graphql-code-generator-for-wpgraphql) by Kellen Mace -- [GraphQL Queries in Apollo React](https://dgraph.io/learn/courses/messageboardapp/react/develop/react/graphql-queries/) by DGraph +- [GraphQL Queries in Apollo React](https://dgraph.io/learn/courses/messageboardapp/react/develop/react/graphql-queries) by DGraph - [Using Apollo GraphQL with Angular in an Nx Workspace](https://blog.nrwl.io/using-apollo-graphql-with-angular-in-an-nx-workspace-9ad0155c1914?gi=603641d4b51a) by [Philip Fulcher](https://medium.com/@philipjfulcher?source=post_page-----9ad0155c1914-----------------------------------) -- [Simplify GraphQL requests with React Query, GraphQL Code Generator, and TypeScript](https://blog.logrocket.com/making-graphql-requests-easy-with-react-typescript-and-react-query/) by [Iva Kop](https://blog.logrocket.com/author/ivakop/) +- [Simplify GraphQL requests with React Query, GraphQL Code Generator, and TypeScript](https://blog.logrocket.com/making-graphql-requests-easy-with-react-typescript-and-react-query) by [Iva Kop](https://blog.logrocket.com/author/ivakop) - [Gatsby and GraphQL Code Generator - A Perfect Match](https://talohana.com/blog/gatsby-graphql-code-generator) by [Tal Ohana](https://talohana.com) diff --git a/website/docs/guides/graphql-modules.mdx b/website/src/pages/docs/guides/graphql-modules.mdx similarity index 73% rename from website/docs/guides/graphql-modules.mdx rename to website/src/pages/docs/guides/graphql-modules.mdx index 0b79d5fa038..a479433e950 100644 --- a/website/docs/guides/graphql-modules.mdx +++ b/website/src/pages/docs/guides/graphql-modules.mdx @@ -1,8 +1,6 @@ ---- -id: graphql-modules -title: 'Guide: GraphQL Modules' -type: Guide ---- +import { PackageCmd } from '@/components' + +# Guide: GraphQL Modules GraphQL Code Generator's `@graphql-codegen/graphql-modules-preset` plugin helps to generate resolvers type for each module of a GraphQL Modules GraphQL API. @@ -24,19 +22,15 @@ Given the following GraphQL API structure using GraphQL Modules: Just a few configuration steps are required to get the resolvers types generated: -**1. Install the `@graphql-codegen/graphql-modules-preset` plugin** +### Install - -
- -**2. Configure the plugin** +### Configure the plugin Create or update your `codegen.yaml` file as follows: @@ -55,13 +49,11 @@ generates: - typescript-resolvers ``` -
- -**3. Run the codegen and update your code** +### Run the codegen and update your code Assuming that, as recommended, your `package.json` has the following script: -```json +```json filename="package.json" { "scripts": { "generate": "graphql-codegen" @@ -69,18 +61,13 @@ Assuming that, as recommended, your `package.json` has the following script: } ``` -
- Running the following generates the `graphql/generated.tsx` file. - - -
+ The User module resolvers would be: -```tsx -// src/modules/user/resolvers.ts +```tsx filename="src/modules/user/resolvers.ts" import { UsersModule } from './generated-types/module-types' export const resolvers: UsersModule.Resolvers = { @@ -88,12 +75,6 @@ export const resolvers: UsersModule.Resolvers = { } ``` -

 

- ---- - -

 

- -A complete article, written by Arda Tanrikulu from The Guild, is available on our blog: [Writing a GraphQL TypeScript project w/ GraphQL-Modules and GraphQL-Code-Generator](https://www.the-guild.dev/blog/graphql-typescript-modules-codegen). +A complete article, written by Arda Tanrikulu from The Guild, is available on our blog: [Writing a GraphQL TypeScript project w/ GraphQL-Modules and GraphQL-Code-Generator](https://the-guild.dev/blog/graphql-typescript-modules-codegen). For more advanced configuration (models or context typing), please refer to the [plugin documentation](/plugins/graphql-modules-preset). diff --git a/website/docs/guides/graphql-server-apollo-yoga.mdx b/website/src/pages/docs/guides/graphql-server-apollo-yoga.mdx similarity index 70% rename from website/docs/guides/graphql-server-apollo-yoga.mdx rename to website/src/pages/docs/guides/graphql-server-apollo-yoga.mdx index 9df8e172db7..5a32f6fd855 100644 --- a/website/docs/guides/graphql-server-apollo-yoga.mdx +++ b/website/src/pages/docs/guides/graphql-server-apollo-yoga.mdx @@ -1,38 +1,27 @@ ---- -id: graphql-server-apollo-yoga -title: 'Guide: GraphQL Yoga, Apollo Server' -type: Guide ---- +import Callout from 'nextra-theme-docs/callout' +import { Tabs, Tab } from 'nextra-theme-docs/tabs' +import { PackageCmd } from '@/components' -GraphQL Code Generator's `@graphql-codegen/typescript-resolvers` plugin generates TypeScript types for your GraphQL API's resolvers. - -

 

+# Guide: GraphQL Yoga, Apollo Server' ---- - -

 

+GraphQL Code Generator's `@graphql-codegen/typescript-resolvers` plugin generates TypeScript types for your GraphQL API's resolvers. ## Video tutorial [Episode #26 of `graphql.wtf`](https://graphql.wtf/episodes/26-type-safe-resolvers-with-graphql-code-generator) is a great introduction to `@graphql-codegen/typescript-resolvers`: +/> -> [More weekly episodes are available in `graphql.wtf`](https://graphql.wtf/) by [Jamie Barton](https://twitter.com/notrab). - -

 

- ---- - -

 

+ + [More weekly episodes are available in `graphql.wtf`](https://graphql.wtf) by [Jamie + Barton](https://twitter.com/notrab). + ## Guide @@ -44,19 +33,13 @@ Most GraphQL API resolvers remain untyped or wrongly typed, which leads to multi - typos in the resolvers' function type signature -
- For this reason, GraphQL Code Generator provides `@graphql-codegen/typescript-resolvers` that help automate the generation of resolvers' typings. -
- Just a few configuration steps are required to get the resolvers types generated: **1. Move your GraphQL Schema declaration in dedicated `.graphql` files** -```graphql -#schema.graphql - +```graphql filename="schema.graphql" type Author { id: Int! firstName: String! @@ -77,18 +60,14 @@ type Query { **2. Install the `@graphql-codegen/typescript-resolvers` plugin** - - -
+ **3. Configure the plugin** Create or update your `codegen.yaml` file as follows: - - - - + + ```yaml schema: schema.graphql generates: @@ -99,11 +78,9 @@ generates: - typescript - typescript-resolvers ``` + - - - - + ```yaml schema: schema.graphql generates: @@ -112,18 +89,14 @@ generates: - typescript - typescript-resolvers ``` - - - - - -
+ + **4. Run the codegen and update your code** Assuming that, as recommended, your `package.json` has the following script: -```json +```json filename="package.json" { "scripts": { "generate": "graphql-codegen" @@ -131,24 +104,17 @@ Assuming that, as recommended, your `package.json` has the following script: } ``` -
- Running the following generates the `graphql/generated.tsx` file. - - -
+ We can now write/migrate our GraphQL API implementation as follows: - - - - + + ```ts +import { readFileSync } from 'node:fs' import { ApolloServer } from 'apollo-server' -import { readFileSync } from 'fs' - import { Resolvers } from './resolvers-types' const typeDefs = readFileSync('./schema.graphql', 'utf8') @@ -166,15 +132,12 @@ server.listen().then(({ url }) => { console.log(`🚀 Server ready at ${url}`) }) ``` + - - - - + ```ts +import { readFileSync } from 'node:fs' import { createServer } from '@graphql-yoga/node' -import { readFileSync } from 'fs' - import { Resolvers } from './resolvers-types' const typeDefs = readFileSync('./schema.graphql', 'utf8') @@ -185,24 +148,13 @@ const resolvers: Resolvers = { } } -const server = createServer({ - typeDefs, - resolvers -}) +const server = createServer({ typeDefs, resolvers }) server.start() ``` + + - - - - -

 

- ---- - -

 

- -A complete tutorial, written by The Guild's CTO, Dotan Simha, is available on our blog: [Better Type Safety for your GraphQL resolvers with GraphQL Codegen](https://www.the-guild.dev/blog/better-type-safety-for-resolvers-with-graphql-codegen). +A complete tutorial, written by The Guild's CTO, Dotan Simha, is available on our blog: [Better Type Safety for your GraphQL resolvers with GraphQL Codegen](https://the-guild.dev/blog/better-type-safety-for-resolvers-with-graphql-codegen). For more advanced configuration (models or context typing), please refer to the [plugin documentation](/plugins/typescript-resolvers). diff --git a/website/src/pages/docs/guides/meta.json b/website/src/pages/docs/guides/meta.json new file mode 100644 index 00000000000..1cd4ed1c12e --- /dev/null +++ b/website/src/pages/docs/guides/meta.json @@ -0,0 +1,10 @@ +{ + "react": "React", + "vue": "Vue.js", + "angular": "Angular", + "svelte": "Svelte / Kit", + "front-end-typescript-only": "TypeScript only (front-end)", + "graphql-server-apollo-yoga": "Apollo Server / GraphQL Yoga", + "graphql-modules": "GraphQL Modules", + "further-reading": "Further Reading" +} diff --git a/website/docs/guides/react.mdx b/website/src/pages/docs/guides/react.mdx similarity index 78% rename from website/docs/guides/react.mdx rename to website/src/pages/docs/guides/react.mdx index b6ed370339b..eb12848ee18 100644 --- a/website/docs/guides/react.mdx +++ b/website/src/pages/docs/guides/react.mdx @@ -1,25 +1,19 @@ ---- -id: react -title: 'Guide: React and GraphQL' -type: Guide ---- +import { Tabs, Tab } from 'nextra-theme-docs/tabs' +import Callout from 'nextra-theme-docs/callout' +import { PackageCmd } from '@/components' + +# Guide: React and GraphQL GraphQL Code Generator provides typed code generation for React Query, URQL React, React Apollo Client, and other clients. The plugins and available options vary depending on the target client; for this reason, you find guides for each of them below: -
- - [React Query](#react-query) - [Apollo and URQL](#apollo-and-urql) -

 

- All the following guides query the schema below: -```graphql -# schema.graphql - +```graphql filename="schema.graphql" type Author { id: Int! firstName: String! @@ -38,12 +32,6 @@ type Query { } ``` -

 

- ---- - -

 

- ## React Query Most React Query usage with GraphQL and TypeScript will look as follows: @@ -84,7 +72,7 @@ const Posts = () => { return posts }) - // ... + // … } ``` @@ -98,22 +86,16 @@ Not typing or manually maintaining the data-types can lead to many issues: For this reason, GraphQL Code Generator provides a `@graphql-codegen/typescript-react-query` plugin that generates a typed hook for each GraphQL operation. -
- Just a few configuration steps are required to get those typed hooks generated: **1. Install the `@graphql-codegen/typescript-react-query` plugin** - -
- **2. Configure the plugin** Create or update your `codegen.yaml` file as follows: @@ -131,19 +113,20 @@ generates: fetcher: fetch ``` -> **`schema` and `documents` values** -> -> `schema` needs to be your target GraphQL API URL (`"/graphql"` included). -> -> `documents` is a glob expression to your `.graphql`, `.ts` or `.tsx` files. + +**`schema` and `documents` values** -
+`schema` needs to be your target GraphQL API URL (`"/graphql"` included). + +`documents` is a glob expression to your `.graphql`, `.ts` or `.tsx` files. + +
**3. Run the codegen and update your code** Assuming that, as recommended, your `package.json` has the following script: -```json +```json filename="package.json" { "scripts": { "generate": "graphql-codegen" @@ -151,13 +134,9 @@ Assuming that, as recommended, your `package.json` has the following script: } ``` -
- Running the following will generate the `graphql/generated.tsx` file. - - -
+ We can now update our code as follows: @@ -184,23 +163,14 @@ const Posts = () => { const { data } = usePosts() // `data` is typed! - - // ... + // … } ``` -

 

- For more advanced configuration (custom fetcher, infinite queries), please refer to the [plugin documentation](/plugins/typescript-react-query#using-graphql-request). For a different organization of the generated files, please refer to the ["Generated files colocation"](/docs/advanced/generated-files-colocation) page. -

 

- ---- - -

 

- ## Apollo and URQL ### Optimal configuration for Apollo and URQL @@ -215,10 +185,8 @@ While Apollo and URQL have their GraphQL Code Generator plugins that generate fu Given the following code example: - - - - + + ```tsx import { gql, useQuery } from '@apollo/client' @@ -251,14 +219,12 @@ const postsQueryDocument = gql` const Posts = () => { const { data } = useQuery(postsQueryDocument) - // ... + // … } ``` + - - - - + ```tsx import { useQuery } from 'urql' @@ -291,20 +257,16 @@ const postsQueryDocument = ` const Posts = () => { const [result] = useQuery({ query: postsQueryDocument }) - // ... + // … } ``` - - - - + + installing and configuring the `@graphql-codegen/typed-document-node` plugin would allow the following refactoring: - - - - + + ```tsx import { useQuery } from '@apollo/client' import { postsQueryDocument } from './graphql/generated' @@ -313,14 +275,12 @@ const Posts = () => { const { data } = useQuery(postsQueryDocument) // `result` is fully typed! - // ... + // … } ``` + - - - - + ```tsx import { useQuery } from 'urql' import { postsQueryDocument } from './graphql/generated' @@ -329,13 +289,11 @@ const Posts = () => { const [result] = useQuery({ query: postsQueryDocument }) // `result` is fully typed! - // ... + // … } ``` - - - - + + Just a few configuration steps are required to get those typed document nodes generated: @@ -345,9 +303,7 @@ To have `@graphql-codegen/typed-document-node` working and avoid code duplicatio we highly recommend moving all `gql` document declarations outside of `.tsx`/`.ts` files. For this, create a colocated `.graphql` file for each GraphQL document, as follows: -```graphql -# postsQuery.graphql - +```graphql filename="postsQuery.graphql" # 'Document' will be appended to the name of the query in the generated output query postsQuery { posts { @@ -364,16 +320,10 @@ query postsQuery { **2. Install the `@graphql-codegen/typed-document-node` plugin** - -
- **3. Configure the plugin** Create or update your `codegen.yaml` file as follows: @@ -389,18 +339,19 @@ generates: - typed-document-node ``` -> **`schema` and `documents` values** -> -> `schema` needs to be your target GraphQL API URL (`"/graphql"` included). -> `documents` is a glob expression to your `.graphql` files. + +**`schema` and `documents` values** -
+`schema` needs to be your target GraphQL API URL (`"/graphql"` included). + +`documents` is a glob expression to your `.graphql` files. +
**4. Run the codegen and update your code** Assuming that, as recommended, your `package.json` has the following script: -```json +```json filename="package.json" { "scripts": { "generate": "graphql-codegen" @@ -408,20 +359,14 @@ Assuming that, as recommended, your `package.json` has the following script: } ``` -
- Running the following generates the `graphql/generated.tsx` file. - - -
+ We can now update our code as follows: - - - - + + ```tsx import { useQuery } from '@apollo/client' import { postsQueryDocument } from './graphql/generated' @@ -430,14 +375,12 @@ const Posts = () => { const { data } = useQuery(postsQueryDocument) // `result` is fully typed! - // ... + // … } ``` + - - - - + ```tsx import { useQuery } from 'urql' import { postsQueryDocument } from './graphql/generated' @@ -446,23 +389,15 @@ const Posts = () => { const [result] = useQuery({ query: postsQueryDocument }) // `result` is fully typed! - // ... + // … } ``` - - - - - -

 

+ + For more advanced configuration, please refer to the [plugin documentation](/plugins/typed-document-node). -If you are curious about `@graphql-codegen/typed-document-node` inner workings, feel free to read the following The Guild's CTO blog post: [TypedDocumentNode: the next generation of GraphQL and TypeScript](https://www.the-guild.dev/blog/typed-document-node). - -

 

- -

 

+If you are curious about `@graphql-codegen/typed-document-node` inner workings, feel free to read the following The Guild's CTO blog post: [TypedDocumentNode: the next generation of GraphQL and TypeScript](https://the-guild.dev/blog/typed-document-node). ### Typed hooks for Apollo and URQL @@ -470,10 +405,8 @@ GraphQL Code Generator also proposes two plugins (one for Apollo one for URQL) t Given the following code example: - - - - + + ```tsx import { gql, useQuery } from '@apollo/client' @@ -506,14 +439,12 @@ const postsQueryDocument = gql` const Posts = () => { const { data } = useQuery(postsQueryDocument) - // ... + // … } ``` + - - - - + ```tsx import { useQuery } from 'urql' @@ -529,16 +460,16 @@ interface PostQuery { }[] } -const postsQueryDocument = ` +const postsQueryDocument = /* GraphQL */` query Posts { posts { + id + title + author { id - title - author { - id - firstName - lastName - } + firstName + lastName + } } } ` @@ -546,20 +477,16 @@ const postsQueryDocument = ` const Posts = () => { const [result] = useQuery({ query: postsQueryDocument }) - // ... + // … } ``` - - - - + + installing and configuring the `@graphql-codegen/typescript-react-apollo` or `@graphql-codegen/typescript-urql` plugin would allow the following refactoring: - - - - + + ```tsx import { usePostsQuery } from './graphql/generated' @@ -567,14 +494,12 @@ const Posts = () => { const { data } = usePostsQuery() // `result` is fully typed! - // ... + // … } ``` + - - - - + ```tsx import { usePostsQuery } from './graphql/generated' @@ -582,13 +507,11 @@ const Posts = () => { const [result] = usePostsQuery() // `result` is fully typed! - // ... + // … } ``` - - - - + + Some might prefer this approach to `@graphql-codegen/typed-document-node` since its results in a total abstraction of the query logic and fewer imports. @@ -603,34 +526,22 @@ Just a few configuration steps are required to get those typed hooks generated: For React Apollo: - For URQL React: - -
- **2. Configure the plugin** Create or update your `codegen.yaml` file as follows: - - - - + + ```yaml schema: http://my-graphql-api.com/graphql documents: './src/**/*.tsx' @@ -643,11 +554,9 @@ generates: config: withHooks: true ``` + - - - - + ```yaml schema: http://my-graphql-api.com/graphql documents: './src/**/*.tsx' @@ -660,24 +569,23 @@ generates: config: withHooks: true ``` + + - + +**`schema` and `documents` values** - +`schema` needs to be your target GraphQL API URL (`"/graphql"` included). -> **`schema` and `documents` values** -> -> `schema` needs to be your target GraphQL API URL (`"/graphql"` included). -> -> `documents` is a glob expression to your `.graphql`, `.ts` or `.tsx` files. +`documents` is a glob expression to your `.graphql`, `.ts` or `.tsx` files. -
+ **3. Run the codegen and update your code** Assuming that, as recommended, your `package.json` has the following script: -```json +```json filename="package.json" { "scripts": { "generate": "graphql-codegen" @@ -685,20 +593,14 @@ Assuming that, as recommended, your `package.json` has the following script: } ``` -
- Running the following generates the `graphql/generated.tsx` file. - - -
+ We can now update our code as follows: - - - - + + ```tsx import { usePostsQuery } from './graphql/generated' @@ -706,14 +608,12 @@ const Posts = () => { const { data } = usePostsQuery() // `result` is fully typed! - // ... + // … } ``` + - - - - + ```tsx import { usePostsQuery } from './graphql/generated' @@ -721,21 +621,15 @@ const Posts = () => { const [result] = usePostsQuery() // `result` is fully typed! - // ... + // … } ``` - - - - - -

 

+ + For more advanced configuration, please refer to the plugin documentation: - [`@graphql-codegen/typescript-react-apollo` documentation](/plugins/typescript-react-apollo) - [`@graphql-codegen/typescript-urql` documentation](/plugins/typescript-urql) -
- For a different organization of the generated files, please refer to the ["Generated files colocation"](/docs/advanced/generated-files-colocation) page. diff --git a/website/docs/guides/svelte.mdx b/website/src/pages/docs/guides/svelte.mdx similarity index 83% rename from website/docs/guides/svelte.mdx rename to website/src/pages/docs/guides/svelte.mdx index d97cc07fac4..bc2e04d031f 100644 --- a/website/docs/guides/svelte.mdx +++ b/website/src/pages/docs/guides/svelte.mdx @@ -1,25 +1,18 @@ ---- -id: svelte -title: 'Guide: Svelte / Kit' -type: Guide ---- +import Callout from 'nextra-theme-docs/callout' +import { PackageCmd } from '@/components' + +# Guide: Svelte / Kit GraphQL Code Generator and the community provide typed code generation for Apollo, SvelteKit _native_, and other clients. Plugins and available options vary depending on the selected codegen; for this reason, you will find guides for each of them below: -
- - [Svelte Apollo](#svelte-apollo) - [SvelteKit Native](#sveltekit-native) -

 

- All the following guides query the schema below: -```graphql -# schema.graphql - +```graphql filename="schema.graphql" type Author { id: Int! firstName: String! @@ -38,12 +31,6 @@ type Query { } ``` -

 

- ---- - -

 

- ## Svelte Apollo Thank to the [community-built plugin](https://github.com/ticruz38/graphql-codegen-svelte-apollo#readme) `graphql-codegen-svelte-apollo`, GraphQL Code Generator generates full-typed Apollo GraphQL services for Svelte. @@ -71,7 +58,7 @@ and the following reference script: const posts = query(postsQueryDocument) - + {posts.data} ``` @@ -79,12 +66,10 @@ Just a few configuration steps are required to get observable Apollo queries wit **1. Install the `graphql-codegen-svelte-apollo` plugin** - -
- **2. Configure the plugin** Create or update your `codegen.yaml` file as follows: @@ -100,22 +85,23 @@ generates: - graphql-codegen-svelte-apollo ``` -> **`schema` and `documents` values** -> -> `schema` can be: -> -> - your target GraphQL API URL (`"/graphql"` included) -> - your SDL file. (eg: `./src/schema.graphql`) -> -> `documents` is a glob expression to your `.graphql`, `.gql` files. + +**`schema` and `documents` values** + +`schema` can be: -
+- your target GraphQL API URL (`"/graphql"` included) +- your SDL file. (eg: `./src/schema.graphql`) + +`documents` is a glob expression to your `.graphql`, `.gql` files. + +
**3. Run the codegen and update your code** Assuming that, as recommended, your `package.json` has the following script: -```json +```json filename="package.json" { "scripts": { "generate": "graphql-codegen" @@ -123,13 +109,9 @@ Assuming that, as recommended, your `package.json` has the following script: } ``` -
- Running the following generates the `graphql/generated.ts` file. - - -
+ We can now update our code as follows: @@ -141,22 +123,14 @@ We can now update our code as follows: // `posts` is fully typed! - + {$posts.data} ``` -

 

- For more advanced configuration (ex: async queries), please refer to the [plugin documentation](/plugins/typescript-svelte-apollo) and the [GitHub repository README](https://github.com/ticruz38/graphql-codegen-svelte-apollo). For a different organization of the generated files, please refer to the ["Generated files colocation"](/docs/advanced/generated-files-colocation) page. -

 

- ---- - -

 

- ## SvelteKit Native ![logoKitQL](https://raw.githubusercontent.com/jycouet/kitql/main/logo.svg) @@ -167,9 +141,7 @@ Just a few configuration steps are required to get SvelteKit stores fully typed **1. Install the plugin** - - -
+ **2. Configure the plugin** @@ -187,13 +159,11 @@ generates: - '@kitql/graphql-codegen' ``` -
- **3. Run the codegen and update your code** Assuming that, as recommended, your `package.json` has the following script: -```json +```json filename="package.json" { "scripts": { "generate": "graphql-codegen" @@ -201,13 +171,9 @@ Assuming that, as recommended, your `package.json` has the following script: } ``` -
- Running the following generates the `graphql/generated.ts` file. - - -
+ We can now update our code as follows: @@ -222,14 +188,10 @@ We can now update our code as follows: } - + {$PostsQueryStore.data} ``` -

 

- For more advanced configuration, please refer to the [KitQL documentation](https://github.com/jycouet/kitql/tree/main/packages/graphql-codegen). For a different organization of the generated files, please refer to the ["Generated files colocation"](/docs/advanced/generated-files-colocation) page. - -

 

diff --git a/website/docs/guides/vue.mdx b/website/src/pages/docs/guides/vue.mdx similarity index 82% rename from website/docs/guides/vue.mdx rename to website/src/pages/docs/guides/vue.mdx index 8553aa62a2a..299e59c1c48 100644 --- a/website/docs/guides/vue.mdx +++ b/website/src/pages/docs/guides/vue.mdx @@ -1,25 +1,18 @@ ---- -id: vue -title: 'Guide: Vue.js' -type: Guide ---- +import Callout from 'nextra-theme-docs/callout' +import { PackageCmd } from '@/components' + +# Guide: Vue.js GraphQL Code Generator provides typed code generation for URQL Vue.js and Apollo Vue.js. The plugins and available options vary depending on the target client; for this reason, you will find guides for each of them below: -
- - [URQL Vue.js](#vuejs-urql) - [Apollo Vue.js](#vuejs-apollo) -

 

- All the following guides query the schema below: -```graphql -# schema.graphql - +```graphql filename="schema.graphql" type Author { id: Int! firstName: String! @@ -38,12 +31,6 @@ type Query { } ``` -

 

- ---- - -

 

- ## Vue.js URQL Most Vue.js URQL usage with TypeScript will look as follows: @@ -51,7 +38,7 @@ Most Vue.js URQL usage with TypeScript will look as follows: ```vue @@ -107,16 +94,12 @@ For this reason, GraphQL Code Generator is providing a `@graphql-codegen/typescr **1. Install the `@graphql-codegen/typescript-vue-urql` plugin** - -
- **2. Configure the plugin** Create or update your `codegen.yaml` file as follows: @@ -132,19 +115,20 @@ generates: - typescript-vue-urql ``` -> **`schema` and `documents` values** -> -> `schema` needs to be your target GraphQL API URL (`"/graphql"` included). -> -> `documents` is a glob expression to your `.graphql`, `.ts` or `.tsx` files. + +**`schema` and `documents` values** + +`schema` needs to be your target GraphQL API URL (`"/graphql"` included). -
+`documents` is a glob expression to your `.graphql`, `.ts` or `.tsx` files. + +
**3. Run the codegen and update your code** Assuming that, as recommended, your `package.json` has the following script: -```json +```json filename="package.json" { "scripts": { "generate": "graphql-codegen" @@ -152,20 +136,16 @@ Assuming that, as recommended, your `package.json` has the following script: } ``` -
- Running the following generates the `graphql/generated.tsx` file. - - -
+ We can now update our code as follows: ```vue @@ -188,18 +168,10 @@ export default { ``` -

 

- For more advanced configuration, please refer to the [plugin documentation](/plugins/typescript-vue-urql). For a different organization of the generated files, please refer to the ["Generated files colocation"](/docs/advanced/generated-files-colocation) page. -

 

- ---- - -

 

- ## Vue.js Apollo Most Vue.js Apollo usage with TypeScript will look as follows: @@ -207,7 +179,7 @@ Most Vue.js Apollo usage with TypeScript will look as follows: ```vue @@ -262,16 +234,12 @@ For this reason, GraphQL Code Generator is providing a `@graphql-codegen/typescr **1. Install the `@graphql-codegen/typescript-vue-apollo-smart-ops` plugin** - -
- **2. Configure the plugin** Create or update your `codegen.yaml` file as follows: @@ -287,19 +255,20 @@ generates: - typescript-vue-apollo-smart-ops ``` -> **`schema` and `documents` values** -> -> `schema` needs to be your target GraphQL API URL (`"/graphql"` included). -> -> `documents` is a glob expression to your `.graphql`, `.ts` or `.tsx` files. + +**`schema` and `documents` values** -
+`schema` needs to be your target GraphQL API URL (`"/graphql"` included). + +`documents` is a glob expression to your `.graphql`, `.ts` or `.tsx` files. + +
**3. Run the codegen and update your code** Assuming that, as recommended, your `package.json` has the following script: -```json +```json filename="package.json" { "scripts": { "generate": "graphql-codegen" @@ -307,20 +276,16 @@ Assuming that, as recommended, your `package.json` has the following script: } ``` -
- Running the following generates the `graphql/generated.tsx` file. - - -
+ We can now update our code as follows: ```vue @@ -343,8 +308,6 @@ export default { ``` -

 

- For more advanced configuration, please refer to the [plugin documentation](/plugins/typescript-vue-apollo-smart-ops). For a different organization of the generated files, please refer to the ["Generated files colocation"](/docs/advanced/generated-files-colocation) page. diff --git a/website/docs/integrations/apollo-local-state.mdx b/website/src/pages/docs/integrations/apollo-local-state.mdx similarity index 95% rename from website/docs/integrations/apollo-local-state.mdx rename to website/src/pages/docs/integrations/apollo-local-state.mdx index 37e5b846c48..4404e2fba60 100644 --- a/website/docs/integrations/apollo-local-state.mdx +++ b/website/src/pages/docs/integrations/apollo-local-state.mdx @@ -1,7 +1,4 @@ ---- -id: apollo-local-state -title: Apollo Local State ---- +# Apollo Local State Suppose you are using [apollo-client](https://apollographql.com/docs/react/v2/data/local-state) >2.5 (or older, with [apollo-link-state](https://apollographql.com/docs/link/links/state.html)) to manage your app state with GraphQL. In that case, you're probably using a client-side only GraphQL schema and client-side directives such as `@client`. @@ -23,7 +20,7 @@ query myQuery { If you wish to get better integration and fully type-safe types for your client-side schema as well, you can create a `.graphql` file for your local schema, for example: -```gql +```graphql type Todo { selected: Boolean! } diff --git a/website/docs/integrations/create-react-app.mdx b/website/src/pages/docs/integrations/create-react-app.mdx similarity index 87% rename from website/docs/integrations/create-react-app.mdx rename to website/src/pages/docs/integrations/create-react-app.mdx index a600cc068f1..737af671d49 100644 --- a/website/docs/integrations/create-react-app.mdx +++ b/website/src/pages/docs/integrations/create-react-app.mdx @@ -1,7 +1,4 @@ ---- -id: create-react-app -title: Create-React-App ---- +# Create-React-App Since v2 of [Create-React-App](https://github.com/facebook/create-react-app), you can use TypeScript without the need to eject from the basic scripts packages. diff --git a/website/docs/integrations/federation.mdx b/website/src/pages/docs/integrations/federation.mdx similarity index 89% rename from website/docs/integrations/federation.mdx rename to website/src/pages/docs/integrations/federation.mdx index 7ae222bc463..ea12f29bb2f 100644 --- a/website/docs/integrations/federation.mdx +++ b/website/src/pages/docs/integrations/federation.mdx @@ -1,13 +1,10 @@ ---- -id: federation -title: Apollo Federation ---- +# Apollo Federation The `typescript-resolvers` plugin also supports [Apollo Federation](https://apollographql.com/docs/apollo-server/federation/introduction). To use it, add `federation: true` to your configuration: -```yaml +```yaml {6-7} generates: ./src/types.ts: plugins: diff --git a/website/src/pages/docs/integrations/gatsby.mdx b/website/src/pages/docs/integrations/gatsby.mdx new file mode 100644 index 00000000000..3c45a3a8aa4 --- /dev/null +++ b/website/src/pages/docs/integrations/gatsby.mdx @@ -0,0 +1,13 @@ +import Callout from 'nextra-theme-docs/callout' + +# Gatsby + +If you build apps using [Gatsby](https://gatsbyjs.com), you can use its built-in feature called [GraphQL Typegen](https://gatsbyjs.com/docs/how-to/local-development/graphql-typegen). Under the hood it uses the GraphQL Code Generator to generate TypeScript types but you don't need to set anything up other than enabling an option. + +It also sets up everything needed for [GraphQL Config](https://graphql-config.com). + +## Community Plugins + +Gatsby's GraphQL Typegen feature is solving most common use cases. If you find yourself limited by its features you should open a feature request or trying using one of these community plugins: + +- [gatsby-plugin-typegen](https://github.com/cometkim/gatsby-plugin-typegen) diff --git a/website/src/pages/docs/integrations/meta.json b/website/src/pages/docs/integrations/meta.json new file mode 100644 index 00000000000..e7fbbbe8aa5 --- /dev/null +++ b/website/src/pages/docs/integrations/meta.json @@ -0,0 +1,8 @@ +{ + "vscode": "VSCode Extension", + "prettier": "Prettier & Linters", + "federation": "Apollo Federation", + "apollo-local-state": "apollo-local-state", + "create-react-app": "create-react-app", + "gatsby": "Gatsby" +} diff --git a/website/docs/integrations/prettier.mdx b/website/src/pages/docs/integrations/prettier.mdx similarity index 96% rename from website/docs/integrations/prettier.mdx rename to website/src/pages/docs/integrations/prettier.mdx index 19c0d3d7cb1..bd9d5a623e4 100644 --- a/website/docs/integrations/prettier.mdx +++ b/website/src/pages/docs/integrations/prettier.mdx @@ -1,7 +1,4 @@ ---- -id: prettier -title: Prettier & Linters ---- +# Prettier & Linters The codegen supports lifecycle hooks, and you can use those for integration with Prettier or other linters, to apply your custom code style and formatting rules. diff --git a/website/docs/integrations/vscode.mdx b/website/src/pages/docs/integrations/vscode.mdx similarity index 92% rename from website/docs/integrations/vscode.mdx rename to website/src/pages/docs/integrations/vscode.mdx index 41a60a458dd..47de00c06fc 100644 --- a/website/docs/integrations/vscode.mdx +++ b/website/src/pages/docs/integrations/vscode.mdx @@ -1,7 +1,4 @@ ---- -id: vscode -title: VSCode ---- +# VSCode In VSCode, you can install a lightweight extension to get your codegen on every save effortlessly. diff --git a/website/src/pages/docs/meta.json b/website/src/pages/docs/meta.json new file mode 100644 index 00000000000..35c1ed7de7c --- /dev/null +++ b/website/src/pages/docs/meta.json @@ -0,0 +1,9 @@ +{ + "getting-started": "Getting Started", + "guides": "Guides", + "config-reference": "Config Reference", + "advanced": "Advanced Usage", + "integrations": "Integrations", + "custom-codegen": "Writing Plugins", + "migration": "Migration Guides" +} diff --git a/website/docs/migration/from-0-13.mdx b/website/src/pages/docs/migration/from-0-13.mdx similarity index 57% rename from website/docs/migration/from-0-13.mdx rename to website/src/pages/docs/migration/from-0-13.mdx index 2e2dea9b07f..8725874e305 100644 --- a/website/docs/migration/from-0-13.mdx +++ b/website/src/pages/docs/migration/from-0-13.mdx @@ -1,33 +1,30 @@ ---- -id: from-0-13 -title: Migration from 0.13 to 0.18 ---- +import Callout from 'nextra-theme-docs/callout' -_March 1st, 2019_ +# Migration from 0.13 to 0.18 ## What has changed? In >= 0.14 we changed the way you pass configuration to GraphQL Code Generator. -In the previous versions of the code-generator, the configuration was confusing and passed through 3 ways: CLI flags, config file (`gql-gen.json` and environment variables. +In the previous versions of the code-generator, the configuration was confusing and passed through 3 ways: CLI flags, config file `gql-gen.json` and environment variables. -It became very confusing and difficult to use, so we decided to merge all existing configurations into a single .yml file - `codegen.yml`. +It became very confusing and difficult to use, so we decided to merge all existing configurations into a single `.yml` file – `codegen.yml`. ## How to migrate? To migrate from GraphQL Code Generator v0.13 API to >=0.14, just start by installing the latest version of `graphql-code-generator` from NPM. -Then, run your existing `gql-gen ...` command as is. You'll see a warning about your current usage. +Then, run your existing `gql-gen …` command as is. You'll see a warning about your current usage. -The new CLI makes it much easier - it will show you how your `codegen.yml` file should look according to your usage with the old API: +The new CLI makes it much easier – it will show you how your `codegen.yml` file should look according to your usage with the old API: -![CLI Migration](/img/v13-migration-cli.gif) +![CLI Migration](/assets/img/v13-migration-cli.gif) Now, create a file called `codegen.yml` with the content that the codegen suggests for you. Next, update your NPM scripts to run `graphql-codegen` only, without any cli-flags: -```json +```json filename="package.json" { "name": "my-project", "scripts": { @@ -40,4 +37,8 @@ Now, replace your deprecated `templates` packages with the new `plugins` package For example, if you were using `graphql-codegen-typescript-template`, you should replace it with: `graphql-codegen-typescript`, and `graphql-codegen-typescript-operations`. -Note sure which new packages you need to use now? [You can take a look here](https://github.com/dotansimha/graphql-code-generator/tree/master/packages/old-templates). Under each directory you'll find a `package.json` pointing to the new packages names. + + Note sure which new packages you need to use now? [You can take a look + here](https://github.com/dotansimha/graphql-code-generator/tree/master/packages/old-templates). Under each directory + you'll find a `package.json` pointing to the new packages names. + diff --git a/website/docs/migration/from-0-18.mdx b/website/src/pages/docs/migration/from-0-18.mdx similarity index 73% rename from website/docs/migration/from-0-18.mdx rename to website/src/pages/docs/migration/from-0-18.mdx index 2e50ca05870..62b1b8f480e 100644 --- a/website/docs/migration/from-0-18.mdx +++ b/website/src/pages/docs/migration/from-0-18.mdx @@ -1,25 +1,24 @@ ---- -id: from-0-18 -title: Migration to 1.0.0 ---- +import Callout from 'nextra-theme-docs/callout' +import { Tabs, Tab } from 'nextra-theme-docs/tabs' +import { PackageCmd } from '@/components' -_March 20th, 2019_ +# Migration to 1.0.0 ## What has changed? Our goals (and achievements) for 1.0.0 release was: -- Rename all package from `graphql-codegen-...` to scoped packages `@graphql-codegen/...`. -- Stabilize the core package and the YML configuration file. -- Remove the old, deprecated code from this repository (everything related to `flattenDocuments` and `buildSchemaContext`). -- Separate the CLI package from the core package, and create an easy-to-use and easy-to-consume core package. -- Add better support for running the codegen in non-node environments, by clearing unused dependencies and add support for tree shaking. -- Remove the dependency for Handlebars from this repository. -- Introduce a new, easy-to-use common base for plugins, based on `Visitor` pattern, that uses `visit` from `graphql` package. -- Better unit tests for all plugins packages, by use TypeScript compiler to compile each test result- makes it much easier to detect mismatches and invalid output. -- Refactor the entire TypeScript plugin, and create better and optimized output. -- Fix most of the GitHub issues. -- Update website and documentation for all plugins. +- Rename all package from `graphql-codegen-…` to scoped packages `@graphql-codegen/…` +- Stabilize the core package and the YML configuration file +- Remove the old, deprecated code from this repository (everything related to `flattenDocuments` and `buildSchemaContext`) +- Separate the CLI package from the core package, and create an easy-to-use and easy-to-consume core package +- Add better support for running the codegen in non-node environments, by clearing unused dependencies and add support for tree shaking +- Remove the dependency for Handlebars from this repository +- Introduce a new, easy-to-use common base for plugins, based on `Visitor` pattern, that uses `visit` from `graphql` package +- Better unit tests for all plugins packages, by use TypeScript compiler to compile each test result- makes it much easier to detect mismatches and invalid output +- Refactor the entire TypeScript plugin, and create better and optimized output +- Fix most of the GitHub issues +- Update website and documentation for all plugins ### New TypeScript Libraries @@ -35,13 +34,13 @@ The reason for this change is the fact that now `typescript-operations` uses `Pi First, the new packages have a different name, that means that you need to manually update those packages names, and not just it's version. -The `graphql-code-generator` package is now `@graphql-codegen/cli` and all other packages has been changes from `graphql-codegen-...` to `@graphql-codegen/...`. +The `graphql-code-generator` package is now `@graphql-codegen/cli` and all other packages has been changes from `graphql-codegen-…` to `@graphql-codegen/…`. So start by updating your `package.json`: -**Before:** - -```json + + +```json filename="package.json" { "devDependencies": { "graphql-code-generator": "0.18.0", @@ -51,10 +50,10 @@ So start by updating your `package.json`: } } ``` + -**After:** - -```json + +```json filename="package.json" { "devDependencies": { "@graphql-codegen/cli": "^1.0.0", @@ -63,11 +62,13 @@ So start by updating your `package.json`: } } ``` + + Also, make sure to update your YML config file: -**Before**: - + + ```yaml ./my-file.ts: schema: schema.json @@ -75,20 +76,22 @@ Also, make sure to update your YML config file: - typescript-common - typescript-server ``` + -**After:** - + ```yaml ./my-file.ts: schema: schema.json plugins: - typescript ``` + + And for client-side: -**Before**: - + + ```yaml ./my-file.ts: schema: schema.json @@ -96,9 +99,9 @@ And for client-side: - typescript-common - typescript-client ``` + -**After:** - + ```yaml ./my-file.ts: schema: schema.json @@ -106,6 +109,8 @@ And for client-side: - typescript - typescript-operations ``` + + ## Breaking Changes & Semver @@ -113,16 +118,14 @@ We tried to avoid breaking changes, but it's not always possible. We had a lot o It was very hard for us to track breaking changes in the past, but it it's easier for us, and we promise to be semver-compatible. -You can find a list of all breaking changes in [GitHub Releases page](https://github.com/dotansimha/graphql-code-generator/releases/). +You can find a list of all breaking changes in [GitHub Releases page](https://github.com/dotansimha/graphql-code-generator/releases). We also created a new plugin, called `typescript-compatibility` that generates backward compatibility for the `typescript-operations` and `typescript-react-apollo` plugins. It will generates for you types that are pointing to the new form of types. It supports _most_ of the use-cases. To use it, start by installing from NPM: -```sh -yarn add -D @graphql-codegen/typescript-compatibility -``` + Then, add it to your codegen configuration: @@ -135,4 +138,7 @@ Then, add it to your codegen configuration: - typescript-compatibility ``` -> Note: If `typescript-react-apollo` plugin also specified in your config file, it will generate backward-compatibility for it. + + If `typescript-react-apollo` plugin also specified in your config file, it will generate backward-compatibility for + it. + diff --git a/website/src/pages/docs/migration/meta.json b/website/src/pages/docs/migration/meta.json new file mode 100644 index 00000000000..c2dcc27deca --- /dev/null +++ b/website/src/pages/docs/migration/meta.json @@ -0,0 +1,4 @@ +{ + "from-0-18": "v0.18 -> v1.0", + "from-0-13": "v0.13 -> v0.17" +} diff --git a/website/src/pages/index.mdx b/website/src/pages/index.mdx new file mode 100644 index 00000000000..1efb31e020c --- /dev/null +++ b/website/src/pages/index.mdx @@ -0,0 +1,42 @@ +import { HeroGradient, HeroIllustration } from '@theguild/components' +import { NPMBadge } from '@guild-docs/client' +import dynamic from 'next/dynamic' + +export const LiveDemo = dynamic(() => import('@/components/live-demo/LiveDemo')) + +} + colors={['#1dbbff', '#ee1cd9']} + image={{ + src: '/assets/illustrations/gql-codegen-cover.svg', + alt: 'Illustration' + }} +/> + + + + + + diff --git a/website/src/pages/index.tsx b/website/src/pages/index.tsx deleted file mode 100644 index 6a6c4e3abb8..00000000000 --- a/website/src/pages/index.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import { FC } from 'react'; -import dynamic from 'next/dynamic'; -import { FeatureList, HeroGradient, HeroIllustration } from '@theguild/components'; -import { handlePushRoute, NPMBadge } from '@guild-docs/client'; -import tw from 'twin.macro'; - -const LiveDemo = dynamic(() => import('../components/live-demo/LiveDemo'), { ssr: false }); - -const IndexPage: FC = () => { - return ( - <> - handlePushRoute('/docs/getting-started', e), - }} - version={} - colors={['#1dbbff', '#ee1cd9']} - image={{ - className: 'no-right', - src: '/assets/illustrations/gql-codegen-cover.svg', - alt: 'Illustration', - }} - wrapperProps={{ - style: { marginTop: 12 }, - }} - /> - -
- -
- - - - - - ); -}; - -export default IndexPage; diff --git a/website/src/pages/meta.json b/website/src/pages/meta.json new file mode 100644 index 00000000000..1dbb3cac5c2 --- /dev/null +++ b/website/src/pages/meta.json @@ -0,0 +1,29 @@ +{ + "index": { + "title": "Home", + "type": "page", + "theme": { + "layout": "raw" + } + }, + "docs": { + "title": "Docs", + "type": "page", + "theme": { + "toc": true + } + }, + "plugin-hub": { + "title": "Plugin Hub", + "type": "page", + "theme": { + "toc": false + } + }, + "contact-us-link": { + "title": "Contact Us", + "href": "https://the-guild.dev/contact", + "type": "page", + "newWindow": true + } +} diff --git a/website/src/pages/plugin-hub/[name].tsx.old b/website/src/pages/plugin-hub/[name].tsx.old new file mode 100644 index 00000000000..abbab4709ed --- /dev/null +++ b/website/src/pages/plugin-hub/[name].tsx.old @@ -0,0 +1,225 @@ +import { ReactElement } from 'react'; +import { GetStaticPaths, GetStaticProps } from 'next'; +import Head from 'next/head'; +import { getPackagesData, PackageInfo, PackageWithStats } from '@guild-docs/server/npm'; +import { compileMdx } from 'nextra/compile'; +import { MDXRemote } from 'next-mdx-remote'; +import { components } from 'nextra-theme-docs/theme'; +import createLayout from 'nextra-theme-docs'; +import themeConfig from '../../../theme.config'; +import { PACKAGES } from '@/lib/plugins'; +import { PackageCmd } from '@/components'; + +interface PluginPageProps { + data: (PackageWithStats & { compiledSource: string })[]; +} + +type PluginPageParams = { + name: string; +}; + +export const getStaticProps: GetStaticProps = async ctx => { + const pluginName = ctx.params?.name; + + const pluginsData = + typeof pluginName === 'string' + ? await getPackagesData({ + idSpecific: pluginName, + packageList: PACKAGES, + }) + .catch(err => { + console.log(err) + throw err + }) + : []; + + const data = await Promise.all( + pluginsData.map(async plugin => { + const source = plugin.readme || plugin.stats?.readme || ''; + const mdx = await compileMdx(source, { + outputFormat: 'function-body', + jsx: false, + }); + + const compiledSource = mdx.result; + + return { + ...plugin, + compiledSource, + }; + }) + ); + + return { + props: { + data, + }, + // Revalidate at most once every 1 hour + revalidate: 60 * 60, + }; +}; + +export const getStaticPaths: GetStaticPaths = async () => { + const plugins = await getPackagesData({ packageList: PACKAGES }); + + return { + fallback: 'blocking', + paths: plugins.map(({ identifier }) => ({ + params: { + name: identifier, + }, + })), + }; +}; + +const NextraLayout = createLayout( + { + filename: '[name].tsx', + route: '/plugins/[name]', + meta: {}, + pageMap: [ + { + name: 'plugins', + children: PACKAGES.map(pkg => ({ + name: pkg.identifier, + route: `/plugins/${pkg.identifier}`, + })), + // [ + // { + // name: '[name]', + // route: '/plugins/[name]' + // } + // ], + }, + ], + titleText: undefined, + headings: [], + hasH1: false, + timestamp: null, + }, + themeConfig +); + +const PluginPage = ({ data }: PluginPageProps): ReactElement => { + const pluginData = data[0]; + + if (!pluginData) { + return ( +
+

404

+
Plugin not found.
+
+ ); + } + + const description = pluginData.stats?.description ? pluginData.stats.description : null; + const title = `${pluginData.title} | GraphQL Codegen Plugin Hub`; + const repoInfo = extractRepositoryInformation(pluginData.stats); + + return ( + + + {title} + + + {description && ( + <> + + + + + )} + +
+

{pluginData.title}

+

Install

+ + +
+ {/*
*/} + {/*

Package Details

*/} + {/*
*/} + {/*
Package
*/} + {/* */} + {/* {pluginData.stats?.license ? (*/} + {/* <>*/} + {/*
License
*/} + {/*
*/} + {/* {pluginData.stats.license}*/} + {/*
*/} + {/* */} + {/* ) : null}*/} + {/* {pluginData.stats?.version ? (*/} + {/* <>*/} + {/*
Version
*/} + {/*
*/} + {/* {pluginData.stats.version}*/} + {/*
*/} + {/* */} + {/* ) : null}*/} + {/* {pluginData.stats?.modifiedDate ? (*/} + {/* <>*/} + {/*
Updated
*/} + {/*
*/} + {/* {format(new Date(pluginData.stats.modifiedDate), 'MMM do, yyyy')}*/} + {/*
*/} + {/* */} + {/* ) : null}*/} + {/* {pluginData.stats?.weeklyNPMDownloads ? (*/} + {/* <>*/} + {/*
Weekly Downloads
*/} + {/*
*/} + {/* {pluginData.stats?.weeklyNPMDownloads}*/} + {/*
*/} + {/* */} + {/* ) : null}*/} + {/* {repoInfo ? (*/} + {/* */} + {/* ) : null}*/} + {/*
*/} + + ); +}; + +/** + * TODO: document how people can configure their yoga plugin package.json so it properly processed. + */ +function extractRepositoryInformation(stats?: PackageInfo | null) { + if ( + stats?.repository == null || + typeof stats.repository !== 'object' || + !stats.repository.directory || + !stats.repository.url + ) { + return null; + } + + const parseRepoURLRegex = /git\+https:\/\/github\.com\/([A-Za-z0-9-]+\/[A-Za-z0-9-]+)\.git/; + const result = stats.repository.url.match(parseRepoURLRegex); + + if (result === null) { + return null; + } + + return { + repo: result[1], + baseDir: stats.repository.directory, + /** TODO: this should probably be more flexible. */ + sourceFilePath: '', + /** TODO: this should probably be more flexible. */ + branch: 'master', + }; +} + +PluginPage.getLayout = NextraLayout.getLayout; + +export default PluginPage; diff --git a/website/docs-templates/c-sharp-operations.md b/website/src/pages/plugin-hub/c-sharp/c-sharp-operations.mdx similarity index 69% rename from website/docs-templates/c-sharp-operations.md rename to website/src/pages/plugin-hub/c-sharp/c-sharp-operations.mdx index ee1d165061c..eac9412e136 100644 --- a/website/docs-templates/c-sharp-operations.md +++ b/website/src/pages/plugin-hub/c-sharp/c-sharp-operations.mdx @@ -1,6 +1,9 @@ ---- -id: c-sharp-operations ---- +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' + +export const getStaticProps = getNpmInfo('c-sharp-operations') + + The `c-sharp-operations` plugin generates C# methods for the resolvers' signature. @@ -17,6 +20,4 @@ using GraphQL.Client.Serializer.Newtonsoft; var response = await client.SendQueryAsync(UsersGQL.Request()); ``` -{@operationsNote} - -{@apiDocs} + diff --git a/website/src/pages/plugin-hub/c-sharp/meta.json b/website/src/pages/plugin-hub/c-sharp/meta.json new file mode 100644 index 00000000000..307d49c50f3 --- /dev/null +++ b/website/src/pages/plugin-hub/c-sharp/meta.json @@ -0,0 +1,3 @@ +{ + "c-sharp-operations": "operations" +} diff --git a/website/src/pages/plugin-hub/flow/flow-operations.mdx b/website/src/pages/plugin-hub/flow/flow-operations.mdx new file mode 100644 index 00000000000..5d4afa43e55 --- /dev/null +++ b/website/src/pages/plugin-hub/flow/flow-operations.mdx @@ -0,0 +1,7 @@ +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' + +export const getStaticProps = getNpmInfo('flow-operations') + + + diff --git a/website/docs-templates/flow-resolvers.md b/website/src/pages/plugin-hub/flow/flow-resolvers.mdx similarity index 72% rename from website/docs-templates/flow-resolvers.md rename to website/src/pages/plugin-hub/flow/flow-resolvers.mdx index e22eb987147..4c51f1900a0 100644 --- a/website/docs-templates/flow-resolvers.md +++ b/website/src/pages/plugin-hub/flow/flow-resolvers.mdx @@ -1,14 +1,19 @@ ---- -id: flow-resolvers ---- +import Callout from 'nextra-theme-docs/callout' +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' -{@apiDocs} +export const getStaticProps = getNpmInfo('flow-resolvers') + + ## Usage Example -> **Quick Start with `flow-resolvers`** -> -> You can find [a blog post we wrote about using and customizing this plugin here](https://the-guild.dev/blog/better-type-safety-for-resolvers-with-graphql-codegen), it refers to `typescript-resolvers` but everything there is relevant to `flow-resolvers` as well. + +**Quick Start with `flow-resolvers`** + +You can find [a blog post we wrote about using and customizing this plugin here](https://the-guild.dev/blog/better-type-safety-for-resolvers-with-graphql-codegen), it refers to `typescript-resolvers` but everything there is relevant to `flow-resolvers` as well. + + ## Enum Resolvers @@ -45,14 +50,14 @@ generates: - flow-resolvers ``` -```ts -// in your enums.js +```ts filename="enums.ts" export enum ColorsCode { MY_RED = '#FF0000', MY_BLUE = '#0000FF' } +``` -// in your resolvers.js +```ts filename="resolvers.ts" import type { Resolvers } from './resolvers-types' import { ColorsCode } from './enums' @@ -69,7 +74,7 @@ const resolvers: Resolvers = { You can also define the same with explicit enum values: -```yaml +```yaml {7-8} schema: schema.graphql generates: ./resolvers-types.js: @@ -85,7 +90,7 @@ generates: Or, with `mappers`: -```yaml +```yaml {5-6} schema: schema.graphql generates: ./resolvers-types.js: @@ -96,3 +101,5 @@ generates: - flow - flow-resolvers ``` + + diff --git a/website/src/pages/plugin-hub/flow/meta.json b/website/src/pages/plugin-hub/flow/meta.json new file mode 100644 index 00000000000..ff57065f4f2 --- /dev/null +++ b/website/src/pages/plugin-hub/flow/meta.json @@ -0,0 +1,4 @@ +{ + "flow-operations": "operations", + "flow-resolvers": "resolvers" +} diff --git a/website/src/pages/plugin-hub/index.mdx b/website/src/pages/plugin-hub/index.mdx new file mode 100644 index 00000000000..1a773cd0e21 --- /dev/null +++ b/website/src/pages/plugin-hub/index.mdx @@ -0,0 +1,35 @@ +import { buildMultipleMDX } from '@guild-docs/server'; +import { getPackagesData } from '@guild-docs/server/npm'; +import { PluginHub } from '@/components/plugin-hub'; +import { PACKAGES } from '@/lib/plugins'; + +export const getStaticProps = async () => { + const pluginsData = await getPackagesData({ packageList: PACKAGES }); + + const data = await Promise.all( + pluginsData.map(async plugin => { + const [description, content] = await buildMultipleMDX([ + `${plugin.stats?.version || ''}\n\n${plugin.stats?.description || ''}`, + plugin.readme || plugin.stats?.readme || '', + ]); + + return { + ...plugin, + description, + content, + }; + }) + ); + + return { + props: { + // We add an `ssg` field to the page props, + // which will be provided to the Nextra `useSSG` hook. + ssg: { data }, + }, + // Revalidate at most once every 1 hour + revalidate: 60 * 60, + }; +}; + + diff --git a/website/docs-templates/java-apollo-android.md b/website/src/pages/plugin-hub/java/java-apollo-android.mdx similarity index 60% rename from website/docs-templates/java-apollo-android.md rename to website/src/pages/plugin-hub/java/java-apollo-android.mdx index 9d728fff2b9..ada2d90466f 100644 --- a/website/docs-templates/java-apollo-android.md +++ b/website/src/pages/plugin-hub/java/java-apollo-android.mdx @@ -1,22 +1,21 @@ ---- -id: java-apollo-android ---- +import Callout from 'nextra-theme-docs/callout' +import { PackageApiDocs, PackageHeader, PackageCmd } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' -{@apiDocs} +export const getStaticProps = getNpmInfo('java-apollo-android') + + ## Prepare your env To get started with these plugins and preset, make sure you have the following installed: -- NodeJS (10 or later) +- Node.js (10 or later) - NPM or Yarn Run the following in your Android project: -```sh -yarn init --yes -yarn add @graphql-codegen/cli graphql @graphql-codegen/java-apollo-android -``` + Then, create `codegen.yml` with the following configuration: @@ -34,14 +33,14 @@ generates: - java-apollo-android ``` -> Also, make sure to add `node_modules` to your `.gitignore` file. +Also, make sure to add `node_modules` to your `.gitignore` file. To integrate with your Gradle build, you can add the following to your app Gradle file: ``` preBuild.doFirst { - def proc = "yarn graphql-codegen".execute() - proc.waitForProcessOutput(System.out, System.err) + def proc = "yarn graphql-codegen".execute() + proc.waitForProcessOutput(System.out, System.err) } build.dependsOn preBuild @@ -51,4 +50,6 @@ This will make sure to run and generate output before each time you build your p ## Usage -You can find a [repository with a working example using AppSync](https://github.com/dotansimha/graphql-codegen-appsync-android-example) +You can find a [repository with a working example using AppSync](https://github.com/dotansimha/graphql-codegen-appsync-android-example). + + diff --git a/website/src/pages/plugin-hub/java/java-resolvers.mdx b/website/src/pages/plugin-hub/java/java-resolvers.mdx new file mode 100644 index 00000000000..095439d2a59 --- /dev/null +++ b/website/src/pages/plugin-hub/java/java-resolvers.mdx @@ -0,0 +1,83 @@ +import Callout from 'nextra-theme-docs/callout' +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' + +export const getStaticProps = getNpmInfo('java-resolvers') + + + +The `java-resolvers` plugin creates Java `interface`s for the resolvers' signature. + +It works with `graphql-java` library, and it uses it's `DataFetcher` API. + +You can use this plugin to generate interfaces and later implement them, this way you can always tell if one of the fields is missing a resolvers: + +```java +import com.my.app.generated.Resolvers; +import com.my.app.models.User; +import graphql.schema.DataFetcher; + +export class QueryResolvers implements Resolvers.Query { + public DataFetcher id() { + return environment -> environment.getSource().getId(); + } +} +``` + +## Prepare your environment + +To use the GraphQL Code Generator with Java, start by adding the [com.moowork.node](https://plugins.gradle.org/plugin/com.moowork.node) Gradle plugin to your `build.gradle`: + +``` +plugins { + id "com.moowork.node" version "1.3.1" +} +``` + +Then, add the following in order to make sure you are running the code-generator on each build: + +``` +build.dependsOn yarn +``` + +Then, create a `package.json` file in your project root, with the following content: + +```json +{ + "name": "java-app", + "scripts": { + "postinstall": "graphql-codegen" + }, + "dependencies": { + "graphql": "14.5.8", + "@graphql-codegen/cli": "1.7.0", + "@graphql-codegen/RELEVANT_PLUGIN": "1.7.0" + } +} +``` + + + Make sure to use the latest version of codegen and the plugins, and replace `RELEVANT_PLUGIN` with your plugin name. + + +Then, create `codegen.yml` file in your root directory, pointing to your schema, and add the plugins you need. For example: + +```yaml +schema: src/main/resources/schema.graphqls +generates: + src/main/java/com/my-name/my-app/generated/File.java: + - RELEVANT_PLUGIN # Replace with your plugin name +``` + +Also, make sure you add the following to your `.gitignore` file: + +```text +yarn.lock +node_modules +``` + +Now, run `gradle yarn` to install the dependencies for the first time. + +Next time, the codegen will run automatically each time you run your Gradle build script. + + diff --git a/website/docs-templates/java-installation.md b/website/src/pages/plugin-hub/java/java.mdx similarity index 56% rename from website/docs-templates/java-installation.md rename to website/src/pages/plugin-hub/java/java.mdx index 2d40eb5f659..2b7ddf964f0 100644 --- a/website/docs-templates/java-installation.md +++ b/website/src/pages/plugin-hub/java/java.mdx @@ -1,3 +1,13 @@ +import Callout from 'nextra-theme-docs/callout' +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' + +export const getStaticProps = getNpmInfo('java') + + + +## Prepare your environment + To use the GraphQL Code Generator with Java, start by adding the [com.moowork.node](https://plugins.gradle.org/plugin/com.moowork.node) Gradle plugin to your `build.gradle`: ``` @@ -28,7 +38,9 @@ Then, create a `package.json` file in your project root, with the following cont } ``` -> Make sure to use the latest version of codegen and the plugins, and replace `RELEVANT_PLUGIN` with your plugin name. + + Make sure to use the latest version of codegen and the plugins, and replace `RELEVANT_PLUGIN` with your plugin name. + Then, create `codegen.yml` file in your root directory, pointing to your schema, and add the plugins you need. For example: @@ -36,14 +48,12 @@ Then, create `codegen.yml` file in your root directory, pointing to your schema, schema: src/main/resources/schema.graphqls generates: src/main/java/com/my-name/my-app/generated/File.java: - - RELEVANT_PLUGIN + - RELEVANT_PLUGIN # Replace with your plugin name ``` -> Replace `RELEVANT_PLUGIN` with your plugin name. - Also, make sure you add the following to your `.gitignore` file: -```gitignore +```text yarn.lock node_modules ``` @@ -51,3 +61,38 @@ node_modules Now, run `gradle yarn` to install the dependencies for the first time. Next time, the codegen will run automatically each time you run your Gradle build script. + +## How to use + +You can use it directly to transform your `input` in your resolvers: + +```graphql +type Query { + user(id: ID!): User! +} + +type User { + id: ID +} +``` + +Then, in your resolver: + +```java +import com.my.app.generated.Types; +import com.my.app.models.User; +import graphql.schema.DataFetcher; + +export class QueryResolvers { + public DataFetcher user() { + return env -> { + Types.QueryUserArgs args = new Types.QueryUserArgs(env.getArguments()); + String userId = args.getId(); + + // rest of the code + }; + } +} +``` + + diff --git a/website/docs-templates/kotlin.md b/website/src/pages/plugin-hub/java/kotlin.mdx similarity index 56% rename from website/docs-templates/kotlin.md rename to website/src/pages/plugin-hub/java/kotlin.mdx index 92824b20aeb..dff4e4f308c 100644 --- a/website/docs-templates/kotlin.md +++ b/website/src/pages/plugin-hub/java/kotlin.mdx @@ -1,6 +1,10 @@ ---- -id: kotlin ---- +import Callout from 'nextra-theme-docs/callout' +import { PackageApiDocs, PackageHeader, PackageCmd } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' + +export const getStaticProps = getNpmInfo('kotlin') + + The `kotlin` plugin generates Kotlin `classes` for Enums and Input types. @@ -10,15 +14,12 @@ You can use this plugin to generate Java enums based on your GraphQL schema, and To get started with these plugins and preset, make sure you have the following installed: -- NodeJS (10 or later) +- Node.js (10 or later) - NPM or Yarn Run the following in your Android project: -```sh -yarn init --yes -yarn add @graphql-codegen/cli graphql @graphql-codegen/kotlin -``` + Then, create `codegen.yml` with the following configuration: @@ -31,6 +32,6 @@ generates: - kotlin ``` -> Also, make sure to add `node_modules` to your `.gitignore` file. +Also, make sure to add `node_modules` to your `.gitignore` file. -{@apiDocs} + diff --git a/website/src/pages/plugin-hub/java/meta.json b/website/src/pages/plugin-hub/java/meta.json new file mode 100644 index 00000000000..f1de40805d5 --- /dev/null +++ b/website/src/pages/plugin-hub/java/meta.json @@ -0,0 +1,6 @@ +{ + "java": "java", + "java-apollo-android": "java-apollo-android", + "java-resolvers": "java-resolvers", + "kotlin": "kotlin" +} diff --git a/website/src/pages/plugin-hub/meta.json b/website/src/pages/plugin-hub/meta.json new file mode 100644 index 00000000000..8252039a673 --- /dev/null +++ b/website/src/pages/plugin-hub/meta.json @@ -0,0 +1,13 @@ +{ + "index": { + "title": "Plugin Hub", + "theme": { + "layout": "raw" + } + }, + "typescript": "TypeScript", + "presets": "Presets", + "java": "Java", + "c-sharp": "C-Sharp", + "flow": "Flow" +} diff --git a/website/docs-templates/add.md b/website/src/pages/plugin-hub/other/add.mdx similarity index 67% rename from website/docs-templates/add.md rename to website/src/pages/plugin-hub/other/add.mdx index 2e0cbadc7a1..238b59b1e7c 100644 --- a/website/docs-templates/add.md +++ b/website/src/pages/plugin-hub/other/add.mdx @@ -1,17 +1,18 @@ ---- -id: add ---- +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' + +export const getStaticProps = getNpmInfo('add') + + `add` plugin adds custom text to your output file. You can use this plugin to add custom code, imports, comments and more to your output file. -{@apiDocs} - ## Examples -```yaml -# ... +```yaml {5-6} +# … generates: path/to/file.ts: plugins: @@ -20,8 +21,8 @@ generates: - typescript ``` -```yaml -# ... +```yaml {5-10} +# … generates: path/to/file.ts: plugins: @@ -33,3 +34,5 @@ generates: content: '}' - typescript ``` + + diff --git a/website/docs-templates/fragment-matcher.md b/website/src/pages/plugin-hub/other/fragment-matcher.mdx similarity index 54% rename from website/docs-templates/fragment-matcher.md rename to website/src/pages/plugin-hub/other/fragment-matcher.mdx index b3c57d72e8e..b1416961d79 100644 --- a/website/docs-templates/fragment-matcher.md +++ b/website/src/pages/plugin-hub/other/fragment-matcher.mdx @@ -1,13 +1,16 @@ ---- -id: fragment-matcher ---- +import Callout from 'nextra-theme-docs/callout' +import { Tabs, Tab } from 'nextra-theme-docs/tabs' +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' -{@apiDocs} +export const getStaticProps = getNpmInfo('fragment-matcher') -## How to use? + -## Usage with Apollo Client 3 +## How to use? + + If you are using Apollo Client 3, update your codegen config accordingly, and then use it in your Apollo cache instance: ```ts @@ -19,11 +22,13 @@ import generatedIntrospection from '../introspection-result' const cache = new InMemoryCache({ possibleTypes: generatedIntrospection.possibleTypes }) ``` -> [Read more about fragment matcher and its usage on Apollo Client](https://apollographql.com/docs/react/data/fragments/#defining-possibletypes-manually) - -## Usage with Apollo Client 2 + +[Read more about fragment matcher and its usage on Apollo Client](https://apollographql.com/docs/react/data/fragments/#defining-possibletypes-manually). + + -If you are using version 2 of Apollo-Client, you need to specify the `apolloClientVersion: 2` configuration, and then use it like that: + +If you are using version 2 of Apollo-Client, you need to specify the `apolloClientVersion: 2{:yaml}` configuration, and then use it like that: ```ts import { InMemoryCache, IntrospectionFragmentMatcher } from 'apollo-cache-inmemory' @@ -37,3 +42,8 @@ const fragmentMatcher = new IntrospectionFragmentMatcher({ const cache = new InMemoryCache({ fragmentMatcher }) ``` + + + + + diff --git a/website/docs-templates/hasura-allow-list.md b/website/src/pages/plugin-hub/other/hasura-allow-list.mdx similarity index 53% rename from website/docs-templates/hasura-allow-list.md rename to website/src/pages/plugin-hub/other/hasura-allow-list.mdx index 3124cd454a7..b37ad936643 100644 --- a/website/docs-templates/hasura-allow-list.md +++ b/website/src/pages/plugin-hub/other/hasura-allow-list.mdx @@ -1,21 +1,24 @@ ---- -id: hasura-allow-list ---- +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' + +export const getStaticProps = getNpmInfo('hasura-allow-list') + + Generate hasura allow list metadata from graphql files -You can use this plugin to generate an [allow list](https://hasura.io/docs/latest/graphql/cloud/security/allow-lists.html) for your [hasura](https://hasura.io/) project. +You can use this plugin to generate an [allow list](https://hasura.io/docs/latest/graphql/cloud/security/allow-lists.html) for your [hasura](https://hasura.io) project. This can be useful to keep your allow list and front end code in sync. -{@apiDocs} - ## Examples -```yaml -# ... +```yaml {5} +# … generates: path/to/metadata/allow_list.yaml: plugins: - - hasura-allow-list: + - hasura-allow-list ``` + + diff --git a/website/src/pages/plugin-hub/other/introspection.mdx b/website/src/pages/plugin-hub/other/introspection.mdx new file mode 100644 index 00000000000..5f7bb553417 --- /dev/null +++ b/website/src/pages/plugin-hub/other/introspection.mdx @@ -0,0 +1,7 @@ +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' + +export const getStaticProps = getNpmInfo('introspection') + + + diff --git a/website/src/pages/plugin-hub/other/jsdoc.mdx b/website/src/pages/plugin-hub/other/jsdoc.mdx new file mode 100644 index 00000000000..f77b5c64307 --- /dev/null +++ b/website/src/pages/plugin-hub/other/jsdoc.mdx @@ -0,0 +1,10 @@ +import { PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' + +export const getStaticProps = getNpmInfo('jsdoc') + + + +_developed by [`CarloPalinckx`](https://github.com/CarloPalinckx)_ + +This plugin generates types in the form of JSDoc comments based on your GraphQLSchema. diff --git a/website/src/pages/plugin-hub/other/meta.json b/website/src/pages/plugin-hub/other/meta.json new file mode 100644 index 00000000000..95408d650d3 --- /dev/null +++ b/website/src/pages/plugin-hub/other/meta.json @@ -0,0 +1,11 @@ +{ + "add": "add", + "fragment-matcher": "fragment-matcher", + "hasura-allow-list": "hasura-allow-list", + "introspection": "introspection", + "jsdoc": "jsdoc", + "reason-client": "reason-client", + "schema-ast": "schema-ast", + "time": "time", + "urql-introspection": "urql-introspection" +} diff --git a/website/docs-templates/reason-client.md b/website/src/pages/plugin-hub/other/reason-client.mdx similarity index 63% rename from website/docs-templates/reason-client.md rename to website/src/pages/plugin-hub/other/reason-client.mdx index cbd2524d9f3..2f59e680ce2 100644 --- a/website/docs-templates/reason-client.md +++ b/website/src/pages/plugin-hub/other/reason-client.mdx @@ -1,14 +1,17 @@ ---- -id: reason-client ---- +import { PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' -_Built and maintained by [kgoggin](https://github.com/kgoggin)_ +export const getStaticProps = getNpmInfo('reason-client') + + + +_Built and maintained by [kgoggin](https://github.com/kgoggin)_. A plugin for GraphQL Codegen to generate ReasonML types based on your GraphQL schema for use in a client application. ## Examples -Set up your project per the GraphQL Codegen Docs, and specify this plugin in your codegen.yml: +Set up your project per the GraphQL Codegen Docs, and specify this plugin in your `codegen.yml`: ```yaml schema: http://path.to.your.app diff --git a/website/src/pages/plugin-hub/other/schema-ast.mdx b/website/src/pages/plugin-hub/other/schema-ast.mdx new file mode 100644 index 00000000000..2220770e84f --- /dev/null +++ b/website/src/pages/plugin-hub/other/schema-ast.mdx @@ -0,0 +1,22 @@ +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' + +export const getStaticProps = getNpmInfo('schema-ast') + + + +## Examples + +```yaml {9} +# … +schema: + - 'http://localhost:3000/graphql' + - './src/**/*.graphql' + - 'scalar MyCustomScalar' +generates: + path/to/file.graphql: + plugins: + - schema-ast +``` + + diff --git a/website/src/pages/plugin-hub/other/time.mdx b/website/src/pages/plugin-hub/other/time.mdx new file mode 100644 index 00000000000..043ac121d82 --- /dev/null +++ b/website/src/pages/plugin-hub/other/time.mdx @@ -0,0 +1,7 @@ +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' + +export const getStaticProps = getNpmInfo('time') + + + diff --git a/website/src/pages/plugin-hub/other/urql-introspection.mdx b/website/src/pages/plugin-hub/other/urql-introspection.mdx new file mode 100644 index 00000000000..8c2d28472e8 --- /dev/null +++ b/website/src/pages/plugin-hub/other/urql-introspection.mdx @@ -0,0 +1,21 @@ +import Callout from 'nextra-theme-docs/callout' +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' + +export const getStaticProps = getNpmInfo('urql-introspection') + + + +## How to use? + +```ts +// generated by the plugin +import schema from './generated-introspection.json' +const cache = cacheExchange({ schema }) +``` + + + [Read more about Schema Awareness](https://formidable.com/open-source/urql/docs/graphcache/schema-awareness) + + + diff --git a/website/docs-templates/gql-tag-operations-preset.md b/website/src/pages/plugin-hub/presets/gql-tag-operations-preset.mdx similarity index 85% rename from website/docs-templates/gql-tag-operations-preset.md rename to website/src/pages/plugin-hub/presets/gql-tag-operations-preset.mdx index 343e744a75a..7ec3b6784e1 100644 --- a/website/docs-templates/gql-tag-operations-preset.md +++ b/website/src/pages/plugin-hub/presets/gql-tag-operations-preset.mdx @@ -1,6 +1,10 @@ ---- -id: gql-tag-operations ---- +import Callout from 'nextra-theme-docs/callout' +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' + +export const getStaticProps = getNpmInfo('gql-tag-operations-preset') + + This preset generates typings for your inline `gql` function usages, without having to manually specify import statements for the documents. All you need to do is import your `gql` function and run codegen in watch mode. @@ -43,7 +47,7 @@ generates: It is also recommended, that you link `./src/gql` to `@app/gql`, so you can import your gql function easily from anywhere within your app. -```bash +```sh yarn add -D @app/gql@link:./src/gql ``` @@ -64,7 +68,7 @@ const TweetsQuery = gql(/* GraphQL */ ` `) ``` -Next we can simply add our GraphQL client of choice and use the typed document! Let's try urql! +Next we can simply add our GraphQL client of choice and use the typed document! Let's try `urql`! ```tsx import { gql } from '@app/gql' @@ -84,8 +88,8 @@ const Tweets = () => { const [result] = useQuery({ query: TweetsQuery }) const { data, fetching, error } = result - if (fetching) return

Loading...

- if (error) return

Oh no... {error.message}

+ if (fetching) return

Loading…

+ if (error) return

Oh no… {error.message}

return (
    @@ -111,7 +115,7 @@ const TweetFragment = gql(/* GraphQL */ ` `) const Tweet = (props: { - /** tweet property has the correct type 🎉 */ + /* tweet property has the correct type 🎉 */ tweet: DocumentType }) => { return
  • {props.tweet.body}
  • @@ -130,8 +134,8 @@ const Tweets = () => { const [result] = useQuery({ query: TweetsQuery }) const { data, fetching, error } = result - if (fetching) return

    Loading...

    - if (error) return

    Oh no... {error.message}

    + if (fetching) return

    Loading…

    + if (error) return

    Oh no… {error.message}

    return (
      @@ -202,15 +206,13 @@ This will result in much smaller bundles when you code-split parts of your code. Applying the babel plugin is straight-forward: -**.babelrc.mjs** - -```ts +```ts filename=".babelrc.mjs" import { babelPlugin } from '@graphql-codegen/gql-tag-operations-preset' export default { plugins: [ // your other plugins such as typescript syntax stripping etc. - // make sure the artifactDirectory is the same as your generates path within the codegen.yml + // make sure the artifactDirectory is the same as your generates path within the `codegen.yml` [babelPlugin, { artifactDirectory: './src/gql' }] ] } @@ -224,9 +226,7 @@ Sometimes the library you are using, let's use `urql` for this example, already This can be easily achieved by running the `gql-tag-operations` plugin in module augmentation mode! -**codegen.yml** - -```yaml +```yaml filename="codegen.yml" schema: src/path/to/your/schema.graphql documents: - 'src/**/*.ts' @@ -267,7 +267,12 @@ const FooQuery = gql(/* GraphQL */ ` `) ``` -**NOTE**: In case you are using fragments you **MUST** use the gql-tag-operations babel plugin as otherwise the `gql` calls that reference global fragments will cause runtime errors, as the `gql` operation cannot find the global fragment. Unfortunately, it is also **NOT** possible to embed fragments with template string interpolation, as it breaks TypeScript type-inference. + + In case you are using fragments you **MUST** use the gql-tag-operations babel plugin as otherwise the `gql` calls that + reference global fragments will cause runtime errors, as the `gql` operation cannot find the global fragment. + Unfortunately, it is also **NOT** possible to embed fragments with template string interpolation, as it breaks + TypeScript type-inference. + ```ts import { gql } from 'urql' @@ -290,9 +295,7 @@ Fragment masking is a powerful tool that allows building scalable UI components, Fragment masking is enabled via the `fragmentMasking` config option. -**codegen.yml** - -```yaml +```yaml filename="codegen.yml" schema: src/path/to/your/schema.graphql documents: - 'src/**/*.ts' @@ -318,7 +321,7 @@ const TweetFragment = gql(/* GraphQL */ ` `) const Tweet = (props: { - /** tweet property has the correct type 🎉 */ + /* tweet property has the correct type 🎉 */ tweet: FragmentType }) => { // we unmask our fragment to the actual type @@ -339,8 +342,8 @@ const Tweets = () => { const [result] = useQuery({ query: TweetsQuery }) const { data, fetching, error } = result - if (fetching) return

      Loading...

      - if (error) return

      Oh no... {error.message}

      + if (fetching) return

      Loading…

      + if (error) return

      Oh no… {error.message}

      return (
        @@ -354,15 +357,18 @@ const Tweets = () => { } ``` -**Note**: The default `useFragment` implementation does only data masking on a TypeScript type level. If you log the object, you can all properties, including the masked ones, are available on the object. For true runtime data masking, the GraphQL client must implement it. Currently, there is no client that does this (aside from relay which should best be used with relay-compiler). + + The default `useFragment` implementation does only data masking on a TypeScript type level. If you log the object, you + can all properties, including the masked ones, are available on the object. For true runtime data masking, the GraphQL + client must implement it. Currently, there is no client that does this (aside from relay which should best be used + with relay-compiler). + ### Fragment Masking with custom unmask name By default, the data unmask function name is `useFragment`, which follows the React hook naming convention. For React users we recommend keeping that name. If you need to customize the name of the function you can provide the `fragmentMasking.unmaskFunctionName` option. -**codegen.yml** - -```yaml +```yaml filename="codegen.yml" schema: src/path/to/your/schema.graphql documents: - 'src/**/*.ts' @@ -380,9 +386,7 @@ generates: Similar to the `gql` module augmentation configuration it is also possible to generate type definitions for the unmask function. The `fragmentMasking.unmaskFunctionName` will be used when doing so. -**codegen.yml** - -```yaml +```yaml filename="codegen.yml" schema: src/path/to/your/schema.graphql documents: - 'src/**/*.ts' @@ -395,4 +399,4 @@ generates: augmentedModuleName: '@something/fragment' ``` -{@apiDocs} + diff --git a/website/docs-templates/graphql-modules-preset.md b/website/src/pages/plugin-hub/presets/graphql-modules-preset.mdx similarity index 72% rename from website/docs-templates/graphql-modules-preset.md rename to website/src/pages/plugin-hub/presets/graphql-modules-preset.mdx index b0edb66da09..faf9f606da4 100644 --- a/website/docs-templates/graphql-modules-preset.md +++ b/website/src/pages/plugin-hub/presets/graphql-modules-preset.mdx @@ -1,20 +1,23 @@ ---- -id: graphql-modules ---- +import Callout from 'nextra-theme-docs/callout' +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' + +export const getStaticProps = getNpmInfo('graphql-modules-preset') + + The `@graphql-codegen/graphql-modules-preset` generates `.ts` file with TypeScript types, per each directory that contains GraphQL SDL definitions. The generates files will be generated based on each module definition, and based on the GraphQL schema defined in that specific module, allowing you to write type-safe resolvers, while keeping modules types boundaries. - -This preset generates code for `graphql-modules` @ `v1` / `v2` (previous versions are not supported) by default. + +**Usage Requirements** -If you are not using `graphql-modules`, you can set `useGraphQLModules: false` to disable this behaviour. - +This preset generates code for `graphql-modules` @ `v1` / `v2` (previous versions are not supported) by default. -## Configuration +If you are not using `graphql-modules`, you can set `useGraphQLModules: false{:yaml}` to disable this behaviour. -{@apiDocs} + ## Usage Example @@ -54,8 +57,7 @@ This will generate a file called `module-types.ts` under each module you have. To use the generates resolvers, you can use `Resolvers` signature and apply it to your resolvers object within the module: -```ts -// src/modules/user/resolvers.ts +```ts filename="src/modules/user/resolvers.ts" import { MyModule } from './generated-types/module-types' export const resolvers: MyModule.Resolvers = { @@ -63,8 +65,13 @@ export const resolvers: MyModule.Resolvers = { } ``` -> You can find [an example project here](https://github.com/dotansimha/graphql-code-generator/tree/master/dev-test/modules). + + You can find [an example project + here](https://github.com/dotansimha/graphql-code-generator/tree/master/dev-test/modules). + ## Using without GraphQL-Modules -By default, this preset it generating code for `graphql-modules`, but if you are not using it, you can set `useGraphQLModules: false` in your preset configuration to generate fully agnostic types that are based on folder structure only. +By default, this preset it generating code for `graphql-modules`, but if you are not using it, you can set `useGraphQLModules: false{:yaml}` in your preset configuration to generate fully agnostic types that are based on folder structure only. + + diff --git a/website/src/pages/plugin-hub/presets/import-types-preset.mdx b/website/src/pages/plugin-hub/presets/import-types-preset.mdx new file mode 100644 index 00000000000..467e07f6657 --- /dev/null +++ b/website/src/pages/plugin-hub/presets/import-types-preset.mdx @@ -0,0 +1,11 @@ +import Callout from 'nextra-theme-docs/callout' +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' + +export const getStaticProps = getNpmInfo('import-types-preset') + + + +This preset generates a file per each operation file, and allow to import types from another file. + + diff --git a/website/src/pages/plugin-hub/presets/meta.json b/website/src/pages/plugin-hub/presets/meta.json new file mode 100644 index 00000000000..658264d526d --- /dev/null +++ b/website/src/pages/plugin-hub/presets/meta.json @@ -0,0 +1,6 @@ +{ + "gql-tag-operations-preset": "gql-tag-operations", + "graphql-modules-preset": "graphql-modules", + "import-types-preset": "import-types", + "near-operation-file-preset": "near-operation-file" +} diff --git a/website/docs-templates/near-operation-file-preset.md b/website/src/pages/plugin-hub/presets/near-operation-file-preset.mdx similarity index 70% rename from website/docs-templates/near-operation-file-preset.md rename to website/src/pages/plugin-hub/presets/near-operation-file-preset.mdx index 3bab4c39199..29922ee4fde 100644 --- a/website/docs-templates/near-operation-file-preset.md +++ b/website/src/pages/plugin-hub/presets/near-operation-file-preset.mdx @@ -1,10 +1,12 @@ ---- -id: near-operation-file ---- +import Callout from 'nextra-theme-docs/callout' +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' -This preset generates a file per each operation file. +export const getStaticProps = getNpmInfo('near-operation-file-preset') + + -{@apiDocs} +This preset generates a file per each operation file. ## Example @@ -39,4 +41,8 @@ The second output refers to the base directory of the project (`./src/`) and it The `presetConfig` section contains a key for setting the output files extension (in our case, `.generated.tsx` because of `react-apollo`), and the location of the base schema types file we created in the first section of this file (it will look for it in the base directory). -> Note: If you're loading your `documents` from files with the same extension as the generated files, make sure the glob you use excludes the generated files. For example, if your original glob was `src/**/*.{ts,tsx}`, use `src/**/!(*.generated).{ts,tsx}` instead. + +Note: If you're loading your `documents` from files with the same extension as the generated files, make sure the glob you use excludes the generated files. For example, if your original glob was `src/**/*.{ts,tsx}`, use `src/**/!(*.generated).{ts,tsx}` instead. + + + diff --git a/website/src/pages/plugin-hub/typescript/meta.json b/website/src/pages/plugin-hub/typescript/meta.json new file mode 100644 index 00000000000..9271cb1f2f3 --- /dev/null +++ b/website/src/pages/plugin-hub/typescript/meta.json @@ -0,0 +1,29 @@ +{ + "named-operations-object": "named-operations-object", + "relay-operation-optimizer": "relay-operation-optimizer", + "typed-document-node": "typed-document-node", + "typescript": "typescript", + "typescript-apollo-angular": "apollo-angular", + "typescript-apollo-client-helpers": "apollo-client-helpers", + "typescript-apollo-next": "apollo-next", + "typescript-document-nodes": "document-nodes", + "typescript-generic-sdk": "generic-sdk", + "typescript-graphql-files-modules": "graphql-files-modules", + "typescript-graphql-request": "graphql-request", + "typescript-mongodb": "mongodb", + "typescript-msw": "msw", + "typescript-oclif": "oclif", + "typescript-operations": "operations", + "typescript-react-apollo": "react-apollo", + "typescript-react-query": "react-query", + "typescript-resolvers": "resolvers", + "typescript-rtk-query": "rtk-query", + "typescript-stencil-apollo": "stencil-apollo", + "typescript-svelte-apollo": "svelte-apollo", + "typescript-type-graphql": "type-graphql", + "typescript-urql": "urql", + "typescript-validation-schema": "validation-schema", + "typescript-vue-apollo": "vue-apollo", + "typescript-vue-apollo-smart-ops": "vue-apollo-smart-ops", + "typescript-vue-urql": "vue-urql" +} diff --git a/website/docs-templates/named-operations-object.md b/website/src/pages/plugin-hub/typescript/named-operations-object.mdx similarity index 86% rename from website/docs-templates/named-operations-object.md rename to website/src/pages/plugin-hub/typescript/named-operations-object.mdx index c4bbdd95cb4..4436e3d4c25 100644 --- a/website/docs-templates/named-operations-object.md +++ b/website/src/pages/plugin-hub/typescript/named-operations-object.mdx @@ -1,6 +1,9 @@ ---- -id: named-operations-object ---- +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' + +export const getStaticProps = getNpmInfo('named-operations-object') + + This plugin generates an object containing a list of all your GraphQL operations and fragments. This is useful if you are using Apollo-Client and wish to have type validation when you are using `refetchQueries`. @@ -15,11 +18,11 @@ export const namedOperations = { } ``` -{@apiDocs} + ## How to use? -Include the plugin within your output (into an existing JS/TS file, or a new file), for example: +Include the plugin within your output (into an existing `.js`/`.ts` file, or a new file), for example: ```yaml schema: YOUR_SCHEMA diff --git a/website/docs-templates/relay-operation-optimizer.md b/website/src/pages/plugin-hub/typescript/relay-operation-optimizer.mdx similarity index 68% rename from website/docs-templates/relay-operation-optimizer.md rename to website/src/pages/plugin-hub/typescript/relay-operation-optimizer.mdx index 016179d6ed4..ef7017c71bd 100644 --- a/website/docs-templates/relay-operation-optimizer.md +++ b/website/src/pages/plugin-hub/typescript/relay-operation-optimizer.mdx @@ -1,10 +1,14 @@ ---- -id: relay-operation-optimizer ---- +import Callout from 'nextra-theme-docs/callout' +import { PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' -_Built and maintained by [n1ru4l](https://github.com/n1ru4l)_ +export const getStaticProps = getNpmInfo('relay-operation-optimizer') -A GraphQL Codegen feature for bringing the benefits of Relay Compiler to any GraphQL Client using [Relay Operation Optimizer](https://graphql-tools.com/docs/relay-operation-optimizer) + + +_Built and maintained by [n1ru4l](https://github.com/n1ru4l)_. + +A GraphQL Codegen feature for bringing the benefits of Relay Compiler to any GraphQL Client using [Relay Operation Optimizer](https://graphql-tools.com/docs/relay-operation-optimizer). You can test how relay-compiler affects your queries over on the [Relay Compiler REPL](https://relay-compiler-repl.netlify.com). @@ -20,9 +24,9 @@ You can test how relay-compiler affects your queries over on the [Relay Compiler ## Usage -Set up your project per the GraphQL Codegen Docs, and add `flattenGeneratedTypes: true` in your codegen.yml: +Set up your project per the GraphQL Codegen Docs, and add `flattenGeneratedTypes: true{:yaml}` in your `codegen.yml`: -```yaml +```yaml {8} overwrite: true schema: schema.graphql generates: @@ -39,4 +43,7 @@ generates: Please notice that you have to skip the document validation - but no worries, relay-compiler will validate your documents instead! -> [See Laurin Quast's blog post to learn how to use those directives in your operations](https://the-guild.dev/blog/graphql-codegen-relay-compiler) + + [See Laurin Quast's blog post to learn how to use those directives in your + operations](https://the-guild.dev/blog/graphql-codegen-relay-compiler) + diff --git a/website/docs-templates/typed-document-node.md b/website/src/pages/plugin-hub/typescript/typed-document-node.mdx similarity index 76% rename from website/docs-templates/typed-document-node.md rename to website/src/pages/plugin-hub/typescript/typed-document-node.mdx index 55cec9db2b2..fab9eb18738 100644 --- a/website/docs-templates/typed-document-node.md +++ b/website/src/pages/plugin-hub/typescript/typed-document-node.mdx @@ -1,8 +1,10 @@ ---- -id: typed-document-node ---- +import Callout from 'nextra-theme-docs/callout' +import { PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' -{@operationsNote} +export const getStaticProps = getNpmInfo('typed-document-node') + + These plugins generate a ready-to-use `TypedDocumentNode` (a combination of pre-compiled `DocumentNode` and the TypeScript signature it represents). @@ -10,17 +12,18 @@ With the `typed-document-node` plugin you no longer need to reconfigure, and ins This plugin also generates less boilerplate code for your GraphQL operations. -> Watch [Episode #41 of `graphql.wtf`](https://graphql.wtf/episodes/41-typed-document-node) for a quick introduction to using this plugin with GraphQL Code Generator: + + Watch [Episode #41 of `graphql.wtf`](https://graphql.wtf/episodes/41-typed-document-node) for a quick introduction to + using this plugin with GraphQL Code Generator: + +/> ### Usage example @@ -67,6 +70,6 @@ export const ratesQuery: TypedDocumentNode = { } ``` -> This plugin also requires `typescript` and `typescript-operations`. +This plugin also requires `typescript` and `typescript-operations`. For information about the setup and usage of `TypedDocumentNode`, [please refer to the library's documentation](https://github.com/dotansimha/graphql-typed-document-node). diff --git a/website/docs-templates/typescript-apollo-angular.md b/website/src/pages/plugin-hub/typescript/typescript-apollo-angular.mdx similarity index 63% rename from website/docs-templates/typescript-apollo-angular.md rename to website/src/pages/plugin-hub/typescript/typescript-apollo-angular.mdx index 9b9840355c9..c5e6635e2ba 100644 --- a/website/docs-templates/typescript-apollo-angular.md +++ b/website/src/pages/plugin-hub/typescript/typescript-apollo-angular.mdx @@ -1,10 +1,11 @@ ---- -id: typescript-apollo-angular ---- +import Callout from 'nextra-theme-docs/callout' +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' -{@operationsNote} +export const getStaticProps = getNpmInfo('typescript-apollo-angular') -{@apiDocs} + + ## How to use? @@ -22,7 +23,7 @@ query MyFeed { Using `graphql-codegen` you can generate a file with Angular services that you can use when coding an Angular component: ```yaml -# ... +# … generates: path/to/output.ts: plugins: @@ -35,7 +36,7 @@ Then, use it: ```ts import { MyFeedGQL, MyFeedQuery } from './graphql' -//BE SURE TO USE Observable from rxjs and not from @apollo/client/core when using map +// BE SURE TO USE Observable from rxjs and not from @apollo/client/core when using map import { Observable } from 'rxjs' import { map } from 'rxjs/operators' @@ -59,9 +60,9 @@ export class FeedComponent { #### `@NgModule` directive -All generated services are defined with `@Injectable({ providedIn: 'root' })` and in most cases you don't need to overwrite it, because providing a service to the root injector is highly recommended. To customize that behavior you can use `@NgModule` directive, anywhere in an operation, to let the codegen know which injector should it use to create a service. +All generated services are defined with `@Injectable({ providedIn: 'root' }){:ts}` and in most cases you don't need to overwrite it, because providing a service to the root injector is highly recommended. To customize that behavior you can use `@NgModule` directive, anywhere in an operation, to let the codegen know which injector should it use to create a service. -> You can't use multiple `@NgModule` directives in the same operation +You can't use multiple `@NgModule` directives in the same operation ```graphql query feed { @@ -76,7 +77,7 @@ query feed { Sometimes you end up with multiple Apollo clients, which means part of operations can't use the defaults. In order to customize that behavior you simply attach the `@namedClient` directive and the `typescript-apollo-angular` plugin takes care of the rest. -> You can't use multiple `@namedClient` directives in the same operation +You can't use multiple `@namedClient` directives in the same operation ```graphql query feed { diff --git a/website/docs-templates/typescript-apollo-client-helpers.md b/website/src/pages/plugin-hub/typescript/typescript-apollo-client-helpers.mdx similarity index 63% rename from website/docs-templates/typescript-apollo-client-helpers.md rename to website/src/pages/plugin-hub/typescript/typescript-apollo-client-helpers.mdx index eb656bac110..a2224efaeaf 100644 --- a/website/docs-templates/typescript-apollo-client-helpers.md +++ b/website/src/pages/plugin-hub/typescript/typescript-apollo-client-helpers.mdx @@ -1,20 +1,27 @@ ---- -id: typescript-apollo-client-helpers ---- +import Callout from 'nextra-theme-docs/callout' +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' + +export const getStaticProps = getNpmInfo('typescript-apollo-client-helpers') + + This plugin generates helpers for improving the integration of TypeScript and Apollo-Client, based on your schema. -> Note: this plugin generates code that intended for `apollo-client` @ `> v3` only. +Note: this plugin generates code that intended for `apollo-client` @ `> v3` only. This plugin generates fully-typed `keyFields` and Type-Policies for Apollo-Client. -> [You can read more about type-policies in Apollo Cache here](https://apollographql.com/docs/react/caching/cache-configuration/#typepolicy-fields) + + [You can read more about type-policies in Apollo Cache + here](https://apollographql.com/docs/react/caching/cache-configuration/#typepolicy-fields) + ### How to use? Start by adding this plugin to your configuration: -```yaml +```yaml {5} schema: my-schema.graphql generates: apollo-helpers.ts: @@ -24,7 +31,7 @@ generates: Then, use the generated TypeScript `type` as your signature for `typePolicies`: -```ts +```ts /StrictTypedTypePolicies/2 import { StrictTypedTypePolicies } from './apollo-helpers' const typePolicies: StrictTypedTypePolicies = { @@ -48,4 +55,4 @@ const typePolicies: StrictTypedTypePolicies = { const cache = new InMemoryCache({ typePolicies }) ``` -{@apiDocs} + diff --git a/website/docs-templates/typescript-apollo-next.md b/website/src/pages/plugin-hub/typescript/typescript-apollo-next.mdx similarity index 90% rename from website/docs-templates/typescript-apollo-next.md rename to website/src/pages/plugin-hub/typescript/typescript-apollo-next.mdx index 035c2e26cd4..141b8ea412e 100644 --- a/website/docs-templates/typescript-apollo-next.md +++ b/website/src/pages/plugin-hub/typescript/typescript-apollo-next.mdx @@ -1,8 +1,9 @@ ---- -id: typescript-apollo-next ---- +import { PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' -{@operationsNote} +export const getStaticProps = getNpmInfo('typescript-apollo-next') + + This plugin generates: @@ -14,7 +15,7 @@ It extends the basic TypeScript plugins: `@graphql-codegen/typescript`, `@graphq ## Motivations -Nextjs recently introduced `getServerSideProps` and `getStaticProps` which doesn't allow to use the HOC pattern adopted by the official apollo graphql plugin (based on `getInitialProps`). At the same time the SSR method offered by apollo client (`getDataFromTree`) enforces the React app to render multiple times in order to collect and fetch all the relevant queries. +Next.js recently introduced `getServerSideProps` and `getStaticProps` which doesn't allow to use the HOC pattern adopted by the official apollo graphql plugin (based on `getInitialProps`). At the same time the SSR method offered by apollo client (`getDataFromTree`) enforces the React app to render multiple times in order to collect and fetch all the relevant queries. By declaring a top level query we can save rendering time and provide a simpler pattern which works with `getServerSideProps`. Note that this pattern requires each SSR query to run at top level. [Example](https://github.com/correttojs/graphql-codegen-apollo-next-ssr/tree/master/example) ## API Reference @@ -56,7 +57,7 @@ Sets the version of react-apollo. #### Usage Examples -```yaml +```yaml {8} generates: path/to/file.ts: plugins: @@ -76,7 +77,7 @@ Customized the output by enabling/disabling the HOC. #### Usage Examples -```yaml +```yaml {8} generates: path/to/file.ts: plugins: @@ -96,7 +97,7 @@ Customized the output by enabling/disabling the generated React Hooks. #### Usage Examples -```yaml +```yaml {8} generates: path/to/file.ts: plugins: @@ -154,14 +155,14 @@ This is useful if you want to use modules other than `graphql-tag`, e.g. `graphq ##### graphql.macro -```yaml +```yaml {2} config: gqlImport: graphql.macro#gql ``` ##### Gatsby -```yaml +```yaml {2} config: gqlImport: gatsby#graphql ``` @@ -254,13 +255,13 @@ This config should be used if `documentMode` is `external`. This has 2 usage: #### Usage Examples -```yaml +```yaml {3} config: documentMode: external importDocumentNodeExternallyFrom: path/to/document-node-file ``` -```yaml +```yaml {3} config: documentMode: external importDocumentNodeExternallyFrom: near-operation-file @@ -274,7 +275,7 @@ Extends or overrides the built-in scalars and custom GraphQL scalars to a custom #### Usage Examples -```yaml +```yaml {2-4} config: scalars: DateTime: Date @@ -298,14 +299,14 @@ which is to preserve underscores. ##### Override All Names -```yaml +```yaml {2} config: namingConvention: change-case-all#lowerCase ``` ##### Upper-case enum values -```yaml +```yaml {4} config: namingConvention: typeNames: change-case-all#pascalCase @@ -314,14 +315,14 @@ config: ##### Keep names as is -```yaml +```yaml {2} config: namingConvention: keep ``` ##### Remove Underscores -```yaml +```yaml {4} config: namingConvention: typeNames: change-case-all#pascalCase @@ -337,7 +338,7 @@ Prefixes all the generated types. #### Usage Examples -```yaml +```yaml {2} config: typesPrefix: I ``` @@ -351,7 +352,7 @@ Does not add `__typename` to the generated types, unless it was specified in the #### Usage Examples -```yaml +```yaml {2} config: skipTypename: true ``` @@ -362,11 +363,11 @@ type: `boolean` default: `false` Automatically adds `__typename` field to the generated types, even when they are not specified -in the selection set, and makes it non-optional +in the selection set, and makes it non-optional. #### Usage Examples -```yaml +```yaml {2} config: nonOptionalTypename: true ``` diff --git a/website/docs-templates/typescript-document-nodes.md b/website/src/pages/plugin-hub/typescript/typescript-document-nodes.mdx similarity index 65% rename from website/docs-templates/typescript-document-nodes.md rename to website/src/pages/plugin-hub/typescript/typescript-document-nodes.mdx index 3369f030d60..540d3fbc174 100644 --- a/website/docs-templates/typescript-document-nodes.md +++ b/website/src/pages/plugin-hub/typescript/typescript-document-nodes.mdx @@ -1,8 +1,10 @@ ---- -id: typescript-document-nodes ---- +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' -{@apiDocs} +export const getStaticProps = getNpmInfo('typescript-document-nodes') + + + ## Usage diff --git a/website/src/pages/plugin-hub/typescript/typescript-generic-sdk.mdx b/website/src/pages/plugin-hub/typescript/typescript-generic-sdk.mdx new file mode 100644 index 00000000000..4ffa72d8344 --- /dev/null +++ b/website/src/pages/plugin-hub/typescript/typescript-generic-sdk.mdx @@ -0,0 +1,15 @@ +import Callout from 'nextra-theme-docs/callout' +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' + +export const getStaticProps = getNpmInfo('typescript-generic-sdk') + + + +Make sure you have `typescript` plugin and `typescript-operations` as well in your configuration: + + + +## Usage + +You can find a usage [example for Apollo-Client here](https://gist.github.com/akozhemiakin/731b0c1e99eb89b01f80f08f9146b6b6). diff --git a/website/docs-templates/typescript-graphql-files-modules.md b/website/src/pages/plugin-hub/typescript/typescript-graphql-files-modules.mdx similarity index 73% rename from website/docs-templates/typescript-graphql-files-modules.md rename to website/src/pages/plugin-hub/typescript/typescript-graphql-files-modules.mdx index 88dae102dce..fca7cab17cc 100644 --- a/website/docs-templates/typescript-graphql-files-modules.md +++ b/website/src/pages/plugin-hub/typescript/typescript-graphql-files-modules.mdx @@ -1,16 +1,23 @@ ---- -id: typescript-graphql-files-modules ---- +import Callout from 'nextra-theme-docs/callout' +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' + +export const getStaticProps = getNpmInfo('typescript-graphql-files-modules') + + + + +**Webpack Integration** -:::note Webpack Integration If you wish to have a simpler integration in a Webpack project, use [`graphql-let`](https://github.com/piglovesyou/graphql-let), it uses this plugin behind the scenes, and provides simpler developer experience. -::: + + ## Pre-Requirements To use this template, make sure you are using [`graphql-tag/loader`](https://github.com/apollographql/graphql-tag#webpack-preprocessing-with-graphql-tagloader) with Webpack. -{@apiDocs} + ## Example diff --git a/website/docs-templates/typescript-graphql-request.md b/website/src/pages/plugin-hub/typescript/typescript-graphql-request.mdx similarity index 86% rename from website/docs-templates/typescript-graphql-request.md rename to website/src/pages/plugin-hub/typescript/typescript-graphql-request.mdx index ca760f776c0..64d42cfdc1a 100644 --- a/website/docs-templates/typescript-graphql-request.md +++ b/website/src/pages/plugin-hub/typescript/typescript-graphql-request.mdx @@ -1,12 +1,14 @@ ---- -id: typescript-graphql-request ---- +import Callout from 'nextra-theme-docs/callout' +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' -{@operationsNote} +export const getStaticProps = getNpmInfo('typescript-graphql-request') -> Make sure you have `typescript` plugin and `typescript-operations` as well in your configuration: + -{@apiDocs} +Make sure you have `typescript` plugin and `typescript-operations` as well in your configuration: + + ## Usage Example diff --git a/website/docs-templates/typescript-mongodb.md b/website/src/pages/plugin-hub/typescript/typescript-mongodb.mdx similarity index 91% rename from website/docs-templates/typescript-mongodb.md rename to website/src/pages/plugin-hub/typescript/typescript-mongodb.mdx index 3541c9a4a15..a508313ddca 100644 --- a/website/docs-templates/typescript-mongodb.md +++ b/website/src/pages/plugin-hub/typescript/typescript-mongodb.mdx @@ -1,6 +1,14 @@ ---- -id: typescript-mongodb ---- +import Callout from 'nextra-theme-docs/callout' +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' + +export const getStaticProps = getNpmInfo('typescript-mongodb') + + + + + Don't install this plugin as `devDependency`, because you need to import the directives from it. + This plugin generates TypeScript types for MongoDB models, which makes it relevant for server-side development only. It uses GraphQL directives to declare the types you want to generate and use in your MongoDB backend. @@ -30,15 +38,13 @@ export interface UserDbObject { This interface can be used for db read/write purposes, thus making communication with the db much more consistent. -> Don't install this plugin as devDependency, because you need to import the directives from it. - -{@apiDocs} + ## Usage Example Once installed, add the directives declaration to your GraphQL Schema definition: -```typescript +```ts import { makeExecutableSchema } from '@graphql-tools/schema' import { DIRECTIVES } from '@graphql-codegen/typescript-mongodb' @@ -94,7 +100,9 @@ Use this directive to declare a specific GraphQL field as part of your generated - `overrideType: String` - use this to override the type of the field; for example, if you store dates as `Date` but expose them as `String`. -> ⚠ If target property is an embedded entity, you should use `@embedded` instead. + + If target property is an embedded entity, you should use `@embedded` instead. + #### `@id` (on `FIELD_DEFINITION`) @@ -154,7 +162,7 @@ type TextNotification implements BaseNotification @entity { This way, you will get: -```typescript +```ts export interface BaseNotificationDbInterface { notificationType: string _id: ObjectId diff --git a/website/docs-templates/typescript-msw.md b/website/src/pages/plugin-hub/typescript/typescript-msw.mdx similarity index 53% rename from website/docs-templates/typescript-msw.md rename to website/src/pages/plugin-hub/typescript/typescript-msw.mdx index 00ca30bbd85..341aa7d6d74 100644 --- a/website/docs-templates/typescript-msw.md +++ b/website/src/pages/plugin-hub/typescript/typescript-msw.mdx @@ -1,12 +1,14 @@ ---- -id: typescript-msw ---- +import Callout from 'nextra-theme-docs/callout' +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' -{@operationsNote} +export const getStaticProps = getNpmInfo('typescript-msw') -> Make sure you have `typescript` plugin and `typescript-operations` as well in your configuration: + -{@apiDocs} +Make sure you have `typescript` plugin and `typescript-operations` as well in your configuration: + + ### Usage @@ -32,7 +34,7 @@ const worker = setupWorker( return res( ctx.data({ - getUser: { name: 'John Doe', id: id } + getUser: { name: 'John Doe', id } }) ) }) diff --git a/website/docs-templates/typescript-oclif.md b/website/src/pages/plugin-hub/typescript/typescript-oclif.mdx similarity index 94% rename from website/docs-templates/typescript-oclif.md rename to website/src/pages/plugin-hub/typescript/typescript-oclif.mdx index 4cfd6fb73f2..fe2d8e1e554 100644 --- a/website/docs-templates/typescript-oclif.md +++ b/website/src/pages/plugin-hub/typescript/typescript-oclif.mdx @@ -1,12 +1,14 @@ ---- -id: typescript-oclif ---- +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' -This plugin generates [`oclif`](https://npmjs.com/package/oclif) CLI commands. +export const getStaticProps = getNpmInfo('typescript-oclif') + + + -{@operationsNote} +This plugin generates [`oclif`](https://npmjs.com/package/oclif) CLI commands. -The, make sure you have `typescript` plugin as well in your configuration: +Then, make sure you have `typescript` plugin as well in your configuration: ```yaml schema: http://localhost:4000 @@ -81,9 +83,7 @@ by the codegen. To get started quickly and easily, consider using the simple `graphql-request` as your handler: -```ts -// handler.ts - +```ts filename="handler.ts" import { GraphQLClient } from 'graphql-request' import { Command } from '@oclif/command' @@ -149,7 +149,7 @@ necessary `oclif` command files. With that complete, follow the directions in th You can add descriptions and examples for your commands via `typescript-oclif` with the `@oclif` client-side directive, like so: -```gql +```graphql mutation CreateAuthor($name: String!) @oclif( description: "Create a new author" diff --git a/website/src/pages/plugin-hub/typescript/typescript-operations.mdx b/website/src/pages/plugin-hub/typescript/typescript-operations.mdx new file mode 100644 index 00000000000..175d98317a5 --- /dev/null +++ b/website/src/pages/plugin-hub/typescript/typescript-operations.mdx @@ -0,0 +1,7 @@ +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' + +export const getStaticProps = getNpmInfo('typescript-operations') + + + diff --git a/website/docs-templates/typescript-react-apollo.md b/website/src/pages/plugin-hub/typescript/typescript-react-apollo.mdx similarity index 69% rename from website/docs-templates/typescript-react-apollo.md rename to website/src/pages/plugin-hub/typescript/typescript-react-apollo.mdx index 1bdd7d25780..7bbe7bddd58 100644 --- a/website/docs-templates/typescript-react-apollo.md +++ b/website/src/pages/plugin-hub/typescript/typescript-react-apollo.mdx @@ -1,10 +1,11 @@ ---- -id: typescript-react-apollo ---- +import Callout from 'nextra-theme-docs/callout' +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' -{@operationsNote} +export const getStaticProps = getNpmInfo('typescript-react-apollo') -{@apiDocs} + + ## Usage Example @@ -51,7 +52,7 @@ import { useTest } from './generated-types' export const MyComponent: React.FC = () => { const { data, error, loading } = useTest() - return
        ...
        + return
        } ``` @@ -73,14 +74,15 @@ config: withHOC: true ``` -> Watch [Episode #29 of `graphql.wtf`](https://graphql.wtf/episodes/29-apollo-client-3-with-graphql-code-generator) for a quick introduction to using this plugin with GraphQL Code Generator: + + Watch [Episode #29 of `graphql.wtf`](https://graphql.wtf/episodes/29-apollo-client-3-with-graphql-code-generator) for + a quick introduction to using this plugin with GraphQL Code Generator: + +/> diff --git a/website/docs-templates/typescript-react-query.md b/website/src/pages/plugin-hub/typescript/typescript-react-query.mdx similarity index 88% rename from website/docs-templates/typescript-react-query.md rename to website/src/pages/plugin-hub/typescript/typescript-react-query.mdx index 32f83201e15..12b014940eb 100644 --- a/website/docs-templates/typescript-react-query.md +++ b/website/src/pages/plugin-hub/typescript/typescript-react-query.mdx @@ -1,14 +1,18 @@ ---- -id: typescript-react-query ---- +import Callout from 'nextra-theme-docs/callout' +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' -{@operationsNote} +export const getStaticProps = getNpmInfo('typescript-react-query') -{@apiDocs} + + ## Usage Examples -> Note: all generated hooks are just wrappers around `react-query` original functions. This codegen plugin just burns the generated TypeScript types into the operation, and provides flexibility to choose your `fetcher`. + + Note: all generated hooks are just wrappers around `react-query` original functions. This codegen plugin just burns + the generated TypeScript types into the operation, and provides flexibility to choose your `fetcher`. + ### Using default `fetch` @@ -160,7 +164,7 @@ generates: As a shortcut, the `fetcher` property may also directly contain the function as a mapper string: ```yaml -#... +# … config: fetcher: './my-file#myFetcher' # isReactHook is false here (the default version) ``` @@ -199,7 +203,7 @@ export const fetchData = ( method: 'POST', headers: { 'Content-Type': 'application/json', - ...(options ?? {}) + ...options }, body: JSON.stringify({ query, @@ -210,8 +214,8 @@ export const fetchData = ( const json = await res.json() if (json.errors) { - const { message } = json.errors[0] || 'Error..' - throw new Error(message) + const { message } = json.errors[0] || {} + throw new Error(message || 'Error…') } return json.data @@ -235,7 +239,7 @@ export const useFetchData = ( headers: { 'Content-Type': 'application/json', ...headers, - ...(options ?? {}) + ...options }, body: JSON.stringify({ query, @@ -246,8 +250,8 @@ export const useFetchData = ( const json = await res.json() if (json.errors) { - const { message } = json.errors[0] || 'Error..' - throw new Error(message) + const { message } = json.errors[0] || {} + throw new Error(message || 'Error…') } return json.data @@ -255,7 +259,9 @@ export const useFetchData = ( } ``` -> Note: The return value is an async function, with no params, that returns a `Promise` with the actual data. + + Note: The return value is an async function, with no params, that returns a `Promise` with the actual data. + ### Using Infinite Query @@ -265,15 +271,15 @@ To use this you need to return an object of new queries, and it blends them in t #### Usage example (`addInfiniteQuery: true`) -with the following query +with the following query: ```graphql query AnimalsQuery($catsRange: Int, $catsStarting: Int, $dogsRange: Int, $dogsStarting: Int) { cats(range: $catsRange, starting: $catsStarting) { - # ... + # … } dogs(range: $dogsRange, starting: $dogsStarting) { - # ... + # … } } ``` diff --git a/website/docs-templates/typescript-resolvers.md b/website/src/pages/plugin-hub/typescript/typescript-resolvers.mdx similarity index 76% rename from website/docs-templates/typescript-resolvers.md rename to website/src/pages/plugin-hub/typescript/typescript-resolvers.mdx index 03531bcdc12..ba321a63407 100644 --- a/website/docs-templates/typescript-resolvers.md +++ b/website/src/pages/plugin-hub/typescript/typescript-resolvers.mdx @@ -1,20 +1,39 @@ ---- -id: typescript-resolvers ---- +import Callout from 'nextra-theme-docs/callout' +import { PackageApiDocs, PackageHeader } from '@/components' +import { getNpmInfo } from '@/lib/get-npm-info' -> Watch [Episode #26 of `graphql.wtf`](https://graphql.wtf/episodes/26-type-safe-resolvers-with-graphql-code-generator) for a quick introduction to this plugin and its features: +export const getStaticProps = getNpmInfo('typescript-resolvers') - + -> [More weekly episodes are available in `graphql.wtf`](https://graphql.wtf/) by [Jamie Barton](https://twitter.com/notrab). + + Watch [Episode #26 of `graphql.wtf`](https://graphql.wtf/episodes/26-type-safe-resolvers-with-graphql-code-generator) + for a quick introduction to this plugin and its features: + -{@apiDocs} +