@constructive-io/graphql-codegen 4.0.2 → 4.1.1

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 (93) hide show
  1. package/cli/handler.d.ts +13 -0
  2. package/cli/handler.js +74 -0
  3. package/cli/index.js +11 -57
  4. package/core/codegen/barrel.d.ts +1 -0
  5. package/core/codegen/barrel.js +5 -2
  6. package/core/codegen/cli/arg-mapper.d.ts +4 -0
  7. package/core/codegen/cli/arg-mapper.js +117 -0
  8. package/core/codegen/cli/command-map-generator.d.ts +16 -0
  9. package/core/codegen/cli/command-map-generator.js +338 -0
  10. package/core/codegen/cli/custom-command-generator.d.ts +8 -0
  11. package/core/codegen/cli/custom-command-generator.js +155 -0
  12. package/core/codegen/cli/docs-generator.d.ts +26 -0
  13. package/core/codegen/cli/docs-generator.js +1399 -0
  14. package/core/codegen/cli/executor-generator.d.ts +11 -0
  15. package/core/codegen/cli/executor-generator.js +217 -0
  16. package/core/codegen/cli/index.d.ts +53 -0
  17. package/core/codegen/cli/index.js +153 -0
  18. package/core/codegen/cli/infra-generator.d.ts +9 -0
  19. package/core/codegen/cli/infra-generator.js +1195 -0
  20. package/core/codegen/cli/table-command-generator.d.ts +7 -0
  21. package/core/codegen/cli/table-command-generator.js +323 -0
  22. package/core/codegen/docs-utils.d.ts +30 -0
  23. package/core/codegen/docs-utils.js +122 -0
  24. package/core/codegen/hooks-docs-generator.d.ts +6 -0
  25. package/core/codegen/hooks-docs-generator.js +468 -0
  26. package/core/codegen/orm/docs-generator.d.ts +6 -0
  27. package/core/codegen/orm/docs-generator.js +416 -0
  28. package/core/codegen/target-docs-generator.d.ts +20 -0
  29. package/core/codegen/target-docs-generator.js +110 -0
  30. package/core/database/index.d.ts +0 -12
  31. package/core/database/index.js +2 -19
  32. package/core/generate.d.ts +34 -2
  33. package/core/generate.js +453 -12
  34. package/core/index.d.ts +0 -2
  35. package/core/index.js +0 -2
  36. package/core/introspect/source/database.js +2 -2
  37. package/core/introspect/source/pgpm-module.js +2 -2
  38. package/core/output/index.d.ts +1 -1
  39. package/core/output/index.js +1 -2
  40. package/core/output/writer.d.ts +0 -10
  41. package/core/output/writer.js +0 -31
  42. package/esm/cli/handler.d.ts +13 -0
  43. package/esm/cli/handler.js +71 -0
  44. package/esm/cli/index.js +11 -57
  45. package/esm/core/codegen/barrel.d.ts +1 -0
  46. package/esm/core/codegen/barrel.js +5 -2
  47. package/esm/core/codegen/cli/arg-mapper.d.ts +4 -0
  48. package/esm/core/codegen/cli/arg-mapper.js +80 -0
  49. package/esm/core/codegen/cli/command-map-generator.d.ts +16 -0
  50. package/esm/core/codegen/cli/command-map-generator.js +301 -0
  51. package/esm/core/codegen/cli/custom-command-generator.d.ts +8 -0
  52. package/esm/core/codegen/cli/custom-command-generator.js +119 -0
  53. package/esm/core/codegen/cli/docs-generator.d.ts +26 -0
  54. package/esm/core/codegen/cli/docs-generator.js +1387 -0
  55. package/esm/core/codegen/cli/executor-generator.d.ts +11 -0
  56. package/esm/core/codegen/cli/executor-generator.js +180 -0
  57. package/esm/core/codegen/cli/index.d.ts +53 -0
  58. package/esm/core/codegen/cli/index.js +128 -0
  59. package/esm/core/codegen/cli/infra-generator.d.ts +9 -0
  60. package/esm/core/codegen/cli/infra-generator.js +1156 -0
  61. package/esm/core/codegen/cli/table-command-generator.d.ts +7 -0
  62. package/esm/core/codegen/cli/table-command-generator.js +287 -0
  63. package/esm/core/codegen/docs-utils.d.ts +30 -0
  64. package/esm/core/codegen/docs-utils.js +112 -0
  65. package/esm/core/codegen/hooks-docs-generator.d.ts +6 -0
  66. package/esm/core/codegen/hooks-docs-generator.js +462 -0
  67. package/esm/core/codegen/orm/docs-generator.d.ts +6 -0
  68. package/esm/core/codegen/orm/docs-generator.js +410 -0
  69. package/esm/core/codegen/target-docs-generator.d.ts +20 -0
  70. package/esm/core/codegen/target-docs-generator.js +105 -0
  71. package/esm/core/database/index.d.ts +0 -12
  72. package/esm/core/database/index.js +1 -17
  73. package/esm/core/generate.d.ts +34 -2
  74. package/esm/core/generate.js +417 -12
  75. package/esm/core/index.d.ts +0 -2
  76. package/esm/core/index.js +0 -2
  77. package/esm/core/introspect/source/database.js +2 -2
  78. package/esm/core/introspect/source/pgpm-module.js +2 -2
  79. package/esm/core/output/index.d.ts +1 -1
  80. package/esm/core/output/index.js +1 -1
  81. package/esm/core/output/writer.d.ts +0 -10
  82. package/esm/core/output/writer.js +0 -30
  83. package/esm/generators/index.d.ts +0 -3
  84. package/esm/generators/index.js +0 -3
  85. package/esm/index.d.ts +4 -3
  86. package/esm/index.js +4 -2
  87. package/esm/types/config.d.ts +78 -0
  88. package/generators/index.d.ts +0 -3
  89. package/generators/index.js +0 -3
  90. package/index.d.ts +4 -3
  91. package/index.js +7 -2
  92. package/package.json +8 -7
  93. package/types/config.d.ts +78 -0
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Shared codegen CLI handler
3
+ *
4
+ * Contains the core logic used by both `graphql-codegen` and `cnc codegen`.
5
+ * Both CLIs delegate to runCodegenHandler() after handling their own
6
+ * help/version flags.
7
+ */
8
+ import type { Question } from 'inquirerer';
9
+ interface Prompter {
10
+ prompt(argv: Record<string, unknown>, questions: Question[]): Promise<Record<string, unknown>>;
11
+ }
12
+ export declare function runCodegenHandler(argv: Record<string, unknown>, prompter: Prompter): Promise<void>;
13
+ export {};
package/cli/handler.js ADDED
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runCodegenHandler = runCodegenHandler;
4
+ const config_1 = require("../core/config");
5
+ const generate_1 = require("../core/generate");
6
+ const shared_1 = require("./shared");
7
+ async function runCodegenHandler(argv, prompter) {
8
+ const args = (0, shared_1.camelizeArgv)(argv);
9
+ const schemaOnly = Boolean(args.schemaOnly);
10
+ const hasSourceFlags = Boolean(args.endpoint || args.schemaFile || args.schemaDir || args.schemas || args.apiNames);
11
+ const configPath = args.config ||
12
+ (!hasSourceFlags ? (0, config_1.findConfigFile)() : undefined);
13
+ const targetName = args.target;
14
+ let fileConfig = {};
15
+ if (configPath) {
16
+ const loaded = await (0, config_1.loadConfigFile)(configPath);
17
+ if (!loaded.success) {
18
+ console.error('x', loaded.error);
19
+ process.exit(1);
20
+ }
21
+ const config = loaded.config;
22
+ const isMulti = !('endpoint' in config ||
23
+ 'schemaFile' in config ||
24
+ 'schemaDir' in config ||
25
+ 'db' in config);
26
+ if (isMulti) {
27
+ const targets = config;
28
+ if (targetName && !targets[targetName]) {
29
+ console.error('x', `Target "${targetName}" not found. Available: ${Object.keys(targets).join(', ')}`);
30
+ process.exit(1);
31
+ }
32
+ const cliOptions = (0, shared_1.buildDbConfig)((0, shared_1.normalizeCodegenListOptions)(args));
33
+ const selectedTargets = targetName
34
+ ? { [targetName]: targets[targetName] }
35
+ : targets;
36
+ const { results, hasError } = await (0, generate_1.generateMulti)({
37
+ configs: selectedTargets,
38
+ cliOverrides: cliOptions,
39
+ schemaOnly,
40
+ });
41
+ for (const { name, result } of results) {
42
+ console.log(`\n[${name}]`);
43
+ (0, shared_1.printResult)(result);
44
+ }
45
+ if (hasError)
46
+ process.exit(1);
47
+ return;
48
+ }
49
+ fileConfig = config;
50
+ }
51
+ const seeded = (0, shared_1.seedArgvFromConfig)(args, fileConfig);
52
+ const answers = (0, shared_1.hasResolvedCodegenSource)(seeded)
53
+ ? seeded
54
+ : await prompter.prompt(seeded, shared_1.codegenQuestions);
55
+ const options = (0, shared_1.buildGenerateOptions)(answers, fileConfig);
56
+ const expandedApi = (0, generate_1.expandApiNamesToMultiTarget)(options);
57
+ const expandedDir = (0, generate_1.expandSchemaDirToMultiTarget)(options);
58
+ const expanded = expandedApi || expandedDir;
59
+ if (expanded) {
60
+ const { results, hasError } = await (0, generate_1.generateMulti)({
61
+ configs: expanded,
62
+ schemaOnly,
63
+ });
64
+ for (const { name, result } of results) {
65
+ console.log(`\n[${name}]`);
66
+ (0, shared_1.printResult)(result);
67
+ }
68
+ if (hasError)
69
+ process.exit(1);
70
+ return;
71
+ }
72
+ const result = await (0, generate_1.generate)({ ...options, schemaOnly });
73
+ (0, shared_1.printResult)(result);
74
+ }
package/cli/index.js CHANGED
@@ -9,10 +9,7 @@ exports.options = exports.commands = void 0;
9
9
  * All business logic is in the core modules.
10
10
  */
11
11
  const inquirerer_1 = require("inquirerer");
12
- const config_1 = require("../core/config");
13
- const generate_1 = require("../core/generate");
14
- const config_2 = require("../types/config");
15
- const shared_1 = require("./shared");
12
+ const handler_1 = require("./handler");
16
13
  const usage = `
17
14
  graphql-codegen - GraphQL SDK generator for Constructive databases
18
15
 
@@ -23,10 +20,12 @@ Source Options (choose one):
23
20
  -c, --config <path> Path to config file
24
21
  -e, --endpoint <url> GraphQL endpoint URL
25
22
  -s, --schema-file <path> Path to GraphQL schema file
23
+ --schema-dir <dir> Directory of .graphql files (auto-expands to multi-target)
26
24
 
27
25
  Database Options:
28
26
  --schemas <list> Comma-separated PostgreSQL schemas
29
27
  --api-names <list> Comma-separated API names (mutually exclusive with --schemas)
28
+ Multiple apiNames auto-expand to multi-target (one schema per API).
30
29
 
31
30
  Generator Options:
32
31
  --react-query Generate React Query hooks
@@ -37,6 +36,11 @@ Generator Options:
37
36
  --dry-run Preview without writing files
38
37
  -v, --verbose Show detailed output
39
38
 
39
+ Schema Export:
40
+ --schema-only Export GraphQL SDL instead of running full codegen.
41
+ Works with any source (endpoint, file, database, PGPM).
42
+ With multiple apiNames, writes one .graphql per API.
43
+
40
44
  -h, --help Show this help message
41
45
  --version Show version number
42
46
  `;
@@ -50,56 +54,7 @@ const commands = async (argv, prompter, _options) => {
50
54
  console.log(usage);
51
55
  process.exit(0);
52
56
  }
53
- const hasSourceFlags = Boolean(argv.endpoint ||
54
- argv.e ||
55
- argv['schema-file'] ||
56
- argv.s ||
57
- argv.schemas ||
58
- argv['api-names']);
59
- const explicitConfigPath = (argv.config || argv.c);
60
- const configPath = explicitConfigPath || (!hasSourceFlags ? (0, config_1.findConfigFile)() : undefined);
61
- const targetName = (argv.target || argv.t);
62
- let fileConfig = {};
63
- if (configPath) {
64
- const loaded = await (0, config_1.loadConfigFile)(configPath);
65
- if (!loaded.success) {
66
- console.error('x', loaded.error);
67
- process.exit(1);
68
- }
69
- const config = loaded.config;
70
- const isMulti = !('endpoint' in config ||
71
- 'schemaFile' in config ||
72
- 'db' in config);
73
- if (isMulti) {
74
- const targets = config;
75
- const names = targetName ? [targetName] : Object.keys(targets);
76
- if (targetName && !targets[targetName]) {
77
- console.error('x', `Target "${targetName}" not found. Available: ${Object.keys(targets).join(', ')}`);
78
- process.exit(1);
79
- }
80
- const cliOptions = (0, shared_1.buildDbConfig)((0, shared_1.normalizeCodegenListOptions)((0, shared_1.camelizeArgv)(argv)));
81
- let hasError = false;
82
- for (const name of names) {
83
- console.log(`\n[${name}]`);
84
- const result = await (0, generate_1.generate)((0, config_2.mergeConfig)(targets[name], cliOptions));
85
- (0, shared_1.printResult)(result);
86
- if (!result.success)
87
- hasError = true;
88
- }
89
- prompter.close();
90
- if (hasError)
91
- process.exit(1);
92
- return argv;
93
- }
94
- fileConfig = config;
95
- }
96
- const seeded = (0, shared_1.seedArgvFromConfig)(argv, fileConfig);
97
- const answers = (0, shared_1.hasResolvedCodegenSource)(seeded)
98
- ? seeded
99
- : await prompter.prompt(seeded, shared_1.codegenQuestions);
100
- const options = (0, shared_1.buildGenerateOptions)(answers, fileConfig);
101
- const result = await (0, generate_1.generate)(options);
102
- (0, shared_1.printResult)(result);
57
+ await (0, handler_1.runCodegenHandler)(argv, prompter);
103
58
  prompter.close();
104
59
  return argv;
105
60
  };
@@ -116,16 +71,15 @@ exports.options = {
116
71
  a: 'authorization',
117
72
  v: 'verbose',
118
73
  },
74
+ boolean: ['schema-only'],
119
75
  string: [
120
76
  'config',
121
77
  'endpoint',
122
78
  'schema-file',
79
+ 'schema-dir',
123
80
  'output',
124
81
  'target',
125
82
  'authorization',
126
- 'pgpm-module-path',
127
- 'pgpm-workspace-path',
128
- 'pgpm-module-name',
129
83
  'schemas',
130
84
  'api-names',
131
85
  ],
@@ -27,6 +27,7 @@ export interface RootBarrelOptions {
27
27
  hasTypes?: boolean;
28
28
  hasHooks?: boolean;
29
29
  hasOrm?: boolean;
30
+ hasCli?: boolean;
30
31
  }
31
32
  /**
32
33
  * Generate the root index.ts barrel file for the output directory.
@@ -176,7 +176,7 @@ function generateMainBarrel(tables, options = {}) {
176
176
  * Re-exports from subdirectories based on which generators are enabled.
177
177
  */
178
178
  function generateRootBarrel(options = {}) {
179
- const { hasTypes = false, hasHooks = false, hasOrm = false } = options;
179
+ const { hasTypes = false, hasHooks = false, hasOrm = false, hasCli = false } = options;
180
180
  const statements = [];
181
181
  if (hasTypes) {
182
182
  statements.push(exportAllFrom('./types'));
@@ -187,7 +187,10 @@ function generateRootBarrel(options = {}) {
187
187
  if (hasOrm) {
188
188
  statements.push(exportAllFrom('./orm'));
189
189
  }
190
- // Add file header as leading comment on first statement
190
+ if (hasCli) {
191
+ statements.push(exportAllFrom('./cli'));
192
+ }
193
+ // Add file headeras leading comment on first statement
191
194
  if (statements.length > 0) {
192
195
  (0, babel_ast_1.addJSDocComment)(statements[0], [
193
196
  'Generated SDK - auto-generated, do not edit',
@@ -0,0 +1,4 @@
1
+ import * as t from '@babel/types';
2
+ import type { CleanArgument } from '../../../types/schema';
3
+ export declare function buildQuestionObject(arg: CleanArgument): t.ObjectExpression;
4
+ export declare function buildQuestionsArray(args: CleanArgument[]): t.ArrayExpression;
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.buildQuestionObject = buildQuestionObject;
37
+ exports.buildQuestionsArray = buildQuestionsArray;
38
+ const t = __importStar(require("@babel/types"));
39
+ function unwrapNonNull(typeRef) {
40
+ if (typeRef.kind === 'NON_NULL' && typeRef.ofType) {
41
+ return { inner: typeRef.ofType, required: true };
42
+ }
43
+ return { inner: typeRef, required: false };
44
+ }
45
+ function resolveBaseType(typeRef) {
46
+ if ((typeRef.kind === 'NON_NULL' || typeRef.kind === 'LIST') && typeRef.ofType) {
47
+ return resolveBaseType(typeRef.ofType);
48
+ }
49
+ return typeRef;
50
+ }
51
+ function buildQuestionObject(arg) {
52
+ const { inner, required } = unwrapNonNull(arg.type);
53
+ const base = resolveBaseType(arg.type);
54
+ const props = [];
55
+ if (base.kind === 'ENUM' && base.enumValues && base.enumValues.length > 0) {
56
+ props.push(t.objectProperty(t.identifier('type'), t.stringLiteral('autocomplete')));
57
+ props.push(t.objectProperty(t.identifier('name'), t.stringLiteral(arg.name)));
58
+ props.push(t.objectProperty(t.identifier('message'), t.stringLiteral(arg.description || arg.name)));
59
+ props.push(t.objectProperty(t.identifier('options'), t.arrayExpression(base.enumValues.map((v) => t.stringLiteral(v)))));
60
+ }
61
+ else if (base.kind === 'SCALAR' && base.name === 'Boolean') {
62
+ props.push(t.objectProperty(t.identifier('type'), t.stringLiteral('confirm')));
63
+ props.push(t.objectProperty(t.identifier('name'), t.stringLiteral(arg.name)));
64
+ props.push(t.objectProperty(t.identifier('message'), t.stringLiteral(arg.description || arg.name)));
65
+ props.push(t.objectProperty(t.identifier('default'), t.booleanLiteral(false)));
66
+ }
67
+ else if (base.kind === 'SCALAR' &&
68
+ (base.name === 'Int' || base.name === 'Float')) {
69
+ props.push(t.objectProperty(t.identifier('type'), t.stringLiteral('text')));
70
+ props.push(t.objectProperty(t.identifier('name'), t.stringLiteral(arg.name)));
71
+ props.push(t.objectProperty(t.identifier('message'), t.stringLiteral(arg.description || `${arg.name} (number)`)));
72
+ }
73
+ else if (inner.kind === 'INPUT_OBJECT' && inner.inputFields) {
74
+ return buildInputObjectQuestion(arg.name, inner, required);
75
+ }
76
+ else {
77
+ props.push(t.objectProperty(t.identifier('type'), t.stringLiteral('text')));
78
+ props.push(t.objectProperty(t.identifier('name'), t.stringLiteral(arg.name)));
79
+ props.push(t.objectProperty(t.identifier('message'), t.stringLiteral(arg.description || arg.name)));
80
+ }
81
+ if (required) {
82
+ props.push(t.objectProperty(t.identifier('required'), t.booleanLiteral(true)));
83
+ }
84
+ return t.objectExpression(props);
85
+ }
86
+ function buildInputObjectQuestion(_name, typeRef, _required) {
87
+ if (typeRef.inputFields && typeRef.inputFields.length > 0) {
88
+ const firstField = typeRef.inputFields[0];
89
+ return buildQuestionObject(firstField);
90
+ }
91
+ return t.objectExpression([
92
+ t.objectProperty(t.identifier('type'), t.stringLiteral('text')),
93
+ t.objectProperty(t.identifier('name'), t.stringLiteral(_name)),
94
+ t.objectProperty(t.identifier('message'), t.stringLiteral(_name)),
95
+ ]);
96
+ }
97
+ function buildQuestionsArray(args) {
98
+ const questions = [];
99
+ for (const arg of args) {
100
+ const base = resolveBaseType(arg.type);
101
+ const { inner } = unwrapNonNull(arg.type);
102
+ if (inner.kind === 'INPUT_OBJECT' && inner.inputFields) {
103
+ for (const field of inner.inputFields) {
104
+ questions.push(buildQuestionObject(field));
105
+ }
106
+ }
107
+ else if (base.kind === 'INPUT_OBJECT' && base.inputFields) {
108
+ for (const field of base.inputFields) {
109
+ questions.push(buildQuestionObject(field));
110
+ }
111
+ }
112
+ else {
113
+ questions.push(buildQuestionObject(arg));
114
+ }
115
+ }
116
+ return t.arrayExpression(questions);
117
+ }
@@ -0,0 +1,16 @@
1
+ import type { CleanTable, CleanOperation } from '../../../types/schema';
2
+ import type { GeneratedFile } from './executor-generator';
3
+ export declare function generateCommandMap(tables: CleanTable[], customOperations: CleanOperation[], toolName: string): GeneratedFile;
4
+ export interface MultiTargetCommandMapInput {
5
+ toolName: string;
6
+ builtinNames: {
7
+ auth: string;
8
+ context: string;
9
+ };
10
+ targets: Array<{
11
+ name: string;
12
+ tables: CleanTable[];
13
+ customOperations: CleanOperation[];
14
+ }>;
15
+ }
16
+ export declare function generateMultiTargetCommandMap(input: MultiTargetCommandMapInput): GeneratedFile;