@technicity/data-service-generator 0.13.26 → 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 +269 -787
- package/dist/ksql.js +1 -24
- package/dist/runtime/Cache.js +3 -6
- package/dist/runtime/IRuntime.d.ts +4 -33
- package/dist/runtime/RuntimeKSQL.d.ts +0 -7
- package/dist/runtime/RuntimeKSQL.js +17 -47
- 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 +21 -46
- package/dist/runtime/lib/shared.js +44 -156
- package/dist/runtime/lib/stringifyWhere.js +12 -39
- package/dist/runtime/lib/typeCastMSSQL.js +1 -24
- 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/runTransforms.test.d.ts +0 -1
- package/dist/runtime/lib/runTransforms.test.js +0 -112
- 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 -72
|
@@ -1,50 +1,22 @@
|
|
|
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");
|
|
45
19
|
const MySQL_1 = require("../runtime/lib/MySQL");
|
|
46
|
-
const node_util_1 = require("node:util");
|
|
47
|
-
const spawn = (0, node_util_1.promisify)(child_process.spawn);
|
|
48
20
|
// json-schema-to-typescript inlines everything. We don't want that,
|
|
49
21
|
// so use `tsType`, and add imports manually.
|
|
50
22
|
// https://github.com/bcherny/json-schema-to-typescript#custom-schema-properties
|
|
@@ -53,7 +25,7 @@ const spawn = (0, node_util_1.promisify)(child_process.spawn);
|
|
|
53
25
|
let query = undefined;
|
|
54
26
|
let dialect = "mysql";
|
|
55
27
|
const json2TsOpts = {
|
|
56
|
-
bannerComment: ""
|
|
28
|
+
bannerComment: "",
|
|
57
29
|
};
|
|
58
30
|
async function generate(input) {
|
|
59
31
|
if (input.tables != null && input.excludeTables != null) {
|
|
@@ -85,26 +57,22 @@ async function generate(input) {
|
|
|
85
57
|
getPatchOneData(x, specialCaseUuidColumn, includeMappedFields),
|
|
86
58
|
getPatchListData(x),
|
|
87
59
|
getDeleteOneData(x),
|
|
88
|
-
getDeleteListData(x)
|
|
60
|
+
getDeleteListData(x),
|
|
89
61
|
]));
|
|
90
|
-
const
|
|
91
|
-
const artifactsSource = getArtifactsSource(artifacts);
|
|
62
|
+
const artifactsSource = await getArtifactsSource(tables, includeMappedFields, specialCaseUuidColumn);
|
|
92
63
|
const sdkSource = await getSDKSource(data, specialCaseUuidColumn, supplementClientOpts);
|
|
93
64
|
const sdkFilename = "index.ts";
|
|
94
|
-
const sourceIRuntimeFilePath = fs.existsSync(path.join(__dirname, "../runtime", "IRuntime.ts"))
|
|
95
|
-
? path.join(__dirname, "../runtime", "IRuntime.ts")
|
|
96
|
-
: path.join(__dirname, "../runtime", "IRuntime.js");
|
|
97
|
-
const IRuntimeFilename = path.basename(sourceIRuntimeFilePath);
|
|
98
65
|
const artifactsFilename = "artifacts.ts";
|
|
66
|
+
const IRuntimeFilename = "IRuntime.d.ts";
|
|
99
67
|
const tsConfigJSON = {
|
|
100
68
|
compilerOptions: {
|
|
101
69
|
module: "commonjs",
|
|
102
70
|
moduleResolution: "node",
|
|
103
71
|
target: "es2020",
|
|
104
72
|
declaration: true,
|
|
105
|
-
outDir: "./sdk-ts"
|
|
73
|
+
outDir: "./sdk-ts",
|
|
106
74
|
},
|
|
107
|
-
include: [sdkFilename, artifactsFilename, IRuntimeFilename]
|
|
75
|
+
include: [sdkFilename, artifactsFilename, IRuntimeFilename],
|
|
108
76
|
};
|
|
109
77
|
const packageJSON = {
|
|
110
78
|
name: "temp",
|
|
@@ -113,15 +81,14 @@ async function generate(input) {
|
|
|
113
81
|
dependencies: require("../../package.json").dependencies,
|
|
114
82
|
devDependencies: {
|
|
115
83
|
"@types/node": require("../../package.json").devDependencies["@types/node"],
|
|
116
|
-
typescript: require("../../package.json").devDependencies.typescript
|
|
117
|
-
}
|
|
84
|
+
typescript: require("../../package.json").devDependencies.typescript,
|
|
85
|
+
},
|
|
118
86
|
};
|
|
119
|
-
const tmpDirPath = path.join(os.tmpdir(),
|
|
120
|
-
// _ because - in filename is not supported by mysql2sqlite
|
|
121
|
-
`dsg_${node_crypto_1.default.randomUUID()}`.replace(/-/g, "_"));
|
|
87
|
+
const tmpDirPath = path.join(os.tmpdir(), `dsg-${(0, uuid_1.v4)()}`);
|
|
122
88
|
fse.mkdirpSync(tmpDirPath);
|
|
123
89
|
fs.writeFileSync(path.join(tmpDirPath, sdkFilename), sdkSource);
|
|
124
90
|
fs.writeFileSync(path.join(tmpDirPath, artifactsFilename), artifactsSource);
|
|
91
|
+
const sourceIRuntimeFilePath = path.join(__dirname, "../runtime", IRuntimeFilename);
|
|
125
92
|
fse.copyFileSync(sourceIRuntimeFilePath, path.join(tmpDirPath, IRuntimeFilename));
|
|
126
93
|
const typesDirPath = path.join(tmpDirPath, "types");
|
|
127
94
|
fse.mkdirpSync(typesDirPath);
|
|
@@ -161,40 +128,7 @@ async function generate(input) {
|
|
|
161
128
|
.join("\n"));
|
|
162
129
|
// TODO: workaround for IRuntime.d.ts not being included
|
|
163
130
|
// copyFileSync hangs for some reason, so use writeFileSync + readFileSync instead
|
|
164
|
-
fs.writeFileSync(path.join(tmpBuildOutputPath,
|
|
165
|
-
? fs.readFileSync(path.join(__dirname, "../runtime", "IRuntime.d.ts"))
|
|
166
|
-
: fs.readFileSync(sourceIRuntimeFilePath));
|
|
167
|
-
if (dialect === "mysql" && input.outputSqliteSchema) {
|
|
168
|
-
// Since mysql2sqlite outputs a malformed string if a column
|
|
169
|
-
// has the name `enum`, temporarily change the name to something else,
|
|
170
|
-
// then change it back.
|
|
171
|
-
const enumMarker = "`" + node_crypto_1.default.randomUUID() + "`";
|
|
172
|
-
const schemaMySql = Object.values(artifacts)
|
|
173
|
-
.reduce((acc, x) => {
|
|
174
|
-
let d = x.dump?.schema;
|
|
175
|
-
if (!d) {
|
|
176
|
-
return acc;
|
|
177
|
-
}
|
|
178
|
-
d = d.replace(/`enum`/g, enumMarker);
|
|
179
|
-
d += ";";
|
|
180
|
-
acc.push(d);
|
|
181
|
-
return acc;
|
|
182
|
-
}, [])
|
|
183
|
-
.join("\n\n");
|
|
184
|
-
const mysql2SqliteSrc = getMysql2sqliteSrc();
|
|
185
|
-
const mysql2SqlitePath = path.join(tmpDirPath, "mysql2sqlite");
|
|
186
|
-
fs.writeFileSync(mysql2SqlitePath, mysql2SqliteSrc);
|
|
187
|
-
fs.chmodSync(mysql2SqlitePath, 0o755);
|
|
188
|
-
const tmpMySqlSchemaFilename = "tmp.sql";
|
|
189
|
-
const tmpMySqlSchemaPath = path.join(tmpDirPath, tmpMySqlSchemaFilename);
|
|
190
|
-
fs.writeFileSync(tmpMySqlSchemaPath, schemaMySql);
|
|
191
|
-
let schemaSqlite = child_process
|
|
192
|
-
.execFileSync(mysql2SqlitePath, [tmpMySqlSchemaFilename], { cwd: tmpDirPath })
|
|
193
|
-
.toString();
|
|
194
|
-
schemaSqlite = schemaSqlite.replace(new RegExp(enumMarker, "g"), "`enum`");
|
|
195
|
-
const src = prettier.format(`module.exports = { schema: \`${schemaSqlite.replace(/`/g, "\\`")}\` }`, { parser: "babel" });
|
|
196
|
-
fs.writeFileSync(path.join(tmpBuildOutputPath, "artifacts.sqlite.js"), src);
|
|
197
|
-
}
|
|
131
|
+
fs.writeFileSync(path.join(tmpBuildOutputPath, IRuntimeFilename), fs.readFileSync(sourceIRuntimeFilePath));
|
|
198
132
|
if (!fs.existsSync(outdir)) {
|
|
199
133
|
fse.mkdirpSync(outdir);
|
|
200
134
|
}
|
|
@@ -211,7 +145,7 @@ function init(input) {
|
|
|
211
145
|
password,
|
|
212
146
|
host,
|
|
213
147
|
port,
|
|
214
|
-
database
|
|
148
|
+
database,
|
|
215
149
|
});
|
|
216
150
|
query = mysql.query.bind(mysql);
|
|
217
151
|
}
|
|
@@ -221,7 +155,7 @@ function init(input) {
|
|
|
221
155
|
user,
|
|
222
156
|
password,
|
|
223
157
|
port,
|
|
224
|
-
database
|
|
158
|
+
database,
|
|
225
159
|
});
|
|
226
160
|
const poolConnect = pool.connect();
|
|
227
161
|
async function runMSSQLQuery(...input) {
|
|
@@ -245,7 +179,7 @@ async function getSDKSource(input, specialCaseUuidColumn, supplementClientOpts)
|
|
|
245
179
|
"typeReturnBaseName",
|
|
246
180
|
"typeWhereName",
|
|
247
181
|
"typeOrderByName",
|
|
248
|
-
"typeDataName"
|
|
182
|
+
"typeDataName",
|
|
249
183
|
]) {
|
|
250
184
|
const str = d[k];
|
|
251
185
|
if (str) {
|
|
@@ -270,13 +204,10 @@ async function getSDKSource(input, specialCaseUuidColumn, supplementClientOpts)
|
|
|
270
204
|
clientOpts: { [k: string]: any; },
|
|
271
205
|
otherOpts?: { [k: string]: any; }
|
|
272
206
|
}) {
|
|
273
|
-
|
|
274
|
-
if (opts.clientOpts.filename === ":memory:") {
|
|
275
|
-
otherOpts = { ...otherOpts, createTablesString: require("./artifacts.sqlite").schema }
|
|
276
|
-
}
|
|
207
|
+
opts.otherOpts = opts.otherOpts ?? {}
|
|
277
208
|
this.runtime = new opts.runtime(opts.clientOpts, ${supplementClientOpts === true
|
|
278
|
-
? "{ supplementClientOpts: true, ...otherOpts }"
|
|
279
|
-
: "otherOpts"}, artifacts);
|
|
209
|
+
? "{ supplementClientOpts: true, ...opts.otherOpts }"
|
|
210
|
+
: "opts.otherOpts"}, artifacts);
|
|
280
211
|
}
|
|
281
212
|
|
|
282
213
|
$use(middleware: TMiddleware) {
|
|
@@ -302,269 +233,159 @@ async function getSDKSource(input, specialCaseUuidColumn, supplementClientOpts)
|
|
|
302
233
|
return this.runtime.$shutdown();
|
|
303
234
|
}
|
|
304
235
|
|
|
305
|
-
async $startTransaction(input?: {
|
|
306
|
-
isolationLevel?:
|
|
307
|
-
| "READ UNCOMMITTED"
|
|
308
|
-
| "READ COMMITTED"
|
|
309
|
-
| "REPEATABLE READ"
|
|
310
|
-
| "SERIALIZABLE"
|
|
311
|
-
}) {
|
|
312
|
-
const { dbCall, commit, rollback } = await this.runtime.$startTransaction(input);
|
|
313
|
-
const runtime = this.runtime;
|
|
314
|
-
return {
|
|
315
|
-
$commit: commit,
|
|
316
|
-
$rollback: rollback,
|
|
317
|
-
${(await Promise.all(input.flatMap(async (x) => {
|
|
318
|
-
if (x.kind === "getOne") {
|
|
319
|
-
const findOnes = await getFindOnes(x, specialCaseUuidColumn);
|
|
320
|
-
return getMethodSourceGetOne(x, findOnes, true);
|
|
321
|
-
}
|
|
322
|
-
if (x.kind === "getList") {
|
|
323
|
-
return getMethodSourceGetList(x, true);
|
|
324
|
-
}
|
|
325
|
-
if (x.kind === "getListPaginated") {
|
|
326
|
-
return getMethodSourceGetListPaginated(x, true);
|
|
327
|
-
}
|
|
328
|
-
if (x.kind === "postOne") {
|
|
329
|
-
return getMethodSourcePostOne(x, specialCaseUuidColumn, true);
|
|
330
|
-
}
|
|
331
|
-
if (x.kind === "patchOne") {
|
|
332
|
-
const findOnes = await getFindOnes(x, specialCaseUuidColumn);
|
|
333
|
-
return getMethodSourcePatchOne(x, findOnes, true);
|
|
334
|
-
}
|
|
335
|
-
if (x.kind === "patchList") {
|
|
336
|
-
return getMethodSourcePatchList(x, true);
|
|
337
|
-
}
|
|
338
|
-
if (x.kind === "deleteOne") {
|
|
339
|
-
const findOnes = await getFindOnes(x, specialCaseUuidColumn);
|
|
340
|
-
return getMethodSourceDeleteOne(x, findOnes, true);
|
|
341
|
-
}
|
|
342
|
-
if (x.kind === "deleteList") {
|
|
343
|
-
return getMethodSourceDeleteList(x, true);
|
|
344
|
-
}
|
|
345
|
-
}))).join(",\n")}
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
|
|
349
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
|
+
}));
|
|
350
247
|
if (x.kind === "getOne") {
|
|
351
|
-
|
|
352
|
-
|
|
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
|
+
}`;
|
|
353
266
|
}
|
|
354
267
|
if (x.kind === "getList") {
|
|
355
|
-
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
|
+
}`;
|
|
356
284
|
}
|
|
357
285
|
if (x.kind === "getListPaginated") {
|
|
358
|
-
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
|
+
}`;
|
|
359
302
|
}
|
|
360
303
|
if (x.kind === "postOne") {
|
|
361
|
-
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
|
+
}`;
|
|
362
317
|
}
|
|
363
318
|
if (x.kind === "patchOne") {
|
|
364
|
-
|
|
365
|
-
|
|
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
|
+
}`;
|
|
366
336
|
}
|
|
367
337
|
if (x.kind === "patchList") {
|
|
368
|
-
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
|
+
}`;
|
|
369
353
|
}
|
|
370
354
|
if (x.kind === "deleteOne") {
|
|
371
|
-
|
|
372
|
-
|
|
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
|
+
}`;
|
|
373
369
|
}
|
|
374
370
|
if (x.kind === "deleteList") {
|
|
375
|
-
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
|
+
}`;
|
|
376
383
|
}
|
|
377
384
|
}))).join("\n\n")}
|
|
378
385
|
}
|
|
379
|
-
|
|
380
386
|
`;
|
|
381
387
|
return prettier.format(src, { parser: "typescript" });
|
|
382
388
|
}
|
|
383
|
-
async function getFindOnes(x, specialCaseUuidColumn) {
|
|
384
|
-
let findOnes = [];
|
|
385
|
-
const primaryColumn = await getPrimaryColumn(x.table);
|
|
386
|
-
const uniqueColumns = await getUniqueColumns(x.table, specialCaseUuidColumn);
|
|
387
|
-
findOnes = findOnes
|
|
388
|
-
.concat([primaryColumn])
|
|
389
|
-
.concat(uniqueColumns)
|
|
390
|
-
.map((x) => ({
|
|
391
|
-
...x,
|
|
392
|
-
type: x.type === "integer" ? "number" : x.type
|
|
393
|
-
}));
|
|
394
|
-
return findOnes;
|
|
395
|
-
}
|
|
396
|
-
function getMethodSourceGetOne(x, findOnes, isTransaction) {
|
|
397
|
-
return `async ${x.methodName}(
|
|
398
|
-
param1: ${findOnes
|
|
399
|
-
.map((findOne) => `{ ${findOne.name}: ${findOne.type}${findOne.nullable ? " | null" : ""} }`)
|
|
400
|
-
.join(" | ")},
|
|
401
|
-
param2?: { fields?: ${x.typeFieldsName}, correlationId?: string, skipCache?: boolean, context?: TContext }
|
|
402
|
-
): Promise<${x.typeReturnBaseName}> {
|
|
403
|
-
return ${isTransaction ? "runtime" : "this.runtime"}.resolve(
|
|
404
|
-
{
|
|
405
|
-
resource: "${x.table}",
|
|
406
|
-
action: "${mapKindToAction(x.kind)}",
|
|
407
|
-
args: { $where: param1 },
|
|
408
|
-
fields: param2?.fields,
|
|
409
|
-
artifacts,
|
|
410
|
-
context: param2?.context,
|
|
411
|
-
skipCache: param2?.skipCache,
|
|
412
|
-
${isTransaction ? "dbCall" : ""}
|
|
413
|
-
}
|
|
414
|
-
);
|
|
415
|
-
}`;
|
|
416
|
-
}
|
|
417
|
-
function getMethodSourceGetList(x, isTransaction) {
|
|
418
|
-
return `async ${x.methodName}(
|
|
419
|
-
param1: { $where?: ${x.typeWhereName}, $orderBy?: ${x.typeOrderByName}, $limit?: number },
|
|
420
|
-
param2?: { fields?: ${x.typeFieldsName}, correlationId?: string, skipCache?: boolean, context?: TContext }
|
|
421
|
-
): Promise<Array<${x.typeReturnBaseName}>> {
|
|
422
|
-
return ${isTransaction ? "runtime" : "this.runtime"}.resolve(
|
|
423
|
-
{
|
|
424
|
-
resource: "${x.table}",
|
|
425
|
-
action: "${mapKindToAction(x.kind)}",
|
|
426
|
-
args: param1,
|
|
427
|
-
fields: param2?.fields,
|
|
428
|
-
artifacts,
|
|
429
|
-
context: param2?.context,
|
|
430
|
-
skipCache: param2?.skipCache,
|
|
431
|
-
${isTransaction ? "dbCall" : ""}
|
|
432
|
-
}
|
|
433
|
-
);
|
|
434
|
-
}`;
|
|
435
|
-
}
|
|
436
|
-
function getMethodSourceGetListPaginated(x, isTransaction) {
|
|
437
|
-
return `async ${x.methodName}(
|
|
438
|
-
param1: { $where?: ${x.typeWhereName}, $orderBy?: ${x.typeOrderByName}, $paginate: Paginate },
|
|
439
|
-
param2?: { fields?: ${x.typeFieldsName}, correlationId?: string, skipCache?: boolean, context?: TContext }
|
|
440
|
-
): Promise<ListPaginated<${x.typeReturnBaseName}>> {
|
|
441
|
-
return ${isTransaction ? "runtime" : "this.runtime"}.resolve(
|
|
442
|
-
{
|
|
443
|
-
resource: "${x.table}",
|
|
444
|
-
action: "${mapKindToAction(x.kind)}",
|
|
445
|
-
args: param1,
|
|
446
|
-
fields: param2?.fields,
|
|
447
|
-
artifacts,
|
|
448
|
-
context: param2?.context,
|
|
449
|
-
skipCache: param2?.skipCache,
|
|
450
|
-
${isTransaction ? "dbCall" : ""}
|
|
451
|
-
}
|
|
452
|
-
);
|
|
453
|
-
}`;
|
|
454
|
-
}
|
|
455
|
-
function getMethodSourcePostOne(x, specialCaseUuidColumn, isTransaction) {
|
|
456
|
-
return `async ${x.methodName}(
|
|
457
|
-
data: ${x.typeDataName},
|
|
458
|
-
param2?: { fields?: ${x.typeFieldsName}, correlationId?: string, context?: TContext }
|
|
459
|
-
): Promise<${x.typeReturnBaseName}> {
|
|
460
|
-
return ${isTransaction ? "runtime" : "this.runtime"}.resolve({
|
|
461
|
-
resource: "${x.table}",
|
|
462
|
-
action: "${mapKindToAction(x.kind)}",
|
|
463
|
-
data,
|
|
464
|
-
artifacts,
|
|
465
|
-
fields: param2?.fields,
|
|
466
|
-
context: {...param2?.context, specialCaseUuidColumn: ${JSON.stringify(specialCaseUuidColumn)}},
|
|
467
|
-
${isTransaction ? "dbCall" : ""}
|
|
468
|
-
});
|
|
469
|
-
}`;
|
|
470
|
-
}
|
|
471
|
-
function getMethodSourcePatchOne(x, findOnes, isTransaction) {
|
|
472
|
-
return `async ${x.methodName}(
|
|
473
|
-
param1: ${findOnes
|
|
474
|
-
.map((findOne) => `{ ${findOne.name}: ${findOne.type}${findOne.nullable ? " | null" : ""} }`)
|
|
475
|
-
.join(" | ")},
|
|
476
|
-
data: ${x.typeDataName},
|
|
477
|
-
param2?: { fields?: ${x.typeFieldsName}, correlationId?: string, context?: TContext }
|
|
478
|
-
): Promise<${x.typeReturnBaseName}> {
|
|
479
|
-
return ${isTransaction ? "runtime" : "this.runtime"}.resolve({
|
|
480
|
-
resource: "${x.table}",
|
|
481
|
-
action: "${mapKindToAction(x.kind)}",
|
|
482
|
-
args: { $where: param1 },
|
|
483
|
-
data,
|
|
484
|
-
artifacts,
|
|
485
|
-
fields: param2?.fields,
|
|
486
|
-
context: param2?.context,
|
|
487
|
-
${isTransaction ? "dbCall" : ""}
|
|
488
|
-
});
|
|
489
|
-
}`;
|
|
490
|
-
}
|
|
491
|
-
function getMethodSourcePatchList(x, isTransaction) {
|
|
492
|
-
return `async ${x.methodName}(
|
|
493
|
-
param1: { $where?: ${x.typeWhereName} },
|
|
494
|
-
data: ${x.typeDataName},
|
|
495
|
-
param2?: { fields?: ${x.typeFieldsName}, correlationId?: string, context?: TContext }
|
|
496
|
-
): Promise<Array<${x.typeReturnBaseName}>> {
|
|
497
|
-
return ${isTransaction ? "runtime" : "this.runtime"}.resolve({
|
|
498
|
-
resource: "${x.table}",
|
|
499
|
-
action: "${mapKindToAction(x.kind)}",
|
|
500
|
-
args: param1,
|
|
501
|
-
data,
|
|
502
|
-
artifacts,
|
|
503
|
-
fields: param2?.fields,
|
|
504
|
-
context: param2?.context,
|
|
505
|
-
${isTransaction ? "dbCall" : ""}
|
|
506
|
-
});
|
|
507
|
-
}`;
|
|
508
|
-
}
|
|
509
|
-
function getMethodSourceDeleteOne(x, findOnes, isTransaction) {
|
|
510
|
-
return `async ${x.methodName}(
|
|
511
|
-
param1: ${findOnes
|
|
512
|
-
.map((findOne) => `{ ${findOne.name}: ${findOne.type}${findOne.nullable ? " | null" : ""} }`)
|
|
513
|
-
.join(" | ")},
|
|
514
|
-
param2?: { correlationId?: string, context?: TContext }
|
|
515
|
-
): Promise<void> {
|
|
516
|
-
await ${isTransaction ? "runtime" : "this.runtime"}.resolve({
|
|
517
|
-
resource: "${x.table}",
|
|
518
|
-
action: "${mapKindToAction(x.kind)}",
|
|
519
|
-
args: { $where: param1 },
|
|
520
|
-
artifacts,
|
|
521
|
-
context: param2?.context,
|
|
522
|
-
${isTransaction ? "dbCall" : ""}
|
|
523
|
-
});
|
|
524
|
-
}`;
|
|
525
|
-
}
|
|
526
|
-
function getMethodSourceDeleteList(x, isTransaction) {
|
|
527
|
-
return `async ${x.methodName}(
|
|
528
|
-
param1: { $where?: ${x.typeWhereName} },
|
|
529
|
-
param2?: { correlationId?: string, context?: TContext }
|
|
530
|
-
): Promise<void> {
|
|
531
|
-
await ${isTransaction ? "runtime" : "this.runtime"}.resolve({
|
|
532
|
-
resource: "${x.table}",
|
|
533
|
-
action: "${mapKindToAction(x.kind)}",
|
|
534
|
-
args: param1,
|
|
535
|
-
artifacts,
|
|
536
|
-
context: param2?.context,
|
|
537
|
-
${isTransaction ? "dbCall" : ""}
|
|
538
|
-
});
|
|
539
|
-
}`;
|
|
540
|
-
}
|
|
541
|
-
function mapKindToAction(kind) {
|
|
542
|
-
if (kind === "getOne") {
|
|
543
|
-
return "findUnique";
|
|
544
|
-
}
|
|
545
|
-
if (kind === "getList") {
|
|
546
|
-
return "findMany";
|
|
547
|
-
}
|
|
548
|
-
if (kind === "getListPaginated") {
|
|
549
|
-
return "findManyPaginated";
|
|
550
|
-
}
|
|
551
|
-
if (kind === "postOne") {
|
|
552
|
-
return "create";
|
|
553
|
-
}
|
|
554
|
-
if (kind === "patchOne") {
|
|
555
|
-
return "update";
|
|
556
|
-
}
|
|
557
|
-
if (kind === "patchList") {
|
|
558
|
-
return "updateMany";
|
|
559
|
-
}
|
|
560
|
-
if (kind === "deleteOne") {
|
|
561
|
-
return "delete";
|
|
562
|
-
}
|
|
563
|
-
if (kind === "deleteList") {
|
|
564
|
-
return "deleteMany";
|
|
565
|
-
}
|
|
566
|
-
throw new Error(`Unhandled kind: ${kind}`);
|
|
567
|
-
}
|
|
568
389
|
function getTypeReturnBaseName(table) {
|
|
569
390
|
return "ReturnBase" + changeCase.pascalCase(table);
|
|
570
391
|
}
|
|
@@ -590,7 +411,7 @@ async function getGetOneData(table, includeMappedFields) {
|
|
|
590
411
|
typeFields: await getTypeFields(table, typeFieldsName, includeMappedFields),
|
|
591
412
|
typeFieldsName,
|
|
592
413
|
typeReturnBase: await getTypeReturnBase(table, typeReturnBaseName, includeMappedFields),
|
|
593
|
-
typeReturnBaseName
|
|
414
|
+
typeReturnBaseName,
|
|
594
415
|
};
|
|
595
416
|
}
|
|
596
417
|
async function getGetListData(table) {
|
|
@@ -609,7 +430,7 @@ async function getGetListData(table) {
|
|
|
609
430
|
typeWhere,
|
|
610
431
|
typeWhereName,
|
|
611
432
|
typeOrderBy,
|
|
612
|
-
typeOrderByName
|
|
433
|
+
typeOrderByName,
|
|
613
434
|
};
|
|
614
435
|
}
|
|
615
436
|
async function getGetListPaginatedData(table) {
|
|
@@ -624,7 +445,7 @@ async function getGetListPaginatedData(table) {
|
|
|
624
445
|
typeFieldsName,
|
|
625
446
|
typeReturnBaseName,
|
|
626
447
|
typeWhereName,
|
|
627
|
-
typeOrderByName
|
|
448
|
+
typeOrderByName,
|
|
628
449
|
};
|
|
629
450
|
}
|
|
630
451
|
async function getPostOneData(table, specialCaseUuidColumn, includeMappedFields) {
|
|
@@ -638,7 +459,7 @@ async function getPostOneData(table, specialCaseUuidColumn, includeMappedFields)
|
|
|
638
459
|
typeFieldsName,
|
|
639
460
|
typeReturnBaseName,
|
|
640
461
|
typeData: await getTypeDataPost(table, typeDataName, specialCaseUuidColumn, includeMappedFields),
|
|
641
|
-
typeDataName
|
|
462
|
+
typeDataName,
|
|
642
463
|
};
|
|
643
464
|
}
|
|
644
465
|
async function getPatchOneData(table, specialCaseUuidColumn, includeMappedFields) {
|
|
@@ -652,7 +473,7 @@ async function getPatchOneData(table, specialCaseUuidColumn, includeMappedFields
|
|
|
652
473
|
typeFieldsName,
|
|
653
474
|
typeReturnBaseName,
|
|
654
475
|
typeData: await getTypeDataPatch(table, typeDataName, specialCaseUuidColumn, includeMappedFields),
|
|
655
|
-
typeDataName
|
|
476
|
+
typeDataName,
|
|
656
477
|
};
|
|
657
478
|
}
|
|
658
479
|
async function getPatchListData(table) {
|
|
@@ -667,14 +488,14 @@ async function getPatchListData(table) {
|
|
|
667
488
|
typeFieldsName,
|
|
668
489
|
typeReturnBaseName,
|
|
669
490
|
typeWhereName,
|
|
670
|
-
typeDataName
|
|
491
|
+
typeDataName,
|
|
671
492
|
};
|
|
672
493
|
}
|
|
673
494
|
function getDeleteOneData(table) {
|
|
674
495
|
return {
|
|
675
496
|
kind: "deleteOne",
|
|
676
497
|
table,
|
|
677
|
-
methodName: "delete" + changeCase.pascalCase(table)
|
|
498
|
+
methodName: "delete" + changeCase.pascalCase(table),
|
|
678
499
|
};
|
|
679
500
|
}
|
|
680
501
|
function getDeleteListData(table) {
|
|
@@ -683,7 +504,7 @@ function getDeleteListData(table) {
|
|
|
683
504
|
kind: "deleteList",
|
|
684
505
|
table,
|
|
685
506
|
methodName: "delete" + changeCase.pascalCase(table) + "List",
|
|
686
|
-
typeWhereName
|
|
507
|
+
typeWhereName,
|
|
687
508
|
};
|
|
688
509
|
}
|
|
689
510
|
async function getTypeWhere(table, name) {
|
|
@@ -695,11 +516,11 @@ async function getTypeDataPost(table, name, specialCaseUuidColumn, includeMapped
|
|
|
695
516
|
const tableMeta = (await getTableMeta(table)).filter((x) => x.Field !== primaryColumn.name);
|
|
696
517
|
const nullable = tableMeta.reduce((acc, m) => ({
|
|
697
518
|
...acc,
|
|
698
|
-
[m.Field]: m.Null === "YES" ? true : false
|
|
519
|
+
[m.Field]: m.Null === "YES" ? true : false,
|
|
699
520
|
}), {});
|
|
700
521
|
const hasDefault = tableMeta.reduce((acc, m) => ({
|
|
701
522
|
...acc,
|
|
702
|
-
[m.Field]: m.Default == null ? false : true
|
|
523
|
+
[m.Field]: m.Default == null ? false : true,
|
|
703
524
|
}), {});
|
|
704
525
|
let properties = getJSONSchemaObjProperties(tableMeta);
|
|
705
526
|
let notRequiredList = [];
|
|
@@ -712,7 +533,7 @@ async function getTypeDataPost(table, name, specialCaseUuidColumn, includeMapped
|
|
|
712
533
|
...mappedFields.reduce((acc, v) => {
|
|
713
534
|
acc[v.as] = { type: getJSONTypes(v.type, v.nullable) };
|
|
714
535
|
return acc;
|
|
715
|
-
}, {})
|
|
536
|
+
}, {}),
|
|
716
537
|
};
|
|
717
538
|
notRequiredList = mappedFields.flatMap((x) => [x.as, x.foreignKey]);
|
|
718
539
|
for (let r of oneToManyRelations) {
|
|
@@ -727,7 +548,9 @@ async function getTypeDataPost(table, name, specialCaseUuidColumn, includeMapped
|
|
|
727
548
|
...oneToManyRelations.reduce((acc, v) => {
|
|
728
549
|
let tsType = getTypeDataPostName(v.table);
|
|
729
550
|
const mappedFields = mappedFieldsMap.get(v.table);
|
|
730
|
-
if (includeMappedFields &&
|
|
551
|
+
if (includeMappedFields &&
|
|
552
|
+
mappedFields != null &&
|
|
553
|
+
mappedFields.length > 0) {
|
|
731
554
|
tsType = `Omit<${tsType}, ${mappedFields
|
|
732
555
|
.map((x) => JSON.stringify(x.as))
|
|
733
556
|
.join(" | ")}>`;
|
|
@@ -735,19 +558,21 @@ async function getTypeDataPost(table, name, specialCaseUuidColumn, includeMapped
|
|
|
735
558
|
tsType = `{$create: ${tsType}[]}`;
|
|
736
559
|
acc[v.name] = { tsType };
|
|
737
560
|
return acc;
|
|
738
|
-
}, {})
|
|
561
|
+
}, {}),
|
|
739
562
|
},
|
|
740
563
|
additionalProperties: false,
|
|
741
564
|
required: Object.keys(properties)
|
|
742
565
|
.filter(
|
|
743
566
|
// `uuid` should not be required
|
|
744
|
-
(x) => !specialCaseUuidColumn || uuidColumn == null
|
|
567
|
+
(x) => !specialCaseUuidColumn || uuidColumn == null
|
|
568
|
+
? true
|
|
569
|
+
: x !== uuidColumn.name)
|
|
745
570
|
.filter(
|
|
746
571
|
// Required if column is non-nullable and has no default.
|
|
747
572
|
(x) => !nullable[x] && !hasDefault[x])
|
|
748
573
|
// Instead of doing a union with all possible permutations of UUID and IDs,
|
|
749
574
|
// for simplicity, just make both not required for now.
|
|
750
|
-
.filter((x) => !notRequiredList.includes(x))
|
|
575
|
+
.filter((x) => !notRequiredList.includes(x)),
|
|
751
576
|
};
|
|
752
577
|
let type = await (0, json_schema_to_typescript_1.compile)(jsonSchema, name, json2TsOpts);
|
|
753
578
|
const imports = _.uniq(oneToManyRelations
|
|
@@ -776,13 +601,13 @@ async function getTypeDataPatch(table, name, specialCaseUuidColumn, includeMappe
|
|
|
776
601
|
const type = unwrapJSONType(properties[key].type);
|
|
777
602
|
if (type === "string") {
|
|
778
603
|
properties[key] = {
|
|
779
|
-
oneOf: [properties[key], { tsType: "TUpdateOperationsString" }]
|
|
604
|
+
oneOf: [properties[key], { tsType: "TUpdateOperationsString" }],
|
|
780
605
|
};
|
|
781
606
|
mustImportTUpdateOperationsString = true;
|
|
782
607
|
}
|
|
783
608
|
else if (type === "number" || type === "integer") {
|
|
784
609
|
properties[key] = {
|
|
785
|
-
oneOf: [properties[key], { tsType: "TUpdateOperationsNumber" }]
|
|
610
|
+
oneOf: [properties[key], { tsType: "TUpdateOperationsNumber" }],
|
|
786
611
|
};
|
|
787
612
|
mustImportTUpdateOperationsNumber = true;
|
|
788
613
|
}
|
|
@@ -794,14 +619,14 @@ async function getTypeDataPatch(table, name, specialCaseUuidColumn, includeMappe
|
|
|
794
619
|
...mappedFields.reduce((acc, v) => {
|
|
795
620
|
acc[v.as] = { type: getJSONTypes(v.type, v.nullable) };
|
|
796
621
|
return acc;
|
|
797
|
-
}, {})
|
|
622
|
+
}, {}),
|
|
798
623
|
};
|
|
799
624
|
}
|
|
800
625
|
const jsonSchema = {
|
|
801
626
|
type: "object",
|
|
802
627
|
properties,
|
|
803
628
|
additionalProperties: false,
|
|
804
|
-
required: []
|
|
629
|
+
required: [],
|
|
805
630
|
};
|
|
806
631
|
let type = await (0, json_schema_to_typescript_1.compile)(jsonSchema, name, json2TsOpts);
|
|
807
632
|
if (mustImportTUpdateOperationsString || mustImportTUpdateOperationsNumber) {
|
|
@@ -844,7 +669,7 @@ async function getMappedFields(table) {
|
|
|
844
669
|
name: "uuid",
|
|
845
670
|
// Replace `Id` with `Uuid`
|
|
846
671
|
as: x.foreignKey.slice(0, -2) + "Uuid",
|
|
847
|
-
type: getBaseJSONType(uuidColumn.Type)
|
|
672
|
+
type: getBaseJSONType(uuidColumn.Type),
|
|
848
673
|
});
|
|
849
674
|
}
|
|
850
675
|
return out;
|
|
@@ -863,52 +688,52 @@ async function getJSONSchemaWhere(table) {
|
|
|
863
688
|
{
|
|
864
689
|
type: "object",
|
|
865
690
|
properties: { $eq: v },
|
|
866
|
-
additionalProperties: false
|
|
691
|
+
additionalProperties: false,
|
|
867
692
|
},
|
|
868
693
|
{
|
|
869
694
|
type: "object",
|
|
870
695
|
properties: { $neq: v },
|
|
871
|
-
additionalProperties: false
|
|
696
|
+
additionalProperties: false,
|
|
872
697
|
},
|
|
873
698
|
{
|
|
874
699
|
type: "object",
|
|
875
700
|
properties: { $gt: v },
|
|
876
|
-
additionalProperties: false
|
|
701
|
+
additionalProperties: false,
|
|
877
702
|
},
|
|
878
703
|
{
|
|
879
704
|
type: "object",
|
|
880
705
|
properties: { $gte: v },
|
|
881
|
-
additionalProperties: false
|
|
706
|
+
additionalProperties: false,
|
|
882
707
|
},
|
|
883
708
|
{
|
|
884
709
|
type: "object",
|
|
885
710
|
properties: { $lt: v },
|
|
886
|
-
additionalProperties: false
|
|
711
|
+
additionalProperties: false,
|
|
887
712
|
},
|
|
888
713
|
{
|
|
889
714
|
type: "object",
|
|
890
715
|
properties: { $lte: v },
|
|
891
|
-
additionalProperties: false
|
|
716
|
+
additionalProperties: false,
|
|
892
717
|
},
|
|
893
718
|
{
|
|
894
719
|
type: "object",
|
|
895
720
|
properties: { $like: { type: "string", minLength: 1 } },
|
|
896
|
-
additionalProperties: false
|
|
721
|
+
additionalProperties: false,
|
|
897
722
|
},
|
|
898
723
|
{
|
|
899
724
|
type: "object",
|
|
900
725
|
properties: { $nlike: { type: "string", minLength: 1 } },
|
|
901
|
-
additionalProperties: false
|
|
726
|
+
additionalProperties: false,
|
|
902
727
|
},
|
|
903
728
|
{
|
|
904
729
|
type: "object",
|
|
905
730
|
properties: { $in: { type: "array", items: v } },
|
|
906
|
-
additionalProperties: false
|
|
731
|
+
additionalProperties: false,
|
|
907
732
|
},
|
|
908
733
|
{
|
|
909
734
|
type: "object",
|
|
910
735
|
properties: { $nin: { type: "array", items: v } },
|
|
911
|
-
additionalProperties: false
|
|
736
|
+
additionalProperties: false,
|
|
912
737
|
},
|
|
913
738
|
{
|
|
914
739
|
type: "object",
|
|
@@ -918,10 +743,10 @@ async function getJSONSchemaWhere(table) {
|
|
|
918
743
|
items: v,
|
|
919
744
|
minItems: 2,
|
|
920
745
|
maxItems: 2,
|
|
921
|
-
uniqueItems: true
|
|
922
|
-
}
|
|
746
|
+
uniqueItems: true,
|
|
747
|
+
},
|
|
923
748
|
},
|
|
924
|
-
additionalProperties: false
|
|
749
|
+
additionalProperties: false,
|
|
925
750
|
},
|
|
926
751
|
{
|
|
927
752
|
type: "object",
|
|
@@ -931,15 +756,15 @@ async function getJSONSchemaWhere(table) {
|
|
|
931
756
|
items: v,
|
|
932
757
|
minItems: 2,
|
|
933
758
|
maxItems: 2,
|
|
934
|
-
uniqueItems: true
|
|
935
|
-
}
|
|
759
|
+
uniqueItems: true,
|
|
760
|
+
},
|
|
936
761
|
},
|
|
937
|
-
additionalProperties: false
|
|
938
|
-
}
|
|
939
|
-
]
|
|
940
|
-
}
|
|
762
|
+
additionalProperties: false,
|
|
763
|
+
},
|
|
764
|
+
],
|
|
765
|
+
},
|
|
941
766
|
}), {}),
|
|
942
|
-
additionalProperties: false
|
|
767
|
+
additionalProperties: false,
|
|
943
768
|
},
|
|
944
769
|
{
|
|
945
770
|
type: "object",
|
|
@@ -947,17 +772,17 @@ async function getJSONSchemaWhere(table) {
|
|
|
947
772
|
$and: {
|
|
948
773
|
type: "array",
|
|
949
774
|
items: {
|
|
950
|
-
$ref: `#/definitions/${whereSchemaName}
|
|
775
|
+
$ref: `#/definitions/${whereSchemaName}`,
|
|
951
776
|
},
|
|
952
777
|
// While it makes sense conceptually for $and to have
|
|
953
778
|
// at least 2 items, in practice, $and could be
|
|
954
779
|
// generated dynamically and could end up having
|
|
955
780
|
// less than 2 items, so don't enforce minItems.
|
|
956
781
|
// minItems: 2,
|
|
957
|
-
additionalProperties: false
|
|
958
|
-
}
|
|
782
|
+
additionalProperties: false,
|
|
783
|
+
},
|
|
959
784
|
},
|
|
960
|
-
additionalProperties: false
|
|
785
|
+
additionalProperties: false,
|
|
961
786
|
},
|
|
962
787
|
{
|
|
963
788
|
type: "object",
|
|
@@ -965,19 +790,19 @@ async function getJSONSchemaWhere(table) {
|
|
|
965
790
|
$or: {
|
|
966
791
|
type: "array",
|
|
967
792
|
items: {
|
|
968
|
-
$ref: `#/definitions/${whereSchemaName}
|
|
793
|
+
$ref: `#/definitions/${whereSchemaName}`,
|
|
969
794
|
},
|
|
970
795
|
// While it makes sense conceptually for $and to have
|
|
971
796
|
// at least 2 items, in practice, $and could be
|
|
972
797
|
// generated dynamically and could end up having
|
|
973
798
|
// less than 2 items, so don't enforce minItems.
|
|
974
799
|
// minItems: 2,
|
|
975
|
-
additionalProperties: false
|
|
976
|
-
}
|
|
800
|
+
additionalProperties: false,
|
|
801
|
+
},
|
|
977
802
|
},
|
|
978
|
-
additionalProperties: false
|
|
979
|
-
}
|
|
980
|
-
]
|
|
803
|
+
additionalProperties: false,
|
|
804
|
+
},
|
|
805
|
+
],
|
|
981
806
|
};
|
|
982
807
|
return {
|
|
983
808
|
definitions: { [whereSchemaName]: defWhere },
|
|
@@ -994,12 +819,12 @@ async function getJSONSchemaWhere(table) {
|
|
|
994
819
|
// generated dynamically and could end up having
|
|
995
820
|
// less than 2 items, so don't enforce minItems.
|
|
996
821
|
// minItems: 2,
|
|
997
|
-
additionalProperties: false
|
|
998
|
-
}
|
|
822
|
+
additionalProperties: false,
|
|
823
|
+
},
|
|
999
824
|
},
|
|
1000
|
-
additionalProperties: false
|
|
1001
|
-
}))
|
|
1002
|
-
]
|
|
825
|
+
additionalProperties: false,
|
|
826
|
+
})),
|
|
827
|
+
],
|
|
1003
828
|
};
|
|
1004
829
|
}
|
|
1005
830
|
async function getTypeOrderBy(table, name) {
|
|
@@ -1012,14 +837,14 @@ async function getJSONSchemaOrderBy(table, name) {
|
|
|
1012
837
|
type: "object",
|
|
1013
838
|
properties: { [k]: { enum: ["asc", "desc"] } },
|
|
1014
839
|
required: [k],
|
|
1015
|
-
additionalProperties: false
|
|
1016
|
-
}))
|
|
840
|
+
additionalProperties: false,
|
|
841
|
+
})),
|
|
1017
842
|
};
|
|
1018
843
|
const defName = `_${name}`;
|
|
1019
844
|
const _schema = { $ref: `#/definitions/${defName}` };
|
|
1020
845
|
return {
|
|
1021
846
|
definitions: { [defName]: def },
|
|
1022
|
-
oneOf: [_schema, { type: "array", items: _schema }]
|
|
847
|
+
oneOf: [_schema, { type: "array", items: _schema }],
|
|
1023
848
|
};
|
|
1024
849
|
}
|
|
1025
850
|
function getTypeTypesIndex(data) {
|
|
@@ -1033,7 +858,7 @@ function getTypeTypesIndex(data) {
|
|
|
1033
858
|
"typeReturnBaseName",
|
|
1034
859
|
"typeWhereName",
|
|
1035
860
|
"typeOrderByName",
|
|
1036
|
-
"typeDataName"
|
|
861
|
+
"typeDataName",
|
|
1037
862
|
]) {
|
|
1038
863
|
const str = d[k];
|
|
1039
864
|
if (str) {
|
|
@@ -1045,7 +870,7 @@ function getTypeTypesIndex(data) {
|
|
|
1045
870
|
"Paginate",
|
|
1046
871
|
"ListPaginated",
|
|
1047
872
|
"TUpdateOperationsString",
|
|
1048
|
-
"TUpdateOperationsNumber"
|
|
873
|
+
"TUpdateOperationsNumber",
|
|
1049
874
|
].join(",")} } from "./_shared";\n\n`;
|
|
1050
875
|
let arr = Array.from(set).sort();
|
|
1051
876
|
for (let x of arr) {
|
|
@@ -1095,7 +920,7 @@ async function getTypeFields(table, name, includeMappedFields) {
|
|
|
1095
920
|
items: {
|
|
1096
921
|
anyOf: [
|
|
1097
922
|
{
|
|
1098
|
-
enum: scalarKeys.concat(mappedFields.map((x) => x.as))
|
|
923
|
+
enum: scalarKeys.concat(mappedFields.map((x) => x.as)),
|
|
1099
924
|
},
|
|
1100
925
|
...relations.map((x) => {
|
|
1101
926
|
const argsProperties = x.type === "many-to-many"
|
|
@@ -1105,17 +930,17 @@ async function getTypeFields(table, name, includeMappedFields) {
|
|
|
1105
930
|
properties: {
|
|
1106
931
|
[x.table]: { tsType: getTypeWhereName(x.table) },
|
|
1107
932
|
[x.junctionTable]: {
|
|
1108
|
-
tsType: getTypeWhereName(x.junctionTable)
|
|
1109
|
-
}
|
|
933
|
+
tsType: getTypeWhereName(x.junctionTable),
|
|
934
|
+
},
|
|
1110
935
|
},
|
|
1111
|
-
additionalProperties: false
|
|
1112
|
-
}
|
|
936
|
+
additionalProperties: false,
|
|
937
|
+
},
|
|
1113
938
|
}
|
|
1114
939
|
: { [keyWhere]: { tsType: getTypeWhereName(x.table) } };
|
|
1115
940
|
// $orderBy only makes sense for a list
|
|
1116
941
|
if (x.grabMany) {
|
|
1117
942
|
argsProperties[keyOrderBy] = {
|
|
1118
|
-
tsType: getTypeOrderByName(x.table)
|
|
943
|
+
tsType: getTypeOrderByName(x.table),
|
|
1119
944
|
};
|
|
1120
945
|
}
|
|
1121
946
|
return {
|
|
@@ -1127,19 +952,21 @@ async function getTypeFields(table, name, includeMappedFields) {
|
|
|
1127
952
|
args: {
|
|
1128
953
|
type: "object",
|
|
1129
954
|
properties: argsProperties,
|
|
1130
|
-
additionalProperties: false
|
|
955
|
+
additionalProperties: false,
|
|
1131
956
|
},
|
|
1132
|
-
transform: { tsType: `(x: any) => any` }
|
|
957
|
+
transform: { tsType: `(x: any) => any` },
|
|
1133
958
|
},
|
|
1134
959
|
additionalProperties: false,
|
|
1135
|
-
required: ["name", "fields"]
|
|
960
|
+
required: ["name", "fields"],
|
|
1136
961
|
};
|
|
1137
|
-
})
|
|
1138
|
-
]
|
|
1139
|
-
}
|
|
962
|
+
}),
|
|
963
|
+
],
|
|
964
|
+
},
|
|
1140
965
|
};
|
|
1141
966
|
let type = await (0, json_schema_to_typescript_1.compile)(jsonSchemaFields, name, json2TsOpts);
|
|
1142
|
-
const fieldImports = _.uniq(relations
|
|
967
|
+
const fieldImports = _.uniq(relations
|
|
968
|
+
.filter((x) => x.table !== table)
|
|
969
|
+
.map((x) => getTypeFieldsName(x.table)));
|
|
1143
970
|
const whereImports = _.uniq(relations.flatMap((x) => x.type === "many-to-many"
|
|
1144
971
|
? [getTypeWhereName(x.table), getTypeWhereName(x.junctionTable)]
|
|
1145
972
|
: getTypeWhereName(x.table)));
|
|
@@ -1179,10 +1006,10 @@ async function getTypeReturnBase(table, name, includeMappedFields) {
|
|
|
1179
1006
|
acc[key] = { tsType };
|
|
1180
1007
|
}
|
|
1181
1008
|
return acc;
|
|
1182
|
-
}, {})
|
|
1009
|
+
}, {}),
|
|
1183
1010
|
},
|
|
1184
1011
|
// Because of aliases
|
|
1185
|
-
additionalProperties: true
|
|
1012
|
+
additionalProperties: true,
|
|
1186
1013
|
};
|
|
1187
1014
|
let type = await (0, json_schema_to_typescript_1.compile)(jsonSchemaReturn, name, json2TsOpts);
|
|
1188
1015
|
const imports = _.uniq(relations.map((x) => getTypeReturnBaseName(x.table)))
|
|
@@ -1198,21 +1025,10 @@ function getMaybeNullableTsType(type, nullable) {
|
|
|
1198
1025
|
}
|
|
1199
1026
|
return type;
|
|
1200
1027
|
}
|
|
1201
|
-
function getArtifactsSource(
|
|
1202
|
-
const src = `
|
|
1203
|
-
import type {IArtifacts} from "./IRuntime";
|
|
1204
|
-
|
|
1205
|
-
export const artifacts: IArtifacts = ${JSON.stringify(artifacts)};
|
|
1206
|
-
`;
|
|
1207
|
-
return prettier.format(src, { parser: "typescript" });
|
|
1208
|
-
}
|
|
1209
|
-
async function getArtifacts(tables, includeMappedFields, specialCaseUuidColumn) {
|
|
1028
|
+
async function getArtifactsSource(tables, includeMappedFields, specialCaseUuidColumn) {
|
|
1210
1029
|
const tableMetaList = await Promise.all(tables.map(async (table) => {
|
|
1211
|
-
const
|
|
1212
|
-
|
|
1213
|
-
getPrimaryColumn(table).then((x) => x.name),
|
|
1214
|
-
getShowCreateTable(table)
|
|
1215
|
-
]);
|
|
1030
|
+
const tableMeta = await getTableMeta(table);
|
|
1031
|
+
const primaryKey = await getPrimaryColumn(table).then((x) => x.name);
|
|
1216
1032
|
const scalarFields = tableMeta.map((x) => x.Field);
|
|
1217
1033
|
const relationInfo = await getRelationInfo(table);
|
|
1218
1034
|
const relationFields = relationInfo.reduce((acc, x) => {
|
|
@@ -1224,7 +1040,7 @@ async function getArtifacts(tables, includeMappedFields, specialCaseUuidColumn)
|
|
|
1224
1040
|
table: x.table,
|
|
1225
1041
|
grabMany: x.grabMany,
|
|
1226
1042
|
nullable: x.nullable,
|
|
1227
|
-
relation: x.relation
|
|
1043
|
+
relation: x.relation,
|
|
1228
1044
|
};
|
|
1229
1045
|
}
|
|
1230
1046
|
else {
|
|
@@ -1234,12 +1050,14 @@ async function getArtifacts(tables, includeMappedFields, specialCaseUuidColumn)
|
|
|
1234
1050
|
table: x.table,
|
|
1235
1051
|
junctionTable: x.junctionTable,
|
|
1236
1052
|
grabMany: x.grabMany,
|
|
1237
|
-
relations: x.relations
|
|
1053
|
+
relations: x.relations,
|
|
1238
1054
|
};
|
|
1239
1055
|
}
|
|
1240
1056
|
return acc;
|
|
1241
1057
|
}, {});
|
|
1242
|
-
const _mappedFields = includeMappedFields
|
|
1058
|
+
const _mappedFields = includeMappedFields
|
|
1059
|
+
? await getMappedFields(table)
|
|
1060
|
+
: [];
|
|
1243
1061
|
const mappedFields = _mappedFields.length === 0
|
|
1244
1062
|
? null
|
|
1245
1063
|
: _mappedFields.reduce((acc, v) => {
|
|
@@ -1255,47 +1073,6 @@ async function getArtifacts(tables, includeMappedFields, specialCaseUuidColumn)
|
|
|
1255
1073
|
return acc;
|
|
1256
1074
|
}, {});
|
|
1257
1075
|
const uniqueFields = await getUniqueColumns(table, specialCaseUuidColumn);
|
|
1258
|
-
let fields = tableMeta.map((t) => {
|
|
1259
|
-
const nullable = t.Null === "YES";
|
|
1260
|
-
const isEnum = t.Type.startsWith("enum");
|
|
1261
|
-
if (isEnum) {
|
|
1262
|
-
const values = getPropertyEnum(t.Type);
|
|
1263
|
-
if (values && nullable) {
|
|
1264
|
-
values.push(null);
|
|
1265
|
-
}
|
|
1266
|
-
return {
|
|
1267
|
-
kind: "enum",
|
|
1268
|
-
values,
|
|
1269
|
-
name: t.Field,
|
|
1270
|
-
nullable
|
|
1271
|
-
};
|
|
1272
|
-
}
|
|
1273
|
-
return {
|
|
1274
|
-
kind: "scalar",
|
|
1275
|
-
type: getBaseJSONType(t.Type),
|
|
1276
|
-
name: t.Field,
|
|
1277
|
-
nullable,
|
|
1278
|
-
hasDefaultValue: !!t.Default
|
|
1279
|
-
};
|
|
1280
|
-
});
|
|
1281
|
-
for (let x of _mappedFields) {
|
|
1282
|
-
fields.push({
|
|
1283
|
-
kind: "scalar",
|
|
1284
|
-
type: x.type,
|
|
1285
|
-
name: x.as,
|
|
1286
|
-
nullable: x.nullable,
|
|
1287
|
-
// TODO
|
|
1288
|
-
hasDefaultValue: false
|
|
1289
|
-
});
|
|
1290
|
-
}
|
|
1291
|
-
for (let x of relationInfo) {
|
|
1292
|
-
fields.push({
|
|
1293
|
-
kind: "object",
|
|
1294
|
-
type: x.table,
|
|
1295
|
-
name: x.name,
|
|
1296
|
-
isList: x.grabMany
|
|
1297
|
-
});
|
|
1298
|
-
}
|
|
1299
1076
|
return {
|
|
1300
1077
|
table,
|
|
1301
1078
|
primaryKey,
|
|
@@ -1305,15 +1082,18 @@ async function getArtifacts(tables, includeMappedFields, specialCaseUuidColumn)
|
|
|
1305
1082
|
uniqueFields,
|
|
1306
1083
|
dateTimeFields,
|
|
1307
1084
|
dateTimeFieldsCount: Object.keys(dateTimeFields).length,
|
|
1308
|
-
fields,
|
|
1309
|
-
dump: dumpSchema == null ? null : { schema: dumpSchema }
|
|
1310
1085
|
};
|
|
1311
1086
|
}));
|
|
1312
1087
|
const artifacts = tableMetaList.reduce((acc, x) => {
|
|
1313
1088
|
acc[x.table] = x;
|
|
1314
1089
|
return acc;
|
|
1315
1090
|
}, {});
|
|
1316
|
-
|
|
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" });
|
|
1317
1097
|
}
|
|
1318
1098
|
const getRelationInfo = _.memoize(async function getRelationInfo(table) {
|
|
1319
1099
|
const relationsManyToOne = await getRelationsManyToOne(table);
|
|
@@ -1328,7 +1108,7 @@ const getRelationInfo = _.memoize(async function getRelationInfo(table) {
|
|
|
1328
1108
|
table: x.referencedTable,
|
|
1329
1109
|
name,
|
|
1330
1110
|
relation: x,
|
|
1331
|
-
nullable: x.nullable
|
|
1111
|
+
nullable: x.nullable,
|
|
1332
1112
|
};
|
|
1333
1113
|
}));
|
|
1334
1114
|
const relationsOneToManyDuplicates = (0, getDuplicates_1.getDuplicates)(relationsOneToMany.map((x) => x.referencedTable));
|
|
@@ -1351,7 +1131,7 @@ const getRelationInfo = _.memoize(async function getRelationInfo(table) {
|
|
|
1351
1131
|
table: x.referencedTable,
|
|
1352
1132
|
name,
|
|
1353
1133
|
relation: x,
|
|
1354
|
-
nullable: x.nullable
|
|
1134
|
+
nullable: x.nullable,
|
|
1355
1135
|
};
|
|
1356
1136
|
}));
|
|
1357
1137
|
const relationsManyToMany = (await getJunctionTables()).reduce((acc, x) => {
|
|
@@ -1370,7 +1150,7 @@ const getRelationInfo = _.memoize(async function getRelationInfo(table) {
|
|
|
1370
1150
|
name: changeCase.camelCase(dataForChildTable.referencedTable) + "List",
|
|
1371
1151
|
// Ensure parent comes before child
|
|
1372
1152
|
relations: [dataForParentTable, dataForChildTable],
|
|
1373
|
-
grabMany: true
|
|
1153
|
+
grabMany: true,
|
|
1374
1154
|
});
|
|
1375
1155
|
return acc;
|
|
1376
1156
|
}, []);
|
|
@@ -1391,7 +1171,7 @@ async function getJunctionTables() {
|
|
|
1391
1171
|
// e.g. junction of Foo, Bar must be FooBar or BarFoo
|
|
1392
1172
|
[
|
|
1393
1173
|
relations[0].referencedTable + relations[1].referencedTable,
|
|
1394
|
-
relations[1].referencedTable + relations[0].referencedTable
|
|
1174
|
+
relations[1].referencedTable + relations[0].referencedTable,
|
|
1395
1175
|
].includes(table)) {
|
|
1396
1176
|
return { table, relations };
|
|
1397
1177
|
}
|
|
@@ -1447,7 +1227,7 @@ const getRelationsManyToOne = _.memoize(async function getRelationsManyToOne(tab
|
|
|
1447
1227
|
foreignKey: v.t1Field,
|
|
1448
1228
|
referencedTable: v.t2,
|
|
1449
1229
|
referencedKey: v.t2Field,
|
|
1450
|
-
nullable: tableMeta.find((m) => m.Field === v.t1Field)?.Null === "YES"
|
|
1230
|
+
nullable: tableMeta.find((m) => m.Field === v.t1Field)?.Null === "YES",
|
|
1451
1231
|
};
|
|
1452
1232
|
})));
|
|
1453
1233
|
return _.sortBy((x) => x.referencedTable, xs);
|
|
@@ -1496,7 +1276,7 @@ const getRelationsOneToMany = _.memoize(async function getRelationsOneToMany(tab
|
|
|
1496
1276
|
referencedTable: v.t1,
|
|
1497
1277
|
referencedKey: v.t1Field,
|
|
1498
1278
|
// TODO? I think this is right, since it's one-to-many, so a list
|
|
1499
|
-
nullable: false
|
|
1279
|
+
nullable: false,
|
|
1500
1280
|
};
|
|
1501
1281
|
})));
|
|
1502
1282
|
return _.sortBy((x) => x.referencedKey, _.sortBy((x) => x.referencedTable, xs));
|
|
@@ -1511,7 +1291,7 @@ async function getPrimaryColumn(table) {
|
|
|
1511
1291
|
return {
|
|
1512
1292
|
name: column.Field,
|
|
1513
1293
|
type: getBaseJSONType(column.Type),
|
|
1514
|
-
nullable: column.Null === "YES"
|
|
1294
|
+
nullable: column.Null === "YES",
|
|
1515
1295
|
};
|
|
1516
1296
|
}
|
|
1517
1297
|
async function getUniqueColumns(table, specialCaseUuidColumn) {
|
|
@@ -1523,7 +1303,7 @@ async function getUniqueColumns(table, specialCaseUuidColumn) {
|
|
|
1523
1303
|
.map((x) => ({
|
|
1524
1304
|
name: x.Field,
|
|
1525
1305
|
type: getBaseJSONType(x.Type),
|
|
1526
|
-
nullable: x.Null === "YES"
|
|
1306
|
+
nullable: x.Null === "YES",
|
|
1527
1307
|
}));
|
|
1528
1308
|
}
|
|
1529
1309
|
async function getUuidColumn(table) {
|
|
@@ -1535,7 +1315,7 @@ async function getUuidColumn(table) {
|
|
|
1535
1315
|
return {
|
|
1536
1316
|
name: column.Field,
|
|
1537
1317
|
type: column.Type,
|
|
1538
|
-
nullable: column.Null === "YES"
|
|
1318
|
+
nullable: column.Null === "YES",
|
|
1539
1319
|
};
|
|
1540
1320
|
}
|
|
1541
1321
|
const getTableMeta = _.memoize(async function getTableMeta(table) {
|
|
@@ -1579,20 +1359,12 @@ const getTableMeta = _.memoize(async function getTableMeta(table) {
|
|
|
1579
1359
|
? "UNI"
|
|
1580
1360
|
: "",
|
|
1581
1361
|
Null: x["IS_NULLABLE"],
|
|
1582
|
-
Default: x["COLUMN_DEFAULT"]
|
|
1362
|
+
Default: x["COLUMN_DEFAULT"],
|
|
1583
1363
|
};
|
|
1584
1364
|
})));
|
|
1585
1365
|
}
|
|
1586
1366
|
throw new Error("Unsupported dialect: " + dialect);
|
|
1587
1367
|
});
|
|
1588
|
-
function getShowCreateTable(table) {
|
|
1589
|
-
if (dialect === "mysql") {
|
|
1590
|
-
return query("SHOW CREATE TABLE ??", [table]).then((xs) => xs[0]["Create Table"]
|
|
1591
|
-
// https://github.com/bradzacher/mysqldump/blob/66839a57e572a07c046b0ba98753f30a7026cbd8/src/getSchemaDump.ts#L65
|
|
1592
|
-
.replace(/AUTO_INCREMENT\s*=\s*\d+ /g, ""));
|
|
1593
|
-
}
|
|
1594
|
-
return Promise.resolve(null);
|
|
1595
|
-
}
|
|
1596
1368
|
function getJSONSchemaObjProperties(tableMeta) {
|
|
1597
1369
|
return tableMeta.reduce((acc, m) => {
|
|
1598
1370
|
const baseType = getBaseJSONType(m.Type);
|
|
@@ -1606,7 +1378,7 @@ function getJSONSchemaObjProperties(tableMeta) {
|
|
|
1606
1378
|
_enum.push(null);
|
|
1607
1379
|
}
|
|
1608
1380
|
acc[m.Field] = {
|
|
1609
|
-
type: getJSONTypes(baseType, nullable)
|
|
1381
|
+
type: getJSONTypes(baseType, nullable),
|
|
1610
1382
|
// maxLength:
|
|
1611
1383
|
// baseType === "string" && format == null && isEnum == null
|
|
1612
1384
|
// ? getPropertyMaxLength(m.Type)
|
|
@@ -1716,7 +1488,9 @@ function getPropertyEnum(sqlType) {
|
|
|
1716
1488
|
return c;
|
|
1717
1489
|
}
|
|
1718
1490
|
function getPropertyFormat(sqlType) {
|
|
1719
|
-
if (sqlType === "datetime" ||
|
|
1491
|
+
if (sqlType === "datetime" ||
|
|
1492
|
+
sqlType === "datetime2" ||
|
|
1493
|
+
sqlType === "timestamp") {
|
|
1720
1494
|
// TODO: not sure this is correct for `timestamp`
|
|
1721
1495
|
return "date-time";
|
|
1722
1496
|
}
|
|
@@ -1740,7 +1514,7 @@ const mssqlTableExcludes = new Set([
|
|
|
1740
1514
|
"ddl_history",
|
|
1741
1515
|
"index_columns",
|
|
1742
1516
|
"lsn_time_mapping",
|
|
1743
|
-
"systranschemas"
|
|
1517
|
+
"systranschemas",
|
|
1744
1518
|
]);
|
|
1745
1519
|
async function getTableNames() {
|
|
1746
1520
|
if (dialect === "mysql") {
|
|
@@ -1754,295 +1528,3 @@ async function getTableNames() {
|
|
|
1754
1528
|
}
|
|
1755
1529
|
throw new Error("Unsupported dialect: " + dialect);
|
|
1756
1530
|
}
|
|
1757
|
-
function getMysql2sqliteSrc() {
|
|
1758
|
-
return `#!/usr/bin/awk -f
|
|
1759
|
-
|
|
1760
|
-
# Authors: @esperlu, @artemyk, @gkuenning, @dumblob
|
|
1761
|
-
|
|
1762
|
-
# FIXME detect empty input file and issue a warning
|
|
1763
|
-
|
|
1764
|
-
function printerr( s ){ print s | "cat >&2" }
|
|
1765
|
-
|
|
1766
|
-
BEGIN {
|
|
1767
|
-
if( ARGC != 2 ){
|
|
1768
|
-
printerr( \\
|
|
1769
|
-
"USAGE:\\n"\\
|
|
1770
|
-
" mysql2sqlite dump_mysql.sql > dump_sqlite3.sql\\n" \\
|
|
1771
|
-
" OR\\n" \\
|
|
1772
|
-
" mysql2sqlite dump_mysql.sql | sqlite3 sqlite.db\\n" \\
|
|
1773
|
-
"\\n" \\
|
|
1774
|
-
"NOTES:\\n" \\
|
|
1775
|
-
" Dash in filename is not supported, because dash (-) means stdin." )
|
|
1776
|
-
no_END = 1
|
|
1777
|
-
exit 1
|
|
1778
|
-
}
|
|
1779
|
-
|
|
1780
|
-
# Find INT_MAX supported by both this AWK (usually an ISO C signed int)
|
|
1781
|
-
# and SQlite.
|
|
1782
|
-
# On non-8bit-based architectures, the additional bits are safely ignored.
|
|
1783
|
-
|
|
1784
|
-
# 8bit (lower precision should not exist)
|
|
1785
|
-
s="127"
|
|
1786
|
-
# "63" + 0 avoids potential parser misbehavior
|
|
1787
|
-
if( (s + 0) "" == s ){ INT_MAX_HALF = "63" + 0 }
|
|
1788
|
-
# 16bit
|
|
1789
|
-
s="32767"
|
|
1790
|
-
if( (s + 0) "" == s ){ INT_MAX_HALF = "16383" + 0 }
|
|
1791
|
-
# 32bit
|
|
1792
|
-
s="2147483647"
|
|
1793
|
-
if( (s + 0) "" == s ){ INT_MAX_HALF = "1073741823" + 0 }
|
|
1794
|
-
# 64bit (as INTEGER in SQlite3)
|
|
1795
|
-
s="9223372036854775807"
|
|
1796
|
-
if( (s + 0) "" == s ){ INT_MAX_HALF = "4611686018427387904" + 0 }
|
|
1797
|
-
# # 128bit
|
|
1798
|
-
# s="170141183460469231731687303715884105728"
|
|
1799
|
-
# if( (s + 0) "" == s ){ INT_MAX_HALF = "85070591730234615865843651857942052864" + 0 }
|
|
1800
|
-
# # 256bit
|
|
1801
|
-
# s="57896044618658097711785492504343953926634992332820282019728792003956564819968"
|
|
1802
|
-
# if( (s + 0) "" == s ){ INT_MAX_HALF = "28948022309329048855892746252171976963317496166410141009864396001978282409984" + 0 }
|
|
1803
|
-
# # 512bit
|
|
1804
|
-
# s="6703903964971298549787012499102923063739682910296196688861780721860882015036773488400937149083451713845015929093243025426876941405973284973216824503042048"
|
|
1805
|
-
# if( (s + 0) "" == s ){ INT_MAX_HALF = "3351951982485649274893506249551461531869841455148098344430890360930441007518386744200468574541725856922507964546621512713438470702986642486608412251521024" + 0 }
|
|
1806
|
-
# # 1024bit
|
|
1807
|
-
# s="89884656743115795386465259539451236680898848947115328636715040578866337902750481566354238661203768010560056939935696678829394884407208311246423715319737062188883946712432742638151109800623047059726541476042502884419075341171231440736956555270413618581675255342293149119973622969239858152417678164812112068608"
|
|
1808
|
-
# if( (s + 0) "" == s ){ INT_MAX_HALF = "44942328371557897693232629769725618340449424473557664318357520289433168951375240783177119330601884005280028469967848339414697442203604155623211857659868531094441973356216371319075554900311523529863270738021251442209537670585615720368478277635206809290837627671146574559986811484619929076208839082406056034304" + 0 }
|
|
1809
|
-
# # higher precision probably not needed
|
|
1810
|
-
|
|
1811
|
-
FS=",$"
|
|
1812
|
-
print "PRAGMA synchronous = OFF;"
|
|
1813
|
-
print "PRAGMA journal_mode = MEMORY;"
|
|
1814
|
-
print "BEGIN TRANSACTION;"
|
|
1815
|
-
}
|
|
1816
|
-
|
|
1817
|
-
# historically 3 spaces separate non-argument local variables
|
|
1818
|
-
function bit_to_int( str_bit, powtwo, i, res, bit, overflow ){
|
|
1819
|
-
powtwo = 1
|
|
1820
|
-
overflow = 0
|
|
1821
|
-
# 011101 = 1*2^0 + 0*2^1 + 1*2^2 ...
|
|
1822
|
-
for( i = length( str_bit ); i > 0; --i ){
|
|
1823
|
-
bit = substr( str_bit, i, 1 )
|
|
1824
|
-
if( overflow || ( bit == 1 && res > INT_MAX_HALF ) ){
|
|
1825
|
-
printerr( \\
|
|
1826
|
-
NR ": WARN Bit field overflow, number truncated (LSBs saved, MSBs ignored)." )
|
|
1827
|
-
break
|
|
1828
|
-
}
|
|
1829
|
-
res = res + bit * powtwo
|
|
1830
|
-
# no warning here as it might be the last iteration
|
|
1831
|
-
if( powtwo > INT_MAX_HALF ){ overflow = 1; continue }
|
|
1832
|
-
powtwo = powtwo * 2
|
|
1833
|
-
}
|
|
1834
|
-
return res
|
|
1835
|
-
}
|
|
1836
|
-
|
|
1837
|
-
# CREATE TRIGGER statements have funny commenting. Remember we are in trigger.
|
|
1838
|
-
/^\\/\\*.*(CREATE.*TRIGGER|create.*trigger)/ {
|
|
1839
|
-
gsub( /^.*(TRIGGER|trigger)/, "CREATE TRIGGER" )
|
|
1840
|
-
print
|
|
1841
|
-
inTrigger = 1
|
|
1842
|
-
next
|
|
1843
|
-
}
|
|
1844
|
-
# The end of CREATE TRIGGER has a stray comment terminator
|
|
1845
|
-
/(END|end) \\*\\/;;/ { gsub( /\\*\\//, "" ); print; inTrigger = 0; next }
|
|
1846
|
-
# The rest of triggers just get passed through
|
|
1847
|
-
inTrigger != 0 { print; next }
|
|
1848
|
-
|
|
1849
|
-
# CREATE VIEW looks like a TABLE in comments
|
|
1850
|
-
/^\\/\\*.*(CREATE.*TABLE|create.*table)/ {
|
|
1851
|
-
inView = 1
|
|
1852
|
-
next
|
|
1853
|
-
}
|
|
1854
|
-
# end of CREATE VIEW
|
|
1855
|
-
/^(\\).*(ENGINE|engine).*\\*\\/;)/ {
|
|
1856
|
-
inView = 0
|
|
1857
|
-
next
|
|
1858
|
-
}
|
|
1859
|
-
# content of CREATE VIEW
|
|
1860
|
-
inView != 0 { next }
|
|
1861
|
-
|
|
1862
|
-
# skip comments
|
|
1863
|
-
/^\\/\\*/ { next }
|
|
1864
|
-
|
|
1865
|
-
# skip PARTITION statements
|
|
1866
|
-
/^ *[(]?(PARTITION|partition) +[^ ]+/ { next }
|
|
1867
|
-
|
|
1868
|
-
# print all INSERT lines
|
|
1869
|
-
( /^ *\\(/ && /\\) *[,;] *$/ ) || /^(INSERT|insert|REPLACE|replace)/ {
|
|
1870
|
-
prev = ""
|
|
1871
|
-
|
|
1872
|
-
# first replace \\\\ by \\_ that mysqldump never generates to deal with
|
|
1873
|
-
# sequnces like \\\\n that should be translated into \\n, not \\<LF>.
|
|
1874
|
-
# After we convert all escapes we replace \\_ by backslashes.
|
|
1875
|
-
gsub( /\\\\\\\\/, "\\\\_" )
|
|
1876
|
-
|
|
1877
|
-
# single quotes are escaped by another single quote
|
|
1878
|
-
gsub( /\\\\'/, "''" )
|
|
1879
|
-
gsub( /\\\\n/, "\\n" )
|
|
1880
|
-
gsub( /\\\\r/, "\\r" )
|
|
1881
|
-
gsub( /\\\\"/, "\\"" )
|
|
1882
|
-
gsub( /\\\\\\032/, "\\032" ) # substitute char
|
|
1883
|
-
|
|
1884
|
-
gsub( /\\\\_/, "\\\\" )
|
|
1885
|
-
|
|
1886
|
-
# sqlite3 is limited to 16 significant digits of precision
|
|
1887
|
-
while( match( $0, /0x[0-9a-fA-F]{17}/ ) ){
|
|
1888
|
-
hexIssue = 1
|
|
1889
|
-
sub( /0x[0-9a-fA-F]+/, substr( $0, RSTART, RLENGTH-1 ), $0 )
|
|
1890
|
-
}
|
|
1891
|
-
if( hexIssue ){
|
|
1892
|
-
printerr( \\
|
|
1893
|
-
NR ": WARN Hex number trimmed (length longer than 16 chars)." )
|
|
1894
|
-
hexIssue = 0
|
|
1895
|
-
}
|
|
1896
|
-
print
|
|
1897
|
-
next
|
|
1898
|
-
}
|
|
1899
|
-
|
|
1900
|
-
# CREATE DATABASE is not supported
|
|
1901
|
-
/^(CREATE DATABASE|create database)/ { next }
|
|
1902
|
-
|
|
1903
|
-
# print the CREATE line as is and capture the table name
|
|
1904
|
-
/^(CREATE|create)/ {
|
|
1905
|
-
if( $0 ~ /IF NOT EXISTS|if not exists/ || $0 ~ /TEMPORARY|temporary/ ){
|
|
1906
|
-
caseIssue = 1
|
|
1907
|
-
printerr( \\
|
|
1908
|
-
NR ": WARN Potential case sensitivity issues with table/column naming\\n" \\
|
|
1909
|
-
" (see INFO at the end)." )
|
|
1910
|
-
}
|
|
1911
|
-
if( match( $0, /\`[^\`]+/ ) ){
|
|
1912
|
-
tableName = substr( $0, RSTART+1, RLENGTH-1 )
|
|
1913
|
-
}
|
|
1914
|
-
aInc = 0
|
|
1915
|
-
prev = ""
|
|
1916
|
-
firstInTable = 1
|
|
1917
|
-
print
|
|
1918
|
-
next
|
|
1919
|
-
}
|
|
1920
|
-
|
|
1921
|
-
# Replace \`FULLTEXT KEY\` (probably other \`XXXXX KEY\`)
|
|
1922
|
-
/^ (FULLTEXT KEY|fulltext key)/ { gsub( /[A-Za-z ]+(KEY|key)/, " KEY" ) }
|
|
1923
|
-
|
|
1924
|
-
# Get rid of field lengths in KEY lines
|
|
1925
|
-
/ (PRIMARY |primary )?(KEY|key)/ { gsub( /\\([0-9]+\\)/, "" ) }
|
|
1926
|
-
|
|
1927
|
-
aInc == 1 && /PRIMARY KEY|primary key/ { next }
|
|
1928
|
-
|
|
1929
|
-
# Replace COLLATE xxx_xxxx_xx statements with COLLATE BINARY
|
|
1930
|
-
/ (COLLATE|collate) [a-z0-9_]*/ { gsub( /(COLLATE|collate) [a-z0-9_]*/, "COLLATE BINARY" ) }
|
|
1931
|
-
|
|
1932
|
-
# Print all fields definition lines except the \`KEY\` lines.
|
|
1933
|
-
/^ / && !/^( (KEY|key)|\\);)/ {
|
|
1934
|
-
if( match( $0, /[^"\`]AUTO_INCREMENT|auto_increment[^"\`]/) ){
|
|
1935
|
-
aInc = 1
|
|
1936
|
-
gsub( /AUTO_INCREMENT|auto_increment/, "PRIMARY KEY AUTOINCREMENT" )
|
|
1937
|
-
}
|
|
1938
|
-
gsub( /(UNIQUE KEY|unique key) (\`.*\`|".*") /, "UNIQUE " )
|
|
1939
|
-
gsub( /(CHARACTER SET|character set) [^ ]+[ ,]/, "" )
|
|
1940
|
-
# FIXME
|
|
1941
|
-
# CREATE TRIGGER [UpdateLastTime]
|
|
1942
|
-
# AFTER UPDATE
|
|
1943
|
-
# ON Package
|
|
1944
|
-
# FOR EACH ROW
|
|
1945
|
-
# BEGIN
|
|
1946
|
-
# UPDATE Package SET LastUpdate = CURRENT_TIMESTAMP WHERE ActionId = old.ActionId;
|
|
1947
|
-
# END
|
|
1948
|
-
gsub( /(ON|on) (UPDATE|update) (CURRENT_TIMESTAMP|current_timestamp)(\\(\\))?/, "" )
|
|
1949
|
-
gsub( /(DEFAULT|default) (CURRENT_TIMESTAMP|current_timestamp)(\\(\\))?/, "DEFAULT current_timestamp")
|
|
1950
|
-
gsub( /(COLLATE|collate) [^ ]+ /, "" )
|
|
1951
|
-
gsub( /(ENUM|enum)[^)]+\\)/, "text " )
|
|
1952
|
-
gsub( /(SET|set)\\([^)]+\\)/, "text " )
|
|
1953
|
-
gsub( /UNSIGNED|unsigned/, "" )
|
|
1954
|
-
gsub( /_utf8mb3/, "" )
|
|
1955
|
-
gsub( /\` [^ ]*(INT|int|BIT|bit)[^ ]*/, "\` integer" )
|
|
1956
|
-
gsub( /" [^ ]*(INT|int|BIT|bit)[^ ]*/, "\\" integer" )
|
|
1957
|
-
ere_bit_field = "[bB]'[10]+'"
|
|
1958
|
-
if( match($0, ere_bit_field) ){
|
|
1959
|
-
sub( ere_bit_field, bit_to_int( substr( $0, RSTART +2, RLENGTH -2 -1 ) ) )
|
|
1960
|
-
}
|
|
1961
|
-
|
|
1962
|
-
# remove USING BTREE and other suffixes for USING, for example: "UNIQUE KEY
|
|
1963
|
-
# \`hostname_domain\` (\`hostname\`,\`domain\`) USING BTREE,"
|
|
1964
|
-
gsub( / USING [^, ]+/, "" )
|
|
1965
|
-
|
|
1966
|
-
# field comments are not supported
|
|
1967
|
-
gsub( / (COMMENT|comment).+$/, "" )
|
|
1968
|
-
# Get commas off end of line
|
|
1969
|
-
gsub( /,.?$/, "" )
|
|
1970
|
-
if( prev ){
|
|
1971
|
-
if( firstInTable ){
|
|
1972
|
-
print prev
|
|
1973
|
-
firstInTable = 0
|
|
1974
|
-
}
|
|
1975
|
-
else {
|
|
1976
|
-
print "," prev
|
|
1977
|
-
}
|
|
1978
|
-
}
|
|
1979
|
-
else {
|
|
1980
|
-
# FIXME check if this is correct in all cases
|
|
1981
|
-
if( match( $1,
|
|
1982
|
-
/(CONSTRAINT|constraint) ["].*["] (FOREIGN KEY|foreign key)/ ) ){
|
|
1983
|
-
print ","
|
|
1984
|
-
}
|
|
1985
|
-
}
|
|
1986
|
-
prev = $1
|
|
1987
|
-
}
|
|
1988
|
-
|
|
1989
|
-
/ ENGINE| engine/ {
|
|
1990
|
-
if( prev ){
|
|
1991
|
-
if( firstInTable ){
|
|
1992
|
-
print prev
|
|
1993
|
-
firstInTable = 0
|
|
1994
|
-
}
|
|
1995
|
-
else {
|
|
1996
|
-
print "," prev
|
|
1997
|
-
}
|
|
1998
|
-
}
|
|
1999
|
-
prev=""
|
|
2000
|
-
print ");"
|
|
2001
|
-
next
|
|
2002
|
-
}
|
|
2003
|
-
# \`KEY\` lines are extracted from the \`CREATE\` block and stored in array for later print
|
|
2004
|
-
# in a separate \`CREATE KEY\` command. The index name is prefixed by the table name to
|
|
2005
|
-
# avoid a sqlite error for duplicate index name.
|
|
2006
|
-
/^( (KEY|key)|\\);)/ {
|
|
2007
|
-
if( prev ){
|
|
2008
|
-
if( firstInTable ){
|
|
2009
|
-
print prev
|
|
2010
|
-
firstInTable = 0
|
|
2011
|
-
}
|
|
2012
|
-
else {
|
|
2013
|
-
print "," prev
|
|
2014
|
-
}
|
|
2015
|
-
}
|
|
2016
|
-
prev = ""
|
|
2017
|
-
if( $0 == ");" ){
|
|
2018
|
-
print
|
|
2019
|
-
}
|
|
2020
|
-
else {
|
|
2021
|
-
if( match( $0, /\`[^\`]+/ ) ){
|
|
2022
|
-
indexName = substr( $0, RSTART+1, RLENGTH-1 )
|
|
2023
|
-
}
|
|
2024
|
-
if( match( $0, /\\([^()]+/ ) ){
|
|
2025
|
-
indexKey = substr( $0, RSTART+1, RLENGTH-1 )
|
|
2026
|
-
}
|
|
2027
|
-
# idx_ prefix to avoid name clashes (they really happen!)
|
|
2028
|
-
key[tableName] = key[tableName] "CREATE INDEX \\"idx_" \\
|
|
2029
|
-
tableName "_" indexName "\\" ON \\"" tableName "\\" (" indexKey ");\\n"
|
|
2030
|
-
}
|
|
2031
|
-
}
|
|
2032
|
-
|
|
2033
|
-
END {
|
|
2034
|
-
if( no_END ){ exit 1}
|
|
2035
|
-
# print all KEY creation lines.
|
|
2036
|
-
for( table in key ){ printf key[table] }
|
|
2037
|
-
|
|
2038
|
-
print "END TRANSACTION;"
|
|
2039
|
-
|
|
2040
|
-
if( caseIssue ){
|
|
2041
|
-
printerr( \\
|
|
2042
|
-
"INFO Pure sqlite identifiers are case insensitive (even if quoted\\n" \\
|
|
2043
|
-
" or if ASCII) and doesnt cross-check TABLE and TEMPORARY TABLE\\n" \\
|
|
2044
|
-
" identifiers. Thus expect errors like \\"table T has no column named F\\".")
|
|
2045
|
-
}
|
|
2046
|
-
}
|
|
2047
|
-
`;
|
|
2048
|
-
}
|