@constructive-io/graphql-codegen 3.2.1 → 3.3.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 (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
@@ -4,15 +4,15 @@
4
4
  * This is the primary entry point for programmatic usage.
5
5
  * The CLI is a thin wrapper around this function.
6
6
  */
7
- import path from 'path';
8
- import { createSchemaSource, validateSourceOptions } from './introspect';
9
- import { runCodegenPipeline, validateTablesFound } from './pipeline';
7
+ import path from 'node:path';
8
+ import { getConfigOptions } from '../types/config';
10
9
  import { generate as generateReactQueryFiles } from './codegen';
11
10
  import { generateRootBarrel } from './codegen/barrel';
12
11
  import { generateOrm as generateOrmFiles } from './codegen/orm';
13
12
  import { generateSharedTypes } from './codegen/shared';
13
+ import { createSchemaSource, validateSourceOptions } from './introspect';
14
14
  import { writeGeneratedFiles } from './output';
15
- import { getConfigOptions } from '../types/config';
15
+ import { runCodegenPipeline, validateTablesFound } from './pipeline';
16
16
  /**
17
17
  * Main generate function - takes a single config and generates code
18
18
  *
@@ -24,8 +24,10 @@ export async function generate(options = {}) {
24
24
  const config = getConfigOptions(options);
25
25
  const outputRoot = config.output;
26
26
  // Determine which generators to run
27
+ // ORM is always required when React Query is enabled (hooks delegate to ORM)
28
+ // This handles minimist setting orm=false when --orm flag is absent
27
29
  const runReactQuery = config.reactQuery ?? false;
28
- const runOrm = config.orm ?? false;
30
+ const runOrm = runReactQuery || (options.orm !== undefined ? !!options.orm : false);
29
31
  if (!runReactQuery && !runOrm) {
30
32
  return {
31
33
  success: false,
@@ -50,7 +52,7 @@ export async function generate(options = {}) {
50
52
  endpoint: config.endpoint || undefined,
51
53
  schemaFile: config.schemaFile || undefined,
52
54
  db: config.db,
53
- authorization: options.authorization || config.headers?.['Authorization'],
55
+ authorization: options.authorization || config.headers?.Authorization,
54
56
  headers: config.headers,
55
57
  });
56
58
  // Run pipeline
@@ -83,6 +85,7 @@ export async function generate(options = {}) {
83
85
  }
84
86
  const allFilesWritten = [];
85
87
  const bothEnabled = runReactQuery && runOrm;
88
+ const filesToWrite = [];
86
89
  // Generate shared types when both are enabled
87
90
  if (bothEnabled) {
88
91
  console.log('Generating shared types...');
@@ -95,22 +98,10 @@ export async function generate(options = {}) {
95
98
  },
96
99
  config,
97
100
  });
98
- if (!options.dryRun) {
99
- const writeResult = await writeGeneratedFiles(sharedResult.files, outputRoot, []);
100
- if (!writeResult.success) {
101
- return {
102
- success: false,
103
- message: `Failed to write shared types: ${writeResult.errors?.join(', ')}`,
104
- output: outputRoot,
105
- errors: writeResult.errors,
106
- };
107
- }
108
- allFilesWritten.push(...(writeResult.filesWritten ?? []));
109
- }
101
+ filesToWrite.push(...sharedResult.files);
110
102
  }
111
103
  // Generate React Query hooks
112
104
  if (runReactQuery) {
113
- const hooksDir = path.join(outputRoot, 'hooks');
114
105
  console.log('Generating React Query hooks...');
115
106
  const { files } = generateReactQueryFiles({
116
107
  tables,
@@ -122,22 +113,13 @@ export async function generate(options = {}) {
122
113
  config,
123
114
  sharedTypesPath: bothEnabled ? '..' : undefined,
124
115
  });
125
- if (!options.dryRun) {
126
- const writeResult = await writeGeneratedFiles(files, hooksDir, ['queries', 'mutations']);
127
- if (!writeResult.success) {
128
- return {
129
- success: false,
130
- message: `Failed to write React Query hooks: ${writeResult.errors?.join(', ')}`,
131
- output: outputRoot,
132
- errors: writeResult.errors,
133
- };
134
- }
135
- allFilesWritten.push(...(writeResult.filesWritten ?? []));
136
- }
116
+ filesToWrite.push(...files.map((file) => ({
117
+ ...file,
118
+ path: path.posix.join('hooks', file.path),
119
+ })));
137
120
  }
138
121
  // Generate ORM client
139
122
  if (runOrm) {
140
- const ormDir = path.join(outputRoot, 'orm');
141
123
  console.log('Generating ORM client...');
142
124
  const { files } = generateOrmFiles({
143
125
  tables,
@@ -149,30 +131,36 @@ export async function generate(options = {}) {
149
131
  config,
150
132
  sharedTypesPath: bothEnabled ? '..' : undefined,
151
133
  });
152
- if (!options.dryRun) {
153
- const writeResult = await writeGeneratedFiles(files, ormDir, ['models', 'query', 'mutation']);
154
- if (!writeResult.success) {
155
- return {
156
- success: false,
157
- message: `Failed to write ORM client: ${writeResult.errors?.join(', ')}`,
158
- output: outputRoot,
159
- errors: writeResult.errors,
160
- };
161
- }
162
- allFilesWritten.push(...(writeResult.filesWritten ?? []));
163
- }
134
+ filesToWrite.push(...files.map((file) => ({
135
+ ...file,
136
+ path: path.posix.join('orm', file.path),
137
+ })));
164
138
  }
165
139
  // Generate barrel file at output root
166
140
  // This re-exports from the appropriate subdirectories based on which generators are enabled
141
+ const barrelContent = generateRootBarrel({
142
+ hasTypes: bothEnabled,
143
+ hasHooks: runReactQuery,
144
+ hasOrm: runOrm,
145
+ });
146
+ filesToWrite.push({ path: 'index.ts', content: barrelContent });
167
147
  if (!options.dryRun) {
168
- const barrelContent = generateRootBarrel({
169
- hasTypes: bothEnabled,
170
- hasHooks: runReactQuery,
171
- hasOrm: runOrm,
148
+ const writeResult = await writeGeneratedFiles(filesToWrite, outputRoot, [], {
149
+ pruneStaleFiles: true,
172
150
  });
173
- await writeGeneratedFiles([{ path: 'index.ts', content: barrelContent }], outputRoot, []);
151
+ if (!writeResult.success) {
152
+ return {
153
+ success: false,
154
+ message: `Failed to write generated files: ${writeResult.errors?.join(', ')}`,
155
+ output: outputRoot,
156
+ errors: writeResult.errors,
157
+ };
158
+ }
159
+ allFilesWritten.push(...(writeResult.filesWritten ?? []));
174
160
  }
175
- const generators = [runReactQuery && 'React Query', runOrm && 'ORM'].filter(Boolean).join(' and ');
161
+ const generators = [runReactQuery && 'React Query', runOrm && 'ORM']
162
+ .filter(Boolean)
163
+ .join(' and ');
176
164
  return {
177
165
  success: true,
178
166
  message: options.dryRun
@@ -4,13 +4,13 @@
4
4
  * This module contains all the core business logic for graphql-codegen.
5
5
  * The CLI is a thin wrapper around these core functions.
6
6
  */
7
- export { generate } from './generate';
8
7
  export type { GenerateOptions, GenerateResult } from './generate';
8
+ export { generate } from './generate';
9
9
  export * from './types';
10
10
  export * from './ast';
11
11
  export * from './custom-ast';
12
- export { QueryBuilder, MetaObject } from './query-builder';
13
- export { validateMetaObject, convertFromMetaSchema } from './meta-object';
12
+ export { MetaObject, QueryBuilder } from './query-builder';
13
+ export { convertFromMetaSchema, validateMetaObject } from './meta-object';
14
14
  export * from './config';
15
15
  export * from './codegen';
16
16
  export * from './introspect';
package/esm/core/index.js CHANGED
@@ -4,7 +4,6 @@
4
4
  * This module contains all the core business logic for graphql-codegen.
5
5
  * The CLI is a thin wrapper around these core functions.
6
6
  */
7
- // Main generate function (orchestrates the entire pipeline)
8
7
  export { generate } from './generate';
9
8
  // Types
10
9
  export * from './types';
@@ -12,9 +11,9 @@ export * from './types';
12
11
  export * from './ast';
13
12
  export * from './custom-ast';
14
13
  // Query builder
15
- export { QueryBuilder, MetaObject } from './query-builder';
14
+ export { MetaObject, QueryBuilder } from './query-builder';
16
15
  // Meta object utilities
17
- export { validateMetaObject, convertFromMetaSchema } from './meta-object';
16
+ export { convertFromMetaSchema, validateMetaObject } from './meta-object';
18
17
  // Configuration loading and resolution
19
18
  export * from './config';
20
19
  // Code generation
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * Introspection module exports
3
3
  */
4
- export { inferTablesFromIntrospection } from './infer-tables';
5
4
  export type { InferTablesOptions } from './infer-tables';
6
- export { singularize, pluralize } from 'inflekt';
7
- export { createSchemaSource, validateSourceOptions, EndpointSchemaSource, FileSchemaSource, SchemaSourceError, } from './source';
8
- export type { SchemaSource, SchemaSourceResult, CreateSchemaSourceOptions, } from './source';
9
- export { fetchSchema } from './fetch-schema';
5
+ export { inferTablesFromIntrospection } from './infer-tables';
6
+ export { pluralize, singularize } from 'inflekt';
7
+ export type { CreateSchemaSourceOptions, SchemaSource, SchemaSourceResult, } from './source';
8
+ export { createSchemaSource, EndpointSchemaSource, FileSchemaSource, SchemaSourceError, validateSourceOptions, } from './source';
10
9
  export type { FetchSchemaOptions, FetchSchemaResult } from './fetch-schema';
11
- export { getTableNames, findTable, filterTables } from './transform';
10
+ export { fetchSchema } from './fetch-schema';
11
+ export { filterTables, findTable, getTableNames } from './transform';
@@ -1,13 +1,10 @@
1
1
  /**
2
2
  * Introspection module exports
3
3
  */
4
- // Table inference from introspection
5
4
  export { inferTablesFromIntrospection } from './infer-tables';
6
5
  // Pluralization utilities (from inflekt)
7
- export { singularize, pluralize } from 'inflekt';
8
- // Schema sources
9
- export { createSchemaSource, validateSourceOptions, EndpointSchemaSource, FileSchemaSource, SchemaSourceError, } from './source';
10
- // Schema fetching (still used by watch mode)
6
+ export { pluralize, singularize } from 'inflekt';
7
+ export { createSchemaSource, EndpointSchemaSource, FileSchemaSource, SchemaSourceError, validateSourceOptions, } from './source';
11
8
  export { fetchSchema } from './fetch-schema';
12
9
  // Transform utilities (only filterTables, getTableNames, findTable are still useful)
13
- export { getTableNames, findTable, filterTables } from './transform';
10
+ export { filterTables, findTable, getTableNames } from './transform';
@@ -1,17 +1,3 @@
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
1
  import type { IntrospectionQueryResponse } from '../../types/introspection';
16
2
  import type { CleanTable } from '../../types/schema';
17
3
  /**
@@ -1,5 +1,19 @@
1
- import { unwrapType, getBaseTypeName, isList } from '../../types/introspection';
2
- import { singularize, pluralize, lcFirst, ucFirst } from 'inflekt';
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 { lcFirst, pluralize, singularize, ucFirst } from 'inflekt';
16
+ import { getBaseTypeName, isList, unwrapType } from '../../types/introspection';
3
17
  // ============================================================================
4
18
  // Pattern Matching Constants
5
19
  // ============================================================================
@@ -5,9 +5,9 @@
5
5
  * introspection and converts it to introspection format.
6
6
  */
7
7
  import { buildSchema, introspectionFromSchema } from 'graphql';
8
- import { SchemaSourceError } from './types';
9
8
  import { buildSchemaSDLFromDatabase } from '../../database';
10
- import { createDatabasePool, resolveApiSchemas, validateServicesSchemas } from './api-schemas';
9
+ import { createDatabasePool, resolveApiSchemas, validateServicesSchemas, } from './api-schemas';
10
+ import { SchemaSourceError } from './types';
11
11
  /**
12
12
  * Schema source that loads from a PostgreSQL database
13
13
  *
@@ -1,9 +1,3 @@
1
- /**
2
- * Endpoint Schema Source
3
- *
4
- * Fetches GraphQL schema via introspection from a live endpoint.
5
- * Wraps the existing fetchSchema() function with the SchemaSource interface.
6
- */
7
1
  import type { SchemaSource, SchemaSourceResult } from './types';
8
2
  export interface EndpointSchemaSourceOptions {
9
3
  /**
@@ -1,5 +1,11 @@
1
- import { SchemaSourceError } from './types';
1
+ /**
2
+ * Endpoint Schema Source
3
+ *
4
+ * Fetches GraphQL schema via introspection from a live endpoint.
5
+ * Wraps the existing fetchSchema() function with the SchemaSource interface.
6
+ */
2
7
  import { fetchSchema } from '../fetch-schema';
8
+ import { SchemaSourceError } from './types';
3
9
  /**
4
10
  * Schema source that fetches from a live GraphQL endpoint
5
11
  */
@@ -7,14 +7,14 @@
7
7
  * - PostgreSQL databases (via PostGraphile introspection)
8
8
  * - PGPM modules (via ephemeral database deployment)
9
9
  */
10
- export * from './types';
10
+ export * from './api-schemas';
11
+ export * from './database';
11
12
  export * from './endpoint';
12
13
  export * from './file';
13
- export * from './database';
14
14
  export * from './pgpm-module';
15
- export * from './api-schemas';
16
- import type { SchemaSource } from './types';
15
+ export * from './types';
17
16
  import type { DbConfig } from '../../../types/config';
17
+ import type { SchemaSource } from './types';
18
18
  /**
19
19
  * Options for endpoint-based schema source
20
20
  */
@@ -7,16 +7,16 @@
7
7
  * - PostgreSQL databases (via PostGraphile introspection)
8
8
  * - PGPM modules (via ephemeral database deployment)
9
9
  */
10
- export * from './types';
10
+ export * from './api-schemas';
11
+ export * from './database';
11
12
  export * from './endpoint';
12
13
  export * from './file';
13
- export * from './database';
14
14
  export * from './pgpm-module';
15
- export * from './api-schemas';
15
+ export * from './types';
16
+ import { DatabaseSchemaSource } from './database';
16
17
  import { EndpointSchemaSource } from './endpoint';
17
18
  import { FileSchemaSource } from './file';
18
- import { DatabaseSchemaSource } from './database';
19
- import { PgpmModuleSchemaSource, } from './pgpm-module';
19
+ import { PgpmModuleSchemaSource } from './pgpm-module';
20
20
  export function detectSourceMode(options) {
21
21
  if (options.endpoint)
22
22
  return 'endpoint';
@@ -93,11 +93,7 @@ export function createSchemaSource(options) {
93
93
  */
94
94
  export function validateSourceOptions(options) {
95
95
  // Count primary sources
96
- const sources = [
97
- options.endpoint,
98
- options.schemaFile,
99
- options.db,
100
- ].filter(Boolean);
96
+ const sources = [options.endpoint, options.schemaFile, options.db].filter(Boolean);
101
97
  if (sources.length === 0) {
102
98
  return {
103
99
  valid: false,
@@ -7,14 +7,14 @@
7
7
  * 3. Introspecting the database with PostGraphile
8
8
  * 4. Cleaning up the ephemeral database (unless keepDb is true)
9
9
  */
10
- import { buildSchema, introspectionFromSchema } from 'graphql';
11
10
  import { PgpmPackage } from '@pgpmjs/core';
11
+ import { buildSchema, introspectionFromSchema } from 'graphql';
12
+ import { getPgPool } from 'pg-cache';
12
13
  import { createEphemeralDb } from 'pgsql-client';
13
14
  import { deployPgpm } from 'pgsql-seed';
14
- import { getPgPool } from 'pg-cache';
15
- import { SchemaSourceError } from './types';
16
15
  import { buildSchemaSDLFromDatabase } from '../../database';
17
16
  import { resolveApiSchemas, validateServicesSchemas } from './api-schemas';
17
+ import { SchemaSourceError } from './types';
18
18
  /**
19
19
  * Type guard to check if options use direct module path
20
20
  */
@@ -5,7 +5,7 @@
5
5
  * format used by code generators.
6
6
  */
7
7
  import type { IntrospectionQueryResponse, IntrospectionType } from '../../types/introspection';
8
- import { unwrapType, getBaseTypeName, isNonNull } from '../../types/introspection';
8
+ import { getBaseTypeName, isNonNull, unwrapType } from '../../types/introspection';
9
9
  import type { CleanOperation, TypeRegistry } from '../../types/schema';
10
10
  /**
11
11
  * Build a type registry from introspection types
@@ -83,4 +83,4 @@ export declare function isTableOperation(operation: CleanOperation, tableOperati
83
83
  * - True custom operations (login, register, bootstrapUser, etc.)
84
84
  */
85
85
  export declare function getCustomOperations(operations: CleanOperation[], tableOperationNames: TableOperationNames): CleanOperation[];
86
- export { unwrapType, getBaseTypeName, isNonNull };
86
+ export { getBaseTypeName, isNonNull, unwrapType };
@@ -1,4 +1,4 @@
1
- import { unwrapType, getBaseTypeName, isNonNull, } from '../../types/introspection';
1
+ import { getBaseTypeName, isNonNull, unwrapType, } from '../../types/introspection';
2
2
  // ============================================================================
3
3
  // Type Registry Builder
4
4
  // ============================================================================
@@ -266,4 +266,4 @@ export function getCustomOperations(operations, tableOperationNames) {
266
266
  return operations.filter((op) => !isTableOperation(op, tableOperationNames));
267
267
  }
268
268
  // Re-export utility functions from introspection types
269
- export { unwrapType, getBaseTypeName, isNonNull };
269
+ export { getBaseTypeName, isNonNull, unwrapType };
@@ -1,4 +1,4 @@
1
1
  /**
2
2
  * Output module exports
3
3
  */
4
- export { writeGeneratedFiles, formatOutput, type GeneratedFile, type WriteResult, type WriteOptions, } from './writer';
4
+ export { formatOutput, type GeneratedFile, writeGeneratedFiles, type WriteOptions, type WriteResult, } from './writer';
@@ -1,4 +1,4 @@
1
1
  /**
2
2
  * Output module exports
3
3
  */
4
- export { writeGeneratedFiles, formatOutput, } from './writer';
4
+ export { formatOutput, writeGeneratedFiles, } from './writer';
@@ -6,6 +6,7 @@ export type { GeneratedFile };
6
6
  export interface WriteResult {
7
7
  success: boolean;
8
8
  filesWritten?: string[];
9
+ filesRemoved?: string[];
9
10
  errors?: string[];
10
11
  }
11
12
  /**
@@ -16,6 +17,8 @@ export interface WriteOptions {
16
17
  showProgress?: boolean;
17
18
  /** Format files with oxfmt after writing (default: true) */
18
19
  formatFiles?: boolean;
20
+ /** Remove stale .ts files in outputDir that are not in current file list (default: false) */
21
+ pruneStaleFiles?: boolean;
19
22
  }
20
23
  /**
21
24
  * Write generated files to disk
@@ -46,9 +46,10 @@ async function formatFileContent(fileName, content, formatFn) {
46
46
  * @param options - Write options
47
47
  */
48
48
  export async function writeGeneratedFiles(files, outputDir, subdirs, options = {}) {
49
- const { showProgress = true, formatFiles = true } = options;
49
+ const { showProgress = true, formatFiles = true, pruneStaleFiles = false, } = options;
50
50
  const errors = [];
51
51
  const written = [];
52
+ const removed = [];
52
53
  const total = files.length;
53
54
  const isTTY = process.stdout.isTTY;
54
55
  // Ensure output directory exists
@@ -76,6 +77,23 @@ export async function writeGeneratedFiles(files, outputDir, subdirs, options = {
76
77
  if (errors.length > 0) {
77
78
  return { success: false, errors };
78
79
  }
80
+ if (pruneStaleFiles) {
81
+ const expectedFiles = new Set(files.map((file) => path.resolve(outputDir, file.path)));
82
+ const existingTsFiles = findTsFiles(outputDir);
83
+ for (const existingFile of existingTsFiles) {
84
+ const absolutePath = path.resolve(existingFile);
85
+ if (expectedFiles.has(absolutePath))
86
+ continue;
87
+ try {
88
+ fs.rmSync(absolutePath, { force: true });
89
+ removed.push(absolutePath);
90
+ }
91
+ catch (err) {
92
+ const message = err instanceof Error ? err.message : 'Unknown error';
93
+ errors.push(`Failed to remove stale file ${absolutePath}: ${message}`);
94
+ }
95
+ }
96
+ }
79
97
  // Get oxfmt format function if formatting is enabled
80
98
  const formatFn = formatFiles ? await getOxfmtFormat() : null;
81
99
  if (formatFiles && !formatFn && showProgress) {
@@ -124,6 +142,7 @@ export async function writeGeneratedFiles(files, outputDir, subdirs, options = {
124
142
  return {
125
143
  success: errors.length === 0,
126
144
  filesWritten: written,
145
+ filesRemoved: removed,
127
146
  errors: errors.length > 0 ? errors : undefined,
128
147
  };
129
148
  }
@@ -9,10 +9,10 @@
9
9
  * - Filtering
10
10
  */
11
11
  import type { GraphQLSDKConfigTarget } from '../../types/config';
12
- import type { CleanTable, CleanOperation, TypeRegistry } from '../../types/schema';
12
+ import type { CleanOperation, CleanTable, TypeRegistry } from '../../types/schema';
13
13
  import type { SchemaSource } from '../introspect/source';
14
14
  export type { SchemaSource } from '../introspect/source';
15
- export { createSchemaSource, validateSourceOptions } from '../introspect/source';
15
+ export { createSchemaSource, validateSourceOptions, } from '../introspect/source';
16
16
  export interface CodegenPipelineOptions {
17
17
  /**
18
18
  * Schema source (endpoint or file)
@@ -1,7 +1,7 @@
1
1
  import { inferTablesFromIntrospection } from '../introspect/infer-tables';
2
2
  import { filterTables } from '../introspect/transform';
3
- import { transformSchemaToOperations, filterOperations, getTableOperationNames, getCustomOperations, } from '../introspect/transform-schema';
4
- export { createSchemaSource, validateSourceOptions } from '../introspect/source';
3
+ import { filterOperations, getCustomOperations, getTableOperationNames, transformSchemaToOperations, } from '../introspect/transform-schema';
4
+ export { createSchemaSource, validateSourceOptions, } from '../introspect/source';
5
5
  // ============================================================================
6
6
  // Main Pipeline
7
7
  // ============================================================================
@@ -1,4 +1,4 @@
1
- import type { QueryFieldSelection, IntrospectionSchema, MetaObject, QueryBuilderOptions, QueryBuilderResult, QueryDefinition, QuerySelectionOptions } from './types';
1
+ import type { IntrospectionSchema, MetaObject, QueryBuilderOptions, QueryBuilderResult, QueryDefinition, QueryFieldSelection, QuerySelectionOptions } from './types';
2
2
  export * as MetaObject from './meta-object';
3
3
  export declare class QueryBuilder {
4
4
  _introspection: IntrospectionSchema;
@@ -12,7 +12,7 @@ export declare class QueryBuilder {
12
12
  private _op;
13
13
  private _mutation;
14
14
  private _select;
15
- constructor({ meta, introspection, }: QueryBuilderOptions);
15
+ constructor({ meta, introspection }: QueryBuilderOptions);
16
16
  initModelMap(): void;
17
17
  clear(): void;
18
18
  query(model: string): QueryBuilder;
@@ -1,5 +1,5 @@
1
1
  import { print as gqlPrint } from 'graphql';
2
- import { camelize, underscore, pluralize } from 'inflekt';
2
+ import { camelize, pluralize, underscore } from 'inflekt';
3
3
  import { createOne, deleteOne, getAll, getCount, getMany, getOne, patchOne, } from './ast';
4
4
  import { validateMetaObject } from './meta-object';
5
5
  export * as MetaObject from './meta-object';
@@ -16,7 +16,7 @@ export class QueryBuilder {
16
16
  _op;
17
17
  _mutation;
18
18
  _select;
19
- constructor({ meta = {}, introspection, }) {
19
+ constructor({ meta = {}, introspection }) {
20
20
  this._introspection = introspection;
21
21
  this._meta = meta;
22
22
  this.clear();
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * Watch mode module exports
3
3
  */
4
- export { SchemaPoller, computeSchemaHash } from './poller';
5
4
  export { SchemaCache, touchFile } from './cache';
6
- export { sha256, hashObject, combineHashes } from './hash';
7
5
  export { debounce, debounceAsync } from './debounce';
8
- export { WatchOrchestrator, startWatch } from './orchestrator';
9
- export type { PollResult, WatchOptions, PollEventType, PollEventHandler, PollEvent, GeneratorType, } from './types';
6
+ export { combineHashes, hashObject, sha256 } from './hash';
10
7
  export type { WatchOrchestratorOptions, WatchStatus } from './orchestrator';
8
+ export { startWatch, WatchOrchestrator } from './orchestrator';
9
+ export { computeSchemaHash, SchemaPoller } from './poller';
10
+ export type { GeneratorType, PollEvent, PollEventHandler, PollEventType, PollResult, WatchOptions, } from './types';
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Watch mode module exports
3
3
  */
4
- export { SchemaPoller, computeSchemaHash } from './poller';
5
4
  export { SchemaCache, touchFile } from './cache';
6
- export { sha256, hashObject, combineHashes } from './hash';
7
5
  export { debounce, debounceAsync } from './debounce';
8
- export { WatchOrchestrator, startWatch } from './orchestrator';
6
+ export { combineHashes, hashObject, sha256 } from './hash';
7
+ export { startWatch, WatchOrchestrator } from './orchestrator';
8
+ export { computeSchemaHash, SchemaPoller } from './poller';
@@ -3,8 +3,8 @@
3
3
  *
4
4
  * Coordinates schema polling, change detection, and code regeneration
5
5
  */
6
- import { SchemaPoller } from './poller';
7
6
  import { debounce } from './debounce';
7
+ import { SchemaPoller } from './poller';
8
8
  /**
9
9
  * Main watch orchestrator class
10
10
  */
@@ -135,12 +135,14 @@ export class WatchOrchestrator {
135
135
  case 'react-query':
136
136
  generateFn = this.options.generateReactQuery;
137
137
  // React Query hooks go to {output}/hooks
138
- outputDir = this.options.outputDir ?? `${this.options.config.output}/hooks`;
138
+ outputDir =
139
+ this.options.outputDir ?? `${this.options.config.output}/hooks`;
139
140
  break;
140
141
  case 'orm':
141
142
  generateFn = this.options.generateOrm;
142
143
  // ORM client goes to {output}/orm
143
- outputDir = this.options.outputDir ?? `${this.options.config.output}/orm`;
144
+ outputDir =
145
+ this.options.outputDir ?? `${this.options.config.output}/orm`;
144
146
  break;
145
147
  default:
146
148
  throw new Error(`Unknown generator type: ${this.options.generatorType}`);
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Query and mutation generator exports
3
3
  */
4
- export { convertToSelectionOptions, isRelationalField, getAvailableRelations, validateFieldSelection, } from './field-selector';
5
- export { buildSelect, buildFindOne, buildCount, toCamelCasePlural, toOrderByTypeName, cleanTableToMetaObject, generateIntrospectionSchema, createASTQueryBuilder, } from './select';
6
- export { buildPostGraphileCreate, buildPostGraphileUpdate, buildPostGraphileDelete, } from './mutations';
4
+ export { convertToSelectionOptions, getAvailableRelations, isRelationalField, validateFieldSelection, } from './field-selector';
5
+ export { buildCount, buildFindOne, buildSelect, cleanTableToMetaObject, createASTQueryBuilder, generateIntrospectionSchema, toCamelCasePlural, toOrderByTypeName, } from './select';
6
+ export { buildPostGraphileCreate, buildPostGraphileDelete, buildPostGraphileUpdate, } from './mutations';
@@ -2,8 +2,8 @@
2
2
  * Query and mutation generator exports
3
3
  */
4
4
  // Field selector utilities
5
- export { convertToSelectionOptions, isRelationalField, getAvailableRelations, validateFieldSelection, } from './field-selector';
5
+ export { convertToSelectionOptions, getAvailableRelations, isRelationalField, validateFieldSelection, } from './field-selector';
6
6
  // Query generators
7
- export { buildSelect, buildFindOne, buildCount, toCamelCasePlural, toOrderByTypeName, cleanTableToMetaObject, generateIntrospectionSchema, createASTQueryBuilder, } from './select';
7
+ export { buildCount, buildFindOne, buildSelect, cleanTableToMetaObject, createASTQueryBuilder, generateIntrospectionSchema, toCamelCasePlural, toOrderByTypeName, } from './select';
8
8
  // Mutation generators
9
- export { buildPostGraphileCreate, buildPostGraphileUpdate, buildPostGraphileDelete, } from './mutations';
9
+ export { buildPostGraphileCreate, buildPostGraphileDelete, buildPostGraphileUpdate, } from './mutations';
@@ -1,6 +1,6 @@
1
1
  import { TypedDocumentString } from '../client/typed-document';
2
- import type { CleanTable } from '../types/schema';
3
2
  import type { MutationOptions } from '../types/mutation';
3
+ import type { CleanTable } from '../types/schema';
4
4
  /**
5
5
  * Build PostGraphile-style CREATE mutation
6
6
  * PostGraphile expects: mutation { createTableName(input: { tableName: TableNameInput! }) { tableName { ... } } }