@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
package/cli/codegen/ts-ast.js
DELETED
|
@@ -1,280 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createProject = createProject;
|
|
4
|
-
exports.createSourceFile = createSourceFile;
|
|
5
|
-
exports.getFormattedOutput = getFormattedOutput;
|
|
6
|
-
exports.getMinimalFormattedOutput = getMinimalFormattedOutput;
|
|
7
|
-
exports.createFileHeader = createFileHeader;
|
|
8
|
-
exports.createJsDoc = createJsDoc;
|
|
9
|
-
exports.createImport = createImport;
|
|
10
|
-
exports.createInterface = createInterface;
|
|
11
|
-
exports.createFilterInterface = createFilterInterface;
|
|
12
|
-
exports.createTypeAlias = createTypeAlias;
|
|
13
|
-
exports.createUnionType = createUnionType;
|
|
14
|
-
exports.createConst = createConst;
|
|
15
|
-
exports.createTemplateLiteral = createTemplateLiteral;
|
|
16
|
-
exports.createFunction = createFunction;
|
|
17
|
-
exports.createReExport = createReExport;
|
|
18
|
-
exports.createBarrelExport = createBarrelExport;
|
|
19
|
-
exports.createSectionComment = createSectionComment;
|
|
20
|
-
exports.addSectionComment = addSectionComment;
|
|
21
|
-
/**
|
|
22
|
-
* TypeScript AST builders using ts-morph
|
|
23
|
-
*
|
|
24
|
-
* Provides utilities for generating TypeScript code via AST manipulation
|
|
25
|
-
* instead of string concatenation.
|
|
26
|
-
*/
|
|
27
|
-
const ts_morph_1 = require("ts-morph");
|
|
28
|
-
// ============================================================================
|
|
29
|
-
// Project management
|
|
30
|
-
// ============================================================================
|
|
31
|
-
/**
|
|
32
|
-
* Create a new ts-morph project for code generation
|
|
33
|
-
*/
|
|
34
|
-
function createProject() {
|
|
35
|
-
return new ts_morph_1.Project({
|
|
36
|
-
useInMemoryFileSystem: true,
|
|
37
|
-
compilerOptions: {
|
|
38
|
-
declaration: true,
|
|
39
|
-
strict: true,
|
|
40
|
-
target: ts_morph_1.ScriptTarget.ESNext,
|
|
41
|
-
module: ts_morph_1.ModuleKind.ESNext,
|
|
42
|
-
},
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Create a source file in the project
|
|
47
|
-
*/
|
|
48
|
-
function createSourceFile(project, fileName) {
|
|
49
|
-
return project.createSourceFile(fileName, '', { overwrite: true });
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Get formatted output from source file
|
|
53
|
-
*/
|
|
54
|
-
function getFormattedOutput(sourceFile) {
|
|
55
|
-
sourceFile.formatText({
|
|
56
|
-
indentSize: 2,
|
|
57
|
-
convertTabsToSpaces: true,
|
|
58
|
-
});
|
|
59
|
-
return sourceFile.getFullText();
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Get output with minimal formatting (preserves intentional blank lines)
|
|
63
|
-
* Post-processes to fix indentation and section comment spacing
|
|
64
|
-
*
|
|
65
|
-
* ts-morph generates type alias bodies with extra indentation:
|
|
66
|
-
* - Properties get 6 spaces (we want 2)
|
|
67
|
-
* - Closing brace gets 4 spaces (we want 0)
|
|
68
|
-
*
|
|
69
|
-
* For interfaces it uses 4 spaces which we convert to 2.
|
|
70
|
-
*/
|
|
71
|
-
function getMinimalFormattedOutput(sourceFile) {
|
|
72
|
-
let text = sourceFile.getFullText();
|
|
73
|
-
// Process each line to fix indentation
|
|
74
|
-
// ts-morph uses inconsistent indentation for type alias bodies
|
|
75
|
-
// We halve all indentation: 4->2, 6->3 (rounds to 2), 8->4, etc.
|
|
76
|
-
text = text.split('\n').map(line => {
|
|
77
|
-
// Match leading whitespace
|
|
78
|
-
const match = line.match(/^(\s*)/);
|
|
79
|
-
if (!match)
|
|
80
|
-
return line;
|
|
81
|
-
const spaces = match[1].length;
|
|
82
|
-
const content = line.slice(spaces);
|
|
83
|
-
// Skip empty lines
|
|
84
|
-
if (content === '')
|
|
85
|
-
return line;
|
|
86
|
-
// No indentation - keep as-is
|
|
87
|
-
if (spaces === 0)
|
|
88
|
-
return line;
|
|
89
|
-
// Halve the indentation (minimum 0)
|
|
90
|
-
const newSpaces = Math.floor(spaces / 2);
|
|
91
|
-
return ' '.repeat(newSpaces) + content;
|
|
92
|
-
}).join('\n');
|
|
93
|
-
// Ensure blank line after section comment blocks
|
|
94
|
-
text = text.replace(/(\/\/ =+\n\/\/ .+\n\/\/ =+)\n(export|\/\/)/g, '$1\n\n$2');
|
|
95
|
-
// Add blank line between consecutive export declarations (type aliases, interfaces)
|
|
96
|
-
// Pattern: "}\nexport" or ";\nexport" should become "}\n\nexport" or ";\n\nexport"
|
|
97
|
-
text = text.replace(/(\}|\;)\n(export )/g, '$1\n\n$2');
|
|
98
|
-
// Remove trailing extra blank lines at end of file
|
|
99
|
-
text = text.replace(/\n\n+$/, '\n');
|
|
100
|
-
return text;
|
|
101
|
-
}
|
|
102
|
-
// ============================================================================
|
|
103
|
-
// Comment helpers
|
|
104
|
-
// ============================================================================
|
|
105
|
-
/**
|
|
106
|
-
* Create a file header comment
|
|
107
|
-
*/
|
|
108
|
-
function createFileHeader(description) {
|
|
109
|
-
return [
|
|
110
|
-
'/**',
|
|
111
|
-
` * ${description}`,
|
|
112
|
-
' * @generated by @constructive-io/graphql-codegen',
|
|
113
|
-
' * DO NOT EDIT - changes will be overwritten',
|
|
114
|
-
' */',
|
|
115
|
-
].join('\n');
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Create JSDoc comment for a declaration
|
|
119
|
-
*/
|
|
120
|
-
function createJsDoc(lines) {
|
|
121
|
-
if (lines.length === 1) {
|
|
122
|
-
return `/** ${lines[0]} */`;
|
|
123
|
-
}
|
|
124
|
-
return ['/**', ...lines.map((l) => ` * ${l}`), ' */'].join('\n');
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* Create import declaration structure
|
|
128
|
-
*/
|
|
129
|
-
function createImport(spec) {
|
|
130
|
-
const namedImports = [];
|
|
131
|
-
if (spec.namedImports) {
|
|
132
|
-
namedImports.push(...spec.namedImports.map((name) => ({ name })));
|
|
133
|
-
}
|
|
134
|
-
if (spec.typeOnlyNamedImports) {
|
|
135
|
-
namedImports.push(...spec.typeOnlyNamedImports.map((name) => ({ name, isTypeOnly: true })));
|
|
136
|
-
}
|
|
137
|
-
return {
|
|
138
|
-
kind: ts_morph_1.StructureKind.ImportDeclaration,
|
|
139
|
-
moduleSpecifier: spec.moduleSpecifier,
|
|
140
|
-
defaultImport: spec.defaultImport,
|
|
141
|
-
namedImports: namedImports.length > 0 ? namedImports : undefined,
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Create interface declaration structure
|
|
146
|
-
*/
|
|
147
|
-
function createInterface(name, properties, options) {
|
|
148
|
-
return {
|
|
149
|
-
kind: ts_morph_1.StructureKind.Interface,
|
|
150
|
-
name,
|
|
151
|
-
isExported: options?.isExported ?? true,
|
|
152
|
-
extends: options?.extends,
|
|
153
|
-
docs: options?.docs ? [{ description: options.docs.join('\n') }] : undefined,
|
|
154
|
-
properties: properties.map((prop) => ({
|
|
155
|
-
kind: ts_morph_1.StructureKind.PropertySignature,
|
|
156
|
-
name: prop.name,
|
|
157
|
-
type: prop.type,
|
|
158
|
-
hasQuestionToken: prop.optional,
|
|
159
|
-
docs: prop.docs ? [{ description: prop.docs.join('\n') }] : undefined,
|
|
160
|
-
})),
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Create filter interface with standard PostGraphile operators
|
|
165
|
-
*/
|
|
166
|
-
function createFilterInterface(name, fieldFilters, options) {
|
|
167
|
-
const properties = [
|
|
168
|
-
...fieldFilters.map((f) => ({
|
|
169
|
-
name: f.fieldName,
|
|
170
|
-
type: f.filterType,
|
|
171
|
-
optional: true,
|
|
172
|
-
})),
|
|
173
|
-
{ name: 'and', type: `${name}[]`, optional: true, docs: ['Logical AND'] },
|
|
174
|
-
{ name: 'or', type: `${name}[]`, optional: true, docs: ['Logical OR'] },
|
|
175
|
-
{ name: 'not', type: name, optional: true, docs: ['Logical NOT'] },
|
|
176
|
-
];
|
|
177
|
-
return createInterface(name, properties, { isExported: options?.isExported ?? true });
|
|
178
|
-
}
|
|
179
|
-
// ============================================================================
|
|
180
|
-
// Type alias builders
|
|
181
|
-
// ============================================================================
|
|
182
|
-
/**
|
|
183
|
-
* Create type alias declaration structure
|
|
184
|
-
*/
|
|
185
|
-
function createTypeAlias(name, type, options) {
|
|
186
|
-
return {
|
|
187
|
-
kind: ts_morph_1.StructureKind.TypeAlias,
|
|
188
|
-
name,
|
|
189
|
-
type,
|
|
190
|
-
isExported: options?.isExported ?? true,
|
|
191
|
-
docs: options?.docs ? [{ description: options.docs.join('\n') }] : undefined,
|
|
192
|
-
};
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* Create union type from string literals
|
|
196
|
-
*/
|
|
197
|
-
function createUnionType(values) {
|
|
198
|
-
return values.map((v) => `'${v}'`).join(' | ');
|
|
199
|
-
}
|
|
200
|
-
// ============================================================================
|
|
201
|
-
// Variable/constant builders
|
|
202
|
-
// ============================================================================
|
|
203
|
-
/**
|
|
204
|
-
* Create const variable statement structure
|
|
205
|
-
*/
|
|
206
|
-
function createConst(name, initializer, options) {
|
|
207
|
-
return {
|
|
208
|
-
kind: ts_morph_1.StructureKind.VariableStatement,
|
|
209
|
-
declarationKind: ts_morph_1.VariableDeclarationKind.Const,
|
|
210
|
-
isExported: options?.isExported ?? true,
|
|
211
|
-
docs: options?.docs ? [{ description: options.docs.join('\n') }] : undefined,
|
|
212
|
-
declarations: [
|
|
213
|
-
{
|
|
214
|
-
name,
|
|
215
|
-
type: options?.type,
|
|
216
|
-
initializer,
|
|
217
|
-
},
|
|
218
|
-
],
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
/**
|
|
222
|
-
* Create a template literal string (for GraphQL documents)
|
|
223
|
-
*/
|
|
224
|
-
function createTemplateLiteral(content) {
|
|
225
|
-
return '`\n' + content + '\n`';
|
|
226
|
-
}
|
|
227
|
-
/**
|
|
228
|
-
* Create function declaration structure
|
|
229
|
-
*/
|
|
230
|
-
function createFunction(name, parameters, returnType, body, options) {
|
|
231
|
-
return {
|
|
232
|
-
kind: ts_morph_1.StructureKind.Function,
|
|
233
|
-
name,
|
|
234
|
-
isExported: options?.isExported ?? true,
|
|
235
|
-
isAsync: options?.isAsync,
|
|
236
|
-
parameters: parameters.map((p) => ({
|
|
237
|
-
name: p.name,
|
|
238
|
-
type: p.type,
|
|
239
|
-
hasQuestionToken: p.optional,
|
|
240
|
-
initializer: p.initializer,
|
|
241
|
-
})),
|
|
242
|
-
returnType,
|
|
243
|
-
statements: body,
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
|
-
// ============================================================================
|
|
247
|
-
// Export builders
|
|
248
|
-
// ============================================================================
|
|
249
|
-
/**
|
|
250
|
-
* Create re-export statement
|
|
251
|
-
*/
|
|
252
|
-
function createReExport(names, moduleSpecifier, isTypeOnly = false) {
|
|
253
|
-
const typePrefix = isTypeOnly ? 'type ' : '';
|
|
254
|
-
return `export ${typePrefix}{ ${names.join(', ')} } from '${moduleSpecifier}';`;
|
|
255
|
-
}
|
|
256
|
-
/**
|
|
257
|
-
* Create barrel export statement
|
|
258
|
-
*/
|
|
259
|
-
function createBarrelExport(moduleSpecifier) {
|
|
260
|
-
return `export * from '${moduleSpecifier}';`;
|
|
261
|
-
}
|
|
262
|
-
// ============================================================================
|
|
263
|
-
// Section comment helpers
|
|
264
|
-
// ============================================================================
|
|
265
|
-
/**
|
|
266
|
-
* Create a section divider comment for generated code
|
|
267
|
-
*/
|
|
268
|
-
function createSectionComment(title) {
|
|
269
|
-
return [
|
|
270
|
-
'// ============================================================================',
|
|
271
|
-
`// ${title}`,
|
|
272
|
-
'// ============================================================================',
|
|
273
|
-
].join('\n');
|
|
274
|
-
}
|
|
275
|
-
/**
|
|
276
|
-
* Add a section comment to source file with proper spacing
|
|
277
|
-
*/
|
|
278
|
-
function addSectionComment(sourceFile, title) {
|
|
279
|
-
sourceFile.addStatements(`\n${createSectionComment(title)}\n\n`);
|
|
280
|
-
}
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TypeScript AST builders using ts-morph
|
|
3
|
-
*
|
|
4
|
-
* Provides utilities for generating TypeScript code via AST manipulation
|
|
5
|
-
* instead of string concatenation.
|
|
6
|
-
*/
|
|
7
|
-
import { Project, SourceFile, type InterfaceDeclarationStructure, type FunctionDeclarationStructure, type VariableStatementStructure, type ImportDeclarationStructure, type TypeAliasDeclarationStructure } from 'ts-morph';
|
|
8
|
-
/**
|
|
9
|
-
* Create a new ts-morph project for code generation
|
|
10
|
-
*/
|
|
11
|
-
export declare function createProject(): Project;
|
|
12
|
-
/**
|
|
13
|
-
* Create a source file in the project
|
|
14
|
-
*/
|
|
15
|
-
export declare function createSourceFile(project: Project, fileName: string): SourceFile;
|
|
16
|
-
/**
|
|
17
|
-
* Get formatted output from source file
|
|
18
|
-
*/
|
|
19
|
-
export declare function getFormattedOutput(sourceFile: SourceFile): string;
|
|
20
|
-
/**
|
|
21
|
-
* Get output with minimal formatting (preserves intentional blank lines)
|
|
22
|
-
* Post-processes to fix indentation and section comment spacing
|
|
23
|
-
*
|
|
24
|
-
* ts-morph generates type alias bodies with extra indentation:
|
|
25
|
-
* - Properties get 6 spaces (we want 2)
|
|
26
|
-
* - Closing brace gets 4 spaces (we want 0)
|
|
27
|
-
*
|
|
28
|
-
* For interfaces it uses 4 spaces which we convert to 2.
|
|
29
|
-
*/
|
|
30
|
-
export declare function getMinimalFormattedOutput(sourceFile: SourceFile): string;
|
|
31
|
-
/**
|
|
32
|
-
* Create a file header comment
|
|
33
|
-
*/
|
|
34
|
-
export declare function createFileHeader(description: string): string;
|
|
35
|
-
/**
|
|
36
|
-
* Create JSDoc comment for a declaration
|
|
37
|
-
*/
|
|
38
|
-
export declare function createJsDoc(lines: string[]): string;
|
|
39
|
-
export interface ImportSpec {
|
|
40
|
-
moduleSpecifier: string;
|
|
41
|
-
namedImports?: string[];
|
|
42
|
-
typeOnlyNamedImports?: string[];
|
|
43
|
-
defaultImport?: string;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Create import declaration structure
|
|
47
|
-
*/
|
|
48
|
-
export declare function createImport(spec: ImportSpec): ImportDeclarationStructure;
|
|
49
|
-
export interface InterfaceProperty {
|
|
50
|
-
name: string;
|
|
51
|
-
type: string;
|
|
52
|
-
optional?: boolean;
|
|
53
|
-
docs?: string[];
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Create interface declaration structure
|
|
57
|
-
*/
|
|
58
|
-
export declare function createInterface(name: string, properties: InterfaceProperty[], options?: {
|
|
59
|
-
docs?: string[];
|
|
60
|
-
isExported?: boolean;
|
|
61
|
-
extends?: string[];
|
|
62
|
-
}): InterfaceDeclarationStructure;
|
|
63
|
-
/**
|
|
64
|
-
* Create filter interface with standard PostGraphile operators
|
|
65
|
-
*/
|
|
66
|
-
export declare function createFilterInterface(name: string, fieldFilters: Array<{
|
|
67
|
-
fieldName: string;
|
|
68
|
-
filterType: string;
|
|
69
|
-
}>, options?: {
|
|
70
|
-
isExported?: boolean;
|
|
71
|
-
}): InterfaceDeclarationStructure;
|
|
72
|
-
/**
|
|
73
|
-
* Create type alias declaration structure
|
|
74
|
-
*/
|
|
75
|
-
export declare function createTypeAlias(name: string, type: string, options?: {
|
|
76
|
-
docs?: string[];
|
|
77
|
-
isExported?: boolean;
|
|
78
|
-
}): TypeAliasDeclarationStructure;
|
|
79
|
-
/**
|
|
80
|
-
* Create union type from string literals
|
|
81
|
-
*/
|
|
82
|
-
export declare function createUnionType(values: string[]): string;
|
|
83
|
-
/**
|
|
84
|
-
* Create const variable statement structure
|
|
85
|
-
*/
|
|
86
|
-
export declare function createConst(name: string, initializer: string, options?: {
|
|
87
|
-
docs?: string[];
|
|
88
|
-
isExported?: boolean;
|
|
89
|
-
type?: string;
|
|
90
|
-
}): VariableStatementStructure;
|
|
91
|
-
/**
|
|
92
|
-
* Create a template literal string (for GraphQL documents)
|
|
93
|
-
*/
|
|
94
|
-
export declare function createTemplateLiteral(content: string): string;
|
|
95
|
-
export interface FunctionParameter {
|
|
96
|
-
name: string;
|
|
97
|
-
type: string;
|
|
98
|
-
optional?: boolean;
|
|
99
|
-
initializer?: string;
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Create function declaration structure
|
|
103
|
-
*/
|
|
104
|
-
export declare function createFunction(name: string, parameters: FunctionParameter[], returnType: string, body: string, options?: {
|
|
105
|
-
docs?: string[];
|
|
106
|
-
isExported?: boolean;
|
|
107
|
-
isAsync?: boolean;
|
|
108
|
-
}): FunctionDeclarationStructure;
|
|
109
|
-
/**
|
|
110
|
-
* Create re-export statement
|
|
111
|
-
*/
|
|
112
|
-
export declare function createReExport(names: string[], moduleSpecifier: string, isTypeOnly?: boolean): string;
|
|
113
|
-
/**
|
|
114
|
-
* Create barrel export statement
|
|
115
|
-
*/
|
|
116
|
-
export declare function createBarrelExport(moduleSpecifier: string): string;
|
|
117
|
-
/**
|
|
118
|
-
* Create a section divider comment for generated code
|
|
119
|
-
*/
|
|
120
|
-
export declare function createSectionComment(title: string): string;
|
|
121
|
-
/**
|
|
122
|
-
* Add a section comment to source file with proper spacing
|
|
123
|
-
*/
|
|
124
|
-
export declare function addSectionComment(sourceFile: SourceFile, title: string): void;
|
|
@@ -1,260 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TypeScript AST builders using ts-morph
|
|
3
|
-
*
|
|
4
|
-
* Provides utilities for generating TypeScript code via AST manipulation
|
|
5
|
-
* instead of string concatenation.
|
|
6
|
-
*/
|
|
7
|
-
import { Project, StructureKind, VariableDeclarationKind, ScriptTarget, ModuleKind, } from 'ts-morph';
|
|
8
|
-
// ============================================================================
|
|
9
|
-
// Project management
|
|
10
|
-
// ============================================================================
|
|
11
|
-
/**
|
|
12
|
-
* Create a new ts-morph project for code generation
|
|
13
|
-
*/
|
|
14
|
-
export function createProject() {
|
|
15
|
-
return new Project({
|
|
16
|
-
useInMemoryFileSystem: true,
|
|
17
|
-
compilerOptions: {
|
|
18
|
-
declaration: true,
|
|
19
|
-
strict: true,
|
|
20
|
-
target: ScriptTarget.ESNext,
|
|
21
|
-
module: ModuleKind.ESNext,
|
|
22
|
-
},
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Create a source file in the project
|
|
27
|
-
*/
|
|
28
|
-
export function createSourceFile(project, fileName) {
|
|
29
|
-
return project.createSourceFile(fileName, '', { overwrite: true });
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Get formatted output from source file
|
|
33
|
-
*/
|
|
34
|
-
export function getFormattedOutput(sourceFile) {
|
|
35
|
-
sourceFile.formatText({
|
|
36
|
-
indentSize: 2,
|
|
37
|
-
convertTabsToSpaces: true,
|
|
38
|
-
});
|
|
39
|
-
return sourceFile.getFullText();
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Get output with minimal formatting (preserves intentional blank lines)
|
|
43
|
-
* Post-processes to fix indentation and section comment spacing
|
|
44
|
-
*
|
|
45
|
-
* ts-morph generates type alias bodies with extra indentation:
|
|
46
|
-
* - Properties get 6 spaces (we want 2)
|
|
47
|
-
* - Closing brace gets 4 spaces (we want 0)
|
|
48
|
-
*
|
|
49
|
-
* For interfaces it uses 4 spaces which we convert to 2.
|
|
50
|
-
*/
|
|
51
|
-
export function getMinimalFormattedOutput(sourceFile) {
|
|
52
|
-
let text = sourceFile.getFullText();
|
|
53
|
-
// Process each line to fix indentation
|
|
54
|
-
// ts-morph uses inconsistent indentation for type alias bodies
|
|
55
|
-
// We halve all indentation: 4->2, 6->3 (rounds to 2), 8->4, etc.
|
|
56
|
-
text = text.split('\n').map(line => {
|
|
57
|
-
// Match leading whitespace
|
|
58
|
-
const match = line.match(/^(\s*)/);
|
|
59
|
-
if (!match)
|
|
60
|
-
return line;
|
|
61
|
-
const spaces = match[1].length;
|
|
62
|
-
const content = line.slice(spaces);
|
|
63
|
-
// Skip empty lines
|
|
64
|
-
if (content === '')
|
|
65
|
-
return line;
|
|
66
|
-
// No indentation - keep as-is
|
|
67
|
-
if (spaces === 0)
|
|
68
|
-
return line;
|
|
69
|
-
// Halve the indentation (minimum 0)
|
|
70
|
-
const newSpaces = Math.floor(spaces / 2);
|
|
71
|
-
return ' '.repeat(newSpaces) + content;
|
|
72
|
-
}).join('\n');
|
|
73
|
-
// Ensure blank line after section comment blocks
|
|
74
|
-
text = text.replace(/(\/\/ =+\n\/\/ .+\n\/\/ =+)\n(export|\/\/)/g, '$1\n\n$2');
|
|
75
|
-
// Add blank line between consecutive export declarations (type aliases, interfaces)
|
|
76
|
-
// Pattern: "}\nexport" or ";\nexport" should become "}\n\nexport" or ";\n\nexport"
|
|
77
|
-
text = text.replace(/(\}|\;)\n(export )/g, '$1\n\n$2');
|
|
78
|
-
// Remove trailing extra blank lines at end of file
|
|
79
|
-
text = text.replace(/\n\n+$/, '\n');
|
|
80
|
-
return text;
|
|
81
|
-
}
|
|
82
|
-
// ============================================================================
|
|
83
|
-
// Comment helpers
|
|
84
|
-
// ============================================================================
|
|
85
|
-
/**
|
|
86
|
-
* Create a file header comment
|
|
87
|
-
*/
|
|
88
|
-
export function createFileHeader(description) {
|
|
89
|
-
return [
|
|
90
|
-
'/**',
|
|
91
|
-
` * ${description}`,
|
|
92
|
-
' * @generated by @constructive-io/graphql-codegen',
|
|
93
|
-
' * DO NOT EDIT - changes will be overwritten',
|
|
94
|
-
' */',
|
|
95
|
-
].join('\n');
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Create JSDoc comment for a declaration
|
|
99
|
-
*/
|
|
100
|
-
export function createJsDoc(lines) {
|
|
101
|
-
if (lines.length === 1) {
|
|
102
|
-
return `/** ${lines[0]} */`;
|
|
103
|
-
}
|
|
104
|
-
return ['/**', ...lines.map((l) => ` * ${l}`), ' */'].join('\n');
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Create import declaration structure
|
|
108
|
-
*/
|
|
109
|
-
export function createImport(spec) {
|
|
110
|
-
const namedImports = [];
|
|
111
|
-
if (spec.namedImports) {
|
|
112
|
-
namedImports.push(...spec.namedImports.map((name) => ({ name })));
|
|
113
|
-
}
|
|
114
|
-
if (spec.typeOnlyNamedImports) {
|
|
115
|
-
namedImports.push(...spec.typeOnlyNamedImports.map((name) => ({ name, isTypeOnly: true })));
|
|
116
|
-
}
|
|
117
|
-
return {
|
|
118
|
-
kind: StructureKind.ImportDeclaration,
|
|
119
|
-
moduleSpecifier: spec.moduleSpecifier,
|
|
120
|
-
defaultImport: spec.defaultImport,
|
|
121
|
-
namedImports: namedImports.length > 0 ? namedImports : undefined,
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Create interface declaration structure
|
|
126
|
-
*/
|
|
127
|
-
export function createInterface(name, properties, options) {
|
|
128
|
-
return {
|
|
129
|
-
kind: StructureKind.Interface,
|
|
130
|
-
name,
|
|
131
|
-
isExported: options?.isExported ?? true,
|
|
132
|
-
extends: options?.extends,
|
|
133
|
-
docs: options?.docs ? [{ description: options.docs.join('\n') }] : undefined,
|
|
134
|
-
properties: properties.map((prop) => ({
|
|
135
|
-
kind: StructureKind.PropertySignature,
|
|
136
|
-
name: prop.name,
|
|
137
|
-
type: prop.type,
|
|
138
|
-
hasQuestionToken: prop.optional,
|
|
139
|
-
docs: prop.docs ? [{ description: prop.docs.join('\n') }] : undefined,
|
|
140
|
-
})),
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Create filter interface with standard PostGraphile operators
|
|
145
|
-
*/
|
|
146
|
-
export function createFilterInterface(name, fieldFilters, options) {
|
|
147
|
-
const properties = [
|
|
148
|
-
...fieldFilters.map((f) => ({
|
|
149
|
-
name: f.fieldName,
|
|
150
|
-
type: f.filterType,
|
|
151
|
-
optional: true,
|
|
152
|
-
})),
|
|
153
|
-
{ name: 'and', type: `${name}[]`, optional: true, docs: ['Logical AND'] },
|
|
154
|
-
{ name: 'or', type: `${name}[]`, optional: true, docs: ['Logical OR'] },
|
|
155
|
-
{ name: 'not', type: name, optional: true, docs: ['Logical NOT'] },
|
|
156
|
-
];
|
|
157
|
-
return createInterface(name, properties, { isExported: options?.isExported ?? true });
|
|
158
|
-
}
|
|
159
|
-
// ============================================================================
|
|
160
|
-
// Type alias builders
|
|
161
|
-
// ============================================================================
|
|
162
|
-
/**
|
|
163
|
-
* Create type alias declaration structure
|
|
164
|
-
*/
|
|
165
|
-
export function createTypeAlias(name, type, options) {
|
|
166
|
-
return {
|
|
167
|
-
kind: StructureKind.TypeAlias,
|
|
168
|
-
name,
|
|
169
|
-
type,
|
|
170
|
-
isExported: options?.isExported ?? true,
|
|
171
|
-
docs: options?.docs ? [{ description: options.docs.join('\n') }] : undefined,
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Create union type from string literals
|
|
176
|
-
*/
|
|
177
|
-
export function createUnionType(values) {
|
|
178
|
-
return values.map((v) => `'${v}'`).join(' | ');
|
|
179
|
-
}
|
|
180
|
-
// ============================================================================
|
|
181
|
-
// Variable/constant builders
|
|
182
|
-
// ============================================================================
|
|
183
|
-
/**
|
|
184
|
-
* Create const variable statement structure
|
|
185
|
-
*/
|
|
186
|
-
export function createConst(name, initializer, options) {
|
|
187
|
-
return {
|
|
188
|
-
kind: StructureKind.VariableStatement,
|
|
189
|
-
declarationKind: VariableDeclarationKind.Const,
|
|
190
|
-
isExported: options?.isExported ?? true,
|
|
191
|
-
docs: options?.docs ? [{ description: options.docs.join('\n') }] : undefined,
|
|
192
|
-
declarations: [
|
|
193
|
-
{
|
|
194
|
-
name,
|
|
195
|
-
type: options?.type,
|
|
196
|
-
initializer,
|
|
197
|
-
},
|
|
198
|
-
],
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* Create a template literal string (for GraphQL documents)
|
|
203
|
-
*/
|
|
204
|
-
export function createTemplateLiteral(content) {
|
|
205
|
-
return '`\n' + content + '\n`';
|
|
206
|
-
}
|
|
207
|
-
/**
|
|
208
|
-
* Create function declaration structure
|
|
209
|
-
*/
|
|
210
|
-
export function createFunction(name, parameters, returnType, body, options) {
|
|
211
|
-
return {
|
|
212
|
-
kind: StructureKind.Function,
|
|
213
|
-
name,
|
|
214
|
-
isExported: options?.isExported ?? true,
|
|
215
|
-
isAsync: options?.isAsync,
|
|
216
|
-
parameters: parameters.map((p) => ({
|
|
217
|
-
name: p.name,
|
|
218
|
-
type: p.type,
|
|
219
|
-
hasQuestionToken: p.optional,
|
|
220
|
-
initializer: p.initializer,
|
|
221
|
-
})),
|
|
222
|
-
returnType,
|
|
223
|
-
statements: body,
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
// ============================================================================
|
|
227
|
-
// Export builders
|
|
228
|
-
// ============================================================================
|
|
229
|
-
/**
|
|
230
|
-
* Create re-export statement
|
|
231
|
-
*/
|
|
232
|
-
export function createReExport(names, moduleSpecifier, isTypeOnly = false) {
|
|
233
|
-
const typePrefix = isTypeOnly ? 'type ' : '';
|
|
234
|
-
return `export ${typePrefix}{ ${names.join(', ')} } from '${moduleSpecifier}';`;
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
* Create barrel export statement
|
|
238
|
-
*/
|
|
239
|
-
export function createBarrelExport(moduleSpecifier) {
|
|
240
|
-
return `export * from '${moduleSpecifier}';`;
|
|
241
|
-
}
|
|
242
|
-
// ============================================================================
|
|
243
|
-
// Section comment helpers
|
|
244
|
-
// ============================================================================
|
|
245
|
-
/**
|
|
246
|
-
* Create a section divider comment for generated code
|
|
247
|
-
*/
|
|
248
|
-
export function createSectionComment(title) {
|
|
249
|
-
return [
|
|
250
|
-
'// ============================================================================',
|
|
251
|
-
`// ${title}`,
|
|
252
|
-
'// ============================================================================',
|
|
253
|
-
].join('\n');
|
|
254
|
-
}
|
|
255
|
-
/**
|
|
256
|
-
* Add a section comment to source file with proper spacing
|
|
257
|
-
*/
|
|
258
|
-
export function addSectionComment(sourceFile, title) {
|
|
259
|
-
sourceFile.addStatements(`\n${createSectionComment(title)}\n\n`);
|
|
260
|
-
}
|