@constructive-io/graphql-codegen 3.2.0 → 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.
- package/README.md +25 -30
- package/cli/index.js +36 -41
- package/cli/shared.d.ts +15 -17
- package/cli/shared.js +113 -21
- package/client/error.js +31 -9
- package/client/execute.js +2 -2
- package/client/index.d.ts +3 -3
- package/client/index.js +6 -6
- package/core/ast.d.ts +1 -1
- package/core/ast.js +1 -1
- package/core/codegen/babel-ast.d.ts +1 -1
- package/core/codegen/babel-ast.js +2 -2
- package/core/codegen/barrel.d.ts +0 -6
- package/core/codegen/barrel.js +22 -19
- package/core/codegen/client.d.ts +2 -12
- package/core/codegen/client.js +7 -21
- package/core/codegen/custom-mutations.d.ts +0 -14
- package/core/codegen/custom-mutations.js +139 -88
- package/core/codegen/custom-queries.d.ts +0 -14
- package/core/codegen/custom-queries.js +483 -193
- package/core/codegen/hooks-ast.d.ts +75 -0
- package/core/codegen/hooks-ast.js +522 -0
- package/core/codegen/index.d.ts +16 -18
- package/core/codegen/index.js +42 -88
- package/core/codegen/invalidation.d.ts +1 -7
- package/core/codegen/invalidation.js +50 -16
- package/core/codegen/mutation-keys.d.ts +1 -10
- package/core/codegen/mutation-keys.js +22 -8
- package/core/codegen/mutations.d.ts +0 -13
- package/core/codegen/mutations.js +301 -366
- package/core/codegen/orm/barrel.d.ts +0 -5
- package/core/codegen/orm/barrel.js +5 -0
- package/core/codegen/orm/client-generator.d.ts +0 -5
- package/core/codegen/orm/client-generator.js +7 -2
- package/core/codegen/orm/client.js +3 -1
- package/core/codegen/orm/custom-ops-generator.d.ts +0 -6
- package/core/codegen/orm/custom-ops-generator.js +104 -51
- package/core/codegen/orm/index.d.ts +4 -4
- package/core/codegen/orm/index.js +28 -15
- package/core/codegen/orm/input-types-generator.d.ts +1 -13
- package/core/codegen/orm/input-types-generator.js +85 -23
- package/core/codegen/orm/model-generator.d.ts +0 -5
- package/core/codegen/orm/model-generator.js +309 -131
- package/core/codegen/orm/select-types.d.ts +19 -14
- package/core/codegen/queries.d.ts +0 -8
- package/core/codegen/queries.js +360 -559
- package/core/codegen/query-keys.d.ts +1 -1
- package/core/codegen/query-keys.js +37 -23
- package/core/codegen/scalars.js +3 -1
- package/core/codegen/schema-types-generator.d.ts +1 -1
- package/core/codegen/schema-types-generator.js +17 -2
- package/core/codegen/select-helpers.d.ts +19 -0
- package/core/codegen/select-helpers.js +40 -0
- package/core/codegen/selection.d.ts +4 -0
- package/core/codegen/selection.js +65 -0
- package/core/codegen/shared/index.d.ts +2 -15
- package/core/codegen/shared/index.js +17 -4
- package/core/codegen/templates/hooks-client.ts +49 -0
- package/core/codegen/templates/hooks-selection.ts +58 -0
- package/core/codegen/templates/orm-client.ts +8 -6
- package/core/codegen/templates/query-builder.ts +250 -46
- package/core/codegen/templates/select-types.ts +31 -14
- package/core/codegen/type-resolver.d.ts +1 -5
- package/core/codegen/type-resolver.js +0 -22
- package/core/codegen/types.d.ts +0 -3
- package/core/codegen/types.js +71 -14
- package/core/codegen/utils.d.ts +1 -4
- package/core/codegen/utils.js +4 -1
- package/core/config/index.d.ts +1 -1
- package/core/config/resolver.js +1 -3
- package/core/generate.js +38 -50
- package/core/index.d.ts +3 -3
- package/core/index.js +3 -4
- package/core/introspect/index.d.ts +6 -6
- package/core/introspect/index.js +5 -8
- package/core/introspect/infer-tables.d.ts +0 -14
- package/core/introspect/infer-tables.js +15 -1
- package/core/introspect/source/database.js +1 -1
- package/core/introspect/source/endpoint.d.ts +0 -6
- package/core/introspect/source/endpoint.js +7 -1
- package/core/introspect/source/index.d.ts +4 -4
- package/core/introspect/source/index.js +5 -9
- package/core/introspect/source/pgpm-module.js +3 -3
- package/core/introspect/transform-schema.d.ts +2 -2
- package/core/introspect/transform-schema.js +2 -2
- package/core/output/index.d.ts +1 -1
- package/core/output/index.js +2 -2
- package/core/output/writer.d.ts +3 -0
- package/core/output/writer.js +20 -1
- package/core/pipeline/index.d.ts +2 -2
- package/core/query-builder.d.ts +2 -2
- package/core/query-builder.js +1 -1
- package/core/watch/index.d.ts +4 -4
- package/core/watch/index.js +9 -9
- package/core/watch/orchestrator.js +5 -3
- package/esm/cli/index.js +37 -42
- package/esm/cli/shared.d.ts +15 -17
- package/esm/cli/shared.js +103 -20
- package/esm/client/error.js +31 -9
- package/esm/client/execute.js +2 -2
- package/esm/client/index.d.ts +3 -3
- package/esm/client/index.js +3 -3
- package/esm/core/ast.d.ts +1 -1
- package/esm/core/ast.js +1 -1
- package/esm/core/codegen/babel-ast.d.ts +1 -1
- package/esm/core/codegen/babel-ast.js +2 -2
- package/esm/core/codegen/barrel.d.ts +0 -6
- package/esm/core/codegen/barrel.js +23 -20
- package/esm/core/codegen/client.d.ts +2 -12
- package/esm/core/codegen/client.js +7 -21
- package/esm/core/codegen/custom-mutations.d.ts +0 -14
- package/esm/core/codegen/custom-mutations.js +141 -90
- package/esm/core/codegen/custom-queries.d.ts +0 -14
- package/esm/core/codegen/custom-queries.js +486 -196
- package/esm/core/codegen/hooks-ast.d.ts +75 -0
- package/esm/core/codegen/hooks-ast.js +424 -0
- package/esm/core/codegen/index.d.ts +16 -18
- package/esm/core/codegen/index.js +26 -71
- package/esm/core/codegen/invalidation.d.ts +1 -7
- package/esm/core/codegen/invalidation.js +51 -17
- package/esm/core/codegen/mutation-keys.d.ts +1 -10
- package/esm/core/codegen/mutation-keys.js +23 -9
- package/esm/core/codegen/mutations.d.ts +0 -13
- package/esm/core/codegen/mutations.js +302 -367
- package/esm/core/codegen/orm/barrel.d.ts +0 -5
- package/esm/core/codegen/orm/barrel.js +6 -1
- package/esm/core/codegen/orm/client-generator.d.ts +0 -5
- package/esm/core/codegen/orm/client-generator.js +7 -2
- package/esm/core/codegen/orm/client.js +3 -1
- package/esm/core/codegen/orm/custom-ops-generator.d.ts +0 -6
- package/esm/core/codegen/orm/custom-ops-generator.js +103 -50
- package/esm/core/codegen/orm/index.d.ts +4 -4
- package/esm/core/codegen/orm/index.js +25 -12
- package/esm/core/codegen/orm/input-types-generator.d.ts +1 -13
- package/esm/core/codegen/orm/input-types-generator.js +85 -23
- package/esm/core/codegen/orm/model-generator.d.ts +0 -5
- package/esm/core/codegen/orm/model-generator.js +310 -132
- package/esm/core/codegen/orm/select-types.d.ts +19 -14
- package/esm/core/codegen/queries.d.ts +0 -8
- package/esm/core/codegen/queries.js +362 -561
- package/esm/core/codegen/query-keys.d.ts +1 -1
- package/esm/core/codegen/query-keys.js +38 -24
- package/esm/core/codegen/scalars.js +3 -1
- package/esm/core/codegen/schema-types-generator.d.ts +1 -1
- package/esm/core/codegen/schema-types-generator.js +17 -2
- package/esm/core/codegen/select-helpers.d.ts +19 -0
- package/esm/core/codegen/select-helpers.js +35 -0
- package/esm/core/codegen/selection.d.ts +4 -0
- package/esm/core/codegen/selection.js +29 -0
- package/esm/core/codegen/shared/index.d.ts +2 -15
- package/esm/core/codegen/shared/index.js +16 -3
- package/esm/core/codegen/type-resolver.d.ts +1 -5
- package/esm/core/codegen/type-resolver.js +1 -22
- package/esm/core/codegen/types.d.ts +0 -3
- package/esm/core/codegen/types.js +72 -15
- package/esm/core/codegen/utils.d.ts +1 -4
- package/esm/core/codegen/utils.js +4 -1
- package/esm/core/config/index.d.ts +1 -1
- package/esm/core/config/resolver.js +2 -4
- package/esm/core/generate.js +38 -50
- package/esm/core/index.d.ts +3 -3
- package/esm/core/index.js +2 -3
- package/esm/core/introspect/index.d.ts +6 -6
- package/esm/core/introspect/index.js +3 -6
- package/esm/core/introspect/infer-tables.d.ts +0 -14
- package/esm/core/introspect/infer-tables.js +16 -2
- package/esm/core/introspect/source/database.js +2 -2
- package/esm/core/introspect/source/endpoint.d.ts +0 -6
- package/esm/core/introspect/source/endpoint.js +7 -1
- package/esm/core/introspect/source/index.d.ts +4 -4
- package/esm/core/introspect/source/index.js +6 -10
- package/esm/core/introspect/source/pgpm-module.js +3 -3
- package/esm/core/introspect/transform-schema.d.ts +2 -2
- package/esm/core/introspect/transform-schema.js +2 -2
- package/esm/core/output/index.d.ts +1 -1
- package/esm/core/output/index.js +1 -1
- package/esm/core/output/writer.d.ts +3 -0
- package/esm/core/output/writer.js +20 -1
- package/esm/core/pipeline/index.d.ts +2 -2
- package/esm/core/pipeline/index.js +2 -2
- package/esm/core/query-builder.d.ts +2 -2
- package/esm/core/query-builder.js +2 -2
- package/esm/core/watch/index.d.ts +4 -4
- package/esm/core/watch/index.js +3 -3
- package/esm/core/watch/orchestrator.js +5 -3
- package/esm/generators/index.d.ts +3 -3
- package/esm/generators/index.js +3 -3
- package/esm/generators/mutations.d.ts +1 -1
- package/esm/generators/select.d.ts +1 -1
- package/esm/index.d.ts +3 -3
- package/esm/index.js +1 -4
- package/esm/types/config.d.ts +0 -10
- package/esm/types/config.js +0 -2
- package/esm/types/index.d.ts +6 -6
- package/esm/types/index.js +1 -1
- package/generators/index.d.ts +3 -3
- package/generators/index.js +8 -8
- package/generators/mutations.d.ts +1 -1
- package/generators/select.d.ts +1 -1
- package/index.d.ts +3 -3
- package/index.js +11 -5
- package/package.json +11 -11
- package/types/config.d.ts +0 -10
- package/types/config.js +0 -2
- package/types/index.d.ts +6 -6
- package/types/index.js +2 -2
- package/core/codegen/gql-ast.d.ts +0 -41
- package/core/codegen/gql-ast.js +0 -353
- package/core/codegen/schema-gql-ast.d.ts +0 -51
- package/core/codegen/schema-gql-ast.js +0 -385
- package/core/codegen/templates/client.browser.ts +0 -271
- package/core/codegen/templates/client.node.ts +0 -337
- package/esm/core/codegen/gql-ast.d.ts +0 -41
- package/esm/core/codegen/gql-ast.js +0 -312
- package/esm/core/codegen/schema-gql-ast.d.ts +0 -51
- package/esm/core/codegen/schema-gql-ast.js +0 -343
package/core/codegen/barrel.js
CHANGED
|
@@ -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 {
|
|
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({
|
|
163
|
-
'
|
|
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}`));
|
package/core/codegen/client.d.ts
CHANGED
|
@@ -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(
|
|
4
|
+
export declare function generateClientFile(): string;
|
package/core/codegen/client.js
CHANGED
|
@@ -35,45 +35,31 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.generateClientFile = generateClientFile;
|
|
37
37
|
/**
|
|
38
|
-
* Client generator - generates client.ts
|
|
38
|
+
* Client generator - generates client.ts as ORM client wrapper
|
|
39
39
|
*
|
|
40
|
-
*
|
|
40
|
+
* Uses template-copy pattern: reads hooks-client.ts from templates/
|
|
41
|
+
* and writes it to the output directory with a generated file header.
|
|
41
42
|
*/
|
|
42
43
|
const fs = __importStar(require("fs"));
|
|
43
44
|
const path = __importStar(require("path"));
|
|
44
45
|
const utils_1 = require("./utils");
|
|
45
|
-
/**
|
|
46
|
-
* Find a template file path.
|
|
47
|
-
* Templates are at ./templates/ relative to this file in both src/ and dist/.
|
|
48
|
-
*/
|
|
49
46
|
function findTemplateFile(templateName) {
|
|
50
47
|
const templatePath = path.join(__dirname, 'templates', templateName);
|
|
51
48
|
if (fs.existsSync(templatePath)) {
|
|
52
49
|
return templatePath;
|
|
53
50
|
}
|
|
54
|
-
throw new Error(`Could not find template file: ${templateName}. `
|
|
55
|
-
`Searched in: ${templatePath}`);
|
|
51
|
+
throw new Error(`Could not find template file: ${templateName}. Searched in: ${templatePath}`);
|
|
56
52
|
}
|
|
57
|
-
/**
|
|
58
|
-
* Read a template file and replace the header with generated file header
|
|
59
|
-
*/
|
|
60
53
|
function readTemplateFile(templateName, description) {
|
|
61
54
|
const templatePath = findTemplateFile(templateName);
|
|
62
55
|
let content = fs.readFileSync(templatePath, 'utf-8');
|
|
63
|
-
// Replace the source file header comment with the generated file header
|
|
64
|
-
// Match the header pattern used in template files
|
|
65
56
|
const headerPattern = /\/\*\*[\s\S]*?\* NOTE: This file is read at codegen time and written to output\.[\s\S]*?\*\/\n*/;
|
|
66
57
|
content = content.replace(headerPattern, (0, utils_1.getGeneratedFileHeader)(description) + '\n');
|
|
67
58
|
return content;
|
|
68
59
|
}
|
|
69
60
|
/**
|
|
70
|
-
* Generate client.ts content
|
|
71
|
-
* @param options - Generation options
|
|
61
|
+
* Generate client.ts content - ORM client wrapper with configure/getClient
|
|
72
62
|
*/
|
|
73
|
-
function generateClientFile(
|
|
74
|
-
|
|
75
|
-
const templateName = browserCompatible
|
|
76
|
-
? 'client.browser.ts'
|
|
77
|
-
: 'client.node.ts';
|
|
78
|
-
return readTemplateFile(templateName, 'GraphQL client configuration and execution');
|
|
63
|
+
function generateClientFile() {
|
|
64
|
+
return readTemplateFile('hooks-client.ts', 'ORM client wrapper for React Query hooks');
|
|
79
65
|
}
|
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Custom mutation hook generators for non-table operations
|
|
3
|
-
*
|
|
4
|
-
* Generates hooks for operations discovered via schema introspection
|
|
5
|
-
* that are NOT table CRUD operations (e.g., login, register, etc.)
|
|
6
|
-
*
|
|
7
|
-
* Output structure:
|
|
8
|
-
* mutations/
|
|
9
|
-
* useLoginMutation.ts
|
|
10
|
-
* useRegisterMutation.ts
|
|
11
|
-
* ...
|
|
12
|
-
*/
|
|
13
1
|
import type { CleanOperation, TypeRegistry } from '../../types/schema';
|
|
14
2
|
export interface GeneratedCustomMutationFile {
|
|
15
3
|
fileName: string;
|
|
@@ -19,7 +7,6 @@ export interface GeneratedCustomMutationFile {
|
|
|
19
7
|
export interface GenerateCustomMutationHookOptions {
|
|
20
8
|
operation: CleanOperation;
|
|
21
9
|
typeRegistry: TypeRegistry;
|
|
22
|
-
maxDepth?: number;
|
|
23
10
|
skipQueryField?: boolean;
|
|
24
11
|
reactQueryEnabled?: boolean;
|
|
25
12
|
tableTypeNames?: Set<string>;
|
|
@@ -29,7 +16,6 @@ export declare function generateCustomMutationHook(options: GenerateCustomMutati
|
|
|
29
16
|
export interface GenerateAllCustomMutationHooksOptions {
|
|
30
17
|
operations: CleanOperation[];
|
|
31
18
|
typeRegistry: TypeRegistry;
|
|
32
|
-
maxDepth?: number;
|
|
33
19
|
skipQueryField?: boolean;
|
|
34
20
|
reactQueryEnabled?: boolean;
|
|
35
21
|
tableTypeNames?: Set<string>;
|
|
@@ -35,19 +35,26 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.generateCustomMutationHook = generateCustomMutationHook;
|
|
37
37
|
exports.generateAllCustomMutationHooks = generateAllCustomMutationHooks;
|
|
38
|
+
/**
|
|
39
|
+
* Custom mutation hook generators for non-table operations (Babel AST-based)
|
|
40
|
+
*
|
|
41
|
+
* Generates hooks for operations discovered via schema introspection
|
|
42
|
+
* that are NOT table CRUD operations (e.g., login, register, etc.)
|
|
43
|
+
*
|
|
44
|
+
* Delegates to ORM custom mutation operations:
|
|
45
|
+
* getClient().mutation.operationName(args, { select }).unwrap()
|
|
46
|
+
*
|
|
47
|
+
* Output structure:
|
|
48
|
+
* mutations/
|
|
49
|
+
* useLoginMutation.ts
|
|
50
|
+
* useRegisterMutation.ts
|
|
51
|
+
* ...
|
|
52
|
+
*/
|
|
38
53
|
const t = __importStar(require("@babel/types"));
|
|
39
|
-
const
|
|
40
|
-
const
|
|
54
|
+
const hooks_ast_1 = require("./hooks-ast");
|
|
55
|
+
const select_helpers_1 = require("./select-helpers");
|
|
41
56
|
const type_resolver_1 = require("./type-resolver");
|
|
42
57
|
const utils_1 = require("./utils");
|
|
43
|
-
function generateVariablesProperties(args, tracker) {
|
|
44
|
-
return args.map((arg) => ({
|
|
45
|
-
name: arg.name,
|
|
46
|
-
type: (0, type_resolver_1.typeRefToTsType)(arg.type, tracker),
|
|
47
|
-
optional: !(0, type_resolver_1.isTypeRequired)(arg.type),
|
|
48
|
-
docs: arg.description ? [arg.description] : undefined,
|
|
49
|
-
}));
|
|
50
|
-
}
|
|
51
58
|
function generateCustomMutationHook(options) {
|
|
52
59
|
const { operation, reactQueryEnabled = true } = options;
|
|
53
60
|
if (!reactQueryEnabled) {
|
|
@@ -63,95 +70,140 @@ function generateCustomMutationHook(options) {
|
|
|
63
70
|
}
|
|
64
71
|
}
|
|
65
72
|
function generateCustomMutationHookInternal(options) {
|
|
66
|
-
const { operation, typeRegistry,
|
|
73
|
+
const { operation, typeRegistry, tableTypeNames, useCentralizedKeys = true, } = options;
|
|
67
74
|
const hookName = (0, type_resolver_1.getOperationHookName)(operation.name, 'mutation');
|
|
68
75
|
const fileName = (0, type_resolver_1.getOperationFileName)(operation.name, 'mutation');
|
|
69
|
-
const
|
|
70
|
-
const resultTypeName = (0, type_resolver_1.getOperationResultTypeName)(operation.name, 'mutation');
|
|
71
|
-
const documentConstName = (0, type_resolver_1.getDocumentConstName)(operation.name, 'mutation');
|
|
76
|
+
const varTypeName = `${(0, utils_1.ucFirst)(operation.name)}Variables`;
|
|
72
77
|
const tracker = (0, type_resolver_1.createTypeTracker)({ tableTypeNames });
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
78
|
+
const hasArgs = operation.args.length > 0;
|
|
79
|
+
(0, type_resolver_1.typeRefToTsType)(operation.returnType, tracker);
|
|
80
|
+
for (const arg of operation.args) {
|
|
81
|
+
(0, type_resolver_1.typeRefToTsType)(arg.type, tracker);
|
|
82
|
+
}
|
|
83
|
+
const selectTypeName = (0, select_helpers_1.getSelectTypeName)(operation.returnType);
|
|
84
|
+
const payloadTypeName = (0, type_resolver_1.getTypeBaseName)(operation.returnType);
|
|
85
|
+
const hasSelect = !!selectTypeName && !!payloadTypeName;
|
|
79
86
|
const statements = [];
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const reactQueryTypeImport = t.importDeclaration([t.importSpecifier(t.identifier('UseMutationOptions'), t.identifier('UseMutationOptions'))], t.stringLiteral('@tanstack/react-query'));
|
|
89
|
-
reactQueryTypeImport.importKind = 'type';
|
|
90
|
-
statements.push(reactQueryTypeImport);
|
|
91
|
-
const clientImport = t.importDeclaration([t.importSpecifier(t.identifier('execute'), t.identifier('execute'))], t.stringLiteral('../client'));
|
|
92
|
-
statements.push(clientImport);
|
|
93
|
-
if (tableTypes.length > 0) {
|
|
94
|
-
const typesImport = t.importDeclaration(tableTypes.map((tt) => t.importSpecifier(t.identifier(tt), t.identifier(tt))), t.stringLiteral('../types'));
|
|
95
|
-
typesImport.importKind = 'type';
|
|
96
|
-
statements.push(typesImport);
|
|
87
|
+
// Imports
|
|
88
|
+
statements.push((0, hooks_ast_1.createImportDeclaration)('@tanstack/react-query', ['useMutation']));
|
|
89
|
+
statements.push((0, hooks_ast_1.createImportDeclaration)('@tanstack/react-query', ['UseMutationOptions', 'UseMutationResult'], true));
|
|
90
|
+
statements.push((0, hooks_ast_1.createImportDeclaration)('../client', ['getClient']));
|
|
91
|
+
statements.push((0, hooks_ast_1.createImportDeclaration)('../selection', ['buildSelectionArgs']));
|
|
92
|
+
statements.push((0, hooks_ast_1.createImportDeclaration)('../selection', ['SelectionConfig'], true));
|
|
93
|
+
if (useCentralizedKeys) {
|
|
94
|
+
statements.push((0, hooks_ast_1.createImportDeclaration)('../mutation-keys', ['customMutationKeys']));
|
|
97
95
|
}
|
|
98
|
-
if (
|
|
99
|
-
|
|
100
|
-
schemaTypesImport.importKind = 'type';
|
|
101
|
-
statements.push(schemaTypesImport);
|
|
96
|
+
if (hasArgs) {
|
|
97
|
+
statements.push((0, hooks_ast_1.createImportDeclaration)('../../orm/mutation', [varTypeName], true));
|
|
102
98
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
99
|
+
const inputTypeImports = [];
|
|
100
|
+
if (hasSelect) {
|
|
101
|
+
inputTypeImports.push(selectTypeName);
|
|
102
|
+
inputTypeImports.push(payloadTypeName);
|
|
106
103
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
if (operation.args.length > 0) {
|
|
114
|
-
const variablesInterfaceProps = variablesProps.map((vp) => {
|
|
115
|
-
const prop = t.tsPropertySignature(t.identifier(vp.name), t.tsTypeAnnotation(t.tsTypeReference(t.identifier(vp.type))));
|
|
116
|
-
prop.optional = vp.optional;
|
|
117
|
-
return prop;
|
|
118
|
-
});
|
|
119
|
-
const variablesInterface = t.tsInterfaceDeclaration(t.identifier(variablesTypeName), null, null, t.tsInterfaceBody(variablesInterfaceProps));
|
|
120
|
-
statements.push(t.exportNamedDeclaration(variablesInterface));
|
|
104
|
+
else {
|
|
105
|
+
for (const refType of tracker.referencedTypes) {
|
|
106
|
+
if (!inputTypeImports.includes(refType)) {
|
|
107
|
+
inputTypeImports.push(refType);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
121
110
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
]);
|
|
125
|
-
const resultInterface = t.tsInterfaceDeclaration(t.identifier(resultTypeName), null, null, resultInterfaceBody);
|
|
126
|
-
statements.push(t.exportNamedDeclaration(resultInterface));
|
|
127
|
-
const hasArgs = operation.args.length > 0;
|
|
128
|
-
const hookBodyStatements = [];
|
|
129
|
-
const mutationOptions = [];
|
|
130
|
-
if (useCentralizedKeys) {
|
|
131
|
-
mutationOptions.push(t.objectProperty(t.identifier('mutationKey'), t.callExpression(t.memberExpression(t.identifier('customMutationKeys'), t.identifier(operation.name)), [])));
|
|
111
|
+
if (inputTypeImports.length > 0) {
|
|
112
|
+
statements.push((0, hooks_ast_1.createImportDeclaration)('../../orm/input-types', inputTypeImports, true));
|
|
132
113
|
}
|
|
114
|
+
if (hasSelect) {
|
|
115
|
+
statements.push((0, hooks_ast_1.createImportDeclaration)('../../orm/select-types', ['InferSelectResult', 'StrictSelect'], true));
|
|
116
|
+
}
|
|
117
|
+
// Re-exports
|
|
133
118
|
if (hasArgs) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
]))
|
|
119
|
+
statements.push((0, hooks_ast_1.createTypeReExport)([varTypeName], '../../orm/mutation'));
|
|
120
|
+
}
|
|
121
|
+
if (hasSelect) {
|
|
122
|
+
statements.push((0, hooks_ast_1.createTypeReExport)([selectTypeName], '../../orm/input-types'));
|
|
123
|
+
}
|
|
124
|
+
// Hook
|
|
125
|
+
if (hasSelect) {
|
|
126
|
+
const mutationVarType = hasArgs
|
|
127
|
+
? (0, hooks_ast_1.typeRef)(varTypeName)
|
|
128
|
+
: t.tsVoidKeyword();
|
|
129
|
+
const selectedResultType = (sel) => (0, hooks_ast_1.customSelectResultTypeLiteral)(operation.name, operation.returnType, payloadTypeName, sel);
|
|
130
|
+
// Overload 1: with selection.fields
|
|
131
|
+
const o1ParamType = t.tsIntersectionType([
|
|
132
|
+
t.tsTypeLiteral([
|
|
133
|
+
t.tsPropertySignature(t.identifier('selection'), t.tsTypeAnnotation(t.tsParenthesizedType(t.tsIntersectionType([
|
|
134
|
+
t.tsTypeLiteral([
|
|
135
|
+
t.tsPropertySignature(t.identifier('fields'), t.tsTypeAnnotation((0, hooks_ast_1.sRef)())),
|
|
136
|
+
]),
|
|
137
|
+
(0, hooks_ast_1.typeRef)('StrictSelect', [(0, hooks_ast_1.sRef)(), (0, hooks_ast_1.typeRef)(selectTypeName)]),
|
|
138
|
+
])))),
|
|
139
|
+
]),
|
|
140
|
+
(0, hooks_ast_1.useMutationOptionsType)(selectedResultType((0, hooks_ast_1.sRef)()), mutationVarType),
|
|
141
|
+
]);
|
|
142
|
+
statements.push((0, hooks_ast_1.exportDeclareFunction)(hookName, (0, hooks_ast_1.createSTypeParam)(selectTypeName), [(0, hooks_ast_1.createFunctionParam)('params', o1ParamType)], (0, hooks_ast_1.useMutationResultType)(selectedResultType((0, hooks_ast_1.sRef)()), mutationVarType)));
|
|
143
|
+
// Implementation
|
|
144
|
+
const implSelProp = t.tsPropertySignature(t.identifier('selection'), t.tsTypeAnnotation((0, hooks_ast_1.selectionConfigType)((0, hooks_ast_1.typeRef)(selectTypeName))));
|
|
145
|
+
const implParamType = t.tsIntersectionType([
|
|
146
|
+
t.tsTypeLiteral([implSelProp]),
|
|
147
|
+
(0, hooks_ast_1.omitType)((0, hooks_ast_1.typeRef)('UseMutationOptions', [
|
|
148
|
+
t.tsAnyKeyword(),
|
|
149
|
+
(0, hooks_ast_1.typeRef)('Error'),
|
|
150
|
+
mutationVarType,
|
|
151
|
+
]), ['mutationFn']),
|
|
152
|
+
]);
|
|
153
|
+
const body = [];
|
|
154
|
+
body.push((0, hooks_ast_1.buildSelectionArgsCall)(selectTypeName));
|
|
155
|
+
body.push((0, hooks_ast_1.destructureParamsWithSelection)('mutationOptions'));
|
|
156
|
+
body.push((0, hooks_ast_1.voidStatement)('_selection'));
|
|
157
|
+
const mutationKeyExpr = useCentralizedKeys
|
|
158
|
+
? (0, hooks_ast_1.callExpr)(t.memberExpression(t.identifier('customMutationKeys'), t.identifier(operation.name)), [])
|
|
159
|
+
: undefined;
|
|
160
|
+
const selectArgExpr = t.objectExpression([
|
|
161
|
+
(0, hooks_ast_1.objectProp)('select', t.memberExpression(t.identifier('args'), t.identifier('select'))),
|
|
162
|
+
]);
|
|
163
|
+
let mutationFnExpr;
|
|
164
|
+
if (hasArgs) {
|
|
165
|
+
const variablesParam = (0, hooks_ast_1.createFunctionParam)('variables', (0, hooks_ast_1.typeRef)(varTypeName));
|
|
166
|
+
mutationFnExpr = t.arrowFunctionExpression([variablesParam], (0, hooks_ast_1.getClientCustomCallUnwrap)('mutation', operation.name, [t.identifier('variables')], selectArgExpr));
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
mutationFnExpr = t.arrowFunctionExpression([], (0, hooks_ast_1.getClientCustomCallUnwrap)('mutation', operation.name, [], selectArgExpr));
|
|
170
|
+
}
|
|
171
|
+
body.push((0, hooks_ast_1.returnUseMutation)(mutationFnExpr, [(0, hooks_ast_1.spreadObj)(t.identifier('mutationOptions'))], mutationKeyExpr));
|
|
172
|
+
statements.push((0, hooks_ast_1.exportFunction)(hookName, null, [(0, hooks_ast_1.createFunctionParam)('params', implParamType)], body));
|
|
138
173
|
}
|
|
139
174
|
else {
|
|
140
|
-
|
|
175
|
+
// Without select: simple hook (scalar return type)
|
|
176
|
+
const resultTypeStr = (0, type_resolver_1.typeRefToTsType)(operation.returnType, tracker);
|
|
177
|
+
const resultTypeLiteral = t.tsTypeLiteral([
|
|
178
|
+
t.tsPropertySignature(t.identifier(operation.name), t.tsTypeAnnotation((0, hooks_ast_1.typeRef)(resultTypeStr))),
|
|
179
|
+
]);
|
|
180
|
+
const mutationVarType = hasArgs
|
|
181
|
+
? (0, hooks_ast_1.typeRef)(varTypeName)
|
|
182
|
+
: t.tsVoidKeyword();
|
|
183
|
+
const optionsType = (0, hooks_ast_1.omitType)((0, hooks_ast_1.typeRef)('UseMutationOptions', [
|
|
184
|
+
resultTypeLiteral,
|
|
185
|
+
(0, hooks_ast_1.typeRef)('Error'),
|
|
186
|
+
mutationVarType,
|
|
187
|
+
]), ['mutationFn']);
|
|
188
|
+
const body = [];
|
|
189
|
+
body.push((0, hooks_ast_1.constDecl)('mutationOptions', t.logicalExpression('??', t.identifier('params'), t.objectExpression([]))));
|
|
190
|
+
const mutationKeyExpr = useCentralizedKeys
|
|
191
|
+
? (0, hooks_ast_1.callExpr)(t.memberExpression(t.identifier('customMutationKeys'), t.identifier(operation.name)), [])
|
|
192
|
+
: undefined;
|
|
193
|
+
let mutationFnExpr;
|
|
194
|
+
if (hasArgs) {
|
|
195
|
+
const variablesParam = (0, hooks_ast_1.createFunctionParam)('variables', (0, hooks_ast_1.typeRef)(varTypeName));
|
|
196
|
+
mutationFnExpr = t.arrowFunctionExpression([variablesParam], (0, hooks_ast_1.getClientCustomCallUnwrap)('mutation', operation.name, [
|
|
197
|
+
t.identifier('variables'),
|
|
198
|
+
]));
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
mutationFnExpr = t.arrowFunctionExpression([], (0, hooks_ast_1.getClientCustomCallUnwrap)('mutation', operation.name, []));
|
|
202
|
+
}
|
|
203
|
+
body.push((0, hooks_ast_1.returnUseMutation)(mutationFnExpr, [(0, hooks_ast_1.spreadObj)(t.identifier('mutationOptions'))], mutationKeyExpr));
|
|
204
|
+
statements.push((0, hooks_ast_1.exportFunction)(hookName, null, [(0, hooks_ast_1.createFunctionParam)('params', optionsType, true)], body));
|
|
141
205
|
}
|
|
142
|
-
|
|
143
|
-
hookBodyStatements.push(t.returnStatement(t.callExpression(t.identifier('useMutation'), [t.objectExpression(mutationOptions)])));
|
|
144
|
-
const optionsType = hasArgs
|
|
145
|
-
? `Omit<UseMutationOptions<${resultTypeName}, Error, ${variablesTypeName}>, 'mutationFn'>`
|
|
146
|
-
: `Omit<UseMutationOptions<${resultTypeName}, Error, void>, 'mutationFn'>`;
|
|
147
|
-
const optionsParam = t.identifier('options');
|
|
148
|
-
optionsParam.optional = true;
|
|
149
|
-
optionsParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier(optionsType)));
|
|
150
|
-
const hookFunc = t.functionDeclaration(t.identifier(hookName), [optionsParam], t.blockStatement(hookBodyStatements));
|
|
151
|
-
const hookExport = t.exportNamedDeclaration(hookFunc);
|
|
152
|
-
statements.push(hookExport);
|
|
153
|
-
const code = (0, babel_ast_1.generateCode)(statements);
|
|
154
|
-
const content = (0, utils_1.getGeneratedFileHeader)(`Custom mutation hook for ${operation.name}`) + '\n\n' + code;
|
|
206
|
+
const content = (0, hooks_ast_1.generateHookFileCode)(`Custom mutation hook for ${operation.name}`, statements);
|
|
155
207
|
return {
|
|
156
208
|
fileName,
|
|
157
209
|
content,
|
|
@@ -159,13 +211,12 @@ function generateCustomMutationHookInternal(options) {
|
|
|
159
211
|
};
|
|
160
212
|
}
|
|
161
213
|
function generateAllCustomMutationHooks(options) {
|
|
162
|
-
const { operations, typeRegistry,
|
|
214
|
+
const { operations, typeRegistry, skipQueryField = true, reactQueryEnabled = true, tableTypeNames, useCentralizedKeys = true, } = options;
|
|
163
215
|
return operations
|
|
164
216
|
.filter((op) => op.kind === 'mutation')
|
|
165
217
|
.map((operation) => generateCustomMutationHook({
|
|
166
218
|
operation,
|
|
167
219
|
typeRegistry,
|
|
168
|
-
maxDepth,
|
|
169
220
|
skipQueryField,
|
|
170
221
|
reactQueryEnabled,
|
|
171
222
|
tableTypeNames,
|
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Custom query hook generators for non-table operations
|
|
3
|
-
*
|
|
4
|
-
* Generates hooks for operations discovered via schema introspection
|
|
5
|
-
* that are NOT table CRUD operations (e.g., currentUser, nodeById, etc.)
|
|
6
|
-
*
|
|
7
|
-
* Output structure:
|
|
8
|
-
* queries/
|
|
9
|
-
* useCurrentUserQuery.ts
|
|
10
|
-
* useNodeQuery.ts
|
|
11
|
-
* ...
|
|
12
|
-
*/
|
|
13
1
|
import type { CleanOperation, TypeRegistry } from '../../types/schema';
|
|
14
2
|
export interface GeneratedCustomQueryFile {
|
|
15
3
|
fileName: string;
|
|
@@ -19,7 +7,6 @@ export interface GeneratedCustomQueryFile {
|
|
|
19
7
|
export interface GenerateCustomQueryHookOptions {
|
|
20
8
|
operation: CleanOperation;
|
|
21
9
|
typeRegistry: TypeRegistry;
|
|
22
|
-
maxDepth?: number;
|
|
23
10
|
skipQueryField?: boolean;
|
|
24
11
|
reactQueryEnabled?: boolean;
|
|
25
12
|
tableTypeNames?: Set<string>;
|
|
@@ -29,7 +16,6 @@ export declare function generateCustomQueryHook(options: GenerateCustomQueryHook
|
|
|
29
16
|
export interface GenerateAllCustomQueryHooksOptions {
|
|
30
17
|
operations: CleanOperation[];
|
|
31
18
|
typeRegistry: TypeRegistry;
|
|
32
|
-
maxDepth?: number;
|
|
33
19
|
skipQueryField?: boolean;
|
|
34
20
|
reactQueryEnabled?: boolean;
|
|
35
21
|
tableTypeNames?: Set<string>;
|