Skip to content

Commit 6cfdae8

Browse files
committed
add programmtic typescript example with esm
1 parent 1036da0 commit 6cfdae8

File tree

10 files changed

+722
-34
lines changed

10 files changed

+722
-34
lines changed

.changeset/config.json

+2-5
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,5 @@
66
"access": "restricted",
77
"baseBranch": "master",
88
"updateInternalDependencies": "patch",
9-
"ignore": [
10-
"@graphql-codegen/testing",
11-
"@graphql-codegen/website"
12-
]
13-
}
9+
"ignore": ["@graphql-codegen/testing", "@graphql-codegen/website", "example-*"]
10+
}

bob.config.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
module.exports = {
2-
ignore: ['@graphql-codegen/website', '@graphql-codegen/live-demo', '@graphql-codegen/config-schema'],
2+
ignore: [
3+
'@graphql-codegen/website',
4+
'@graphql-codegen/live-demo',
5+
'@graphql-codegen/config-schema',
6+
'example-programmatic-typescript',
7+
],
38
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "example-programmatic-typescript",
3+
"version": "0.0.1",
4+
"private": true,
5+
"scripts": {
6+
"dev:cjs": "tsup --watch src --onSuccess \"node dist/index.js\"",
7+
"dev:mjs": "tsup --watch src --onSuccess \"node dist/index.mjs\""
8+
},
9+
"dependencies": {
10+
"@graphql-codegen/core": "*",
11+
"@graphql-codegen/typed-document-node": "^1.18.8",
12+
"@graphql-codegen/typescript": "*",
13+
"@graphql-codegen/typescript-operations": "^1.18.2",
14+
"@graphql-codegen/typescript-resolvers": "^1.19.4",
15+
"@graphql-ez/fastify": "^0.2.0",
16+
"@graphql-tools/graphql-file-loader": "^6.2.7",
17+
"@graphql-tools/load": "^6.2.8",
18+
"fastify": "^3.18.0",
19+
"graphql": "^15.5.1",
20+
"prettier": "^2.3.1"
21+
},
22+
"devDependencies": {
23+
"@types/node": "^15.12.4",
24+
"tsup": "^4.11.2"
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
import type { GraphQLResolveInfo } from 'graphql';
2+
import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
3+
export type Maybe<T> = T | null;
4+
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
5+
export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };
6+
export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };
7+
/** All built-in and custom scalars, mapped to their actual values */
8+
export type Scalars = {
9+
ID: string;
10+
String: string;
11+
Boolean: boolean;
12+
Int: number;
13+
Float: number;
14+
};
15+
16+
export type Query = {
17+
__typename?: 'Query';
18+
hello: Scalars['String'];
19+
};
20+
21+
export type ResolverTypeWrapper<T> = Promise<T> | T;
22+
23+
export type LegacyStitchingResolver<TResult, TParent, TContext, TArgs> = {
24+
fragment: string;
25+
resolve: ResolverFn<TResult, TParent, TContext, TArgs>;
26+
};
27+
28+
export type NewStitchingResolver<TResult, TParent, TContext, TArgs> = {
29+
selectionSet: string;
30+
resolve: ResolverFn<TResult, TParent, TContext, TArgs>;
31+
};
32+
export type StitchingResolver<TResult, TParent, TContext, TArgs> =
33+
| LegacyStitchingResolver<TResult, TParent, TContext, TArgs>
34+
| NewStitchingResolver<TResult, TParent, TContext, TArgs>;
35+
export type Resolver<TResult, TParent = {}, TContext = {}, TArgs = {}> =
36+
| ResolverFn<TResult, TParent, TContext, TArgs>
37+
| StitchingResolver<TResult, TParent, TContext, TArgs>;
38+
39+
export type ResolverFn<TResult, TParent, TContext, TArgs> = (
40+
parent: TParent,
41+
args: TArgs,
42+
context: TContext,
43+
info: GraphQLResolveInfo
44+
) => Promise<TResult> | TResult;
45+
46+
export type SubscriptionSubscribeFn<TResult, TParent, TContext, TArgs> = (
47+
parent: TParent,
48+
args: TArgs,
49+
context: TContext,
50+
info: GraphQLResolveInfo
51+
) => AsyncIterator<TResult> | Promise<AsyncIterator<TResult>>;
52+
53+
export type SubscriptionResolveFn<TResult, TParent, TContext, TArgs> = (
54+
parent: TParent,
55+
args: TArgs,
56+
context: TContext,
57+
info: GraphQLResolveInfo
58+
) => TResult | Promise<TResult>;
59+
60+
export interface SubscriptionSubscriberObject<TResult, TKey extends string, TParent, TContext, TArgs> {
61+
subscribe: SubscriptionSubscribeFn<{ [key in TKey]: TResult }, TParent, TContext, TArgs>;
62+
resolve?: SubscriptionResolveFn<TResult, { [key in TKey]: TResult }, TContext, TArgs>;
63+
}
64+
65+
export interface SubscriptionResolverObject<TResult, TParent, TContext, TArgs> {
66+
subscribe: SubscriptionSubscribeFn<any, TParent, TContext, TArgs>;
67+
resolve: SubscriptionResolveFn<TResult, any, TContext, TArgs>;
68+
}
69+
70+
export type SubscriptionObject<TResult, TKey extends string, TParent, TContext, TArgs> =
71+
| SubscriptionSubscriberObject<TResult, TKey, TParent, TContext, TArgs>
72+
| SubscriptionResolverObject<TResult, TParent, TContext, TArgs>;
73+
74+
export type SubscriptionResolver<TResult, TKey extends string, TParent = {}, TContext = {}, TArgs = {}> =
75+
| ((...args: any[]) => SubscriptionObject<TResult, TKey, TParent, TContext, TArgs>)
76+
| SubscriptionObject<TResult, TKey, TParent, TContext, TArgs>;
77+
78+
export type TypeResolveFn<TTypes, TParent = {}, TContext = {}> = (
79+
parent: TParent,
80+
context: TContext,
81+
info: GraphQLResolveInfo
82+
) => Maybe<TTypes> | Promise<Maybe<TTypes>>;
83+
84+
export type IsTypeOfResolverFn<T = {}, TContext = {}> = (
85+
obj: T,
86+
context: TContext,
87+
info: GraphQLResolveInfo
88+
) => boolean | Promise<boolean>;
89+
90+
export type NextResolverFn<T> = () => Promise<T>;
91+
92+
export type DirectiveResolverFn<TResult = {}, TParent = {}, TContext = {}, TArgs = {}> = (
93+
next: NextResolverFn<TResult>,
94+
parent: TParent,
95+
args: TArgs,
96+
context: TContext,
97+
info: GraphQLResolveInfo
98+
) => TResult | Promise<TResult>;
99+
100+
/** Mapping between all available schema types and the resolvers types */
101+
export type ResolversTypes = {
102+
Query: ResolverTypeWrapper<{}>;
103+
String: ResolverTypeWrapper<Scalars['String']>;
104+
Boolean: ResolverTypeWrapper<Scalars['Boolean']>;
105+
};
106+
107+
/** Mapping between all available schema types and the resolvers parents */
108+
export type ResolversParentTypes = {
109+
Query: {};
110+
String: Scalars['String'];
111+
Boolean: Scalars['Boolean'];
112+
};
113+
114+
export type QueryResolvers<
115+
ContextType = any,
116+
ParentType extends ResolversParentTypes['Query'] = ResolversParentTypes['Query']
117+
> = {
118+
hello?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
119+
};
120+
121+
export type Resolvers<ContextType = any> = {
122+
Query?: QueryResolvers<ContextType>;
123+
};
124+
125+
/**
126+
* @deprecated
127+
* Use "Resolvers" root object instead. If you wish to get "IResolvers", add "typesPrefix: I" to your config.
128+
*/
129+
export type IResolvers<ContextType = any> = Resolvers<ContextType>;
130+
131+
export type HelloQueryVariables = Exact<{ [key: string]: never }>;
132+
133+
export type HelloQuery = { __typename?: 'Query' } & Pick<Query, 'hello'>;
134+
135+
export const HelloDocument = {
136+
kind: 'Document',
137+
definitions: [
138+
{
139+
kind: 'OperationDefinition',
140+
operation: 'query',
141+
name: { kind: 'Name', value: 'hello' },
142+
selectionSet: { kind: 'SelectionSet', selections: [{ kind: 'Field', name: { kind: 'Name', value: 'hello' } }] },
143+
},
144+
],
145+
} as unknown as DocumentNode<HelloQuery, HelloQueryVariables>;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
query hello {
2+
hello
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import Fastify from 'fastify';
2+
import { promises } from 'fs';
3+
import { parse, printSchema } from 'graphql';
4+
5+
import { codegen } from '@graphql-codegen/core';
6+
import * as typedDocumentNode from '@graphql-codegen/typed-document-node';
7+
import * as typescript from '@graphql-codegen/typescript';
8+
import * as typescriptOperations from '@graphql-codegen/typescript-operations';
9+
import * as typescriptResolvers from '@graphql-codegen/typescript-resolvers';
10+
import { CreateApp, gql, EZContext } from '@graphql-ez/fastify';
11+
import { GraphQLFileLoader } from '@graphql-tools/graphql-file-loader';
12+
import { loadDocuments } from '@graphql-tools/load';
13+
import prettier from 'prettier';
14+
15+
import type { Resolvers } from './ez.generated';
16+
17+
declare module '@graphql-ez/fastify' {
18+
interface EZResolvers extends Resolvers<EZContext> {}
19+
}
20+
21+
const { writeFile } = promises;
22+
23+
const server = Fastify({
24+
logger: true,
25+
});
26+
27+
const ezApp = CreateApp({
28+
schema: {
29+
typeDefs: gql`
30+
type Query {
31+
hello: String!
32+
}
33+
`,
34+
resolvers: {
35+
Query: {
36+
hello(_root, _args, _ctx) {
37+
return 'world';
38+
},
39+
},
40+
},
41+
},
42+
});
43+
44+
const { fastifyPlugin, getEnveloped } = ezApp.buildApp();
45+
46+
server.register(fastifyPlugin);
47+
48+
(async () => {
49+
const { schema } = (await getEnveloped)();
50+
51+
const loadedDocuments = await loadDocuments(['src/graphql/**/*.gql'], {
52+
loaders: [new GraphQLFileLoader()],
53+
});
54+
55+
const config: typescript.TypeScriptPluginConfig &
56+
typescriptResolvers.TypeScriptResolversPluginConfig &
57+
typescriptOperations.TypeScriptDocumentsPluginConfig &
58+
typedDocumentNode.TypeScriptTypedDocumentNodesConfig = {
59+
useTypeImports: true,
60+
};
61+
62+
const codegenCode = await codegen({
63+
schema: parse(printSchema(schema)),
64+
config,
65+
documents: loadedDocuments,
66+
filename: 'ez.generated.ts',
67+
pluginMap: {
68+
typescript,
69+
typescriptResolvers,
70+
typescriptOperations,
71+
typedDocumentNode,
72+
},
73+
plugins: [
74+
{
75+
typescript: {},
76+
},
77+
{
78+
typescriptResolvers: {},
79+
},
80+
{
81+
typescriptOperations: {},
82+
},
83+
{
84+
typedDocumentNode: {},
85+
},
86+
],
87+
});
88+
89+
await writeFile(
90+
'src/ez.generated.ts',
91+
prettier.format(codegenCode, {
92+
...(await prettier.resolveConfig(process.cwd())),
93+
parser: 'typescript',
94+
}),
95+
{
96+
encoding: 'utf-8',
97+
}
98+
);
99+
})().catch(err => {
100+
console.error(err);
101+
process.exit(1);
102+
});
103+
104+
server.listen(8080);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"extends": "../../tsconfig.json",
3+
"compilerOptions": {
4+
"target": "es2020",
5+
"module": "commonjs",
6+
"strict": true,
7+
"esModuleInterop": true,
8+
"skipLibCheck": true,
9+
"forceConsistentCasingInFileNames": true,
10+
"rootDir": "../../"
11+
},
12+
"include": ["src/**/*.ts"]
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export const tsup: import('tsup').Options = {
2+
target: 'es2019',
3+
entryPoints: ['src/index.ts'],
4+
format: ['cjs', 'esm'],
5+
ignoreWatch: ['src/ez.generated.ts'],
6+
};

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@
3030
"packages/plugins/other/*",
3131
"packages/presets/*",
3232
"website",
33-
"website/live-demo"
33+
"website/live-demo",
34+
"examples/*"
3435
],
3536
"nohoist": [
3637
"@graphql-codegen/website/@docusaurus/*",

0 commit comments

Comments
 (0)