typesql-cli 0.9.6 → 0.10.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 +2 -3
- package/cli.js +87 -78
- package/cli.js.map +1 -1
- package/code-generator.d.ts +7 -7
- package/code-generator.d.ts.map +1 -1
- package/code-generator.js +257 -193
- package/code-generator.js.map +1 -1
- package/describe-dynamic-query.d.ts +1 -1
- package/describe-dynamic-query.d.ts.map +1 -1
- package/describe-dynamic-query.js +51 -39
- package/describe-dynamic-query.js.map +1 -1
- package/describe-nested-query.d.ts +2 -2
- package/describe-nested-query.d.ts.map +1 -1
- package/describe-nested-query.js +43 -24
- package/describe-nested-query.js.map +1 -1
- package/describe-query.d.ts +4 -4
- package/describe-query.d.ts.map +1 -1
- package/describe-query.js +29 -21
- package/describe-query.js.map +1 -1
- package/drivers/libsql.d.ts +2 -2
- package/drivers/libsql.d.ts.map +1 -1
- package/drivers/libsql.js +3 -3
- package/drivers/libsql.js.map +1 -1
- package/mysql-mapping.d.ts +1 -1
- package/mysql-mapping.d.ts.map +1 -1
- package/mysql-mapping.js +9 -9
- package/mysql-mapping.js.map +1 -1
- package/mysql-query-analyzer/collect-constraints.d.ts +4 -4
- package/mysql-query-analyzer/collect-constraints.d.ts.map +1 -1
- package/mysql-query-analyzer/collect-constraints.js +21 -16
- package/mysql-query-analyzer/collect-constraints.js.map +1 -1
- package/mysql-query-analyzer/infer-column-nullability.d.ts +2 -2
- package/mysql-query-analyzer/infer-column-nullability.d.ts.map +1 -1
- package/mysql-query-analyzer/infer-column-nullability.js +81 -67
- package/mysql-query-analyzer/infer-column-nullability.js.map +1 -1
- package/mysql-query-analyzer/infer-param-nullability.d.ts +2 -2
- package/mysql-query-analyzer/infer-param-nullability.d.ts.map +1 -1
- package/mysql-query-analyzer/infer-param-nullability.js +11 -10
- package/mysql-query-analyzer/infer-param-nullability.js.map +1 -1
- package/mysql-query-analyzer/parse.d.ts +2 -2
- package/mysql-query-analyzer/parse.d.ts.map +1 -1
- package/mysql-query-analyzer/parse.js +39 -32
- package/mysql-query-analyzer/parse.js.map +1 -1
- package/mysql-query-analyzer/select-columns.d.ts +4 -4
- package/mysql-query-analyzer/select-columns.d.ts.map +1 -1
- package/mysql-query-analyzer/select-columns.js +76 -53
- package/mysql-query-analyzer/select-columns.js.map +1 -1
- package/mysql-query-analyzer/traverse.d.ts +4 -4
- package/mysql-query-analyzer/traverse.d.ts.map +1 -1
- package/mysql-query-analyzer/traverse.js +312 -206
- package/mysql-query-analyzer/traverse.js.map +1 -1
- package/mysql-query-analyzer/types.d.ts +5 -5
- package/mysql-query-analyzer/types.d.ts.map +1 -1
- package/mysql-query-analyzer/unify.d.ts +2 -2
- package/mysql-query-analyzer/unify.d.ts.map +1 -1
- package/mysql-query-analyzer/unify.js +533 -491
- package/mysql-query-analyzer/unify.js.map +1 -1
- package/mysql-query-analyzer/util.d.ts.map +1 -1
- package/mysql-query-analyzer/util.js +2 -3
- package/mysql-query-analyzer/util.js.map +1 -1
- package/mysql-query-analyzer/verify-multiple-result.d.ts +2 -2
- package/mysql-query-analyzer/verify-multiple-result.d.ts.map +1 -1
- package/mysql-query-analyzer/verify-multiple-result.js +12 -8
- package/mysql-query-analyzer/verify-multiple-result.js.map +1 -1
- package/package.json +46 -45
- package/queryExectutor.d.ts +4 -4
- package/queryExectutor.d.ts.map +1 -1
- package/queryExectutor.js +11 -13
- package/queryExectutor.js.map +1 -1
- package/sql-generator.d.ts +2 -2
- package/sql-generator.d.ts.map +1 -1
- package/sql-generator.js +29 -25
- package/sql-generator.js.map +1 -1
- package/sqlite-query-analyzer/code-generator.d.ts +5 -5
- package/sqlite-query-analyzer/code-generator.d.ts.map +1 -1
- package/sqlite-query-analyzer/code-generator.js +372 -221
- package/sqlite-query-analyzer/code-generator.js.map +1 -1
- package/sqlite-query-analyzer/parser.d.ts +4 -4
- package/sqlite-query-analyzer/parser.d.ts.map +1 -1
- package/sqlite-query-analyzer/parser.js +30 -17
- package/sqlite-query-analyzer/parser.js.map +1 -1
- package/sqlite-query-analyzer/query-executor.d.ts +5 -5
- package/sqlite-query-analyzer/query-executor.d.ts.map +1 -1
- package/sqlite-query-analyzer/query-executor.js +39 -25
- package/sqlite-query-analyzer/query-executor.js.map +1 -1
- package/sqlite-query-analyzer/replace-list-params.d.ts +1 -1
- package/sqlite-query-analyzer/replace-list-params.d.ts.map +1 -1
- package/sqlite-query-analyzer/replace-list-params.js +4 -3
- package/sqlite-query-analyzer/replace-list-params.js.map +1 -1
- package/sqlite-query-analyzer/sqlite-describe-nested-query.d.ts +4 -4
- package/sqlite-query-analyzer/sqlite-describe-nested-query.d.ts.map +1 -1
- package/sqlite-query-analyzer/sqlite-describe-nested-query.js +33 -18
- package/sqlite-query-analyzer/sqlite-describe-nested-query.js.map +1 -1
- package/sqlite-query-analyzer/traverse.d.ts +5 -5
- package/sqlite-query-analyzer/traverse.d.ts.map +1 -1
- package/sqlite-query-analyzer/traverse.js +249 -160
- package/sqlite-query-analyzer/traverse.js.map +1 -1
- package/ts-dynamic-query-descriptor.d.ts +1 -1
- package/ts-dynamic-query-descriptor.d.ts.map +1 -1
- package/ts-dynamic-query-descriptor.js +4 -4
- package/ts-dynamic-query-descriptor.js.map +1 -1
- package/ts-nested-descriptor.d.ts +4 -4
- package/ts-nested-descriptor.d.ts.map +1 -1
- package/ts-nested-descriptor.js +11 -11
- package/ts-nested-descriptor.js.map +1 -1
- package/types.d.ts +13 -14
- package/types.d.ts.map +1 -1
- package/util.d.ts.map +1 -1
- package/util.js.map +1 -1
- package/utility-types.d.ts.map +1 -1
@@ -12,7 +12,7 @@ const ts_nested_descriptor_1 = require("../ts-nested-descriptor");
|
|
12
12
|
const describe_query_1 = require("../describe-query");
|
13
13
|
const query_executor_1 = require("./query-executor");
|
14
14
|
const ts_dynamic_query_descriptor_1 = require("../ts-dynamic-query-descriptor");
|
15
|
-
const
|
15
|
+
const node_os_1 = require("node:os");
|
16
16
|
function validateAndGenerateCode(client, sql, queryName, sqliteDbSchema, isCrud = false) {
|
17
17
|
const { sql: processedSql } = (0, describe_query_1.preprocessSql)(sql);
|
18
18
|
const explainSqlResult = (0, query_executor_1.explainSql)(client.client, processedSql);
|
@@ -22,12 +22,14 @@ function validateAndGenerateCode(client, sql, queryName, sqliteDbSchema, isCrud
|
|
22
22
|
description: explainSqlResult.left.description
|
23
23
|
});
|
24
24
|
}
|
25
|
-
const code = generateTsCode(sql, queryName, sqliteDbSchema,
|
25
|
+
const code = generateTsCode(sql, queryName, sqliteDbSchema, client.type, isCrud);
|
26
26
|
return code;
|
27
27
|
}
|
28
28
|
exports.validateAndGenerateCode = validateAndGenerateCode;
|
29
29
|
function mapToColumnInfo(col, checkOptional) {
|
30
|
-
const defaultValue = col.columnKey
|
30
|
+
const defaultValue = col.columnKey === 'PRI' && col.column_type === 'INTEGER'
|
31
|
+
? 'AUTOINCREMENT'
|
32
|
+
: col.defaultValue;
|
31
33
|
const columnInfo = {
|
32
34
|
columnName: col.column,
|
33
35
|
notNull: col.notNull,
|
@@ -37,24 +39,28 @@ function mapToColumnInfo(col, checkOptional) {
|
|
37
39
|
};
|
38
40
|
return columnInfo;
|
39
41
|
}
|
40
|
-
function generateCrud(client
|
41
|
-
const columns = dbSchema.filter(col => col.table
|
42
|
-
const columnInfo = columns.map(col => mapToColumnInfo(col, queryType
|
43
|
-
const keys = columns.filter(col => col.columnKey
|
44
|
-
if (keys.length
|
45
|
-
keys.push(...columns.filter(col => col.columnKey
|
46
|
-
}
|
47
|
-
const keyColumnInfo = keys
|
42
|
+
function generateCrud(client, queryType, tableName, dbSchema) {
|
43
|
+
const columns = dbSchema.filter((col) => col.table === tableName);
|
44
|
+
const columnInfo = columns.map((col) => mapToColumnInfo(col, queryType === 'Insert' || queryType === 'Update'));
|
45
|
+
const keys = columns.filter((col) => col.columnKey === 'PRI');
|
46
|
+
if (keys.length === 0) {
|
47
|
+
keys.push(...columns.filter((col) => col.columnKey === 'UNI'));
|
48
|
+
}
|
49
|
+
const keyColumnInfo = keys
|
50
|
+
.map((key) => mapToColumnInfo(key, false))
|
51
|
+
.map((col) => mapColumnToTsFieldDescriptor(col, client));
|
48
52
|
const resultColumns = mapColumns(client, queryType, columnInfo, false);
|
49
|
-
const params = columnInfo.map(col => mapColumnToTsFieldDescriptor(col, client));
|
53
|
+
const params = columnInfo.map((col) => mapColumnToTsFieldDescriptor(col, client));
|
50
54
|
const tsDescriptor = {
|
51
55
|
sql: '',
|
52
56
|
queryType,
|
53
57
|
multipleRowsResult: false,
|
54
58
|
columns: resultColumns,
|
55
59
|
parameterNames: [],
|
56
|
-
parameters: queryType
|
57
|
-
data: queryType
|
60
|
+
parameters: queryType === 'Insert' ? params : keyColumnInfo,
|
61
|
+
data: queryType === 'Update'
|
62
|
+
? params.filter((param) => { var _a; return param.name !== ((_a = keyColumnInfo[0]) === null || _a === void 0 ? void 0 : _a.name); })
|
63
|
+
: []
|
58
64
|
};
|
59
65
|
const queryName = getQueryName(queryType, tableName);
|
60
66
|
const code = generateCodeFromTsDescriptor(client, queryName, tsDescriptor, true, tableName);
|
@@ -65,17 +71,17 @@ function getQueryName(queryType, tableName) {
|
|
65
71
|
const camelCaseName = (0, code_generator_1.convertToCamelCaseName)(tableName);
|
66
72
|
const captitalizedName = (0, code_generator_1.capitalize)(camelCaseName);
|
67
73
|
switch (queryType) {
|
68
|
-
case
|
69
|
-
return
|
70
|
-
case
|
71
|
-
return
|
72
|
-
case
|
73
|
-
return
|
74
|
-
case
|
75
|
-
return
|
74
|
+
case 'Select':
|
75
|
+
return `selectFrom${captitalizedName}`;
|
76
|
+
case 'Insert':
|
77
|
+
return `insertInto${captitalizedName}`;
|
78
|
+
case 'Update':
|
79
|
+
return `update${captitalizedName}`;
|
80
|
+
case 'Delete':
|
81
|
+
return `deleteFrom${captitalizedName}`;
|
76
82
|
}
|
77
83
|
}
|
78
|
-
function generateTsCode(sql, queryName, sqliteDbSchema, isCrud = false
|
84
|
+
function generateTsCode(sql, queryName, sqliteDbSchema, client, isCrud = false) {
|
79
85
|
const schemaDefResult = (0, parser_1.parseSql)(sql, sqliteDbSchema);
|
80
86
|
if ((0, Either_1.isLeft)(schemaDefResult)) {
|
81
87
|
return schemaDefResult;
|
@@ -94,17 +100,17 @@ function createTsDescriptor(queryInfo, client) {
|
|
94
100
|
returning: queryInfo.returning,
|
95
101
|
columns: mapColumns(client, queryInfo.queryType, queryInfo.columns, queryInfo.returning),
|
96
102
|
parameterNames: [],
|
97
|
-
parameters: queryInfo.parameters.map(param => mapParameterToTsFieldDescriptor(param, client)),
|
98
|
-
data: (_a = queryInfo.data) === null || _a === void 0 ? void 0 : _a.map(param => mapParameterToTsFieldDescriptor(param, client)),
|
103
|
+
parameters: queryInfo.parameters.map((param) => mapParameterToTsFieldDescriptor(param, client)),
|
104
|
+
data: (_a = queryInfo.data) === null || _a === void 0 ? void 0 : _a.map((param) => mapParameterToTsFieldDescriptor(param, client)),
|
99
105
|
orderByColumns: queryInfo.orderByColumns
|
100
106
|
};
|
101
107
|
if (queryInfo.nestedInfo) {
|
102
|
-
const nestedDescriptor2 = queryInfo.nestedInfo.map(relation => {
|
108
|
+
const nestedDescriptor2 = queryInfo.nestedInfo.map((relation) => {
|
103
109
|
const tsRelation = {
|
104
110
|
groupIndex: relation.groupIndex,
|
105
111
|
name: relation.name,
|
106
|
-
fields: relation.fields.map(field => mapFieldToTsField(queryInfo.columns, field, client)),
|
107
|
-
relations: relation.relations.map(relation => (0, ts_nested_descriptor_1.mapToTsRelation2)(relation))
|
112
|
+
fields: relation.fields.map((field) => mapFieldToTsField(queryInfo.columns, field, client)),
|
113
|
+
relations: relation.relations.map((relation) => (0, ts_nested_descriptor_1.mapToTsRelation2)(relation))
|
108
114
|
};
|
109
115
|
return tsRelation;
|
110
116
|
});
|
@@ -138,13 +144,17 @@ function mapColumns(client, queryType, columns, returning = false) {
|
|
138
144
|
notNull: true
|
139
145
|
}
|
140
146
|
];
|
141
|
-
if (queryType
|
142
|
-
return client
|
147
|
+
if (queryType === 'Insert' && !returning) {
|
148
|
+
return client === 'better-sqlite3'
|
149
|
+
? sqliteInsertColumns
|
150
|
+
: libSqlInsertColumns;
|
143
151
|
}
|
144
|
-
if (queryType
|
145
|
-
return client
|
152
|
+
if (queryType === 'Update' || queryType === 'Delete') {
|
153
|
+
return client === 'better-sqlite3'
|
154
|
+
? [sqliteInsertColumns[0]]
|
155
|
+
: [libSqlInsertColumns[0]];
|
146
156
|
}
|
147
|
-
const escapedColumnsNames = (0, code_generator_1.renameInvalidNames)(columns.map(col => col.columnName));
|
157
|
+
const escapedColumnsNames = (0, code_generator_1.renameInvalidNames)(columns.map((col) => col.columnName));
|
148
158
|
return columns.map((col, index) => mapColumnToTsFieldDescriptor(Object.assign(Object.assign({}, col), { columnName: escapedColumnsNames[index] }), client));
|
149
159
|
}
|
150
160
|
function mapFieldToTsField(columns, field, client) {
|
@@ -194,7 +204,7 @@ function mapColumnType(sqliteType, client) {
|
|
194
204
|
case 'DATE':
|
195
205
|
return 'Date';
|
196
206
|
case 'BLOB':
|
197
|
-
return client
|
207
|
+
return client === 'better-sqlite3' ? 'Uint8Array' : 'ArrayBuffer';
|
198
208
|
}
|
199
209
|
}
|
200
210
|
function generateCodeFromTsDescriptor(client, queryName, tsDescriptor, isCrud = false, tableName = '') {
|
@@ -206,35 +216,46 @@ function generateCodeFromTsDescriptor(client, queryName, tsDescriptor, isCrud =
|
|
206
216
|
const capitalizedName = (0, code_generator_1.capitalize)(camelCaseName);
|
207
217
|
const queryType = tsDescriptor.queryType;
|
208
218
|
const sql = tsDescriptor.sql;
|
209
|
-
const dataTypeName = capitalizedName
|
210
|
-
const paramsTypeName = capitalizedName
|
211
|
-
const resultTypeName = capitalizedName
|
212
|
-
const dynamicParamsTypeName = capitalizedName
|
213
|
-
const selectColumnsTypeName = capitalizedName
|
214
|
-
const whereTypeName = capitalizedName
|
215
|
-
const orderByTypeName = capitalizedName
|
216
|
-
const generateOrderBy = tsDescriptor.orderByColumns != null &&
|
219
|
+
const dataTypeName = `${capitalizedName}Data`;
|
220
|
+
const paramsTypeName = `${capitalizedName}Params`;
|
221
|
+
const resultTypeName = `${capitalizedName}Result`;
|
222
|
+
const dynamicParamsTypeName = `${capitalizedName}DynamicParams`;
|
223
|
+
const selectColumnsTypeName = `${capitalizedName}Select`;
|
224
|
+
const whereTypeName = `${capitalizedName}Where`;
|
225
|
+
const orderByTypeName = `${capitalizedName}OrderBy`;
|
226
|
+
const generateOrderBy = tsDescriptor.orderByColumns != null &&
|
227
|
+
tsDescriptor.orderByColumns.length > 0;
|
217
228
|
const uniqueParams = (0, code_generator_1.removeDuplicatedParameters2)(tsDescriptor.parameters);
|
218
229
|
const uniqueUpdateParams = (0, code_generator_1.removeDuplicatedParameters2)(tsDescriptor.data || []);
|
219
|
-
const orderByField = generateOrderBy
|
220
|
-
|
221
|
-
|
222
|
-
|
230
|
+
const orderByField = generateOrderBy
|
231
|
+
? `orderBy: [${orderByTypeName}, 'asc' | 'desc'][]`
|
232
|
+
: undefined;
|
233
|
+
const paramsTypes = (0, code_generator_1.removeDuplicatedParameters2)(tsDescriptor.dynamicQuery2 == null
|
234
|
+
? tsDescriptor.parameters
|
235
|
+
: (0, ts_dynamic_query_descriptor_1.mapToDynamicParams)(tsDescriptor.parameters));
|
236
|
+
let functionArguments = client === 'better-sqlite3'
|
237
|
+
? 'db: Database'
|
238
|
+
: 'client: Client | Transaction';
|
239
|
+
functionArguments += queryType === 'Update' ? `, data: ${dataTypeName}` : '';
|
223
240
|
if (tsDescriptor.dynamicQuery2 == null) {
|
224
|
-
functionArguments +=
|
241
|
+
functionArguments +=
|
242
|
+
tsDescriptor.parameters.length > 0 || generateOrderBy
|
243
|
+
? `, params: ${paramsTypeName}`
|
244
|
+
: '';
|
225
245
|
}
|
226
246
|
else {
|
227
247
|
functionArguments += `, ${orderByField ? 'params' : 'params?'}: ${dynamicParamsTypeName}`;
|
228
248
|
}
|
229
|
-
const orNull = queryType
|
230
|
-
const returnType = tsDescriptor.multipleRowsResult
|
231
|
-
|
232
|
-
|
233
|
-
const
|
234
|
-
|
249
|
+
const orNull = queryType === 'Select' ? ' | null' : '';
|
250
|
+
const returnType = tsDescriptor.multipleRowsResult
|
251
|
+
? `${resultTypeName}[]`
|
252
|
+
: `${resultTypeName}${orNull}`;
|
253
|
+
const allParameters = (((_a = tsDescriptor.data) === null || _a === void 0 ? void 0 : _a.map((param) => fromDriver('data', param))) || []).concat(tsDescriptor.parameters.map((param) => fromDriver('params', param)));
|
254
|
+
const queryParams = allParameters.length > 0 ? `[${allParameters.join(', ')}]` : '';
|
255
|
+
if (client === 'better-sqlite3') {
|
235
256
|
writer.writeLine(`import type { Database } from 'better-sqlite3';`);
|
236
257
|
}
|
237
|
-
if (client
|
258
|
+
if (client === 'libsql') {
|
238
259
|
writer.writeLine(`import type { Client, Transaction } from '@libsql/client';`);
|
239
260
|
}
|
240
261
|
if (tsDescriptor.dynamicQuery2 != null) {
|
@@ -252,11 +273,13 @@ function generateCodeFromTsDescriptor(client, queryName, tsDescriptor, isCrud =
|
|
252
273
|
});
|
253
274
|
writer.blankLine();
|
254
275
|
(0, code_generator_1.writeTypeBlock)(writer, paramsTypes, paramsTypeName, false, tsDescriptor.dynamicQuery2 ? undefined : orderByField);
|
255
|
-
const resultTypes = tsDescriptor.dynamicQuery2 == null
|
276
|
+
const resultTypes = tsDescriptor.dynamicQuery2 == null
|
277
|
+
? tsDescriptor.columns
|
278
|
+
: (0, ts_dynamic_query_descriptor_1.mapToDynamicResultColumns)(tsDescriptor.columns);
|
256
279
|
(0, code_generator_1.writeTypeBlock)(writer, resultTypes, resultTypeName, false);
|
257
280
|
const selectFields = (0, ts_dynamic_query_descriptor_1.mapToDynamicSelectColumns)(tsDescriptor.columns);
|
258
281
|
(0, code_generator_1.writeTypeBlock)(writer, selectFields, selectColumnsTypeName, false);
|
259
|
-
writer.write(
|
282
|
+
writer.write('const selectFragments = ').inlineBlock(() => {
|
260
283
|
var _a;
|
261
284
|
(_a = tsDescriptor.dynamicQuery2) === null || _a === void 0 ? void 0 : _a.select.forEach((fragment, index) => {
|
262
285
|
const field = tsDescriptor.columns[index].name;
|
@@ -266,7 +289,7 @@ function generateCodeFromTsDescriptor(client, queryName, tsDescriptor, isCrud =
|
|
266
289
|
writer.write(' as const;');
|
267
290
|
writer.blankLine();
|
268
291
|
writer.writeLine(`const NumericOperatorList = ['=', '<>', '>', '<', '>=', '<='] as const;`);
|
269
|
-
writer.writeLine(
|
292
|
+
writer.writeLine('type NumericOperator = typeof NumericOperatorList[number];');
|
270
293
|
if ((0, code_generator_1.hasStringColumn)(tsDescriptor.columns)) {
|
271
294
|
writer.writeLine(`type StringOperator = '=' | '<>' | '>' | '<' | '>=' | '<=' | 'LIKE';`);
|
272
295
|
}
|
@@ -274,20 +297,24 @@ function generateCodeFromTsDescriptor(client, queryName, tsDescriptor, isCrud =
|
|
274
297
|
writer.writeLine(`type BetweenOperator = 'BETWEEN';`);
|
275
298
|
writer.blankLine();
|
276
299
|
writer.write(`export type ${whereTypeName} =`).indent(() => {
|
277
|
-
tsDescriptor.columns.forEach(col => {
|
300
|
+
tsDescriptor.columns.forEach((col) => {
|
278
301
|
writer.writeLine(`| ['${col.name}', ${(0, code_generator_1.getOperator)(col.tsType)}, ${col.tsType} | null]`);
|
279
302
|
writer.writeLine(`| ['${col.name}', SetOperator, ${col.tsType}[]]`);
|
280
303
|
writer.writeLine(`| ['${col.name}', BetweenOperator, ${col.tsType} | null, ${col.tsType} | null]`);
|
281
304
|
});
|
282
305
|
});
|
283
306
|
writer.blankLine();
|
284
|
-
const asyncModified = client
|
285
|
-
const returnTypeModifier = client
|
286
|
-
writer
|
307
|
+
const asyncModified = client === 'libsql' ? 'async ' : '';
|
308
|
+
const returnTypeModifier = client === 'libsql' ? `Promise<${returnType}>` : returnType;
|
309
|
+
writer
|
310
|
+
.write(`export ${asyncModified}function ${camelCaseName}(${functionArguments}): ${returnTypeModifier}`)
|
311
|
+
.block(() => {
|
287
312
|
var _a, _b, _c, _d, _e, _f;
|
288
|
-
writer
|
313
|
+
writer
|
314
|
+
.write('const where = whereConditionsToObject(params?.where);')
|
315
|
+
.newLine();
|
289
316
|
if (orderByField != null) {
|
290
|
-
writer.writeLine(
|
317
|
+
writer.writeLine('const orderBy = orderByToObject(params.orderBy);');
|
291
318
|
}
|
292
319
|
writer.write('const paramsValues: any = [];').newLine();
|
293
320
|
const hasCte = (((_a = tsDescriptor.dynamicQuery2) === null || _a === void 0 ? void 0 : _a.with.length) || 0) > 0;
|
@@ -295,79 +322,97 @@ function generateCodeFromTsDescriptor(client, queryName, tsDescriptor, isCrud =
|
|
295
322
|
writer.writeLine(`let withClause = '';`);
|
296
323
|
(_b = tsDescriptor.dynamicQuery2) === null || _b === void 0 ? void 0 : _b.with.forEach((withFragment, index) => {
|
297
324
|
var _a;
|
298
|
-
const selectConditions = withFragment.dependOnFields.map(fieldIndex =>
|
325
|
+
const selectConditions = withFragment.dependOnFields.map((fieldIndex) => `params.select.${tsDescriptor.columns[fieldIndex].name}`);
|
299
326
|
if (selectConditions.length > 0) {
|
300
327
|
selectConditions.unshift('params?.select == null');
|
301
328
|
}
|
302
|
-
const whereConditions = withFragment.dependOnFields.map(fieldIndex =>
|
303
|
-
const orderByConditions = ((_a = withFragment.dependOnOrderBy) === null || _a === void 0 ? void 0 : _a.map(orderBy =>
|
304
|
-
const allConditions = [
|
305
|
-
|
306
|
-
|
329
|
+
const whereConditions = withFragment.dependOnFields.map((fieldIndex) => `where.${tsDescriptor.columns[fieldIndex].name} != null`);
|
330
|
+
const orderByConditions = ((_a = withFragment.dependOnOrderBy) === null || _a === void 0 ? void 0 : _a.map((orderBy) => `orderBy['${orderBy}'] != null`)) || [];
|
331
|
+
const allConditions = [
|
332
|
+
...selectConditions,
|
333
|
+
...whereConditions,
|
334
|
+
...orderByConditions
|
335
|
+
];
|
336
|
+
const paramValues = withFragment.parameters.map((param) => `params?.params?.${param}`);
|
337
|
+
writer
|
338
|
+
.write(`if (${allConditions.join(`${node_os_1.EOL}\t|| `)})`)
|
339
|
+
.block(() => {
|
307
340
|
writer.write(`withClause += EOL + \`${withFragment.fragment}\`;`);
|
308
|
-
paramValues.forEach(paramValues => {
|
341
|
+
paramValues.forEach((paramValues) => {
|
309
342
|
writer.writeLine(`paramsValues.push(${paramValues});`);
|
310
343
|
});
|
311
344
|
});
|
312
345
|
});
|
313
|
-
writer
|
346
|
+
writer
|
347
|
+
.write(`let sql = 'WITH ' + withClause + EOL + 'SELECT';`)
|
348
|
+
.newLine();
|
314
349
|
}
|
315
350
|
else {
|
316
351
|
writer.write(`let sql = 'SELECT';`).newLine();
|
317
352
|
}
|
318
353
|
(_c = tsDescriptor.dynamicQuery2) === null || _c === void 0 ? void 0 : _c.select.forEach((select, index) => {
|
319
|
-
writer
|
354
|
+
writer
|
355
|
+
.write(`if (params?.select == null || params.select.${tsDescriptor.columns[index].name})`)
|
356
|
+
.block(() => {
|
320
357
|
writer.writeLine(`sql = appendSelect(sql, \`${select.fragment}\`);`);
|
321
|
-
select.parameters.forEach(param => {
|
358
|
+
select.parameters.forEach((param) => {
|
322
359
|
writer.writeLine(`paramsValues.push(params?.params?.${param} ?? null);`);
|
323
360
|
});
|
324
361
|
});
|
325
362
|
});
|
326
363
|
(_d = tsDescriptor.dynamicQuery2) === null || _d === void 0 ? void 0 : _d.from.forEach((from, index) => {
|
327
364
|
var _a;
|
328
|
-
if (index
|
365
|
+
if (index === 0) {
|
329
366
|
writer.writeLine(`sql += EOL + \`${from.fragment}\`;`);
|
330
367
|
}
|
331
368
|
else {
|
332
|
-
const selectConditions = from.dependOnFields.map(fieldIndex =>
|
369
|
+
const selectConditions = from.dependOnFields.map((fieldIndex) => `params.select.${tsDescriptor.columns[fieldIndex].name}`);
|
333
370
|
if (selectConditions.length > 0) {
|
334
371
|
selectConditions.unshift('params?.select == null');
|
335
372
|
}
|
336
|
-
const whereConditions = from.dependOnFields.map(fieldIndex =>
|
337
|
-
const orderByConditions = ((_a = from.dependOnOrderBy) === null || _a === void 0 ? void 0 : _a.map(orderBy =>
|
338
|
-
const allConditions = [
|
339
|
-
|
340
|
-
|
373
|
+
const whereConditions = from.dependOnFields.map((fieldIndex) => `where.${tsDescriptor.columns[fieldIndex].name} != null`);
|
374
|
+
const orderByConditions = ((_a = from.dependOnOrderBy) === null || _a === void 0 ? void 0 : _a.map((orderBy) => `orderBy['${orderBy}'] != null`)) || [];
|
375
|
+
const allConditions = [
|
376
|
+
...selectConditions,
|
377
|
+
...whereConditions,
|
378
|
+
...orderByConditions
|
379
|
+
];
|
380
|
+
const paramValues = from.parameters.map((param) => `params?.params?.${param}`);
|
381
|
+
writer
|
382
|
+
.write(`if (${allConditions.join(`${node_os_1.EOL}\t|| `)})`)
|
383
|
+
.block(() => {
|
341
384
|
writer.write(`sql += EOL + \`${from.fragment}\`;`);
|
342
|
-
paramValues.forEach(paramValues => {
|
385
|
+
paramValues.forEach((paramValues) => {
|
343
386
|
writer.writeLine(`paramsValues.push(${paramValues});`);
|
344
387
|
});
|
345
388
|
});
|
346
389
|
}
|
347
390
|
});
|
348
|
-
writer.writeLine(
|
349
|
-
(_e = tsDescriptor.dynamicQuery2) === null || _e === void 0 ? void 0 : _e.where.forEach(fragment => {
|
350
|
-
const paramValues = fragment.parameters.map(param =>
|
391
|
+
writer.writeLine('sql += EOL + `WHERE 1 = 1`;');
|
392
|
+
(_e = tsDescriptor.dynamicQuery2) === null || _e === void 0 ? void 0 : _e.where.forEach((fragment) => {
|
393
|
+
const paramValues = fragment.parameters.map((param) => `params?.params?.${param} ?? null`);
|
351
394
|
writer.writeLine(`sql += EOL + \`${fragment.fragment}\`;`);
|
352
|
-
paramValues.forEach(paramValues => {
|
395
|
+
paramValues.forEach((paramValues) => {
|
353
396
|
writer.writeLine(`paramsValues.push(${paramValues});`);
|
354
397
|
});
|
355
398
|
});
|
356
|
-
writer.write(
|
399
|
+
writer.write('params?.where?.forEach(condition => ').inlineBlock(() => {
|
357
400
|
var _a;
|
358
|
-
writer.writeLine(
|
401
|
+
writer.writeLine('const where = whereCondition(condition);');
|
359
402
|
(_a = tsDescriptor.dynamicQuery2) === null || _a === void 0 ? void 0 : _a.select.forEach((select, index) => {
|
360
403
|
if (select.parameters.length > 0) {
|
361
|
-
writer
|
362
|
-
|
404
|
+
writer
|
405
|
+
.write(`if (condition[0] == '${tsDescriptor.columns[index].name}')`)
|
406
|
+
.block(() => {
|
407
|
+
select.parameters.forEach((param) => {
|
363
408
|
writer.writeLine(`paramsValues.push(params?.params?.${param} ?? null);`);
|
364
409
|
});
|
365
410
|
});
|
366
411
|
}
|
367
412
|
});
|
368
|
-
writer.write(
|
413
|
+
writer.write('if (where?.hasValue)').block(() => {
|
369
414
|
writer.writeLine(`sql += EOL + 'AND ' + where.sql;`);
|
370
|
-
writer.write(
|
415
|
+
writer.write('paramsValues.push(...where.values);');
|
371
416
|
});
|
372
417
|
});
|
373
418
|
writer.write(');').newLine();
|
@@ -377,82 +422,102 @@ function generateCodeFromTsDescriptor(client, queryName, tsDescriptor, isCrud =
|
|
377
422
|
const limitOffset = (_f = tsDescriptor.dynamicQuery2) === null || _f === void 0 ? void 0 : _f.limitOffset;
|
378
423
|
if (limitOffset) {
|
379
424
|
writer.writeLine(`sql += EOL + \`${limitOffset.fragment}\`;`);
|
380
|
-
limitOffset.parameters.forEach(param => {
|
425
|
+
limitOffset.parameters.forEach((param) => {
|
381
426
|
writer.writeLine(`paramsValues.push(params?.params?.${param} ?? null);`);
|
382
427
|
});
|
383
428
|
}
|
384
|
-
if (client
|
429
|
+
if (client === 'better-sqlite3') {
|
385
430
|
writer.write('return db.prepare(sql)').newLine();
|
386
431
|
writer.indent().write('.raw(true)').newLine();
|
387
|
-
writer.indent().write(
|
388
|
-
writer
|
432
|
+
writer.indent().write('.all(paramsValues)').newLine();
|
433
|
+
writer
|
434
|
+
.indent()
|
435
|
+
.write(`.map(data => mapArrayTo${resultTypeName}(data, params?.select))${tsDescriptor.multipleRowsResult ? '' : '[0]'};`);
|
389
436
|
}
|
390
|
-
if (client
|
391
|
-
writer
|
437
|
+
if (client === 'libsql') {
|
438
|
+
writer
|
439
|
+
.write('return client.execute({ sql, args: paramsValues })')
|
440
|
+
.newLine();
|
392
441
|
writer.indent().write('.then(res => res.rows)').newLine();
|
393
|
-
writer
|
442
|
+
writer
|
443
|
+
.indent()
|
444
|
+
.write(`.then(rows => rows.map(row => mapArrayTo${resultTypeName}(row, params?.select)))${tsDescriptor.multipleRowsResult ? '' : '[0]'};`);
|
394
445
|
}
|
395
446
|
});
|
396
447
|
writer.blankLine();
|
397
|
-
writer
|
448
|
+
writer
|
449
|
+
.write(`function mapArrayTo${resultTypeName}(data: any, select?: ${selectColumnsTypeName})`)
|
450
|
+
.block(() => {
|
398
451
|
writer.writeLine(`const result = {} as ${resultTypeName};`);
|
399
|
-
writer.writeLine(
|
452
|
+
writer.writeLine('let rowIndex = -1;');
|
400
453
|
tsDescriptor.columns.forEach((tsField) => {
|
401
|
-
writer
|
402
|
-
|
454
|
+
writer
|
455
|
+
.write(`if (select == null || select.${tsField.name})`)
|
456
|
+
.block(() => {
|
457
|
+
writer.writeLine('rowIndex++;');
|
403
458
|
writer.writeLine(`result.${tsField.name} = ${toDriver('data[rowIndex]', tsField)};`);
|
404
459
|
});
|
405
460
|
});
|
406
461
|
writer.write('return result;');
|
407
462
|
});
|
408
463
|
writer.blankLine();
|
409
|
-
writer
|
464
|
+
writer
|
465
|
+
.write('function appendSelect(sql: string, selectField: string)')
|
466
|
+
.block(() => {
|
410
467
|
writer.write(`if (sql == 'SELECT')`).block(() => {
|
411
|
-
writer.writeLine(
|
468
|
+
writer.writeLine('return sql + EOL + selectField;');
|
412
469
|
});
|
413
|
-
writer.write(
|
470
|
+
writer.write('else').block(() => {
|
414
471
|
writer.writeLine(`return sql + ', ' + EOL + selectField;`);
|
415
472
|
});
|
416
473
|
});
|
417
474
|
writer.blankLine();
|
418
|
-
writer
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
475
|
+
writer
|
476
|
+
.write(`function whereConditionsToObject(whereConditions?: ${whereTypeName}[])`)
|
477
|
+
.block(() => {
|
478
|
+
writer.writeLine('const obj = {} as any;');
|
479
|
+
writer
|
480
|
+
.write('whereConditions?.forEach(condition => ')
|
481
|
+
.inlineBlock(() => {
|
482
|
+
writer.writeLine('const where = whereCondition(condition);');
|
483
|
+
writer.write('if (where?.hasValue) ').block(() => {
|
484
|
+
writer.writeLine('obj[condition[0]] = true;');
|
424
485
|
});
|
425
486
|
});
|
426
487
|
writer.write(');');
|
427
|
-
writer.writeLine(
|
488
|
+
writer.writeLine('return obj;');
|
428
489
|
});
|
429
490
|
if (orderByField != null) {
|
430
491
|
writer.blankLine();
|
431
|
-
writer
|
432
|
-
|
433
|
-
|
434
|
-
|
492
|
+
writer
|
493
|
+
.write(`function orderByToObject(orderBy: ${dynamicParamsTypeName}['orderBy'])`)
|
494
|
+
.block(() => {
|
495
|
+
writer.writeLine('const obj = {} as any;');
|
496
|
+
writer.write('orderBy?.forEach(order => ').inlineBlock(() => {
|
497
|
+
writer.writeLine('obj[order[0]] = true;');
|
435
498
|
});
|
436
499
|
writer.write(');');
|
437
|
-
writer.writeLine(
|
500
|
+
writer.writeLine('return obj;');
|
438
501
|
});
|
439
502
|
}
|
440
503
|
writer.blankLine();
|
441
|
-
writer.write(
|
504
|
+
writer.write('type WhereConditionResult = ').block(() => {
|
442
505
|
writer.writeLine('sql: string;');
|
443
506
|
writer.writeLine('hasValue: boolean;');
|
444
507
|
writer.writeLine('values: any[];');
|
445
508
|
});
|
446
509
|
writer.blankLine();
|
447
|
-
writer
|
510
|
+
writer
|
511
|
+
.write(`function whereCondition(condition: ${whereTypeName}): WhereConditionResult | undefined `)
|
512
|
+
.block(() => {
|
448
513
|
writer.blankLine();
|
449
514
|
writer.writeLine('const selectFragment = selectFragments[condition[0]];');
|
450
515
|
writer.writeLine('const operator = condition[1];');
|
451
516
|
writer.blankLine();
|
452
517
|
if ((0, code_generator_1.hasStringColumn)(tsDescriptor.columns)) {
|
453
518
|
writer.write(`if (operator == 'LIKE') `).block(() => {
|
454
|
-
writer.write(
|
455
|
-
writer.writeLine(
|
519
|
+
writer.write('return ').block(() => {
|
520
|
+
writer.writeLine("sql: `${selectFragment} LIKE concat('%', ?, '%')`,");
|
456
521
|
writer.writeLine('hasValue: condition[2] != null,');
|
457
522
|
writer.writeLine('values: [condition[2]]');
|
458
523
|
});
|
@@ -460,51 +525,55 @@ function generateCodeFromTsDescriptor(client, queryName, tsDescriptor, isCrud =
|
|
460
525
|
}
|
461
526
|
writer.write(`if (operator == 'BETWEEN') `).block(() => {
|
462
527
|
if ((0, code_generator_1.hasDateColumn)(tsDescriptor.columns)) {
|
463
|
-
writer.writeLine(
|
464
|
-
writer.writeLine(
|
528
|
+
writer.writeLine('const value1 = isDate(condition[2]) ? condition[2]?.toISOString() : condition[2];');
|
529
|
+
writer.writeLine('const value2 = isDate(condition[3]) ? condition[3]?.toISOString() : condition[3];');
|
465
530
|
writer.writeLine(`const param = isDate(condition[2]) && isDate(condition[3]) ? 'date(?)' : '?';`);
|
466
|
-
writer.write(
|
531
|
+
writer.write('return ').block(() => {
|
467
532
|
writer.writeLine('sql: `${selectFragment} BETWEEN ${param} AND ${param}`,');
|
468
533
|
writer.writeLine('hasValue: value1 != null && value2 != null,');
|
469
534
|
writer.writeLine('values: [value1, value2]');
|
470
535
|
});
|
471
536
|
}
|
472
537
|
else {
|
473
|
-
writer.write(
|
538
|
+
writer.write('return ').block(() => {
|
474
539
|
writer.writeLine('sql: `${selectFragment} BETWEEN ? AND ?`,');
|
475
540
|
writer.writeLine('hasValue: condition[2] != null && condition[3] != null,');
|
476
541
|
writer.writeLine('values: [condition[2], condition[3]]');
|
477
542
|
});
|
478
543
|
}
|
479
544
|
});
|
480
|
-
writer
|
545
|
+
writer
|
546
|
+
.write(`if (operator == 'IN' || operator == 'NOT IN') `)
|
547
|
+
.block(() => {
|
481
548
|
if ((0, code_generator_1.hasDateColumn)(tsDescriptor.columns)) {
|
482
|
-
writer.write(
|
483
|
-
writer.writeLine(
|
549
|
+
writer.write('return ').block(() => {
|
550
|
+
writer.writeLine("sql: `${selectFragment} ${operator} (${condition[2]?.map(value => isDate(value) ? 'date(?)' : '?').join(', ')})`,");
|
484
551
|
writer.writeLine('hasValue: condition[2] != null && condition[2].length > 0,');
|
485
552
|
writer.writeLine('values: condition[2].map(value => isDate(value) ? value.toISOString() : value)');
|
486
553
|
});
|
487
554
|
}
|
488
555
|
else {
|
489
|
-
writer.write(
|
490
|
-
writer.writeLine(
|
556
|
+
writer.write('return ').block(() => {
|
557
|
+
writer.writeLine("sql: `${selectFragment} ${operator} (${condition[2]?.map(_ => '?').join(', ')})`,");
|
491
558
|
writer.writeLine('hasValue: condition[2] != null && condition[2].length > 0,');
|
492
559
|
writer.writeLine('values: condition[2]');
|
493
560
|
});
|
494
561
|
}
|
495
562
|
});
|
496
|
-
writer
|
563
|
+
writer
|
564
|
+
.write('if (NumericOperatorList.includes(operator)) ')
|
565
|
+
.block(() => {
|
497
566
|
if ((0, code_generator_1.hasDateColumn)(tsDescriptor.columns)) {
|
498
|
-
writer.writeLine(
|
567
|
+
writer.writeLine('const value = isDate(condition[2]) ? condition[2]?.toISOString() : condition[2];');
|
499
568
|
writer.writeLine(`const param = isDate(condition[2]) ? 'date(?)' : '?';`);
|
500
|
-
writer.write(
|
569
|
+
writer.write('return ').block(() => {
|
501
570
|
writer.writeLine('sql: `${selectFragment} ${operator} ${param}`,');
|
502
571
|
writer.writeLine('hasValue: value != null,');
|
503
572
|
writer.writeLine('values: [value]');
|
504
573
|
});
|
505
574
|
}
|
506
575
|
else {
|
507
|
-
writer.write(
|
576
|
+
writer.write('return ').block(() => {
|
508
577
|
writer.writeLine('sql: `${selectFragment} ${operator} ?`,');
|
509
578
|
writer.writeLine('hasValue: condition[2] != null,');
|
510
579
|
writer.writeLine('values: [condition[2]]');
|
@@ -514,8 +583,8 @@ function generateCodeFromTsDescriptor(client, queryName, tsDescriptor, isCrud =
|
|
514
583
|
});
|
515
584
|
if ((0, code_generator_1.hasDateColumn)(tsDescriptor.columns)) {
|
516
585
|
writer.blankLine();
|
517
|
-
writer.write(
|
518
|
-
writer.writeLine(
|
586
|
+
writer.write('function isDate(value: any): value is Date').block(() => {
|
587
|
+
writer.writeLine('return value instanceof Date;');
|
519
588
|
});
|
520
589
|
}
|
521
590
|
}
|
@@ -523,7 +592,7 @@ function generateCodeFromTsDescriptor(client, queryName, tsDescriptor, isCrud =
|
|
523
592
|
if (uniqueUpdateParams.length > 0) {
|
524
593
|
writer.blankLine();
|
525
594
|
writer.write(`export type ${dataTypeName} =`).block(() => {
|
526
|
-
uniqueUpdateParams.forEach(field => {
|
595
|
+
uniqueUpdateParams.forEach((field) => {
|
527
596
|
const optionalOp = field.optional ? '?' : '';
|
528
597
|
const orNull = field.notNull ? '' : ' | null';
|
529
598
|
writer.writeLine(`${field.name}${optionalOp}: ${field.tsType}${orNull};`);
|
@@ -545,7 +614,7 @@ function generateCodeFromTsDescriptor(client, queryName, tsDescriptor, isCrud =
|
|
545
614
|
}
|
546
615
|
writer.blankLine();
|
547
616
|
writer.write(`export type ${resultTypeName} =`).block(() => {
|
548
|
-
tsDescriptor.columns.forEach(field => {
|
617
|
+
tsDescriptor.columns.forEach((field) => {
|
549
618
|
const optionalOp = field.notNull ? '' : '?';
|
550
619
|
writer.writeLine(`${field.name}${optionalOp}: ${field.tsType};`);
|
551
620
|
});
|
@@ -553,7 +622,7 @@ function generateCodeFromTsDescriptor(client, queryName, tsDescriptor, isCrud =
|
|
553
622
|
writer.blankLine();
|
554
623
|
}
|
555
624
|
if (isCrud) {
|
556
|
-
const crudFunction = client
|
625
|
+
const crudFunction = client === 'libsql'
|
557
626
|
? `async function ${camelCaseName}(${functionArguments}): Promise<${returnType}>`
|
558
627
|
: `function ${camelCaseName}(${functionArguments}): ${returnType}`;
|
559
628
|
writer.write(`export ${crudFunction}`).block(() => {
|
@@ -561,77 +630,110 @@ function generateCodeFromTsDescriptor(client, queryName, tsDescriptor, isCrud =
|
|
561
630
|
writeExecuteCrudBlock(client, queryType, tableName, tsDescriptor.columns, idColumn, queryParams, paramsTypeName, dataTypeName, resultTypeName, writer);
|
562
631
|
});
|
563
632
|
}
|
564
|
-
if (tsDescriptor.dynamicQuery2 == null &&
|
565
|
-
|
566
|
-
|
567
|
-
|
633
|
+
if (tsDescriptor.dynamicQuery2 == null &&
|
634
|
+
!isCrud &&
|
635
|
+
(queryType === 'Select' ||
|
636
|
+
(queryType === 'Insert' && tsDescriptor.returning))) {
|
637
|
+
if (client === 'better-sqlite3') {
|
638
|
+
writer
|
639
|
+
.write(`export function ${camelCaseName}(${functionArguments}): ${returnType}`)
|
640
|
+
.block(() => {
|
641
|
+
const processedSql = tsDescriptor.orderByColumns
|
642
|
+
? (0, code_generator_1.replaceOrderByParam)(sql)
|
643
|
+
: sql;
|
568
644
|
const sqlSplit = processedSql.split('\n');
|
569
645
|
writer.write('const sql = `').newLine();
|
570
|
-
sqlSplit.forEach(sqlLine => {
|
646
|
+
sqlSplit.forEach((sqlLine) => {
|
571
647
|
writer.indent().write(sqlLine).newLine();
|
572
648
|
});
|
573
649
|
writer.indent().write('`').newLine();
|
574
650
|
writer.write('return db.prepare(sql)').newLine();
|
575
651
|
writer.indent().write('.raw(true)').newLine();
|
576
652
|
writer.indent().write(`.all(${queryParams})`).newLine();
|
577
|
-
writer
|
653
|
+
writer
|
654
|
+
.indent()
|
655
|
+
.write(`.map(data => mapArrayTo${resultTypeName}(data))${tsDescriptor.multipleRowsResult ? '' : '[0]'};`);
|
578
656
|
});
|
579
657
|
}
|
580
|
-
if (!isCrud && client
|
581
|
-
writer
|
582
|
-
|
658
|
+
if (!isCrud && client === 'libsql') {
|
659
|
+
writer
|
660
|
+
.write(`export async function ${camelCaseName}(${functionArguments}): Promise<${returnType}>`)
|
661
|
+
.block(() => {
|
662
|
+
const processedSql = tsDescriptor.orderByColumns
|
663
|
+
? (0, code_generator_1.replaceOrderByParam)(sql)
|
664
|
+
: sql;
|
583
665
|
const sqlSplit = processedSql.split('\n');
|
584
666
|
writer.write('const sql = `').newLine();
|
585
|
-
sqlSplit.forEach(sqlLine => {
|
667
|
+
sqlSplit.forEach((sqlLine) => {
|
586
668
|
writer.indent().write(sqlLine).newLine();
|
587
669
|
});
|
588
670
|
writer.indent().write('`').newLine();
|
589
|
-
const executeParams = queryParams
|
671
|
+
const executeParams = queryParams !== '' ? `{ sql, args: ${queryParams} }` : 'sql';
|
590
672
|
writer.write(`return client.execute(${executeParams})`).newLine();
|
591
|
-
if (queryType
|
592
|
-
writer.indent().write(
|
673
|
+
if (queryType === 'Select') {
|
674
|
+
writer.indent().write('.then(res => res.rows)').newLine();
|
593
675
|
if (tsDescriptor.multipleRowsResult) {
|
594
|
-
writer
|
676
|
+
writer
|
677
|
+
.indent()
|
678
|
+
.write(`.then(rows => rows.map(row => mapArrayTo${resultTypeName}(row)));`);
|
595
679
|
}
|
596
680
|
else {
|
597
|
-
writer
|
681
|
+
writer
|
682
|
+
.indent()
|
683
|
+
.write(`.then(rows => mapArrayTo${resultTypeName}(rows[0]));`);
|
598
684
|
}
|
599
685
|
}
|
600
|
-
if (queryType
|
686
|
+
if (queryType === 'Insert') {
|
601
687
|
if (tsDescriptor.returning) {
|
602
|
-
writer.indent().write(
|
603
|
-
writer
|
688
|
+
writer.indent().write('.then(res => res.rows)').newLine();
|
689
|
+
writer
|
690
|
+
.indent()
|
691
|
+
.write(`.then(rows => mapArrayTo${resultTypeName}(rows[0]));`);
|
604
692
|
}
|
605
693
|
else {
|
606
|
-
writer
|
694
|
+
writer
|
695
|
+
.indent()
|
696
|
+
.write(`.then(res => mapArrayTo${resultTypeName}(res));`);
|
607
697
|
}
|
608
698
|
}
|
609
699
|
});
|
610
700
|
}
|
611
701
|
}
|
612
|
-
if (!isCrud &&
|
613
|
-
|
614
|
-
|
702
|
+
if (!isCrud &&
|
703
|
+
(queryType === 'Update' ||
|
704
|
+
queryType === 'Delete' ||
|
705
|
+
(queryType === 'Insert' && !tsDescriptor.returning))) {
|
706
|
+
if (client === 'better-sqlite3') {
|
707
|
+
writer
|
708
|
+
.write(`export function ${camelCaseName}(${functionArguments}): ${resultTypeName}`)
|
709
|
+
.block(() => {
|
615
710
|
writeExecuteBlock(sql, queryParams, resultTypeName, writer);
|
616
711
|
});
|
617
712
|
}
|
618
|
-
if (client
|
619
|
-
writer
|
713
|
+
if (client === 'libsql') {
|
714
|
+
writer
|
715
|
+
.write(`export async function ${camelCaseName}(${functionArguments}): Promise<${resultTypeName}>`)
|
716
|
+
.block(() => {
|
620
717
|
const sqlSplit = sql.split('\n');
|
621
718
|
writer.write('const sql = `').newLine();
|
622
|
-
sqlSplit.forEach(sqlLine => {
|
719
|
+
sqlSplit.forEach((sqlLine) => {
|
623
720
|
writer.indent().write(sqlLine).newLine();
|
624
721
|
});
|
625
722
|
writer.indent().write('`').newLine();
|
626
|
-
const executeParams = queryParams
|
723
|
+
const executeParams = queryParams !== '' ? `{ sql, args: ${queryParams} }` : 'sql';
|
627
724
|
writer.write(`return client.execute(${executeParams})`).newLine();
|
628
|
-
writer
|
725
|
+
writer
|
726
|
+
.indent()
|
727
|
+
.write(`.then(res => mapArrayTo${resultTypeName}(res));`);
|
629
728
|
});
|
630
729
|
}
|
631
730
|
}
|
632
|
-
if ((queryType
|
731
|
+
if ((queryType === 'Select' || tsDescriptor.returning) &&
|
732
|
+
tsDescriptor.dynamicQuery2 == null) {
|
633
733
|
writer.blankLine();
|
634
|
-
writer
|
734
|
+
writer
|
735
|
+
.write(`function mapArrayTo${resultTypeName}(data: any) `)
|
736
|
+
.block(() => {
|
635
737
|
writer.write(`const result: ${resultTypeName} = `).block(() => {
|
636
738
|
tsDescriptor.columns.forEach((col, index) => {
|
637
739
|
const separator = index < tsDescriptor.columns.length - 1 ? ',' : '';
|
@@ -641,9 +743,13 @@ function generateCodeFromTsDescriptor(client, queryName, tsDescriptor, isCrud =
|
|
641
743
|
writer.writeLine('return result;');
|
642
744
|
});
|
643
745
|
}
|
644
|
-
else if (client
|
746
|
+
else if (client === 'libsql' &&
|
747
|
+
!tsDescriptor.returning &&
|
748
|
+
tsDescriptor.dynamicQuery2 == null) {
|
645
749
|
writer.blankLine();
|
646
|
-
writer
|
750
|
+
writer
|
751
|
+
.write(`function mapArrayTo${resultTypeName}(data: any) `)
|
752
|
+
.block(() => {
|
647
753
|
writer.write(`const result: ${resultTypeName} = `).block(() => {
|
648
754
|
tsDescriptor.columns.forEach((col, index) => {
|
649
755
|
const separator = index < tsDescriptor.columns.length - 1 ? ',' : '';
|
@@ -654,10 +760,12 @@ function generateCodeFromTsDescriptor(client, queryName, tsDescriptor, isCrud =
|
|
654
760
|
});
|
655
761
|
}
|
656
762
|
if (tsDescriptor.orderByColumns) {
|
657
|
-
const orderByType = tsDescriptor.dynamicQuery2 == null
|
763
|
+
const orderByType = tsDescriptor.dynamicQuery2 == null
|
764
|
+
? paramsTypeName
|
765
|
+
: dynamicParamsTypeName;
|
658
766
|
if (orderByField != null) {
|
659
767
|
writer.blankLine();
|
660
|
-
writer.write(
|
768
|
+
writer.write('const orderByFragments = ').inlineBlock(() => {
|
661
769
|
var _a;
|
662
770
|
(_a = tsDescriptor.orderByColumns) === null || _a === void 0 ? void 0 : _a.forEach((col) => {
|
663
771
|
writer.writeLine(`'${col}': \`${col}\`,`);
|
@@ -668,7 +776,9 @@ function generateCodeFromTsDescriptor(client, queryName, tsDescriptor, isCrud =
|
|
668
776
|
writer.blankLine();
|
669
777
|
writer.writeLine(`export type ${orderByTypeName} = keyof typeof orderByFragments;`);
|
670
778
|
writer.blankLine();
|
671
|
-
writer
|
779
|
+
writer
|
780
|
+
.write(`function escapeOrderBy(orderBy: ${orderByType}['orderBy']): string`)
|
781
|
+
.block(() => {
|
672
782
|
writer.writeLine(`return orderBy.map(order => \`\${orderByFragments[order[0]]} \${order[1] == 'desc' ? 'desc' : 'asc'}\`).join(', ');`);
|
673
783
|
});
|
674
784
|
}
|
@@ -678,11 +788,11 @@ function generateCodeFromTsDescriptor(client, queryName, tsDescriptor, isCrud =
|
|
678
788
|
const relationType = (0, code_generator_1.generateRelationType)(capitalizedName, relation.name);
|
679
789
|
writer.blankLine();
|
680
790
|
writer.write(`export type ${relationType} = `).block(() => {
|
681
|
-
const uniqueNameFields = (0, code_generator_1.renameInvalidNames)(relation.fields.map(f => f.name));
|
791
|
+
const uniqueNameFields = (0, code_generator_1.renameInvalidNames)(relation.fields.map((f) => f.name));
|
682
792
|
relation.fields.forEach((field, index) => {
|
683
793
|
writer.writeLine(`${uniqueNameFields[index]}: ${field.tsType};`);
|
684
794
|
});
|
685
|
-
relation.relations.forEach(field => {
|
795
|
+
relation.relations.forEach((field) => {
|
686
796
|
const nestedRelationType = (0, code_generator_1.generateRelationType)(capitalizedName, field.tsType);
|
687
797
|
const nullableOperator = field.notNull ? '' : '?';
|
688
798
|
writer.writeLine(`${field.name}${nullableOperator}: ${nestedRelationType};`);
|
@@ -692,9 +802,11 @@ function generateCodeFromTsDescriptor(client, queryName, tsDescriptor, isCrud =
|
|
692
802
|
writer.blankLine();
|
693
803
|
relations.forEach((relation, index) => {
|
694
804
|
const relationType = (0, code_generator_1.generateRelationType)(capitalizedName, relation.name);
|
695
|
-
if (index
|
696
|
-
if (client
|
697
|
-
writer
|
805
|
+
if (index === 0) {
|
806
|
+
if (client === 'better-sqlite3') {
|
807
|
+
writer
|
808
|
+
.write(`export function ${camelCaseName}Nested(${functionArguments}): ${relationType}[]`)
|
809
|
+
.block(() => {
|
698
810
|
const params = tsDescriptor.parameters.length > 0 ? ', params' : '';
|
699
811
|
writer.writeLine(`const selectResult = ${camelCaseName}(db${params});`);
|
700
812
|
writer.write('if (selectResult.length == 0)').block(() => {
|
@@ -703,8 +815,10 @@ function generateCodeFromTsDescriptor(client, queryName, tsDescriptor, isCrud =
|
|
703
815
|
writer.writeLine(`return collect${relationType}(selectResult);`);
|
704
816
|
});
|
705
817
|
}
|
706
|
-
else if (client
|
707
|
-
writer
|
818
|
+
else if (client === 'libsql') {
|
819
|
+
writer
|
820
|
+
.write(`export async function ${camelCaseName}Nested(${functionArguments}): Promise<${relationType}[]>`)
|
821
|
+
.block(() => {
|
708
822
|
const params = tsDescriptor.parameters.length > 0 ? ', params' : '';
|
709
823
|
writer.writeLine(`const selectResult = await ${camelCaseName}(client${params});`);
|
710
824
|
writer.write('if (selectResult.length == 0)').block(() => {
|
@@ -717,12 +831,17 @@ function generateCodeFromTsDescriptor(client, queryName, tsDescriptor, isCrud =
|
|
717
831
|
writeCollectFunction(writer, relation, tsDescriptor.columns, capitalizedName, resultTypeName);
|
718
832
|
});
|
719
833
|
writer.blankLine();
|
720
|
-
writer
|
721
|
-
|
834
|
+
writer
|
835
|
+
.write('const groupBy = <T, Q>(array: T[], predicate: (value: T, index: number, array: T[]) => Q) =>')
|
836
|
+
.block(() => {
|
837
|
+
writer
|
838
|
+
.write('return array.reduce((map, value, index, array) => ')
|
839
|
+
.inlineBlock(() => {
|
722
840
|
writer.writeLine('const key = predicate(value, index, array);');
|
723
841
|
writer.writeLine('map.get(key)?.push(value) ?? map.set(key, [value]);');
|
724
842
|
writer.writeLine('return map;');
|
725
|
-
})
|
843
|
+
})
|
844
|
+
.write(', new Map<Q, T[]>());');
|
726
845
|
});
|
727
846
|
}
|
728
847
|
return writer.toString();
|
@@ -730,7 +849,7 @@ function generateCodeFromTsDescriptor(client, queryName, tsDescriptor, isCrud =
|
|
730
849
|
function writeExecuteBlock(sql, queryParams, resultTypeName, writer) {
|
731
850
|
const sqlSplit = sql.split('\n');
|
732
851
|
writer.write('const sql = `').newLine();
|
733
|
-
sqlSplit.forEach(sqlLine => {
|
852
|
+
sqlSplit.forEach((sqlLine) => {
|
734
853
|
writer.indent().write(sqlLine).newLine();
|
735
854
|
});
|
736
855
|
writer.indent().write('`').newLine();
|
@@ -739,13 +858,13 @@ function writeExecuteBlock(sql, queryParams, resultTypeName, writer) {
|
|
739
858
|
}
|
740
859
|
function writeExecuteCrudBlock(client, queryType, tableName, columns, idColumn, queryParams, paramTypeName, dataTypeName, resultTypeName, writer) {
|
741
860
|
switch (queryType) {
|
742
|
-
case
|
861
|
+
case 'Select':
|
743
862
|
return writeExecutSelectCrudBlock(client, tableName, idColumn, columns, queryParams, resultTypeName, writer);
|
744
|
-
case
|
863
|
+
case 'Insert':
|
745
864
|
return writeExecuteInsertCrudBlock(client, tableName, paramTypeName, resultTypeName, writer);
|
746
|
-
case
|
865
|
+
case 'Update':
|
747
866
|
return writeExecuteUpdateCrudBlock(client, tableName, idColumn, dataTypeName, resultTypeName, writer);
|
748
|
-
case
|
867
|
+
case 'Delete':
|
749
868
|
return writeExecutDeleteCrudBlock(client, tableName, idColumn, queryParams, resultTypeName, writer);
|
750
869
|
}
|
751
870
|
}
|
@@ -759,55 +878,76 @@ function writeExecutSelectCrudBlock(client, tableName, idColumn, columns, queryP
|
|
759
878
|
writer.indent().write(`FROM ${tableName}`).newLine();
|
760
879
|
writer.indent().write(`WHERE ${idColumn} = ?\``).newLine();
|
761
880
|
writer.blankLine();
|
762
|
-
if (client
|
881
|
+
if (client === 'better-sqlite3') {
|
763
882
|
writer.write('return db.prepare(sql)').newLine();
|
764
883
|
writer.indent().write('.raw(true)').newLine();
|
765
884
|
writer.indent().write(`.all(${queryParams})`).newLine();
|
766
|
-
writer
|
885
|
+
writer
|
886
|
+
.indent()
|
887
|
+
.write(`.map(data => mapArrayTo${resultTypeName}(data))[0];`);
|
767
888
|
}
|
768
889
|
else {
|
769
|
-
writer
|
770
|
-
|
771
|
-
|
890
|
+
writer
|
891
|
+
.write(`return client.execute({ sql, args: ${queryParams} })`)
|
892
|
+
.newLine();
|
893
|
+
writer.indent().write('.then(res => res.rows)').newLine();
|
894
|
+
writer
|
895
|
+
.indent()
|
896
|
+
.write(`.then(rows => mapArrayTo${resultTypeName}(rows[0]));`);
|
772
897
|
}
|
773
898
|
}
|
774
899
|
function writeExecuteInsertCrudBlock(client, tableName, paramTypeName, resultTypeName, writer) {
|
775
900
|
writer.blankLine();
|
776
901
|
writer.writeLine(`const keys = Object.keys(params) as Array<keyof ${paramTypeName}>;`);
|
777
|
-
writer.writeLine(
|
778
|
-
writer.writeLine(
|
902
|
+
writer.writeLine('const columns = keys.filter(key => params[key] !== undefined);');
|
903
|
+
writer.writeLine('const values = columns.map(col => params[col]!);');
|
779
904
|
writer.blankLine();
|
780
905
|
writer.writeLine('const sql = columns.length == 0');
|
781
|
-
writer
|
782
|
-
|
906
|
+
writer
|
907
|
+
.indent()
|
908
|
+
.write(`? \`INSERT INTO ${tableName} DEFAULT VALUES\``)
|
909
|
+
.newLine();
|
910
|
+
writer
|
911
|
+
.indent()
|
912
|
+
.write(`: \`INSERT INTO ${tableName}(\${columns.join(',')}) VALUES(\${columns.map(_ => '?').join(',')})\``)
|
913
|
+
.newLine();
|
783
914
|
writer.blankLine();
|
784
|
-
if (client
|
915
|
+
if (client === 'better-sqlite3') {
|
785
916
|
writer.write('return db.prepare(sql)').newLine();
|
786
917
|
writer.indent().write(`.run(values) as ${resultTypeName};`);
|
787
918
|
}
|
788
919
|
else {
|
789
|
-
writer.write(
|
790
|
-
writer
|
920
|
+
writer.write('return client.execute({ sql, args: values })').newLine();
|
921
|
+
writer
|
922
|
+
.indent()
|
923
|
+
.write(`.then(res => mapArrayTo${resultTypeName}(res));`)
|
924
|
+
.newLine();
|
791
925
|
}
|
792
926
|
}
|
793
927
|
function writeExecuteUpdateCrudBlock(client, tableName, idColumn, paramTypeName, resultTypeName, writer) {
|
794
928
|
writer.blankLine();
|
795
929
|
writer.writeLine(`const keys = Object.keys(data) as Array<keyof ${paramTypeName}>;`);
|
796
|
-
writer.writeLine(
|
930
|
+
writer.writeLine('const columns = keys.filter(key => data[key] !== undefined);');
|
797
931
|
writer.writeLine(`const values = columns.map(col => data[col]!).concat(params.${idColumn});`);
|
798
932
|
writer.blankLine();
|
799
933
|
writer.writeLine('const sql = `');
|
800
934
|
writer.indent().write(`UPDATE ${tableName}`).newLine();
|
801
|
-
writer
|
935
|
+
writer
|
936
|
+
.indent()
|
937
|
+
.write(`SET \${columns.map(col => \`\${col} = ?\`).join(', ')}`)
|
938
|
+
.newLine();
|
802
939
|
writer.indent().write(`WHERE ${idColumn} = ?\``).newLine();
|
803
940
|
writer.blankLine();
|
804
|
-
if (client
|
941
|
+
if (client === 'better-sqlite3') {
|
805
942
|
writer.write('return db.prepare(sql)').newLine();
|
806
943
|
writer.indent().write(`.run(values) as ${resultTypeName};`);
|
807
944
|
}
|
808
945
|
else {
|
809
|
-
writer.write(
|
810
|
-
writer
|
946
|
+
writer.write('return client.execute({ sql, args: values })').newLine();
|
947
|
+
writer
|
948
|
+
.indent()
|
949
|
+
.write(`.then(res => mapArrayTo${resultTypeName}(res));`)
|
950
|
+
.newLine();
|
811
951
|
}
|
812
952
|
}
|
813
953
|
function writeExecutDeleteCrudBlock(client, tableName, idColumn, queryParams, resultTypeName, writer) {
|
@@ -816,32 +956,38 @@ function writeExecutDeleteCrudBlock(client, tableName, idColumn, queryParams, re
|
|
816
956
|
writer.indent().write(`FROM ${tableName}`).newLine();
|
817
957
|
writer.indent().write(`WHERE ${idColumn} = ?\``).newLine();
|
818
958
|
writer.blankLine();
|
819
|
-
if (client
|
959
|
+
if (client === 'better-sqlite3') {
|
820
960
|
writer.write('return db.prepare(sql)').newLine();
|
821
|
-
writer
|
961
|
+
writer
|
962
|
+
.indent()
|
963
|
+
.write(`.run(${queryParams}) as ${resultTypeName};`)
|
964
|
+
.newLine();
|
822
965
|
}
|
823
966
|
else {
|
824
|
-
writer
|
825
|
-
|
967
|
+
writer
|
968
|
+
.write(`return client.execute({ sql, args: ${queryParams} })`)
|
969
|
+
.newLine();
|
970
|
+
writer
|
971
|
+
.indent()
|
972
|
+
.write(`.then(res => mapArrayTo${resultTypeName}(res));`)
|
973
|
+
.newLine();
|
826
974
|
}
|
827
975
|
}
|
828
976
|
function toDriver(variableData, param) {
|
829
|
-
if (param.tsType
|
977
|
+
if (param.tsType === 'Date') {
|
830
978
|
if (param.notNull) {
|
831
979
|
return `new Date(${variableData})`;
|
832
980
|
}
|
833
|
-
|
834
|
-
return `${variableData} != null ? new Date(${variableData}) : ${variableData}`;
|
835
|
-
}
|
981
|
+
return `${variableData} != null ? new Date(${variableData}) : ${variableData}`;
|
836
982
|
}
|
837
983
|
return variableData;
|
838
984
|
}
|
839
985
|
function fromDriver(variableName, param) {
|
840
986
|
var _a;
|
841
|
-
if (param.tsType
|
987
|
+
if (param.tsType === 'Date') {
|
842
988
|
return `${variableName}.${param.name}?.toISOString()`;
|
843
989
|
}
|
844
|
-
if ((_a = param.tsType) === null || _a === void 0 ? void 0 : _a.endsWith(
|
990
|
+
if ((_a = param.tsType) === null || _a === void 0 ? void 0 : _a.endsWith('[]')) {
|
845
991
|
return `...${variableName}.${param.name}`;
|
846
992
|
}
|
847
993
|
return `${variableName}.${param.name}`;
|
@@ -850,22 +996,27 @@ function writeCollectFunction(writer, relation, columns, capitalizedName, result
|
|
850
996
|
const relationType = (0, code_generator_1.generateRelationType)(capitalizedName, relation.name);
|
851
997
|
const collectFunctionName = `collect${relationType}`;
|
852
998
|
writer.blankLine();
|
853
|
-
writer
|
999
|
+
writer
|
1000
|
+
.write(`function ${collectFunctionName}(selectResult: ${resultTypeName}[]): ${relationType}[]`)
|
1001
|
+
.block(() => {
|
854
1002
|
const groupBy = columns[relation.groupIndex].name;
|
855
1003
|
writer.writeLine(`const grouped = groupBy(selectResult.filter(r => r.${groupBy} != null), r => r.${groupBy});`);
|
856
|
-
writer
|
1004
|
+
writer
|
1005
|
+
.write('return [...grouped.values()].map(row => (')
|
1006
|
+
.inlineBlock(() => {
|
857
1007
|
relation.fields.forEach((field, index) => {
|
858
|
-
const uniqueNameFields = (0, code_generator_1.renameInvalidNames)(relation.fields.map(f => f.name));
|
1008
|
+
const uniqueNameFields = (0, code_generator_1.renameInvalidNames)(relation.fields.map((f) => f.name));
|
859
1009
|
const separator = ',';
|
860
1010
|
const fieldName = columns[field.index].name;
|
861
|
-
writer.writeLine(`${uniqueNameFields[index]}: row[0].${fieldName}
|
1011
|
+
writer.writeLine(`${uniqueNameFields[index]}: row[0].${fieldName}!${separator}`);
|
862
1012
|
});
|
863
|
-
relation.relations.forEach(fieldRelation => {
|
1013
|
+
relation.relations.forEach((fieldRelation) => {
|
864
1014
|
const relationType = (0, code_generator_1.generateRelationType)(capitalizedName, fieldRelation.name);
|
865
1015
|
const cardinality = fieldRelation.list ? '' : '[0]';
|
866
1016
|
writer.writeLine(`${fieldRelation.name}: collect${relationType}(row)${cardinality},`);
|
867
1017
|
});
|
868
|
-
})
|
1018
|
+
})
|
1019
|
+
.write('))');
|
869
1020
|
});
|
870
1021
|
}
|
871
1022
|
//# sourceMappingURL=code-generator.js.map
|