@technicity/data-service-generator 0.14.0 → 0.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/generation/generate.d.ts +0 -1
- package/dist/generation/generate.js +309 -917
- package/dist/ksql.d.ts +15 -0
- package/dist/ksql.js +55 -0
- package/dist/runtime/Cache.js +3 -6
- package/dist/runtime/IRuntime.d.ts +17 -46
- package/dist/runtime/RuntimeKSQL.d.ts +19 -0
- package/dist/runtime/RuntimeKSQL.js +446 -0
- package/dist/runtime/RuntimeMSSQL.d.ts +1 -7
- package/dist/runtime/RuntimeMSSQL.js +4 -4
- package/dist/runtime/RuntimeMySQL.d.ts +1 -3
- package/dist/runtime/RuntimeMySQL.js +7 -33
- package/dist/runtime/lib/MSSQL.d.ts +1 -2
- package/dist/runtime/lib/MSSQL.js +8 -36
- package/dist/runtime/lib/MySQL.d.ts +1 -1
- package/dist/runtime/lib/MySQL.js +2 -15
- package/dist/runtime/lib/getSqlAst.js +121 -158
- package/dist/runtime/lib/runTransforms.d.ts +2 -0
- package/dist/runtime/lib/runTransforms.js +36 -0
- package/dist/runtime/lib/shared.d.ts +2 -1
- package/dist/runtime/lib/shared.js +71 -180
- package/dist/runtime/lib/stringifyWhere.js +12 -39
- package/dist/runtime/lib/typeCastMSSQL.js +1 -24
- package/dist/traverseFieldArgs.d.ts +2 -2
- package/dist/traverseFieldArgs.js +3 -8
- package/package.json +4 -1
- package/dist/runtime/RuntimeSQLite.d.ts +0 -38
- package/dist/runtime/RuntimeSQLite.js +0 -135
- package/dist/runtime/lib/addNullFallbacks.test.d.ts +0 -1
- package/dist/runtime/lib/addNullFallbacks.test.js +0 -206
- package/dist/runtime/lib/stringifyWhere.test.d.ts +0 -1
- package/dist/runtime/lib/stringifyWhere.test.js +0 -236
- package/dist/traverseFieldArgs.test.d.ts +0 -1
- package/dist/traverseFieldArgs.test.js +0 -56
|
@@ -1,44 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
-
};
|
|
28
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
3
|
exports.generate = void 0;
|
|
30
|
-
const path =
|
|
31
|
-
const fs =
|
|
32
|
-
const os =
|
|
33
|
-
const child_process =
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
const mssql =
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const fs = require("fs");
|
|
6
|
+
const os = require("os");
|
|
7
|
+
const child_process = require("child_process");
|
|
8
|
+
const prettier = require("prettier");
|
|
9
|
+
const changeCase = require("change-case");
|
|
10
|
+
const fse = require("fs-extra");
|
|
11
|
+
const _ = require("lodash/fp");
|
|
12
|
+
const uuid_1 = require("uuid");
|
|
13
|
+
const mssql = require("mssql");
|
|
40
14
|
// @ts-ignore
|
|
41
|
-
const TSqlString =
|
|
15
|
+
const TSqlString = require("tsqlstring");
|
|
42
16
|
const json_schema_to_typescript_1 = require("json-schema-to-typescript");
|
|
43
17
|
const getDuplicates_1 = require("../lib/getDuplicates");
|
|
44
18
|
const isNotNullOrUndefined_1 = require("../lib/isNotNullOrUndefined");
|
|
@@ -51,9 +25,8 @@ const MySQL_1 = require("../runtime/lib/MySQL");
|
|
|
51
25
|
let query = undefined;
|
|
52
26
|
let dialect = "mysql";
|
|
53
27
|
const json2TsOpts = {
|
|
54
|
-
bannerComment: ""
|
|
28
|
+
bannerComment: "",
|
|
55
29
|
};
|
|
56
|
-
const keyFields = "$fields";
|
|
57
30
|
async function generate(input) {
|
|
58
31
|
if (input.tables != null && input.excludeTables != null) {
|
|
59
32
|
throw new Error("Must specify either `tables` or `excludeTables`, not both");
|
|
@@ -84,26 +57,22 @@ async function generate(input) {
|
|
|
84
57
|
getPatchOneData(x, specialCaseUuidColumn, includeMappedFields),
|
|
85
58
|
getPatchListData(x),
|
|
86
59
|
getDeleteOneData(x),
|
|
87
|
-
getDeleteListData(x)
|
|
60
|
+
getDeleteListData(x),
|
|
88
61
|
]));
|
|
89
|
-
const
|
|
90
|
-
const
|
|
91
|
-
const sdkSource = await getSDKSource(data, specialCaseUuidColumn, supplementClientOpts, artifacts);
|
|
62
|
+
const artifactsSource = await getArtifactsSource(tables, includeMappedFields, specialCaseUuidColumn);
|
|
63
|
+
const sdkSource = await getSDKSource(data, specialCaseUuidColumn, supplementClientOpts);
|
|
92
64
|
const sdkFilename = "index.ts";
|
|
93
|
-
const sourceIRuntimeFilePath = fs.existsSync(path.join(__dirname, "../runtime", "IRuntime.ts"))
|
|
94
|
-
? path.join(__dirname, "../runtime", "IRuntime.ts")
|
|
95
|
-
: path.join(__dirname, "../runtime", "IRuntime.js");
|
|
96
|
-
const IRuntimeFilename = path.basename(sourceIRuntimeFilePath);
|
|
97
65
|
const artifactsFilename = "artifacts.ts";
|
|
66
|
+
const IRuntimeFilename = "IRuntime.d.ts";
|
|
98
67
|
const tsConfigJSON = {
|
|
99
68
|
compilerOptions: {
|
|
100
69
|
module: "commonjs",
|
|
101
70
|
moduleResolution: "node",
|
|
102
71
|
target: "es2020",
|
|
103
72
|
declaration: true,
|
|
104
|
-
outDir: "./sdk-ts"
|
|
73
|
+
outDir: "./sdk-ts",
|
|
105
74
|
},
|
|
106
|
-
include: [sdkFilename, artifactsFilename, IRuntimeFilename]
|
|
75
|
+
include: [sdkFilename, artifactsFilename, IRuntimeFilename],
|
|
107
76
|
};
|
|
108
77
|
const packageJSON = {
|
|
109
78
|
name: "temp",
|
|
@@ -112,15 +81,14 @@ async function generate(input) {
|
|
|
112
81
|
dependencies: require("../../package.json").dependencies,
|
|
113
82
|
devDependencies: {
|
|
114
83
|
"@types/node": require("../../package.json").devDependencies["@types/node"],
|
|
115
|
-
typescript: require("../../package.json").devDependencies.typescript
|
|
116
|
-
}
|
|
84
|
+
typescript: require("../../package.json").devDependencies.typescript,
|
|
85
|
+
},
|
|
117
86
|
};
|
|
118
|
-
const tmpDirPath = path.join(os.tmpdir(),
|
|
119
|
-
// _ because - in filename is not supported by mysql2sqlite
|
|
120
|
-
`dsg_${node_crypto_1.default.randomUUID()}`.replace(/-/g, "_"));
|
|
87
|
+
const tmpDirPath = path.join(os.tmpdir(), `dsg-${(0, uuid_1.v4)()}`);
|
|
121
88
|
fse.mkdirpSync(tmpDirPath);
|
|
122
89
|
fs.writeFileSync(path.join(tmpDirPath, sdkFilename), sdkSource);
|
|
123
90
|
fs.writeFileSync(path.join(tmpDirPath, artifactsFilename), artifactsSource);
|
|
91
|
+
const sourceIRuntimeFilePath = path.join(__dirname, "../runtime", IRuntimeFilename);
|
|
124
92
|
fse.copyFileSync(sourceIRuntimeFilePath, path.join(tmpDirPath, IRuntimeFilename));
|
|
125
93
|
const typesDirPath = path.join(tmpDirPath, "types");
|
|
126
94
|
fse.mkdirpSync(typesDirPath);
|
|
@@ -160,40 +128,7 @@ async function generate(input) {
|
|
|
160
128
|
.join("\n"));
|
|
161
129
|
// TODO: workaround for IRuntime.d.ts not being included
|
|
162
130
|
// copyFileSync hangs for some reason, so use writeFileSync + readFileSync instead
|
|
163
|
-
fs.writeFileSync(path.join(tmpBuildOutputPath,
|
|
164
|
-
? fs.readFileSync(path.join(__dirname, "../runtime", "IRuntime.d.ts"))
|
|
165
|
-
: fs.readFileSync(sourceIRuntimeFilePath));
|
|
166
|
-
if (dialect === "mysql" && input.outputSqliteSchema) {
|
|
167
|
-
// Since mysql2sqlite outputs a malformed string if a column
|
|
168
|
-
// has the name `enum`, temporarily change the name to something else,
|
|
169
|
-
// then change it back.
|
|
170
|
-
const enumMarker = "`" + node_crypto_1.default.randomUUID() + "`";
|
|
171
|
-
const schemaMySql = Object.values(artifacts)
|
|
172
|
-
.reduce((acc, x) => {
|
|
173
|
-
let d = x.dump?.schema;
|
|
174
|
-
if (!d) {
|
|
175
|
-
return acc;
|
|
176
|
-
}
|
|
177
|
-
d = d.replace(/`enum`/g, enumMarker);
|
|
178
|
-
d += ";";
|
|
179
|
-
acc.push(d);
|
|
180
|
-
return acc;
|
|
181
|
-
}, [])
|
|
182
|
-
.join("\n\n");
|
|
183
|
-
const mysql2SqliteSrc = getMysql2sqliteSrc();
|
|
184
|
-
const mysql2SqlitePath = path.join(tmpDirPath, "mysql2sqlite");
|
|
185
|
-
fs.writeFileSync(mysql2SqlitePath, mysql2SqliteSrc);
|
|
186
|
-
fs.chmodSync(mysql2SqlitePath, 0o755);
|
|
187
|
-
const tmpMySqlSchemaFilename = "tmp.sql";
|
|
188
|
-
const tmpMySqlSchemaPath = path.join(tmpDirPath, tmpMySqlSchemaFilename);
|
|
189
|
-
fs.writeFileSync(tmpMySqlSchemaPath, schemaMySql);
|
|
190
|
-
let schemaSqlite = child_process
|
|
191
|
-
.execFileSync(mysql2SqlitePath, [tmpMySqlSchemaFilename], { cwd: tmpDirPath })
|
|
192
|
-
.toString();
|
|
193
|
-
schemaSqlite = schemaSqlite.replace(new RegExp(enumMarker, "g"), "`enum`");
|
|
194
|
-
const src = prettier.format(`module.exports = { schema: \`${schemaSqlite.replace(/`/g, "\\`")}\` }`, { parser: "babel" });
|
|
195
|
-
fs.writeFileSync(path.join(tmpBuildOutputPath, "artifacts.sqlite.js"), src);
|
|
196
|
-
}
|
|
131
|
+
fs.writeFileSync(path.join(tmpBuildOutputPath, IRuntimeFilename), fs.readFileSync(sourceIRuntimeFilePath));
|
|
197
132
|
if (!fs.existsSync(outdir)) {
|
|
198
133
|
fse.mkdirpSync(outdir);
|
|
199
134
|
}
|
|
@@ -210,17 +145,17 @@ function init(input) {
|
|
|
210
145
|
password,
|
|
211
146
|
host,
|
|
212
147
|
port,
|
|
213
|
-
database
|
|
148
|
+
database,
|
|
214
149
|
});
|
|
215
150
|
query = mysql.query.bind(mysql);
|
|
216
151
|
}
|
|
217
|
-
if (dialect === "mssql") {
|
|
152
|
+
if (dialect === "mssql" || dialect === "ksql") {
|
|
218
153
|
const pool = new mssql.ConnectionPool({
|
|
219
154
|
server: server ?? "localhost",
|
|
220
155
|
user,
|
|
221
156
|
password,
|
|
222
157
|
port,
|
|
223
|
-
database
|
|
158
|
+
database,
|
|
224
159
|
});
|
|
225
160
|
const poolConnect = pool.connect();
|
|
226
161
|
async function runMSSQLQuery(...input) {
|
|
@@ -235,7 +170,7 @@ function init(input) {
|
|
|
235
170
|
}
|
|
236
171
|
// It's a bit awkward to put __whereNeedsProcessing, __prepareWhere on the class,
|
|
237
172
|
// but it allows us to share the same database pool, clientOpts, etc.
|
|
238
|
-
async function getSDKSource(input, specialCaseUuidColumn, supplementClientOpts
|
|
173
|
+
async function getSDKSource(input, specialCaseUuidColumn, supplementClientOpts) {
|
|
239
174
|
function getTypeImports() {
|
|
240
175
|
let set = new Set();
|
|
241
176
|
for (let d of input) {
|
|
@@ -244,7 +179,7 @@ async function getSDKSource(input, specialCaseUuidColumn, supplementClientOpts,
|
|
|
244
179
|
"typeReturnBaseName",
|
|
245
180
|
"typeWhereName",
|
|
246
181
|
"typeOrderByName",
|
|
247
|
-
"typeDataName"
|
|
182
|
+
"typeDataName",
|
|
248
183
|
]) {
|
|
249
184
|
const str = d[k];
|
|
250
185
|
if (str) {
|
|
@@ -269,13 +204,10 @@ async function getSDKSource(input, specialCaseUuidColumn, supplementClientOpts,
|
|
|
269
204
|
clientOpts: { [k: string]: any; },
|
|
270
205
|
otherOpts?: { [k: string]: any; }
|
|
271
206
|
}) {
|
|
272
|
-
|
|
273
|
-
if (opts.clientOpts.filename === ":memory:") {
|
|
274
|
-
otherOpts = { ...otherOpts, createTablesString: require("./artifacts.sqlite").schema }
|
|
275
|
-
}
|
|
207
|
+
opts.otherOpts = opts.otherOpts ?? {}
|
|
276
208
|
this.runtime = new opts.runtime(opts.clientOpts, ${supplementClientOpts === true
|
|
277
|
-
? "{ supplementClientOpts: true, ...otherOpts }"
|
|
278
|
-
: "otherOpts"}, artifacts);
|
|
209
|
+
? "{ supplementClientOpts: true, ...opts.otherOpts }"
|
|
210
|
+
: "opts.otherOpts"}, artifacts);
|
|
279
211
|
}
|
|
280
212
|
|
|
281
213
|
$use(middleware: TMiddleware) {
|
|
@@ -301,363 +233,159 @@ async function getSDKSource(input, specialCaseUuidColumn, supplementClientOpts,
|
|
|
301
233
|
return this.runtime.$shutdown();
|
|
302
234
|
}
|
|
303
235
|
|
|
304
|
-
async $startTransaction(input?: {
|
|
305
|
-
isolationLevel?:
|
|
306
|
-
| "READ UNCOMMITTED"
|
|
307
|
-
| "READ COMMITTED"
|
|
308
|
-
| "REPEATABLE READ"
|
|
309
|
-
| "SERIALIZABLE"
|
|
310
|
-
}) {
|
|
311
|
-
const { dbCall, commit, rollback } = await this.runtime.$startTransaction(input);
|
|
312
|
-
const runtime = this.runtime;
|
|
313
|
-
return {
|
|
314
|
-
$commit: commit,
|
|
315
|
-
$rollback: rollback,
|
|
316
|
-
${(await Promise.all(input.flatMap(async (x) => {
|
|
317
|
-
if (x.kind === "getOne") {
|
|
318
|
-
const findOnes = await getFindOnes(x, specialCaseUuidColumn);
|
|
319
|
-
return getMethodSourceGetOne(x, findOnes, true);
|
|
320
|
-
}
|
|
321
|
-
if (x.kind === "getList") {
|
|
322
|
-
return getMethodSourceGetList(x, true);
|
|
323
|
-
}
|
|
324
|
-
if (x.kind === "getListPaginated") {
|
|
325
|
-
return getMethodSourceGetListPaginated(x, true);
|
|
326
|
-
}
|
|
327
|
-
if (x.kind === "postOne") {
|
|
328
|
-
return getMethodSourcePostOne(x, specialCaseUuidColumn, true);
|
|
329
|
-
}
|
|
330
|
-
if (x.kind === "patchOne") {
|
|
331
|
-
const findOnes = await getFindOnes(x, specialCaseUuidColumn);
|
|
332
|
-
return getMethodSourcePatchOne(x, findOnes, true);
|
|
333
|
-
}
|
|
334
|
-
if (x.kind === "patchList") {
|
|
335
|
-
return getMethodSourcePatchList(x, true);
|
|
336
|
-
}
|
|
337
|
-
if (x.kind === "deleteOne") {
|
|
338
|
-
const findOnes = await getFindOnes(x, specialCaseUuidColumn);
|
|
339
|
-
return getMethodSourceDeleteOne(x, findOnes, true);
|
|
340
|
-
}
|
|
341
|
-
if (x.kind === "deleteList") {
|
|
342
|
-
return getMethodSourceDeleteList(x, true);
|
|
343
|
-
}
|
|
344
|
-
}))).join(",\n")}
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
|
|
348
236
|
${(await Promise.all(input.flatMap(async (x) => {
|
|
237
|
+
let findOnes = [];
|
|
238
|
+
const primaryColumn = await getPrimaryColumn(x.table);
|
|
239
|
+
const uniqueColumns = await getUniqueColumns(x.table, specialCaseUuidColumn);
|
|
240
|
+
findOnes = findOnes
|
|
241
|
+
.concat([primaryColumn])
|
|
242
|
+
.concat(uniqueColumns)
|
|
243
|
+
.map((x) => ({
|
|
244
|
+
...x,
|
|
245
|
+
type: x.type === "integer" ? "number" : x.type,
|
|
246
|
+
}));
|
|
349
247
|
if (x.kind === "getOne") {
|
|
350
|
-
|
|
351
|
-
|
|
248
|
+
return `async ${x.methodName}(
|
|
249
|
+
param1: ${findOnes
|
|
250
|
+
.map((findOne) => `{ ${findOne.name}: ${findOne.type}${findOne.nullable ? " | null" : ""} }`)
|
|
251
|
+
.join(" | ")},
|
|
252
|
+
param2?: { fields?: ${x.typeFieldsName}, correlationId?: string, skipCache?: boolean, context?: TContext }
|
|
253
|
+
): Promise<${x.typeReturnBaseName}> {
|
|
254
|
+
return this.runtime.resolve(
|
|
255
|
+
{
|
|
256
|
+
resource: "${x.table}",
|
|
257
|
+
action: "findUnique",
|
|
258
|
+
args: { $where: param1 },
|
|
259
|
+
fields: param2?.fields,
|
|
260
|
+
artifacts,
|
|
261
|
+
context: param2?.context,
|
|
262
|
+
skipCache: param2?.skipCache
|
|
263
|
+
}
|
|
264
|
+
);
|
|
265
|
+
}`;
|
|
352
266
|
}
|
|
353
267
|
if (x.kind === "getList") {
|
|
354
|
-
return
|
|
268
|
+
return `async ${x.methodName}(
|
|
269
|
+
param1: { $where?: ${x.typeWhereName}, $orderBy?: ${x.typeOrderByName}, $limit?: number },
|
|
270
|
+
param2?: { fields?: ${x.typeFieldsName}, correlationId?: string, skipCache?: boolean, context?: TContext }
|
|
271
|
+
): Promise<Array<${x.typeReturnBaseName}>> {
|
|
272
|
+
return this.runtime.resolve(
|
|
273
|
+
{
|
|
274
|
+
resource: "${x.table}",
|
|
275
|
+
action: "findMany",
|
|
276
|
+
args: param1,
|
|
277
|
+
fields: param2?.fields,
|
|
278
|
+
artifacts,
|
|
279
|
+
context: param2?.context,
|
|
280
|
+
skipCache: param2?.skipCache
|
|
281
|
+
}
|
|
282
|
+
);
|
|
283
|
+
}`;
|
|
355
284
|
}
|
|
356
285
|
if (x.kind === "getListPaginated") {
|
|
357
|
-
return
|
|
286
|
+
return `async ${x.methodName}(
|
|
287
|
+
param1: { $where?: ${x.typeWhereName}, $orderBy?: ${x.typeOrderByName}, $paginate: Paginate },
|
|
288
|
+
param2?: { fields?: ${x.typeFieldsName}, correlationId?: string, skipCache?: boolean, context?: TContext }
|
|
289
|
+
): Promise<ListPaginated<${x.typeReturnBaseName}>> {
|
|
290
|
+
return this.runtime.resolve(
|
|
291
|
+
{
|
|
292
|
+
resource: "${x.table}",
|
|
293
|
+
action: "findManyPaginated",
|
|
294
|
+
args: param1,
|
|
295
|
+
fields: param2?.fields,
|
|
296
|
+
artifacts,
|
|
297
|
+
context: param2?.context,
|
|
298
|
+
skipCache: param2?.skipCache
|
|
299
|
+
}
|
|
300
|
+
);
|
|
301
|
+
}`;
|
|
358
302
|
}
|
|
359
303
|
if (x.kind === "postOne") {
|
|
360
|
-
return
|
|
304
|
+
return `async ${x.methodName}(
|
|
305
|
+
data: ${x.typeDataName},
|
|
306
|
+
param2?: { fields?: ${x.typeFieldsName}, correlationId?: string, context?: TContext }
|
|
307
|
+
): Promise<${x.typeReturnBaseName}> {
|
|
308
|
+
return this.runtime.resolve({
|
|
309
|
+
resource: "${x.table}",
|
|
310
|
+
action: "create",
|
|
311
|
+
data,
|
|
312
|
+
artifacts,
|
|
313
|
+
fields: param2?.fields,
|
|
314
|
+
context: {...param2?.context, specialCaseUuidColumn: ${JSON.stringify(specialCaseUuidColumn)}}
|
|
315
|
+
});
|
|
316
|
+
}`;
|
|
361
317
|
}
|
|
362
318
|
if (x.kind === "patchOne") {
|
|
363
|
-
|
|
364
|
-
|
|
319
|
+
return `async ${x.methodName}(
|
|
320
|
+
param1: ${findOnes
|
|
321
|
+
.map((findOne) => `{ ${findOne.name}: ${findOne.type}${findOne.nullable ? " | null" : ""} }`)
|
|
322
|
+
.join(" | ")},
|
|
323
|
+
data: ${x.typeDataName},
|
|
324
|
+
param2?: { fields?: ${x.typeFieldsName}, correlationId?: string, context?: TContext }
|
|
325
|
+
): Promise<${x.typeReturnBaseName}> {
|
|
326
|
+
return this.runtime.resolve({
|
|
327
|
+
resource: "${x.table}",
|
|
328
|
+
action: "update",
|
|
329
|
+
args: { $where: param1 },
|
|
330
|
+
data,
|
|
331
|
+
artifacts,
|
|
332
|
+
fields: param2?.fields,
|
|
333
|
+
context: param2?.context
|
|
334
|
+
});
|
|
335
|
+
}`;
|
|
365
336
|
}
|
|
366
337
|
if (x.kind === "patchList") {
|
|
367
|
-
return
|
|
338
|
+
return `async ${x.methodName}(
|
|
339
|
+
param1: { $where?: ${x.typeWhereName} },
|
|
340
|
+
data: ${x.typeDataName},
|
|
341
|
+
param2?: { fields?: ${x.typeFieldsName}, correlationId?: string, context?: TContext }
|
|
342
|
+
): Promise<Array<${x.typeReturnBaseName}>> {
|
|
343
|
+
return this.runtime.resolve({
|
|
344
|
+
resource: "${x.table}",
|
|
345
|
+
action: "updateMany",
|
|
346
|
+
args: param1,
|
|
347
|
+
data,
|
|
348
|
+
artifacts,
|
|
349
|
+
fields: param2?.fields,
|
|
350
|
+
context: param2?.context
|
|
351
|
+
});
|
|
352
|
+
}`;
|
|
368
353
|
}
|
|
369
354
|
if (x.kind === "deleteOne") {
|
|
370
|
-
|
|
371
|
-
|
|
355
|
+
return `async ${x.methodName}(
|
|
356
|
+
param1: ${findOnes
|
|
357
|
+
.map((findOne) => `{ ${findOne.name}: ${findOne.type}${findOne.nullable ? " | null" : ""} }`)
|
|
358
|
+
.join(" | ")},
|
|
359
|
+
param2?: { correlationId?: string, context?: TContext }
|
|
360
|
+
): Promise<void> {
|
|
361
|
+
await this.runtime.resolve({
|
|
362
|
+
resource: "${x.table}",
|
|
363
|
+
action: "delete",
|
|
364
|
+
args: { $where: param1 },
|
|
365
|
+
artifacts,
|
|
366
|
+
context: param2?.context
|
|
367
|
+
});
|
|
368
|
+
}`;
|
|
372
369
|
}
|
|
373
370
|
if (x.kind === "deleteList") {
|
|
374
|
-
return
|
|
371
|
+
return `async ${x.methodName}(
|
|
372
|
+
param1: { $where?: ${x.typeWhereName} },
|
|
373
|
+
param2?: { correlationId?: string, context?: TContext }
|
|
374
|
+
): Promise<void> {
|
|
375
|
+
await this.runtime.resolve({
|
|
376
|
+
resource: "${x.table}",
|
|
377
|
+
action: "deleteMany",
|
|
378
|
+
args: param1,
|
|
379
|
+
artifacts,
|
|
380
|
+
context: param2?.context
|
|
381
|
+
});
|
|
382
|
+
}`;
|
|
375
383
|
}
|
|
376
384
|
}))).join("\n\n")}
|
|
377
385
|
}
|
|
378
|
-
|
|
379
|
-
${await Promise.all(Object.entries(artifacts).map(async ([table, tableArtifacts]) => {
|
|
380
|
-
const jsonSchema = {
|
|
381
|
-
type: "object",
|
|
382
|
-
properties: tableArtifacts.fields.reduce((acc, x) => {
|
|
383
|
-
if (x.kind === "object") {
|
|
384
|
-
return acc;
|
|
385
|
-
}
|
|
386
|
-
if (x.kind === "scalar" && x.mapped) {
|
|
387
|
-
return acc;
|
|
388
|
-
}
|
|
389
|
-
acc[x.name] =
|
|
390
|
-
x.kind === "enum"
|
|
391
|
-
? { enum: x.values }
|
|
392
|
-
: { type: getJSONTypes(x.type, x.nullable) };
|
|
393
|
-
return acc;
|
|
394
|
-
}, {}),
|
|
395
|
-
required: tableArtifacts.fields
|
|
396
|
-
.filter((x) => x.kind === "scalar" || x.kind === "enum")
|
|
397
|
-
.map((x) => x.name),
|
|
398
|
-
additionalProperties: false
|
|
399
|
-
};
|
|
400
|
-
return (0, json_schema_to_typescript_1.compile)(jsonSchema, getTypeReturnName(table), json2TsOpts);
|
|
401
|
-
})).then((xs) => xs.join(";\n\n"))}
|
|
402
|
-
|
|
403
|
-
${Object.entries(artifacts)
|
|
404
|
-
.map(([table, tableArtifacts]) => {
|
|
405
|
-
// https://pkerschbaum.com/blog/how-prisma-adapts-result-types-based-on-the-actual-arguments-given
|
|
406
|
-
// https://github.com/pkerschbaum/how-prisma-adapts-result-types-based-on-the-actual-arguments-given_example/blob/main/prisma/lib/prisma-client/index.d.ts
|
|
407
|
-
// https://www.typescriptlang.org/play?target=6&ts=4.9.5#code/C4TwDgpgBACglgYwNYCYA8AVANFA0lCAD2AgDsATAZyiQhAHsAzKDAPigF4oBvAWACgoUANowocUngC6ALhaipAbgEBfZfwGhIUAEoQAjgFc4AJwjlcdSpnZc+gkfgk06TFlIC0AfjncVBYjIqWERUTBxcdi8oUggANwgTKDlcdRVhWgZmDCUBTXBoDBNDYAALEEsQazZOHgEhDLpxSUy3HLkMRpApAJIKakYAQwAbSmgAHyhDCghGCXMoSdJDYeGoaNiEpLlMtK623I1+LULiiErq2xZisoqrNHhkdGxdA2MzC3u2VlZ1fO0AMoQYYQBDAAGGABGY2A4SgAFUrvYGplmi4su4dk0iH1gq1mPD1vJMj05JtEmk8scClAABKDShAkFg2rcKBjZnAOSDUggRRQNRUk5QADCpVBSCZoNhLwBOERtRYvSC1HpjOB0qJhLkAL+-CIYHoJmAUGF8LGSTs9XE5DJhgAtpCKdaIPbBnBhnJKMATBIAObqIRGv3w0hwYAASVtMQdTpMaT1AHoAFTJ+rJqAAWXo5GBUAA8iYQ2HgOn04mBAajSbhYXi+HWda4NHlo7nQ5SIN7RAvT7-QmqQFDcbTTTzYkAGISciZnkgACCReoVocQhTadXQgzUpZlEgCDgcwQUDmwOCwHoJ4gwAQpRPJno9tN4oRFutQigG4-W+TFc3HOlHxX0SHcTSWFZhkDD913fLdRVKeh6DGHAAHdSkQO8zGGQYSHIGIcwgagLyvG87wZKAUOBYYADpYM-OjUz-b9E0TZoEGGQxcyA8cTAjUh2M4iYY1WKC11TBioCnYYSBMVD0NvYCTCIy9GGvW9aM3ejNMY2CWIo8UzG4i0AHUDIgPiwBKUSoBg7SeAAAWGCQkCgUpgGAMBKBkFiUN86iwF9Sg3WouB6ETch6AQShEwQeh+IgMBgGi2L7UNWJSCSxMArgILBg8di4DIYBE0oat-SgAEytIP0oAAEUiygVAYiTauvRJ7XmZ9oCNXMkjcHjlJI9Tmu039dNYnrEgAIRAICAFFW0SQZIRBNAeMLXqZuM8NSj0bDgFC0gLJKX5dPEuzuEc5zXPczzvMTXyUP8wLgtC8KGpiuKEASzKUrSorouy3L8qcoqssGP0JBww6AGIEEMJSjQ8SEGXMDwwAhqGDri0UEdKpJ6qiprtIkoEkq6qBDUocNDpPI0oCc71yoGjTvy0tmdM3PT4cRkwjMSUzEggUM4CMczSEs4BrNsjmHKc0gXLcjyvJ8vygdesKIqiz74sS5LH3+jLAZevKCrBjHIc7bHJBgTGrdpwnGpG2WMEGWgoAAAwARtID3FIGB8nzKaAqZpnG3GDqAefx1nvy-OOxs3YA3YgIDWzjaXztly75cV26VYetWTZCzWPti3XfoNuKAayk2QcKjLwct6Gcdt5vrbqhriY50mkDgMAKbmJSTQ933-djj948nxPv0oPuwDT2N22Y1jyByg7+OAebFpMZbVp4gEEBGQYTCnM8FodU6HEFI4h2rUdtDrEXwQ1FkV2-ZsgMhRCQR5azO27F-H+EA-6wR4kA+gv9JCTB4lOCgs5eSLj9JQaWrEAD6sVphbzkN-SBIDoEFiLM-EU9AsH5hKJLDABQkEoOtDfeoVYRy1iISWGhjYuZZzjhVV+Jo9ygkPIgE8hVhjnhUmpO8jBA4UyfiWZ2CcmIfgAmCICMjwygUWMJSCZ0p5wTFIhZC+kMJQCwjhBYpACKDVUqRKA5FKKrAnluBiM9oKsQkAJLichVGRn4hxXMGjlgiToYOO+TCxwWnUe-D8n8cHANAZuV07phgQKgdZYMz9kn4I0V4mhqSWHhijBkuJQh6EOEYTWMJiQ2GRLEjoz83DOTsn3AI48p4RGWPEfeR8FMeJyOngooQSjsGKXUeBQJHDakZj0UhCAckjEmNwvhXM7TrG2Kog49m8jxpsV8anOQPE+LuKEgErR189TWj0mUh+0AeIAHFry2xAMMeggxyBoHOaxIQAJlT9CgLgqB-iIIaOmLmOYsQ8IwItDQrA7yPyEi4PiCqMKrhfJxCqU0ZwYVCGiD0hwekhA6m+cEYFsx5jkExUSckJhyUEtRT8nibCIWTmnAghcS5yXRHJR+AARIMrlhLqDwk5USZENkPlswaGIZwRRDDnHuACYQPKeFcqkKwWQsB+VQC5WkksXKhUrygPZJKHgDTSmNSYB8VLcVivFViwh9ZgB3OAA8p5Ly0DysVZyZVChWB6rZnIMQtK8SuAJG+K1NrvzYotAoX134yTxGXqKm13dE2xsUtSxSeo1ysUuWaC0jrnXPNeeSlFgQ6WQqXNCsNQg4XojcACJFtQS24gFeW5BGjYHMrnDQ9lUA9UeulHywNAqhXRHdbynoQ6pgzFBQsSNiRkh1CrTa0QaJpWyqqG6hV47VX+o1VqvJwBdVLvFXpQ1lBjWEH3MAM1FqY0fmiF4-NgxHmFs3f2sEXqYAqrvfi9Vk6EU4qzeG+9ilo3HptXGrYUE8Vs2TTB39gGU0Lp4pmj8OaKkmCfS+11sEm1ooPjwytQgriLuAyISVkg10XDdTuv9pbgj7vtUesjtrH33OfS6158qv0+s0hBujzba0hsSHRG1c6TBgZYwuyl1lvzExdJe++zD7VwJnF2pc7DmKcMnvUzUfCDxHiEWeZZClJFdMjl43pP5+nsh4Sog9IzNGZwmfBfRMzDEKXmWYixpoxErOoHYmiVnPzOKA24nZ9n7UHJ2QCsZWmXNSRkrMhSXiTOlHWRM0Lia0JC0i8-QWZhjpS20RJHO10lZ3VVk9dWgwS7vW1uXb6etPqpWrkbWuOU3T1zBvjDeNVKrGnKo7ZNk8WptRMB1WIFNJp9WYKl3zQ10vBc5vqmbM1t4OiWitCAaAvEbWmiAbaZQ9otyOhLE6znStXQVjdZW91HrPU67Vt6Wt9YV31q19KmUavdcbhbLGsNo5IxRmMcg6M7andxrzTuRNlvcPJpHUOHdGD00Zn1u1z9KAZacTZ7meMjR5ZLAV4WYYxZFcuxda7ec7tVce7lOrr2dZNcrp9muP2zZ-Yhx3NuAOcbDbh67d23sx7zbM0HF8SPaYRxfEDkw2PRo2eTrQRebZ4wlcp7nW7lXC7VeLi9suX0fofcNt9uuHPir-ftq3LnDsu5w4BPPQephvSexFwerHy2stz37irjOWy15M03ht7su9tu7Yc0fbCp9hHkAvvaK+xTUPfnQ4-A9WHONvM3Hhn5fzMmjLWJMYlM7wUY9YRWsBtQEX1ocMijVPoZWwQfQe2CNL6PUCL6SxvMR42WtTdn4I2SNOTC8apll3bNyieiO+w9GrBV8eiCK8NK6pVnGo2OpVKq1UBrb5qnizHgOnqNSasEN6jSifFdERcu8QBrTzex7DXGt0b+9bxqTu7-3BtL+Gc-bMm-2skyxpBgmuKiNh+J4s3puOAfamckcFSApsOOUtoB2hQCLGLFUqRtBNpnBOovps0kZm0gtlYqZlIpHIhqNgrlsoMvzCYI5sctZFQXsuEjwhTrLFMgYmhHMsCKYnhOYksoQR0qsvYp7rjq4j4oJNQdFoJLFicvFhJIlokMlneDxPwaRPLhzFlnpDlmYIwQLGZKgTKuTnQknomoYJQBDNAHAQ4OxAyNQCKKDBlBgaCuQPoTthgLPkwQ0oXtOqSqwAABSiYnzILci8hEZswYy7z2goC+D4FUBASgQQjQjXhwgEacjsCgEACU-qgcOUrh7hIEPCWod+TqHGr6NQOhJg7Ai+H4ZgwACMkgXKKO9AfK5Ec4sEya8msBRwekwojRKAtQty9+Ge3AgyvgCSHocg9e7m2q4YvgIxPAACPY6KMq8oFosxPCvgzYExZwKgOxuxvGVI5cLujRtQgwKE7oJosQKEoo9hwAvh6R1EThLhvhfgOA3ArSVAoxbo4xSxUxB6axnIvgCxWxyxik-x0oGx0Ykxuxux6RAghxJovRJxZxDYlx1xDctx9xjxpOMqzxKgrx7xXkPACSa8noPxOA0xXIPAcx3AQJZJoJVJ6xPAmxPx0JOxsJ-A8JvyJ8SJ5x3eVxdh6JdxDx04TxLxPAKg7JnJKMJgfRXApxvJqJApRUQpWJosOJYpbxMehJHeYKEpcJcULu0pAAzDySiRAPyTcSqSKdiRALifiVqb4GyQINzAaSaMaaaRceaWicqZidaWqbacMYyccnqfwEAA
|
|
408
|
-
return `export type ${getTypeGetPayloadName(table)}<S extends { ${keyFields}?: ${getTypeFieldsName(table)} } | boolean, U = keyof S> = S extends true ? ${getTypeReturnName(table)} : S extends { ${keyFields}?: ${getTypeFieldsName(table)}, [k: string]: any } ? "${keyFields}" extends U ? S["${keyFields}"] extends undefined ? ${getTypeReturnName(table)} : { [P in TrueKeys<S["${keyFields}"]>]: ${tableArtifacts.fields
|
|
409
|
-
.reduce((acc, x) => {
|
|
410
|
-
if (x.kind !== "object") {
|
|
411
|
-
return acc;
|
|
412
|
-
}
|
|
413
|
-
let str = `P extends "${x.name}" ? ${getTypeGetPayloadName(x.type)}<S["${keyFields}"][P]>`;
|
|
414
|
-
if (x.isList) {
|
|
415
|
-
str += "[]";
|
|
416
|
-
}
|
|
417
|
-
if (x.nullable) {
|
|
418
|
-
str += " | null";
|
|
419
|
-
}
|
|
420
|
-
str += " : ";
|
|
421
|
-
acc.push(str);
|
|
422
|
-
return acc;
|
|
423
|
-
}, [])
|
|
424
|
-
.join("")} ${tableArtifacts.fields
|
|
425
|
-
.reduce((acc, x) => {
|
|
426
|
-
if (x.kind === "scalar" && x.mapped) {
|
|
427
|
-
let type = x.type;
|
|
428
|
-
if (x.nullable) {
|
|
429
|
-
type += " | null";
|
|
430
|
-
}
|
|
431
|
-
const str = `P extends "${x.name}" ? ${type} : `;
|
|
432
|
-
acc.push(str);
|
|
433
|
-
}
|
|
434
|
-
return acc;
|
|
435
|
-
}, [])
|
|
436
|
-
.join("")} P extends keyof ${getTypeReturnName(table)} ? ${getTypeReturnName(table)}[P] : never } : ${getTypeReturnName(table)} : ${getTypeReturnName(table)}`;
|
|
437
|
-
})
|
|
438
|
-
.join(";\n\n")}
|
|
439
|
-
|
|
440
|
-
// Utils
|
|
441
|
-
|
|
442
|
-
type Pick2<T, K extends keyof T> = { [P in K]: T[P]; };
|
|
443
|
-
|
|
444
|
-
type RequiredKeys<T> = {
|
|
445
|
-
[K in keyof T]-?: {} extends Pick2<T, K> ? never : K;
|
|
446
|
-
}[keyof T];
|
|
447
|
-
|
|
448
|
-
type TruthyKeys<T> = {
|
|
449
|
-
[key in keyof T]: T[key] extends false | undefined | null ? never : key;
|
|
450
|
-
}[keyof T];
|
|
451
|
-
|
|
452
|
-
type TrueKeys<T> = TruthyKeys<Pick2<T, RequiredKeys<T>>>;
|
|
453
|
-
|
|
454
|
-
type SelectSubset<T, U> = {
|
|
455
|
-
[key in keyof T]: key extends keyof U ? T[key] : never;
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
type HasSelect = { ${keyFields}: any; };
|
|
459
|
-
|
|
460
|
-
type CheckSelect<T, S, U> = T extends HasSelect ? U : S;
|
|
461
386
|
`;
|
|
462
387
|
return prettier.format(src, { parser: "typescript" });
|
|
463
388
|
}
|
|
464
|
-
async function getFindOnes(x, specialCaseUuidColumn) {
|
|
465
|
-
let findOnes = [];
|
|
466
|
-
const primaryColumn = await getPrimaryColumn(x.table);
|
|
467
|
-
const uniqueColumns = await getUniqueColumns(x.table, specialCaseUuidColumn);
|
|
468
|
-
findOnes = findOnes
|
|
469
|
-
.concat([primaryColumn])
|
|
470
|
-
.concat(uniqueColumns)
|
|
471
|
-
.map((x) => ({
|
|
472
|
-
...x,
|
|
473
|
-
type: x.type === "integer" ? "number" : x.type
|
|
474
|
-
}));
|
|
475
|
-
return findOnes;
|
|
476
|
-
}
|
|
477
|
-
function getMethodSourceGetOne(x, findOnes, isTransaction) {
|
|
478
|
-
const param2 = `{ ${keyFields}?: ${x.typeFieldsName}, correlationId?: string, skipCache?: boolean, context?: TContext }`;
|
|
479
|
-
return `async ${x.methodName}<T extends ${param2}>(
|
|
480
|
-
param1: ${findOnes
|
|
481
|
-
.map((findOne) => `{ ${findOne.name}: ${findOne.type}${findOne.nullable ? " | null" : ""} }`)
|
|
482
|
-
.join(" | ")},
|
|
483
|
-
param2?: SelectSubset<T, ${param2}>
|
|
484
|
-
): Promise<CheckSelect<T, ${getTypeReturnName(x.table)}, ${getTypeGetPayloadName(x.table)}<T>>> {
|
|
485
|
-
return ${isTransaction ? "runtime" : "this.runtime"}.resolve(
|
|
486
|
-
{
|
|
487
|
-
resource: "${x.table}",
|
|
488
|
-
action: "${mapKindToAction(x.kind)}",
|
|
489
|
-
args: { $where: param1 },
|
|
490
|
-
fields: param2?.$fields as any,
|
|
491
|
-
artifacts,
|
|
492
|
-
context: param2?.context,
|
|
493
|
-
skipCache: param2?.skipCache,
|
|
494
|
-
${isTransaction ? "dbCall" : ""}
|
|
495
|
-
}
|
|
496
|
-
);
|
|
497
|
-
}`;
|
|
498
|
-
}
|
|
499
|
-
function getMethodSourceGetList(x, isTransaction) {
|
|
500
|
-
const param2 = `{ ${keyFields}?: ${x.typeFieldsName}, correlationId?: string, skipCache?: boolean, context?: TContext }`;
|
|
501
|
-
return `async ${x.methodName}<T extends ${param2}>(
|
|
502
|
-
param1: { $where?: ${x.typeWhereName}, $orderBy?: ${x.typeOrderByName}, $limit?: number },
|
|
503
|
-
param2?: SelectSubset<T, ${param2}>
|
|
504
|
-
): Promise<Array<CheckSelect<T, ${getTypeReturnName(x.table)}, ${getTypeGetPayloadName(x.table)}<T>>>> {
|
|
505
|
-
return ${isTransaction ? "runtime" : "this.runtime"}.resolve(
|
|
506
|
-
{
|
|
507
|
-
resource: "${x.table}",
|
|
508
|
-
action: "${mapKindToAction(x.kind)}",
|
|
509
|
-
args: param1,
|
|
510
|
-
fields: param2?.$fields as any,
|
|
511
|
-
artifacts,
|
|
512
|
-
context: param2?.context,
|
|
513
|
-
skipCache: param2?.skipCache,
|
|
514
|
-
${isTransaction ? "dbCall" : ""}
|
|
515
|
-
}
|
|
516
|
-
);
|
|
517
|
-
}`;
|
|
518
|
-
}
|
|
519
|
-
function getMethodSourceGetListPaginated(x, isTransaction) {
|
|
520
|
-
const param2 = `{ ${keyFields}?: ${x.typeFieldsName}, correlationId?: string, skipCache?: boolean, context?: TContext }`;
|
|
521
|
-
return `async ${x.methodName}<T extends ${param2}>(
|
|
522
|
-
param1: { $where?: ${x.typeWhereName}, $orderBy?: ${x.typeOrderByName}, $paginate: Paginate },
|
|
523
|
-
param2?: SelectSubset<T, ${param2}>
|
|
524
|
-
): Promise<ListPaginated<CheckSelect<T, ${getTypeReturnName(x.table)}, ${getTypeGetPayloadName(x.table)}<T>>>> {
|
|
525
|
-
return ${isTransaction ? "runtime" : "this.runtime"}.resolve(
|
|
526
|
-
{
|
|
527
|
-
resource: "${x.table}",
|
|
528
|
-
action: "${mapKindToAction(x.kind)}",
|
|
529
|
-
args: param1,
|
|
530
|
-
fields: param2?.$fields as any,
|
|
531
|
-
artifacts,
|
|
532
|
-
context: param2?.context,
|
|
533
|
-
skipCache: param2?.skipCache,
|
|
534
|
-
${isTransaction ? "dbCall" : ""}
|
|
535
|
-
}
|
|
536
|
-
);
|
|
537
|
-
}`;
|
|
538
|
-
}
|
|
539
|
-
function getMethodSourcePostOne(x, specialCaseUuidColumn, isTransaction) {
|
|
540
|
-
const param2 = `{ ${keyFields}?: ${x.typeFieldsName}, correlationId?: string, context?: TContext }`;
|
|
541
|
-
return `async ${x.methodName}<T extends ${param2}>(
|
|
542
|
-
data: ${x.typeDataName},
|
|
543
|
-
param2?: SelectSubset<T, ${param2}>
|
|
544
|
-
): Promise<CheckSelect<T, ${getTypeReturnName(x.table)}, ${getTypeGetPayloadName(x.table)}<T>>> {
|
|
545
|
-
return ${isTransaction ? "runtime" : "this.runtime"}.resolve({
|
|
546
|
-
resource: "${x.table}",
|
|
547
|
-
action: "${mapKindToAction(x.kind)}",
|
|
548
|
-
data,
|
|
549
|
-
artifacts,
|
|
550
|
-
fields: param2?.$fields as any,
|
|
551
|
-
context: {...param2?.context, specialCaseUuidColumn: ${JSON.stringify(specialCaseUuidColumn)}},
|
|
552
|
-
${isTransaction ? "dbCall" : ""}
|
|
553
|
-
});
|
|
554
|
-
}`;
|
|
555
|
-
}
|
|
556
|
-
function getMethodSourcePatchOne(x, findOnes, isTransaction) {
|
|
557
|
-
const param2 = `{ ${keyFields}?: ${x.typeFieldsName}, correlationId?: string, context?: TContext }`;
|
|
558
|
-
return `async ${x.methodName}<T extends ${param2}>(
|
|
559
|
-
param1: ${findOnes
|
|
560
|
-
.map((findOne) => `{ ${findOne.name}: ${findOne.type}${findOne.nullable ? " | null" : ""} }`)
|
|
561
|
-
.join(" | ")},
|
|
562
|
-
data: ${x.typeDataName},
|
|
563
|
-
param2?: SelectSubset<T, ${param2}>
|
|
564
|
-
): Promise<CheckSelect<T, ${getTypeReturnName(x.table)}, ${getTypeGetPayloadName(x.table)}<T>>> {
|
|
565
|
-
return ${isTransaction ? "runtime" : "this.runtime"}.resolve({
|
|
566
|
-
resource: "${x.table}",
|
|
567
|
-
action: "${mapKindToAction(x.kind)}",
|
|
568
|
-
args: { $where: param1 },
|
|
569
|
-
data,
|
|
570
|
-
artifacts,
|
|
571
|
-
fields: param2?.$fields as any,
|
|
572
|
-
context: param2?.context,
|
|
573
|
-
${isTransaction ? "dbCall" : ""}
|
|
574
|
-
});
|
|
575
|
-
}`;
|
|
576
|
-
}
|
|
577
|
-
function getMethodSourcePatchList(x, isTransaction) {
|
|
578
|
-
const param2 = `{ ${keyFields}?: ${x.typeFieldsName}, correlationId?: string, context?: TContext }`;
|
|
579
|
-
return `async ${x.methodName}<T extends ${param2}>(
|
|
580
|
-
param1: { $where?: ${x.typeWhereName}, $orderBy?: ${x.typeOrderByName} },
|
|
581
|
-
data: ${x.typeDataName},
|
|
582
|
-
param2?: SelectSubset<T, ${param2}>
|
|
583
|
-
): Promise<Array<CheckSelect<T, ${getTypeReturnName(x.table)}, ${getTypeGetPayloadName(x.table)}<T>>>> {
|
|
584
|
-
return ${isTransaction ? "runtime" : "this.runtime"}.resolve({
|
|
585
|
-
resource: "${x.table}",
|
|
586
|
-
action: "${mapKindToAction(x.kind)}",
|
|
587
|
-
args: param1,
|
|
588
|
-
data,
|
|
589
|
-
artifacts,
|
|
590
|
-
fields: param2?.$fields as any,
|
|
591
|
-
context: param2?.context,
|
|
592
|
-
${isTransaction ? "dbCall" : ""}
|
|
593
|
-
});
|
|
594
|
-
}`;
|
|
595
|
-
}
|
|
596
|
-
function getMethodSourceDeleteOne(x, findOnes, isTransaction) {
|
|
597
|
-
return `async ${x.methodName}(
|
|
598
|
-
param1: ${findOnes
|
|
599
|
-
.map((findOne) => `{ ${findOne.name}: ${findOne.type}${findOne.nullable ? " | null" : ""} }`)
|
|
600
|
-
.join(" | ")},
|
|
601
|
-
param2?: { correlationId?: string, context?: TContext }
|
|
602
|
-
): Promise<void> {
|
|
603
|
-
await ${isTransaction ? "runtime" : "this.runtime"}.resolve({
|
|
604
|
-
resource: "${x.table}",
|
|
605
|
-
action: "${mapKindToAction(x.kind)}",
|
|
606
|
-
args: { $where: param1 },
|
|
607
|
-
artifacts,
|
|
608
|
-
context: param2?.context,
|
|
609
|
-
${isTransaction ? "dbCall" : ""}
|
|
610
|
-
});
|
|
611
|
-
}`;
|
|
612
|
-
}
|
|
613
|
-
function getMethodSourceDeleteList(x, isTransaction) {
|
|
614
|
-
return `async ${x.methodName}(
|
|
615
|
-
param1: { $where?: ${x.typeWhereName} },
|
|
616
|
-
param2?: { correlationId?: string, context?: TContext }
|
|
617
|
-
): Promise<void> {
|
|
618
|
-
await ${isTransaction ? "runtime" : "this.runtime"}.resolve({
|
|
619
|
-
resource: "${x.table}",
|
|
620
|
-
action: "${mapKindToAction(x.kind)}",
|
|
621
|
-
args: param1,
|
|
622
|
-
artifacts,
|
|
623
|
-
context: param2?.context,
|
|
624
|
-
${isTransaction ? "dbCall" : ""}
|
|
625
|
-
});
|
|
626
|
-
}`;
|
|
627
|
-
}
|
|
628
|
-
function mapKindToAction(kind) {
|
|
629
|
-
if (kind === "getOne") {
|
|
630
|
-
return "findUnique";
|
|
631
|
-
}
|
|
632
|
-
if (kind === "getList") {
|
|
633
|
-
return "findMany";
|
|
634
|
-
}
|
|
635
|
-
if (kind === "getListPaginated") {
|
|
636
|
-
return "findManyPaginated";
|
|
637
|
-
}
|
|
638
|
-
if (kind === "postOne") {
|
|
639
|
-
return "create";
|
|
640
|
-
}
|
|
641
|
-
if (kind === "patchOne") {
|
|
642
|
-
return "update";
|
|
643
|
-
}
|
|
644
|
-
if (kind === "patchList") {
|
|
645
|
-
return "updateMany";
|
|
646
|
-
}
|
|
647
|
-
if (kind === "deleteOne") {
|
|
648
|
-
return "delete";
|
|
649
|
-
}
|
|
650
|
-
if (kind === "deleteList") {
|
|
651
|
-
return "deleteMany";
|
|
652
|
-
}
|
|
653
|
-
throw new Error(`Unhandled kind: ${kind}`);
|
|
654
|
-
}
|
|
655
|
-
function getTypeGetPayloadName(table) {
|
|
656
|
-
return "GetPayload" + changeCase.pascalCase(table);
|
|
657
|
-
}
|
|
658
|
-
function getTypeReturnName(table) {
|
|
659
|
-
return changeCase.pascalCase(table);
|
|
660
|
-
}
|
|
661
389
|
function getTypeReturnBaseName(table) {
|
|
662
390
|
return "ReturnBase" + changeCase.pascalCase(table);
|
|
663
391
|
}
|
|
@@ -683,7 +411,7 @@ async function getGetOneData(table, includeMappedFields) {
|
|
|
683
411
|
typeFields: await getTypeFields(table, typeFieldsName, includeMappedFields),
|
|
684
412
|
typeFieldsName,
|
|
685
413
|
typeReturnBase: await getTypeReturnBase(table, typeReturnBaseName, includeMappedFields),
|
|
686
|
-
typeReturnBaseName
|
|
414
|
+
typeReturnBaseName,
|
|
687
415
|
};
|
|
688
416
|
}
|
|
689
417
|
async function getGetListData(table) {
|
|
@@ -702,7 +430,7 @@ async function getGetListData(table) {
|
|
|
702
430
|
typeWhere,
|
|
703
431
|
typeWhereName,
|
|
704
432
|
typeOrderBy,
|
|
705
|
-
typeOrderByName
|
|
433
|
+
typeOrderByName,
|
|
706
434
|
};
|
|
707
435
|
}
|
|
708
436
|
async function getGetListPaginatedData(table) {
|
|
@@ -717,7 +445,7 @@ async function getGetListPaginatedData(table) {
|
|
|
717
445
|
typeFieldsName,
|
|
718
446
|
typeReturnBaseName,
|
|
719
447
|
typeWhereName,
|
|
720
|
-
typeOrderByName
|
|
448
|
+
typeOrderByName,
|
|
721
449
|
};
|
|
722
450
|
}
|
|
723
451
|
async function getPostOneData(table, specialCaseUuidColumn, includeMappedFields) {
|
|
@@ -731,7 +459,7 @@ async function getPostOneData(table, specialCaseUuidColumn, includeMappedFields)
|
|
|
731
459
|
typeFieldsName,
|
|
732
460
|
typeReturnBaseName,
|
|
733
461
|
typeData: await getTypeDataPost(table, typeDataName, specialCaseUuidColumn, includeMappedFields),
|
|
734
|
-
typeDataName
|
|
462
|
+
typeDataName,
|
|
735
463
|
};
|
|
736
464
|
}
|
|
737
465
|
async function getPatchOneData(table, specialCaseUuidColumn, includeMappedFields) {
|
|
@@ -745,7 +473,7 @@ async function getPatchOneData(table, specialCaseUuidColumn, includeMappedFields
|
|
|
745
473
|
typeFieldsName,
|
|
746
474
|
typeReturnBaseName,
|
|
747
475
|
typeData: await getTypeDataPatch(table, typeDataName, specialCaseUuidColumn, includeMappedFields),
|
|
748
|
-
typeDataName
|
|
476
|
+
typeDataName,
|
|
749
477
|
};
|
|
750
478
|
}
|
|
751
479
|
async function getPatchListData(table) {
|
|
@@ -753,7 +481,6 @@ async function getPatchListData(table) {
|
|
|
753
481
|
const typeReturnBaseName = getTypeReturnBaseName(table);
|
|
754
482
|
const typeWhereName = getTypeWhereName(table);
|
|
755
483
|
const typeDataName = "DataPatch" + changeCase.pascalCase(table);
|
|
756
|
-
const typeOrderByName = getTypeOrderByName(table);
|
|
757
484
|
return {
|
|
758
485
|
kind: "patchList",
|
|
759
486
|
table,
|
|
@@ -762,14 +489,13 @@ async function getPatchListData(table) {
|
|
|
762
489
|
typeReturnBaseName,
|
|
763
490
|
typeWhereName,
|
|
764
491
|
typeDataName,
|
|
765
|
-
typeOrderByName
|
|
766
492
|
};
|
|
767
493
|
}
|
|
768
494
|
function getDeleteOneData(table) {
|
|
769
495
|
return {
|
|
770
496
|
kind: "deleteOne",
|
|
771
497
|
table,
|
|
772
|
-
methodName: "delete" + changeCase.pascalCase(table)
|
|
498
|
+
methodName: "delete" + changeCase.pascalCase(table),
|
|
773
499
|
};
|
|
774
500
|
}
|
|
775
501
|
function getDeleteListData(table) {
|
|
@@ -778,7 +504,7 @@ function getDeleteListData(table) {
|
|
|
778
504
|
kind: "deleteList",
|
|
779
505
|
table,
|
|
780
506
|
methodName: "delete" + changeCase.pascalCase(table) + "List",
|
|
781
|
-
typeWhereName
|
|
507
|
+
typeWhereName,
|
|
782
508
|
};
|
|
783
509
|
}
|
|
784
510
|
async function getTypeWhere(table, name) {
|
|
@@ -790,11 +516,11 @@ async function getTypeDataPost(table, name, specialCaseUuidColumn, includeMapped
|
|
|
790
516
|
const tableMeta = (await getTableMeta(table)).filter((x) => x.Field !== primaryColumn.name);
|
|
791
517
|
const nullable = tableMeta.reduce((acc, m) => ({
|
|
792
518
|
...acc,
|
|
793
|
-
[m.Field]: m.Null === "YES" ? true : false
|
|
519
|
+
[m.Field]: m.Null === "YES" ? true : false,
|
|
794
520
|
}), {});
|
|
795
521
|
const hasDefault = tableMeta.reduce((acc, m) => ({
|
|
796
522
|
...acc,
|
|
797
|
-
[m.Field]: m.Default == null ? false : true
|
|
523
|
+
[m.Field]: m.Default == null ? false : true,
|
|
798
524
|
}), {});
|
|
799
525
|
let properties = getJSONSchemaObjProperties(tableMeta);
|
|
800
526
|
let notRequiredList = [];
|
|
@@ -807,7 +533,7 @@ async function getTypeDataPost(table, name, specialCaseUuidColumn, includeMapped
|
|
|
807
533
|
...mappedFields.reduce((acc, v) => {
|
|
808
534
|
acc[v.as] = { type: getJSONTypes(v.type, v.nullable) };
|
|
809
535
|
return acc;
|
|
810
|
-
}, {})
|
|
536
|
+
}, {}),
|
|
811
537
|
};
|
|
812
538
|
notRequiredList = mappedFields.flatMap((x) => [x.as, x.foreignKey]);
|
|
813
539
|
for (let r of oneToManyRelations) {
|
|
@@ -822,7 +548,9 @@ async function getTypeDataPost(table, name, specialCaseUuidColumn, includeMapped
|
|
|
822
548
|
...oneToManyRelations.reduce((acc, v) => {
|
|
823
549
|
let tsType = getTypeDataPostName(v.table);
|
|
824
550
|
const mappedFields = mappedFieldsMap.get(v.table);
|
|
825
|
-
if (includeMappedFields &&
|
|
551
|
+
if (includeMappedFields &&
|
|
552
|
+
mappedFields != null &&
|
|
553
|
+
mappedFields.length > 0) {
|
|
826
554
|
tsType = `Omit<${tsType}, ${mappedFields
|
|
827
555
|
.map((x) => JSON.stringify(x.as))
|
|
828
556
|
.join(" | ")}>`;
|
|
@@ -830,19 +558,21 @@ async function getTypeDataPost(table, name, specialCaseUuidColumn, includeMapped
|
|
|
830
558
|
tsType = `{$create: ${tsType}[]}`;
|
|
831
559
|
acc[v.name] = { tsType };
|
|
832
560
|
return acc;
|
|
833
|
-
}, {})
|
|
561
|
+
}, {}),
|
|
834
562
|
},
|
|
835
563
|
additionalProperties: false,
|
|
836
564
|
required: Object.keys(properties)
|
|
837
565
|
.filter(
|
|
838
566
|
// `uuid` should not be required
|
|
839
|
-
(x) => !specialCaseUuidColumn || uuidColumn == null
|
|
567
|
+
(x) => !specialCaseUuidColumn || uuidColumn == null
|
|
568
|
+
? true
|
|
569
|
+
: x !== uuidColumn.name)
|
|
840
570
|
.filter(
|
|
841
571
|
// Required if column is non-nullable and has no default.
|
|
842
572
|
(x) => !nullable[x] && !hasDefault[x])
|
|
843
573
|
// Instead of doing a union with all possible permutations of UUID and IDs,
|
|
844
574
|
// for simplicity, just make both not required for now.
|
|
845
|
-
.filter((x) => !notRequiredList.includes(x))
|
|
575
|
+
.filter((x) => !notRequiredList.includes(x)),
|
|
846
576
|
};
|
|
847
577
|
let type = await (0, json_schema_to_typescript_1.compile)(jsonSchema, name, json2TsOpts);
|
|
848
578
|
const imports = _.uniq(oneToManyRelations
|
|
@@ -871,13 +601,13 @@ async function getTypeDataPatch(table, name, specialCaseUuidColumn, includeMappe
|
|
|
871
601
|
const type = unwrapJSONType(properties[key].type);
|
|
872
602
|
if (type === "string") {
|
|
873
603
|
properties[key] = {
|
|
874
|
-
oneOf: [properties[key], { tsType: "TUpdateOperationsString" }]
|
|
604
|
+
oneOf: [properties[key], { tsType: "TUpdateOperationsString" }],
|
|
875
605
|
};
|
|
876
606
|
mustImportTUpdateOperationsString = true;
|
|
877
607
|
}
|
|
878
608
|
else if (type === "number" || type === "integer") {
|
|
879
609
|
properties[key] = {
|
|
880
|
-
oneOf: [properties[key], { tsType: "TUpdateOperationsNumber" }]
|
|
610
|
+
oneOf: [properties[key], { tsType: "TUpdateOperationsNumber" }],
|
|
881
611
|
};
|
|
882
612
|
mustImportTUpdateOperationsNumber = true;
|
|
883
613
|
}
|
|
@@ -889,14 +619,14 @@ async function getTypeDataPatch(table, name, specialCaseUuidColumn, includeMappe
|
|
|
889
619
|
...mappedFields.reduce((acc, v) => {
|
|
890
620
|
acc[v.as] = { type: getJSONTypes(v.type, v.nullable) };
|
|
891
621
|
return acc;
|
|
892
|
-
}, {})
|
|
622
|
+
}, {}),
|
|
893
623
|
};
|
|
894
624
|
}
|
|
895
625
|
const jsonSchema = {
|
|
896
626
|
type: "object",
|
|
897
627
|
properties,
|
|
898
628
|
additionalProperties: false,
|
|
899
|
-
required: []
|
|
629
|
+
required: [],
|
|
900
630
|
};
|
|
901
631
|
let type = await (0, json_schema_to_typescript_1.compile)(jsonSchema, name, json2TsOpts);
|
|
902
632
|
if (mustImportTUpdateOperationsString || mustImportTUpdateOperationsNumber) {
|
|
@@ -939,7 +669,7 @@ async function getMappedFields(table) {
|
|
|
939
669
|
name: "uuid",
|
|
940
670
|
// Replace `Id` with `Uuid`
|
|
941
671
|
as: x.foreignKey.slice(0, -2) + "Uuid",
|
|
942
|
-
type: getBaseJSONType(uuidColumn.Type)
|
|
672
|
+
type: getBaseJSONType(uuidColumn.Type),
|
|
943
673
|
});
|
|
944
674
|
}
|
|
945
675
|
return out;
|
|
@@ -958,52 +688,52 @@ async function getJSONSchemaWhere(table) {
|
|
|
958
688
|
{
|
|
959
689
|
type: "object",
|
|
960
690
|
properties: { $eq: v },
|
|
961
|
-
additionalProperties: false
|
|
691
|
+
additionalProperties: false,
|
|
962
692
|
},
|
|
963
693
|
{
|
|
964
694
|
type: "object",
|
|
965
695
|
properties: { $neq: v },
|
|
966
|
-
additionalProperties: false
|
|
696
|
+
additionalProperties: false,
|
|
967
697
|
},
|
|
968
698
|
{
|
|
969
699
|
type: "object",
|
|
970
700
|
properties: { $gt: v },
|
|
971
|
-
additionalProperties: false
|
|
701
|
+
additionalProperties: false,
|
|
972
702
|
},
|
|
973
703
|
{
|
|
974
704
|
type: "object",
|
|
975
705
|
properties: { $gte: v },
|
|
976
|
-
additionalProperties: false
|
|
706
|
+
additionalProperties: false,
|
|
977
707
|
},
|
|
978
708
|
{
|
|
979
709
|
type: "object",
|
|
980
710
|
properties: { $lt: v },
|
|
981
|
-
additionalProperties: false
|
|
711
|
+
additionalProperties: false,
|
|
982
712
|
},
|
|
983
713
|
{
|
|
984
714
|
type: "object",
|
|
985
715
|
properties: { $lte: v },
|
|
986
|
-
additionalProperties: false
|
|
716
|
+
additionalProperties: false,
|
|
987
717
|
},
|
|
988
718
|
{
|
|
989
719
|
type: "object",
|
|
990
720
|
properties: { $like: { type: "string", minLength: 1 } },
|
|
991
|
-
additionalProperties: false
|
|
721
|
+
additionalProperties: false,
|
|
992
722
|
},
|
|
993
723
|
{
|
|
994
724
|
type: "object",
|
|
995
725
|
properties: { $nlike: { type: "string", minLength: 1 } },
|
|
996
|
-
additionalProperties: false
|
|
726
|
+
additionalProperties: false,
|
|
997
727
|
},
|
|
998
728
|
{
|
|
999
729
|
type: "object",
|
|
1000
730
|
properties: { $in: { type: "array", items: v } },
|
|
1001
|
-
additionalProperties: false
|
|
731
|
+
additionalProperties: false,
|
|
1002
732
|
},
|
|
1003
733
|
{
|
|
1004
734
|
type: "object",
|
|
1005
735
|
properties: { $nin: { type: "array", items: v } },
|
|
1006
|
-
additionalProperties: false
|
|
736
|
+
additionalProperties: false,
|
|
1007
737
|
},
|
|
1008
738
|
{
|
|
1009
739
|
type: "object",
|
|
@@ -1013,10 +743,10 @@ async function getJSONSchemaWhere(table) {
|
|
|
1013
743
|
items: v,
|
|
1014
744
|
minItems: 2,
|
|
1015
745
|
maxItems: 2,
|
|
1016
|
-
uniqueItems: true
|
|
1017
|
-
}
|
|
746
|
+
uniqueItems: true,
|
|
747
|
+
},
|
|
1018
748
|
},
|
|
1019
|
-
additionalProperties: false
|
|
749
|
+
additionalProperties: false,
|
|
1020
750
|
},
|
|
1021
751
|
{
|
|
1022
752
|
type: "object",
|
|
@@ -1026,15 +756,15 @@ async function getJSONSchemaWhere(table) {
|
|
|
1026
756
|
items: v,
|
|
1027
757
|
minItems: 2,
|
|
1028
758
|
maxItems: 2,
|
|
1029
|
-
uniqueItems: true
|
|
1030
|
-
}
|
|
759
|
+
uniqueItems: true,
|
|
760
|
+
},
|
|
1031
761
|
},
|
|
1032
|
-
additionalProperties: false
|
|
1033
|
-
}
|
|
1034
|
-
]
|
|
1035
|
-
}
|
|
762
|
+
additionalProperties: false,
|
|
763
|
+
},
|
|
764
|
+
],
|
|
765
|
+
},
|
|
1036
766
|
}), {}),
|
|
1037
|
-
additionalProperties: false
|
|
767
|
+
additionalProperties: false,
|
|
1038
768
|
},
|
|
1039
769
|
{
|
|
1040
770
|
type: "object",
|
|
@@ -1042,17 +772,17 @@ async function getJSONSchemaWhere(table) {
|
|
|
1042
772
|
$and: {
|
|
1043
773
|
type: "array",
|
|
1044
774
|
items: {
|
|
1045
|
-
$ref: `#/definitions/${whereSchemaName}
|
|
775
|
+
$ref: `#/definitions/${whereSchemaName}`,
|
|
1046
776
|
},
|
|
1047
777
|
// While it makes sense conceptually for $and to have
|
|
1048
778
|
// at least 2 items, in practice, $and could be
|
|
1049
779
|
// generated dynamically and could end up having
|
|
1050
780
|
// less than 2 items, so don't enforce minItems.
|
|
1051
781
|
// minItems: 2,
|
|
1052
|
-
additionalProperties: false
|
|
1053
|
-
}
|
|
782
|
+
additionalProperties: false,
|
|
783
|
+
},
|
|
1054
784
|
},
|
|
1055
|
-
additionalProperties: false
|
|
785
|
+
additionalProperties: false,
|
|
1056
786
|
},
|
|
1057
787
|
{
|
|
1058
788
|
type: "object",
|
|
@@ -1060,19 +790,19 @@ async function getJSONSchemaWhere(table) {
|
|
|
1060
790
|
$or: {
|
|
1061
791
|
type: "array",
|
|
1062
792
|
items: {
|
|
1063
|
-
$ref: `#/definitions/${whereSchemaName}
|
|
793
|
+
$ref: `#/definitions/${whereSchemaName}`,
|
|
1064
794
|
},
|
|
1065
795
|
// While it makes sense conceptually for $and to have
|
|
1066
796
|
// at least 2 items, in practice, $and could be
|
|
1067
797
|
// generated dynamically and could end up having
|
|
1068
798
|
// less than 2 items, so don't enforce minItems.
|
|
1069
799
|
// minItems: 2,
|
|
1070
|
-
additionalProperties: false
|
|
1071
|
-
}
|
|
800
|
+
additionalProperties: false,
|
|
801
|
+
},
|
|
1072
802
|
},
|
|
1073
|
-
additionalProperties: false
|
|
1074
|
-
}
|
|
1075
|
-
]
|
|
803
|
+
additionalProperties: false,
|
|
804
|
+
},
|
|
805
|
+
],
|
|
1076
806
|
};
|
|
1077
807
|
return {
|
|
1078
808
|
definitions: { [whereSchemaName]: defWhere },
|
|
@@ -1089,12 +819,12 @@ async function getJSONSchemaWhere(table) {
|
|
|
1089
819
|
// generated dynamically and could end up having
|
|
1090
820
|
// less than 2 items, so don't enforce minItems.
|
|
1091
821
|
// minItems: 2,
|
|
1092
|
-
additionalProperties: false
|
|
1093
|
-
}
|
|
822
|
+
additionalProperties: false,
|
|
823
|
+
},
|
|
1094
824
|
},
|
|
1095
|
-
additionalProperties: false
|
|
1096
|
-
}))
|
|
1097
|
-
]
|
|
825
|
+
additionalProperties: false,
|
|
826
|
+
})),
|
|
827
|
+
],
|
|
1098
828
|
};
|
|
1099
829
|
}
|
|
1100
830
|
async function getTypeOrderBy(table, name) {
|
|
@@ -1107,14 +837,14 @@ async function getJSONSchemaOrderBy(table, name) {
|
|
|
1107
837
|
type: "object",
|
|
1108
838
|
properties: { [k]: { enum: ["asc", "desc"] } },
|
|
1109
839
|
required: [k],
|
|
1110
|
-
additionalProperties: false
|
|
1111
|
-
}))
|
|
840
|
+
additionalProperties: false,
|
|
841
|
+
})),
|
|
1112
842
|
};
|
|
1113
843
|
const defName = `_${name}`;
|
|
1114
844
|
const _schema = { $ref: `#/definitions/${defName}` };
|
|
1115
845
|
return {
|
|
1116
846
|
definitions: { [defName]: def },
|
|
1117
|
-
oneOf: [_schema, { type: "array", items: _schema }]
|
|
847
|
+
oneOf: [_schema, { type: "array", items: _schema }],
|
|
1118
848
|
};
|
|
1119
849
|
}
|
|
1120
850
|
function getTypeTypesIndex(data) {
|
|
@@ -1128,7 +858,7 @@ function getTypeTypesIndex(data) {
|
|
|
1128
858
|
"typeReturnBaseName",
|
|
1129
859
|
"typeWhereName",
|
|
1130
860
|
"typeOrderByName",
|
|
1131
|
-
"typeDataName"
|
|
861
|
+
"typeDataName",
|
|
1132
862
|
]) {
|
|
1133
863
|
const str = d[k];
|
|
1134
864
|
if (str) {
|
|
@@ -1140,7 +870,7 @@ function getTypeTypesIndex(data) {
|
|
|
1140
870
|
"Paginate",
|
|
1141
871
|
"ListPaginated",
|
|
1142
872
|
"TUpdateOperationsString",
|
|
1143
|
-
"TUpdateOperationsNumber"
|
|
873
|
+
"TUpdateOperationsNumber",
|
|
1144
874
|
].join(",")} } from "./_shared";\n\n`;
|
|
1145
875
|
let arr = Array.from(set).sort();
|
|
1146
876
|
for (let x of arr) {
|
|
@@ -1166,8 +896,8 @@ export type ListPaginated<T> = {
|
|
|
1166
896
|
paginationInfo: {
|
|
1167
897
|
hasPreviousPage?: boolean,
|
|
1168
898
|
hasNextPage?: boolean,
|
|
1169
|
-
startCursor?: string,
|
|
1170
|
-
endCursor?: string,
|
|
899
|
+
startCursor?: string | number,
|
|
900
|
+
endCursor?: string | number,
|
|
1171
901
|
totalCount: number,
|
|
1172
902
|
},
|
|
1173
903
|
results: Array<T>,
|
|
@@ -1185,49 +915,58 @@ async function getTypeFields(table, name, includeMappedFields) {
|
|
|
1185
915
|
const mappedFields = includeMappedFields ? await getMappedFields(table) : [];
|
|
1186
916
|
const keyWhere = "$where";
|
|
1187
917
|
const keyOrderBy = "$orderBy";
|
|
1188
|
-
let properties = {};
|
|
1189
|
-
for (let x of scalarKeys) {
|
|
1190
|
-
properties[x] = { type: "boolean" };
|
|
1191
|
-
}
|
|
1192
|
-
for (let x of mappedFields) {
|
|
1193
|
-
properties[x.as] = { type: "boolean" };
|
|
1194
|
-
}
|
|
1195
|
-
for (let x of relations) {
|
|
1196
|
-
const argsProperties = x.type === "many-to-many"
|
|
1197
|
-
? {
|
|
1198
|
-
[keyWhere]: {
|
|
1199
|
-
type: "object",
|
|
1200
|
-
properties: {
|
|
1201
|
-
[x.table]: { tsType: getTypeWhereName(x.table) },
|
|
1202
|
-
[x.junctionTable]: {
|
|
1203
|
-
tsType: getTypeWhereName(x.junctionTable)
|
|
1204
|
-
}
|
|
1205
|
-
},
|
|
1206
|
-
additionalProperties: false
|
|
1207
|
-
}
|
|
1208
|
-
}
|
|
1209
|
-
: { [keyWhere]: { tsType: getTypeWhereName(x.table) } };
|
|
1210
|
-
// $orderBy only makes sense for a list
|
|
1211
|
-
if (x.grabMany) {
|
|
1212
|
-
argsProperties[keyOrderBy] = {
|
|
1213
|
-
tsType: getTypeOrderByName(x.table)
|
|
1214
|
-
};
|
|
1215
|
-
}
|
|
1216
|
-
argsProperties[keyFields] = { tsType: getTypeFieldsName(x.table) };
|
|
1217
|
-
const jsonSchemaArgs = {
|
|
1218
|
-
type: "object",
|
|
1219
|
-
properties: argsProperties,
|
|
1220
|
-
additionalProperties: false
|
|
1221
|
-
};
|
|
1222
|
-
properties[x.name] = { enum: [{ type: "boolean" }, jsonSchemaArgs] };
|
|
1223
|
-
}
|
|
1224
918
|
const jsonSchemaFields = {
|
|
1225
|
-
type: "
|
|
1226
|
-
|
|
1227
|
-
|
|
919
|
+
type: "array",
|
|
920
|
+
items: {
|
|
921
|
+
anyOf: [
|
|
922
|
+
{
|
|
923
|
+
enum: scalarKeys.concat(mappedFields.map((x) => x.as)),
|
|
924
|
+
},
|
|
925
|
+
...relations.map((x) => {
|
|
926
|
+
const argsProperties = x.type === "many-to-many"
|
|
927
|
+
? {
|
|
928
|
+
[keyWhere]: {
|
|
929
|
+
type: "object",
|
|
930
|
+
properties: {
|
|
931
|
+
[x.table]: { tsType: getTypeWhereName(x.table) },
|
|
932
|
+
[x.junctionTable]: {
|
|
933
|
+
tsType: getTypeWhereName(x.junctionTable),
|
|
934
|
+
},
|
|
935
|
+
},
|
|
936
|
+
additionalProperties: false,
|
|
937
|
+
},
|
|
938
|
+
}
|
|
939
|
+
: { [keyWhere]: { tsType: getTypeWhereName(x.table) } };
|
|
940
|
+
// $orderBy only makes sense for a list
|
|
941
|
+
if (x.grabMany) {
|
|
942
|
+
argsProperties[keyOrderBy] = {
|
|
943
|
+
tsType: getTypeOrderByName(x.table),
|
|
944
|
+
};
|
|
945
|
+
}
|
|
946
|
+
return {
|
|
947
|
+
type: "object",
|
|
948
|
+
properties: {
|
|
949
|
+
name: { enum: [x.name] },
|
|
950
|
+
as: { type: "string" },
|
|
951
|
+
fields: { tsType: getTypeFieldsName(x.table) },
|
|
952
|
+
args: {
|
|
953
|
+
type: "object",
|
|
954
|
+
properties: argsProperties,
|
|
955
|
+
additionalProperties: false,
|
|
956
|
+
},
|
|
957
|
+
transform: { tsType: `(x: any) => any` },
|
|
958
|
+
},
|
|
959
|
+
additionalProperties: false,
|
|
960
|
+
required: ["name", "fields"],
|
|
961
|
+
};
|
|
962
|
+
}),
|
|
963
|
+
],
|
|
964
|
+
},
|
|
1228
965
|
};
|
|
1229
966
|
let type = await (0, json_schema_to_typescript_1.compile)(jsonSchemaFields, name, json2TsOpts);
|
|
1230
|
-
const fieldImports = _.uniq(relations
|
|
967
|
+
const fieldImports = _.uniq(relations
|
|
968
|
+
.filter((x) => x.table !== table)
|
|
969
|
+
.map((x) => getTypeFieldsName(x.table)));
|
|
1231
970
|
const whereImports = _.uniq(relations.flatMap((x) => x.type === "many-to-many"
|
|
1232
971
|
? [getTypeWhereName(x.table), getTypeWhereName(x.junctionTable)]
|
|
1233
972
|
: getTypeWhereName(x.table)));
|
|
@@ -1267,10 +1006,10 @@ async function getTypeReturnBase(table, name, includeMappedFields) {
|
|
|
1267
1006
|
acc[key] = { tsType };
|
|
1268
1007
|
}
|
|
1269
1008
|
return acc;
|
|
1270
|
-
}, {})
|
|
1009
|
+
}, {}),
|
|
1271
1010
|
},
|
|
1272
1011
|
// Because of aliases
|
|
1273
|
-
additionalProperties: true
|
|
1012
|
+
additionalProperties: true,
|
|
1274
1013
|
};
|
|
1275
1014
|
let type = await (0, json_schema_to_typescript_1.compile)(jsonSchemaReturn, name, json2TsOpts);
|
|
1276
1015
|
const imports = _.uniq(relations.map((x) => getTypeReturnBaseName(x.table)))
|
|
@@ -1286,21 +1025,10 @@ function getMaybeNullableTsType(type, nullable) {
|
|
|
1286
1025
|
}
|
|
1287
1026
|
return type;
|
|
1288
1027
|
}
|
|
1289
|
-
function getArtifactsSource(
|
|
1290
|
-
const src = `
|
|
1291
|
-
import type {IArtifacts} from "./IRuntime";
|
|
1292
|
-
|
|
1293
|
-
export const artifacts: IArtifacts = ${JSON.stringify(artifacts)};
|
|
1294
|
-
`;
|
|
1295
|
-
return prettier.format(src, { parser: "typescript" });
|
|
1296
|
-
}
|
|
1297
|
-
async function getArtifacts(tables, includeMappedFields, specialCaseUuidColumn) {
|
|
1028
|
+
async function getArtifactsSource(tables, includeMappedFields, specialCaseUuidColumn) {
|
|
1298
1029
|
const tableMetaList = await Promise.all(tables.map(async (table) => {
|
|
1299
|
-
const
|
|
1300
|
-
|
|
1301
|
-
getPrimaryColumn(table).then((x) => x.name),
|
|
1302
|
-
getShowCreateTable(table)
|
|
1303
|
-
]);
|
|
1030
|
+
const tableMeta = await getTableMeta(table);
|
|
1031
|
+
const primaryKey = await getPrimaryColumn(table).then((x) => x.name);
|
|
1304
1032
|
const scalarFields = tableMeta.map((x) => x.Field);
|
|
1305
1033
|
const relationInfo = await getRelationInfo(table);
|
|
1306
1034
|
const relationFields = relationInfo.reduce((acc, x) => {
|
|
@@ -1312,7 +1040,7 @@ async function getArtifacts(tables, includeMappedFields, specialCaseUuidColumn)
|
|
|
1312
1040
|
table: x.table,
|
|
1313
1041
|
grabMany: x.grabMany,
|
|
1314
1042
|
nullable: x.nullable,
|
|
1315
|
-
relation: x.relation
|
|
1043
|
+
relation: x.relation,
|
|
1316
1044
|
};
|
|
1317
1045
|
}
|
|
1318
1046
|
else {
|
|
@@ -1322,12 +1050,14 @@ async function getArtifacts(tables, includeMappedFields, specialCaseUuidColumn)
|
|
|
1322
1050
|
table: x.table,
|
|
1323
1051
|
junctionTable: x.junctionTable,
|
|
1324
1052
|
grabMany: x.grabMany,
|
|
1325
|
-
relations: x.relations
|
|
1053
|
+
relations: x.relations,
|
|
1326
1054
|
};
|
|
1327
1055
|
}
|
|
1328
1056
|
return acc;
|
|
1329
1057
|
}, {});
|
|
1330
|
-
const _mappedFields = includeMappedFields
|
|
1058
|
+
const _mappedFields = includeMappedFields
|
|
1059
|
+
? await getMappedFields(table)
|
|
1060
|
+
: [];
|
|
1331
1061
|
const mappedFields = _mappedFields.length === 0
|
|
1332
1062
|
? null
|
|
1333
1063
|
: _mappedFields.reduce((acc, v) => {
|
|
@@ -1343,49 +1073,6 @@ async function getArtifacts(tables, includeMappedFields, specialCaseUuidColumn)
|
|
|
1343
1073
|
return acc;
|
|
1344
1074
|
}, {});
|
|
1345
1075
|
const uniqueFields = await getUniqueColumns(table, specialCaseUuidColumn);
|
|
1346
|
-
let fields = tableMeta.map((t) => {
|
|
1347
|
-
const nullable = t.Null === "YES";
|
|
1348
|
-
const isEnum = t.Type.startsWith("enum");
|
|
1349
|
-
if (isEnum) {
|
|
1350
|
-
const values = getPropertyEnum(t.Type);
|
|
1351
|
-
if (values && nullable) {
|
|
1352
|
-
values.push(null);
|
|
1353
|
-
}
|
|
1354
|
-
return {
|
|
1355
|
-
kind: "enum",
|
|
1356
|
-
values,
|
|
1357
|
-
name: t.Field,
|
|
1358
|
-
nullable
|
|
1359
|
-
};
|
|
1360
|
-
}
|
|
1361
|
-
return {
|
|
1362
|
-
kind: "scalar",
|
|
1363
|
-
type: getBaseJSONType(t.Type),
|
|
1364
|
-
name: t.Field,
|
|
1365
|
-
nullable,
|
|
1366
|
-
hasDefaultValue: !!t.Default
|
|
1367
|
-
};
|
|
1368
|
-
});
|
|
1369
|
-
for (let x of _mappedFields) {
|
|
1370
|
-
fields.push({
|
|
1371
|
-
kind: "scalar",
|
|
1372
|
-
type: x.type,
|
|
1373
|
-
name: x.as,
|
|
1374
|
-
nullable: x.nullable,
|
|
1375
|
-
// TODO
|
|
1376
|
-
hasDefaultValue: false,
|
|
1377
|
-
mapped: true
|
|
1378
|
-
});
|
|
1379
|
-
}
|
|
1380
|
-
for (let x of relationInfo) {
|
|
1381
|
-
fields.push({
|
|
1382
|
-
kind: "object",
|
|
1383
|
-
type: x.table,
|
|
1384
|
-
name: x.name,
|
|
1385
|
-
isList: x.grabMany,
|
|
1386
|
-
nullable: x.type === "one-to-many__many-to-one" ? x.nullable : false
|
|
1387
|
-
});
|
|
1388
|
-
}
|
|
1389
1076
|
return {
|
|
1390
1077
|
table,
|
|
1391
1078
|
primaryKey,
|
|
@@ -1395,15 +1082,18 @@ async function getArtifacts(tables, includeMappedFields, specialCaseUuidColumn)
|
|
|
1395
1082
|
uniqueFields,
|
|
1396
1083
|
dateTimeFields,
|
|
1397
1084
|
dateTimeFieldsCount: Object.keys(dateTimeFields).length,
|
|
1398
|
-
fields,
|
|
1399
|
-
dump: dumpSchema == null ? null : { schema: dumpSchema }
|
|
1400
1085
|
};
|
|
1401
1086
|
}));
|
|
1402
1087
|
const artifacts = tableMetaList.reduce((acc, x) => {
|
|
1403
1088
|
acc[x.table] = x;
|
|
1404
1089
|
return acc;
|
|
1405
1090
|
}, {});
|
|
1406
|
-
|
|
1091
|
+
const src = `
|
|
1092
|
+
import type {IArtifacts} from "./IRuntime";
|
|
1093
|
+
|
|
1094
|
+
export const artifacts: IArtifacts = ${JSON.stringify(artifacts)};
|
|
1095
|
+
`;
|
|
1096
|
+
return prettier.format(src, { parser: "typescript" });
|
|
1407
1097
|
}
|
|
1408
1098
|
const getRelationInfo = _.memoize(async function getRelationInfo(table) {
|
|
1409
1099
|
const relationsManyToOne = await getRelationsManyToOne(table);
|
|
@@ -1418,7 +1108,7 @@ const getRelationInfo = _.memoize(async function getRelationInfo(table) {
|
|
|
1418
1108
|
table: x.referencedTable,
|
|
1419
1109
|
name,
|
|
1420
1110
|
relation: x,
|
|
1421
|
-
nullable: x.nullable
|
|
1111
|
+
nullable: x.nullable,
|
|
1422
1112
|
};
|
|
1423
1113
|
}));
|
|
1424
1114
|
const relationsOneToManyDuplicates = (0, getDuplicates_1.getDuplicates)(relationsOneToMany.map((x) => x.referencedTable));
|
|
@@ -1441,7 +1131,7 @@ const getRelationInfo = _.memoize(async function getRelationInfo(table) {
|
|
|
1441
1131
|
table: x.referencedTable,
|
|
1442
1132
|
name,
|
|
1443
1133
|
relation: x,
|
|
1444
|
-
nullable: x.nullable
|
|
1134
|
+
nullable: x.nullable,
|
|
1445
1135
|
};
|
|
1446
1136
|
}));
|
|
1447
1137
|
const relationsManyToMany = (await getJunctionTables()).reduce((acc, x) => {
|
|
@@ -1460,7 +1150,7 @@ const getRelationInfo = _.memoize(async function getRelationInfo(table) {
|
|
|
1460
1150
|
name: changeCase.camelCase(dataForChildTable.referencedTable) + "List",
|
|
1461
1151
|
// Ensure parent comes before child
|
|
1462
1152
|
relations: [dataForParentTable, dataForChildTable],
|
|
1463
|
-
grabMany: true
|
|
1153
|
+
grabMany: true,
|
|
1464
1154
|
});
|
|
1465
1155
|
return acc;
|
|
1466
1156
|
}, []);
|
|
@@ -1481,7 +1171,7 @@ async function getJunctionTables() {
|
|
|
1481
1171
|
// e.g. junction of Foo, Bar must be FooBar or BarFoo
|
|
1482
1172
|
[
|
|
1483
1173
|
relations[0].referencedTable + relations[1].referencedTable,
|
|
1484
|
-
relations[1].referencedTable + relations[0].referencedTable
|
|
1174
|
+
relations[1].referencedTable + relations[0].referencedTable,
|
|
1485
1175
|
].includes(table)) {
|
|
1486
1176
|
return { table, relations };
|
|
1487
1177
|
}
|
|
@@ -1537,7 +1227,7 @@ const getRelationsManyToOne = _.memoize(async function getRelationsManyToOne(tab
|
|
|
1537
1227
|
foreignKey: v.t1Field,
|
|
1538
1228
|
referencedTable: v.t2,
|
|
1539
1229
|
referencedKey: v.t2Field,
|
|
1540
|
-
nullable: tableMeta.find((m) => m.Field === v.t1Field)?.Null === "YES"
|
|
1230
|
+
nullable: tableMeta.find((m) => m.Field === v.t1Field)?.Null === "YES",
|
|
1541
1231
|
};
|
|
1542
1232
|
})));
|
|
1543
1233
|
return _.sortBy((x) => x.referencedTable, xs);
|
|
@@ -1586,7 +1276,7 @@ const getRelationsOneToMany = _.memoize(async function getRelationsOneToMany(tab
|
|
|
1586
1276
|
referencedTable: v.t1,
|
|
1587
1277
|
referencedKey: v.t1Field,
|
|
1588
1278
|
// TODO? I think this is right, since it's one-to-many, so a list
|
|
1589
|
-
nullable: false
|
|
1279
|
+
nullable: false,
|
|
1590
1280
|
};
|
|
1591
1281
|
})));
|
|
1592
1282
|
return _.sortBy((x) => x.referencedKey, _.sortBy((x) => x.referencedTable, xs));
|
|
@@ -1601,7 +1291,7 @@ async function getPrimaryColumn(table) {
|
|
|
1601
1291
|
return {
|
|
1602
1292
|
name: column.Field,
|
|
1603
1293
|
type: getBaseJSONType(column.Type),
|
|
1604
|
-
nullable: column.Null === "YES"
|
|
1294
|
+
nullable: column.Null === "YES",
|
|
1605
1295
|
};
|
|
1606
1296
|
}
|
|
1607
1297
|
async function getUniqueColumns(table, specialCaseUuidColumn) {
|
|
@@ -1613,7 +1303,7 @@ async function getUniqueColumns(table, specialCaseUuidColumn) {
|
|
|
1613
1303
|
.map((x) => ({
|
|
1614
1304
|
name: x.Field,
|
|
1615
1305
|
type: getBaseJSONType(x.Type),
|
|
1616
|
-
nullable: x.Null === "YES"
|
|
1306
|
+
nullable: x.Null === "YES",
|
|
1617
1307
|
}));
|
|
1618
1308
|
}
|
|
1619
1309
|
async function getUuidColumn(table) {
|
|
@@ -1625,14 +1315,14 @@ async function getUuidColumn(table) {
|
|
|
1625
1315
|
return {
|
|
1626
1316
|
name: column.Field,
|
|
1627
1317
|
type: column.Type,
|
|
1628
|
-
nullable: column.Null === "YES"
|
|
1318
|
+
nullable: column.Null === "YES",
|
|
1629
1319
|
};
|
|
1630
1320
|
}
|
|
1631
1321
|
const getTableMeta = _.memoize(async function getTableMeta(table) {
|
|
1632
1322
|
if (dialect === "mysql") {
|
|
1633
1323
|
return query("DESCRIBE ??", [table]).then((xs) => _.sortBy((x) => x.Field, xs));
|
|
1634
1324
|
}
|
|
1635
|
-
if (dialect === "mssql") {
|
|
1325
|
+
if (dialect === "mssql" || dialect === "ksql") {
|
|
1636
1326
|
const primaryColumn = await query(`SELECT columns.name as COLUMN_NAME
|
|
1637
1327
|
FROM sys.tables tables
|
|
1638
1328
|
JOIN sys.columns columns
|
|
@@ -1669,20 +1359,12 @@ const getTableMeta = _.memoize(async function getTableMeta(table) {
|
|
|
1669
1359
|
? "UNI"
|
|
1670
1360
|
: "",
|
|
1671
1361
|
Null: x["IS_NULLABLE"],
|
|
1672
|
-
Default: x["COLUMN_DEFAULT"]
|
|
1362
|
+
Default: x["COLUMN_DEFAULT"],
|
|
1673
1363
|
};
|
|
1674
1364
|
})));
|
|
1675
1365
|
}
|
|
1676
1366
|
throw new Error("Unsupported dialect: " + dialect);
|
|
1677
1367
|
});
|
|
1678
|
-
function getShowCreateTable(table) {
|
|
1679
|
-
if (dialect === "mysql") {
|
|
1680
|
-
return query("SHOW CREATE TABLE ??", [table]).then((xs) => xs[0]["Create Table"]
|
|
1681
|
-
// https://github.com/bradzacher/mysqldump/blob/66839a57e572a07c046b0ba98753f30a7026cbd8/src/getSchemaDump.ts#L65
|
|
1682
|
-
.replace(/AUTO_INCREMENT\s*=\s*\d+ /g, ""));
|
|
1683
|
-
}
|
|
1684
|
-
return Promise.resolve(null);
|
|
1685
|
-
}
|
|
1686
1368
|
function getJSONSchemaObjProperties(tableMeta) {
|
|
1687
1369
|
return tableMeta.reduce((acc, m) => {
|
|
1688
1370
|
const baseType = getBaseJSONType(m.Type);
|
|
@@ -1696,7 +1378,7 @@ function getJSONSchemaObjProperties(tableMeta) {
|
|
|
1696
1378
|
_enum.push(null);
|
|
1697
1379
|
}
|
|
1698
1380
|
acc[m.Field] = {
|
|
1699
|
-
type: getJSONTypes(baseType, nullable)
|
|
1381
|
+
type: getJSONTypes(baseType, nullable),
|
|
1700
1382
|
// maxLength:
|
|
1701
1383
|
// baseType === "string" && format == null && isEnum == null
|
|
1702
1384
|
// ? getPropertyMaxLength(m.Type)
|
|
@@ -1806,7 +1488,9 @@ function getPropertyEnum(sqlType) {
|
|
|
1806
1488
|
return c;
|
|
1807
1489
|
}
|
|
1808
1490
|
function getPropertyFormat(sqlType) {
|
|
1809
|
-
if (sqlType === "datetime" ||
|
|
1491
|
+
if (sqlType === "datetime" ||
|
|
1492
|
+
sqlType === "datetime2" ||
|
|
1493
|
+
sqlType === "timestamp") {
|
|
1810
1494
|
// TODO: not sure this is correct for `timestamp`
|
|
1811
1495
|
return "date-time";
|
|
1812
1496
|
}
|
|
@@ -1830,13 +1514,13 @@ const mssqlTableExcludes = new Set([
|
|
|
1830
1514
|
"ddl_history",
|
|
1831
1515
|
"index_columns",
|
|
1832
1516
|
"lsn_time_mapping",
|
|
1833
|
-
"systranschemas"
|
|
1517
|
+
"systranschemas",
|
|
1834
1518
|
]);
|
|
1835
1519
|
async function getTableNames() {
|
|
1836
1520
|
if (dialect === "mysql") {
|
|
1837
1521
|
return query("SHOW TABLES").then((xs) => xs.flatMap((x) => Object.values(x)).sort());
|
|
1838
1522
|
}
|
|
1839
|
-
if (dialect === "mssql") {
|
|
1523
|
+
if (dialect === "mssql" || dialect === "ksql") {
|
|
1840
1524
|
return query("SELECT * FROM INFORMATION_SCHEMA.TABLES").then((xs) => xs
|
|
1841
1525
|
.map((x) => x["TABLE_NAME"])
|
|
1842
1526
|
.filter((x) => !x.startsWith("dbo_") && !mssqlTableExcludes.has(x))
|
|
@@ -1844,295 +1528,3 @@ async function getTableNames() {
|
|
|
1844
1528
|
}
|
|
1845
1529
|
throw new Error("Unsupported dialect: " + dialect);
|
|
1846
1530
|
}
|
|
1847
|
-
function getMysql2sqliteSrc() {
|
|
1848
|
-
return `#!/usr/bin/awk -f
|
|
1849
|
-
|
|
1850
|
-
# Authors: @esperlu, @artemyk, @gkuenning, @dumblob
|
|
1851
|
-
|
|
1852
|
-
# FIXME detect empty input file and issue a warning
|
|
1853
|
-
|
|
1854
|
-
function printerr( s ){ print s | "cat >&2" }
|
|
1855
|
-
|
|
1856
|
-
BEGIN {
|
|
1857
|
-
if( ARGC != 2 ){
|
|
1858
|
-
printerr( \\
|
|
1859
|
-
"USAGE:\\n"\\
|
|
1860
|
-
" mysql2sqlite dump_mysql.sql > dump_sqlite3.sql\\n" \\
|
|
1861
|
-
" OR\\n" \\
|
|
1862
|
-
" mysql2sqlite dump_mysql.sql | sqlite3 sqlite.db\\n" \\
|
|
1863
|
-
"\\n" \\
|
|
1864
|
-
"NOTES:\\n" \\
|
|
1865
|
-
" Dash in filename is not supported, because dash (-) means stdin." )
|
|
1866
|
-
no_END = 1
|
|
1867
|
-
exit 1
|
|
1868
|
-
}
|
|
1869
|
-
|
|
1870
|
-
# Find INT_MAX supported by both this AWK (usually an ISO C signed int)
|
|
1871
|
-
# and SQlite.
|
|
1872
|
-
# On non-8bit-based architectures, the additional bits are safely ignored.
|
|
1873
|
-
|
|
1874
|
-
# 8bit (lower precision should not exist)
|
|
1875
|
-
s="127"
|
|
1876
|
-
# "63" + 0 avoids potential parser misbehavior
|
|
1877
|
-
if( (s + 0) "" == s ){ INT_MAX_HALF = "63" + 0 }
|
|
1878
|
-
# 16bit
|
|
1879
|
-
s="32767"
|
|
1880
|
-
if( (s + 0) "" == s ){ INT_MAX_HALF = "16383" + 0 }
|
|
1881
|
-
# 32bit
|
|
1882
|
-
s="2147483647"
|
|
1883
|
-
if( (s + 0) "" == s ){ INT_MAX_HALF = "1073741823" + 0 }
|
|
1884
|
-
# 64bit (as INTEGER in SQlite3)
|
|
1885
|
-
s="9223372036854775807"
|
|
1886
|
-
if( (s + 0) "" == s ){ INT_MAX_HALF = "4611686018427387904" + 0 }
|
|
1887
|
-
# # 128bit
|
|
1888
|
-
# s="170141183460469231731687303715884105728"
|
|
1889
|
-
# if( (s + 0) "" == s ){ INT_MAX_HALF = "85070591730234615865843651857942052864" + 0 }
|
|
1890
|
-
# # 256bit
|
|
1891
|
-
# s="57896044618658097711785492504343953926634992332820282019728792003956564819968"
|
|
1892
|
-
# if( (s + 0) "" == s ){ INT_MAX_HALF = "28948022309329048855892746252171976963317496166410141009864396001978282409984" + 0 }
|
|
1893
|
-
# # 512bit
|
|
1894
|
-
# s="6703903964971298549787012499102923063739682910296196688861780721860882015036773488400937149083451713845015929093243025426876941405973284973216824503042048"
|
|
1895
|
-
# if( (s + 0) "" == s ){ INT_MAX_HALF = "3351951982485649274893506249551461531869841455148098344430890360930441007518386744200468574541725856922507964546621512713438470702986642486608412251521024" + 0 }
|
|
1896
|
-
# # 1024bit
|
|
1897
|
-
# s="89884656743115795386465259539451236680898848947115328636715040578866337902750481566354238661203768010560056939935696678829394884407208311246423715319737062188883946712432742638151109800623047059726541476042502884419075341171231440736956555270413618581675255342293149119973622969239858152417678164812112068608"
|
|
1898
|
-
# if( (s + 0) "" == s ){ INT_MAX_HALF = "44942328371557897693232629769725618340449424473557664318357520289433168951375240783177119330601884005280028469967848339414697442203604155623211857659868531094441973356216371319075554900311523529863270738021251442209537670585615720368478277635206809290837627671146574559986811484619929076208839082406056034304" + 0 }
|
|
1899
|
-
# # higher precision probably not needed
|
|
1900
|
-
|
|
1901
|
-
FS=",$"
|
|
1902
|
-
print "PRAGMA synchronous = OFF;"
|
|
1903
|
-
print "PRAGMA journal_mode = MEMORY;"
|
|
1904
|
-
print "BEGIN TRANSACTION;"
|
|
1905
|
-
}
|
|
1906
|
-
|
|
1907
|
-
# historically 3 spaces separate non-argument local variables
|
|
1908
|
-
function bit_to_int( str_bit, powtwo, i, res, bit, overflow ){
|
|
1909
|
-
powtwo = 1
|
|
1910
|
-
overflow = 0
|
|
1911
|
-
# 011101 = 1*2^0 + 0*2^1 + 1*2^2 ...
|
|
1912
|
-
for( i = length( str_bit ); i > 0; --i ){
|
|
1913
|
-
bit = substr( str_bit, i, 1 )
|
|
1914
|
-
if( overflow || ( bit == 1 && res > INT_MAX_HALF ) ){
|
|
1915
|
-
printerr( \\
|
|
1916
|
-
NR ": WARN Bit field overflow, number truncated (LSBs saved, MSBs ignored)." )
|
|
1917
|
-
break
|
|
1918
|
-
}
|
|
1919
|
-
res = res + bit * powtwo
|
|
1920
|
-
# no warning here as it might be the last iteration
|
|
1921
|
-
if( powtwo > INT_MAX_HALF ){ overflow = 1; continue }
|
|
1922
|
-
powtwo = powtwo * 2
|
|
1923
|
-
}
|
|
1924
|
-
return res
|
|
1925
|
-
}
|
|
1926
|
-
|
|
1927
|
-
# CREATE TRIGGER statements have funny commenting. Remember we are in trigger.
|
|
1928
|
-
/^\\/\\*.*(CREATE.*TRIGGER|create.*trigger)/ {
|
|
1929
|
-
gsub( /^.*(TRIGGER|trigger)/, "CREATE TRIGGER" )
|
|
1930
|
-
print
|
|
1931
|
-
inTrigger = 1
|
|
1932
|
-
next
|
|
1933
|
-
}
|
|
1934
|
-
# The end of CREATE TRIGGER has a stray comment terminator
|
|
1935
|
-
/(END|end) \\*\\/;;/ { gsub( /\\*\\//, "" ); print; inTrigger = 0; next }
|
|
1936
|
-
# The rest of triggers just get passed through
|
|
1937
|
-
inTrigger != 0 { print; next }
|
|
1938
|
-
|
|
1939
|
-
# CREATE VIEW looks like a TABLE in comments
|
|
1940
|
-
/^\\/\\*.*(CREATE.*TABLE|create.*table)/ {
|
|
1941
|
-
inView = 1
|
|
1942
|
-
next
|
|
1943
|
-
}
|
|
1944
|
-
# end of CREATE VIEW
|
|
1945
|
-
/^(\\).*(ENGINE|engine).*\\*\\/;)/ {
|
|
1946
|
-
inView = 0
|
|
1947
|
-
next
|
|
1948
|
-
}
|
|
1949
|
-
# content of CREATE VIEW
|
|
1950
|
-
inView != 0 { next }
|
|
1951
|
-
|
|
1952
|
-
# skip comments
|
|
1953
|
-
/^\\/\\*/ { next }
|
|
1954
|
-
|
|
1955
|
-
# skip PARTITION statements
|
|
1956
|
-
/^ *[(]?(PARTITION|partition) +[^ ]+/ { next }
|
|
1957
|
-
|
|
1958
|
-
# print all INSERT lines
|
|
1959
|
-
( /^ *\\(/ && /\\) *[,;] *$/ ) || /^(INSERT|insert|REPLACE|replace)/ {
|
|
1960
|
-
prev = ""
|
|
1961
|
-
|
|
1962
|
-
# first replace \\\\ by \\_ that mysqldump never generates to deal with
|
|
1963
|
-
# sequnces like \\\\n that should be translated into \\n, not \\<LF>.
|
|
1964
|
-
# After we convert all escapes we replace \\_ by backslashes.
|
|
1965
|
-
gsub( /\\\\\\\\/, "\\\\_" )
|
|
1966
|
-
|
|
1967
|
-
# single quotes are escaped by another single quote
|
|
1968
|
-
gsub( /\\\\'/, "''" )
|
|
1969
|
-
gsub( /\\\\n/, "\\n" )
|
|
1970
|
-
gsub( /\\\\r/, "\\r" )
|
|
1971
|
-
gsub( /\\\\"/, "\\"" )
|
|
1972
|
-
gsub( /\\\\\\032/, "\\032" ) # substitute char
|
|
1973
|
-
|
|
1974
|
-
gsub( /\\\\_/, "\\\\" )
|
|
1975
|
-
|
|
1976
|
-
# sqlite3 is limited to 16 significant digits of precision
|
|
1977
|
-
while( match( $0, /0x[0-9a-fA-F]{17}/ ) ){
|
|
1978
|
-
hexIssue = 1
|
|
1979
|
-
sub( /0x[0-9a-fA-F]+/, substr( $0, RSTART, RLENGTH-1 ), $0 )
|
|
1980
|
-
}
|
|
1981
|
-
if( hexIssue ){
|
|
1982
|
-
printerr( \\
|
|
1983
|
-
NR ": WARN Hex number trimmed (length longer than 16 chars)." )
|
|
1984
|
-
hexIssue = 0
|
|
1985
|
-
}
|
|
1986
|
-
print
|
|
1987
|
-
next
|
|
1988
|
-
}
|
|
1989
|
-
|
|
1990
|
-
# CREATE DATABASE is not supported
|
|
1991
|
-
/^(CREATE DATABASE|create database)/ { next }
|
|
1992
|
-
|
|
1993
|
-
# print the CREATE line as is and capture the table name
|
|
1994
|
-
/^(CREATE|create)/ {
|
|
1995
|
-
if( $0 ~ /IF NOT EXISTS|if not exists/ || $0 ~ /TEMPORARY|temporary/ ){
|
|
1996
|
-
caseIssue = 1
|
|
1997
|
-
printerr( \\
|
|
1998
|
-
NR ": WARN Potential case sensitivity issues with table/column naming\\n" \\
|
|
1999
|
-
" (see INFO at the end)." )
|
|
2000
|
-
}
|
|
2001
|
-
if( match( $0, /\`[^\`]+/ ) ){
|
|
2002
|
-
tableName = substr( $0, RSTART+1, RLENGTH-1 )
|
|
2003
|
-
}
|
|
2004
|
-
aInc = 0
|
|
2005
|
-
prev = ""
|
|
2006
|
-
firstInTable = 1
|
|
2007
|
-
print
|
|
2008
|
-
next
|
|
2009
|
-
}
|
|
2010
|
-
|
|
2011
|
-
# Replace \`FULLTEXT KEY\` (probably other \`XXXXX KEY\`)
|
|
2012
|
-
/^ (FULLTEXT KEY|fulltext key)/ { gsub( /[A-Za-z ]+(KEY|key)/, " KEY" ) }
|
|
2013
|
-
|
|
2014
|
-
# Get rid of field lengths in KEY lines
|
|
2015
|
-
/ (PRIMARY |primary )?(KEY|key)/ { gsub( /\\([0-9]+\\)/, "" ) }
|
|
2016
|
-
|
|
2017
|
-
aInc == 1 && /PRIMARY KEY|primary key/ { next }
|
|
2018
|
-
|
|
2019
|
-
# Replace COLLATE xxx_xxxx_xx statements with COLLATE BINARY
|
|
2020
|
-
/ (COLLATE|collate) [a-z0-9_]*/ { gsub( /(COLLATE|collate) [a-z0-9_]*/, "COLLATE BINARY" ) }
|
|
2021
|
-
|
|
2022
|
-
# Print all fields definition lines except the \`KEY\` lines.
|
|
2023
|
-
/^ / && !/^( (KEY|key)|\\);)/ {
|
|
2024
|
-
if( match( $0, /[^"\`]AUTO_INCREMENT|auto_increment[^"\`]/) ){
|
|
2025
|
-
aInc = 1
|
|
2026
|
-
gsub( /AUTO_INCREMENT|auto_increment/, "PRIMARY KEY AUTOINCREMENT" )
|
|
2027
|
-
}
|
|
2028
|
-
gsub( /(UNIQUE KEY|unique key) (\`.*\`|".*") /, "UNIQUE " )
|
|
2029
|
-
gsub( /(CHARACTER SET|character set) [^ ]+[ ,]/, "" )
|
|
2030
|
-
# FIXME
|
|
2031
|
-
# CREATE TRIGGER [UpdateLastTime]
|
|
2032
|
-
# AFTER UPDATE
|
|
2033
|
-
# ON Package
|
|
2034
|
-
# FOR EACH ROW
|
|
2035
|
-
# BEGIN
|
|
2036
|
-
# UPDATE Package SET LastUpdate = CURRENT_TIMESTAMP WHERE ActionId = old.ActionId;
|
|
2037
|
-
# END
|
|
2038
|
-
gsub( /(ON|on) (UPDATE|update) (CURRENT_TIMESTAMP|current_timestamp)(\\(\\))?/, "" )
|
|
2039
|
-
gsub( /(DEFAULT|default) (CURRENT_TIMESTAMP|current_timestamp)(\\(\\))?/, "DEFAULT current_timestamp")
|
|
2040
|
-
gsub( /(COLLATE|collate) [^ ]+ /, "" )
|
|
2041
|
-
gsub( /(ENUM|enum)[^)]+\\)/, "text " )
|
|
2042
|
-
gsub( /(SET|set)\\([^)]+\\)/, "text " )
|
|
2043
|
-
gsub( /UNSIGNED|unsigned/, "" )
|
|
2044
|
-
gsub( /_utf8mb3/, "" )
|
|
2045
|
-
gsub( /\` [^ ]*(INT|int|BIT|bit)[^ ]*/, "\` integer" )
|
|
2046
|
-
gsub( /" [^ ]*(INT|int|BIT|bit)[^ ]*/, "\\" integer" )
|
|
2047
|
-
ere_bit_field = "[bB]'[10]+'"
|
|
2048
|
-
if( match($0, ere_bit_field) ){
|
|
2049
|
-
sub( ere_bit_field, bit_to_int( substr( $0, RSTART +2, RLENGTH -2 -1 ) ) )
|
|
2050
|
-
}
|
|
2051
|
-
|
|
2052
|
-
# remove USING BTREE and other suffixes for USING, for example: "UNIQUE KEY
|
|
2053
|
-
# \`hostname_domain\` (\`hostname\`,\`domain\`) USING BTREE,"
|
|
2054
|
-
gsub( / USING [^, ]+/, "" )
|
|
2055
|
-
|
|
2056
|
-
# field comments are not supported
|
|
2057
|
-
gsub( / (COMMENT|comment).+$/, "" )
|
|
2058
|
-
# Get commas off end of line
|
|
2059
|
-
gsub( /,.?$/, "" )
|
|
2060
|
-
if( prev ){
|
|
2061
|
-
if( firstInTable ){
|
|
2062
|
-
print prev
|
|
2063
|
-
firstInTable = 0
|
|
2064
|
-
}
|
|
2065
|
-
else {
|
|
2066
|
-
print "," prev
|
|
2067
|
-
}
|
|
2068
|
-
}
|
|
2069
|
-
else {
|
|
2070
|
-
# FIXME check if this is correct in all cases
|
|
2071
|
-
if( match( $1,
|
|
2072
|
-
/(CONSTRAINT|constraint) ["].*["] (FOREIGN KEY|foreign key)/ ) ){
|
|
2073
|
-
print ","
|
|
2074
|
-
}
|
|
2075
|
-
}
|
|
2076
|
-
prev = $1
|
|
2077
|
-
}
|
|
2078
|
-
|
|
2079
|
-
/ ENGINE| engine/ {
|
|
2080
|
-
if( prev ){
|
|
2081
|
-
if( firstInTable ){
|
|
2082
|
-
print prev
|
|
2083
|
-
firstInTable = 0
|
|
2084
|
-
}
|
|
2085
|
-
else {
|
|
2086
|
-
print "," prev
|
|
2087
|
-
}
|
|
2088
|
-
}
|
|
2089
|
-
prev=""
|
|
2090
|
-
print ");"
|
|
2091
|
-
next
|
|
2092
|
-
}
|
|
2093
|
-
# \`KEY\` lines are extracted from the \`CREATE\` block and stored in array for later print
|
|
2094
|
-
# in a separate \`CREATE KEY\` command. The index name is prefixed by the table name to
|
|
2095
|
-
# avoid a sqlite error for duplicate index name.
|
|
2096
|
-
/^( (KEY|key)|\\);)/ {
|
|
2097
|
-
if( prev ){
|
|
2098
|
-
if( firstInTable ){
|
|
2099
|
-
print prev
|
|
2100
|
-
firstInTable = 0
|
|
2101
|
-
}
|
|
2102
|
-
else {
|
|
2103
|
-
print "," prev
|
|
2104
|
-
}
|
|
2105
|
-
}
|
|
2106
|
-
prev = ""
|
|
2107
|
-
if( $0 == ");" ){
|
|
2108
|
-
print
|
|
2109
|
-
}
|
|
2110
|
-
else {
|
|
2111
|
-
if( match( $0, /\`[^\`]+/ ) ){
|
|
2112
|
-
indexName = substr( $0, RSTART+1, RLENGTH-1 )
|
|
2113
|
-
}
|
|
2114
|
-
if( match( $0, /\\([^()]+/ ) ){
|
|
2115
|
-
indexKey = substr( $0, RSTART+1, RLENGTH-1 )
|
|
2116
|
-
}
|
|
2117
|
-
# idx_ prefix to avoid name clashes (they really happen!)
|
|
2118
|
-
key[tableName] = key[tableName] "CREATE INDEX \\"idx_" \\
|
|
2119
|
-
tableName "_" indexName "\\" ON \\"" tableName "\\" (" indexKey ");\\n"
|
|
2120
|
-
}
|
|
2121
|
-
}
|
|
2122
|
-
|
|
2123
|
-
END {
|
|
2124
|
-
if( no_END ){ exit 1}
|
|
2125
|
-
# print all KEY creation lines.
|
|
2126
|
-
for( table in key ){ printf key[table] }
|
|
2127
|
-
|
|
2128
|
-
print "END TRANSACTION;"
|
|
2129
|
-
|
|
2130
|
-
if( caseIssue ){
|
|
2131
|
-
printerr( \\
|
|
2132
|
-
"INFO Pure sqlite identifiers are case insensitive (even if quoted\\n" \\
|
|
2133
|
-
" or if ASCII) and doesnt cross-check TABLE and TEMPORARY TABLE\\n" \\
|
|
2134
|
-
" identifiers. Thus expect errors like \\"table T has no column named F\\".")
|
|
2135
|
-
}
|
|
2136
|
-
}
|
|
2137
|
-
`;
|
|
2138
|
-
}
|