@constructive-io/graphql-codegen 3.2.1 → 3.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/index.js +36 -43
- package/cli/shared.d.ts +15 -19
- package/cli/shared.js +104 -25
- 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 -44
- package/esm/cli/shared.d.ts +15 -19
- package/esm/cli/shared.js +94 -23
- 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 -6
- package/package.json +10 -10
- 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
|
@@ -35,6 +35,12 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.generateModelFile = generateModelFile;
|
|
37
37
|
exports.generateAllModelFiles = generateAllModelFiles;
|
|
38
|
+
/**
|
|
39
|
+
* Model class generator for ORM client (Babel AST-based)
|
|
40
|
+
*
|
|
41
|
+
* Generates per-table model classes with findMany, findFirst, create, update, delete methods.
|
|
42
|
+
* Each method uses function overloads for IDE autocompletion of select objects.
|
|
43
|
+
*/
|
|
38
44
|
const t = __importStar(require("@babel/types"));
|
|
39
45
|
const babel_ast_1 = require("../babel-ast");
|
|
40
46
|
const utils_1 = require("../utils");
|
|
@@ -69,11 +75,36 @@ function createClassMethod(name, typeParameters, params, returnType, body) {
|
|
|
69
75
|
method.returnType = returnType;
|
|
70
76
|
return method;
|
|
71
77
|
}
|
|
72
|
-
function
|
|
73
|
-
const
|
|
74
|
-
|
|
78
|
+
function createDeclareMethod(name, typeParameters, params, returnType) {
|
|
79
|
+
const method = t.tsDeclareMethod(null, t.identifier(name), typeParameters, params, returnType);
|
|
80
|
+
return method;
|
|
81
|
+
}
|
|
82
|
+
function createTypeParam(constraintTypeName, defaultType) {
|
|
83
|
+
const param = t.tsTypeParameter(t.tsTypeReference(t.identifier(constraintTypeName)), defaultType ?? null, 'S');
|
|
75
84
|
return t.tsTypeParameterDeclaration([param]);
|
|
76
85
|
}
|
|
86
|
+
function tsTypeFromPrimitive(typeName) {
|
|
87
|
+
if (typeName === 'string')
|
|
88
|
+
return t.tsStringKeyword();
|
|
89
|
+
if (typeName === 'number')
|
|
90
|
+
return t.tsNumberKeyword();
|
|
91
|
+
if (typeName === 'boolean')
|
|
92
|
+
return t.tsBooleanKeyword();
|
|
93
|
+
return t.tsTypeReference(t.identifier(typeName));
|
|
94
|
+
}
|
|
95
|
+
/** Build a required `select: S` property for overload signatures */
|
|
96
|
+
function requiredSelectProp() {
|
|
97
|
+
const prop = t.tsPropertySignature(t.identifier('select'), t.tsTypeAnnotation(t.tsTypeReference(t.identifier('S'))));
|
|
98
|
+
prop.optional = false;
|
|
99
|
+
return prop;
|
|
100
|
+
}
|
|
101
|
+
/** Build `StrictSelect<S, XxxSelect>` type reference for overload intersections */
|
|
102
|
+
function strictSelectGuard(selectTypeName) {
|
|
103
|
+
return t.tsTypeReference(t.identifier('StrictSelect'), t.tsTypeParameterInstantiation([
|
|
104
|
+
t.tsTypeReference(t.identifier('S')),
|
|
105
|
+
t.tsTypeReference(t.identifier(selectTypeName)),
|
|
106
|
+
]));
|
|
107
|
+
}
|
|
77
108
|
function generateModelFile(table, _useSharedTypes) {
|
|
78
109
|
const { typeName, singularName, pluralName } = (0, utils_1.getTableNames)(table);
|
|
79
110
|
const modelName = `${typeName}Model`;
|
|
@@ -88,6 +119,8 @@ function generateModelFile(table, _useSharedTypes) {
|
|
|
88
119
|
const updateInputTypeName = `Update${typeName}Input`;
|
|
89
120
|
const deleteInputTypeName = `Delete${typeName}Input`;
|
|
90
121
|
const patchTypeName = `${typeName}Patch`;
|
|
122
|
+
const pkFields = (0, utils_1.getPrimaryKeyInfo)(table);
|
|
123
|
+
const pkField = pkFields[0];
|
|
91
124
|
const pluralQueryName = table.query?.all ?? pluralName;
|
|
92
125
|
const createMutationName = table.query?.create ?? `create${typeName}`;
|
|
93
126
|
const updateMutationName = table.query?.update;
|
|
@@ -95,17 +128,35 @@ function generateModelFile(table, _useSharedTypes) {
|
|
|
95
128
|
const statements = [];
|
|
96
129
|
statements.push(createImportDeclaration('../client', ['OrmClient']));
|
|
97
130
|
statements.push(createImportDeclaration('../query-builder', [
|
|
98
|
-
'QueryBuilder',
|
|
99
|
-
'
|
|
131
|
+
'QueryBuilder',
|
|
132
|
+
'buildFindManyDocument',
|
|
133
|
+
'buildFindFirstDocument',
|
|
134
|
+
'buildFindOneDocument',
|
|
135
|
+
'buildCreateDocument',
|
|
136
|
+
'buildUpdateByPkDocument',
|
|
137
|
+
'buildDeleteByPkDocument',
|
|
100
138
|
]));
|
|
101
139
|
statements.push(createImportDeclaration('../select-types', [
|
|
102
|
-
'ConnectionResult',
|
|
103
|
-
'
|
|
140
|
+
'ConnectionResult',
|
|
141
|
+
'FindManyArgs',
|
|
142
|
+
'FindFirstArgs',
|
|
143
|
+
'CreateArgs',
|
|
144
|
+
'UpdateArgs',
|
|
145
|
+
'DeleteArgs',
|
|
146
|
+
'InferSelectResult',
|
|
147
|
+
'StrictSelect',
|
|
104
148
|
], true));
|
|
105
149
|
statements.push(createImportDeclaration('../input-types', [
|
|
106
|
-
typeName,
|
|
107
|
-
|
|
150
|
+
typeName,
|
|
151
|
+
relationTypeName,
|
|
152
|
+
selectTypeName,
|
|
153
|
+
whereTypeName,
|
|
154
|
+
orderByTypeName,
|
|
155
|
+
createInputTypeName,
|
|
156
|
+
updateInputTypeName,
|
|
157
|
+
patchTypeName,
|
|
108
158
|
], true));
|
|
159
|
+
statements.push(createImportDeclaration('../input-types', ['connectionFieldsMap']));
|
|
109
160
|
const classBody = [];
|
|
110
161
|
// Constructor
|
|
111
162
|
const constructorParam = t.identifier('client');
|
|
@@ -113,162 +164,289 @@ function generateModelFile(table, _useSharedTypes) {
|
|
|
113
164
|
const paramProp = t.tsParameterProperty(constructorParam);
|
|
114
165
|
paramProp.accessibility = 'private';
|
|
115
166
|
classBody.push(t.classMethod('constructor', t.identifier('constructor'), [paramProp], t.blockStatement([])));
|
|
116
|
-
//
|
|
117
|
-
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
])),
|
|
135
|
-
])))),
|
|
136
|
-
]),
|
|
137
|
-
])));
|
|
138
|
-
const findManyArgs = [
|
|
139
|
-
t.stringLiteral(typeName),
|
|
140
|
-
t.stringLiteral(pluralQueryName),
|
|
141
|
-
t.optionalMemberExpression(t.identifier('args'), t.identifier('select'), false, true),
|
|
142
|
-
t.objectExpression([
|
|
143
|
-
t.objectProperty(t.identifier('where'), t.optionalMemberExpression(t.identifier('args'), t.identifier('where'), false, true)),
|
|
144
|
-
t.objectProperty(t.identifier('orderBy'), t.tsAsExpression(t.optionalMemberExpression(t.identifier('args'), t.identifier('orderBy'), false, true), t.tsUnionType([t.tsArrayType(t.tsStringKeyword()), t.tsUndefinedKeyword()]))),
|
|
145
|
-
t.objectProperty(t.identifier('first'), t.optionalMemberExpression(t.identifier('args'), t.identifier('first'), false, true)),
|
|
146
|
-
t.objectProperty(t.identifier('last'), t.optionalMemberExpression(t.identifier('args'), t.identifier('last'), false, true)),
|
|
147
|
-
t.objectProperty(t.identifier('after'), t.optionalMemberExpression(t.identifier('args'), t.identifier('after'), false, true)),
|
|
148
|
-
t.objectProperty(t.identifier('before'), t.optionalMemberExpression(t.identifier('args'), t.identifier('before'), false, true)),
|
|
149
|
-
t.objectProperty(t.identifier('offset'), t.optionalMemberExpression(t.identifier('args'), t.identifier('offset'), false, true)),
|
|
150
|
-
]),
|
|
151
|
-
t.stringLiteral(whereTypeName),
|
|
152
|
-
t.stringLiteral(orderByTypeName),
|
|
153
|
-
];
|
|
154
|
-
classBody.push(createClassMethod('findMany', createConstTypeParam(selectTypeName), [findManyParam], findManyReturnType, buildMethodBody('buildFindManyDocument', findManyArgs, 'query', typeName, pluralQueryName)));
|
|
155
|
-
// findFirst method
|
|
156
|
-
const findFirstParam = t.identifier('args');
|
|
157
|
-
findFirstParam.optional = true;
|
|
158
|
-
findFirstParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('FindFirstArgs'), t.tsTypeParameterInstantiation([
|
|
159
|
-
t.tsTypeReference(t.identifier('DeepExact'), t.tsTypeParameterInstantiation([
|
|
160
|
-
t.tsTypeReference(t.identifier('S')),
|
|
161
|
-
t.tsTypeReference(t.identifier(selectTypeName)),
|
|
162
|
-
])),
|
|
163
|
-
t.tsTypeReference(t.identifier(whereTypeName)),
|
|
164
|
-
])));
|
|
165
|
-
const findFirstReturnType = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('QueryBuilder'), t.tsTypeParameterInstantiation([
|
|
166
|
-
t.tsTypeLiteral([
|
|
167
|
-
t.tsPropertySignature(t.identifier(pluralQueryName), t.tsTypeAnnotation(t.tsTypeLiteral([
|
|
168
|
-
t.tsPropertySignature(t.identifier('nodes'), t.tsTypeAnnotation(t.tsArrayType(t.tsTypeReference(t.identifier('InferSelectResult'), t.tsTypeParameterInstantiation([
|
|
169
|
-
t.tsTypeReference(t.identifier(relationTypeName)),
|
|
170
|
-
t.tsTypeReference(t.identifier('S')),
|
|
171
|
-
]))))),
|
|
172
|
-
]))),
|
|
173
|
-
]),
|
|
174
|
-
])));
|
|
175
|
-
const findFirstArgs = [
|
|
176
|
-
t.stringLiteral(typeName),
|
|
177
|
-
t.stringLiteral(pluralQueryName),
|
|
178
|
-
t.optionalMemberExpression(t.identifier('args'), t.identifier('select'), false, true),
|
|
179
|
-
t.objectExpression([
|
|
180
|
-
t.objectProperty(t.identifier('where'), t.optionalMemberExpression(t.identifier('args'), t.identifier('where'), false, true)),
|
|
181
|
-
]),
|
|
182
|
-
t.stringLiteral(whereTypeName),
|
|
183
|
-
];
|
|
184
|
-
classBody.push(createClassMethod('findFirst', createConstTypeParam(selectTypeName), [findFirstParam], findFirstReturnType, buildMethodBody('buildFindFirstDocument', findFirstArgs, 'query', typeName, pluralQueryName)));
|
|
185
|
-
// create method
|
|
186
|
-
const createParam = t.identifier('args');
|
|
187
|
-
createParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('CreateArgs'), t.tsTypeParameterInstantiation([
|
|
188
|
-
t.tsTypeReference(t.identifier('DeepExact'), t.tsTypeParameterInstantiation([
|
|
189
|
-
t.tsTypeReference(t.identifier('S')),
|
|
190
|
-
t.tsTypeReference(t.identifier(selectTypeName)),
|
|
191
|
-
])),
|
|
192
|
-
t.tsIndexedAccessType(t.tsTypeReference(t.identifier(createInputTypeName)), t.tsLiteralType(t.stringLiteral(singularName))),
|
|
193
|
-
])));
|
|
194
|
-
const createReturnType = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('QueryBuilder'), t.tsTypeParameterInstantiation([
|
|
195
|
-
t.tsTypeLiteral([
|
|
196
|
-
t.tsPropertySignature(t.identifier(createMutationName), t.tsTypeAnnotation(t.tsTypeLiteral([
|
|
197
|
-
t.tsPropertySignature(t.identifier(entityLower), t.tsTypeAnnotation(t.tsTypeReference(t.identifier('InferSelectResult'), t.tsTypeParameterInstantiation([
|
|
198
|
-
t.tsTypeReference(t.identifier(relationTypeName)),
|
|
199
|
-
t.tsTypeReference(t.identifier('S')),
|
|
167
|
+
// Reusable type reference factories
|
|
168
|
+
const sRef = () => t.tsTypeReference(t.identifier('S'));
|
|
169
|
+
const selectRef = () => t.tsTypeReference(t.identifier(selectTypeName));
|
|
170
|
+
const pkTsType = () => tsTypeFromPrimitive(pkField.tsType);
|
|
171
|
+
// ── findMany ───────────────────────────────────────────────────────────
|
|
172
|
+
{
|
|
173
|
+
const argsType = (sel) => t.tsTypeReference(t.identifier('FindManyArgs'), t.tsTypeParameterInstantiation([
|
|
174
|
+
sel,
|
|
175
|
+
t.tsTypeReference(t.identifier(whereTypeName)),
|
|
176
|
+
t.tsTypeReference(t.identifier(orderByTypeName)),
|
|
177
|
+
]));
|
|
178
|
+
const retType = (sel) => t.tsTypeAnnotation(t.tsTypeReference(t.identifier('QueryBuilder'), t.tsTypeParameterInstantiation([
|
|
179
|
+
t.tsTypeLiteral([
|
|
180
|
+
t.tsPropertySignature(t.identifier(pluralQueryName), t.tsTypeAnnotation(t.tsTypeReference(t.identifier('ConnectionResult'), t.tsTypeParameterInstantiation([
|
|
181
|
+
t.tsTypeReference(t.identifier('InferSelectResult'), t.tsTypeParameterInstantiation([
|
|
182
|
+
t.tsTypeReference(t.identifier(relationTypeName)),
|
|
183
|
+
sel,
|
|
184
|
+
])),
|
|
200
185
|
])))),
|
|
201
|
-
])
|
|
202
|
-
])
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
t.
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
186
|
+
]),
|
|
187
|
+
])));
|
|
188
|
+
// Overload 1: with select (autocompletion)
|
|
189
|
+
const o1Param = t.identifier('args');
|
|
190
|
+
o1Param.typeAnnotation = t.tsTypeAnnotation(t.tsIntersectionType([
|
|
191
|
+
argsType(sRef()),
|
|
192
|
+
t.tsTypeLiteral([requiredSelectProp()]),
|
|
193
|
+
strictSelectGuard(selectTypeName),
|
|
194
|
+
]));
|
|
195
|
+
classBody.push(createDeclareMethod('findMany', createTypeParam(selectTypeName), [o1Param], retType(sRef())));
|
|
196
|
+
// Implementation
|
|
197
|
+
const implParam = t.identifier('args');
|
|
198
|
+
implParam.typeAnnotation = t.tsTypeAnnotation(argsType(selectRef()));
|
|
199
|
+
const selectExpr = t.memberExpression(t.identifier('args'), t.identifier('select'));
|
|
200
|
+
const bodyArgs = [
|
|
201
|
+
t.stringLiteral(typeName),
|
|
202
|
+
t.stringLiteral(pluralQueryName),
|
|
203
|
+
selectExpr,
|
|
204
|
+
t.objectExpression([
|
|
205
|
+
t.objectProperty(t.identifier('where'), t.optionalMemberExpression(t.identifier('args'), t.identifier('where'), false, true)),
|
|
206
|
+
t.objectProperty(t.identifier('orderBy'), t.tsAsExpression(t.optionalMemberExpression(t.identifier('args'), t.identifier('orderBy'), false, true), t.tsUnionType([
|
|
207
|
+
t.tsArrayType(t.tsStringKeyword()),
|
|
208
|
+
t.tsUndefinedKeyword(),
|
|
209
|
+
]))),
|
|
210
|
+
t.objectProperty(t.identifier('first'), t.optionalMemberExpression(t.identifier('args'), t.identifier('first'), false, true)),
|
|
211
|
+
t.objectProperty(t.identifier('last'), t.optionalMemberExpression(t.identifier('args'), t.identifier('last'), false, true)),
|
|
212
|
+
t.objectProperty(t.identifier('after'), t.optionalMemberExpression(t.identifier('args'), t.identifier('after'), false, true)),
|
|
213
|
+
t.objectProperty(t.identifier('before'), t.optionalMemberExpression(t.identifier('args'), t.identifier('before'), false, true)),
|
|
214
|
+
t.objectProperty(t.identifier('offset'), t.optionalMemberExpression(t.identifier('args'), t.identifier('offset'), false, true)),
|
|
215
|
+
]),
|
|
216
|
+
t.stringLiteral(whereTypeName),
|
|
217
|
+
t.stringLiteral(orderByTypeName),
|
|
218
|
+
t.identifier('connectionFieldsMap'),
|
|
219
|
+
];
|
|
220
|
+
classBody.push(createClassMethod('findMany', null, [implParam], null, buildMethodBody('buildFindManyDocument', bodyArgs, 'query', typeName, pluralQueryName)));
|
|
221
|
+
}
|
|
222
|
+
// ── findFirst ──────────────────────────────────────────────────────────
|
|
223
|
+
{
|
|
224
|
+
const argsType = (sel) => t.tsTypeReference(t.identifier('FindFirstArgs'), t.tsTypeParameterInstantiation([
|
|
225
|
+
sel,
|
|
226
|
+
t.tsTypeReference(t.identifier(whereTypeName)),
|
|
227
|
+
]));
|
|
228
|
+
const retType = (sel) => t.tsTypeAnnotation(t.tsTypeReference(t.identifier('QueryBuilder'), t.tsTypeParameterInstantiation([
|
|
229
|
+
t.tsTypeLiteral([
|
|
230
|
+
t.tsPropertySignature(t.identifier(pluralQueryName), t.tsTypeAnnotation(t.tsTypeLiteral([
|
|
231
|
+
t.tsPropertySignature(t.identifier('nodes'), t.tsTypeAnnotation(t.tsArrayType(t.tsTypeReference(t.identifier('InferSelectResult'), t.tsTypeParameterInstantiation([
|
|
232
|
+
t.tsTypeReference(t.identifier(relationTypeName)),
|
|
233
|
+
sel,
|
|
234
|
+
]))))),
|
|
235
|
+
]))),
|
|
236
|
+
]),
|
|
237
|
+
])));
|
|
238
|
+
// Overload 1: with select (autocompletion)
|
|
239
|
+
const o1Param = t.identifier('args');
|
|
240
|
+
o1Param.typeAnnotation = t.tsTypeAnnotation(t.tsIntersectionType([
|
|
241
|
+
argsType(sRef()),
|
|
242
|
+
t.tsTypeLiteral([requiredSelectProp()]),
|
|
243
|
+
strictSelectGuard(selectTypeName),
|
|
244
|
+
]));
|
|
245
|
+
classBody.push(createDeclareMethod('findFirst', createTypeParam(selectTypeName), [o1Param], retType(sRef())));
|
|
246
|
+
// Implementation
|
|
247
|
+
const implParam = t.identifier('args');
|
|
248
|
+
implParam.typeAnnotation = t.tsTypeAnnotation(argsType(selectRef()));
|
|
249
|
+
const selectExpr = t.memberExpression(t.identifier('args'), t.identifier('select'));
|
|
250
|
+
const bodyArgs = [
|
|
251
|
+
t.stringLiteral(typeName),
|
|
252
|
+
t.stringLiteral(pluralQueryName),
|
|
253
|
+
selectExpr,
|
|
254
|
+
t.objectExpression([
|
|
255
|
+
t.objectProperty(t.identifier('where'), t.optionalMemberExpression(t.identifier('args'), t.identifier('where'), false, true)),
|
|
256
|
+
]),
|
|
257
|
+
t.stringLiteral(whereTypeName),
|
|
258
|
+
t.identifier('connectionFieldsMap'),
|
|
259
|
+
];
|
|
260
|
+
classBody.push(createClassMethod('findFirst', null, [implParam], null, buildMethodBody('buildFindFirstDocument', bodyArgs, 'query', typeName, pluralQueryName)));
|
|
261
|
+
}
|
|
262
|
+
// ── findOne ────────────────────────────────────────────────────────────
|
|
263
|
+
const singleQueryName = table.query?.one;
|
|
264
|
+
if (singleQueryName && (0, utils_1.hasValidPrimaryKey)(table)) {
|
|
265
|
+
const pkGqlType = pkField.gqlType.replace(/!/g, '') + '!';
|
|
266
|
+
const retType = (sel) => t.tsTypeAnnotation(t.tsTypeReference(t.identifier('QueryBuilder'), t.tsTypeParameterInstantiation([
|
|
267
|
+
t.tsTypeLiteral([
|
|
268
|
+
t.tsPropertySignature(t.identifier(singleQueryName), t.tsTypeAnnotation(t.tsUnionType([
|
|
269
|
+
t.tsTypeReference(t.identifier('InferSelectResult'), t.tsTypeParameterInstantiation([
|
|
270
|
+
t.tsTypeReference(t.identifier(relationTypeName)),
|
|
271
|
+
sel,
|
|
272
|
+
])),
|
|
273
|
+
t.tsNullKeyword(),
|
|
274
|
+
]))),
|
|
275
|
+
]),
|
|
276
|
+
])));
|
|
277
|
+
const pkProp = () => {
|
|
278
|
+
const prop = t.tsPropertySignature(t.identifier(pkField.name), t.tsTypeAnnotation(pkTsType()));
|
|
279
|
+
prop.optional = false;
|
|
280
|
+
return prop;
|
|
281
|
+
};
|
|
282
|
+
// Overload 1: with select (autocompletion)
|
|
283
|
+
const o1Param = t.identifier('args');
|
|
284
|
+
o1Param.typeAnnotation = t.tsTypeAnnotation(t.tsIntersectionType([
|
|
285
|
+
t.tsTypeLiteral([pkProp(), requiredSelectProp()]),
|
|
286
|
+
strictSelectGuard(selectTypeName),
|
|
287
|
+
]));
|
|
288
|
+
classBody.push(createDeclareMethod('findOne', createTypeParam(selectTypeName), [o1Param], retType(sRef())));
|
|
289
|
+
// Implementation
|
|
290
|
+
const implParam = t.identifier('args');
|
|
291
|
+
implParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeLiteral([
|
|
292
|
+
pkProp(),
|
|
293
|
+
(() => {
|
|
294
|
+
const prop = t.tsPropertySignature(t.identifier('select'), t.tsTypeAnnotation(t.tsTypeReference(t.identifier(selectTypeName))));
|
|
295
|
+
return prop;
|
|
296
|
+
})(),
|
|
297
|
+
]));
|
|
298
|
+
const selectExpr = t.memberExpression(t.identifier('args'), t.identifier('select'));
|
|
299
|
+
const bodyArgs = [
|
|
300
|
+
t.stringLiteral(typeName),
|
|
301
|
+
t.stringLiteral(singleQueryName),
|
|
302
|
+
t.memberExpression(t.identifier('args'), t.identifier(pkField.name)),
|
|
303
|
+
selectExpr,
|
|
304
|
+
t.stringLiteral(pkField.name),
|
|
305
|
+
t.stringLiteral(pkGqlType),
|
|
306
|
+
t.identifier('connectionFieldsMap'),
|
|
307
|
+
];
|
|
308
|
+
classBody.push(createClassMethod('findOne', null, [implParam], null, buildMethodBody('buildFindOneDocument', bodyArgs, 'query', typeName, singleQueryName)));
|
|
309
|
+
}
|
|
310
|
+
// ── create ─────────────────────────────────────────────────────────────
|
|
311
|
+
{
|
|
312
|
+
const dataType = () => t.tsIndexedAccessType(t.tsTypeReference(t.identifier(createInputTypeName)), t.tsLiteralType(t.stringLiteral(singularName)));
|
|
313
|
+
const argsType = (sel) => t.tsTypeReference(t.identifier('CreateArgs'), t.tsTypeParameterInstantiation([sel, dataType()]));
|
|
314
|
+
const retType = (sel) => t.tsTypeAnnotation(t.tsTypeReference(t.identifier('QueryBuilder'), t.tsTypeParameterInstantiation([
|
|
315
|
+
t.tsTypeLiteral([
|
|
316
|
+
t.tsPropertySignature(t.identifier(createMutationName), t.tsTypeAnnotation(t.tsTypeLiteral([
|
|
317
|
+
t.tsPropertySignature(t.identifier(entityLower), t.tsTypeAnnotation(t.tsTypeReference(t.identifier('InferSelectResult'), t.tsTypeParameterInstantiation([
|
|
318
|
+
t.tsTypeReference(t.identifier(relationTypeName)),
|
|
319
|
+
sel,
|
|
320
|
+
])))),
|
|
321
|
+
]))),
|
|
322
|
+
]),
|
|
323
|
+
])));
|
|
324
|
+
// Overload 1: with select (autocompletion)
|
|
325
|
+
const o1Param = t.identifier('args');
|
|
326
|
+
o1Param.typeAnnotation = t.tsTypeAnnotation(t.tsIntersectionType([
|
|
327
|
+
argsType(sRef()),
|
|
328
|
+
t.tsTypeLiteral([requiredSelectProp()]),
|
|
329
|
+
strictSelectGuard(selectTypeName),
|
|
330
|
+
]));
|
|
331
|
+
classBody.push(createDeclareMethod('create', createTypeParam(selectTypeName), [o1Param], retType(sRef())));
|
|
332
|
+
// Implementation
|
|
333
|
+
const implParam = t.identifier('args');
|
|
334
|
+
implParam.typeAnnotation = t.tsTypeAnnotation(argsType(selectRef()));
|
|
335
|
+
const selectExpr = t.memberExpression(t.identifier('args'), t.identifier('select'));
|
|
336
|
+
const bodyArgs = [
|
|
337
|
+
t.stringLiteral(typeName),
|
|
338
|
+
t.stringLiteral(createMutationName),
|
|
339
|
+
t.stringLiteral(entityLower),
|
|
340
|
+
selectExpr,
|
|
341
|
+
t.memberExpression(t.identifier('args'), t.identifier('data')),
|
|
342
|
+
t.stringLiteral(createInputTypeName),
|
|
343
|
+
t.identifier('connectionFieldsMap'),
|
|
344
|
+
];
|
|
345
|
+
classBody.push(createClassMethod('create', null, [implParam], null, buildMethodBody('buildCreateDocument', bodyArgs, 'mutation', typeName, createMutationName)));
|
|
346
|
+
}
|
|
347
|
+
// ── update ─────────────────────────────────────────────────────────────
|
|
214
348
|
if (updateMutationName) {
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
349
|
+
const whereLiteral = () => t.tsTypeLiteral([
|
|
350
|
+
(() => {
|
|
351
|
+
const prop = t.tsPropertySignature(t.identifier(pkField.name), t.tsTypeAnnotation(pkTsType()));
|
|
352
|
+
prop.optional = false;
|
|
353
|
+
return prop;
|
|
354
|
+
})(),
|
|
355
|
+
]);
|
|
356
|
+
const argsType = (sel) => t.tsTypeReference(t.identifier('UpdateArgs'), t.tsTypeParameterInstantiation([
|
|
357
|
+
sel,
|
|
358
|
+
whereLiteral(),
|
|
222
359
|
t.tsTypeReference(t.identifier(patchTypeName)),
|
|
223
|
-
]))
|
|
224
|
-
const
|
|
360
|
+
]));
|
|
361
|
+
const retType = (sel) => t.tsTypeAnnotation(t.tsTypeReference(t.identifier('QueryBuilder'), t.tsTypeParameterInstantiation([
|
|
225
362
|
t.tsTypeLiteral([
|
|
226
363
|
t.tsPropertySignature(t.identifier(updateMutationName), t.tsTypeAnnotation(t.tsTypeLiteral([
|
|
227
364
|
t.tsPropertySignature(t.identifier(entityLower), t.tsTypeAnnotation(t.tsTypeReference(t.identifier('InferSelectResult'), t.tsTypeParameterInstantiation([
|
|
228
365
|
t.tsTypeReference(t.identifier(relationTypeName)),
|
|
229
|
-
|
|
366
|
+
sel,
|
|
230
367
|
])))),
|
|
231
368
|
]))),
|
|
232
369
|
]),
|
|
233
370
|
])));
|
|
234
|
-
|
|
371
|
+
// Overload 1: with select (autocompletion)
|
|
372
|
+
const o1Param = t.identifier('args');
|
|
373
|
+
o1Param.typeAnnotation = t.tsTypeAnnotation(t.tsIntersectionType([
|
|
374
|
+
argsType(sRef()),
|
|
375
|
+
t.tsTypeLiteral([requiredSelectProp()]),
|
|
376
|
+
strictSelectGuard(selectTypeName),
|
|
377
|
+
]));
|
|
378
|
+
classBody.push(createDeclareMethod('update', createTypeParam(selectTypeName), [o1Param], retType(sRef())));
|
|
379
|
+
// Implementation
|
|
380
|
+
const implParam = t.identifier('args');
|
|
381
|
+
implParam.typeAnnotation = t.tsTypeAnnotation(argsType(selectRef()));
|
|
382
|
+
const selectExpr = t.memberExpression(t.identifier('args'), t.identifier('select'));
|
|
383
|
+
const bodyArgs = [
|
|
235
384
|
t.stringLiteral(typeName),
|
|
236
385
|
t.stringLiteral(updateMutationName),
|
|
237
386
|
t.stringLiteral(entityLower),
|
|
238
|
-
|
|
239
|
-
t.memberExpression(t.identifier('args'), t.identifier('where')),
|
|
387
|
+
selectExpr,
|
|
388
|
+
t.memberExpression(t.memberExpression(t.identifier('args'), t.identifier('where')), t.identifier(pkField.name)),
|
|
240
389
|
t.memberExpression(t.identifier('args'), t.identifier('data')),
|
|
241
390
|
t.stringLiteral(updateInputTypeName),
|
|
391
|
+
t.stringLiteral(pkField.name),
|
|
392
|
+
t.identifier('connectionFieldsMap'),
|
|
242
393
|
];
|
|
243
|
-
classBody.push(createClassMethod('update',
|
|
394
|
+
classBody.push(createClassMethod('update', null, [implParam], null, buildMethodBody('buildUpdateByPkDocument', bodyArgs, 'mutation', typeName, updateMutationName)));
|
|
244
395
|
}
|
|
245
|
-
// delete
|
|
396
|
+
// ── delete ─────────────────────────────────────────────────────────────
|
|
246
397
|
if (deleteMutationName) {
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
398
|
+
const whereLiteral = () => t.tsTypeLiteral([
|
|
399
|
+
(() => {
|
|
400
|
+
const prop = t.tsPropertySignature(t.identifier(pkField.name), t.tsTypeAnnotation(pkTsType()));
|
|
401
|
+
prop.optional = false;
|
|
402
|
+
return prop;
|
|
403
|
+
})(),
|
|
404
|
+
]);
|
|
405
|
+
const argsType = (sel) => t.tsTypeReference(t.identifier('DeleteArgs'), t.tsTypeParameterInstantiation([whereLiteral(), sel]));
|
|
406
|
+
const retType = (sel) => t.tsTypeAnnotation(t.tsTypeReference(t.identifier('QueryBuilder'), t.tsTypeParameterInstantiation([
|
|
252
407
|
t.tsTypeLiteral([
|
|
253
408
|
t.tsPropertySignature(t.identifier(deleteMutationName), t.tsTypeAnnotation(t.tsTypeLiteral([
|
|
254
|
-
t.tsPropertySignature(t.identifier(entityLower), t.tsTypeAnnotation(t.
|
|
409
|
+
t.tsPropertySignature(t.identifier(entityLower), t.tsTypeAnnotation(t.tsTypeReference(t.identifier('InferSelectResult'), t.tsTypeParameterInstantiation([
|
|
410
|
+
t.tsTypeReference(t.identifier(relationTypeName)),
|
|
411
|
+
sel,
|
|
412
|
+
])))),
|
|
255
413
|
]))),
|
|
256
414
|
]),
|
|
257
415
|
])));
|
|
258
|
-
|
|
416
|
+
// Overload 1: with select (autocompletion)
|
|
417
|
+
const o1Param = t.identifier('args');
|
|
418
|
+
o1Param.typeAnnotation = t.tsTypeAnnotation(t.tsIntersectionType([
|
|
419
|
+
argsType(sRef()),
|
|
420
|
+
t.tsTypeLiteral([requiredSelectProp()]),
|
|
421
|
+
strictSelectGuard(selectTypeName),
|
|
422
|
+
]));
|
|
423
|
+
classBody.push(createDeclareMethod('delete', createTypeParam(selectTypeName), [o1Param], retType(sRef())));
|
|
424
|
+
// Implementation
|
|
425
|
+
const implParam = t.identifier('args');
|
|
426
|
+
implParam.typeAnnotation = t.tsTypeAnnotation(argsType(selectRef()));
|
|
427
|
+
const selectExpr = t.memberExpression(t.identifier('args'), t.identifier('select'));
|
|
428
|
+
const bodyArgs = [
|
|
259
429
|
t.stringLiteral(typeName),
|
|
260
430
|
t.stringLiteral(deleteMutationName),
|
|
261
431
|
t.stringLiteral(entityLower),
|
|
262
|
-
t.memberExpression(t.identifier('args'), t.identifier('where')),
|
|
432
|
+
t.memberExpression(t.memberExpression(t.identifier('args'), t.identifier('where')), t.identifier(pkField.name)),
|
|
263
433
|
t.stringLiteral(deleteInputTypeName),
|
|
434
|
+
t.stringLiteral(pkField.name),
|
|
435
|
+
selectExpr,
|
|
436
|
+
t.identifier('connectionFieldsMap'),
|
|
264
437
|
];
|
|
265
|
-
classBody.push(createClassMethod('delete', null, [
|
|
438
|
+
classBody.push(createClassMethod('delete', null, [implParam], null, buildMethodBody('buildDeleteByPkDocument', bodyArgs, 'mutation', typeName, deleteMutationName)));
|
|
266
439
|
}
|
|
267
440
|
const classDecl = t.classDeclaration(t.identifier(modelName), null, t.classBody(classBody));
|
|
268
441
|
statements.push(t.exportNamedDeclaration(classDecl));
|
|
269
442
|
const header = (0, utils_1.getGeneratedFileHeader)(`${typeName} model for ORM client`);
|
|
270
443
|
const code = (0, babel_ast_1.generateCode)(statements);
|
|
271
|
-
return {
|
|
444
|
+
return {
|
|
445
|
+
fileName,
|
|
446
|
+
content: header + '\n' + code,
|
|
447
|
+
modelName,
|
|
448
|
+
tableName: table.name,
|
|
449
|
+
};
|
|
272
450
|
}
|
|
273
451
|
function generateAllModelFiles(tables, useSharedTypes) {
|
|
274
452
|
return tables.map((table) => generateModelFile(table, useSharedTypes));
|
|
@@ -47,16 +47,10 @@ export interface NestedSelectConfig {
|
|
|
47
47
|
/**
|
|
48
48
|
* Recursively validates select objects, rejecting unknown keys.
|
|
49
49
|
*
|
|
50
|
-
* This type
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* Why this is needed:
|
|
55
|
-
* TypeScript's excess property checking has a quirk where it only catches
|
|
56
|
-
* invalid fields when they are the ONLY fields. When mixed with valid fields
|
|
57
|
-
* (e.g., `{ id: true, invalidField: true }`), the structural typing allows
|
|
58
|
-
* the excess property through. This type explicitly checks for and rejects
|
|
59
|
-
* such cases.
|
|
50
|
+
* NOTE: This type is intentionally NOT used in generated parameter positions
|
|
51
|
+
* (conditional types block IDE autocompletion). Parameters use `S` directly
|
|
52
|
+
* with `S extends XxxSelect` constraints, which provides full
|
|
53
|
+
* autocompletion via TypeScript's contextual typing.
|
|
60
54
|
*
|
|
61
55
|
* @example
|
|
62
56
|
* // This will cause a type error because 'invalid' doesn't exist:
|
|
@@ -71,12 +65,22 @@ export interface NestedSelectConfig {
|
|
|
71
65
|
export type DeepExact<T, Shape> = T extends Shape ? Exclude<keyof T, keyof Shape> extends never ? {
|
|
72
66
|
[K in keyof T]: K extends keyof Shape ? T[K] extends {
|
|
73
67
|
select: infer NS;
|
|
74
|
-
} ? Shape[K]
|
|
68
|
+
} ? Extract<Shape[K], {
|
|
69
|
+
select?: unknown;
|
|
70
|
+
}> extends {
|
|
75
71
|
select?: infer ShapeNS;
|
|
76
|
-
} ? {
|
|
72
|
+
} ? DeepExact<Omit<T[K], 'select'> & {
|
|
77
73
|
select: DeepExact<NS, NonNullable<ShapeNS>>;
|
|
78
|
-
}
|
|
74
|
+
}, Extract<Shape[K], {
|
|
75
|
+
select?: unknown;
|
|
76
|
+
}>> : never : T[K] : never;
|
|
79
77
|
} : never : never;
|
|
78
|
+
/**
|
|
79
|
+
* Enforces exact select shape while keeping contextual typing on `S extends XxxSelect`.
|
|
80
|
+
* Use this as an intersection in overloads:
|
|
81
|
+
* `{ select: S } & StrictSelect<S, XxxSelect>`.
|
|
82
|
+
*/
|
|
83
|
+
export type StrictSelect<S, Shape> = S extends DeepExact<S, Shape> ? {} : never;
|
|
80
84
|
/**
|
|
81
85
|
* Infers the result type from a select configuration
|
|
82
86
|
*
|
|
@@ -172,8 +176,9 @@ export interface UpdateArgs<TSelect, TWhere, TData> {
|
|
|
172
176
|
/**
|
|
173
177
|
* Arguments for delete operations
|
|
174
178
|
*/
|
|
175
|
-
export interface DeleteArgs<TWhere> {
|
|
179
|
+
export interface DeleteArgs<TWhere, TSelect = undefined> {
|
|
176
180
|
where: TWhere;
|
|
181
|
+
select?: TSelect;
|
|
177
182
|
}
|
|
178
183
|
/**
|
|
179
184
|
* Helper type to get the final result type from a query
|
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Query hook generators using Babel AST-based code generation
|
|
3
|
-
*
|
|
4
|
-
* Output structure:
|
|
5
|
-
* queries/
|
|
6
|
-
* useCarsQuery.ts - List query hook
|
|
7
|
-
* useCarQuery.ts - Single item query hook
|
|
8
|
-
*/
|
|
9
1
|
import type { CleanTable } from '../../types/schema';
|
|
10
2
|
export interface GeneratedQueryFile {
|
|
11
3
|
fileName: string;
|