dotansimha / dotansimha/graphql-code-generator

fragments on interfaces are not exported

Open
#6,090 3 comments 5 reactions 0 assignees View on GitHub
core stage/0-issue-prerequisites
Dominant language
TypeScript
Stars
11.3k
Forks
1.4k
Avg merge
1d 1h
Merged PRs (30d)
23

Description

**Describe the bug**

I have a monorepo in which I define schema and common fragments in one package `@myorg/schema`, and then use the schema and these fragments in other packages. The schema contains interface, implementing types and a fragment on this interface (see below). Generated fragment in `@myorg/schema` packages produces following code:

```ts

type TimestampedMeta_Media_Fragment = {
__typename?: 'Media';
createdAt?: Types.Maybe;
updatedAt?: Types.Maybe;
};

type TimestampedMeta_Descent_Fragment = {
__typename?: 'Descent';
createdAt?: Types.Maybe;
updatedAt?: Types.Maybe;
};

// ...

export type TimestampedMetaFragment =
| TimestampedMeta_Region_Fragment
| TimestampedMeta_River_Fragment
| TimestampedMeta_Section_Fragment
| TimestampedMeta_Gauge_Fragment
| TimestampedMeta_Source_Fragment
| TimestampedMeta_User_Fragment
| TimestampedMeta_Media_Fragment
| TimestampedMeta_Descent_Fragment;
```

Note that types like `TimestampedMeta_Region_Fragment` are not exported.

I another package I have a query with `TimestampedMeta` fragment, and code generator produces following code:

```ts
import {
TimestampedMeta_Region_Fragment,
TimestampedMeta_River_Fragment,
TimestampedMeta_Section_Fragment,
TimestampedMeta_Gauge_Fragment,
TimestampedMeta_Source_Fragment,
TimestampedMeta_User_Fragment,
TimestampedMeta_Media_Fragment,
TimestampedMeta_Descent_Fragment,
} from '@myorg/schema';

// ...

export type SectionDetailsFragment = {
__typename?: 'Section';
description?: Types.Maybe;
shape: Array>;
region?: Types.Maybe<{ __typename?: 'Region'; id: string }>;
} & SectionCoreFragment &
SectionEndsFragment &
SectionMeasurementsFragment &
SectionPoIsFragment &
SectionTagsFragment &
SectionLicenseFragment &
TimestampedMeta_Section_Fragment;

```

Note that all the variations of `TimestampedMeta` fragment are imported, except for the one which is really exported.

**To Reproduce**
Steps to reproduce the behavior:

1. My GraphQL schema (defined in `@myorg/schema`):

```graphql

interface Timestamped {
createdAt: Date
updatedAt: Date
}

# ...

type Section implements NamedNode & Timestamped {
id: ID!
name: String!
createdAt: Date
updatedAt: Date
# ...
}

# ...
```

2. My GraphQL operations:

This fragment is defined in `@myorg/schema` package
```graphql
fragment TimestampedMeta on Timestamped {
createdAt
updatedAt
}
```

This query is defined in `@myorg/clients` package
```graphql
fragment SectionDetails on Section {
...SectionCore
# ... more fragments
...TimestampedMeta
}

query sectionDetails($sectionId: ID) {
section(id: $sectionId) {
...SectionDetails
}
}
```

3. My `codegen.yml` config file:

```yml
overwrite: true
schema:
- './packages/schema/schema/*.graphql'
documents:
# Shared fragments, used both by frontend and by backend tests
- ./packages/schema/fragments/*.gql
generates:
# Common types shared by backend, web frontend and mobile are generated in schema package
# Common validation schemas are also in schema package
./packages/schema/src/__generated__/types.ts:
plugins:
- typescript
- add:
content: '/* eslint-disable @typescript-eslint/no-explicit-any */'
config:
scalars:
Date: Date
DateTime: Date
JSON: '{ [key: string]: any }'

# Typedefs are used to make executable schema on backend
./packages/schema/src/__generated__/typeDefs.ts:
plugins:
- add:
content: '/* eslint-disable @typescript-eslint/no-explicit-any */'
- ./packages/schema/plugins/codegen-typedefs.js

./packages/schema/src/__generated__/fragments.ts:
preset: import-types
presetConfig:
typesPath: ./types
documents:
- ./packages/schema/fragments/*.gql
plugins:
- typescript-operations
- typescript-document-nodes
- add:
content: '/* eslint-disable @typescript-eslint/no-explicit-any */'
config:
# Setting this suffix will allow inports using 'importAllFragmentsFrom'
fragmentSuffix: 'FragmentDoc'

# GRAPHQL resolvers
./packages/backend/src/apollo/resolvers.generated.ts:
preset: import-types
presetConfig:
typesPath: '@myorg/schema'
plugins:
- add:
content:
- '/* eslint-disable @typescript-eslint/no-explicit-any */'
- typescript-resolvers
config:
useIndexSignature: true
noSchemaStitching: true
contextType: ./context#Context
resolverTypeWrapperSignature: 'T extends object ? Promise> | Partial : Promise | T'
defaultMapper: any
mappers:
Banner: ~/db#Sql.Banners
BannerSource: ~/db#Sql.BannerSource
Descent: ~/db#Sql.Descents
Gauge: ~/db#Sql.GaugesView
GaugeBinding: ~/db#Sql.GaugeBinding
Group: ~/db#Sql.GroupsView
License: '@myorg/schema#License'
Media: ~/db#Sql.MediaView
Point: ~/db#Sql.PointsView
Region: ~/db#Sql.RegionsView
RegionCoverImage: ~/db#Sql.RegionCoverImage
River: ~/db#Sql.RiversView
Section: ~/db#Sql.SectionsView
Source: ~/db#Sql.SourcesView
Suggestion: ~/db#Sql.Suggestions
User: ~/db#Sql.Users
scalars:
Date: Date
DateTime: Date
JSON: unknown

# Tests that run GRAPHQL queries and mutations against our API
./packages/backend/src/:
documents:
- ./packages/backend/src/**/__tests__/*.ts
- ./packages/backend/src/**/*.test.ts
preset: near-operation-file
presetConfig:
extension: .generated.ts
baseTypesPath: '~@myorg/schema'
importAllFragmentsFrom: '~@myorg/schema'
plugins:
- typescript-operations
# This custom-made plugin generates strongly typed functions to execute graphql queries in tests
- '@myorg/codegen-backend-tests'

# Frontend queries and mutations
./:
documents:
- ./packages/clients/src/**/*.gql
- ./packages/mobile/src/**/*.gql
- ./packages/web/src/**/*.gql
preset: near-operation-file
presetConfig:
extension: .generated.ts
baseTypesPath: '~@myorg/schema'
importAllFragmentsFrom: '~@myorg/schema'
plugins:
- add:
content: '/* eslint-disable @typescript-eslint/no-explicit-any */'
- typescript-operations
- typescript-react-apollo
config:
withComponent: false
withHOC: false
withHooks: true
withMutationFn: false
reactApolloVersion: 2
scalars:
Date: string
DateTime: string
JSON: unknown

config:
preResolveTypes: true

hooks:
afterAllFileWrite:
- prettier --write
beforeDone:
# These files are generated by near-operation-file and are same as generated fragments.ts
# They are generated because we want to use fragments in backend/frontend queries
- 'rm -rf ./packages/schema/fragments/*.ts'

```

**Expected behavior**

I expect types like `TimestampedMeta_Media_Fragment` to be exported, so that I can consume them in another package.

**Environment:**

- OS:
```
"@graphql-codegen/cli": "^1.21.5",
"@graphql-codegen/import-types-preset": "^1.18.2",
"@graphql-codegen/near-operation-file-preset": "^1.18.1",
"@graphql-codegen/typescript": "^1.22.1",
"@graphql-codegen/typescript-document-nodes": "^1.17.12",
"@graphql-codegen/typescript-operations": "^1.18.0",
"@graphql-codegen/typescript-react-apollo": "^2.2.5",
"@graphql-codegen/typescript-resolvers": "^1.19.2",
```
- NodeJS: 14

**Additional context**

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.