From aa23d1ea769e2cc2756843a270dbc847436a3e18 Mon Sep 17 00:00:00 2001 From: Matthew Volk Date: Thu, 14 Mar 2024 13:03:58 -0500 Subject: [PATCH] feat(cli): create graphql schema using gql.tada --- .github/workflows/basic.yml | 3 + apps/core/codegen.ts | 56 +------------------ apps/core/package.json | 4 +- apps/core/scripts/generate.cjs | 52 +++++++++++++++++ .../create-catalyst/src/commands/create.ts | 6 ++ pnpm-lock.yaml | 19 ++++--- 6 files changed, 75 insertions(+), 65 deletions(-) create mode 100644 apps/core/scripts/generate.cjs diff --git a/.github/workflows/basic.yml b/.github/workflows/basic.yml index 9fd01c1a2..5cbd13679 100644 --- a/.github/workflows/basic.yml +++ b/.github/workflows/basic.yml @@ -38,6 +38,9 @@ jobs: - name: Install dependencies run: pnpm install --frozen-lockfile + - name: Graphql Tada + run: pnpm run -r generate + - name: Graphql Codegen run: pnpm run -r codegen diff --git a/apps/core/codegen.ts b/apps/core/codegen.ts index bbf049234..e40815ab1 100644 --- a/apps/core/codegen.ts +++ b/apps/core/codegen.ts @@ -1,57 +1,7 @@ import { CodegenConfig } from '@graphql-codegen/cli'; -export const graphqlApiDomain: string = - process.env.BIGCOMMERCE_GRAPHQL_API_DOMAIN ?? 'mybigcommerce.com'; - -const getToken = () => { - const token = process.env.BIGCOMMERCE_CUSTOMER_IMPERSONATION_TOKEN; - - if (!token) { - throw new Error('Missing customer impersonation token'); - } - - return token; -}; - -const getStoreHash = () => { - const storeHash = process.env.BIGCOMMERCE_STORE_HASH; - - if (!storeHash) { - throw new Error('Missing store hash'); - } - - return storeHash; -}; - -const getChannelId = () => { - const channelId = process.env.BIGCOMMERCE_CHANNEL_ID; - - return channelId; -}; - -const getEndpoint = () => { - const storeHash = getStoreHash(); - const channelId = getChannelId(); - - // Not all sites have the channel-specific canonical URL backfilled. - // Wait till MSF-2643 is resolved before removing and simplifying the endpoint logic. - if (!channelId || channelId === '1') { - return `https://store-${storeHash}.${graphqlApiDomain}/graphql`; - } - - return `https://store-${storeHash}-${channelId}.${graphqlApiDomain}/graphql`; -}; - const config: CodegenConfig = { - schema: [ - { - [getEndpoint()]: { - headers: { - Authorization: `Bearer ${getToken()}`, - }, - }, - }, - ], + schema: './schema.graphql', documents: ['client/queries/**/*.ts', 'client/mutations/**/*.ts', 'client/fragments/**/*.ts'], generates: { './client/generated/': { @@ -71,10 +21,6 @@ const config: CodegenConfig = { }, }, }, - './schema.graphql': { - plugins: ['schema-ast'], - watchPattern: '', - }, }, }; diff --git a/apps/core/package.json b/apps/core/package.json index 93a0ab06e..eca5a0e25 100644 --- a/apps/core/package.json +++ b/apps/core/package.json @@ -8,6 +8,7 @@ "dev-next": "next dev", "dev-codegen": "dotenv -e .env.local -- npm run codegen -- -w", "codegen": "dotenv -e .env.local -- gql-gen --errors-only --config codegen.ts", + "generate": "dotenv -e .env.local -- node ./scripts/generate.cjs", "build": "npm run codegen && next build", "start": "next start", "lint": "next lint", @@ -23,7 +24,7 @@ "@vercel/kv": "^1.0.0", "@vercel/speed-insights": "^1.0.1", "clsx": "^2.0.0", - "gql.tada": "^1.3.2", + "gql.tada": "^1.3.5", "graphql": "^16.8.1", "lodash.debounce": "^4.0.8", "lucide-react": "^0.294.0", @@ -44,6 +45,7 @@ "devDependencies": { "@0no-co/graphqlsp": "^1.5.0", "@bigcommerce/eslint-config-catalyst": "workspace:^", + "@gql.tada/cli-utils": "^0.2.0", "@graphql-codegen/cli": "^5.0.0", "@graphql-codegen/client-preset": "^4.1.0", "@graphql-codegen/schema-ast": "^4.0.0", diff --git a/apps/core/scripts/generate.cjs b/apps/core/scripts/generate.cjs new file mode 100644 index 000000000..3c7cb35d2 --- /dev/null +++ b/apps/core/scripts/generate.cjs @@ -0,0 +1,52 @@ +const { generateSchema, generateTadaTypes } = require('@gql.tada/cli-utils'); + +const graphqlApiDomain = process.env.BIGCOMMERCE_GRAPHQL_API_DOMAIN ?? 'mybigcommerce.com'; + +const getStoreHash = () => { + const storeHash = process.env.BIGCOMMERCE_STORE_HASH; + + if (!storeHash) { + throw new Error('Missing store hash'); + } + + return storeHash; +}; + +const getChannelId = () => { + const channelId = process.env.BIGCOMMERCE_CHANNEL_ID; + + return channelId; +}; + +const getToken = () => { + const token = process.env.BIGCOMMERCE_CUSTOMER_IMPERSONATION_TOKEN; + + if (!token) { + throw new Error('Missing customer impersonation token'); + } + + return token; +}; + +const getEndpoint = () => { + const storeHash = getStoreHash(); + const channelId = getChannelId(); + + // Not all sites have the channel-specific canonical URL backfilled. + // Wait till MSF-2643 is resolved before removing and simplifying the endpoint logic. + if (!channelId || channelId === '1') { + return `https://store-${storeHash}.${graphqlApiDomain}/graphql`; + } + + return `https://store-${storeHash}-${channelId}.${graphqlApiDomain}/graphql`; +}; + +const generate = async () => { + await generateSchema(getEndpoint(), { + headers: { Authorization: `Bearer ${getToken()}` }, + }); + + await generateTadaTypes(); +}; + +generate(); diff --git a/packages/create-catalyst/src/commands/create.ts b/packages/create-catalyst/src/commands/create.ts index 4e3e3c06d..f14fdafb9 100644 --- a/packages/create-catalyst/src/commands/create.ts +++ b/packages/create-catalyst/src/commands/create.ts @@ -198,6 +198,12 @@ export const create = async (options: CreateCommandOptions) => { await installDependencies(projectDir, packageManager); + await spinner(exec(`${packageManager} run generate`, { cwd: projectDir }), { + text: 'Creating GraphQL schema...', + successText: 'Created GraphQL schema', + failText: (err) => chalk.red(`Failed to create GraphQL schema: ${err.message}`), + }); + await spinner(exec(`${packageManager} run codegen`, { cwd: projectDir }), { text: 'Generating GraphQL types...', successText: 'GraphQL types generated successfully', diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 90e912c39..ce6ae485c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -54,8 +54,8 @@ importers: specifier: ^2.0.0 version: 2.0.0 gql.tada: - specifier: ^1.3.2 - version: 1.3.3(graphql@16.8.1) + specifier: ^1.3.5 + version: 1.3.5(graphql@16.8.1) graphql: specifier: ^16.8.1 version: 16.8.1 @@ -111,6 +111,9 @@ importers: '@bigcommerce/eslint-config-catalyst': specifier: workspace:^ version: link:../../packages/eslint-config-catalyst + '@gql.tada/cli-utils': + specifier: ^0.2.0 + version: 0.2.0 '@graphql-codegen/cli': specifier: ^5.0.0 version: 5.0.0(@parcel/watcher@2.3.0)(@types/node@18.19.3)(graphql@16.8.1) @@ -2785,12 +2788,11 @@ packages: tslib: 2.6.2 dev: false - /@gql.tada/cli-utils@0.1.1: - resolution: {integrity: sha512-UwT7N1hY3WVUeqeq80MoRovV2mqqu4A8dUEcZThC5KklIYlvxOux6ql3XqKTV1dd9Sva8uCfm+Eym2i7eMFeEg==} + /@gql.tada/cli-utils@0.2.0: + resolution: {integrity: sha512-S/1KdJ08G9wKbsHUrBBT6GK38OtGaC82lY9MIFwkIziR9rf/N1PmDxWOThvMWJsaKQaEf5PhioRxquVCjeIbtw==} dependencies: '@urql/introspection': 1.0.3(graphql@16.8.1) graphql: 16.8.1 - dev: false /@graphql-codegen/add@5.0.0(graphql@16.8.1): resolution: {integrity: sha512-ynWDOsK2yxtFHwcJTB9shoSkUd7YXd6ZE57f0nk7W5cu/nAgxZZpEsnTPEpZB/Mjf14YRGe2uJHQ7AfElHjqUQ==} @@ -6869,7 +6871,6 @@ packages: graphql: ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 dependencies: graphql: 16.8.1 - dev: false /@vercel/analytics@1.1.1: resolution: {integrity: sha512-+NqgNmSabg3IFfxYhrWCfB/H+RCUOCR5ExRudNG2+pcRehq628DJB5e1u1xqwpLtn4pAYii4D98w7kofORAGQA==} @@ -10219,12 +10220,12 @@ packages: dependencies: get-intrinsic: 1.2.2 - /gql.tada@1.3.3(graphql@16.8.1): - resolution: {integrity: sha512-enQSg6FIiK6yvgvTSpvc1qOqu7SzZF0J/9Vsm1LUvDwVoPZMN1sYsrIT19QcO/1UqHg72NpPF7CvyrHAiKvIzw==} + /gql.tada@1.3.5(graphql@16.8.1): + resolution: {integrity: sha512-g5ZtNc72fuOHrrMgxnok6vhDoXMt6Q1RJefiuFzAusHMPR0L3/8a3Yyc2HSfEnHBt+tYBgIrvKmWDYIRNl80jg==} hasBin: true dependencies: '@0no-co/graphql.web': 1.0.4(graphql@16.8.1) - '@gql.tada/cli-utils': 0.1.1 + '@gql.tada/cli-utils': 0.2.0 transitivePeerDependencies: - graphql dev: false