Describe the bug
Given:
schema:
- ./src/main.graphql
generates:
./src/types.ts:
plugins:
- typescript
- typescript-operations
config:
enumValues:
UserStatusNotOk: ./Enums#USER_STATUS_NOT_OK
UserStatusOk: ./Enums#UserStatusOk
It seems as if enumValues which do not have the same name in the .ts and .graphql files are now generating:
import { USER_STATUS_NOT_OK } from './Enums';
import UserStatusNotOk = USER_STATUS_NOT_OK; // <--
instead of the previous:
import { USER_STATUS_NOT_OK as UserStatusNotOk } from './Enums';
I am not sure if this is a bug, or expected behaviour, but it breaks the usage of those types with bable and @babel/plugin-transform-typescript.
To Reproduce
I have created a simple repo here:
https://github.com/philiiiiiipp/Grapqhl-Generator-Enum-Bug
Expected behavior
I would expect that this to still work with a project using babel and typescript.
Additional information
The last known working version was
"@graphql-codegen/cli": "^1.10.0",
"@graphql-codegen/typescript": "^1.10.0",
"@graphql-codegen/typescript-operations": "^1.10.0",
"@graphql-codegen/typescript-resolvers": "^1.10.0",
Hi @philiiiiiipp
It's not a bug, but something we changed to have better TS support. I guess we didn't know that Babel-TS doesn't support aliasing using import.
As a workaround, you can point enumValues only to the name, and then import it manually with add plugin.
schema:
- ./src/main.graphql
generates:
./src/types.ts:
plugins:
- add: "import { USER_STATUS_NOT_OK, UserStatusOk } from './Enums';"
- typescript
- typescript-operations
config:
enumValues:
UserStatusNotOk: USER_STATUS_NOT_OK
UserStatusOk: UserStatusOk
Ok great I will try that out. If this works fine should I add a PR with a note in https://graphql-code-generator.com/docs/plugins/typescript#enumvalues-enumvaluesmap describing the workaround?
@philiiiiiipp sounds good!
Note that those documentation files are generated from the comments we have on the code.
I tried using the add plugin, but it does not seem to use the imported values. It just ignores those and generates the enums again.
schema:
- ./src/main.graphql
generates:
./src/types.ts:
plugins:
- add: "import { USER_STATUS_NOT_OK, UserStatusOk } from './Enums';"
- typescript
- typescript-operations
config:
enumValues:
# UserStatusNotOk: ./Enums#USER_STATUS_NOT_OK
# UserStatusOk: ./Enums#UserStatusOk
UserStatusNotOk: USER_STATUS_NOT_OK
UserStatusOk: UserStatusOk
generates
import { USER_STATUS_NOT_OK, UserStatusOk } from './Enums';
export type Maybe<T> = T | null;
/** All built-in and custom scalars, mapped to their actual values */
export type Scalars = {
ID: string;
String: string;
Boolean: boolean;
Int: number;
Float: number;
};
export enum UserStatusNotOk {
Pending = 'Pending',
InvitedPending = 'InvitedPending',
Invited = 'Invited',
Active = 'Active',
Inactive = 'Inactive'
}
export enum UserStatusOk {
Pending = 'Pending',
InvitedPending = 'InvitedPending',
Invited = 'Invited',
Active = 'Active',
Inactive = 'Inactive'
}
This then of course ends with the syntaxt error
SyntaxError: /Users/philipp/node/dev/dh/gql-types-test/src/types.ts: Identifier 'UserStatusOk' has already been declared (21:12)
19 | }
20 |
> 21 | export enum UserStatusOk {
| ^
22 | Pending = 'Pending',
23 | InvitedPending = 'InvitedPending',
24 | Invited = 'Invited',
at Object._raise (/Users/philipp/node/dev/dh/gql-types-test/node_modules/@babel/core/node_modules/@babel/parser/src/parser/location.js:241:45)
at Object.raiseWithData (/Users/philipp/node/dev/dh/gql-types-test/node_modules/@babel/core/node_modules/@babel/parser/src/parser/location.js:236:17)
at Object.raise (/Users/philipp/node/dev/dh/gql-types-test/node_modules/@babel/core/node_modules/@babel/parser/src/parser/location.js:220:17)
at TypeScriptScopeHandler.checkRedeclarationInScope (/Users/philipp/node/dev/dh/gql-types-test/node_modules/@babel/core/node_modules/@babel/parser/src/util/scope.js:137:12)
at TypeScriptScopeHandler.declareName (/Users/philipp/node/dev/dh/gql-types-test/node_modules/@babel/core/node_modules/@babel/parser/src/util/scope.js:98:12)
at TypeScriptScopeHandler.declareName (/Users/philipp/node/dev/dh/gql-types-test/node_modules/@babel/core/node_modules/@babel/parser/src/plugins/typescript/scope.js:51:11)
at Object.checkLVal (/Users/philipp/node/dev/dh/gql-types-test/node_modules/@babel/core/node_modules/@babel/parser/src/parser/lval.js:392:22)
at Object.checkLVal (/Users/philipp/node/dev/dh/gql-types-test/node_modules/@babel/core/node_modules/@babel/parser/src/plugins/typescript/index.js:2508:17)
at Object.tsParseEnumDeclaration (/Users/philipp/node/dev/dh/gql-types-test/node_modules/@babel/core/node_modules/@babel/parser/src/plugins/typescript/index.js:1242:12)
at Object.tsParseDeclaration (/Users/philipp/node/dev/dh/gql-types-test/node_modules/@babel/core/node_modules/@babel/parser/src/plugins/typescript/index.js:1517:25) {
loc: Position { line: 21, column: 12 },
pos: 449,
code: 'BABEL_PARSE_ERROR'
}
* EDIT *
I updated the test repository to reflect the changes
So how about using aliases or * in the imports then;
schema:
- ./src/main.graphql
generates:
./src/types.ts:
plugins:
- add: "import * as Enums from './Enums';"
- typescript
- typescript-operations
config:
enumValues:
# UserStatusNotOk: ./Enums#USER_STATUS_NOT_OK
# UserStatusOk: ./Enums#UserStatusOk
UserStatusNotOk: Enums.USER_STATUS_NOT_OK
UserStatusOk: Enums.UserStatusOk
or
schema:
- ./src/main.graphql
generates:
./src/types.ts:
plugins:
- add: "import { USER_STATUS_NOT_OK, UserStatusOk as USER_STATUS_OK } from './Enums';"
- typescript
- typescript-operations
config:
enumValues:
# UserStatusNotOk: ./Enums#USER_STATUS_NOT_OK
# UserStatusOk: ./Enums#UserStatusOk
UserStatusNotOk: USER_STATUS_NOT_OK
UserStatusOk: USER_STATUS_OK
The problem is that the enum values are not getting picked up from the generated file itself.
E.g.:
import { USER_STATUS_NOT_OK as UserStatusNotOk, UserStatusOk } from './Enums';
export type Maybe<T> = T | null;
/** All built-in and custom scalars, mapped to their actual values */
export type Scalars = {
ID: string;
String: string;
Boolean: boolean;
Int: number;
Float: number;
};
export enum UserStatusNotOk {
Pending = 'Pending',
InvitedPending = 'InvitedPending',
Invited = 'Invited',
Active = 'Active',
Inactive = 'Inactive'
}
export enum UserStatusOk {
Pending = 'Pending',
InvitedPending = 'InvitedPending',
Invited = 'Invited',
Active = 'Active',
Inactive = 'Inactive'
}
Is the generated file using - add: "import { USER_STATUS_NOT_OK as UserStatusNotOk, UserStatusOk } from './Enums';"
while it should have been
import { USER_STATUS_NOT_OK as UserStatusNotOk, UserStatusOk } from './Enums';
export type Maybe<T> = T | null;
/** All built-in and custom scalars, mapped to their actual values */
export type Scalars = {
ID: string;
String: string;
Boolean: boolean;
Int: number;
Float: number;
};
export { UserStatusNotOk };
export { UserStatusOk };
I have also tried your suggestions, but they all have the issues.
Most helpful comment
Ok great I will try that out. If this works fine should I add a PR with a note in https://graphql-code-generator.com/docs/plugins/typescript#enumvalues-enumvaluesmap describing the workaround?