@constructive-io/graphql-codegen 2.24.1 → 2.26.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/README.md +403 -279
- package/cli/codegen/orm/client-generator.js +475 -136
- package/cli/codegen/orm/custom-ops-generator.js +8 -3
- package/cli/codegen/orm/model-generator.js +18 -5
- package/cli/codegen/orm/select-types.d.ts +33 -0
- package/cli/commands/generate-orm.d.ts +14 -0
- package/cli/commands/generate-orm.js +160 -44
- package/cli/commands/generate.d.ts +22 -0
- package/cli/commands/generate.js +195 -55
- package/cli/commands/init.js +29 -9
- package/cli/index.js +133 -28
- package/cli/watch/orchestrator.d.ts +4 -0
- package/cli/watch/orchestrator.js +4 -0
- package/esm/cli/codegen/orm/client-generator.js +475 -136
- package/esm/cli/codegen/orm/custom-ops-generator.js +8 -3
- package/esm/cli/codegen/orm/model-generator.js +18 -5
- package/esm/cli/codegen/orm/select-types.d.ts +33 -0
- package/esm/cli/commands/generate-orm.d.ts +14 -0
- package/esm/cli/commands/generate-orm.js +161 -45
- package/esm/cli/commands/generate.d.ts +22 -0
- package/esm/cli/commands/generate.js +195 -56
- package/esm/cli/commands/init.js +29 -9
- package/esm/cli/index.js +134 -29
- package/esm/cli/watch/orchestrator.d.ts +4 -0
- package/esm/cli/watch/orchestrator.js +5 -1
- package/esm/types/config.d.ts +39 -2
- package/esm/types/config.js +88 -4
- package/esm/types/index.d.ts +2 -2
- package/esm/types/index.js +1 -1
- package/package.json +10 -7
- package/types/config.d.ts +39 -2
- package/types/config.js +91 -4
- package/types/index.d.ts +2 -2
- package/types/index.js +2 -1
- package/cli/codegen/orm/query-builder.d.ts +0 -161
- package/cli/codegen/orm/query-builder.js +0 -366
- package/esm/cli/codegen/orm/query-builder.d.ts +0 -161
- package/esm/cli/codegen/orm/query-builder.js +0 -353
package/esm/cli/index.js
CHANGED
|
@@ -6,7 +6,18 @@ import { initCommand, findConfigFile, loadConfigFile } from './commands/init';
|
|
|
6
6
|
import { generateCommand } from './commands/generate';
|
|
7
7
|
import { generateOrmCommand } from './commands/generate-orm';
|
|
8
8
|
import { startWatch } from './watch';
|
|
9
|
-
import { resolveConfig, } from '../types/config';
|
|
9
|
+
import { isMultiConfig, mergeConfig, resolveConfig, } from '../types/config';
|
|
10
|
+
/**
|
|
11
|
+
* Format duration in a human-readable way
|
|
12
|
+
* - Under 1 second: show milliseconds (e.g., "123ms")
|
|
13
|
+
* - Over 1 second: show seconds with 2 decimal places (e.g., "1.23s")
|
|
14
|
+
*/
|
|
15
|
+
function formatDuration(ms) {
|
|
16
|
+
if (ms < 1000) {
|
|
17
|
+
return `${Math.round(ms)}ms`;
|
|
18
|
+
}
|
|
19
|
+
return `${(ms / 1000).toFixed(2)}s`;
|
|
20
|
+
}
|
|
10
21
|
const program = new Command();
|
|
11
22
|
/**
|
|
12
23
|
* Load configuration for watch mode, merging CLI options with config file
|
|
@@ -26,23 +37,27 @@ async function loadWatchConfig(options) {
|
|
|
26
37
|
}
|
|
27
38
|
baseConfig = loadResult.config;
|
|
28
39
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
if (isMultiConfig(baseConfig)) {
|
|
41
|
+
if (!options.target) {
|
|
42
|
+
console.error('x Watch mode requires --target when using multiple targets.');
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
if (!baseConfig.targets[options.target]) {
|
|
46
|
+
console.error(`x Target "${options.target}" not found in config file.`);
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else if (options.target) {
|
|
51
|
+
console.error('x Config file does not define targets. Remove --target.');
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
const sourceOverrides = {};
|
|
55
|
+
if (options.endpoint) {
|
|
56
|
+
sourceOverrides.endpoint = options.endpoint;
|
|
57
|
+
sourceOverrides.schema = undefined;
|
|
58
|
+
}
|
|
59
|
+
const watchOverrides = {
|
|
43
60
|
watch: {
|
|
44
|
-
...baseConfig.watch,
|
|
45
|
-
// CLI options override config
|
|
46
61
|
...(options.pollInterval !== undefined && {
|
|
47
62
|
pollInterval: options.pollInterval,
|
|
48
63
|
}),
|
|
@@ -51,11 +66,26 @@ async function loadWatchConfig(options) {
|
|
|
51
66
|
...(options.clear !== undefined && { clearScreen: options.clear }),
|
|
52
67
|
},
|
|
53
68
|
};
|
|
54
|
-
|
|
55
|
-
|
|
69
|
+
let mergedTarget;
|
|
70
|
+
if (isMultiConfig(baseConfig)) {
|
|
71
|
+
const defaults = baseConfig.defaults ?? {};
|
|
72
|
+
const targetConfig = baseConfig.targets[options.target];
|
|
73
|
+
mergedTarget = mergeConfig(defaults, targetConfig);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
mergedTarget = baseConfig;
|
|
77
|
+
}
|
|
78
|
+
mergedTarget = mergeConfig(mergedTarget, sourceOverrides);
|
|
79
|
+
mergedTarget = mergeConfig(mergedTarget, watchOverrides);
|
|
80
|
+
if (!mergedTarget.endpoint) {
|
|
81
|
+
console.error('x No endpoint specified. Watch mode only supports live endpoints.');
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
if (mergedTarget.schema) {
|
|
85
|
+
console.error('x Watch mode is only supported with an endpoint, not schema.');
|
|
56
86
|
return null;
|
|
57
87
|
}
|
|
58
|
-
return resolveConfig(
|
|
88
|
+
return resolveConfig(mergedTarget);
|
|
59
89
|
}
|
|
60
90
|
program
|
|
61
91
|
.name('graphql-codegen')
|
|
@@ -70,17 +100,19 @@ program
|
|
|
70
100
|
.option('-e, --endpoint <url>', 'GraphQL endpoint URL to pre-populate')
|
|
71
101
|
.option('-o, --output <dir>', 'Output directory to pre-populate', './generated')
|
|
72
102
|
.action(async (options) => {
|
|
103
|
+
const startTime = performance.now();
|
|
73
104
|
const result = await initCommand({
|
|
74
105
|
directory: options.directory,
|
|
75
106
|
force: options.force,
|
|
76
107
|
endpoint: options.endpoint,
|
|
77
108
|
output: options.output,
|
|
78
109
|
});
|
|
110
|
+
const duration = formatDuration(performance.now() - startTime);
|
|
79
111
|
if (result.success) {
|
|
80
|
-
console.log('[ok]', result.message);
|
|
112
|
+
console.log('[ok]', result.message, `(${duration})`);
|
|
81
113
|
}
|
|
82
114
|
else {
|
|
83
|
-
console.error('x', result.message);
|
|
115
|
+
console.error('x', result.message, `(${duration})`);
|
|
84
116
|
process.exit(1);
|
|
85
117
|
}
|
|
86
118
|
});
|
|
@@ -89,6 +121,7 @@ program
|
|
|
89
121
|
.command('generate')
|
|
90
122
|
.description('Generate SDK from GraphQL endpoint or schema file')
|
|
91
123
|
.option('-c, --config <path>', 'Path to config file')
|
|
124
|
+
.option('-t, --target <name>', 'Target name in config file')
|
|
92
125
|
.option('-e, --endpoint <url>', 'GraphQL endpoint URL (overrides config)')
|
|
93
126
|
.option('-s, --schema <path>', 'Path to GraphQL schema file (.graphql)')
|
|
94
127
|
.option('-o, --output <dir>', 'Output directory (overrides config)')
|
|
@@ -101,6 +134,7 @@ program
|
|
|
101
134
|
.option('--touch <file>', 'File to touch on schema change')
|
|
102
135
|
.option('--no-clear', 'Do not clear terminal on regeneration')
|
|
103
136
|
.action(async (options) => {
|
|
137
|
+
const startTime = performance.now();
|
|
104
138
|
// Validate source options
|
|
105
139
|
if (options.endpoint && options.schema) {
|
|
106
140
|
console.error('x Cannot use both --endpoint and --schema. Choose one source.');
|
|
@@ -121,6 +155,8 @@ program
|
|
|
121
155
|
generatorType: 'generate',
|
|
122
156
|
verbose: options.verbose,
|
|
123
157
|
authorization: options.authorization,
|
|
158
|
+
configPath: options.config,
|
|
159
|
+
target: options.target,
|
|
124
160
|
outputDir: options.output,
|
|
125
161
|
});
|
|
126
162
|
return;
|
|
@@ -128,6 +164,7 @@ program
|
|
|
128
164
|
// Normal one-shot generation
|
|
129
165
|
const result = await generateCommand({
|
|
130
166
|
config: options.config,
|
|
167
|
+
target: options.target,
|
|
131
168
|
endpoint: options.endpoint,
|
|
132
169
|
schema: options.schema,
|
|
133
170
|
output: options.output,
|
|
@@ -135,8 +172,34 @@ program
|
|
|
135
172
|
verbose: options.verbose,
|
|
136
173
|
dryRun: options.dryRun,
|
|
137
174
|
});
|
|
175
|
+
const duration = formatDuration(performance.now() - startTime);
|
|
176
|
+
const targetResults = result.targets ?? [];
|
|
177
|
+
const hasNamedTargets = targetResults.length > 0 &&
|
|
178
|
+
(targetResults.length > 1 || targetResults[0]?.name !== 'default');
|
|
179
|
+
if (hasNamedTargets) {
|
|
180
|
+
console.log(result.success ? '[ok]' : 'x', result.message);
|
|
181
|
+
targetResults.forEach((target) => {
|
|
182
|
+
const status = target.success ? '[ok]' : 'x';
|
|
183
|
+
console.log(`\n${status} ${target.message}`);
|
|
184
|
+
if (target.tables && target.tables.length > 0) {
|
|
185
|
+
console.log(' Tables:');
|
|
186
|
+
target.tables.forEach((table) => console.log(` - ${table}`));
|
|
187
|
+
}
|
|
188
|
+
if (target.filesWritten && target.filesWritten.length > 0) {
|
|
189
|
+
console.log(' Files written:');
|
|
190
|
+
target.filesWritten.forEach((file) => console.log(` - ${file}`));
|
|
191
|
+
}
|
|
192
|
+
if (!target.success && target.errors) {
|
|
193
|
+
target.errors.forEach((error) => console.error(` - ${error}`));
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
if (!result.success) {
|
|
197
|
+
process.exit(1);
|
|
198
|
+
}
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
138
201
|
if (result.success) {
|
|
139
|
-
console.log('[ok]', result.message);
|
|
202
|
+
console.log('[ok]', result.message, `(${duration})`);
|
|
140
203
|
if (result.tables && result.tables.length > 0) {
|
|
141
204
|
console.log('\nTables:');
|
|
142
205
|
result.tables.forEach((t) => console.log(` - ${t}`));
|
|
@@ -147,7 +210,7 @@ program
|
|
|
147
210
|
}
|
|
148
211
|
}
|
|
149
212
|
else {
|
|
150
|
-
console.error('x', result.message);
|
|
213
|
+
console.error('x', result.message, `(${duration})`);
|
|
151
214
|
if (result.errors) {
|
|
152
215
|
result.errors.forEach((e) => console.error(' -', e));
|
|
153
216
|
}
|
|
@@ -159,9 +222,10 @@ program
|
|
|
159
222
|
.command('generate-orm')
|
|
160
223
|
.description('Generate Prisma-like ORM client from GraphQL endpoint or schema file')
|
|
161
224
|
.option('-c, --config <path>', 'Path to config file')
|
|
225
|
+
.option('-t, --target <name>', 'Target name in config file')
|
|
162
226
|
.option('-e, --endpoint <url>', 'GraphQL endpoint URL (overrides config)')
|
|
163
227
|
.option('-s, --schema <path>', 'Path to GraphQL schema file (.graphql)')
|
|
164
|
-
.option('-o, --output <dir>', 'Output directory (overrides config)'
|
|
228
|
+
.option('-o, --output <dir>', 'Output directory (overrides config)')
|
|
165
229
|
.option('-a, --authorization <header>', 'Authorization header value')
|
|
166
230
|
.option('-v, --verbose', 'Verbose output', false)
|
|
167
231
|
.option('--dry-run', 'Dry run - show what would be generated without writing files', false)
|
|
@@ -172,6 +236,7 @@ program
|
|
|
172
236
|
.option('--touch <file>', 'File to touch on schema change')
|
|
173
237
|
.option('--no-clear', 'Do not clear terminal on regeneration')
|
|
174
238
|
.action(async (options) => {
|
|
239
|
+
const startTime = performance.now();
|
|
175
240
|
// Validate source options
|
|
176
241
|
if (options.endpoint && options.schema) {
|
|
177
242
|
console.error('x Cannot use both --endpoint and --schema. Choose one source.');
|
|
@@ -192,6 +257,8 @@ program
|
|
|
192
257
|
generatorType: 'generate-orm',
|
|
193
258
|
verbose: options.verbose,
|
|
194
259
|
authorization: options.authorization,
|
|
260
|
+
configPath: options.config,
|
|
261
|
+
target: options.target,
|
|
195
262
|
outputDir: options.output,
|
|
196
263
|
skipCustomOperations: options.skipCustomOperations,
|
|
197
264
|
});
|
|
@@ -200,6 +267,7 @@ program
|
|
|
200
267
|
// Normal one-shot generation
|
|
201
268
|
const result = await generateOrmCommand({
|
|
202
269
|
config: options.config,
|
|
270
|
+
target: options.target,
|
|
203
271
|
endpoint: options.endpoint,
|
|
204
272
|
schema: options.schema,
|
|
205
273
|
output: options.output,
|
|
@@ -208,8 +276,42 @@ program
|
|
|
208
276
|
dryRun: options.dryRun,
|
|
209
277
|
skipCustomOperations: options.skipCustomOperations,
|
|
210
278
|
});
|
|
279
|
+
const duration = formatDuration(performance.now() - startTime);
|
|
280
|
+
const targetResults = result.targets ?? [];
|
|
281
|
+
const hasNamedTargets = targetResults.length > 0 &&
|
|
282
|
+
(targetResults.length > 1 || targetResults[0]?.name !== 'default');
|
|
283
|
+
if (hasNamedTargets) {
|
|
284
|
+
console.log(result.success ? '[ok]' : 'x', result.message);
|
|
285
|
+
targetResults.forEach((target) => {
|
|
286
|
+
const status = target.success ? '[ok]' : 'x';
|
|
287
|
+
console.log(`\n${status} ${target.message}`);
|
|
288
|
+
if (target.tables && target.tables.length > 0) {
|
|
289
|
+
console.log(' Tables:');
|
|
290
|
+
target.tables.forEach((table) => console.log(` - ${table}`));
|
|
291
|
+
}
|
|
292
|
+
if (target.customQueries && target.customQueries.length > 0) {
|
|
293
|
+
console.log(' Custom Queries:');
|
|
294
|
+
target.customQueries.forEach((query) => console.log(` - ${query}`));
|
|
295
|
+
}
|
|
296
|
+
if (target.customMutations && target.customMutations.length > 0) {
|
|
297
|
+
console.log(' Custom Mutations:');
|
|
298
|
+
target.customMutations.forEach((mutation) => console.log(` - ${mutation}`));
|
|
299
|
+
}
|
|
300
|
+
if (target.filesWritten && target.filesWritten.length > 0) {
|
|
301
|
+
console.log(' Files written:');
|
|
302
|
+
target.filesWritten.forEach((file) => console.log(` - ${file}`));
|
|
303
|
+
}
|
|
304
|
+
if (!target.success && target.errors) {
|
|
305
|
+
target.errors.forEach((error) => console.error(` - ${error}`));
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
if (!result.success) {
|
|
309
|
+
process.exit(1);
|
|
310
|
+
}
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
211
313
|
if (result.success) {
|
|
212
|
-
console.log('[ok]', result.message);
|
|
314
|
+
console.log('[ok]', result.message, `(${duration})`);
|
|
213
315
|
if (result.tables && result.tables.length > 0) {
|
|
214
316
|
console.log('\nTables:');
|
|
215
317
|
result.tables.forEach((t) => console.log(` - ${t}`));
|
|
@@ -228,7 +330,7 @@ program
|
|
|
228
330
|
}
|
|
229
331
|
}
|
|
230
332
|
else {
|
|
231
|
-
console.error('x', result.message);
|
|
333
|
+
console.error('x', result.message, `(${duration})`);
|
|
232
334
|
if (result.errors) {
|
|
233
335
|
result.errors.forEach((e) => console.error(' -', e));
|
|
234
336
|
}
|
|
@@ -244,6 +346,7 @@ program
|
|
|
244
346
|
.option('-a, --authorization <header>', 'Authorization header value')
|
|
245
347
|
.option('--json', 'Output as JSON', false)
|
|
246
348
|
.action(async (options) => {
|
|
349
|
+
const startTime = performance.now();
|
|
247
350
|
// Validate source options
|
|
248
351
|
if (!options.endpoint && !options.schema) {
|
|
249
352
|
console.error('x Either --endpoint or --schema must be provided.');
|
|
@@ -264,11 +367,12 @@ program
|
|
|
264
367
|
console.log('Fetching schema from', source.describe(), '...');
|
|
265
368
|
const { introspection } = await source.fetch();
|
|
266
369
|
const tables = inferTablesFromIntrospection(introspection);
|
|
370
|
+
const duration = formatDuration(performance.now() - startTime);
|
|
267
371
|
if (options.json) {
|
|
268
372
|
console.log(JSON.stringify(tables, null, 2));
|
|
269
373
|
}
|
|
270
374
|
else {
|
|
271
|
-
console.log(`\n[ok] Found ${tables.length} tables:\n`);
|
|
375
|
+
console.log(`\n[ok] Found ${tables.length} tables (${duration}):\n`);
|
|
272
376
|
tables.forEach((table) => {
|
|
273
377
|
const fieldCount = table.fields.length;
|
|
274
378
|
const relationCount = table.relations.belongsTo.length +
|
|
@@ -280,7 +384,8 @@ program
|
|
|
280
384
|
}
|
|
281
385
|
}
|
|
282
386
|
catch (err) {
|
|
283
|
-
|
|
387
|
+
const duration = formatDuration(performance.now() - startTime);
|
|
388
|
+
console.error('x Failed to introspect schema:', err instanceof Error ? err.message : err, `(${duration})`);
|
|
284
389
|
process.exit(1);
|
|
285
390
|
}
|
|
286
391
|
});
|
|
@@ -10,6 +10,10 @@ export interface WatchOrchestratorOptions {
|
|
|
10
10
|
generatorType: GeneratorType;
|
|
11
11
|
verbose: boolean;
|
|
12
12
|
authorization?: string;
|
|
13
|
+
/** Config file path for regeneration */
|
|
14
|
+
configPath?: string;
|
|
15
|
+
/** Target name for multi-target configs */
|
|
16
|
+
target?: string;
|
|
13
17
|
/** Override output directory (for ORM) */
|
|
14
18
|
outputDir?: string;
|
|
15
19
|
/** Skip custom operations flag */
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { SchemaPoller } from './poller';
|
|
7
7
|
import { debounce } from './debounce';
|
|
8
8
|
import { generateCommand } from '../commands/generate';
|
|
9
|
-
import { generateOrmCommand } from '../commands/generate-orm';
|
|
9
|
+
import { generateOrmCommand, } from '../commands/generate-orm';
|
|
10
10
|
/**
|
|
11
11
|
* Main watch orchestrator class
|
|
12
12
|
*/
|
|
@@ -134,6 +134,8 @@ export class WatchOrchestrator {
|
|
|
134
134
|
let result;
|
|
135
135
|
if (this.options.generatorType === 'generate') {
|
|
136
136
|
result = await generateCommand({
|
|
137
|
+
config: this.options.configPath,
|
|
138
|
+
target: this.options.target,
|
|
137
139
|
endpoint: this.options.config.endpoint,
|
|
138
140
|
output: this.options.outputDir ?? this.options.config.output,
|
|
139
141
|
authorization: this.options.authorization,
|
|
@@ -143,6 +145,8 @@ export class WatchOrchestrator {
|
|
|
143
145
|
}
|
|
144
146
|
else {
|
|
145
147
|
result = await generateOrmCommand({
|
|
148
|
+
config: this.options.configPath,
|
|
149
|
+
target: this.options.target,
|
|
146
150
|
endpoint: this.options.config.endpoint,
|
|
147
151
|
output: this.options.outputDir ?? this.options.config.orm?.output,
|
|
148
152
|
authorization: this.options.authorization,
|
package/esm/types/config.d.ts
CHANGED
|
@@ -57,9 +57,10 @@ export interface QueryKeyConfig {
|
|
|
57
57
|
generateMutationKeys?: boolean;
|
|
58
58
|
}
|
|
59
59
|
/**
|
|
60
|
-
*
|
|
60
|
+
* Target configuration for graphql-codegen
|
|
61
|
+
* Represents a single schema source and output destination.
|
|
61
62
|
*/
|
|
62
|
-
export interface
|
|
63
|
+
export interface GraphQLSDKConfigTarget {
|
|
63
64
|
/**
|
|
64
65
|
* GraphQL endpoint URL for live introspection
|
|
65
66
|
* Either endpoint or schema must be provided
|
|
@@ -179,6 +180,23 @@ export interface GraphQLSDKConfig {
|
|
|
179
180
|
*/
|
|
180
181
|
watch?: WatchConfig;
|
|
181
182
|
}
|
|
183
|
+
/**
|
|
184
|
+
* Multi-target configuration for graphql-codegen
|
|
185
|
+
*/
|
|
186
|
+
export interface GraphQLSDKMultiConfig {
|
|
187
|
+
/**
|
|
188
|
+
* Shared defaults applied to every target
|
|
189
|
+
*/
|
|
190
|
+
defaults?: GraphQLSDKConfigTarget;
|
|
191
|
+
/**
|
|
192
|
+
* Named target configurations
|
|
193
|
+
*/
|
|
194
|
+
targets: Record<string, GraphQLSDKConfigTarget>;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Main configuration type for graphql-codegen
|
|
198
|
+
*/
|
|
199
|
+
export type GraphQLSDKConfig = GraphQLSDKConfigTarget | GraphQLSDKMultiConfig;
|
|
182
200
|
/**
|
|
183
201
|
* Watch mode configuration options
|
|
184
202
|
*
|
|
@@ -299,7 +317,26 @@ export declare const DEFAULT_ORM_CONFIG: {
|
|
|
299
317
|
* Helper function to define configuration with type checking
|
|
300
318
|
*/
|
|
301
319
|
export declare function defineConfig(config: GraphQLSDKConfig): GraphQLSDKConfig;
|
|
320
|
+
/**
|
|
321
|
+
* Resolved target configuration helper
|
|
322
|
+
*/
|
|
323
|
+
export interface ResolvedTargetConfig {
|
|
324
|
+
name: string;
|
|
325
|
+
config: ResolvedConfig;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Type guard for multi-target configs
|
|
329
|
+
*/
|
|
330
|
+
export declare function isMultiConfig(config: GraphQLSDKConfig): config is GraphQLSDKMultiConfig;
|
|
331
|
+
/**
|
|
332
|
+
* Merge two target configs (defaults + overrides)
|
|
333
|
+
*/
|
|
334
|
+
export declare function mergeConfig(base: GraphQLSDKConfigTarget, overrides: GraphQLSDKConfigTarget): GraphQLSDKConfigTarget;
|
|
302
335
|
/**
|
|
303
336
|
* Resolve configuration by applying defaults
|
|
304
337
|
*/
|
|
305
338
|
export declare function resolveConfig(config: GraphQLSDKConfig): ResolvedConfig;
|
|
339
|
+
/**
|
|
340
|
+
* Resolve all targets in a multi-target config
|
|
341
|
+
*/
|
|
342
|
+
export declare function resolveConfigTargets(config: GraphQLSDKMultiConfig): ResolvedTargetConfig[];
|
package/esm/types/config.js
CHANGED
|
@@ -71,10 +71,80 @@ export const DEFAULT_ORM_CONFIG = {
|
|
|
71
71
|
export function defineConfig(config) {
|
|
72
72
|
return config;
|
|
73
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* Type guard for multi-target configs
|
|
76
|
+
*/
|
|
77
|
+
export function isMultiConfig(config) {
|
|
78
|
+
const targets = config.targets;
|
|
79
|
+
return typeof targets === 'object' && targets !== null;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Merge two target configs (defaults + overrides)
|
|
83
|
+
*/
|
|
84
|
+
export function mergeConfig(base, overrides) {
|
|
85
|
+
const headers = base.headers || overrides.headers
|
|
86
|
+
? { ...(base.headers ?? {}), ...(overrides.headers ?? {}) }
|
|
87
|
+
: undefined;
|
|
88
|
+
const tables = base.tables || overrides.tables
|
|
89
|
+
? { ...(base.tables ?? {}), ...(overrides.tables ?? {}) }
|
|
90
|
+
: undefined;
|
|
91
|
+
const queries = base.queries || overrides.queries
|
|
92
|
+
? { ...(base.queries ?? {}), ...(overrides.queries ?? {}) }
|
|
93
|
+
: undefined;
|
|
94
|
+
const mutations = base.mutations || overrides.mutations
|
|
95
|
+
? { ...(base.mutations ?? {}), ...(overrides.mutations ?? {}) }
|
|
96
|
+
: undefined;
|
|
97
|
+
const hooks = base.hooks || overrides.hooks
|
|
98
|
+
? { ...(base.hooks ?? {}), ...(overrides.hooks ?? {}) }
|
|
99
|
+
: undefined;
|
|
100
|
+
const postgraphile = base.postgraphile || overrides.postgraphile
|
|
101
|
+
? { ...(base.postgraphile ?? {}), ...(overrides.postgraphile ?? {}) }
|
|
102
|
+
: undefined;
|
|
103
|
+
const codegen = base.codegen || overrides.codegen
|
|
104
|
+
? { ...(base.codegen ?? {}), ...(overrides.codegen ?? {}) }
|
|
105
|
+
: undefined;
|
|
106
|
+
const orm = base.orm || overrides.orm
|
|
107
|
+
? { ...(base.orm ?? {}), ...(overrides.orm ?? {}) }
|
|
108
|
+
: undefined;
|
|
109
|
+
const reactQuery = base.reactQuery || overrides.reactQuery
|
|
110
|
+
? { ...(base.reactQuery ?? {}), ...(overrides.reactQuery ?? {}) }
|
|
111
|
+
: undefined;
|
|
112
|
+
const queryKeys = base.queryKeys || overrides.queryKeys
|
|
113
|
+
? {
|
|
114
|
+
...(base.queryKeys ?? {}),
|
|
115
|
+
...(overrides.queryKeys ?? {}),
|
|
116
|
+
relationships: {
|
|
117
|
+
...(base.queryKeys?.relationships ?? {}),
|
|
118
|
+
...(overrides.queryKeys?.relationships ?? {}),
|
|
119
|
+
},
|
|
120
|
+
}
|
|
121
|
+
: undefined;
|
|
122
|
+
const watch = base.watch || overrides.watch
|
|
123
|
+
? { ...(base.watch ?? {}), ...(overrides.watch ?? {}) }
|
|
124
|
+
: undefined;
|
|
125
|
+
return {
|
|
126
|
+
...base,
|
|
127
|
+
...overrides,
|
|
128
|
+
headers,
|
|
129
|
+
tables,
|
|
130
|
+
queries,
|
|
131
|
+
mutations,
|
|
132
|
+
hooks,
|
|
133
|
+
postgraphile,
|
|
134
|
+
codegen,
|
|
135
|
+
orm,
|
|
136
|
+
reactQuery,
|
|
137
|
+
queryKeys,
|
|
138
|
+
watch,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
74
141
|
/**
|
|
75
142
|
* Resolve configuration by applying defaults
|
|
76
143
|
*/
|
|
77
144
|
export function resolveConfig(config) {
|
|
145
|
+
if (isMultiConfig(config)) {
|
|
146
|
+
throw new Error('Multi-target config cannot be resolved with resolveConfig(). Use resolveConfigTargets().');
|
|
147
|
+
}
|
|
78
148
|
return {
|
|
79
149
|
endpoint: config.endpoint ?? '',
|
|
80
150
|
schema: config.schema ?? null,
|
|
@@ -116,10 +186,14 @@ export function resolveConfig(config) {
|
|
|
116
186
|
},
|
|
117
187
|
queryKeys: {
|
|
118
188
|
style: config.queryKeys?.style ?? DEFAULT_QUERY_KEY_CONFIG.style,
|
|
119
|
-
relationships: config.queryKeys?.relationships ??
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
189
|
+
relationships: config.queryKeys?.relationships ??
|
|
190
|
+
DEFAULT_QUERY_KEY_CONFIG.relationships,
|
|
191
|
+
generateScopedKeys: config.queryKeys?.generateScopedKeys ??
|
|
192
|
+
DEFAULT_QUERY_KEY_CONFIG.generateScopedKeys,
|
|
193
|
+
generateCascadeHelpers: config.queryKeys?.generateCascadeHelpers ??
|
|
194
|
+
DEFAULT_QUERY_KEY_CONFIG.generateCascadeHelpers,
|
|
195
|
+
generateMutationKeys: config.queryKeys?.generateMutationKeys ??
|
|
196
|
+
DEFAULT_QUERY_KEY_CONFIG.generateMutationKeys,
|
|
123
197
|
},
|
|
124
198
|
watch: {
|
|
125
199
|
pollInterval: config.watch?.pollInterval ?? DEFAULT_WATCH_CONFIG.pollInterval,
|
|
@@ -129,3 +203,13 @@ export function resolveConfig(config) {
|
|
|
129
203
|
},
|
|
130
204
|
};
|
|
131
205
|
}
|
|
206
|
+
/**
|
|
207
|
+
* Resolve all targets in a multi-target config
|
|
208
|
+
*/
|
|
209
|
+
export function resolveConfigTargets(config) {
|
|
210
|
+
const defaults = config.defaults ?? {};
|
|
211
|
+
return Object.entries(config.targets).map(([name, target]) => ({
|
|
212
|
+
name,
|
|
213
|
+
config: resolveConfig(mergeConfig(defaults, target)),
|
|
214
|
+
}));
|
|
215
|
+
}
|
package/esm/types/index.d.ts
CHANGED
|
@@ -5,5 +5,5 @@ export type { CleanTable, CleanField, CleanFieldType, CleanRelations, CleanBelon
|
|
|
5
5
|
export type { PageInfo, ConnectionResult, QueryOptions, OrderByItem, FilterOperator, FieldFilter, RelationalFilter, Filter, } from './query';
|
|
6
6
|
export type { MutationOptions, CreateInput, UpdateInput, DeleteInput, MutationResult, } from './mutation';
|
|
7
7
|
export type { SimpleFieldSelection, FieldSelectionPreset, FieldSelection, SelectionOptions, } from './selection';
|
|
8
|
-
export type { GraphQLSDKConfig, ResolvedConfig, } from './config';
|
|
9
|
-
export { defineConfig, resolveConfig, DEFAULT_CONFIG } from './config';
|
|
8
|
+
export type { GraphQLSDKConfig, GraphQLSDKConfigTarget, GraphQLSDKMultiConfig, ResolvedConfig, ResolvedTargetConfig, } from './config';
|
|
9
|
+
export { defineConfig, resolveConfig, resolveConfigTargets, DEFAULT_CONFIG, } from './config';
|
package/esm/types/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@constructive-io/graphql-codegen",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.26.0",
|
|
4
4
|
"description": "CLI-based GraphQL SDK generator for PostGraphile endpoints with React Query hooks",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"graphql",
|
|
@@ -39,25 +39,28 @@
|
|
|
39
39
|
"build:dev": "makage build --dev",
|
|
40
40
|
"dev": "ts-node ./src/index.ts",
|
|
41
41
|
"lint": "eslint . --fix",
|
|
42
|
+
"fmt": "oxfmt",
|
|
43
|
+
"fmt:check": "oxfmt --check",
|
|
42
44
|
"test": "jest --passWithNoTests",
|
|
43
45
|
"test:watch": "jest --watch",
|
|
44
|
-
"example:codegen:sdk": "
|
|
45
|
-
"example:codegen:orm": "
|
|
46
|
+
"example:codegen:sdk": "tsx src/cli/index.ts generate --config examples/multi-target.config.ts",
|
|
47
|
+
"example:codegen:orm": "tsx src/cli/index.ts generate-orm --config examples/multi-target.config.ts",
|
|
46
48
|
"example:codegen:sdk:schema": "node dist/cli/index.js generate --schema examples/example.schema.graphql --output examples/output/generated-sdk-schema",
|
|
47
49
|
"example:codegen:orm:schema": "node dist/cli/index.js generate-orm --schema examples/example.schema.graphql --output examples/output/generated-orm-schema",
|
|
48
50
|
"example:sdk": "tsx examples/react-query-sdk.ts",
|
|
49
|
-
"example:orm": "tsx examples/orm-sdk.ts"
|
|
51
|
+
"example:orm": "tsx examples/orm-sdk.ts",
|
|
52
|
+
"example:sdk:typecheck": "tsc --noEmit --jsx react --esModuleInterop --skipLibCheck --moduleResolution node examples/react-hooks-test.tsx"
|
|
50
53
|
},
|
|
51
54
|
"dependencies": {
|
|
52
55
|
"@babel/generator": "^7.28.5",
|
|
53
56
|
"@babel/types": "^7.28.5",
|
|
54
57
|
"ajv": "^8.17.1",
|
|
55
58
|
"commander": "^12.1.0",
|
|
56
|
-
"gql-ast": "^2.
|
|
59
|
+
"gql-ast": "^2.5.0",
|
|
57
60
|
"graphql": "15.10.1",
|
|
58
61
|
"inflekt": "^0.2.0",
|
|
59
62
|
"jiti": "^2.6.1",
|
|
60
|
-
"
|
|
63
|
+
"oxfmt": "^0.13.0"
|
|
61
64
|
},
|
|
62
65
|
"peerDependencies": {
|
|
63
66
|
"@tanstack/react-query": "^5.0.0",
|
|
@@ -83,5 +86,5 @@
|
|
|
83
86
|
"tsx": "^4.21.0",
|
|
84
87
|
"typescript": "^5.9.3"
|
|
85
88
|
},
|
|
86
|
-
"gitHead": "
|
|
89
|
+
"gitHead": "b7abf2fdaf0a827d79a80c9c0a29e5c960f227df"
|
|
87
90
|
}
|
package/types/config.d.ts
CHANGED
|
@@ -57,9 +57,10 @@ export interface QueryKeyConfig {
|
|
|
57
57
|
generateMutationKeys?: boolean;
|
|
58
58
|
}
|
|
59
59
|
/**
|
|
60
|
-
*
|
|
60
|
+
* Target configuration for graphql-codegen
|
|
61
|
+
* Represents a single schema source and output destination.
|
|
61
62
|
*/
|
|
62
|
-
export interface
|
|
63
|
+
export interface GraphQLSDKConfigTarget {
|
|
63
64
|
/**
|
|
64
65
|
* GraphQL endpoint URL for live introspection
|
|
65
66
|
* Either endpoint or schema must be provided
|
|
@@ -179,6 +180,23 @@ export interface GraphQLSDKConfig {
|
|
|
179
180
|
*/
|
|
180
181
|
watch?: WatchConfig;
|
|
181
182
|
}
|
|
183
|
+
/**
|
|
184
|
+
* Multi-target configuration for graphql-codegen
|
|
185
|
+
*/
|
|
186
|
+
export interface GraphQLSDKMultiConfig {
|
|
187
|
+
/**
|
|
188
|
+
* Shared defaults applied to every target
|
|
189
|
+
*/
|
|
190
|
+
defaults?: GraphQLSDKConfigTarget;
|
|
191
|
+
/**
|
|
192
|
+
* Named target configurations
|
|
193
|
+
*/
|
|
194
|
+
targets: Record<string, GraphQLSDKConfigTarget>;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Main configuration type for graphql-codegen
|
|
198
|
+
*/
|
|
199
|
+
export type GraphQLSDKConfig = GraphQLSDKConfigTarget | GraphQLSDKMultiConfig;
|
|
182
200
|
/**
|
|
183
201
|
* Watch mode configuration options
|
|
184
202
|
*
|
|
@@ -299,7 +317,26 @@ export declare const DEFAULT_ORM_CONFIG: {
|
|
|
299
317
|
* Helper function to define configuration with type checking
|
|
300
318
|
*/
|
|
301
319
|
export declare function defineConfig(config: GraphQLSDKConfig): GraphQLSDKConfig;
|
|
320
|
+
/**
|
|
321
|
+
* Resolved target configuration helper
|
|
322
|
+
*/
|
|
323
|
+
export interface ResolvedTargetConfig {
|
|
324
|
+
name: string;
|
|
325
|
+
config: ResolvedConfig;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Type guard for multi-target configs
|
|
329
|
+
*/
|
|
330
|
+
export declare function isMultiConfig(config: GraphQLSDKConfig): config is GraphQLSDKMultiConfig;
|
|
331
|
+
/**
|
|
332
|
+
* Merge two target configs (defaults + overrides)
|
|
333
|
+
*/
|
|
334
|
+
export declare function mergeConfig(base: GraphQLSDKConfigTarget, overrides: GraphQLSDKConfigTarget): GraphQLSDKConfigTarget;
|
|
302
335
|
/**
|
|
303
336
|
* Resolve configuration by applying defaults
|
|
304
337
|
*/
|
|
305
338
|
export declare function resolveConfig(config: GraphQLSDKConfig): ResolvedConfig;
|
|
339
|
+
/**
|
|
340
|
+
* Resolve all targets in a multi-target config
|
|
341
|
+
*/
|
|
342
|
+
export declare function resolveConfigTargets(config: GraphQLSDKMultiConfig): ResolvedTargetConfig[];
|