@constructive-io/graphql-codegen 3.0.3 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/codegen/barrel.d.ts +10 -0
- package/core/codegen/barrel.js +26 -0
- package/core/codegen/client.d.ts +11 -1
- package/core/codegen/client.js +63 -248
- package/core/codegen/index.js +3 -1
- package/core/codegen/orm/client-generator.d.ts +5 -2
- package/core/codegen/orm/client-generator.js +28 -289
- package/core/codegen/templates/client.browser.ts +265 -0
- package/core/codegen/templates/client.node.ts +350 -0
- package/core/codegen/templates/orm-client.ts +158 -0
- package/core/codegen/templates/select-types.ts +116 -0
- package/core/generate.js +9 -10
- package/core/introspect/fetch-schema.js +10 -3
- package/esm/core/codegen/barrel.d.ts +10 -0
- package/esm/core/codegen/barrel.js +25 -0
- package/esm/core/codegen/client.d.ts +11 -1
- package/esm/core/codegen/client.js +31 -249
- package/esm/core/codegen/index.js +3 -1
- package/esm/core/codegen/orm/client-generator.d.ts +5 -2
- package/esm/core/codegen/orm/client-generator.js +28 -289
- package/esm/core/generate.js +9 -10
- package/esm/core/introspect/fetch-schema.js +10 -3
- package/esm/types/config.d.ts +8 -0
- package/esm/types/config.js +1 -0
- package/package.json +5 -5
- package/types/config.d.ts +8 -0
- package/types/config.js +1 -0
- package/core/codegen/orm/query-builder.d.ts +0 -85
- package/core/codegen/orm/query-builder.js +0 -485
- package/esm/core/codegen/orm/query-builder.d.ts +0 -85
- package/esm/core/codegen/orm/query-builder.js +0 -441
- /package/core/codegen/{orm → templates}/query-builder.ts +0 -0
|
@@ -4,322 +4,61 @@ import { getTableNames, lcFirst, getGeneratedFileHeader } from '../utils';
|
|
|
4
4
|
import * as fs from 'fs';
|
|
5
5
|
import * as path from 'path';
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*/
|
|
10
|
-
export function generateOrmClientFile() {
|
|
11
|
-
// This is runtime code that doesn't change based on schema
|
|
12
|
-
// We generate it as a static file
|
|
13
|
-
const content = `/**
|
|
14
|
-
* ORM Client - Runtime GraphQL executor
|
|
15
|
-
* @generated by @constructive-io/graphql-codegen
|
|
16
|
-
* DO NOT EDIT - changes will be overwritten
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
import type { GraphQLAdapter, GraphQLError, QueryResult } from '@constructive-io/graphql-types';
|
|
20
|
-
|
|
21
|
-
export type { GraphQLAdapter, GraphQLError, QueryResult } from '@constructive-io/graphql-types';
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Default adapter that uses fetch for HTTP requests.
|
|
25
|
-
* This is used when no custom adapter is provided.
|
|
7
|
+
* Find a template file path.
|
|
8
|
+
* Templates are at ../templates/ relative to this file in both src/ and dist/.
|
|
26
9
|
*/
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
private endpoint: string,
|
|
32
|
-
headers?: Record<string, string>
|
|
33
|
-
) {
|
|
34
|
-
this.headers = headers ?? {};
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
async execute<T>(
|
|
38
|
-
document: string,
|
|
39
|
-
variables?: Record<string, unknown>
|
|
40
|
-
): Promise<QueryResult<T>> {
|
|
41
|
-
const response = await fetch(this.endpoint, {
|
|
42
|
-
method: 'POST',
|
|
43
|
-
headers: {
|
|
44
|
-
'Content-Type': 'application/json',
|
|
45
|
-
Accept: 'application/json',
|
|
46
|
-
...this.headers,
|
|
47
|
-
},
|
|
48
|
-
body: JSON.stringify({
|
|
49
|
-
query: document,
|
|
50
|
-
variables: variables ?? {},
|
|
51
|
-
}),
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
if (!response.ok) {
|
|
55
|
-
return {
|
|
56
|
-
ok: false,
|
|
57
|
-
data: null,
|
|
58
|
-
errors: [{ message: \`HTTP \${response.status}: \${response.statusText}\` }],
|
|
59
|
-
};
|
|
10
|
+
function findTemplateFile(templateName) {
|
|
11
|
+
const templatePath = path.join(__dirname, '../templates', templateName);
|
|
12
|
+
if (fs.existsSync(templatePath)) {
|
|
13
|
+
return templatePath;
|
|
60
14
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
data?: T;
|
|
64
|
-
errors?: GraphQLError[];
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
if (json.errors && json.errors.length > 0) {
|
|
68
|
-
return {
|
|
69
|
-
ok: false,
|
|
70
|
-
data: null,
|
|
71
|
-
errors: json.errors,
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return {
|
|
76
|
-
ok: true,
|
|
77
|
-
data: json.data as T,
|
|
78
|
-
errors: undefined,
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
setHeaders(headers: Record<string, string>): void {
|
|
83
|
-
this.headers = { ...this.headers, ...headers };
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
getEndpoint(): string {
|
|
87
|
-
return this.endpoint;
|
|
88
|
-
}
|
|
15
|
+
throw new Error(`Could not find template file: ${templateName}. ` +
|
|
16
|
+
`Searched in: ${templatePath}`);
|
|
89
17
|
}
|
|
90
|
-
|
|
91
18
|
/**
|
|
92
|
-
*
|
|
93
|
-
* Either provide endpoint (and optional headers) for HTTP requests,
|
|
94
|
-
* or provide a custom adapter for alternative execution strategies.
|
|
19
|
+
* Read a template file and replace the header with generated file header
|
|
95
20
|
*/
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
21
|
+
function readTemplateFile(templateName, description) {
|
|
22
|
+
const templatePath = findTemplateFile(templateName);
|
|
23
|
+
let content = fs.readFileSync(templatePath, 'utf-8');
|
|
24
|
+
// Replace the source file header comment with the generated file header
|
|
25
|
+
// Match the header pattern used in template files
|
|
26
|
+
const headerPattern = /\/\*\*[\s\S]*?\* NOTE: This file is read at codegen time and written to output\.[\s\S]*?\*\/\n*/;
|
|
27
|
+
content = content.replace(headerPattern, getGeneratedFileHeader(description) + '\n');
|
|
28
|
+
return content;
|
|
103
29
|
}
|
|
104
|
-
|
|
105
30
|
/**
|
|
106
|
-
*
|
|
31
|
+
* Generate the main client.ts file (OrmClient class)
|
|
32
|
+
* This is the runtime client that handles GraphQL execution
|
|
33
|
+
*
|
|
34
|
+
* Reads from the templates directory for proper type checking.
|
|
107
35
|
*/
|
|
108
|
-
export
|
|
109
|
-
constructor(
|
|
110
|
-
public readonly errors: GraphQLError[],
|
|
111
|
-
public readonly data: unknown = null
|
|
112
|
-
) {
|
|
113
|
-
const messages = errors.map(e => e.message).join('; ');
|
|
114
|
-
super(\`GraphQL Error: \${messages}\`);
|
|
115
|
-
this.name = 'GraphQLRequestError';
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
export class OrmClient {
|
|
120
|
-
private adapter: GraphQLAdapter;
|
|
121
|
-
|
|
122
|
-
constructor(config: OrmClientConfig) {
|
|
123
|
-
if (config.adapter) {
|
|
124
|
-
this.adapter = config.adapter;
|
|
125
|
-
} else if (config.endpoint) {
|
|
126
|
-
this.adapter = new FetchAdapter(config.endpoint, config.headers);
|
|
127
|
-
} else {
|
|
128
|
-
throw new Error('OrmClientConfig requires either an endpoint or a custom adapter');
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
async execute<T>(
|
|
133
|
-
document: string,
|
|
134
|
-
variables?: Record<string, unknown>
|
|
135
|
-
): Promise<QueryResult<T>> {
|
|
136
|
-
return this.adapter.execute<T>(document, variables);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Set headers for requests.
|
|
141
|
-
* Only works if the adapter supports headers.
|
|
142
|
-
*/
|
|
143
|
-
setHeaders(headers: Record<string, string>): void {
|
|
144
|
-
if (this.adapter.setHeaders) {
|
|
145
|
-
this.adapter.setHeaders(headers);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Get the endpoint URL.
|
|
151
|
-
* Returns empty string if the adapter doesn't have an endpoint.
|
|
152
|
-
*/
|
|
153
|
-
getEndpoint(): string {
|
|
154
|
-
return this.adapter.getEndpoint?.() ?? '';
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
`;
|
|
36
|
+
export function generateOrmClientFile() {
|
|
158
37
|
return {
|
|
159
38
|
fileName: 'client.ts',
|
|
160
|
-
content,
|
|
39
|
+
content: readTemplateFile('orm-client.ts', 'ORM Client - Runtime GraphQL executor'),
|
|
161
40
|
};
|
|
162
41
|
}
|
|
163
42
|
/**
|
|
164
43
|
* Generate the query-builder.ts file (runtime query builder)
|
|
165
44
|
*
|
|
166
|
-
* Reads from the
|
|
167
|
-
* which enables proper type checking and testability.
|
|
45
|
+
* Reads from the templates directory for proper type checking and testability.
|
|
168
46
|
*/
|
|
169
47
|
export function generateQueryBuilderFile() {
|
|
170
|
-
// Read the query-builder.ts source file
|
|
171
|
-
// Handle both development (src/) and production (dist/) scenarios
|
|
172
|
-
let sourceFilePath = path.join(__dirname, 'query-builder.ts');
|
|
173
|
-
// If running from dist/, look for the source in src/ instead
|
|
174
|
-
if (!fs.existsSync(sourceFilePath)) {
|
|
175
|
-
// Navigate from dist/cli/codegen/orm/ to src/cli/codegen/orm/
|
|
176
|
-
sourceFilePath = path.resolve(__dirname, '../../../../src/cli/codegen/orm/query-builder.ts');
|
|
177
|
-
}
|
|
178
|
-
// If still not found, try relative to package root
|
|
179
|
-
if (!fs.existsSync(sourceFilePath)) {
|
|
180
|
-
// For installed packages, the file should be adjacent in the same dir
|
|
181
|
-
throw new Error(`Could not find query-builder.ts source file. ` +
|
|
182
|
-
`Searched in: ${path.join(__dirname, 'query-builder.ts')} and ` +
|
|
183
|
-
`${path.resolve(__dirname, '../../../../src/cli/codegen/orm/query-builder.ts')}`);
|
|
184
|
-
}
|
|
185
|
-
let sourceContent = fs.readFileSync(sourceFilePath, 'utf-8');
|
|
186
|
-
// Replace the source file header comment with the generated file header
|
|
187
|
-
const headerComment = `/**
|
|
188
|
-
* Query Builder - Builds and executes GraphQL operations
|
|
189
|
-
*
|
|
190
|
-
* This is the RUNTIME code that gets copied to generated output.
|
|
191
|
-
* It uses gql-ast to build GraphQL documents programmatically.
|
|
192
|
-
*
|
|
193
|
-
* NOTE: This file is read at codegen time and written to output.
|
|
194
|
-
* Any changes here will affect all generated ORM clients.
|
|
195
|
-
*/`;
|
|
196
|
-
const generatedHeader = `/**
|
|
197
|
-
* Query Builder - Builds and executes GraphQL operations
|
|
198
|
-
* @generated by @constructive-io/graphql-codegen
|
|
199
|
-
* DO NOT EDIT - changes will be overwritten
|
|
200
|
-
*/`;
|
|
201
|
-
sourceContent = sourceContent.replace(headerComment, generatedHeader);
|
|
202
48
|
return {
|
|
203
49
|
fileName: 'query-builder.ts',
|
|
204
|
-
content:
|
|
50
|
+
content: readTemplateFile('query-builder.ts', 'Query Builder - Builds and executes GraphQL operations'),
|
|
205
51
|
};
|
|
206
52
|
}
|
|
207
53
|
/**
|
|
208
54
|
* Generate the select-types.ts file
|
|
209
|
-
*/
|
|
210
|
-
export function generateSelectTypesFile() {
|
|
211
|
-
const content = `/**
|
|
212
|
-
* Type utilities for select inference
|
|
213
|
-
* @generated by @constructive-io/graphql-codegen
|
|
214
|
-
* DO NOT EDIT - changes will be overwritten
|
|
215
|
-
*/
|
|
216
|
-
|
|
217
|
-
export interface ConnectionResult<T> {
|
|
218
|
-
nodes: T[];
|
|
219
|
-
totalCount: number;
|
|
220
|
-
pageInfo: PageInfo;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
export interface PageInfo {
|
|
224
|
-
hasNextPage: boolean;
|
|
225
|
-
hasPreviousPage: boolean;
|
|
226
|
-
startCursor?: string | null;
|
|
227
|
-
endCursor?: string | null;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
export interface FindManyArgs<TSelect, TWhere, TOrderBy> {
|
|
231
|
-
select?: TSelect;
|
|
232
|
-
where?: TWhere;
|
|
233
|
-
orderBy?: TOrderBy[];
|
|
234
|
-
first?: number;
|
|
235
|
-
last?: number;
|
|
236
|
-
after?: string;
|
|
237
|
-
before?: string;
|
|
238
|
-
offset?: number;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
export interface FindFirstArgs<TSelect, TWhere> {
|
|
242
|
-
select?: TSelect;
|
|
243
|
-
where?: TWhere;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
export interface CreateArgs<TSelect, TData> {
|
|
247
|
-
data: TData;
|
|
248
|
-
select?: TSelect;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
export interface UpdateArgs<TSelect, TWhere, TData> {
|
|
252
|
-
where: TWhere;
|
|
253
|
-
data: TData;
|
|
254
|
-
select?: TSelect;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
export interface DeleteArgs<TWhere> {
|
|
258
|
-
where: TWhere;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Recursively validates select objects, rejecting unknown keys.
|
|
263
|
-
*
|
|
264
|
-
* This type ensures that users can only select fields that actually exist
|
|
265
|
-
* in the GraphQL schema. It returns \`never\` if any excess keys are found
|
|
266
|
-
* at any nesting level, causing a TypeScript compile error.
|
|
267
|
-
*
|
|
268
|
-
* Why this is needed:
|
|
269
|
-
* TypeScript's excess property checking has a quirk where it only catches
|
|
270
|
-
* invalid fields when they are the ONLY fields. When mixed with valid fields
|
|
271
|
-
* (e.g., \`{ id: true, invalidField: true }\`), the structural typing allows
|
|
272
|
-
* the excess property through. This type explicitly checks for and rejects
|
|
273
|
-
* such cases.
|
|
274
|
-
*
|
|
275
|
-
* @example
|
|
276
|
-
* // This will cause a type error because 'invalid' doesn't exist:
|
|
277
|
-
* type Result = DeepExact<{ id: true, invalid: true }, { id?: boolean }>;
|
|
278
|
-
* // Result = never (causes assignment error)
|
|
279
55
|
*
|
|
280
|
-
*
|
|
281
|
-
* // This works because all fields are valid:
|
|
282
|
-
* type Result = DeepExact<{ id: true }, { id?: boolean; name?: boolean }>;
|
|
283
|
-
* // Result = { id: true }
|
|
284
|
-
*/
|
|
285
|
-
export type DeepExact<T, Shape> = T extends Shape
|
|
286
|
-
? Exclude<keyof T, keyof Shape> extends never
|
|
287
|
-
? {
|
|
288
|
-
[K in keyof T]: K extends keyof Shape
|
|
289
|
-
? T[K] extends { select: infer NS }
|
|
290
|
-
? Shape[K] extends { select?: infer ShapeNS }
|
|
291
|
-
? { select: DeepExact<NS, NonNullable<ShapeNS>> }
|
|
292
|
-
: T[K]
|
|
293
|
-
: T[K]
|
|
294
|
-
: never;
|
|
295
|
-
}
|
|
296
|
-
: never
|
|
297
|
-
: never;
|
|
298
|
-
|
|
299
|
-
/**
|
|
300
|
-
* Infer result type from select configuration
|
|
56
|
+
* Reads from the templates directory for proper type checking.
|
|
301
57
|
*/
|
|
302
|
-
export
|
|
303
|
-
? TEntity
|
|
304
|
-
: {
|
|
305
|
-
[K in keyof TSelect as TSelect[K] extends false | undefined ? never : K]: TSelect[K] extends true
|
|
306
|
-
? K extends keyof TEntity
|
|
307
|
-
? TEntity[K]
|
|
308
|
-
: never
|
|
309
|
-
: TSelect[K] extends { select: infer NestedSelect }
|
|
310
|
-
? K extends keyof TEntity
|
|
311
|
-
? NonNullable<TEntity[K]> extends ConnectionResult<infer NodeType>
|
|
312
|
-
? ConnectionResult<InferSelectResult<NodeType, NestedSelect>>
|
|
313
|
-
: InferSelectResult<NonNullable<TEntity[K]>, NestedSelect> | (null extends TEntity[K] ? null : never)
|
|
314
|
-
: never
|
|
315
|
-
: K extends keyof TEntity
|
|
316
|
-
? TEntity[K]
|
|
317
|
-
: never;
|
|
318
|
-
};
|
|
319
|
-
`;
|
|
58
|
+
export function generateSelectTypesFile() {
|
|
320
59
|
return {
|
|
321
60
|
fileName: 'select-types.ts',
|
|
322
|
-
content,
|
|
61
|
+
content: readTemplateFile('select-types.ts', 'Type utilities for select inference'),
|
|
323
62
|
};
|
|
324
63
|
}
|
|
325
64
|
function createImportDeclaration(moduleSpecifier, namedImports, typeOnly = false) {
|
package/esm/core/generate.js
CHANGED
|
@@ -8,6 +8,7 @@ import path from 'path';
|
|
|
8
8
|
import { createSchemaSource, validateSourceOptions } from './introspect';
|
|
9
9
|
import { runCodegenPipeline, validateTablesFound } from './pipeline';
|
|
10
10
|
import { generate as generateReactQueryFiles } from './codegen';
|
|
11
|
+
import { generateRootBarrel } from './codegen/barrel';
|
|
11
12
|
import { generateOrm as generateOrmFiles } from './codegen/orm';
|
|
12
13
|
import { generateSharedTypes } from './codegen/shared';
|
|
13
14
|
import { writeGeneratedFiles } from './output';
|
|
@@ -161,16 +162,14 @@ export async function generate(options = {}) {
|
|
|
161
162
|
allFilesWritten.push(...(writeResult.filesWritten ?? []));
|
|
162
163
|
}
|
|
163
164
|
}
|
|
164
|
-
// Generate
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
export * from './orm';
|
|
173
|
-
`;
|
|
165
|
+
// Generate barrel file at output root
|
|
166
|
+
// This re-exports from the appropriate subdirectories based on which generators are enabled
|
|
167
|
+
if (!options.dryRun) {
|
|
168
|
+
const barrelContent = generateRootBarrel({
|
|
169
|
+
hasTypes: bothEnabled,
|
|
170
|
+
hasHooks: runReactQuery,
|
|
171
|
+
hasOrm: runOrm,
|
|
172
|
+
});
|
|
174
173
|
await writeGeneratedFiles([{ path: 'index.ts', content: barrelContent }], outputRoot, []);
|
|
175
174
|
}
|
|
176
175
|
const generators = [runReactQuery && 'React Query', runOrm && 'ORM'].filter(Boolean).join(' and ');
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Fetch GraphQL schema introspection from an endpoint
|
|
3
3
|
*/
|
|
4
4
|
import dns from 'node:dns';
|
|
5
|
-
import { Agent } from 'undici';
|
|
5
|
+
import { Agent, fetch } from 'undici';
|
|
6
6
|
import { SCHEMA_INTROSPECTION_QUERY } from './schema-query';
|
|
7
7
|
/**
|
|
8
8
|
* Check if a hostname is localhost or a localhost subdomain
|
|
@@ -20,7 +20,14 @@ function createLocalhostAgent() {
|
|
|
20
20
|
connect: {
|
|
21
21
|
lookup(hostname, opts, cb) {
|
|
22
22
|
if (isLocalhostHostname(hostname)) {
|
|
23
|
-
|
|
23
|
+
// When opts.all is true, callback expects an array of {address, family} objects
|
|
24
|
+
// When opts.all is false/undefined, callback expects (err, address, family)
|
|
25
|
+
if (opts.all) {
|
|
26
|
+
cb(null, [{ address: '127.0.0.1', family: 4 }]);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
cb(null, '127.0.0.1', 4);
|
|
30
|
+
}
|
|
24
31
|
return;
|
|
25
32
|
}
|
|
26
33
|
dns.lookup(hostname, opts, cb);
|
|
@@ -59,7 +66,7 @@ export async function fetchSchema(options) {
|
|
|
59
66
|
// Create abort controller for timeout
|
|
60
67
|
const controller = new AbortController();
|
|
61
68
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
62
|
-
// Build fetch options
|
|
69
|
+
// Build fetch options using undici's RequestInit type
|
|
63
70
|
const fetchOptions = {
|
|
64
71
|
method: 'POST',
|
|
65
72
|
headers: requestHeaders,
|
package/esm/types/config.d.ts
CHANGED
|
@@ -223,6 +223,14 @@ export interface GraphQLSDKConfigTarget {
|
|
|
223
223
|
* @default false
|
|
224
224
|
*/
|
|
225
225
|
reactQuery?: boolean;
|
|
226
|
+
/**
|
|
227
|
+
* Generate browser-compatible code using native fetch
|
|
228
|
+
* When true (default), uses native W3C fetch API (works in browsers and Node.js)
|
|
229
|
+
* When false, uses undici fetch with dispatcher support for localhost DNS resolution
|
|
230
|
+
* (Node.js only - enables proper *.localhost subdomain resolution on macOS)
|
|
231
|
+
* @default true
|
|
232
|
+
*/
|
|
233
|
+
browserCompatible?: boolean;
|
|
226
234
|
/**
|
|
227
235
|
* Query key generation configuration
|
|
228
236
|
* Controls how query keys are structured for cache management
|
package/esm/types/config.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@constructive-io/graphql-codegen",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "GraphQL SDK generator for Constructive databases with React Query hooks",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"graphql",
|
|
@@ -35,9 +35,9 @@
|
|
|
35
35
|
"scripts": {
|
|
36
36
|
"clean": "makage clean",
|
|
37
37
|
"prepack": "npm run build",
|
|
38
|
-
"copy:
|
|
39
|
-
"build": "makage build && npm run copy:
|
|
40
|
-
"build:dev": "makage build --dev && npm run copy:
|
|
38
|
+
"copy:templates": "mkdir -p dist/core/codegen/templates && cp src/core/codegen/templates/*.ts dist/core/codegen/templates/",
|
|
39
|
+
"build": "makage build && npm run copy:templates",
|
|
40
|
+
"build:dev": "makage build --dev && npm run copy:templates",
|
|
41
41
|
"dev": "ts-node ./src/index.ts",
|
|
42
42
|
"lint": "eslint . --fix",
|
|
43
43
|
"fmt": "oxfmt --write .",
|
|
@@ -99,5 +99,5 @@
|
|
|
99
99
|
"tsx": "^4.21.0",
|
|
100
100
|
"typescript": "^5.9.3"
|
|
101
101
|
},
|
|
102
|
-
"gitHead": "
|
|
102
|
+
"gitHead": "feaeaaeb78656bccab7725854fb1cfc4e724ba0a"
|
|
103
103
|
}
|
package/types/config.d.ts
CHANGED
|
@@ -223,6 +223,14 @@ export interface GraphQLSDKConfigTarget {
|
|
|
223
223
|
* @default false
|
|
224
224
|
*/
|
|
225
225
|
reactQuery?: boolean;
|
|
226
|
+
/**
|
|
227
|
+
* Generate browser-compatible code using native fetch
|
|
228
|
+
* When true (default), uses native W3C fetch API (works in browsers and Node.js)
|
|
229
|
+
* When false, uses undici fetch with dispatcher support for localhost DNS resolution
|
|
230
|
+
* (Node.js only - enables proper *.localhost subdomain resolution on macOS)
|
|
231
|
+
* @default true
|
|
232
|
+
*/
|
|
233
|
+
browserCompatible?: boolean;
|
|
226
234
|
/**
|
|
227
235
|
* Query key generation configuration
|
|
228
236
|
* Controls how query keys are structured for cache management
|
package/types/config.js
CHANGED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Query Builder - Builds and executes GraphQL operations
|
|
3
|
-
*
|
|
4
|
-
* This is the RUNTIME code that gets copied to generated output.
|
|
5
|
-
* It uses gql-ast to build GraphQL documents programmatically.
|
|
6
|
-
*
|
|
7
|
-
* NOTE: This file is read at codegen time and written to output.
|
|
8
|
-
* Any changes here will affect all generated ORM clients.
|
|
9
|
-
*/
|
|
10
|
-
import type { FieldNode } from 'graphql';
|
|
11
|
-
import { OrmClient, QueryResult } from './client';
|
|
12
|
-
export interface QueryBuilderConfig {
|
|
13
|
-
client: OrmClient;
|
|
14
|
-
operation: 'query' | 'mutation';
|
|
15
|
-
operationName: string;
|
|
16
|
-
fieldName: string;
|
|
17
|
-
document: string;
|
|
18
|
-
variables?: Record<string, unknown>;
|
|
19
|
-
}
|
|
20
|
-
export declare class QueryBuilder<TResult> {
|
|
21
|
-
private config;
|
|
22
|
-
constructor(config: QueryBuilderConfig);
|
|
23
|
-
/**
|
|
24
|
-
* Execute the query and return a discriminated union result
|
|
25
|
-
* Use result.ok to check success, or .unwrap() to throw on error
|
|
26
|
-
*/
|
|
27
|
-
execute(): Promise<QueryResult<TResult>>;
|
|
28
|
-
/**
|
|
29
|
-
* Execute and unwrap the result, throwing GraphQLRequestError on failure
|
|
30
|
-
* @throws {GraphQLRequestError} If the query returns errors
|
|
31
|
-
*/
|
|
32
|
-
unwrap(): Promise<TResult>;
|
|
33
|
-
/**
|
|
34
|
-
* Execute and unwrap, returning defaultValue on error instead of throwing
|
|
35
|
-
*/
|
|
36
|
-
unwrapOr<D>(defaultValue: D): Promise<TResult | D>;
|
|
37
|
-
/**
|
|
38
|
-
* Execute and unwrap, calling onError callback on failure
|
|
39
|
-
*/
|
|
40
|
-
unwrapOrElse<D>(onError: (errors: import('./client').GraphQLError[]) => D): Promise<TResult | D>;
|
|
41
|
-
toGraphQL(): string;
|
|
42
|
-
getVariables(): Record<string, unknown> | undefined;
|
|
43
|
-
}
|
|
44
|
-
export declare function buildSelections(select: Record<string, unknown> | undefined): FieldNode[];
|
|
45
|
-
export declare function buildFindManyDocument<TSelect, TWhere>(operationName: string, queryField: string, select: TSelect, args: {
|
|
46
|
-
where?: TWhere;
|
|
47
|
-
orderBy?: string[];
|
|
48
|
-
first?: number;
|
|
49
|
-
last?: number;
|
|
50
|
-
after?: string;
|
|
51
|
-
before?: string;
|
|
52
|
-
offset?: number;
|
|
53
|
-
}, filterTypeName: string, orderByTypeName: string): {
|
|
54
|
-
document: string;
|
|
55
|
-
variables: Record<string, unknown>;
|
|
56
|
-
};
|
|
57
|
-
export declare function buildFindFirstDocument<TSelect, TWhere>(operationName: string, queryField: string, select: TSelect, args: {
|
|
58
|
-
where?: TWhere;
|
|
59
|
-
}, filterTypeName: string): {
|
|
60
|
-
document: string;
|
|
61
|
-
variables: Record<string, unknown>;
|
|
62
|
-
};
|
|
63
|
-
export declare function buildCreateDocument<TSelect, TData>(operationName: string, mutationField: string, entityField: string, select: TSelect, data: TData, inputTypeName: string): {
|
|
64
|
-
document: string;
|
|
65
|
-
variables: Record<string, unknown>;
|
|
66
|
-
};
|
|
67
|
-
export declare function buildUpdateDocument<TSelect, TWhere extends {
|
|
68
|
-
id: string;
|
|
69
|
-
}, TData>(operationName: string, mutationField: string, entityField: string, select: TSelect, where: TWhere, data: TData, inputTypeName: string): {
|
|
70
|
-
document: string;
|
|
71
|
-
variables: Record<string, unknown>;
|
|
72
|
-
};
|
|
73
|
-
export declare function buildDeleteDocument<TWhere extends {
|
|
74
|
-
id: string;
|
|
75
|
-
}>(operationName: string, mutationField: string, entityField: string, where: TWhere, inputTypeName: string): {
|
|
76
|
-
document: string;
|
|
77
|
-
variables: Record<string, unknown>;
|
|
78
|
-
};
|
|
79
|
-
export declare function buildCustomDocument<TSelect, TArgs>(operationType: 'query' | 'mutation', operationName: string, fieldName: string, select: TSelect, args: TArgs, variableDefinitions: Array<{
|
|
80
|
-
name: string;
|
|
81
|
-
type: string;
|
|
82
|
-
}>): {
|
|
83
|
-
document: string;
|
|
84
|
-
variables: Record<string, unknown>;
|
|
85
|
-
};
|