@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.
Files changed (34) hide show
  1. package/dist/generation/generate.d.ts +0 -1
  2. package/dist/generation/generate.js +309 -917
  3. package/dist/ksql.d.ts +15 -0
  4. package/dist/ksql.js +55 -0
  5. package/dist/runtime/Cache.js +3 -6
  6. package/dist/runtime/IRuntime.d.ts +17 -46
  7. package/dist/runtime/RuntimeKSQL.d.ts +19 -0
  8. package/dist/runtime/RuntimeKSQL.js +446 -0
  9. package/dist/runtime/RuntimeMSSQL.d.ts +1 -7
  10. package/dist/runtime/RuntimeMSSQL.js +4 -4
  11. package/dist/runtime/RuntimeMySQL.d.ts +1 -3
  12. package/dist/runtime/RuntimeMySQL.js +7 -33
  13. package/dist/runtime/lib/MSSQL.d.ts +1 -2
  14. package/dist/runtime/lib/MSSQL.js +8 -36
  15. package/dist/runtime/lib/MySQL.d.ts +1 -1
  16. package/dist/runtime/lib/MySQL.js +2 -15
  17. package/dist/runtime/lib/getSqlAst.js +121 -158
  18. package/dist/runtime/lib/runTransforms.d.ts +2 -0
  19. package/dist/runtime/lib/runTransforms.js +36 -0
  20. package/dist/runtime/lib/shared.d.ts +2 -1
  21. package/dist/runtime/lib/shared.js +71 -180
  22. package/dist/runtime/lib/stringifyWhere.js +12 -39
  23. package/dist/runtime/lib/typeCastMSSQL.js +1 -24
  24. package/dist/traverseFieldArgs.d.ts +2 -2
  25. package/dist/traverseFieldArgs.js +3 -8
  26. package/package.json +4 -1
  27. package/dist/runtime/RuntimeSQLite.d.ts +0 -38
  28. package/dist/runtime/RuntimeSQLite.js +0 -135
  29. package/dist/runtime/lib/addNullFallbacks.test.d.ts +0 -1
  30. package/dist/runtime/lib/addNullFallbacks.test.js +0 -206
  31. package/dist/runtime/lib/stringifyWhere.test.d.ts +0 -1
  32. package/dist/runtime/lib/stringifyWhere.test.js +0 -236
  33. package/dist/traverseFieldArgs.test.d.ts +0 -1
  34. 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 = __importStar(require("node:path"));
31
- const fs = __importStar(require("node:fs"));
32
- const os = __importStar(require("node:os"));
33
- const child_process = __importStar(require("node:child_process"));
34
- const node_crypto_1 = __importDefault(require("node:crypto"));
35
- const prettier = __importStar(require("prettier"));
36
- const changeCase = __importStar(require("change-case"));
37
- const fse = __importStar(require("fs-extra"));
38
- const _ = __importStar(require("lodash/fp"));
39
- const mssql = __importStar(require("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 = __importStar(require("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 artifacts = await getArtifacts(tables, includeMappedFields, specialCaseUuidColumn);
90
- const artifactsSource = getArtifactsSource(artifacts);
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, "IRuntime.d.ts"), fs.existsSync(path.join(__dirname, "../runtime", "IRuntime.d.ts"))
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, artifacts) {
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
- let otherOpts = opts.otherOpts ?? {};
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
- const findOnes = await getFindOnes(x, specialCaseUuidColumn);
351
- return getMethodSourceGetOne(x, findOnes, false);
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 getMethodSourceGetList(x, false);
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 getMethodSourceGetListPaginated(x, false);
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 getMethodSourcePostOne(x, specialCaseUuidColumn, false);
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
- const findOnes = await getFindOnes(x, specialCaseUuidColumn);
364
- return getMethodSourcePatchOne(x, findOnes, false);
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 getMethodSourcePatchList(x, false);
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
- const findOnes = await getFindOnes(x, specialCaseUuidColumn);
371
- return getMethodSourceDeleteOne(x, findOnes, false);
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 getMethodSourceDeleteList(x, false);
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 && mappedFields != null && mappedFields.length > 0) {
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 ? true : x !== uuidColumn.name)
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: "object",
1226
- additionalProperties: false,
1227
- properties
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.filter((x) => x.table !== table).map((x) => getTypeFieldsName(x.table)));
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(artifacts) {
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 [tableMeta, primaryKey, dumpSchema] = await Promise.all([
1300
- getTableMeta(table),
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 ? await getMappedFields(table) : [];
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
- return artifacts;
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" || sqlType === "datetime2" || sqlType === "timestamp") {
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
- }