@constructive-io/graphql-codegen 2.22.1 → 2.23.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.
Files changed (95) hide show
  1. package/cli/codegen/barrel.d.ts +5 -1
  2. package/cli/codegen/barrel.js +13 -11
  3. package/cli/codegen/index.d.ts +3 -3
  4. package/cli/codegen/index.js +15 -9
  5. package/cli/codegen/orm/client-generator.js +3 -2
  6. package/cli/codegen/orm/custom-ops-generator.js +17 -4
  7. package/cli/codegen/orm/input-types-generator.js +129 -18
  8. package/cli/codegen/orm/model-generator.js +2 -1
  9. package/cli/codegen/orm/query-builder.d.ts +1 -1
  10. package/cli/codegen/orm/query-builder.js +2 -2
  11. package/cli/codegen/schema-types-generator.js +5 -5
  12. package/cli/codegen/utils.d.ts +6 -1
  13. package/cli/codegen/utils.js +23 -8
  14. package/cli/commands/generate-orm.d.ts +5 -3
  15. package/cli/commands/generate-orm.js +65 -84
  16. package/cli/commands/generate.d.ts +2 -0
  17. package/cli/commands/generate.js +66 -87
  18. package/cli/commands/shared.d.ts +74 -0
  19. package/cli/commands/shared.js +88 -0
  20. package/cli/index.js +75 -45
  21. package/cli/introspect/index.d.ts +8 -5
  22. package/cli/introspect/index.js +19 -7
  23. package/cli/introspect/infer-tables.d.ts +51 -0
  24. package/cli/introspect/infer-tables.js +550 -0
  25. package/cli/introspect/pluralize.d.ts +30 -0
  26. package/cli/introspect/pluralize.js +124 -0
  27. package/cli/introspect/source/endpoint.d.ts +34 -0
  28. package/cli/introspect/source/endpoint.js +35 -0
  29. package/cli/introspect/source/file.d.ts +20 -0
  30. package/cli/introspect/source/file.js +103 -0
  31. package/cli/introspect/source/index.d.ts +48 -0
  32. package/cli/introspect/source/index.js +72 -0
  33. package/cli/introspect/source/types.d.ts +58 -0
  34. package/cli/introspect/source/types.js +27 -0
  35. package/cli/introspect/transform.d.ts +5 -6
  36. package/cli/introspect/transform.js +0 -173
  37. package/cli/watch/cache.d.ts +3 -4
  38. package/cli/watch/cache.js +6 -10
  39. package/cli/watch/poller.d.ts +1 -2
  40. package/cli/watch/poller.js +27 -45
  41. package/cli/watch/types.d.ts +0 -3
  42. package/esm/cli/codegen/barrel.d.ts +5 -1
  43. package/esm/cli/codegen/barrel.js +13 -11
  44. package/esm/cli/codegen/index.d.ts +3 -3
  45. package/esm/cli/codegen/index.js +18 -12
  46. package/esm/cli/codegen/orm/client-generator.js +3 -2
  47. package/esm/cli/codegen/orm/custom-ops-generator.js +18 -5
  48. package/esm/cli/codegen/orm/input-types-generator.js +130 -19
  49. package/esm/cli/codegen/orm/model-generator.js +3 -2
  50. package/esm/cli/codegen/orm/query-builder.d.ts +1 -1
  51. package/esm/cli/codegen/orm/query-builder.js +2 -2
  52. package/esm/cli/codegen/schema-types-generator.js +6 -6
  53. package/esm/cli/codegen/utils.d.ts +6 -1
  54. package/esm/cli/codegen/utils.js +22 -8
  55. package/esm/cli/commands/generate-orm.d.ts +5 -3
  56. package/esm/cli/commands/generate-orm.js +65 -84
  57. package/esm/cli/commands/generate.d.ts +2 -0
  58. package/esm/cli/commands/generate.js +66 -87
  59. package/esm/cli/commands/shared.d.ts +74 -0
  60. package/esm/cli/commands/shared.js +84 -0
  61. package/esm/cli/index.js +76 -46
  62. package/esm/cli/introspect/index.d.ts +8 -5
  63. package/esm/cli/introspect/index.js +10 -3
  64. package/esm/cli/introspect/infer-tables.d.ts +51 -0
  65. package/esm/cli/introspect/infer-tables.js +547 -0
  66. package/esm/cli/introspect/pluralize.d.ts +30 -0
  67. package/esm/cli/introspect/pluralize.js +83 -0
  68. package/esm/cli/introspect/source/endpoint.d.ts +34 -0
  69. package/esm/cli/introspect/source/endpoint.js +31 -0
  70. package/esm/cli/introspect/source/file.d.ts +20 -0
  71. package/esm/cli/introspect/source/file.js +66 -0
  72. package/esm/cli/introspect/source/index.d.ts +48 -0
  73. package/esm/cli/introspect/source/index.js +54 -0
  74. package/esm/cli/introspect/source/types.d.ts +58 -0
  75. package/esm/cli/introspect/source/types.js +23 -0
  76. package/esm/cli/introspect/transform.d.ts +5 -6
  77. package/esm/cli/introspect/transform.js +0 -172
  78. package/esm/cli/watch/cache.d.ts +3 -4
  79. package/esm/cli/watch/cache.js +7 -11
  80. package/esm/cli/watch/poller.d.ts +1 -2
  81. package/esm/cli/watch/poller.js +28 -46
  82. package/esm/cli/watch/types.d.ts +0 -3
  83. package/esm/types/config.d.ts +21 -5
  84. package/esm/types/config.js +2 -1
  85. package/package.json +4 -2
  86. package/types/config.d.ts +21 -5
  87. package/types/config.js +2 -1
  88. package/cli/introspect/fetch-meta.d.ts +0 -31
  89. package/cli/introspect/fetch-meta.js +0 -108
  90. package/cli/introspect/meta-query.d.ts +0 -111
  91. package/cli/introspect/meta-query.js +0 -191
  92. package/esm/cli/introspect/fetch-meta.d.ts +0 -31
  93. package/esm/cli/introspect/fetch-meta.js +0 -104
  94. package/esm/cli/introspect/meta-query.d.ts +0 -111
  95. package/esm/cli/introspect/meta-query.js +0 -188
package/cli/index.js CHANGED
@@ -56,7 +56,7 @@ async function loadWatchConfig(options) {
56
56
  if (configPath) {
57
57
  const loadResult = await (0, init_1.loadConfigFile)(configPath);
58
58
  if (!loadResult.success) {
59
- console.error('', loadResult.error);
59
+ console.error('x', loadResult.error);
60
60
  return null;
61
61
  }
62
62
  baseConfig = loadResult.config;
@@ -77,21 +77,23 @@ async function loadWatchConfig(options) {
77
77
  watch: {
78
78
  ...baseConfig.watch,
79
79
  // CLI options override config
80
- ...(options.pollInterval !== undefined && { pollInterval: options.pollInterval }),
80
+ ...(options.pollInterval !== undefined && {
81
+ pollInterval: options.pollInterval,
82
+ }),
81
83
  ...(options.debounce !== undefined && { debounce: options.debounce }),
82
84
  ...(options.touch !== undefined && { touchFile: options.touch }),
83
85
  ...(options.clear !== undefined && { clearScreen: options.clear }),
84
86
  },
85
87
  };
86
88
  if (!mergedConfig.endpoint) {
87
- console.error(' No endpoint specified. Use --endpoint or create a config file with "graphql-codegen init".');
89
+ console.error('x No endpoint specified. Use --endpoint or create a config file with "graphql-codegen init".');
88
90
  return null;
89
91
  }
90
92
  return (0, config_1.resolveConfig)(mergedConfig);
91
93
  }
92
94
  program
93
95
  .name('graphql-codegen')
94
- .description('CLI for generating GraphQL SDK from PostGraphile endpoints')
96
+ .description('CLI for generating GraphQL SDK from PostGraphile endpoints or schema files')
95
97
  .version('2.17.48');
96
98
  // Init command
97
99
  program
@@ -109,19 +111,20 @@ program
109
111
  output: options.output,
110
112
  });
111
113
  if (result.success) {
112
- console.log('', result.message);
114
+ console.log('[ok]', result.message);
113
115
  }
114
116
  else {
115
- console.error('', result.message);
117
+ console.error('x', result.message);
116
118
  process.exit(1);
117
119
  }
118
120
  });
119
121
  // Generate command
120
122
  program
121
123
  .command('generate')
122
- .description('Generate SDK from GraphQL endpoint')
124
+ .description('Generate SDK from GraphQL endpoint or schema file')
123
125
  .option('-c, --config <path>', 'Path to config file')
124
126
  .option('-e, --endpoint <url>', 'GraphQL endpoint URL (overrides config)')
127
+ .option('-s, --schema <path>', 'Path to GraphQL schema file (.graphql)')
125
128
  .option('-o, --output <dir>', 'Output directory (overrides config)')
126
129
  .option('-a, --authorization <header>', 'Authorization header value')
127
130
  .option('-v, --verbose', 'Verbose output', false)
@@ -132,8 +135,17 @@ program
132
135
  .option('--touch <file>', 'File to touch on schema change')
133
136
  .option('--no-clear', 'Do not clear terminal on regeneration')
134
137
  .action(async (options) => {
135
- // Watch mode
138
+ // Validate source options
139
+ if (options.endpoint && options.schema) {
140
+ console.error('x Cannot use both --endpoint and --schema. Choose one source.');
141
+ process.exit(1);
142
+ }
143
+ // Watch mode (only for endpoint)
136
144
  if (options.watch) {
145
+ if (options.schema) {
146
+ console.error('x Watch mode is only supported with --endpoint, not --schema.');
147
+ process.exit(1);
148
+ }
137
149
  const config = await loadWatchConfig(options);
138
150
  if (!config) {
139
151
  process.exit(1);
@@ -151,13 +163,14 @@ program
151
163
  const result = await (0, generate_1.generateCommand)({
152
164
  config: options.config,
153
165
  endpoint: options.endpoint,
166
+ schema: options.schema,
154
167
  output: options.output,
155
168
  authorization: options.authorization,
156
169
  verbose: options.verbose,
157
170
  dryRun: options.dryRun,
158
171
  });
159
172
  if (result.success) {
160
- console.log('', result.message);
173
+ console.log('[ok]', result.message);
161
174
  if (result.tables && result.tables.length > 0) {
162
175
  console.log('\nTables:');
163
176
  result.tables.forEach((t) => console.log(` - ${t}`));
@@ -168,7 +181,7 @@ program
168
181
  }
169
182
  }
170
183
  else {
171
- console.error('', result.message);
184
+ console.error('x', result.message);
172
185
  if (result.errors) {
173
186
  result.errors.forEach((e) => console.error(' -', e));
174
187
  }
@@ -178,9 +191,10 @@ program
178
191
  // Generate ORM command
179
192
  program
180
193
  .command('generate-orm')
181
- .description('Generate Prisma-like ORM client from GraphQL endpoint')
194
+ .description('Generate Prisma-like ORM client from GraphQL endpoint or schema file')
182
195
  .option('-c, --config <path>', 'Path to config file')
183
196
  .option('-e, --endpoint <url>', 'GraphQL endpoint URL (overrides config)')
197
+ .option('-s, --schema <path>', 'Path to GraphQL schema file (.graphql)')
184
198
  .option('-o, --output <dir>', 'Output directory (overrides config)', './generated/orm')
185
199
  .option('-a, --authorization <header>', 'Authorization header value')
186
200
  .option('-v, --verbose', 'Verbose output', false)
@@ -192,8 +206,17 @@ program
192
206
  .option('--touch <file>', 'File to touch on schema change')
193
207
  .option('--no-clear', 'Do not clear terminal on regeneration')
194
208
  .action(async (options) => {
195
- // Watch mode
209
+ // Validate source options
210
+ if (options.endpoint && options.schema) {
211
+ console.error('x Cannot use both --endpoint and --schema. Choose one source.');
212
+ process.exit(1);
213
+ }
214
+ // Watch mode (only for endpoint)
196
215
  if (options.watch) {
216
+ if (options.schema) {
217
+ console.error('x Watch mode is only supported with --endpoint, not --schema.');
218
+ process.exit(1);
219
+ }
197
220
  const config = await loadWatchConfig(options);
198
221
  if (!config) {
199
222
  process.exit(1);
@@ -212,6 +235,7 @@ program
212
235
  const result = await (0, generate_orm_1.generateOrmCommand)({
213
236
  config: options.config,
214
237
  endpoint: options.endpoint,
238
+ schema: options.schema,
215
239
  output: options.output,
216
240
  authorization: options.authorization,
217
241
  verbose: options.verbose,
@@ -219,7 +243,7 @@ program
219
243
  skipCustomOperations: options.skipCustomOperations,
220
244
  });
221
245
  if (result.success) {
222
- console.log('', result.message);
246
+ console.log('[ok]', result.message);
223
247
  if (result.tables && result.tables.length > 0) {
224
248
  console.log('\nTables:');
225
249
  result.tables.forEach((t) => console.log(` - ${t}`));
@@ -238,54 +262,60 @@ program
238
262
  }
239
263
  }
240
264
  else {
241
- console.error('', result.message);
265
+ console.error('x', result.message);
242
266
  if (result.errors) {
243
267
  result.errors.forEach((e) => console.error(' -', e));
244
268
  }
245
269
  process.exit(1);
246
270
  }
247
271
  });
248
- // Introspect command (for debugging)
272
+ // Introspect command (for debugging) - uses the new inference system
249
273
  program
250
274
  .command('introspect')
251
- .description('Introspect a GraphQL endpoint and print table info')
252
- .requiredOption('-e, --endpoint <url>', 'GraphQL endpoint URL')
275
+ .description('Introspect a GraphQL endpoint or schema file and print table info')
276
+ .option('-e, --endpoint <url>', 'GraphQL endpoint URL')
277
+ .option('-s, --schema <path>', 'Path to GraphQL schema file (.graphql)')
253
278
  .option('-a, --authorization <header>', 'Authorization header value')
254
279
  .option('--json', 'Output as JSON', false)
255
280
  .action(async (options) => {
256
- const { fetchMeta, validateEndpoint } = await Promise.resolve().then(() => __importStar(require('./introspect/fetch-meta')));
257
- const { transformMetaToCleanTables, getTableNames } = await Promise.resolve().then(() => __importStar(require('./introspect/transform')));
258
- // Validate endpoint
259
- const validation = validateEndpoint(options.endpoint);
260
- if (!validation.valid) {
261
- console.error('✗ Invalid endpoint:', validation.error);
281
+ // Validate source options
282
+ if (!options.endpoint && !options.schema) {
283
+ console.error('x Either --endpoint or --schema must be provided.');
262
284
  process.exit(1);
263
285
  }
264
- console.log('Fetching schema from', options.endpoint, '...');
265
- const result = await fetchMeta({
266
- endpoint: options.endpoint,
267
- authorization: options.authorization,
268
- });
269
- if (!result.success) {
270
- console.error('✗ Failed to fetch schema:', result.error);
286
+ if (options.endpoint && options.schema) {
287
+ console.error('x Cannot use both --endpoint and --schema. Choose one source.');
271
288
  process.exit(1);
272
289
  }
273
- const tables = transformMetaToCleanTables(result.data);
274
- const tableNames = getTableNames(tables);
275
- if (options.json) {
276
- console.log(JSON.stringify(tables, null, 2));
277
- }
278
- else {
279
- console.log(`\n✓ Found ${tables.length} tables:\n`);
280
- tableNames.forEach((name) => {
281
- const table = tables.find((t) => t.name === name);
282
- const fieldCount = table.fields.length;
283
- const relationCount = table.relations.belongsTo.length +
284
- table.relations.hasOne.length +
285
- table.relations.hasMany.length +
286
- table.relations.manyToMany.length;
287
- console.log(` ${name} (${fieldCount} fields, ${relationCount} relations)`);
290
+ const { createSchemaSource } = await Promise.resolve().then(() => __importStar(require('./introspect/source')));
291
+ const { inferTablesFromIntrospection } = await Promise.resolve().then(() => __importStar(require('./introspect/infer-tables')));
292
+ try {
293
+ const source = createSchemaSource({
294
+ endpoint: options.endpoint,
295
+ schema: options.schema,
296
+ authorization: options.authorization,
288
297
  });
298
+ console.log('Fetching schema from', source.describe(), '...');
299
+ const { introspection } = await source.fetch();
300
+ const tables = inferTablesFromIntrospection(introspection);
301
+ if (options.json) {
302
+ console.log(JSON.stringify(tables, null, 2));
303
+ }
304
+ else {
305
+ console.log(`\n[ok] Found ${tables.length} tables:\n`);
306
+ tables.forEach((table) => {
307
+ const fieldCount = table.fields.length;
308
+ const relationCount = table.relations.belongsTo.length +
309
+ table.relations.hasOne.length +
310
+ table.relations.hasMany.length +
311
+ table.relations.manyToMany.length;
312
+ console.log(` ${table.name} (${fieldCount} fields, ${relationCount} relations)`);
313
+ });
314
+ }
315
+ }
316
+ catch (err) {
317
+ console.error('x Failed to introspect schema:', err instanceof Error ? err.message : err);
318
+ process.exit(1);
289
319
  }
290
320
  });
291
321
  program.parse();
@@ -1,8 +1,11 @@
1
1
  /**
2
2
  * Introspection module exports
3
3
  */
4
- export { META_QUERY } from './meta-query';
5
- export type { MetaQueryResponse, MetaTable, MetaField, MetaFieldType, MetaConstraint, MetaForeignKeyConstraint, MetaTableQuery, MetaTableInflection, MetaBelongsToRelation, MetaHasRelation, MetaManyToManyRelation, MetaTableRelations, } from './meta-query';
6
- export { fetchMeta, validateEndpoint } from './fetch-meta';
7
- export type { FetchMetaOptions, FetchMetaResult } from './fetch-meta';
8
- export { transformMetaToCleanTables, getTableNames, findTable, filterTables, } from './transform';
4
+ export { inferTablesFromIntrospection } from './infer-tables';
5
+ export type { InferTablesOptions } from './infer-tables';
6
+ export { singularize, pluralize } from './pluralize';
7
+ export { createSchemaSource, validateSourceOptions, EndpointSchemaSource, FileSchemaSource, SchemaSourceError, } from './source';
8
+ export type { SchemaSource, SchemaSourceResult, CreateSchemaSourceOptions, } from './source';
9
+ export { fetchSchema } from './fetch-schema';
10
+ export type { FetchSchemaOptions, FetchSchemaResult } from './fetch-schema';
11
+ export { getTableNames, findTable, filterTables } from './transform';
@@ -3,14 +3,26 @@
3
3
  * Introspection module exports
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.filterTables = exports.findTable = exports.getTableNames = exports.transformMetaToCleanTables = exports.validateEndpoint = exports.fetchMeta = exports.META_QUERY = void 0;
7
- var meta_query_1 = require("./meta-query");
8
- Object.defineProperty(exports, "META_QUERY", { enumerable: true, get: function () { return meta_query_1.META_QUERY; } });
9
- var fetch_meta_1 = require("./fetch-meta");
10
- Object.defineProperty(exports, "fetchMeta", { enumerable: true, get: function () { return fetch_meta_1.fetchMeta; } });
11
- Object.defineProperty(exports, "validateEndpoint", { enumerable: true, get: function () { return fetch_meta_1.validateEndpoint; } });
6
+ exports.filterTables = exports.findTable = exports.getTableNames = exports.fetchSchema = exports.SchemaSourceError = exports.FileSchemaSource = exports.EndpointSchemaSource = exports.validateSourceOptions = exports.createSchemaSource = exports.pluralize = exports.singularize = exports.inferTablesFromIntrospection = void 0;
7
+ // Table inference from introspection
8
+ var infer_tables_1 = require("./infer-tables");
9
+ Object.defineProperty(exports, "inferTablesFromIntrospection", { enumerable: true, get: function () { return infer_tables_1.inferTablesFromIntrospection; } });
10
+ // Pluralization utilities
11
+ var pluralize_1 = require("./pluralize");
12
+ Object.defineProperty(exports, "singularize", { enumerable: true, get: function () { return pluralize_1.singularize; } });
13
+ Object.defineProperty(exports, "pluralize", { enumerable: true, get: function () { return pluralize_1.pluralize; } });
14
+ // Schema sources
15
+ var source_1 = require("./source");
16
+ Object.defineProperty(exports, "createSchemaSource", { enumerable: true, get: function () { return source_1.createSchemaSource; } });
17
+ Object.defineProperty(exports, "validateSourceOptions", { enumerable: true, get: function () { return source_1.validateSourceOptions; } });
18
+ Object.defineProperty(exports, "EndpointSchemaSource", { enumerable: true, get: function () { return source_1.EndpointSchemaSource; } });
19
+ Object.defineProperty(exports, "FileSchemaSource", { enumerable: true, get: function () { return source_1.FileSchemaSource; } });
20
+ Object.defineProperty(exports, "SchemaSourceError", { enumerable: true, get: function () { return source_1.SchemaSourceError; } });
21
+ // Schema fetching (still used by watch mode)
22
+ var fetch_schema_1 = require("./fetch-schema");
23
+ Object.defineProperty(exports, "fetchSchema", { enumerable: true, get: function () { return fetch_schema_1.fetchSchema; } });
24
+ // Transform utilities (only filterTables, getTableNames, findTable are still useful)
12
25
  var transform_1 = require("./transform");
13
- Object.defineProperty(exports, "transformMetaToCleanTables", { enumerable: true, get: function () { return transform_1.transformMetaToCleanTables; } });
14
26
  Object.defineProperty(exports, "getTableNames", { enumerable: true, get: function () { return transform_1.getTableNames; } });
15
27
  Object.defineProperty(exports, "findTable", { enumerable: true, get: function () { return transform_1.findTable; } });
16
28
  Object.defineProperty(exports, "filterTables", { enumerable: true, get: function () { return transform_1.filterTables; } });
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Infer PostGraphile table metadata from standard GraphQL introspection
3
+ *
4
+ * This module replaces the need for the _meta query by recognizing PostGraphile's
5
+ * naming conventions and type patterns from standard GraphQL introspection.
6
+ *
7
+ * Key patterns recognized:
8
+ * - Connection types: {PluralName}Connection → entity name
9
+ * - Filter types: {Name}Filter
10
+ * - Input types: Create{Name}Input, Update{Name}Input, Delete{Name}Input
11
+ * - Payload types: Create{Name}Payload, Update{Name}Payload, Delete{Name}Payload
12
+ * - Query operations: {pluralName} (list), {singularName} (single)
13
+ * - Mutation operations: create{Name}, update{Name}, delete{Name}
14
+ */
15
+ import type { IntrospectionQueryResponse } from '../../types/introspection';
16
+ import type { CleanTable } from '../../types/schema';
17
+ /**
18
+ * PostGraphile naming patterns for type detection
19
+ */
20
+ declare const PATTERNS: {
21
+ connection: RegExp;
22
+ edge: RegExp;
23
+ filter: RegExp;
24
+ condition: RegExp;
25
+ orderBy: RegExp;
26
+ patch: RegExp;
27
+ createInput: RegExp;
28
+ updateInput: RegExp;
29
+ deleteInput: RegExp;
30
+ createPayload: RegExp;
31
+ updatePayload: RegExp;
32
+ deletePayload: RegExp;
33
+ createMutation: RegExp;
34
+ updateMutation: RegExp;
35
+ deleteMutation: RegExp;
36
+ };
37
+ export interface InferTablesOptions {
38
+ /**
39
+ * Custom pattern overrides (for non-standard PostGraphile configurations)
40
+ */
41
+ patterns?: Partial<typeof PATTERNS>;
42
+ }
43
+ /**
44
+ * Infer CleanTable[] from GraphQL introspection by recognizing PostGraphile patterns
45
+ *
46
+ * @param introspection - Standard GraphQL introspection response
47
+ * @param options - Optional configuration
48
+ * @returns Array of CleanTable objects compatible with existing generators
49
+ */
50
+ export declare function inferTablesFromIntrospection(introspection: IntrospectionQueryResponse, options?: InferTablesOptions): CleanTable[];
51
+ export {};