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