Skip to content

Commit

Permalink
Read codegen documents from user GraphQL config (#1577)
Browse files Browse the repository at this point in the history
* Get codegen documents from user config if available

* Update GraphQL config in skeleton to support changing document locations

* Changesets

* Changesets

* Show gql document globs in success banner after codegen

* Simplify document patterns in skeleton

* Changesets

* Refactor
  • Loading branch information
frandiox committed Dec 15, 2023
1 parent fddabae commit 8c477cb
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .changeset/brown-lobsters-marry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@shopify/cli-hydrogen': minor
---

When generating Codegen, the CLI now looks first at the project GraphQL config (e.g. `.graphqlrc.yml` file) to find the documents for the Storefront API schema.
26 changes: 26 additions & 0 deletions .changeset/grumpy-lemons-drive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
'skeleton': patch
---

Updated the GraphQL config in `.graphqlrc.yml` to use the more modern `projects` structure:

```diff
-schema: node_modules/@shopify/hydrogen/storefront.schema.json
+projects:
+ default:
+ schema: 'node_modules/@shopify/hydrogen/storefront.schema.json'
```

This allows you to add additional projects to the GraphQL config, such as third party CMS schemas.

Also, you can modify the document paths used for the Storefront API queries. This is useful if you have a large codebase and want to exclude certain files from being used for codegen or other GraphQL utilities:

```yaml
projects:
default:
schema: 'node_modules/@shopify/hydrogen/storefront.schema.json'
documents:
- '!*.d.ts'
- '*.{ts,tsx,js,jsx}'
- 'app/**/*.{ts,tsx,js,jsx}'
```
2 changes: 2 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"diff": "^5.1.0",
"fs-extra": "^11.1.0",
"get-port": "^7.0.0",
"graphql-config": "5.0.3",
"gunzip-maybe": "^1.4.2",
"miniflare": "3.20231016.0",
"prettier": "^2.8.4",
Expand Down
12 changes: 11 additions & 1 deletion packages/cli/src/commands/hydrogen/codegen.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import path from 'path';
import Command from '@shopify/cli-kit/node/base-command';
import {renderSuccess} from '@shopify/cli-kit/node/ui';
import colors from '@shopify/cli-kit/node/colors';
import {Flags} from '@oclif/core';
import {getProjectPaths, getRemixConfig} from '../../lib/remix-config.js';
import {commonFlags, flagsToCamelObject} from '../../lib/flags.js';
Expand Down Expand Up @@ -69,7 +70,16 @@ export async function runCodegen({
if (!watch) {
renderSuccess({
headline: 'Generated types for GraphQL:',
body: generatedFiles.map((file) => `- ${file}`).join('\n'),
body: {
list: {
items: Object.entries(generatedFiles).map(
([key, value]) =>
key +
'\n' +
value.map((item) => colors.dim(`- ${item}`)).join('\n'),
),
},
},
});
}
}
41 changes: 36 additions & 5 deletions packages/cli/src/lib/codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import {spawn} from 'node:child_process';
import {fileURLToPath} from 'node:url';
import {formatCode, getCodeFormatOptions} from './format-code.js';
import {renderFatalError, renderWarning} from '@shopify/cli-kit/node/ui';
import {joinPath, relativePath} from '@shopify/cli-kit/node/path';
import {joinPath, relativePath, basename} from '@shopify/cli-kit/node/path';
import {AbortError} from '@shopify/cli-kit/node/error';

// Do not import code synchronously from this dependency, it must be patched first
import type {LoadCodegenConfigResult} from '@graphql-codegen/cli';
import type {GraphQLConfig} from 'graphql-config';

const nodePath = process.argv[1];
const modulePath = fileURLToPath(import.meta.url);
Expand Down Expand Up @@ -160,17 +161,36 @@ async function generateTypes({

await generate(codegenContext, true);

return Object.keys(codegenConfig.generates);
return Object.entries(codegenConfig.generates).reduce((acc, [key, value]) => {
if ('documents' in value) {
acc[key] = (
Array.isArray(value.documents) ? value.documents : [value.documents]
).filter((document) => typeof document === 'string') as string[];
}

return acc;
}, {} as Record<string, string[]>);
}

async function generateDefaultConfig(
{rootDirectory, appDirectory}: ProjectDirs,
forceSfapiVersion?: string,
): Promise<LoadCodegenConfigResult> {
const {schema, preset, pluckConfig} = await import(
const {getSchema, preset, pluckConfig} = await import(
'@shopify/hydrogen-codegen'
);

const {loadConfig} = await import('graphql-config');
const gqlConfig = await loadConfig({
rootDir: rootDirectory,
throwOnEmpty: false,
throwOnMissing: false,
legacy: false,
}).catch(() => undefined);

const sfapiSchema = getSchema('storefront');
const sfapiProject = findGqlProject(sfapiSchema, gqlConfig);

const defaultGlob = '*!(*.d).{ts,tsx,js,jsx}'; // No d.ts files
const appDirRelative = relativePath(rootDirectory, appDirectory);

Expand All @@ -182,8 +202,8 @@ async function generateDefaultConfig(
generates: {
['storefrontapi.generated.d.ts']: {
preset,
schema,
documents: [
schema: sfapiSchema,
documents: sfapiProject?.documents ?? [
defaultGlob, // E.g. ./server.(t|j)s
joinPath(appDirRelative, '**', defaultGlob), // E.g. app/routes/_index.(t|j)sx
],
Expand Down Expand Up @@ -213,6 +233,17 @@ async function generateDefaultConfig(
};
}

function findGqlProject(schemaFilepath: string, gqlConfig?: GraphQLConfig) {
if (!gqlConfig) return;

const schemaFilename = basename(schemaFilepath);
return Object.values(gqlConfig.projects || {}).find(
(project) =>
typeof project.schema === 'string' &&
project.schema.endsWith(schemaFilename),
) as GraphQLConfig['projects'][number];
}

async function addHooksToHydrogenOptions(
codegenConfig: LoadCodegenConfigResult['config'],
{rootDirectory}: ProjectDirs,
Expand Down
8 changes: 7 additions & 1 deletion templates/skeleton/.graphqlrc.yml
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
schema: node_modules/@shopify/hydrogen-react/storefront.schema.json
projects:
default:
schema: 'node_modules/@shopify/hydrogen/storefront.schema.json'
documents:
- '!*.d.ts'
- '*.{ts,tsx,js,jsx}'
- 'app/**/*.{ts,tsx,js,jsx}'

0 comments on commit 8c477cb

Please sign in to comment.