@constructive-io/graphql-codegen 2.23.3 → 2.24.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.
- package/README.md +147 -2
- package/cli/codegen/babel-ast.d.ts +53 -0
- package/cli/codegen/babel-ast.js +160 -0
- package/cli/codegen/barrel.d.ts +7 -2
- package/cli/codegen/barrel.js +193 -102
- package/cli/codegen/client.js +61 -0
- package/cli/codegen/custom-mutations.d.ts +2 -12
- package/cli/codegen/custom-mutations.js +116 -124
- package/cli/codegen/custom-queries.d.ts +2 -10
- package/cli/codegen/custom-queries.js +236 -335
- package/cli/codegen/gql-ast.js +22 -1
- package/cli/codegen/index.d.ts +3 -0
- package/cli/codegen/index.js +73 -3
- package/cli/codegen/invalidation.d.ts +20 -0
- package/cli/codegen/invalidation.js +327 -0
- package/cli/codegen/mutation-keys.d.ts +24 -0
- package/cli/codegen/mutation-keys.js +247 -0
- package/cli/codegen/mutations.d.ts +5 -19
- package/cli/codegen/mutations.js +385 -383
- package/cli/codegen/orm/barrel.d.ts +1 -1
- package/cli/codegen/orm/barrel.js +42 -10
- package/cli/codegen/orm/client-generator.d.ts +1 -19
- package/cli/codegen/orm/client-generator.js +108 -77
- package/cli/codegen/orm/custom-ops-generator.d.ts +1 -12
- package/cli/codegen/orm/custom-ops-generator.js +192 -235
- package/cli/codegen/orm/input-types-generator.d.ts +13 -1
- package/cli/codegen/orm/input-types-generator.js +425 -147
- package/cli/codegen/orm/model-generator.d.ts +1 -19
- package/cli/codegen/orm/model-generator.js +229 -234
- package/cli/codegen/queries.d.ts +4 -12
- package/cli/codegen/queries.js +660 -390
- package/cli/codegen/query-keys.d.ts +15 -0
- package/cli/codegen/query-keys.js +477 -0
- package/cli/codegen/scalars.js +1 -0
- package/cli/codegen/schema-types-generator.d.ts +15 -10
- package/cli/codegen/schema-types-generator.js +87 -175
- package/cli/codegen/type-resolver.d.ts +1 -30
- package/cli/codegen/type-resolver.js +0 -53
- package/cli/codegen/types.d.ts +1 -1
- package/cli/codegen/types.js +76 -21
- package/cli/codegen/utils.d.ts +6 -0
- package/cli/codegen/utils.js +19 -0
- package/esm/cli/codegen/babel-ast.d.ts +53 -0
- package/esm/cli/codegen/babel-ast.js +111 -0
- package/esm/cli/codegen/barrel.d.ts +7 -2
- package/esm/cli/codegen/barrel.js +161 -103
- package/esm/cli/codegen/client.js +61 -0
- package/esm/cli/codegen/custom-mutations.d.ts +2 -12
- package/esm/cli/codegen/custom-mutations.js +83 -124
- package/esm/cli/codegen/custom-queries.d.ts +2 -10
- package/esm/cli/codegen/custom-queries.js +204 -336
- package/esm/cli/codegen/gql-ast.js +23 -2
- package/esm/cli/codegen/index.d.ts +3 -0
- package/esm/cli/codegen/index.js +69 -2
- package/esm/cli/codegen/invalidation.d.ts +20 -0
- package/esm/cli/codegen/invalidation.js +291 -0
- package/esm/cli/codegen/mutation-keys.d.ts +24 -0
- package/esm/cli/codegen/mutation-keys.js +211 -0
- package/esm/cli/codegen/mutations.d.ts +5 -19
- package/esm/cli/codegen/mutations.js +353 -384
- package/esm/cli/codegen/orm/barrel.d.ts +1 -1
- package/esm/cli/codegen/orm/barrel.js +10 -11
- package/esm/cli/codegen/orm/client-generator.d.ts +1 -19
- package/esm/cli/codegen/orm/client-generator.js +76 -78
- package/esm/cli/codegen/orm/custom-ops-generator.d.ts +1 -12
- package/esm/cli/codegen/orm/custom-ops-generator.js +160 -236
- package/esm/cli/codegen/orm/input-types-generator.d.ts +13 -1
- package/esm/cli/codegen/orm/input-types-generator.js +393 -148
- package/esm/cli/codegen/orm/model-generator.d.ts +1 -19
- package/esm/cli/codegen/orm/model-generator.js +197 -235
- package/esm/cli/codegen/queries.d.ts +4 -12
- package/esm/cli/codegen/queries.js +628 -391
- package/esm/cli/codegen/query-keys.d.ts +15 -0
- package/esm/cli/codegen/query-keys.js +441 -0
- package/esm/cli/codegen/scalars.js +1 -0
- package/esm/cli/codegen/schema-types-generator.d.ts +15 -10
- package/esm/cli/codegen/schema-types-generator.js +54 -175
- package/esm/cli/codegen/type-resolver.d.ts +1 -30
- package/esm/cli/codegen/type-resolver.js +0 -49
- package/esm/cli/codegen/types.d.ts +1 -1
- package/esm/cli/codegen/types.js +44 -22
- package/esm/cli/codegen/utils.d.ts +6 -0
- package/esm/cli/codegen/utils.js +18 -0
- package/esm/types/config.d.ts +75 -0
- package/esm/types/config.js +18 -0
- package/package.json +6 -4
- package/types/config.d.ts +75 -0
- package/types/config.js +19 -1
- package/cli/codegen/ts-ast.d.ts +0 -124
- package/cli/codegen/ts-ast.js +0 -280
- package/esm/cli/codegen/ts-ast.d.ts +0 -124
- package/esm/cli/codegen/ts-ast.js +0 -260
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { getTableNames, getGeneratedFileHeader, lcFirst } from './utils';
|
|
2
|
+
import * as t from '@babel/types';
|
|
3
|
+
import { generateCode, addJSDocComment, asConst, constArray, typedParam, } from './babel-ast';
|
|
4
|
+
/**
|
|
5
|
+
* Generate mutation keys declaration for a single table entity
|
|
6
|
+
*/
|
|
7
|
+
function generateEntityMutationKeysDeclaration(table, relationships) {
|
|
8
|
+
const { typeName, singularName } = getTableNames(table);
|
|
9
|
+
const entityKey = typeName.toLowerCase();
|
|
10
|
+
const keysName = `${lcFirst(typeName)}MutationKeys`;
|
|
11
|
+
const relationship = relationships[entityKey];
|
|
12
|
+
const properties = [];
|
|
13
|
+
// all property
|
|
14
|
+
const allProp = t.objectProperty(t.identifier('all'), constArray([t.stringLiteral('mutation'), t.stringLiteral(entityKey)]));
|
|
15
|
+
addJSDocComment(allProp, [`All ${singularName} mutation keys`]);
|
|
16
|
+
properties.push(allProp);
|
|
17
|
+
// create property
|
|
18
|
+
let createProp;
|
|
19
|
+
if (relationship) {
|
|
20
|
+
const fkParam = t.identifier(relationship.foreignKey);
|
|
21
|
+
fkParam.optional = true;
|
|
22
|
+
fkParam.typeAnnotation = t.tsTypeAnnotation(t.tsStringKeyword());
|
|
23
|
+
const arrowFn = t.arrowFunctionExpression([fkParam], t.conditionalExpression(t.identifier(relationship.foreignKey), constArray([
|
|
24
|
+
t.stringLiteral('mutation'),
|
|
25
|
+
t.stringLiteral(entityKey),
|
|
26
|
+
t.stringLiteral('create'),
|
|
27
|
+
t.objectExpression([
|
|
28
|
+
t.objectProperty(t.identifier(relationship.foreignKey), t.identifier(relationship.foreignKey), false, true)
|
|
29
|
+
]),
|
|
30
|
+
]), constArray([
|
|
31
|
+
t.stringLiteral('mutation'),
|
|
32
|
+
t.stringLiteral(entityKey),
|
|
33
|
+
t.stringLiteral('create'),
|
|
34
|
+
])));
|
|
35
|
+
createProp = t.objectProperty(t.identifier('create'), arrowFn);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
const arrowFn = t.arrowFunctionExpression([], constArray([
|
|
39
|
+
t.stringLiteral('mutation'),
|
|
40
|
+
t.stringLiteral(entityKey),
|
|
41
|
+
t.stringLiteral('create'),
|
|
42
|
+
]));
|
|
43
|
+
createProp = t.objectProperty(t.identifier('create'), arrowFn);
|
|
44
|
+
}
|
|
45
|
+
addJSDocComment(createProp, [`Create ${singularName} mutation key`]);
|
|
46
|
+
properties.push(createProp);
|
|
47
|
+
// update property
|
|
48
|
+
const updateArrowFn = t.arrowFunctionExpression([typedParam('id', t.tsUnionType([t.tsStringKeyword(), t.tsNumberKeyword()]))], constArray([
|
|
49
|
+
t.stringLiteral('mutation'),
|
|
50
|
+
t.stringLiteral(entityKey),
|
|
51
|
+
t.stringLiteral('update'),
|
|
52
|
+
t.identifier('id'),
|
|
53
|
+
]));
|
|
54
|
+
const updateProp = t.objectProperty(t.identifier('update'), updateArrowFn);
|
|
55
|
+
addJSDocComment(updateProp, [`Update ${singularName} mutation key`]);
|
|
56
|
+
properties.push(updateProp);
|
|
57
|
+
// delete property
|
|
58
|
+
const deleteArrowFn = t.arrowFunctionExpression([typedParam('id', t.tsUnionType([t.tsStringKeyword(), t.tsNumberKeyword()]))], constArray([
|
|
59
|
+
t.stringLiteral('mutation'),
|
|
60
|
+
t.stringLiteral(entityKey),
|
|
61
|
+
t.stringLiteral('delete'),
|
|
62
|
+
t.identifier('id'),
|
|
63
|
+
]));
|
|
64
|
+
const deleteProp = t.objectProperty(t.identifier('delete'), deleteArrowFn);
|
|
65
|
+
addJSDocComment(deleteProp, [`Delete ${singularName} mutation key`]);
|
|
66
|
+
properties.push(deleteProp);
|
|
67
|
+
return t.exportNamedDeclaration(t.variableDeclaration('const', [
|
|
68
|
+
t.variableDeclarator(t.identifier(keysName), asConst(t.objectExpression(properties)))
|
|
69
|
+
]));
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Generate custom mutation keys declaration
|
|
73
|
+
*/
|
|
74
|
+
function generateCustomMutationKeysDeclaration(operations) {
|
|
75
|
+
if (operations.length === 0)
|
|
76
|
+
return null;
|
|
77
|
+
const properties = [];
|
|
78
|
+
for (const op of operations) {
|
|
79
|
+
const hasArgs = op.args.length > 0;
|
|
80
|
+
let prop;
|
|
81
|
+
if (hasArgs) {
|
|
82
|
+
const identifierParam = t.identifier('identifier');
|
|
83
|
+
identifierParam.optional = true;
|
|
84
|
+
identifierParam.typeAnnotation = t.tsTypeAnnotation(t.tsStringKeyword());
|
|
85
|
+
const arrowFn = t.arrowFunctionExpression([identifierParam], t.conditionalExpression(t.identifier('identifier'), constArray([
|
|
86
|
+
t.stringLiteral('mutation'),
|
|
87
|
+
t.stringLiteral(op.name),
|
|
88
|
+
t.identifier('identifier'),
|
|
89
|
+
]), constArray([t.stringLiteral('mutation'), t.stringLiteral(op.name)])));
|
|
90
|
+
prop = t.objectProperty(t.identifier(op.name), arrowFn);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
const arrowFn = t.arrowFunctionExpression([], constArray([t.stringLiteral('mutation'), t.stringLiteral(op.name)]));
|
|
94
|
+
prop = t.objectProperty(t.identifier(op.name), arrowFn);
|
|
95
|
+
}
|
|
96
|
+
addJSDocComment(prop, [`Mutation key for ${op.name}`]);
|
|
97
|
+
properties.push(prop);
|
|
98
|
+
}
|
|
99
|
+
return t.exportNamedDeclaration(t.variableDeclaration('const', [
|
|
100
|
+
t.variableDeclarator(t.identifier('customMutationKeys'), asConst(t.objectExpression(properties)))
|
|
101
|
+
]));
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Generate the unified mutation keys store declaration
|
|
105
|
+
*/
|
|
106
|
+
function generateUnifiedMutationStoreDeclaration(tables, hasCustomMutations) {
|
|
107
|
+
const properties = [];
|
|
108
|
+
for (const table of tables) {
|
|
109
|
+
const { typeName } = getTableNames(table);
|
|
110
|
+
const keysName = `${lcFirst(typeName)}MutationKeys`;
|
|
111
|
+
properties.push(t.objectProperty(t.identifier(lcFirst(typeName)), t.identifier(keysName)));
|
|
112
|
+
}
|
|
113
|
+
if (hasCustomMutations) {
|
|
114
|
+
properties.push(t.objectProperty(t.identifier('custom'), t.identifier('customMutationKeys')));
|
|
115
|
+
}
|
|
116
|
+
const decl = t.exportNamedDeclaration(t.variableDeclaration('const', [
|
|
117
|
+
t.variableDeclarator(t.identifier('mutationKeys'), asConst(t.objectExpression(properties)))
|
|
118
|
+
]));
|
|
119
|
+
addJSDocComment(decl, [
|
|
120
|
+
'Unified mutation key store',
|
|
121
|
+
'',
|
|
122
|
+
'Use this for tracking in-flight mutations with useIsMutating.',
|
|
123
|
+
'',
|
|
124
|
+
'@example',
|
|
125
|
+
'```ts',
|
|
126
|
+
"import { useIsMutating } from '@tanstack/react-query';",
|
|
127
|
+
"import { mutationKeys } from './generated';",
|
|
128
|
+
'',
|
|
129
|
+
'// Check if any user mutations are in progress',
|
|
130
|
+
'const isMutatingUser = useIsMutating({ mutationKey: mutationKeys.user.all });',
|
|
131
|
+
'',
|
|
132
|
+
'// Check if a specific user is being updated',
|
|
133
|
+
'const isUpdating = useIsMutating({ mutationKey: mutationKeys.user.update(userId) });',
|
|
134
|
+
'```',
|
|
135
|
+
]);
|
|
136
|
+
return decl;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Generate the complete mutation-keys.ts file
|
|
140
|
+
*/
|
|
141
|
+
export function generateMutationKeysFile(options) {
|
|
142
|
+
const { tables, customMutations, config } = options;
|
|
143
|
+
const { relationships } = config;
|
|
144
|
+
const statements = [];
|
|
145
|
+
// Generate entity mutation keys
|
|
146
|
+
for (const table of tables) {
|
|
147
|
+
statements.push(generateEntityMutationKeysDeclaration(table, relationships));
|
|
148
|
+
}
|
|
149
|
+
// Generate custom mutation keys
|
|
150
|
+
const mutationOperations = customMutations.filter((op) => op.kind === 'mutation');
|
|
151
|
+
const customKeysDecl = generateCustomMutationKeysDeclaration(mutationOperations);
|
|
152
|
+
if (customKeysDecl) {
|
|
153
|
+
statements.push(customKeysDecl);
|
|
154
|
+
}
|
|
155
|
+
// Generate unified store
|
|
156
|
+
statements.push(generateUnifiedMutationStoreDeclaration(tables, mutationOperations.length > 0));
|
|
157
|
+
// Generate code from AST
|
|
158
|
+
const code = generateCode(statements);
|
|
159
|
+
// Build final content with header and section comments
|
|
160
|
+
const header = getGeneratedFileHeader('Centralized mutation key factory');
|
|
161
|
+
const description = `// ============================================================================
|
|
162
|
+
// Mutation keys for tracking in-flight mutations
|
|
163
|
+
//
|
|
164
|
+
// Benefits:
|
|
165
|
+
// - Track mutation state with useIsMutating
|
|
166
|
+
// - Implement optimistic updates with proper rollback
|
|
167
|
+
// - Deduplicate identical mutations
|
|
168
|
+
// - Coordinate related mutations
|
|
169
|
+
// ============================================================================`;
|
|
170
|
+
let content = `${header}
|
|
171
|
+
|
|
172
|
+
${description}
|
|
173
|
+
|
|
174
|
+
// ============================================================================
|
|
175
|
+
// Entity Mutation Keys
|
|
176
|
+
// ============================================================================
|
|
177
|
+
|
|
178
|
+
`;
|
|
179
|
+
// Insert section comments into the generated code
|
|
180
|
+
const codeLines = code.split('\n');
|
|
181
|
+
let addedCustomSection = false;
|
|
182
|
+
let addedUnifiedSection = false;
|
|
183
|
+
for (let i = 0; i < codeLines.length; i++) {
|
|
184
|
+
const line = codeLines[i];
|
|
185
|
+
// Detect custom mutation keys section
|
|
186
|
+
if (!addedCustomSection && line.startsWith('export const customMutationKeys')) {
|
|
187
|
+
content += `
|
|
188
|
+
// ============================================================================
|
|
189
|
+
// Custom Mutation Keys
|
|
190
|
+
// ============================================================================
|
|
191
|
+
|
|
192
|
+
`;
|
|
193
|
+
addedCustomSection = true;
|
|
194
|
+
}
|
|
195
|
+
// Detect unified store section
|
|
196
|
+
if (!addedUnifiedSection && line.includes('* Unified mutation key store')) {
|
|
197
|
+
content += `
|
|
198
|
+
// ============================================================================
|
|
199
|
+
// Unified Mutation Key Store
|
|
200
|
+
// ============================================================================
|
|
201
|
+
|
|
202
|
+
`;
|
|
203
|
+
addedUnifiedSection = true;
|
|
204
|
+
}
|
|
205
|
+
content += line + '\n';
|
|
206
|
+
}
|
|
207
|
+
return {
|
|
208
|
+
fileName: 'mutation-keys.ts',
|
|
209
|
+
content,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Mutation hook generators using AST-based code generation
|
|
2
|
+
* Mutation hook generators using Babel AST-based code generation
|
|
3
3
|
*
|
|
4
4
|
* Output structure:
|
|
5
5
|
* mutations/
|
|
@@ -13,28 +13,14 @@ export interface GeneratedMutationFile {
|
|
|
13
13
|
content: string;
|
|
14
14
|
}
|
|
15
15
|
export interface MutationGeneratorOptions {
|
|
16
|
-
/** Whether to generate React Query hooks (default: true for backwards compatibility) */
|
|
17
16
|
reactQueryEnabled?: boolean;
|
|
18
|
-
/** Enum type names that are available from schema-types.ts */
|
|
19
17
|
enumsFromSchemaTypes?: string[];
|
|
18
|
+
useCentralizedKeys?: boolean;
|
|
19
|
+
hasRelationships?: boolean;
|
|
20
|
+
/** All table type names for determining which types to import from types.ts vs schema-types.ts */
|
|
21
|
+
tableTypeNames?: Set<string>;
|
|
20
22
|
}
|
|
21
|
-
/**
|
|
22
|
-
* Generate create mutation hook file content using AST
|
|
23
|
-
* When reactQueryEnabled is false, returns null since mutations require React Query
|
|
24
|
-
*/
|
|
25
23
|
export declare function generateCreateMutationHook(table: CleanTable, options?: MutationGeneratorOptions): GeneratedMutationFile | null;
|
|
26
|
-
/**
|
|
27
|
-
* Generate update mutation hook file content using AST
|
|
28
|
-
* When reactQueryEnabled is false, returns null since mutations require React Query
|
|
29
|
-
*/
|
|
30
24
|
export declare function generateUpdateMutationHook(table: CleanTable, options?: MutationGeneratorOptions): GeneratedMutationFile | null;
|
|
31
|
-
/**
|
|
32
|
-
* Generate delete mutation hook file content using AST
|
|
33
|
-
* When reactQueryEnabled is false, returns null since mutations require React Query
|
|
34
|
-
*/
|
|
35
25
|
export declare function generateDeleteMutationHook(table: CleanTable, options?: MutationGeneratorOptions): GeneratedMutationFile | null;
|
|
36
|
-
/**
|
|
37
|
-
* Generate all mutation hook files for all tables
|
|
38
|
-
* When reactQueryEnabled is false, returns empty array since mutations require React Query
|
|
39
|
-
*/
|
|
40
26
|
export declare function generateAllMutationHooks(tables: CleanTable[], options?: MutationGeneratorOptions): GeneratedMutationFile[];
|