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.
- package/README.md +5 -0
- package/cli.js +51 -64
- package/cli.js.map +1 -1
- package/code-generator.d.ts +1 -1
- package/code-generator.d.ts.map +1 -1
- package/code-generator.js +4 -3
- package/code-generator.js.map +1 -1
- package/code-generator2.d.ts.map +1 -1
- package/code-generator2.js +151 -115
- package/code-generator2.js.map +1 -1
- package/codegen/code-generator.d.ts +13 -0
- package/codegen/code-generator.d.ts.map +1 -0
- package/codegen/code-generator.js +106 -0
- package/codegen/code-generator.js.map +1 -0
- package/codegen/code-generator2.d.ts +10 -0
- package/codegen/code-generator2.d.ts.map +1 -0
- package/codegen/code-generator2.js +917 -0
- package/codegen/code-generator2.js.map +1 -0
- package/codegen/codegen-util.d.ts +1 -0
- package/codegen/codegen-util.d.ts.map +1 -0
- package/codegen/codegen-util.js +2 -0
- package/codegen/codegen-util.js.map +1 -0
- package/codegen/generic/codegen-util.d.ts +8 -0
- package/codegen/generic/codegen-util.d.ts.map +1 -0
- package/codegen/generic/codegen-util.js +89 -0
- package/codegen/generic/codegen-util.js.map +1 -0
- package/codegen/mysql2.d.ts +40 -0
- package/codegen/mysql2.d.ts.map +1 -0
- package/codegen/mysql2.js +667 -0
- package/codegen/mysql2.js.map +1 -0
- package/codegen/pg.d.ts +9 -0
- package/codegen/pg.d.ts.map +1 -0
- package/codegen/pg.js +760 -0
- package/codegen/pg.js.map +1 -0
- package/codegen/postgres-pg.d.ts +10 -0
- package/codegen/postgres-pg.d.ts.map +1 -0
- package/codegen/postgres-pg.js +917 -0
- package/codegen/postgres-pg.js.map +1 -0
- package/codegen/shared/codegen-util.d.ts +28 -0
- package/codegen/shared/codegen-util.d.ts.map +1 -0
- package/codegen/shared/codegen-util.js +303 -0
- package/codegen/shared/codegen-util.js.map +1 -0
- package/codegen/sqlite-code-generator.d.ts +15 -0
- package/codegen/sqlite-code-generator.d.ts.map +1 -0
- package/codegen/sqlite-code-generator.js +1049 -0
- package/codegen/sqlite-code-generator.js.map +1 -0
- package/codegen/sqlite.d.ts +13 -0
- package/codegen/sqlite.d.ts.map +1 -0
- package/codegen/sqlite.js +893 -0
- package/codegen/sqlite.js.map +1 -0
- package/describe-query.d.ts.map +1 -1
- package/describe-query.js +45 -32
- package/describe-query.js.map +1 -1
- package/dialects/postgres.d.ts +4 -1
- package/dialects/postgres.d.ts.map +1 -1
- package/dialects/postgres.js +4 -2
- package/dialects/postgres.js.map +1 -1
- package/drivers/sqlite.d.ts +4 -1
- package/drivers/sqlite.d.ts.map +1 -1
- package/drivers/sqlite.js +4 -1
- package/drivers/sqlite.js.map +1 -1
- package/drivers/types.d.ts +3 -1
- package/drivers/types.d.ts.map +1 -1
- package/generic/codegen-util.d.ts +8 -0
- package/generic/codegen-util.d.ts.map +1 -0
- package/generic/codegen-util.js +89 -0
- package/generic/codegen-util.js.map +1 -0
- package/load-config.d.ts +6 -0
- package/load-config.d.ts.map +1 -1
- package/load-config.js +65 -1
- package/load-config.js.map +1 -1
- package/mysql-mapping.d.ts +4 -1
- package/mysql-mapping.d.ts.map +1 -1
- package/mysql-mapping.js +5 -3
- package/mysql-mapping.js.map +1 -1
- package/mysql-query-analyzer/infer-column-nullability.js +1 -1
- package/mysql-query-analyzer/infer-column-nullability.js.map +1 -1
- package/mysql-query-analyzer/parse.d.ts.map +1 -1
- package/mysql-query-analyzer/parse.js +3 -2
- package/mysql-query-analyzer/parse.js.map +1 -1
- package/package.json +2 -1
- package/postgres-pg.d.ts +10 -0
- package/postgres-pg.d.ts.map +1 -0
- package/postgres-pg.js +917 -0
- package/postgres-pg.js.map +1 -0
- package/postgres-query-analyzer/describe.d.ts +1 -1
- package/postgres-query-analyzer/describe.d.ts.map +1 -1
- package/postgres-query-analyzer/describe.js +77 -48
- package/postgres-query-analyzer/describe.js.map +1 -1
- package/postgres-query-analyzer/traverse.d.ts +1 -0
- package/postgres-query-analyzer/traverse.d.ts.map +1 -1
- package/postgres-query-analyzer/traverse.js +90 -28
- package/postgres-query-analyzer/traverse.js.map +1 -1
- package/postgres-query-analyzer/util.d.ts +9 -0
- package/postgres-query-analyzer/util.d.ts.map +1 -0
- package/postgres-query-analyzer/util.js +58 -0
- package/postgres-query-analyzer/util.js.map +1 -0
- package/rescript.d.ts +1 -0
- package/rescript.d.ts.map +1 -0
- package/rescript.js +2 -0
- package/rescript.js.map +1 -0
- package/sqlite-query-analyzer/parser.js +3 -3
- package/sqlite-query-analyzer/parser.js.map +1 -1
- package/sqlite-query-analyzer/replace-list-params.d.ts.map +1 -1
- package/sqlite-query-analyzer/replace-list-params.js.map +1 -1
- package/sqlite-query-analyzer/sqlite-code-generator.d.ts +15 -0
- package/sqlite-query-analyzer/sqlite-code-generator.d.ts.map +1 -0
- package/sqlite-query-analyzer/sqlite-code-generator.js +1049 -0
- package/sqlite-query-analyzer/sqlite-code-generator.js.map +1 -0
- package/sqlite-query-analyzer/traverse.js +1 -1
- package/sqlite-query-analyzer/traverse.js.map +1 -1
- package/sqlite.d.ts +43 -0
- package/sqlite.d.ts.map +1 -0
- package/sqlite.js +755 -0
- package/sqlite.js.map +1 -0
- package/ts-dynamic-query-descriptor.d.ts.map +1 -1
- package/ts-dynamic-query-descriptor.js +2 -1
- package/ts-dynamic-query-descriptor.js.map +1 -1
- package/ts-nested-descriptor.d.ts.map +1 -1
- package/ts-nested-descriptor.js +1 -1
- package/ts-nested-descriptor.js.map +1 -1
- package/types.d.ts +9 -1
- package/types.d.ts.map +1 -1
package/code-generator2.js
CHANGED
@@ -11,7 +11,6 @@ const code_block_writer_1 = __importDefault(require("code-block-writer"));
|
|
11
11
|
const code_generator_1 = require("./code-generator");
|
12
12
|
const describe_1 = require("./postgres-query-analyzer/describe");
|
13
13
|
const postgres_1 = require("./dialects/postgres");
|
14
|
-
const describe_query_1 = require("./describe-query");
|
15
14
|
const neverthrow_1 = require("neverthrow");
|
16
15
|
const code_generator_2 = require("./sqlite-query-analyzer/code-generator");
|
17
16
|
const ts_nested_descriptor_1 = require("./ts-nested-descriptor");
|
@@ -20,9 +19,8 @@ function generateCode(client, sql, queryName, schemaInfo) {
|
|
20
19
|
if (isEmptySql(sql)) {
|
21
20
|
return (0, neverthrow_1.okAsync)('');
|
22
21
|
}
|
23
|
-
|
24
|
-
|
25
|
-
.map(schemaDef => generateTsCode(processedSql, queryName, schemaDef, client.type));
|
22
|
+
return _describeQuery(client, sql, schemaInfo)
|
23
|
+
.map(schemaDef => generateTsCode(sql, queryName, schemaDef, client.type));
|
26
24
|
}
|
27
25
|
function isEmptySql(sql) {
|
28
26
|
if (sql.trim() === '') {
|
@@ -31,8 +29,8 @@ function isEmptySql(sql) {
|
|
31
29
|
const lines = sql.split('\n');
|
32
30
|
return lines.every(line => line.trim() === '' || line.trim().startsWith('//'));
|
33
31
|
}
|
34
|
-
function _describeQuery(databaseClient, sql,
|
35
|
-
return (0, describe_1.describeQuery)(databaseClient.client, sql,
|
32
|
+
function _describeQuery(databaseClient, sql, dbSchema) {
|
33
|
+
return (0, describe_1.describeQuery)(databaseClient.client, sql, dbSchema);
|
36
34
|
}
|
37
35
|
function createCodeBlockWriter() {
|
38
36
|
const writer = new code_block_writer_1.default({
|
@@ -117,9 +115,9 @@ function generateTsCode(sqlOld, queryName, schemaDef, client, isCrud = false) {
|
|
117
115
|
writer.blankLine();
|
118
116
|
writer.write(`export type ${whereTypeName} =`).indent(() => {
|
119
117
|
for (const col of tsDescriptor.columns) {
|
120
|
-
writer.writeLine(`|
|
121
|
-
writer.writeLine(`|
|
122
|
-
writer.writeLine(`|
|
118
|
+
writer.writeLine(`| { column: '${col.name}'; op: ${(0, code_generator_1.getOperator)(col.tsType)}; value: ${col.tsType} | null }`);
|
119
|
+
writer.writeLine(`| { column: '${col.name}'; op: SetOperator; value: ${col.tsType}[] }`);
|
120
|
+
writer.writeLine(`| { column: '${col.name}'; op: BetweenOperator; value: [${col.tsType} | null, ${col.tsType} | null] }`);
|
123
121
|
}
|
124
122
|
});
|
125
123
|
writer.blankLine();
|
@@ -128,23 +126,25 @@ function generateTsCode(sqlOld, queryName, schemaDef, client, isCrud = false) {
|
|
128
126
|
// functionParams += `, data: ${dataType}`;
|
129
127
|
// }
|
130
128
|
functionArguments += `, params?: ${dynamicParamsTypeName}`;
|
131
|
-
writer.writeLine('let currentIndex: number;');
|
132
129
|
writer.write(`export async function ${camelCaseName}(${functionArguments}): Promise<${resultTypeName}[]>`).block(() => {
|
133
|
-
writer.writeLine(`currentIndex = ${tsDescriptor.parameters.length};`);
|
134
|
-
writer.writeLine('const where = whereConditionsToObject(params?.where);');
|
135
130
|
// if (orderByField != null) {
|
136
131
|
// writer.writeLine('const orderBy = orderByToObject(params.orderBy);');
|
137
132
|
// }
|
138
|
-
writer.writeLine(
|
133
|
+
writer.writeLine(`const isSelected = (field: keyof ${selectColumnsTypeName}) =>`);
|
134
|
+
writer.indent().write('params?.select == null || params.select[field] === true;').newLine();
|
135
|
+
writer.blankLine();
|
136
|
+
writer.writeLine('const selectedSqlFragments: string[] = [];');
|
137
|
+
writer.writeLine(`const selectedFields: (keyof ${resultTypeName})[] = [];`);
|
138
|
+
writer.writeLine('const paramsValues: any[] = [];');
|
139
|
+
writer.blankLine();
|
140
|
+
writer.writeLine('const whereColumns = new Set(params?.where?.map(w => w.column) || []);');
|
141
|
+
writer.blankLine();
|
139
142
|
if (dynamicQueryInfo.with.length > 0) {
|
140
|
-
writer.writeLine(`
|
143
|
+
writer.writeLine(`const withFragments: string[] = [];`);
|
141
144
|
dynamicQueryInfo.with.forEach((withFragment) => {
|
142
145
|
var _a;
|
143
|
-
const selectConditions = withFragment.dependOnFields.map((fieldIndex) => `
|
144
|
-
|
145
|
-
selectConditions.unshift('params?.select == null');
|
146
|
-
}
|
147
|
-
const whereConditions = withFragment.dependOnFields.map((fieldIndex) => `where.${tsDescriptor.columns[fieldIndex].name} != null`);
|
146
|
+
const selectConditions = withFragment.dependOnFields.map((fieldIndex) => `isSelected('${tsDescriptor.columns[fieldIndex].name}')`);
|
147
|
+
const whereConditions = withFragment.dependOnFields.map((fieldIndex) => `whereColumns.has('${tsDescriptor.columns[fieldIndex].name}')`);
|
148
148
|
const orderByConditions = ((_a = withFragment.dependOnOrderBy) === null || _a === void 0 ? void 0 : _a.map((orderBy) => `orderBy['${orderBy}'] != null`)) || [];
|
149
149
|
const allConditions = [...selectConditions, ...whereConditions, ...orderByConditions];
|
150
150
|
const paramValues = withFragment.parameters.map((paramIndex) => {
|
@@ -152,43 +152,38 @@ function generateTsCode(sqlOld, queryName, schemaDef, client, isCrud = false) {
|
|
152
152
|
return `params?.params?.${param.name}`;
|
153
153
|
});
|
154
154
|
if (allConditions.length > 0) {
|
155
|
-
writer.
|
156
|
-
|
157
|
-
|
155
|
+
writer.writeLine(`if (`);
|
156
|
+
writer.indent().write(`${allConditions.join(`${node_os_1.EOL}\t|| `)}`).newLine();
|
157
|
+
writer.write(') ').inlineBlock(() => {
|
158
|
+
writer.write(`withFragments.push(\`${withFragment.fragment}\`);`);
|
158
159
|
paramValues.forEach((paramValues) => {
|
159
160
|
writer.writeLine(`paramsValues.push(${paramValues});`);
|
160
161
|
});
|
161
|
-
});
|
162
|
+
}).newLine();
|
162
163
|
}
|
163
164
|
else {
|
164
|
-
writer.
|
165
|
+
writer.writeLine(`withFragments.push(\`${withFragment.fragment}\`);`);
|
165
166
|
paramValues.forEach((paramValues) => {
|
166
167
|
writer.writeLine(`paramsValues.push(${paramValues});`);
|
167
168
|
});
|
168
169
|
}
|
169
170
|
});
|
170
171
|
}
|
171
|
-
writer.writeLine(`let sql = 'SELECT';`);
|
172
|
-
if (dynamicQueryInfo.with.length > 0) {
|
173
|
-
writer.write('if (withClause)').block(() => {
|
174
|
-
writer.writeLine(`sql = 'WITH' + EOL + withClause + EOL + sql;`);
|
175
|
-
});
|
176
|
-
}
|
177
172
|
dynamicQueryInfo.select.forEach((select, index) => {
|
178
|
-
writer.write(`if (
|
179
|
-
writer.writeLine(`
|
173
|
+
writer.write(`if (isSelected('${tsDescriptor.columns[index].name}'))`).block(() => {
|
174
|
+
writer.writeLine(`selectedSqlFragments.push('${select.fragment}');`);
|
175
|
+
writer.writeLine(`selectedFields.push('${tsDescriptor.columns[index].name}');`);
|
180
176
|
select.parameters.forEach((param) => {
|
181
177
|
writer.writeLine(`paramsValues.push(params?.params?.${param} ?? null);`);
|
182
178
|
});
|
183
179
|
});
|
184
180
|
});
|
181
|
+
writer.blankLine();
|
182
|
+
writer.writeLine('const fromSqlFragments: string[] = [];');
|
185
183
|
dynamicQueryInfo.from.forEach((from) => {
|
186
184
|
var _a;
|
187
|
-
const selectConditions = from.dependOnFields.map((fieldIndex) => `
|
188
|
-
|
189
|
-
selectConditions.unshift('params?.select == null');
|
190
|
-
}
|
191
|
-
const whereConditions = from.dependOnFields.map((fieldIndex) => `where.${tsDescriptor.columns[fieldIndex].name} != null`);
|
185
|
+
const selectConditions = from.dependOnFields.map((fieldIndex) => `isSelected('${tsDescriptor.columns[fieldIndex].name}')`);
|
186
|
+
const whereConditions = from.dependOnFields.map((fieldIndex) => `whereColumns.has('${tsDescriptor.columns[fieldIndex].name}')`);
|
192
187
|
const orderByConditions = ((_a = from.dependOnOrderBy) === null || _a === void 0 ? void 0 : _a.map((orderBy) => `orderBy['${orderBy}'] != null`)) || [];
|
193
188
|
const allConditions = [...selectConditions, ...whereConditions, ...orderByConditions];
|
194
189
|
const paramValues = from.parameters.map((paramIndex) => {
|
@@ -196,33 +191,41 @@ function generateTsCode(sqlOld, queryName, schemaDef, client, isCrud = false) {
|
|
196
191
|
return `params?.params?.${param.name}`;
|
197
192
|
});
|
198
193
|
if (allConditions.length > 0) {
|
199
|
-
writer.
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
});
|
194
|
+
writer.blankLine();
|
195
|
+
writer.writeLine(`if (`);
|
196
|
+
writer.indent().write(`${allConditions.join(`${node_os_1.EOL}\t|| `)}`).newLine();
|
197
|
+
writer.write(') ').inlineBlock(() => {
|
198
|
+
writer.write(`fromSqlFragments.push(\`${from.fragment}\`);`);
|
199
|
+
});
|
200
|
+
paramValues.forEach((paramValues) => {
|
201
|
+
writer.writeLine(`paramsValues.push(${paramValues});`);
|
204
202
|
});
|
205
203
|
}
|
206
204
|
else {
|
207
|
-
writer.writeLine(`
|
205
|
+
writer.writeLine(`fromSqlFragments.push(\`${from.fragment}\`);`);
|
208
206
|
paramValues.forEach((paramValues) => {
|
209
207
|
writer.writeLine(`paramsValues.push(${paramValues});`);
|
210
208
|
});
|
211
209
|
}
|
212
210
|
});
|
213
|
-
writer.
|
211
|
+
writer.blankLine();
|
212
|
+
writer.writeLine('const whereSqlFragments: string[] = [];');
|
213
|
+
writer.blankLine();
|
214
214
|
dynamicQueryInfo.where.forEach((fragment) => {
|
215
215
|
const paramValues = fragment.parameters.map((paramIndex) => {
|
216
216
|
const param = tsDescriptor.parameters[paramIndex];
|
217
217
|
return `params?.params?.${param.name} ?? null`;
|
218
218
|
});
|
219
|
-
writer.writeLine(`
|
219
|
+
writer.writeLine(`whereSqlFragments.push(\`${fragment.fragment}\`);`);
|
220
220
|
paramValues.forEach((paramValues) => {
|
221
221
|
writer.writeLine(`paramsValues.push(${paramValues});`);
|
222
222
|
});
|
223
223
|
});
|
224
|
+
writer.writeLine(`let currentIndex = paramsValues.length;`);
|
225
|
+
writer.writeLine('const placeholder = () => `$${++currentIndex}`;');
|
226
|
+
writer.blankLine();
|
224
227
|
writer.write('params?.where?.forEach(condition => ').inlineBlock(() => {
|
225
|
-
writer.writeLine('const
|
228
|
+
writer.writeLine('const whereClause = whereCondition(condition, placeholder);');
|
226
229
|
dynamicQueryInfo.select.forEach((select, index) => {
|
227
230
|
if (select.parameters.length > 0) {
|
228
231
|
writer.write(`if (condition[0] == '${tsDescriptor.columns[index].name}')`).block(() => {
|
@@ -232,45 +235,44 @@ function generateTsCode(sqlOld, queryName, schemaDef, client, isCrud = false) {
|
|
232
235
|
});
|
233
236
|
}
|
234
237
|
});
|
235
|
-
writer.write('if (
|
236
|
-
writer.writeLine(`
|
237
|
-
writer.write('paramsValues.push(...
|
238
|
+
writer.write('if (whereClause?.hasValue)').block(() => {
|
239
|
+
writer.writeLine(`whereSqlFragments.push(whereClause.sql);`);
|
240
|
+
writer.write('paramsValues.push(...whereClause.values);');
|
238
241
|
});
|
239
242
|
});
|
240
243
|
writer.write(');').newLine();
|
244
|
+
if (dynamicQueryInfo.with.length > 0) {
|
245
|
+
writer.blankLine();
|
246
|
+
writer.writeLine('const withSql = withFragments.length > 0');
|
247
|
+
writer.indent().write('? `WITH${EOL}${withFragments.join(`,${EOL}`)}${EOL}`').newLine();
|
248
|
+
writer.indent().write(`: '';`).newLine();
|
249
|
+
}
|
250
|
+
writer.blankLine();
|
251
|
+
writer.writeLine('const whereSql = whereSqlFragments.length > 0 ? `WHERE ${whereSqlFragments.join(\' AND \')}` : \'\';');
|
252
|
+
writer.blankLine();
|
253
|
+
if (dynamicQueryInfo.with.length > 0) {
|
254
|
+
writer.writeLine('const sql = `${withSql}SELECT');
|
255
|
+
}
|
256
|
+
else {
|
257
|
+
writer.writeLine('const sql = `SELECT');
|
258
|
+
}
|
259
|
+
writer.indent().write('${selectedSqlFragments.join(`,${EOL}`)}').newLine();
|
260
|
+
writer.indent().write('${fromSqlFragments.join(EOL)}').newLine();
|
261
|
+
;
|
262
|
+
writer.indent().write('${whereSql}`;').newLine();
|
263
|
+
writer.blankLine();
|
241
264
|
writer.write(`return client.query({ text: sql, rowMode: 'array', values: paramsValues })`).newLine();
|
242
|
-
writer.indent().write(`.then(res => res.rows.map(row => mapArrayTo${resultTypeName}(row,
|
265
|
+
writer.indent().write(`.then(res => res.rows.map(row => mapArrayTo${resultTypeName}(row, selectedFields)));`);
|
243
266
|
});
|
244
267
|
writer.blankLine();
|
245
|
-
writer.write(`function mapArrayTo${resultTypeName}(data: any,
|
246
|
-
writer.writeLine(`const result
|
247
|
-
writer.
|
248
|
-
|
249
|
-
writer.write(`if (select == null || select.${tsField.name})`).block(() => {
|
250
|
-
writer.writeLine('rowIndex++;');
|
251
|
-
writer.writeLine(`result.${tsField.name} = ${toDriver('data[rowIndex]', tsField)};`);
|
252
|
-
});
|
268
|
+
writer.write(`function mapArrayTo${resultTypeName}(data: any, selectedFields: (keyof ${resultTypeName})[])`).block(() => {
|
269
|
+
writer.writeLine(`const result: ${resultTypeName} = {};`);
|
270
|
+
writer.write(`selectedFields.forEach((field, index) => `).inlineBlock(() => {
|
271
|
+
writer.writeLine(`result[field] = data[index];`);
|
253
272
|
});
|
273
|
+
writer.write(');').newLine();
|
254
274
|
writer.write('return result;');
|
255
275
|
});
|
256
|
-
writer.blankLine();
|
257
|
-
writer.write('function appendSelect(sql: string, selectField: string)').block(() => {
|
258
|
-
writer.write(`if (sql.toUpperCase().endsWith('SELECT'))`).block(() => {
|
259
|
-
writer.writeLine('return sql + EOL + selectField;');
|
260
|
-
});
|
261
|
-
writer.write('else').block(() => {
|
262
|
-
writer.writeLine(`return sql + ', ' + EOL + selectField;`);
|
263
|
-
});
|
264
|
-
});
|
265
|
-
writer.blankLine();
|
266
|
-
writer.write(`function whereConditionsToObject(whereConditions?: ${whereTypeName}[])`).block(() => {
|
267
|
-
writer.writeLine('const obj = {} as any;');
|
268
|
-
writer.write('whereConditions?.forEach(condition => ').inlineBlock(() => {
|
269
|
-
writer.writeLine('obj[condition[0]] = true;');
|
270
|
-
});
|
271
|
-
writer.write(');');
|
272
|
-
writer.writeLine('return obj;');
|
273
|
-
});
|
274
276
|
// if (orderByField != null) {
|
275
277
|
// writer.blankLine();
|
276
278
|
// writer.write(`function orderByToObject(orderBy: ${dynamicParamsTypeName}['orderBy'])`).block(() => {
|
@@ -289,47 +291,46 @@ function generateTsCode(sqlOld, queryName, schemaDef, client, isCrud = false) {
|
|
289
291
|
writer.writeLine('values: any[];');
|
290
292
|
});
|
291
293
|
writer.blankLine();
|
292
|
-
writer.write(`function whereCondition(condition: ${whereTypeName}): WhereConditionResult | null `).block(() => {
|
293
|
-
writer.
|
294
|
-
writer.writeLine('const
|
295
|
-
writer.writeLine('const operator = condition[1];');
|
294
|
+
writer.write(`function whereCondition(condition: ${whereTypeName}, placeholder: () => string): WhereConditionResult | null `).block(() => {
|
295
|
+
writer.writeLine('const selectFragment = selectFragments[condition.column];');
|
296
|
+
writer.writeLine('const { op, value } = condition;');
|
296
297
|
writer.blankLine();
|
297
298
|
if ((0, code_generator_1.hasStringColumn)(tsDescriptor.columns)) {
|
298
|
-
writer.write(`if (
|
299
|
+
writer.write(`if (op === 'LIKE') `).block(() => {
|
299
300
|
writer.write('return ').block(() => {
|
300
301
|
writer.writeLine("sql: `${selectFragment} LIKE ${placeholder()}`,");
|
301
|
-
writer.writeLine('hasValue:
|
302
|
-
writer.writeLine('values: [
|
302
|
+
writer.writeLine('hasValue: value != null,');
|
303
|
+
writer.writeLine('values: [value]');
|
303
304
|
});
|
304
305
|
});
|
305
306
|
}
|
306
|
-
writer.write(`if (
|
307
|
+
writer.write(`if (op === 'BETWEEN') `).block(() => {
|
308
|
+
writer.writeLine('const [from, to] = Array.isArray(value) ? value : [null, null];');
|
307
309
|
writer.write('return ').block(() => {
|
308
310
|
writer.writeLine('sql: `${selectFragment} BETWEEN ${placeholder()} AND ${placeholder()}`,');
|
309
|
-
writer.writeLine('hasValue:
|
310
|
-
writer.writeLine('values: [
|
311
|
+
writer.writeLine('hasValue: from != null && to != null,');
|
312
|
+
writer.writeLine('values: [from, to]');
|
311
313
|
});
|
312
314
|
});
|
313
|
-
writer.write(`if (
|
315
|
+
writer.write(`if (op === 'IN' || op === 'NOT IN') `).block(() => {
|
316
|
+
writer.write('if (!Array.isArray(value) || value.length === 0)').block(() => {
|
317
|
+
writer.writeLine(`return { sql: '', hasValue: false, values: [] };`);
|
318
|
+
});
|
314
319
|
writer.write('return ').block(() => {
|
315
|
-
writer.writeLine("sql: `${selectFragment} ${
|
316
|
-
writer.writeLine('hasValue:
|
317
|
-
writer.writeLine('values:
|
320
|
+
writer.writeLine("sql: `${selectFragment} ${op} (${value.map(() => placeholder()).join(', ')})`,");
|
321
|
+
writer.writeLine('hasValue: true,');
|
322
|
+
writer.writeLine('values: value');
|
318
323
|
});
|
319
324
|
});
|
320
|
-
writer.write('if (NumericOperatorList.includes(
|
325
|
+
writer.write('if (NumericOperatorList.includes(op)) ').block(() => {
|
321
326
|
writer.write('return ').block(() => {
|
322
|
-
writer.writeLine('sql: `${selectFragment} ${
|
323
|
-
writer.writeLine('hasValue:
|
324
|
-
writer.writeLine('values: [
|
327
|
+
writer.writeLine('sql: `${selectFragment} ${op} ${placeholder()}`,');
|
328
|
+
writer.writeLine('hasValue: value != null,');
|
329
|
+
writer.writeLine('values: [value]');
|
325
330
|
});
|
326
331
|
});
|
327
332
|
writer.writeLine('return null;');
|
328
333
|
});
|
329
|
-
writer.blankLine();
|
330
|
-
writer.write('function placeholder(): string').block(() => {
|
331
|
-
writer.writeLine('return `$${++currentIndex}`;');
|
332
|
-
});
|
333
334
|
}
|
334
335
|
if (tsDescriptor.nestedDescriptor2) {
|
335
336
|
const relations = tsDescriptor.nestedDescriptor2;
|
@@ -339,13 +340,13 @@ function generateTsCode(sqlOld, queryName, schemaDef, client, isCrud = false) {
|
|
339
340
|
writer.write(`export type ${relationType} = `).block(() => {
|
340
341
|
const uniqueNameFields = (0, code_generator_1.renameInvalidNames)(relation.fields.map((f) => f.name));
|
341
342
|
relation.fields.forEach((field, index) => {
|
342
|
-
const
|
343
|
-
writer.writeLine(`${uniqueNameFields[index]}: ${field.tsType}${
|
343
|
+
const nullable = field.notNull ? '' : ' | null';
|
344
|
+
writer.writeLine(`${uniqueNameFields[index]}: ${field.tsType}${nullable};`);
|
344
345
|
});
|
345
346
|
relation.relations.forEach((field) => {
|
346
347
|
const nestedRelationType = (0, code_generator_1.generateRelationType)(capitalizedName, field.tsType);
|
347
|
-
const
|
348
|
-
writer.writeLine(`${field.name}
|
348
|
+
const nullable = field.notNull ? '' : ' | null';
|
349
|
+
writer.writeLine(`${field.name}: ${nestedRelationType}${nullable};`);
|
349
350
|
});
|
350
351
|
});
|
351
352
|
});
|
@@ -364,8 +365,10 @@ function generateTsCode(sqlOld, queryName, schemaDef, client, isCrud = false) {
|
|
364
365
|
parameters: tsDescriptor.parameters,
|
365
366
|
data: tsDescriptor.data || [],
|
366
367
|
returning: schemaDef.returning || false,
|
368
|
+
orderByTypeName: orderByTypeName,
|
369
|
+
orderByColumns: tsDescriptor.orderByColumns || [],
|
367
370
|
generateNested: tsDescriptor.nestedDescriptor2 != null,
|
368
|
-
nestedType: tsDescriptor.nestedDescriptor2 ? tsDescriptor.nestedDescriptor2[0].name : ''
|
371
|
+
nestedType: tsDescriptor.nestedDescriptor2 ? tsDescriptor.nestedDescriptor2[0].name : '',
|
369
372
|
};
|
370
373
|
codeWriter.writeExecFunction(writer, execFunctionParams);
|
371
374
|
}
|
@@ -436,15 +439,16 @@ function writeParamsType(writer, paramsTypeName, params, generateOrderBy, orderB
|
|
436
439
|
writer.writeLine(`${field.name}${optionalOp}: ${field.tsType}${orNull};`);
|
437
440
|
});
|
438
441
|
if (generateOrderBy) {
|
439
|
-
writer.writeLine(`orderBy:
|
442
|
+
writer.writeLine(`orderBy: ${orderByTypeName}[];`);
|
440
443
|
}
|
441
444
|
});
|
442
445
|
}
|
443
446
|
function writeResultType(writer, resultTypeName, columns) {
|
444
447
|
writer.write(`export type ${resultTypeName} =`).block(() => {
|
445
448
|
columns.forEach((field) => {
|
446
|
-
const optionalOp = field.
|
447
|
-
|
449
|
+
const optionalOp = field.optional ? '?' : '';
|
450
|
+
const nullable = field.notNull ? '' : ' | null';
|
451
|
+
writer.writeLine(`${field.name}${optionalOp}: ${field.tsType}${nullable};`);
|
448
452
|
});
|
449
453
|
});
|
450
454
|
}
|
@@ -457,9 +461,9 @@ function writeJsonTypes(writer, typeName, type) {
|
|
457
461
|
writer.write(`export type ${typeName}Type =`).block(() => {
|
458
462
|
type.properties.forEach((field) => {
|
459
463
|
if (isJsonObjType(field.type)) {
|
460
|
-
const
|
464
|
+
const nullable = field.type.notNull ? '' : ' | null';
|
461
465
|
const jsonTypeName = createJsonType(typeName, field.key);
|
462
|
-
writer.writeLine(`${field.key}
|
466
|
+
writer.writeLine(`${field.key}: ${jsonTypeName}Type${nullable};`);
|
463
467
|
}
|
464
468
|
else if (isJsonArrayType(field.type)) {
|
465
469
|
const jsonParentName = createJsonType(typeName, field.key);
|
@@ -467,8 +471,8 @@ function writeJsonTypes(writer, typeName, type) {
|
|
467
471
|
writer.writeLine(`${field.key}: ${jsonTypeName};`);
|
468
472
|
}
|
469
473
|
else if (isJsonFieldType(field.type)) {
|
470
|
-
const
|
471
|
-
writer.writeLine(`${field.key}
|
474
|
+
const nullable = field.type.notNull ? '' : ' | null';
|
475
|
+
writer.writeLine(`${field.key}: ${(0, postgres_1.mapColumnType)(field.type.type, true)}${nullable};`);
|
472
476
|
}
|
473
477
|
});
|
474
478
|
});
|
@@ -484,6 +488,9 @@ function createTsDescriptor(capitalizedName, schemaDef) {
|
|
484
488
|
parameterNames: [],
|
485
489
|
data: (_a = schemaDef.data) === null || _a === void 0 ? void 0 : _a.map(param => mapParameterToTsFieldDescriptor(param))
|
486
490
|
};
|
491
|
+
if (schemaDef.orderByColumns) {
|
492
|
+
tsDescriptor.orderByColumns = schemaDef.orderByColumns;
|
493
|
+
}
|
487
494
|
if (schemaDef.nestedInfo) {
|
488
495
|
const nestedDescriptor2 = schemaDef.nestedInfo.map((relation) => {
|
489
496
|
const tsRelation = {
|
@@ -539,7 +546,8 @@ function mapColumnInfoToTsFieldDescriptor(capitalizedName, col, dynamicQuery) {
|
|
539
546
|
const tsField = {
|
540
547
|
name: col.name,
|
541
548
|
tsType: createTsType(typeName, col.type),
|
542
|
-
|
549
|
+
optional: dynamicQuery ? true : false,
|
550
|
+
notNull: dynamicQuery ? true : col.notNull
|
543
551
|
};
|
544
552
|
return tsField;
|
545
553
|
}
|
@@ -601,12 +609,12 @@ function _writeCopyFunction(writer, params) {
|
|
601
609
|
});
|
602
610
|
}
|
603
611
|
function _writeExecFunction(writer, params) {
|
604
|
-
const { functionName, paramsType, dataType, returnType, parameters, generateNested, nestedType } = params;
|
612
|
+
const { functionName, paramsType, dataType, returnType, parameters, orderByTypeName, orderByColumns, generateNested, nestedType } = params;
|
605
613
|
let functionParams = params.queryType === 'Copy' ? 'client: pg.Client | pg.PoolClient' : 'client: pg.Client | pg.Pool | pg.PoolClient';
|
606
614
|
if (params.data.length > 0) {
|
607
615
|
functionParams += `, data: ${dataType}`;
|
608
616
|
}
|
609
|
-
if (parameters.length > 0) {
|
617
|
+
if (parameters.length > 0 || orderByColumns.length > 0) {
|
610
618
|
functionParams += `, params: ${paramsType}`;
|
611
619
|
}
|
612
620
|
const allParamters = [...params.data.map(param => paramToDriver(param, 'data')),
|
@@ -671,6 +679,34 @@ function _writeExecFunction(writer, params) {
|
|
671
679
|
});
|
672
680
|
writer.writeLine('return result;');
|
673
681
|
});
|
682
|
+
if (orderByColumns.length > 0) {
|
683
|
+
writer.blankLine();
|
684
|
+
writer.writeLine(`const orderByColumns = [${orderByColumns.map(col => `'${col}'`).join(', ')}] as const;`);
|
685
|
+
writer.blankLine();
|
686
|
+
writer.write(`export type ${orderByTypeName} =`).block(() => {
|
687
|
+
writer.writeLine('column: typeof orderByColumns[number];');
|
688
|
+
writer.writeLine(`direction: 'asc' | 'desc';`);
|
689
|
+
});
|
690
|
+
writer.blankLine();
|
691
|
+
writer.write(`function buildOrderBy(orderBy: ${orderByTypeName}[]): string`).block(() => {
|
692
|
+
writer.write('if (!Array.isArray(orderBy) || orderBy.length === 0)').block(() => {
|
693
|
+
writer.writeLine(`throw new Error('orderBy must be a non-empty array');`);
|
694
|
+
});
|
695
|
+
writer.blankLine();
|
696
|
+
writer.write('for (const { column, direction } of orderBy)').block(() => {
|
697
|
+
writer.write('if (!orderByColumns.includes(column))').block(() => {
|
698
|
+
writer.writeLine('throw new Error(`Invalid orderBy column: ${column}`);');
|
699
|
+
});
|
700
|
+
writer.write(`if (direction !== 'asc' && direction !== 'desc')`).block(() => {
|
701
|
+
writer.writeLine('throw new Error(`Invalid orderBy direction: ${direction}`);');
|
702
|
+
});
|
703
|
+
});
|
704
|
+
writer.blankLine();
|
705
|
+
writer.writeLine('return orderBy');
|
706
|
+
writer.indent().write('.map(({ column, direction }) => `"${column}" ${direction.toUpperCase()}`)').newLine();
|
707
|
+
writer.indent().write(`.join(', ');`).newLine();
|
708
|
+
});
|
709
|
+
}
|
674
710
|
if (generateNested) {
|
675
711
|
writer.blankLine();
|
676
712
|
const relationType = (0, code_generator_1.generateRelationType)(functionName, nestedType);
|
@@ -722,7 +758,7 @@ function getColumnsForQuery(capitalizedName, schemaDef) {
|
|
722
758
|
}
|
723
759
|
function toDriver(variableData, param) {
|
724
760
|
if (param.tsType === 'Date') {
|
725
|
-
if (param.notNull) {
|
761
|
+
if (param.notNull && !param.optional) {
|
726
762
|
return `new Date(${variableData})`;
|
727
763
|
}
|
728
764
|
return `${variableData} != null ? new Date(${variableData}) : ${variableData}`;
|
@@ -769,7 +805,7 @@ function generateCrud(queryType, tableName, dbSchema) {
|
|
769
805
|
writeParamsType(writer, paramsTypeName, uniqueParams, false, '');
|
770
806
|
}
|
771
807
|
writer.blankLine();
|
772
|
-
const columns = allColumns.map(col => mapPostgresColumnSchemaToTsFieldDescriptor(col));
|
808
|
+
const columns = allColumns.map(col => (Object.assign(Object.assign({}, mapPostgresColumnSchemaToTsFieldDescriptor(col)), { optional: false })));
|
773
809
|
writeResultType(writer, resultTypeName, columns);
|
774
810
|
writer.blankLine();
|
775
811
|
const crudParameters = {
|