Skip to content

Commit

Permalink
Merge branch 'master' into pr-9136-imports
Browse files Browse the repository at this point in the history
  • Loading branch information
beerose authored Mar 28, 2023
2 parents e444eb8 + 1254249 commit b128a39
Show file tree
Hide file tree
Showing 260 changed files with 3,469 additions and 7,816 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@graphql-codegen/client-preset": patch
---
dependencies updates:
- Updated dependency [`@graphql-typed-document-node/[email protected]` ↗︎](https://www.npmjs.com/package/@graphql-typed-document-node/core/v/3.2.0) (from `3.1.2`, in `dependencies`)
63 changes: 63 additions & 0 deletions .changeset/blue-pans-protect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
'@graphql-codegen/visitor-plugin-common': patch
'@graphql-codegen/typescript-resolvers': patch
---

Fix `ResolversUnionTypes` being used in `ResolversParentTypes`

Previously, objects with mappable fields are converted to Omit format that references its own type group or `ResolversTypes` or `ResolversParentTypes` e.g.

```ts
export type ResolversTypes = {
Book: ResolverTypeWrapper<BookMapper>;
BookPayload: ResolversTypes["BookResult"] | ResolversTypes["StandardError"];
// Note: `result` on the next line references `ResolversTypes["Book"]`
BookResult: ResolverTypeWrapper<Omit<BookResult, "result"> & { result?: Maybe<ResolversTypes["Book"]> }>;
StandardError: ResolverTypeWrapper<StandardError>;
};

export type ResolversParentTypes = {
Book: BookMapper;
BookPayload: ResolversParentTypes["BookResult"] | ResolversParentTypes["StandardError"];
// Note: `result` on the next line references `ResolversParentTypes["Book"]`
BookResult: Omit<BookResult, "result"> & { result?: Maybe<ResolversParentTypes["Book"]> };
StandardError: StandardError;
};
```

In https://github.com/dotansimha/graphql-code-generator/pull/9069, we extracted resolver union types to its own group:

```ts
export type ResolversUnionTypes = {
// Note: `result` on the next line references `ResolversTypes["Book"]` which is only correct for the `ResolversTypes` case
BookPayload: (Omit<BookResult, "result"> & { result?: Maybe<ResolversTypes["Book"]> }) | StandardError;
};

export type ResolversTypes = {
Book: ResolverTypeWrapper<BookMapper>;
BookPayload: ResolverTypeWrapper<ResolversUnionTypes["BookPayload"]>;
BookResult: ResolverTypeWrapper<Omit<BookResult, "result"> & { result?: Maybe<ResolversTypes["Book"]> }>;
StandardError: ResolverTypeWrapper<StandardError>;
};

export type ResolversParentTypes = {
Book: BookMapper;
BookPayload: ResolversUnionTypes["BookPayload"];
BookResult: Omit<BookResult, "result"> & { result?: Maybe<ResolversParentTypes["Book"]> };
StandardError: StandardError;
};
```

This change creates an extra `ResolversUnionParentTypes` that is referenced by `ResolversParentTypes` to ensure backwards compatibility:

```ts
export type ResolversUnionTypes = {
BookPayload: (Omit<BookResult, "result"> & { result?: Maybe<ResolversParentTypes["Book"]> }) | StandardError;
};

// ... and the reference is changed in ResolversParentTypes:
export type ResolversParentTypes = {
// ... other fields
BookPayload: ResolversUnionParentTypes["BookPayload"];
};
```
41 changes: 41 additions & 0 deletions .changeset/brave-papayas-shout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
'@graphql-codegen/plugin-helpers': minor
'@graphql-codegen/cli': minor
---

Add `watchPattern` config option for `generates` sections.

By default, `watch` mode automatically watches all GraphQL schema and document files. This means when a change is detected, Codegen CLI is run.

A user may want to run Codegen CLI when non-schema and non-document files are changed. Each `generates` section now has a `watchPattern` option to allow more file patterns to be added to the list of patterns to watch.

In the example below, mappers are exported from `schema.mappers.ts` files. We want to re-run Codegen if the content of `*.mappers.ts` files change because they change the generated types file. To solve this, we can add mapper file patterns to watch using the glob pattern used for schema and document files.

```ts
// codegen.ts
const config: CodegenConfig = {
schema: 'src/schema/**/*.graphql',
generates: {
'src/schema/types.ts': {
plugins: ['typescript', 'typescript-resolvers'],
config: {
mappers: {
User: './user/schema.mappers#UserMapper',
Book: './book/schema.mappers#BookMapper',
},
}
watchPattern: 'src/schema/**/*.mappers.ts', // Watches mapper files in `watch` mode. Use an array for multiple patterns e.g. `['src/*.pattern1.ts','src/*.pattern2.ts']`
},
},
};
```

Then, run Codegen CLI in `watch` mode:

```shell
yarn graphql-codegen --watch
```

Now, updating `*.mappers.ts` files re-runs Codegen! 🎉

Note: `watchPattern` is only used in `watch` mode i.e. running CLI with `--watch` flag.
5 changes: 5 additions & 0 deletions .changeset/clean-files-begin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphql-codegen/typescript': patch
---

Properly escape enum identifiers when enumsAsConst is used
7 changes: 7 additions & 0 deletions .changeset/gold-dragons-poke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@graphql-codegen/typed-document-node': major
'@graphql-codegen/gql-tag-operations': major
'@graphql-codegen/client-preset': major
---

Add `TypedDocumentNode` string alternative that doesn't require GraphQL AST on the client. This change requires `@graphql-typed-document-node/core` in version `3.2.0` or higher.
5 changes: 5 additions & 0 deletions .changeset/happy-queens-rescue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphql-codegen/testing': patch
---

Add complex test cases for resolvers tests
108 changes: 108 additions & 0 deletions .changeset/spicy-worms-jam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
---
'@graphql-codegen/visitor-plugin-common': minor
'@graphql-codegen/typescript-resolvers': minor
---

[typescript-resolvers] Add `resolversNonOptionalTypename` config option.

This is extending on `ResolversUnionTypes` implemented in https://github.com/dotansimha/graphql-code-generator/pull/9069

`resolversNonOptionalTypename` adds non-optional `__typename` to union members of `ResolversUnionTypes`, without affecting the union members' base intefaces.

A common use case for non-optional `__typename` of union members is using it as the common field to work out the final schema type. This makes implementing the union's `__resolveType` very simple as we can use `__typename` to decide which union member the resolved object is. Without this, we have to check the existence of field/s on the incoming object which could be verbose.

For example, consider this schema:

```graphql
type Query {
book(id: ID!): BookPayload!
}

type Book {
id: ID!
isbn: String!
}

type BookResult {
node: Book
}

type PayloadError {
message: String!
}

union BookPayload = BookResult | PayloadError
```

*With optional `__typename`:* We need to check existence of certain fields to resolve type in the union resolver:

```ts
// Query/book.ts
export const book = async () => {
try {
const book = await fetchBook();
// 1. No `__typename` in resolver results...
return {
node: book
}
} catch(e) {
return {
message: "Failed to fetch book"
}
}
}

// BookPayload.ts
export const BookPayload = {
__resolveType: (parent) => {
// 2. ... means more checks in `__resolveType`
if('message' in parent) {
return 'PayloadError';
}
return 'BookResult'
}
}
```

*With non-optional `__typename`:* Resolvers declare the type. This which gives us better TypeScript support in resolvers and simplify `__resolveType` implementation:

```ts
// Query/book.ts
export const book = async () => {
try {
const book = await fetchBook();
// 1. `__typename` is declared in resolver results...
return {
__typename: 'BookResult', // 1a. this also types `node` for us 🎉
node: book
}
} catch(e) {
return {
__typename: 'PayloadError',
message: "Failed to fetch book"
}
}
}

// BookPayload.ts
export const BookPayload = {
__resolveType: (parent) => parent.__typename, // 2. ... means a very simple check in `__resolveType`
}
```

*Using `resolversNonOptionalTypename`:* add it into `typescript-resolvers` plugin config:

```ts
// codegen.ts
const config: CodegenConfig = {
schema: 'src/schema/**/*.graphql',
generates: {
'src/schema/types.ts': {
plugins: ['typescript', 'typescript-resolvers'],
config: {
resolversNonOptionalTypename: true // Or `resolversNonOptionalTypename: { unionMember: true }`
}
},
},
};
```
1 change: 0 additions & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ body:
- '@graphql-codegen/typed-document-node'
- '@graphql-codegen/typescript'
- '@graphql-codegen/client-preset'
- '@graphql-codegen/gql-tag-operations-preset'
- '@graphql-codegen/graphql-modules-preset'
- '@graphql-codegen/testing'
- '@graphql-codegen/plugin-helpers'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/website.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- uses: the-guild-org/shared-config/setup@main
name: setup env
with:
nodeVersion: 17
nodeVersion: 18
packageManager: yarn

- uses: the-guild-org/shared-config/website-cf@main
Expand Down
18 changes: 6 additions & 12 deletions dev-test/codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,32 +185,26 @@ const config: CodegenConfig = {
documents: './dev-test/star-wars/**/*.graphql',
plugins: ['typescript', 'typescript-operations'],
},
'./dev-test/gql-tag-operations/gql': {
'./dev-test/gql-tag-operations/gql/': {
schema: './dev-test/gql-tag-operations/schema.graphql',
documents: './dev-test/gql-tag-operations/src/**/*.ts',
preset: 'gql-tag-operations-preset',
preset: 'client',
},
'./dev-test/gql-tag-operations/graphql/': {
schema: './dev-test/gql-tag-operations/schema.graphql',
documents: './dev-test/gql-tag-operations/src/**/*.ts',
preset: 'client',
},
'./dev-test/gql-tag-operations-urql/gql': {
'./dev-test/gql-tag-operations-urql/gql/': {
schema: './dev-test/gql-tag-operations-urql/schema.graphql',
documents: './dev-test/gql-tag-operations-urql/src/**/*.ts',
preset: 'gql-tag-operations-preset',
preset: 'client',
presetConfig: { augmentedModuleName: '@urql/core' },
},
'./dev-test/gql-tag-operations-masking/gql': {
'./dev-test/gql-tag-operations-masking/gql/': {
schema: './dev-test/gql-tag-operations-masking/schema.graphql',
documents: './dev-test/gql-tag-operations-masking/src/**/*.tsx',
preset: 'gql-tag-operations-preset',
presetConfig: { fragmentMasking: true },
},
'./dev-test/gql-tag-operations-masking-star-wars/gql': {
schema: './dev-test/gql-tag-operations-masking-star-wars/schema.json',
documents: './dev-test/gql-tag-operations-masking-star-wars/src/**/*.tsx',
preset: 'gql-tag-operations-preset',
preset: 'client',
presetConfig: { fragmentMasking: true },
},
},
Expand Down

This file was deleted.

58 changes: 0 additions & 58 deletions dev-test/gql-tag-operations-masking-star-wars/gql/gql.ts

This file was deleted.

Loading

0 comments on commit b128a39

Please sign in to comment.