UNPKG

10.5 kBMarkdownView Raw
1# `graphql-code-generators`
2
3This packages includes the built-in generators for GraphQL Codegen.
4
5Currently includes:
6
7* TypeScript single file
8* TypeScript multiple files
9
10## Build process
11
12The build process of this package is based on Webpack with `awesome-typescript-loader` to compile TypeScript source code, and `raw-loader` to load the handlebars templates as string.
13
14The purpose of the build process is to eliminate the need to use `fs.readFile` for the template files, and integrate the template files into the compiles JS files as strings.
15
16To build this package and the generators template, start by installing the package dependencies:
17
18```
19 $ npm install
20 // Or, with Yarn
21 $ yarn
22```
23
24Then, you can use the existing NPM scripts to build the package:
25
26```
27 $ npm run build
28 // Or, with Yarn
29 $ yarn build
30```
31
32## Adding a new generator
33
34To add a new generator, start by adding a new directory under `./src/` of this directory, with the name of the generator.
35
36Then, create a file called `config.ts`.
37
38Your config file should use default export, and export a config variable that implements the [`GeneratorConfig`](https://github.com/dotansimha/graphql-code-generator/blob/e9e4722723541628bc7ae58c0e4082556af4bfb8/packages/graphql-codegen-generators/src/types.ts#L7-L20) interface, for example:
39
40```typescript
41import { EInputType, GeneratorConfig } from '../types';
42
43const config: GeneratorConfig = {
44 inputType: EInputType.MULTIPLE_FILES,
45 templates: {
46 // Your templates here
47 },
48 flattenTypes: true,
49 primitives: {
50 String: 'string',
51 Int: 'number',
52 Float: 'number',
53 Boolean: 'boolean',
54 ID: 'string'
55 },
56};
57
58export default config;
59```
60
61Next, make sure to import your template files and add them to your `templates`, for example:
62
63```typescript
64import * as index from './template.handlebars';
65import * as type from './type.handlebars';
66import * as schema from './schema.handlebars';
67import * as documents from './documents.handlebars';
68import * as selectionSet from './selection-set.handlebars';
69import { EInputType, GeneratorConfig } from '../types';
70
71const config: GeneratorConfig = {
72 inputType: EInputType.SINGLE_FILE,
73 templates: {
74 index,
75 type,
76 schema,
77 documents,
78 selectionSet,
79 },
80 flattenTypes: true,
81 primitives: {
82 String: 'string',
83 Int: 'number',
84 Float: 'number',
85 Boolean: 'boolean',
86 ID: 'string'
87 },
88 outFile: 'types.d.ts',
89};
90
91export default config;
92```
93
94### inputType
95
96Allowed values: `EInputType.SINGLE_FILE`, `EInputType.MULTIPLE_FILES`
97
98`inputType` defined the template input type of the generator, and also declares the generator output.
99
100For example, we have TypeScript generators for both single and multiple files.
101
102The input type field effects the rest of the fields:
103
104#### *SINGLE_FILE*
105
106When using `SINGLE_FILE`, you must specify the main template name, with a key called `index`, and this will be the root of your app.
107
108You also need to specify the `outFile` of the package, which is the default file name in case of output filename was not specified through the CLI.
109
110#### *MULTIPLE_FILES*
111
112When using `MULTIPLE_FILES`, you need to specify a template for each available compilation context (refer to `templates` section for the list of available contexts).
113
114You also need to specify the `filesExtension` for the generated files.
115
116### templates
117
118`templates` field should contains an object, where the key is the name of the template, and the value is a string.
119
120There are special context types for templates, and each type of templates will compile with a different context:
121
122* `index`: use with `SINGLE_FILE` to declare the main entry point of the generated file, compiled with a merged object, containing all [`SchemaTemplateContext`](https://github.com/dotansimha/graphql-code-generator/blob/e9e4722723541628bc7ae58c0e4082556af4bfb8/packages/graphql-codegen-core/src/types.ts#L78-L94) and [`Document`](https://github.com/dotansimha/graphql-code-generator/blob/e9e4722723541628bc7ae58c0e4082556af4bfb8/packages/graphql-codegen-core/src/types.ts#L170-L175) fields.
123* `type`: use with `MULTIPLE_FILES` to declare that this template belongs to GraphQL schema `type`, this template will compile with *each* [type](https://github.com/dotansimha/graphql-code-generator/blob/e9e4722723541628bc7ae58c0e4082556af4bfb8/packages/graphql-codegen-core/src/types.ts#L38-L46) in your schema.
124* `inputType`: use with `MULTIPLE_FILES` to declare that this template belongs to GraphQL schema `input`, this template will compile with *each* [input type](https://github.com/dotansimha/graphql-code-generator/blob/e9e4722723541628bc7ae58c0e4082556af4bfb8/packages/graphql-codegen-core/src/types.ts#L38-L46) in your schema.
125* `union`: use with `MULTIPLE_FILES` to declare that this template belongs to GraphQL schema `union`, this template will compile with *each* [union](https://github.com/dotansimha/graphql-code-generator/blob/e9e4722723541628bc7ae58c0e4082556af4bfb8/packages/graphql-codegen-core/src/types.ts#L65-L69) in your schema.
126* `scalar`: use with `MULTIPLE_FILES` to declare that this template belongs to GraphQL schema `scalar`, this template will compile with *each* [scalar](https://github.com/dotansimha/graphql-code-generator/blob/e9e4722723541628bc7ae58c0e4082556af4bfb8/packages/graphql-codegen-core/src/types.ts#L48-L51) in your schema.
127* `enum`: use with `MULTIPLE_FILES` to declare that this template belongs to GraphQL schema `enum`, this template will compile with *each* [enum](https://github.com/dotansimha/graphql-code-generator/blob/e9e4722723541628bc7ae58c0e4082556af4bfb8/packages/graphql-codegen-core/src/types.ts#L53-L57) in your schema.
128* `interface`: use with `MULTIPLE_FILES` to declare that this template belongs to GraphQL schema `interface`, this template will compile with *each* [interface](https://github.com/dotansimha/graphql-code-generator/blob/e9e4722723541628bc7ae58c0e4082556af4bfb8/packages/graphql-codegen-core/src/types.ts#L71-L76) in your schema.
129* `operation`: use with `MULTIPLE_FILES` to declare that this template belongs to GraphQL operation (`query`/`mutation`/`subsription`), this template will compile with [`Operation` context](https://github.com/dotansimha/graphql-code-generator/blob/e9e4722723541628bc7ae58c0e4082556af4bfb8/packages/graphql-codegen-core/src/types.ts#L151-L161).
130* `fragment`: use with `MULTIPLE_FILES` to declare that this template belongs to GraphQL `fragment`, this template will compile with [`Fragment` context](https://github.com/dotansimha/graphql-code-generator/blob/e9e4722723541628bc7ae58c0e4082556af4bfb8/packages/graphql-codegen-core/src/types.ts#L144-L149).
131* `schema`: use with `MULTIPLE_FILES` to compile with [`SchemaTemplateContext`](https://github.com/dotansimha/graphql-code-generator/blob/e9e4722723541628bc7ae58c0e4082556af4bfb8/packages/graphql-codegen-core/src/types.ts#L78-L94).
132* `documents`: use with `MULTIPLE_FILES` to compile with all operations, the context will be [`Document`](https://github.com/dotansimha/graphql-code-generator/blob/e9e4722723541628bc7ae58c0e4082556af4bfb8/packages/graphql-codegen-core/src/types.ts#L170-L175).
133* `all`: same as to `index`.
134
135Also, all templates specified under `templates` will be loaded as Handlebars template partials, so you can use it any time inside other templates, for example, the following templates definitions:
136
137```typescript
138const config = {
139 // ...
140 templates: {
141 index: '{{>selectionSet}}',
142 selectionSet: 'Hello',
143 },
144 // ...
145};
146```
147
148The `index` template loads `selectionSet` template, and it can also provide a context for the specific partial:
149
150```typescript
151const config = {
152 // ...
153 templates: {
154 index: '{{>selectionSet types}}',
155 selectionSet: '{{#each this }} Type name: {{ name }}{{/each}}',
156 },
157 // ...
158};
159```
160
161> You can also load a template from itself, and create a recursive generation of the template.
162
163### flattenTypes
164
165Type flattening is a useful feature when generation a template, when `true` is specified, the generator will return a flatten version of the GraphQL selection set when using inner types.
166
167For example, let's take a look in the following GraphQL schema and `query`:
168
169```graphql schema
170type NameFields {
171 firstName: String
172 lastName: String
173}
174
175type User {
176 name: NameFields
177 email: String
178 age: Int
179}
180
181type Query {
182 me: User
183}
184
185schema {
186 query: Query
187}
188```
189
190```graphql
191query myQuery {
192 user {
193 me {
194 firstName
195 lastName
196 }
197 }
198}
199```
200
201This query uses multiple levels of selection set (`user` > `name` > `firstName`), but when adding `flattenTypes: true`, the generator will append a new field to the operation/fragment context, called `innerModels`, and it this case it will contains the following:
202
203```
204[
205 {
206 schemaBaseType: 'User',
207 modelType: 'Me',
208 fields: [ ... ] // Original SelectionSetFieldNode from the operation
209 // .. more fields
210 },
211 {
212 schemaBaseType: 'NameFields',
213 modelType: 'Name',
214 fields: [ ... ] // Original SelectionSetFieldNode from the operation
215 // .. more fields
216 }
217]
218```
219
220So the two available levels of selection set were flatten into a single level, so you can generate you whole selection set in a single iteration.
221
222The `modelType` becomes the name of the selection set field, because we use only part of the available fields (for example, the query only asks for part of the `User` fields), so we can't use the actual GraphQL `type` from the schema - so each selection set creates new "types", and the usage in the selection set also changes, so the `type` of `me` is not `User` - it's `Me`.
223
224The actual compilation context when using `flattenTypes: true` is [available here](https://github.com/dotansimha/graphql-code-generator/blob/e9e4722723541628bc7ae58c0e4082556af4bfb8/packages/graphql-codegen-compiler/src/types.ts#L11-L37).
225
226### primitives
227
228Specify `primitives` object map to replace the original GraphQL built-in types to a language-specific primitives.
229
230For example, GraphQL type of `String` is actually a `string` in TypeScript.
231
232### outFile
233
234Use with `SINGLE_FILE`, specify the default filename for the generated file.
235
236
237### filesExtension
238
239Use with `MULTIPLE_FILES`, specify the file extension for the generated files.
240
241### customHelpers
242
243With `customHelpers` you can add custom helpers that executes with your custom templates.
244
245Provide an object with `key` as the name of the helper, and a `Function` for the helper execution.