Skip to content

Commit

Permalink
ESM support (#6102)
Browse files Browse the repository at this point in the history
* ESM support

* Fix tests

* update lock

* export config types

* fix plugins-helpers esm compat

* refactor lodash usage for esm

* add programmatic typescript example with esm

* small fixes

* use "createRequire" for resolve in cli "createContext"

* fix enum-array package ESM exports

* fix deep graphql import with ".js"

* add test-esm script

* fix gql-tag-operations-preset package

* fix esm import issues

* specify prettier in root

* use globby v11

* update prisma-loader & fix mkdirp import

* remove createRequireFromPath imports

* simplify example

* fix support ESM changeset

* update lock

* update bob-the-bundler to v1.5.1

* fix changeset

Co-authored-by: Arda TANRIKULU <[email protected]>
Co-authored-by: Renovate Bot <[email protected]>
  • Loading branch information
3 people authored Aug 9, 2021
1 parent 62629b3 commit 440172c
Show file tree
Hide file tree
Showing 84 changed files with 1,747 additions and 621 deletions.
7 changes: 2 additions & 5 deletions .changeset/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,5 @@
"access": "restricted",
"baseBranch": "master",
"updateInternalDependencies": "patch",
"ignore": [
"@graphql-codegen/testing",
"@graphql-codegen/website"
]
}
"ignore": ["@graphql-codegen/testing", "@graphql-codegen/website", "example-*"]
}
6 changes: 6 additions & 0 deletions .changeset/lemon-frogs-yawn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@graphql-codegen/typescript-resolvers': patch
'@graphql-codegen/typed-document-node': patch
---

export config types
57 changes: 57 additions & 0 deletions .changeset/unlucky-dots-judge.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
'@graphql-cli/codegen': minor
'@graphql-codegen/cli': minor
'@graphql-codegen/core': minor
'@graphql-codegen/c-sharp': minor
'@graphql-codegen/c-sharp-operations': minor
'@graphql-codegen/flow': minor
'@graphql-codegen/flow-operations': minor
'@graphql-codegen/flow-resolvers': minor
'@graphql-codegen/java-apollo-android': minor
'@graphql-codegen/java-common': minor
'@graphql-codegen/java': minor
'@graphql-codegen/kotlin': minor
'@graphql-codegen/java-resolvers': minor
'@graphql-codegen/add': minor
'@graphql-codegen/fragment-matcher': minor
'@graphql-codegen/introspection': minor
'@graphql-codegen/jsdoc': minor
'@graphql-codegen/schema-ast': minor
'@graphql-codegen/time': minor
'@graphql-codegen/urql-introspection': minor
'@graphql-codegen/visitor-plugin-common': minor
'@graphql-codegen/typescript-apollo-angular': minor
'@graphql-codegen/typescript-apollo-client-helpers': minor
'@graphql-codegen/typescript-document-nodes': minor
'@graphql-codegen/typescript-enum-array': minor
'@graphql-codegen/typescript-generic-sdk': minor
'@graphql-codegen/gql-tag-operations': minor
'@graphql-codegen/typescript-graphql-files-modules': minor
'@graphql-codegen/typescript-graphql-request': minor
'@graphql-codegen/typescript-mongodb': minor
'@graphql-codegen/named-operations-object': minor
'@graphql-codegen/typescript-oclif': minor
'@graphql-codegen/typescript-operations': minor
'@graphql-codegen/typescript-react-apollo': minor
'@graphql-codegen/typescript-react-offix': minor
'@graphql-codegen/typescript-react-query': minor
'@graphql-codegen/typescript-resolvers': minor
'@graphql-codegen/typescript-rtk-query': minor
'@graphql-codegen/typescript-stencil-apollo': minor
'@graphql-codegen/typescript-type-graphql': minor
'@graphql-codegen/typed-document-node': minor
'@graphql-codegen/typescript': minor
'@graphql-codegen/typescript-urql': minor
'@graphql-codegen/typescript-urql-graphcache': minor
'@graphql-codegen/urql-svelte-operations-store': minor
'@graphql-codegen/typescript-vue-apollo': minor
'@graphql-codegen/typescript-vue-apollo-smart-ops': minor
'@graphql-codegen/typescript-vue-urql': minor
'@graphql-codegen/gql-tag-operations-preset': minor
'@graphql-codegen/graphql-modules-preset': minor
'@graphql-codegen/import-types-preset': minor
'@graphql-codegen/near-operation-file-preset': minor
'@graphql-codegen/plugin-helpers': minor
---

support ESM
2 changes: 2 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,5 @@ jobs:
run: |
yarn run generate:examples
git diff --exit-code -- dev-test/
- name: Test ESM
run: node scripts/test-esm.mjs
7 changes: 6 additions & 1 deletion bob.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
module.exports = {
ignore: ['@graphql-codegen/website', '@graphql-codegen/live-demo', '@graphql-codegen/config-schema'],
ignore: [
'@graphql-codegen/website',
'@graphql-codegen/live-demo',
'@graphql-codegen/config-schema',
'example-programmatic-typescript',
],
};
26 changes: 26 additions & 0 deletions examples/programmatic-typescript/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "example-programmatic-typescript",
"version": "0.0.1",
"private": true,
"scripts": {
"start:cjs": "tsup --onSuccess \"node dist/index.js\"",
"start:mjs": "tsup --onSuccess \"node dist/index.mjs\""
},
"dependencies": {
"@graphql-codegen/core": "*",
"@graphql-codegen/typed-document-node": "*",
"@graphql-codegen/typescript": "*",
"@graphql-codegen/typescript-operations": "*",
"@graphql-codegen/typescript-resolvers": "*",
"@graphql-tools/graphql-file-loader": "^7.0.1",
"@graphql-tools/load": "^7.1.0",
"@graphql-tools/schema": "^8.0.1",
"graphql": "^15.5.1",
"graphql-tag": "^2.12.5",
"prettier": "^2.3.2"
},
"devDependencies": {
"@types/node": "^16.4.10",
"tsup": "^4.12.5"
}
}
130 changes: 130 additions & 0 deletions examples/programmatic-typescript/src/gql.generated.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import type { GraphQLResolveInfo } from 'graphql';
import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
export type Maybe<T> = T | null;
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };
export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };
/** 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 type Query = {
__typename?: 'Query';
hello: Scalars['String'];
};

export type ResolverTypeWrapper<T> = Promise<T> | T;

export type ResolverWithResolve<TResult, TParent, TContext, TArgs> = {
resolve: ResolverFn<TResult, TParent, TContext, TArgs>;
};
export type Resolver<TResult, TParent = {}, TContext = {}, TArgs = {}> =
| ResolverFn<TResult, TParent, TContext, TArgs>
| ResolverWithResolve<TResult, TParent, TContext, TArgs>;

export type ResolverFn<TResult, TParent, TContext, TArgs> = (
parent: TParent,
args: TArgs,
context: TContext,
info: GraphQLResolveInfo
) => Promise<TResult> | TResult;

export type SubscriptionSubscribeFn<TResult, TParent, TContext, TArgs> = (
parent: TParent,
args: TArgs,
context: TContext,
info: GraphQLResolveInfo
) => AsyncIterator<TResult> | Promise<AsyncIterator<TResult>>;

export type SubscriptionResolveFn<TResult, TParent, TContext, TArgs> = (
parent: TParent,
args: TArgs,
context: TContext,
info: GraphQLResolveInfo
) => TResult | Promise<TResult>;

export interface SubscriptionSubscriberObject<TResult, TKey extends string, TParent, TContext, TArgs> {
subscribe: SubscriptionSubscribeFn<{ [key in TKey]: TResult }, TParent, TContext, TArgs>;
resolve?: SubscriptionResolveFn<TResult, { [key in TKey]: TResult }, TContext, TArgs>;
}

export interface SubscriptionResolverObject<TResult, TParent, TContext, TArgs> {
subscribe: SubscriptionSubscribeFn<any, TParent, TContext, TArgs>;
resolve: SubscriptionResolveFn<TResult, any, TContext, TArgs>;
}

export type SubscriptionObject<TResult, TKey extends string, TParent, TContext, TArgs> =
| SubscriptionSubscriberObject<TResult, TKey, TParent, TContext, TArgs>
| SubscriptionResolverObject<TResult, TParent, TContext, TArgs>;

export type SubscriptionResolver<TResult, TKey extends string, TParent = {}, TContext = {}, TArgs = {}> =
| ((...args: any[]) => SubscriptionObject<TResult, TKey, TParent, TContext, TArgs>)
| SubscriptionObject<TResult, TKey, TParent, TContext, TArgs>;

export type TypeResolveFn<TTypes, TParent = {}, TContext = {}> = (
parent: TParent,
context: TContext,
info: GraphQLResolveInfo
) => Maybe<TTypes> | Promise<Maybe<TTypes>>;

export type IsTypeOfResolverFn<T = {}, TContext = {}> = (
obj: T,
context: TContext,
info: GraphQLResolveInfo
) => boolean | Promise<boolean>;

export type NextResolverFn<T> = () => Promise<T>;

export type DirectiveResolverFn<TResult = {}, TParent = {}, TContext = {}, TArgs = {}> = (
next: NextResolverFn<TResult>,
parent: TParent,
args: TArgs,
context: TContext,
info: GraphQLResolveInfo
) => TResult | Promise<TResult>;

/** Mapping between all available schema types and the resolvers types */
export type ResolversTypes = {
Query: ResolverTypeWrapper<{}>;
String: ResolverTypeWrapper<Scalars['String']>;
Boolean: ResolverTypeWrapper<Scalars['Boolean']>;
};

/** Mapping between all available schema types and the resolvers parents */
export type ResolversParentTypes = {
Query: {};
String: Scalars['String'];
Boolean: Scalars['Boolean'];
};

export type QueryResolvers<
ContextType = any,
ParentType extends ResolversParentTypes['Query'] = ResolversParentTypes['Query']
> = {
hello?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
};

export type Resolvers<ContextType = any> = {
Query?: QueryResolvers<ContextType>;
};

export type HelloQueryVariables = Exact<{ [key: string]: never }>;

export type HelloQuery = { __typename?: 'Query'; hello: string };

export const HelloDocument = {
kind: 'Document',
definitions: [
{
kind: 'OperationDefinition',
operation: 'query',
name: { kind: 'Name', value: 'hello' },
selectionSet: { kind: 'SelectionSet', selections: [{ kind: 'Field', name: { kind: 'Name', value: 'hello' } }] },
},
],
} as unknown as DocumentNode<HelloQuery, HelloQueryVariables>;
3 changes: 3 additions & 0 deletions examples/programmatic-typescript/src/graphql/hello.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
query hello {
hello
}
86 changes: 86 additions & 0 deletions examples/programmatic-typescript/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/* eslint-disable no-console */

import { promises } from 'fs';
import { parse, printSchema } from 'graphql';
import gql from 'graphql-tag';
import prettier from 'prettier';

import { codegen } from '@graphql-codegen/core';
import * as typedDocumentNode from '@graphql-codegen/typed-document-node';
import * as typescript from '@graphql-codegen/typescript';
import * as typescriptOperations from '@graphql-codegen/typescript-operations';
import * as typescriptResolvers from '@graphql-codegen/typescript-resolvers';
import { GraphQLFileLoader } from '@graphql-tools/graphql-file-loader';
import { loadDocuments } from '@graphql-tools/load';
import { makeExecutableSchema } from '@graphql-tools/schema';

import type { Resolvers } from './gql.generated';

const schema = makeExecutableSchema({
typeDefs: gql`
type Query {
hello: String!
}
`,
resolvers: {
Query: {
hello(_root, _args, _ctx) {
return 'world';
},
},
} as Resolvers<unknown>,
});

(async () => {
const loadedDocuments = await loadDocuments(['src/graphql/**/*.gql'], {
loaders: [new GraphQLFileLoader()],
});

const config: typescript.TypeScriptPluginConfig &
typescriptResolvers.TypeScriptResolversPluginConfig &
typescriptOperations.TypeScriptDocumentsPluginConfig &
typedDocumentNode.TypeScriptTypedDocumentNodesConfig = {
useTypeImports: true,
};

const codegenCode = await codegen({
schema: parse(printSchema(schema)),
config,
documents: loadedDocuments,
filename: 'gql.generated.ts',
pluginMap: {
typescript,
typescriptResolvers,
typescriptOperations,
typedDocumentNode,
},
plugins: [
{
typescript: {},
},
{
typescriptResolvers: {},
},
{
typescriptOperations: {},
},
{
typedDocumentNode: {},
},
],
});

await promises.writeFile(
'src/gql.generated.ts',
prettier.format(codegenCode, {
...(await prettier.resolveConfig(process.cwd())),
parser: 'typescript',
}),
{
encoding: 'utf-8',
}
);
})().catch(err => {
console.error(err);
process.exit(1);
});
13 changes: 13 additions & 0 deletions examples/programmatic-typescript/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"target": "es2020",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"rootDir": "../../"
},
"include": ["src/**/*.ts"]
}
6 changes: 6 additions & 0 deletions examples/programmatic-typescript/tsup.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export const tsup: import('tsup').Options = {
target: 'es2019',
entryPoints: ['src/index.ts'],
format: ['cjs', 'esm'],
ignoreWatch: ['src/ez.generated.ts'],
};
Loading

0 comments on commit 440172c

Please sign in to comment.