@constructive-io/graphql-codegen 3.2.1 → 3.3.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 (215) hide show
  1. package/cli/index.js +36 -43
  2. package/cli/shared.d.ts +15 -19
  3. package/cli/shared.js +104 -25
  4. package/client/error.js +31 -9
  5. package/client/execute.js +2 -2
  6. package/client/index.d.ts +3 -3
  7. package/client/index.js +6 -6
  8. package/core/ast.d.ts +1 -1
  9. package/core/ast.js +1 -1
  10. package/core/codegen/babel-ast.d.ts +1 -1
  11. package/core/codegen/babel-ast.js +2 -2
  12. package/core/codegen/barrel.d.ts +0 -6
  13. package/core/codegen/barrel.js +22 -19
  14. package/core/codegen/client.d.ts +2 -12
  15. package/core/codegen/client.js +7 -21
  16. package/core/codegen/custom-mutations.d.ts +0 -14
  17. package/core/codegen/custom-mutations.js +139 -88
  18. package/core/codegen/custom-queries.d.ts +0 -14
  19. package/core/codegen/custom-queries.js +483 -193
  20. package/core/codegen/hooks-ast.d.ts +75 -0
  21. package/core/codegen/hooks-ast.js +522 -0
  22. package/core/codegen/index.d.ts +16 -18
  23. package/core/codegen/index.js +42 -88
  24. package/core/codegen/invalidation.d.ts +1 -7
  25. package/core/codegen/invalidation.js +50 -16
  26. package/core/codegen/mutation-keys.d.ts +1 -10
  27. package/core/codegen/mutation-keys.js +22 -8
  28. package/core/codegen/mutations.d.ts +0 -13
  29. package/core/codegen/mutations.js +301 -366
  30. package/core/codegen/orm/barrel.d.ts +0 -5
  31. package/core/codegen/orm/barrel.js +5 -0
  32. package/core/codegen/orm/client-generator.d.ts +0 -5
  33. package/core/codegen/orm/client-generator.js +7 -2
  34. package/core/codegen/orm/client.js +3 -1
  35. package/core/codegen/orm/custom-ops-generator.d.ts +0 -6
  36. package/core/codegen/orm/custom-ops-generator.js +104 -51
  37. package/core/codegen/orm/index.d.ts +4 -4
  38. package/core/codegen/orm/index.js +28 -15
  39. package/core/codegen/orm/input-types-generator.d.ts +1 -13
  40. package/core/codegen/orm/input-types-generator.js +85 -23
  41. package/core/codegen/orm/model-generator.d.ts +0 -5
  42. package/core/codegen/orm/model-generator.js +309 -131
  43. package/core/codegen/orm/select-types.d.ts +19 -14
  44. package/core/codegen/queries.d.ts +0 -8
  45. package/core/codegen/queries.js +360 -559
  46. package/core/codegen/query-keys.d.ts +1 -1
  47. package/core/codegen/query-keys.js +37 -23
  48. package/core/codegen/scalars.js +3 -1
  49. package/core/codegen/schema-types-generator.d.ts +1 -1
  50. package/core/codegen/schema-types-generator.js +17 -2
  51. package/core/codegen/select-helpers.d.ts +19 -0
  52. package/core/codegen/select-helpers.js +40 -0
  53. package/core/codegen/selection.d.ts +4 -0
  54. package/core/codegen/selection.js +65 -0
  55. package/core/codegen/shared/index.d.ts +2 -15
  56. package/core/codegen/shared/index.js +17 -4
  57. package/core/codegen/templates/hooks-client.ts +49 -0
  58. package/core/codegen/templates/hooks-selection.ts +58 -0
  59. package/core/codegen/templates/orm-client.ts +8 -6
  60. package/core/codegen/templates/query-builder.ts +250 -46
  61. package/core/codegen/templates/select-types.ts +31 -14
  62. package/core/codegen/type-resolver.d.ts +1 -5
  63. package/core/codegen/type-resolver.js +0 -22
  64. package/core/codegen/types.d.ts +0 -3
  65. package/core/codegen/types.js +71 -14
  66. package/core/codegen/utils.d.ts +1 -4
  67. package/core/codegen/utils.js +4 -1
  68. package/core/config/index.d.ts +1 -1
  69. package/core/config/resolver.js +1 -3
  70. package/core/generate.js +38 -50
  71. package/core/index.d.ts +3 -3
  72. package/core/index.js +3 -4
  73. package/core/introspect/index.d.ts +6 -6
  74. package/core/introspect/index.js +5 -8
  75. package/core/introspect/infer-tables.d.ts +0 -14
  76. package/core/introspect/infer-tables.js +15 -1
  77. package/core/introspect/source/database.js +1 -1
  78. package/core/introspect/source/endpoint.d.ts +0 -6
  79. package/core/introspect/source/endpoint.js +7 -1
  80. package/core/introspect/source/index.d.ts +4 -4
  81. package/core/introspect/source/index.js +5 -9
  82. package/core/introspect/source/pgpm-module.js +3 -3
  83. package/core/introspect/transform-schema.d.ts +2 -2
  84. package/core/introspect/transform-schema.js +2 -2
  85. package/core/output/index.d.ts +1 -1
  86. package/core/output/index.js +2 -2
  87. package/core/output/writer.d.ts +3 -0
  88. package/core/output/writer.js +20 -1
  89. package/core/pipeline/index.d.ts +2 -2
  90. package/core/query-builder.d.ts +2 -2
  91. package/core/query-builder.js +1 -1
  92. package/core/watch/index.d.ts +4 -4
  93. package/core/watch/index.js +9 -9
  94. package/core/watch/orchestrator.js +5 -3
  95. package/esm/cli/index.js +37 -44
  96. package/esm/cli/shared.d.ts +15 -19
  97. package/esm/cli/shared.js +94 -23
  98. package/esm/client/error.js +31 -9
  99. package/esm/client/execute.js +2 -2
  100. package/esm/client/index.d.ts +3 -3
  101. package/esm/client/index.js +3 -3
  102. package/esm/core/ast.d.ts +1 -1
  103. package/esm/core/ast.js +1 -1
  104. package/esm/core/codegen/babel-ast.d.ts +1 -1
  105. package/esm/core/codegen/babel-ast.js +2 -2
  106. package/esm/core/codegen/barrel.d.ts +0 -6
  107. package/esm/core/codegen/barrel.js +23 -20
  108. package/esm/core/codegen/client.d.ts +2 -12
  109. package/esm/core/codegen/client.js +7 -21
  110. package/esm/core/codegen/custom-mutations.d.ts +0 -14
  111. package/esm/core/codegen/custom-mutations.js +141 -90
  112. package/esm/core/codegen/custom-queries.d.ts +0 -14
  113. package/esm/core/codegen/custom-queries.js +486 -196
  114. package/esm/core/codegen/hooks-ast.d.ts +75 -0
  115. package/esm/core/codegen/hooks-ast.js +424 -0
  116. package/esm/core/codegen/index.d.ts +16 -18
  117. package/esm/core/codegen/index.js +26 -71
  118. package/esm/core/codegen/invalidation.d.ts +1 -7
  119. package/esm/core/codegen/invalidation.js +51 -17
  120. package/esm/core/codegen/mutation-keys.d.ts +1 -10
  121. package/esm/core/codegen/mutation-keys.js +23 -9
  122. package/esm/core/codegen/mutations.d.ts +0 -13
  123. package/esm/core/codegen/mutations.js +302 -367
  124. package/esm/core/codegen/orm/barrel.d.ts +0 -5
  125. package/esm/core/codegen/orm/barrel.js +6 -1
  126. package/esm/core/codegen/orm/client-generator.d.ts +0 -5
  127. package/esm/core/codegen/orm/client-generator.js +7 -2
  128. package/esm/core/codegen/orm/client.js +3 -1
  129. package/esm/core/codegen/orm/custom-ops-generator.d.ts +0 -6
  130. package/esm/core/codegen/orm/custom-ops-generator.js +103 -50
  131. package/esm/core/codegen/orm/index.d.ts +4 -4
  132. package/esm/core/codegen/orm/index.js +25 -12
  133. package/esm/core/codegen/orm/input-types-generator.d.ts +1 -13
  134. package/esm/core/codegen/orm/input-types-generator.js +85 -23
  135. package/esm/core/codegen/orm/model-generator.d.ts +0 -5
  136. package/esm/core/codegen/orm/model-generator.js +310 -132
  137. package/esm/core/codegen/orm/select-types.d.ts +19 -14
  138. package/esm/core/codegen/queries.d.ts +0 -8
  139. package/esm/core/codegen/queries.js +362 -561
  140. package/esm/core/codegen/query-keys.d.ts +1 -1
  141. package/esm/core/codegen/query-keys.js +38 -24
  142. package/esm/core/codegen/scalars.js +3 -1
  143. package/esm/core/codegen/schema-types-generator.d.ts +1 -1
  144. package/esm/core/codegen/schema-types-generator.js +17 -2
  145. package/esm/core/codegen/select-helpers.d.ts +19 -0
  146. package/esm/core/codegen/select-helpers.js +35 -0
  147. package/esm/core/codegen/selection.d.ts +4 -0
  148. package/esm/core/codegen/selection.js +29 -0
  149. package/esm/core/codegen/shared/index.d.ts +2 -15
  150. package/esm/core/codegen/shared/index.js +16 -3
  151. package/esm/core/codegen/type-resolver.d.ts +1 -5
  152. package/esm/core/codegen/type-resolver.js +1 -22
  153. package/esm/core/codegen/types.d.ts +0 -3
  154. package/esm/core/codegen/types.js +72 -15
  155. package/esm/core/codegen/utils.d.ts +1 -4
  156. package/esm/core/codegen/utils.js +4 -1
  157. package/esm/core/config/index.d.ts +1 -1
  158. package/esm/core/config/resolver.js +2 -4
  159. package/esm/core/generate.js +38 -50
  160. package/esm/core/index.d.ts +3 -3
  161. package/esm/core/index.js +2 -3
  162. package/esm/core/introspect/index.d.ts +6 -6
  163. package/esm/core/introspect/index.js +3 -6
  164. package/esm/core/introspect/infer-tables.d.ts +0 -14
  165. package/esm/core/introspect/infer-tables.js +16 -2
  166. package/esm/core/introspect/source/database.js +2 -2
  167. package/esm/core/introspect/source/endpoint.d.ts +0 -6
  168. package/esm/core/introspect/source/endpoint.js +7 -1
  169. package/esm/core/introspect/source/index.d.ts +4 -4
  170. package/esm/core/introspect/source/index.js +6 -10
  171. package/esm/core/introspect/source/pgpm-module.js +3 -3
  172. package/esm/core/introspect/transform-schema.d.ts +2 -2
  173. package/esm/core/introspect/transform-schema.js +2 -2
  174. package/esm/core/output/index.d.ts +1 -1
  175. package/esm/core/output/index.js +1 -1
  176. package/esm/core/output/writer.d.ts +3 -0
  177. package/esm/core/output/writer.js +20 -1
  178. package/esm/core/pipeline/index.d.ts +2 -2
  179. package/esm/core/pipeline/index.js +2 -2
  180. package/esm/core/query-builder.d.ts +2 -2
  181. package/esm/core/query-builder.js +2 -2
  182. package/esm/core/watch/index.d.ts +4 -4
  183. package/esm/core/watch/index.js +3 -3
  184. package/esm/core/watch/orchestrator.js +5 -3
  185. package/esm/generators/index.d.ts +3 -3
  186. package/esm/generators/index.js +3 -3
  187. package/esm/generators/mutations.d.ts +1 -1
  188. package/esm/generators/select.d.ts +1 -1
  189. package/esm/index.d.ts +3 -3
  190. package/esm/index.js +1 -4
  191. package/esm/types/config.d.ts +0 -10
  192. package/esm/types/config.js +0 -2
  193. package/esm/types/index.d.ts +6 -6
  194. package/esm/types/index.js +1 -1
  195. package/generators/index.d.ts +3 -3
  196. package/generators/index.js +8 -8
  197. package/generators/mutations.d.ts +1 -1
  198. package/generators/select.d.ts +1 -1
  199. package/index.d.ts +3 -3
  200. package/index.js +11 -6
  201. package/package.json +10 -10
  202. package/types/config.d.ts +0 -10
  203. package/types/config.js +0 -2
  204. package/types/index.d.ts +6 -6
  205. package/types/index.js +2 -2
  206. package/core/codegen/gql-ast.d.ts +0 -41
  207. package/core/codegen/gql-ast.js +0 -353
  208. package/core/codegen/schema-gql-ast.d.ts +0 -51
  209. package/core/codegen/schema-gql-ast.js +0 -385
  210. package/core/codegen/templates/client.browser.ts +0 -271
  211. package/core/codegen/templates/client.node.ts +0 -337
  212. package/esm/core/codegen/gql-ast.d.ts +0 -41
  213. package/esm/core/codegen/gql-ast.js +0 -312
  214. package/esm/core/codegen/schema-gql-ast.d.ts +0 -51
  215. package/esm/core/codegen/schema-gql-ast.js +0 -343
package/cli/index.js CHANGED
@@ -9,8 +9,8 @@ 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 generate_1 = require("../core/generate");
13
12
  const config_1 = require("../core/config");
13
+ const generate_1 = require("../core/generate");
14
14
  const shared_1 = require("./shared");
15
15
  const usage = `
16
16
  graphql-codegen - GraphQL SDK generator for Constructive databases
@@ -33,8 +33,6 @@ Generator Options:
33
33
  -o, --output <dir> Output directory
34
34
  -t, --target <name> Target name (for multi-target configs)
35
35
  -a, --authorization <token> Authorization header value
36
- --browser-compatible Generate browser-compatible code (default: true)
37
- Set to false for Node.js with localhost DNS fix
38
36
  --dry-run Preview without writing files
39
37
  -v, --verbose Show detailed output
40
38
 
@@ -51,9 +49,16 @@ const commands = async (argv, prompter, _options) => {
51
49
  console.log(usage);
52
50
  process.exit(0);
53
51
  }
54
- const configPath = (argv.config || argv.c || (0, config_1.findConfigFile)());
52
+ const hasSourceFlags = Boolean(argv.endpoint ||
53
+ argv.e ||
54
+ argv['schema-file'] ||
55
+ argv.s ||
56
+ argv.schemas ||
57
+ argv['api-names']);
58
+ const explicitConfigPath = (argv.config || argv.c);
59
+ const configPath = explicitConfigPath || (!hasSourceFlags ? (0, config_1.findConfigFile)() : undefined);
55
60
  const targetName = (argv.target || argv.t);
56
- // If config file exists, load and run
61
+ let fileConfig = {};
57
62
  if (configPath) {
58
63
  const loaded = await (0, config_1.loadConfigFile)(configPath);
59
64
  if (!loaded.success) {
@@ -61,20 +66,24 @@ const commands = async (argv, prompter, _options) => {
61
66
  process.exit(1);
62
67
  }
63
68
  const config = loaded.config;
64
- // Check if it's a multi-target config (no source fields at top level)
65
- const isMulti = !('endpoint' in config || 'schemaFile' in config || 'db' in config);
69
+ const isMulti = !('endpoint' in config ||
70
+ 'schemaFile' in config ||
71
+ 'db' in config);
66
72
  if (isMulti) {
67
- // Multi-target: simple for loop over targets
68
73
  const targets = config;
69
74
  const names = targetName ? [targetName] : Object.keys(targets);
70
75
  if (targetName && !targets[targetName]) {
71
76
  console.error('x', `Target "${targetName}" not found. Available: ${Object.keys(targets).join(', ')}`);
72
77
  process.exit(1);
73
78
  }
79
+ const cliOptions = (0, shared_1.buildDbConfig)((0, shared_1.normalizeCodegenListOptions)((0, shared_1.camelizeArgv)(argv)));
74
80
  let hasError = false;
75
81
  for (const name of names) {
76
82
  console.log(`\n[${name}]`);
77
- const result = await (0, generate_1.generate)(targets[name]);
83
+ const result = await (0, generate_1.generate)({
84
+ ...targets[name],
85
+ ...cliOptions,
86
+ });
78
87
  (0, shared_1.printResult)(result);
79
88
  if (!result.success)
80
89
  hasError = true;
@@ -84,35 +93,14 @@ const commands = async (argv, prompter, _options) => {
84
93
  process.exit(1);
85
94
  return argv;
86
95
  }
87
- // Single config
88
- const result = await (0, generate_1.generate)(config);
89
- (0, shared_1.printResult)(result);
90
- if (!result.success)
91
- process.exit(1);
92
- prompter.close();
93
- return argv;
96
+ fileConfig = config;
94
97
  }
95
- // No config file - prompt for options using shared questions
96
- const answers = await prompter.prompt(argv, shared_1.codegenQuestions);
97
- // Convert kebab-case CLI args to camelCase for internal use
98
- const camelized = (0, shared_1.camelizeArgv)(answers);
99
- // Build db config if schemas or apiNames provided
100
- const db = (camelized.schemas || camelized.apiNames) ? {
101
- schemas: camelized.schemas,
102
- apiNames: camelized.apiNames,
103
- } : undefined;
104
- const result = await (0, generate_1.generate)({
105
- endpoint: camelized.endpoint,
106
- schemaFile: camelized.schemaFile,
107
- db,
108
- output: camelized.output,
109
- authorization: camelized.authorization,
110
- reactQuery: camelized.reactQuery,
111
- orm: camelized.orm,
112
- browserCompatible: camelized.browserCompatible,
113
- dryRun: camelized.dryRun,
114
- verbose: camelized.verbose,
115
- });
98
+ const seeded = (0, shared_1.seedArgvFromConfig)(argv, fileConfig);
99
+ const answers = (0, shared_1.hasResolvedCodegenSource)(seeded)
100
+ ? seeded
101
+ : await prompter.prompt(seeded, shared_1.codegenQuestions);
102
+ const options = (0, shared_1.buildGenerateOptions)(answers, fileConfig);
103
+ const result = await (0, generate_1.generate)(options);
116
104
  (0, shared_1.printResult)(result);
117
105
  prompter.close();
118
106
  return argv;
@@ -130,13 +118,18 @@ exports.options = {
130
118
  a: 'authorization',
131
119
  v: 'verbose',
132
120
  },
133
- boolean: [
134
- 'help', 'version', 'verbose', 'dry-run', 'react-query', 'orm', 'keep-db', 'browser-compatible',
135
- ],
136
121
  string: [
137
- 'config', 'endpoint', 'schema-file', 'output', 'target', 'authorization',
138
- 'pgpm-module-path', 'pgpm-workspace-path', 'pgpm-module-name',
139
- 'schemas', 'api-names',
122
+ 'config',
123
+ 'endpoint',
124
+ 'schema-file',
125
+ 'output',
126
+ 'target',
127
+ 'authorization',
128
+ 'pgpm-module-path',
129
+ 'pgpm-workspace-path',
130
+ 'pgpm-module-name',
131
+ 'schemas',
132
+ 'api-names',
140
133
  ],
141
134
  },
142
135
  };
package/cli/shared.d.ts CHANGED
@@ -1,19 +1,7 @@
1
- /**
2
- * Shared CLI utilities for graphql-codegen
3
- *
4
- * These are exported so that packages/cli can use the same questions
5
- * and types, ensuring consistency between the two CLIs.
6
- */
7
1
  import type { Question } from 'inquirerer';
8
2
  import type { GenerateResult } from '../core/generate';
9
- /**
10
- * Sanitize function that splits comma-separated strings into arrays
11
- */
3
+ import type { GraphQLSDKConfigTarget } from '../types/config';
12
4
  export declare const splitCommas: (input: string | undefined) => string[] | undefined;
13
- /**
14
- * Interface for codegen CLI answers
15
- * CLI accepts kebab-case arguments, converted to camelCase for internal use
16
- */
17
5
  export interface CodegenAnswers {
18
6
  endpoint?: string;
19
7
  schemaFile?: string;
@@ -22,17 +10,25 @@ export interface CodegenAnswers {
22
10
  apiNames?: string[];
23
11
  reactQuery?: boolean;
24
12
  orm?: boolean;
25
- browserCompatible?: boolean;
26
13
  authorization?: string;
27
14
  dryRun?: boolean;
28
15
  verbose?: boolean;
29
16
  }
17
+ export declare const codegenQuestions: Question[];
18
+ export declare function printResult(result: GenerateResult): void;
19
+ export declare const camelizeArgv: (argv: Record<string, any>) => Record<string, any>;
20
+ export declare const hyphenateKeys: (obj: Record<string, any>) => Record<string, any>;
21
+ export declare function filterDefined(obj: Record<string, unknown>): Record<string, unknown>;
22
+ export declare function flattenDbFields(config: Record<string, unknown>): Record<string, unknown>;
23
+ export declare function buildDbConfig(options: Record<string, unknown>): Record<string, unknown>;
30
24
  /**
31
- * Questions for the codegen CLI
25
+ * Normalizes top-level list-like CLI options to string arrays.
26
+ * This keeps non-interactive paths equivalent to prompt sanitize behavior.
32
27
  */
33
- export declare const codegenQuestions: Question[];
28
+ export declare function normalizeCodegenListOptions(options: Record<string, unknown>): Record<string, unknown>;
34
29
  /**
35
- * Print the result of a generate operation
30
+ * Returns true when source options are already available, so prompting can be skipped.
36
31
  */
37
- export declare function printResult(result: GenerateResult): void;
38
- export declare const camelizeArgv: (argv: Record<string, any>) => any;
32
+ export declare function hasResolvedCodegenSource(options: Record<string, unknown>): boolean;
33
+ export declare function seedArgvFromConfig(argv: Record<string, unknown>, fileConfig: GraphQLSDKConfigTarget): Record<string, unknown>;
34
+ export declare function buildGenerateOptions(answers: Record<string, unknown>, fileConfig?: GraphQLSDKConfigTarget): GraphQLSDKConfigTarget;
package/cli/shared.js CHANGED
@@ -1,21 +1,43 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.camelizeArgv = exports.codegenQuestions = exports.splitCommas = void 0;
3
+ exports.hyphenateKeys = exports.camelizeArgv = exports.codegenQuestions = exports.splitCommas = void 0;
4
4
  exports.printResult = printResult;
5
- const inflekt_1 = require("inflekt");
6
- const transform_keys_1 = require("inflekt/transform-keys");
5
+ exports.filterDefined = filterDefined;
6
+ exports.flattenDbFields = flattenDbFields;
7
+ exports.buildDbConfig = buildDbConfig;
8
+ exports.normalizeCodegenListOptions = normalizeCodegenListOptions;
9
+ exports.hasResolvedCodegenSource = hasResolvedCodegenSource;
10
+ exports.seedArgvFromConfig = seedArgvFromConfig;
11
+ exports.buildGenerateOptions = buildGenerateOptions;
7
12
  /**
8
- * Sanitize function that splits comma-separated strings into arrays
13
+ * Shared CLI utilities for graphql-codegen
14
+ *
15
+ * These are exported so that packages/cli can use the same questions,
16
+ * types, and transform utilities, ensuring consistency between the two CLIs.
9
17
  */
18
+ const inflekt_1 = require("inflekt");
19
+ const transform_keys_1 = require("inflekt/transform-keys");
10
20
  const splitCommas = (input) => {
11
21
  if (!input)
12
22
  return undefined;
13
- return input.split(',').map((s) => s.trim()).filter(Boolean);
23
+ return input
24
+ .split(',')
25
+ .map((s) => s.trim())
26
+ .filter(Boolean);
14
27
  };
15
28
  exports.splitCommas = splitCommas;
16
- /**
17
- * Questions for the codegen CLI
18
- */
29
+ function normalizeListOption(input) {
30
+ if (Array.isArray(input)) {
31
+ return input
32
+ .flatMap((item) => typeof item === 'string' ? ((0, exports.splitCommas)(item) ?? []) : [String(item)])
33
+ .map((s) => s.trim())
34
+ .filter(Boolean);
35
+ }
36
+ if (typeof input === 'string') {
37
+ return (0, exports.splitCommas)(input);
38
+ }
39
+ return undefined;
40
+ }
19
41
  exports.codegenQuestions = [
20
42
  {
21
43
  name: 'endpoint',
@@ -67,14 +89,6 @@ exports.codegenQuestions = [
67
89
  default: false,
68
90
  useDefault: true,
69
91
  },
70
- {
71
- name: 'browser-compatible',
72
- message: 'Generate browser-compatible code?',
73
- type: 'confirm',
74
- required: false,
75
- default: true,
76
- useDefault: true,
77
- },
78
92
  {
79
93
  name: 'authorization',
80
94
  message: 'Authorization header value',
@@ -98,9 +112,6 @@ exports.codegenQuestions = [
98
112
  useDefault: true,
99
113
  },
100
114
  ];
101
- /**
102
- * Print the result of a generate operation
103
- */
104
115
  function printResult(result) {
105
116
  if (result.success) {
106
117
  console.log('[ok]', result.message);
@@ -114,14 +125,82 @@ function printResult(result) {
114
125
  process.exit(1);
115
126
  }
116
127
  }
128
+ // ============================================================================
129
+ // Key transform utilities
130
+ // ============================================================================
117
131
  const isTopLevel = (_key, path) => path.length === 0;
132
+ const skipNonTopLevel = (key, path) => !isTopLevel(key, path) || key === '_' || key.startsWith('_');
118
133
  const camelizeArgv = (argv) => (0, transform_keys_1.inflektTree)(argv, (key) => {
119
- // inflection.camelize expects underscores, so replace hyphens first
120
134
  const underscored = key.replace(/-/g, '_');
121
135
  return (0, inflekt_1.camelize)(underscored, true);
122
- }, {
123
- skip: (key, path) => !isTopLevel(key, path) ||
124
- key === '_' ||
125
- key.startsWith('_')
126
- });
136
+ }, { skip: skipNonTopLevel });
127
137
  exports.camelizeArgv = camelizeArgv;
138
+ const hyphenateKeys = (obj) => (0, transform_keys_1.inflektTree)(obj, (key) => key.replace(/[A-Z]/g, (m) => '-' + m.toLowerCase()), {
139
+ skip: skipNonTopLevel,
140
+ });
141
+ exports.hyphenateKeys = hyphenateKeys;
142
+ // ============================================================================
143
+ // Config <-> CLI shape transforms
144
+ // ============================================================================
145
+ function filterDefined(obj) {
146
+ return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined && v !== null));
147
+ }
148
+ function flattenDbFields(config) {
149
+ const { db, ...rest } = config;
150
+ if (db && typeof db === 'object') {
151
+ const dbObj = db;
152
+ const schemas = Array.isArray(dbObj.schemas)
153
+ ? dbObj.schemas.join(',')
154
+ : dbObj.schemas;
155
+ const apiNames = Array.isArray(dbObj.apiNames)
156
+ ? dbObj.apiNames.join(',')
157
+ : dbObj.apiNames;
158
+ return { ...rest, schemas, apiNames };
159
+ }
160
+ return rest;
161
+ }
162
+ function buildDbConfig(options) {
163
+ const { schemas, apiNames, ...rest } = options;
164
+ if (schemas || apiNames) {
165
+ return { ...rest, db: { schemas, apiNames } };
166
+ }
167
+ return rest;
168
+ }
169
+ /**
170
+ * Normalizes top-level list-like CLI options to string arrays.
171
+ * This keeps non-interactive paths equivalent to prompt sanitize behavior.
172
+ */
173
+ function normalizeCodegenListOptions(options) {
174
+ return {
175
+ ...options,
176
+ schemas: normalizeListOption(options.schemas),
177
+ apiNames: normalizeListOption(options.apiNames),
178
+ };
179
+ }
180
+ /**
181
+ * Returns true when source options are already available, so prompting can be skipped.
182
+ */
183
+ function hasResolvedCodegenSource(options) {
184
+ const normalized = normalizeCodegenListOptions((0, exports.camelizeArgv)(options));
185
+ const db = normalized.db;
186
+ const dbSchemas = normalizeListOption(db?.schemas);
187
+ const dbApiNames = normalizeListOption(db?.apiNames);
188
+ return Boolean(normalized.endpoint ||
189
+ normalized.schemaFile ||
190
+ normalized.schemas?.length ||
191
+ normalized.apiNames?.length ||
192
+ dbSchemas?.length ||
193
+ dbApiNames?.length);
194
+ }
195
+ function seedArgvFromConfig(argv, fileConfig) {
196
+ const flat = flattenDbFields(fileConfig);
197
+ const hyphenated = (0, exports.hyphenateKeys)(flat);
198
+ const defined = filterDefined(hyphenated);
199
+ return { ...defined, ...argv };
200
+ }
201
+ function buildGenerateOptions(answers, fileConfig = {}) {
202
+ const camelized = (0, exports.camelizeArgv)(answers);
203
+ const normalized = normalizeCodegenListOptions(camelized);
204
+ const withDb = buildDbConfig(normalized);
205
+ return { ...fileConfig, ...withDb };
206
+ }
package/client/error.js CHANGED
@@ -126,17 +126,35 @@ exports.PG_ERROR_CODES = {
126
126
  // Error Factory
127
127
  // ============================================================================
128
128
  exports.createError = {
129
- network: (originalError) => new DataError(exports.DataErrorType.NETWORK_ERROR, 'Network error occurred', { originalError }),
130
- timeout: (originalError) => new DataError(exports.DataErrorType.TIMEOUT_ERROR, 'Request timed out', { originalError }),
129
+ network: (originalError) => new DataError(exports.DataErrorType.NETWORK_ERROR, 'Network error occurred', {
130
+ originalError,
131
+ }),
132
+ timeout: (originalError) => new DataError(exports.DataErrorType.TIMEOUT_ERROR, 'Request timed out', {
133
+ originalError,
134
+ }),
131
135
  unauthorized: (message = 'Authentication required') => new DataError(exports.DataErrorType.UNAUTHORIZED, message),
132
136
  forbidden: (message = 'Access forbidden') => new DataError(exports.DataErrorType.FORBIDDEN, message),
133
137
  badRequest: (message, code) => new DataError(exports.DataErrorType.BAD_REQUEST, message, { code }),
134
138
  notFound: (message = 'Resource not found') => new DataError(exports.DataErrorType.NOT_FOUND, message),
135
139
  graphql: (message, code) => new DataError(exports.DataErrorType.GRAPHQL_ERROR, message, { code }),
136
- uniqueViolation: (message, fieldName, constraint) => new DataError(exports.DataErrorType.UNIQUE_VIOLATION, message, { fieldName, constraint, code: '23505' }),
137
- foreignKeyViolation: (message, fieldName, constraint) => new DataError(exports.DataErrorType.FOREIGN_KEY_VIOLATION, message, { fieldName, constraint, code: '23503' }),
138
- notNullViolation: (message, fieldName, constraint) => new DataError(exports.DataErrorType.NOT_NULL_VIOLATION, message, { fieldName, constraint, code: '23502' }),
139
- unknown: (originalError) => new DataError(exports.DataErrorType.UNKNOWN_ERROR, originalError.message, { originalError }),
140
+ uniqueViolation: (message, fieldName, constraint) => new DataError(exports.DataErrorType.UNIQUE_VIOLATION, message, {
141
+ fieldName,
142
+ constraint,
143
+ code: '23505',
144
+ }),
145
+ foreignKeyViolation: (message, fieldName, constraint) => new DataError(exports.DataErrorType.FOREIGN_KEY_VIOLATION, message, {
146
+ fieldName,
147
+ constraint,
148
+ code: '23503',
149
+ }),
150
+ notNullViolation: (message, fieldName, constraint) => new DataError(exports.DataErrorType.NOT_NULL_VIOLATION, message, {
151
+ fieldName,
152
+ constraint,
153
+ code: '23502',
154
+ }),
155
+ unknown: (originalError) => new DataError(exports.DataErrorType.UNKNOWN_ERROR, originalError.message, {
156
+ originalError,
157
+ }),
140
158
  };
141
159
  function parseGraphQLErrorCode(code) {
142
160
  if (!code)
@@ -167,10 +185,13 @@ function classifyByMessage(message) {
167
185
  if (lower.includes('timeout') || lower.includes('timed out')) {
168
186
  return exports.DataErrorType.TIMEOUT_ERROR;
169
187
  }
170
- if (lower.includes('network') || lower.includes('fetch') || lower.includes('failed to fetch')) {
188
+ if (lower.includes('network') ||
189
+ lower.includes('fetch') ||
190
+ lower.includes('failed to fetch')) {
171
191
  return exports.DataErrorType.NETWORK_ERROR;
172
192
  }
173
- if (lower.includes('unauthorized') || lower.includes('authentication required')) {
193
+ if (lower.includes('unauthorized') ||
194
+ lower.includes('authentication required')) {
174
195
  return exports.DataErrorType.UNAUTHORIZED;
175
196
  }
176
197
  if (lower.includes('forbidden') || lower.includes('permission')) {
@@ -182,7 +203,8 @@ function classifyByMessage(message) {
182
203
  if (lower.includes('foreign key constraint')) {
183
204
  return exports.DataErrorType.FOREIGN_KEY_VIOLATION;
184
205
  }
185
- if (lower.includes('not-null constraint') || lower.includes('null value in column')) {
206
+ if (lower.includes('not-null constraint') ||
207
+ lower.includes('null value in column')) {
186
208
  return exports.DataErrorType.NOT_NULL_VIOLATION;
187
209
  }
188
210
  return exports.DataErrorType.UNKNOWN_ERROR;
package/client/execute.js CHANGED
@@ -6,8 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.execute = execute;
7
7
  exports.createGraphQLClient = createGraphQLClient;
8
8
  const graphql_1 = require("graphql");
9
- const typed_document_1 = require("./typed-document");
10
9
  const error_1 = require("./error");
10
+ const typed_document_1 = require("./typed-document");
11
11
  // ============================================================================
12
12
  // Helpers
13
13
  // ============================================================================
@@ -102,7 +102,7 @@ async function handleHttpError(response) {
102
102
  * Create a GraphQL client instance
103
103
  */
104
104
  function createGraphQLClient(options) {
105
- const { endpoint, headers: defaultHeaders = {}, timeout: defaultTimeout = 30000 } = options;
105
+ const { endpoint, headers: defaultHeaders = {}, timeout: defaultTimeout = 30000, } = options;
106
106
  return {
107
107
  /**
108
108
  * Execute a GraphQL operation
package/client/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Client exports
3
3
  */
4
- export { TypedDocumentString, type DocumentTypeDecoration } from './typed-document';
5
- export { DataError, DataErrorType, createError, parseGraphQLError, isDataError, PG_ERROR_CODES, type DataErrorOptions, type GraphQLError, } from './error';
6
- export { execute, createGraphQLClient, type ExecuteOptions, type GraphQLClientOptions, type GraphQLClient, type GraphQLResponse, } from './execute';
4
+ export { createError, DataError, type DataErrorOptions, DataErrorType, type GraphQLError, isDataError, parseGraphQLError, PG_ERROR_CODES, } from './error';
5
+ export { createGraphQLClient, execute, type ExecuteOptions, type GraphQLClient, type GraphQLClientOptions, type GraphQLResponse, } from './execute';
6
+ export { type DocumentTypeDecoration, TypedDocumentString, } from './typed-document';
package/client/index.js CHANGED
@@ -3,16 +3,16 @@
3
3
  * Client exports
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.createGraphQLClient = exports.execute = exports.PG_ERROR_CODES = exports.isDataError = exports.parseGraphQLError = exports.createError = exports.DataErrorType = exports.DataError = exports.TypedDocumentString = void 0;
7
- var typed_document_1 = require("./typed-document");
8
- Object.defineProperty(exports, "TypedDocumentString", { enumerable: true, get: function () { return typed_document_1.TypedDocumentString; } });
6
+ exports.TypedDocumentString = exports.execute = exports.createGraphQLClient = exports.PG_ERROR_CODES = exports.parseGraphQLError = exports.isDataError = exports.DataErrorType = exports.DataError = exports.createError = void 0;
9
7
  var error_1 = require("./error");
8
+ Object.defineProperty(exports, "createError", { enumerable: true, get: function () { return error_1.createError; } });
10
9
  Object.defineProperty(exports, "DataError", { enumerable: true, get: function () { return error_1.DataError; } });
11
10
  Object.defineProperty(exports, "DataErrorType", { enumerable: true, get: function () { return error_1.DataErrorType; } });
12
- Object.defineProperty(exports, "createError", { enumerable: true, get: function () { return error_1.createError; } });
13
- Object.defineProperty(exports, "parseGraphQLError", { enumerable: true, get: function () { return error_1.parseGraphQLError; } });
14
11
  Object.defineProperty(exports, "isDataError", { enumerable: true, get: function () { return error_1.isDataError; } });
12
+ Object.defineProperty(exports, "parseGraphQLError", { enumerable: true, get: function () { return error_1.parseGraphQLError; } });
15
13
  Object.defineProperty(exports, "PG_ERROR_CODES", { enumerable: true, get: function () { return error_1.PG_ERROR_CODES; } });
16
14
  var execute_1 = require("./execute");
17
- Object.defineProperty(exports, "execute", { enumerable: true, get: function () { return execute_1.execute; } });
18
15
  Object.defineProperty(exports, "createGraphQLClient", { enumerable: true, get: function () { return execute_1.createGraphQLClient; } });
16
+ Object.defineProperty(exports, "execute", { enumerable: true, get: function () { return execute_1.execute; } });
17
+ var typed_document_1 = require("./typed-document");
18
+ Object.defineProperty(exports, "TypedDocumentString", { enumerable: true, get: function () { return typed_document_1.TypedDocumentString; } });
package/core/ast.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { DocumentNode, FieldNode } from 'graphql';
2
- import type { ASTFunctionParams, QueryFieldSelection, MutationASTParams } from './types';
2
+ import type { ASTFunctionParams, MutationASTParams, QueryFieldSelection } from './types';
3
3
  export declare const getAll: ({ queryName, operationName, selection, }: ASTFunctionParams) => DocumentNode;
4
4
  export declare const getCount: ({ queryName, operationName, query, }: Omit<ASTFunctionParams, "selection">) => DocumentNode;
5
5
  export declare const getMany: ({ builder, queryName, operationName, query, selection, }: ASTFunctionParams) => DocumentNode;
package/core/ast.js CHANGED
@@ -571,7 +571,7 @@ function getUpdateVariablesAst(attrs, patchers) {
571
571
  const patchVariables = attrs
572
572
  .filter((field) => !patchers.includes(field.name))
573
573
  .map((field) => {
574
- const { name: fieldName, type: fieldType, isArray, isArrayNotNull } = field;
574
+ const { name: fieldName, type: fieldType, isArray, isArrayNotNull, } = field;
575
575
  let type = t.namedType({ type: fieldType });
576
576
  if (isArray) {
577
577
  type = t.listType({ type });
@@ -7,7 +7,7 @@
7
7
  */
8
8
  import generate from '@babel/generator';
9
9
  import * as t from '@babel/types';
10
- export { t, generate };
10
+ export { generate, t };
11
11
  /**
12
12
  * Generate code from an array of statements
13
13
  */
@@ -36,7 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.commentLine = exports.commentBlock = exports.generate = exports.t = void 0;
39
+ exports.commentLine = exports.commentBlock = exports.t = exports.generate = void 0;
40
40
  exports.generateCode = generateCode;
41
41
  exports.addJSDocComment = addJSDocComment;
42
42
  exports.addLineComment = addLineComment;
@@ -96,7 +96,7 @@ exports.commentLine = commentLine;
96
96
  function addJSDocComment(node, lines) {
97
97
  const commentText = lines.length === 1
98
98
  ? `* ${lines[0]} `
99
- : `*\n${lines.map(line => ` * ${line}`).join('\n')}\n `;
99
+ : `*\n${lines.map((line) => ` * ${line}`).join('\n')}\n `;
100
100
  if (!node.leadingComments) {
101
101
  node.leadingComments = [];
102
102
  }
@@ -1,8 +1,3 @@
1
- /**
2
- * Barrel file generators - creates index.ts files for exports
3
- *
4
- * Using Babel AST for generating barrel (index.ts) files with re-exports.
5
- */
6
1
  import type { CleanTable } from '../../types/schema';
7
2
  /**
8
3
  * Generate the queries/index.ts barrel file
@@ -19,7 +14,6 @@ export declare function generateMutationsBarrel(tables: CleanTable[]): string;
19
14
  * @param hasSchemaTypes - Whether schema-types.ts was generated
20
15
  */
21
16
  export interface MainBarrelOptions {
22
- hasSchemaTypes?: boolean;
23
17
  hasMutations?: boolean;
24
18
  /** Whether query-keys.ts was generated */
25
19
  hasQueryKeys?: boolean;
@@ -39,10 +39,15 @@ exports.generateMainBarrel = generateMainBarrel;
39
39
  exports.generateRootBarrel = generateRootBarrel;
40
40
  exports.generateCustomQueriesBarrel = generateCustomQueriesBarrel;
41
41
  exports.generateCustomMutationsBarrel = generateCustomMutationsBarrel;
42
+ /**
43
+ * Barrel file generators - creates index.ts files for exports
44
+ *
45
+ * Using Babel AST for generating barrel (index.ts) files with re-exports.
46
+ */
42
47
  const t = __importStar(require("@babel/types"));
43
48
  const babel_ast_1 = require("./babel-ast");
44
- const utils_1 = require("./utils");
45
49
  const type_resolver_1 = require("./type-resolver");
50
+ const utils_1 = require("./utils");
46
51
  /**
47
52
  * Helper to create export * from './module' statement
48
53
  */
@@ -82,14 +87,14 @@ function generateMutationsBarrel(tables) {
82
87
  // Export all mutation hooks
83
88
  for (const table of tables) {
84
89
  const createHookName = (0, utils_1.getCreateMutationHookName)(table);
85
- const updateHookName = (0, utils_1.getUpdateMutationHookName)(table);
86
- const deleteHookName = (0, utils_1.getDeleteMutationHookName)(table);
87
90
  statements.push(exportAllFrom(`./${createHookName}`));
88
- // Only add update/delete if they exist
89
- if (table.query?.update !== null) {
91
+ // Only add update/delete if they exist AND table has valid PK
92
+ if (table.query?.update !== null && (0, utils_1.hasValidPrimaryKey)(table)) {
93
+ const updateHookName = (0, utils_1.getUpdateMutationHookName)(table);
90
94
  statements.push(exportAllFrom(`./${updateHookName}`));
91
95
  }
92
- if (table.query?.delete !== null) {
96
+ if (table.query?.delete !== null && (0, utils_1.hasValidPrimaryKey)(table)) {
97
+ const deleteHookName = (0, utils_1.getDeleteMutationHookName)(table);
93
98
  statements.push(exportAllFrom(`./${deleteHookName}`));
94
99
  }
95
100
  }
@@ -105,17 +110,11 @@ function generateMutationsBarrel(tables) {
105
110
  }
106
111
  function generateMainBarrel(tables, options = {}) {
107
112
  const opts = options;
108
- const { hasSchemaTypes = false, hasMutations = true, hasQueryKeys = false, hasMutationKeys = false, hasInvalidation = false, } = opts;
113
+ const { hasMutations = true, hasQueryKeys = false, hasMutationKeys = false, hasInvalidation = false, } = opts;
109
114
  const tableNames = tables.map((tbl) => tbl.name).join(', ');
110
115
  const statements = [];
111
- // Client configuration
116
+ // Client configuration (ORM wrapper with configure/getClient)
112
117
  statements.push(exportAllFrom('./client'));
113
- // Entity and filter types
114
- statements.push(exportAllFrom('./types'));
115
- // Schema types (input, payload, enum types)
116
- if (hasSchemaTypes) {
117
- statements.push(exportAllFrom('./schema-types'));
118
- }
119
118
  // Centralized query keys (for cache management)
120
119
  if (hasQueryKeys) {
121
120
  statements.push(exportAllFrom('./query-keys'));
@@ -159,8 +158,12 @@ function generateMainBarrel(tables, options = {}) {
159
158
  "import { useCarsQuery, useCreateCarMutation } from './generated';",
160
159
  '',
161
160
  'function MyComponent() {',
162
- ' const { data, isLoading } = useCarsQuery({ first: 10 });',
163
- ' const { mutate } = useCreateCarMutation();',
161
+ ' const { data, isLoading } = useCarsQuery({',
162
+ ' selection: { fields: { id: true }, first: 10 },',
163
+ ' });',
164
+ ' const { mutate } = useCreateCarMutation({',
165
+ ' selection: { fields: { id: true } },',
166
+ ' });',
164
167
  ' // ...',
165
168
  '}',
166
169
  '```',
@@ -249,15 +252,15 @@ function generateCustomMutationsBarrel(tables, customMutationNames) {
249
252
  statements.push(exportAllFrom(`./${createHookName}`));
250
253
  exportedHooks.add(createHookName);
251
254
  }
252
- // Only add update/delete if they exist
253
- if (table.query?.update !== null) {
255
+ // Only add update/delete if they exist AND table has valid PK
256
+ if (table.query?.update !== null && (0, utils_1.hasValidPrimaryKey)(table)) {
254
257
  const updateHookName = (0, utils_1.getUpdateMutationHookName)(table);
255
258
  if (!exportedHooks.has(updateHookName)) {
256
259
  statements.push(exportAllFrom(`./${updateHookName}`));
257
260
  exportedHooks.add(updateHookName);
258
261
  }
259
262
  }
260
- if (table.query?.delete !== null) {
263
+ if (table.query?.delete !== null && (0, utils_1.hasValidPrimaryKey)(table)) {
261
264
  const deleteHookName = (0, utils_1.getDeleteMutationHookName)(table);
262
265
  if (!exportedHooks.has(deleteHookName)) {
263
266
  statements.push(exportAllFrom(`./${deleteHookName}`));
@@ -1,14 +1,4 @@
1
- export interface GenerateClientFileOptions {
2
- /**
3
- * Generate browser-compatible code using native fetch
4
- * When true (default), uses native W3C fetch API
5
- * When false, uses undici fetch with dispatcher support for localhost DNS resolution
6
- * @default true
7
- */
8
- browserCompatible?: boolean;
9
- }
10
1
  /**
11
- * Generate client.ts content
12
- * @param options - Generation options
2
+ * Generate client.ts content - ORM client wrapper with configure/getClient
13
3
  */
14
- export declare function generateClientFile(options?: GenerateClientFileOptions): string;
4
+ export declare function generateClientFile(): string;