@technicity/data-service-generator 0.13.26 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -43,8 +43,6 @@ const json_schema_to_typescript_1 = require("json-schema-to-typescript");
43
43
  const getDuplicates_1 = require("../lib/getDuplicates");
44
44
  const isNotNullOrUndefined_1 = require("../lib/isNotNullOrUndefined");
45
45
  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
46
  // json-schema-to-typescript inlines everything. We don't want that,
49
47
  // so use `tsType`, and add imports manually.
50
48
  // https://github.com/bcherny/json-schema-to-typescript#custom-schema-properties
@@ -55,6 +53,7 @@ let dialect = "mysql";
55
53
  const json2TsOpts = {
56
54
  bannerComment: ""
57
55
  };
56
+ const keyFields = "$fields";
58
57
  async function generate(input) {
59
58
  if (input.tables != null && input.excludeTables != null) {
60
59
  throw new Error("Must specify either `tables` or `excludeTables`, not both");
@@ -89,7 +88,7 @@ async function generate(input) {
89
88
  ]));
90
89
  const artifacts = await getArtifacts(tables, includeMappedFields, specialCaseUuidColumn);
91
90
  const artifactsSource = getArtifactsSource(artifacts);
92
- const sdkSource = await getSDKSource(data, specialCaseUuidColumn, supplementClientOpts);
91
+ const sdkSource = await getSDKSource(data, specialCaseUuidColumn, supplementClientOpts, artifacts);
93
92
  const sdkFilename = "index.ts";
94
93
  const sourceIRuntimeFilePath = fs.existsSync(path.join(__dirname, "../runtime", "IRuntime.ts"))
95
94
  ? path.join(__dirname, "../runtime", "IRuntime.ts")
@@ -215,7 +214,7 @@ function init(input) {
215
214
  });
216
215
  query = mysql.query.bind(mysql);
217
216
  }
218
- if (dialect === "mssql" || dialect === "ksql") {
217
+ if (dialect === "mssql") {
219
218
  const pool = new mssql.ConnectionPool({
220
219
  server: server ?? "localhost",
221
220
  user,
@@ -236,7 +235,7 @@ function init(input) {
236
235
  }
237
236
  // It's a bit awkward to put __whereNeedsProcessing, __prepareWhere on the class,
238
237
  // but it allows us to share the same database pool, clientOpts, etc.
239
- async function getSDKSource(input, specialCaseUuidColumn, supplementClientOpts) {
238
+ async function getSDKSource(input, specialCaseUuidColumn, supplementClientOpts, artifacts) {
240
239
  function getTypeImports() {
241
240
  let set = new Set();
242
241
  for (let d of input) {
@@ -377,6 +376,88 @@ async function getSDKSource(input, specialCaseUuidColumn, supplementClientOpts)
377
376
  }))).join("\n\n")}
378
377
  }
379
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;
380
461
  `;
381
462
  return prettier.format(src, { parser: "typescript" });
382
463
  }
@@ -394,18 +475,19 @@ async function getFindOnes(x, specialCaseUuidColumn) {
394
475
  return findOnes;
395
476
  }
396
477
  function getMethodSourceGetOne(x, findOnes, isTransaction) {
397
- return `async ${x.methodName}(
478
+ const param2 = `{ ${keyFields}?: ${x.typeFieldsName}, correlationId?: string, skipCache?: boolean, context?: TContext }`;
479
+ return `async ${x.methodName}<T extends ${param2}>(
398
480
  param1: ${findOnes
399
481
  .map((findOne) => `{ ${findOne.name}: ${findOne.type}${findOne.nullable ? " | null" : ""} }`)
400
482
  .join(" | ")},
401
- param2?: { fields?: ${x.typeFieldsName}, correlationId?: string, skipCache?: boolean, context?: TContext }
402
- ): Promise<${x.typeReturnBaseName}> {
483
+ param2?: SelectSubset<T, ${param2}>
484
+ ): Promise<CheckSelect<T, ${getTypeReturnName(x.table)}, ${getTypeGetPayloadName(x.table)}<T>>> {
403
485
  return ${isTransaction ? "runtime" : "this.runtime"}.resolve(
404
486
  {
405
487
  resource: "${x.table}",
406
488
  action: "${mapKindToAction(x.kind)}",
407
489
  args: { $where: param1 },
408
- fields: param2?.fields,
490
+ fields: param2?.$fields as any,
409
491
  artifacts,
410
492
  context: param2?.context,
411
493
  skipCache: param2?.skipCache,
@@ -415,16 +497,17 @@ function getMethodSourceGetOne(x, findOnes, isTransaction) {
415
497
  }`;
416
498
  }
417
499
  function getMethodSourceGetList(x, isTransaction) {
418
- return `async ${x.methodName}(
500
+ const param2 = `{ ${keyFields}?: ${x.typeFieldsName}, correlationId?: string, skipCache?: boolean, context?: TContext }`;
501
+ return `async ${x.methodName}<T extends ${param2}>(
419
502
  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}>> {
503
+ param2?: SelectSubset<T, ${param2}>
504
+ ): Promise<Array<CheckSelect<T, ${getTypeReturnName(x.table)}, ${getTypeGetPayloadName(x.table)}<T>>>> {
422
505
  return ${isTransaction ? "runtime" : "this.runtime"}.resolve(
423
506
  {
424
507
  resource: "${x.table}",
425
508
  action: "${mapKindToAction(x.kind)}",
426
509
  args: param1,
427
- fields: param2?.fields,
510
+ fields: param2?.$fields as any,
428
511
  artifacts,
429
512
  context: param2?.context,
430
513
  skipCache: param2?.skipCache,
@@ -434,16 +517,17 @@ function getMethodSourceGetList(x, isTransaction) {
434
517
  }`;
435
518
  }
436
519
  function getMethodSourceGetListPaginated(x, isTransaction) {
437
- return `async ${x.methodName}(
520
+ const param2 = `{ ${keyFields}?: ${x.typeFieldsName}, correlationId?: string, skipCache?: boolean, context?: TContext }`;
521
+ return `async ${x.methodName}<T extends ${param2}>(
438
522
  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}>> {
523
+ param2?: SelectSubset<T, ${param2}>
524
+ ): Promise<ListPaginated<CheckSelect<T, ${getTypeReturnName(x.table)}, ${getTypeGetPayloadName(x.table)}<T>>>> {
441
525
  return ${isTransaction ? "runtime" : "this.runtime"}.resolve(
442
526
  {
443
527
  resource: "${x.table}",
444
528
  action: "${mapKindToAction(x.kind)}",
445
529
  args: param1,
446
- fields: param2?.fields,
530
+ fields: param2?.$fields as any,
447
531
  artifacts,
448
532
  context: param2?.context,
449
533
  skipCache: param2?.skipCache,
@@ -453,54 +537,57 @@ function getMethodSourceGetListPaginated(x, isTransaction) {
453
537
  }`;
454
538
  }
455
539
  function getMethodSourcePostOne(x, specialCaseUuidColumn, isTransaction) {
456
- return `async ${x.methodName}(
540
+ const param2 = `{ ${keyFields}?: ${x.typeFieldsName}, correlationId?: string, context?: TContext }`;
541
+ return `async ${x.methodName}<T extends ${param2}>(
457
542
  data: ${x.typeDataName},
458
- param2?: { fields?: ${x.typeFieldsName}, correlationId?: string, context?: TContext }
459
- ): Promise<${x.typeReturnBaseName}> {
543
+ param2?: SelectSubset<T, ${param2}>
544
+ ): Promise<CheckSelect<T, ${getTypeReturnName(x.table)}, ${getTypeGetPayloadName(x.table)}<T>>> {
460
545
  return ${isTransaction ? "runtime" : "this.runtime"}.resolve({
461
546
  resource: "${x.table}",
462
547
  action: "${mapKindToAction(x.kind)}",
463
548
  data,
464
549
  artifacts,
465
- fields: param2?.fields,
550
+ fields: param2?.$fields as any,
466
551
  context: {...param2?.context, specialCaseUuidColumn: ${JSON.stringify(specialCaseUuidColumn)}},
467
552
  ${isTransaction ? "dbCall" : ""}
468
553
  });
469
554
  }`;
470
555
  }
471
556
  function getMethodSourcePatchOne(x, findOnes, isTransaction) {
472
- return `async ${x.methodName}(
557
+ const param2 = `{ ${keyFields}?: ${x.typeFieldsName}, correlationId?: string, context?: TContext }`;
558
+ return `async ${x.methodName}<T extends ${param2}>(
473
559
  param1: ${findOnes
474
560
  .map((findOne) => `{ ${findOne.name}: ${findOne.type}${findOne.nullable ? " | null" : ""} }`)
475
561
  .join(" | ")},
476
562
  data: ${x.typeDataName},
477
- param2?: { fields?: ${x.typeFieldsName}, correlationId?: string, context?: TContext }
478
- ): Promise<${x.typeReturnBaseName}> {
563
+ param2?: SelectSubset<T, ${param2}>
564
+ ): Promise<CheckSelect<T, ${getTypeReturnName(x.table)}, ${getTypeGetPayloadName(x.table)}<T>>> {
479
565
  return ${isTransaction ? "runtime" : "this.runtime"}.resolve({
480
566
  resource: "${x.table}",
481
567
  action: "${mapKindToAction(x.kind)}",
482
568
  args: { $where: param1 },
483
569
  data,
484
570
  artifacts,
485
- fields: param2?.fields,
571
+ fields: param2?.$fields as any,
486
572
  context: param2?.context,
487
573
  ${isTransaction ? "dbCall" : ""}
488
574
  });
489
575
  }`;
490
576
  }
491
577
  function getMethodSourcePatchList(x, isTransaction) {
492
- return `async ${x.methodName}(
493
- param1: { $where?: ${x.typeWhereName} },
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} },
494
581
  data: ${x.typeDataName},
495
- param2?: { fields?: ${x.typeFieldsName}, correlationId?: string, context?: TContext }
496
- ): Promise<Array<${x.typeReturnBaseName}>> {
582
+ param2?: SelectSubset<T, ${param2}>
583
+ ): Promise<Array<CheckSelect<T, ${getTypeReturnName(x.table)}, ${getTypeGetPayloadName(x.table)}<T>>>> {
497
584
  return ${isTransaction ? "runtime" : "this.runtime"}.resolve({
498
585
  resource: "${x.table}",
499
586
  action: "${mapKindToAction(x.kind)}",
500
587
  args: param1,
501
588
  data,
502
589
  artifacts,
503
- fields: param2?.fields,
590
+ fields: param2?.$fields as any,
504
591
  context: param2?.context,
505
592
  ${isTransaction ? "dbCall" : ""}
506
593
  });
@@ -565,6 +652,12 @@ function mapKindToAction(kind) {
565
652
  }
566
653
  throw new Error(`Unhandled kind: ${kind}`);
567
654
  }
655
+ function getTypeGetPayloadName(table) {
656
+ return "GetPayload" + changeCase.pascalCase(table);
657
+ }
658
+ function getTypeReturnName(table) {
659
+ return changeCase.pascalCase(table);
660
+ }
568
661
  function getTypeReturnBaseName(table) {
569
662
  return "ReturnBase" + changeCase.pascalCase(table);
570
663
  }
@@ -660,6 +753,7 @@ async function getPatchListData(table) {
660
753
  const typeReturnBaseName = getTypeReturnBaseName(table);
661
754
  const typeWhereName = getTypeWhereName(table);
662
755
  const typeDataName = "DataPatch" + changeCase.pascalCase(table);
756
+ const typeOrderByName = getTypeOrderByName(table);
663
757
  return {
664
758
  kind: "patchList",
665
759
  table,
@@ -667,7 +761,8 @@ async function getPatchListData(table) {
667
761
  typeFieldsName,
668
762
  typeReturnBaseName,
669
763
  typeWhereName,
670
- typeDataName
764
+ typeDataName,
765
+ typeOrderByName
671
766
  };
672
767
  }
673
768
  function getDeleteOneData(table) {
@@ -1071,8 +1166,8 @@ export type ListPaginated<T> = {
1071
1166
  paginationInfo: {
1072
1167
  hasPreviousPage?: boolean,
1073
1168
  hasNextPage?: boolean,
1074
- startCursor?: string | number,
1075
- endCursor?: string | number,
1169
+ startCursor?: string,
1170
+ endCursor?: string,
1076
1171
  totalCount: number,
1077
1172
  },
1078
1173
  results: Array<T>,
@@ -1090,53 +1185,46 @@ async function getTypeFields(table, name, includeMappedFields) {
1090
1185
  const mappedFields = includeMappedFields ? await getMappedFields(table) : [];
1091
1186
  const keyWhere = "$where";
1092
1187
  const keyOrderBy = "$orderBy";
1093
- const jsonSchemaFields = {
1094
- type: "array",
1095
- items: {
1096
- anyOf: [
1097
- {
1098
- enum: scalarKeys.concat(mappedFields.map((x) => x.as))
1099
- },
1100
- ...relations.map((x) => {
1101
- const argsProperties = x.type === "many-to-many"
1102
- ? {
1103
- [keyWhere]: {
1104
- type: "object",
1105
- properties: {
1106
- [x.table]: { tsType: getTypeWhereName(x.table) },
1107
- [x.junctionTable]: {
1108
- tsType: getTypeWhereName(x.junctionTable)
1109
- }
1110
- },
1111
- additionalProperties: false
1112
- }
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)
1113
1204
  }
1114
- : { [keyWhere]: { tsType: getTypeWhereName(x.table) } };
1115
- // $orderBy only makes sense for a list
1116
- if (x.grabMany) {
1117
- argsProperties[keyOrderBy] = {
1118
- tsType: getTypeOrderByName(x.table)
1119
- };
1120
- }
1121
- return {
1122
- type: "object",
1123
- properties: {
1124
- name: { enum: [x.name] },
1125
- as: { type: "string" },
1126
- fields: { tsType: getTypeFieldsName(x.table) },
1127
- args: {
1128
- type: "object",
1129
- properties: argsProperties,
1130
- additionalProperties: false
1131
- },
1132
- transform: { tsType: `(x: any) => any` }
1133
- },
1134
- additionalProperties: false,
1135
- required: ["name", "fields"]
1136
- };
1137
- })
1138
- ]
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
+ };
1139
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
+ const jsonSchemaFields = {
1225
+ type: "object",
1226
+ additionalProperties: false,
1227
+ properties
1140
1228
  };
1141
1229
  let type = await (0, json_schema_to_typescript_1.compile)(jsonSchemaFields, name, json2TsOpts);
1142
1230
  const fieldImports = _.uniq(relations.filter((x) => x.table !== table).map((x) => getTypeFieldsName(x.table)));
@@ -1285,7 +1373,8 @@ async function getArtifacts(tables, includeMappedFields, specialCaseUuidColumn)
1285
1373
  name: x.as,
1286
1374
  nullable: x.nullable,
1287
1375
  // TODO
1288
- hasDefaultValue: false
1376
+ hasDefaultValue: false,
1377
+ mapped: true
1289
1378
  });
1290
1379
  }
1291
1380
  for (let x of relationInfo) {
@@ -1293,7 +1382,8 @@ async function getArtifacts(tables, includeMappedFields, specialCaseUuidColumn)
1293
1382
  kind: "object",
1294
1383
  type: x.table,
1295
1384
  name: x.name,
1296
- isList: x.grabMany
1385
+ isList: x.grabMany,
1386
+ nullable: x.type === "one-to-many__many-to-one" ? x.nullable : false
1297
1387
  });
1298
1388
  }
1299
1389
  return {
@@ -1542,7 +1632,7 @@ const getTableMeta = _.memoize(async function getTableMeta(table) {
1542
1632
  if (dialect === "mysql") {
1543
1633
  return query("DESCRIBE ??", [table]).then((xs) => _.sortBy((x) => x.Field, xs));
1544
1634
  }
1545
- if (dialect === "mssql" || dialect === "ksql") {
1635
+ if (dialect === "mssql") {
1546
1636
  const primaryColumn = await query(`SELECT columns.name as COLUMN_NAME
1547
1637
  FROM sys.tables tables
1548
1638
  JOIN sys.columns columns
@@ -1746,7 +1836,7 @@ async function getTableNames() {
1746
1836
  if (dialect === "mysql") {
1747
1837
  return query("SHOW TABLES").then((xs) => xs.flatMap((x) => Object.values(x)).sort());
1748
1838
  }
1749
- if (dialect === "mssql" || dialect === "ksql") {
1839
+ if (dialect === "mssql") {
1750
1840
  return query("SELECT * FROM INFORMATION_SCHEMA.TABLES").then((xs) => xs
1751
1841
  .map((x) => x["TABLE_NAME"])
1752
1842
  .filter((x) => !x.startsWith("dbo_") && !mssqlTableExcludes.has(x))
@@ -13,11 +13,11 @@ export declare type TAction = "findUnique" | "findMany" | "findManyPaginated" |
13
13
  export declare type TResolveParams = {
14
14
  resource: string;
15
15
  action: TAction;
16
- args?: IArgs | undefined;
16
+ args?: IArgs;
17
17
  data?: any;
18
18
  artifacts: IArtifacts;
19
- fields?: IField[] | undefined;
20
- context?: TContext | undefined;
19
+ fields?: TSelect;
20
+ context?: TContext;
21
21
  skipCache?: boolean;
22
22
  dbCall?: TDbCall;
23
23
  };
@@ -25,7 +25,7 @@ export declare type TContext = {
25
25
  [k: string]: any;
26
26
  };
27
27
  export declare type TMiddleware = (params: TResolveParams, next: (params: TResolveParams) => Promise<any>) => Promise<any>;
28
- export declare type IDialect = "mysql" | "mssql" | "ksql" | "sqlite";
28
+ export declare type IDialect = "mysql" | "mssql" | "sqlite";
29
29
  export declare type TDbCall = (q: string) => Promise<any>;
30
30
  export declare type TFormatQuery = (q: string, values: any[]) => string;
31
31
  export declare type TBeginTransaction = () => Promise<TBeginTransactionResult>;
@@ -42,12 +42,10 @@ export declare type IOrderBy = {
42
42
  export declare type IArgs = {
43
43
  [k: string]: any;
44
44
  };
45
- export declare type IField = string | {
46
- name: string;
47
- as?: string;
48
- fields: IField[];
49
- args?: IArgs;
50
- transform?: (record: any) => any;
45
+ export declare type TSelect = {
46
+ [k: string]: boolean | {
47
+ $fields?: TSelect;
48
+ };
51
49
  };
52
50
  declare type IWhere = (table: string, args: IArgs) => string | undefined;
53
51
  declare type IASTChildColumn = {
@@ -55,14 +53,14 @@ declare type IASTChildColumn = {
55
53
  name: string;
56
54
  fieldName: string;
57
55
  as: string;
58
- fromOtherTable?: string | undefined;
56
+ fromOtherTable?: string;
59
57
  };
60
58
  declare type IASTChildComposite = {
61
59
  type: "composite";
62
60
  name: string[];
63
61
  fieldName: string;
64
62
  as: string;
65
- fromOtherTable?: string | undefined;
63
+ fromOtherTable?: string;
66
64
  };
67
65
  declare type ISqlJoin = (t1: string, t2: string, args: IArgs) => string;
68
66
  declare type ISqlBatch = {
@@ -88,7 +86,7 @@ declare type IJunction = {
88
86
  export declare type IGetSQLASTInput = {
89
87
  table: string;
90
88
  fieldName: string;
91
- fields: IField[];
89
+ fields: TSelect;
92
90
  args?: IArgs;
93
91
  where?: IWhere;
94
92
  sqlJoin?: ISqlJoin;
@@ -96,7 +94,7 @@ export declare type IGetSQLASTInput = {
96
94
  junction?: IJunction;
97
95
  grabMany: boolean;
98
96
  getWhere: (table: string, args: any, dialect: IDialect, orderBy?: IOrderBy | undefined, rowWithMatchingCursor?: any) => string | null;
99
- orderBy?: IOrderBy | undefined;
97
+ orderBy?: IOrderBy;
100
98
  rowWithMatchingCursor?: any;
101
99
  artifacts: IArtifacts;
102
100
  dialect: IDialect;
@@ -173,6 +171,7 @@ export declare type TField = {
173
171
  name: string;
174
172
  nullable: boolean;
175
173
  hasDefaultValue: boolean;
174
+ mapped?: true;
176
175
  } | {
177
176
  kind: "enum";
178
177
  values: unknown[];
@@ -183,5 +182,6 @@ export declare type TField = {
183
182
  type: string;
184
183
  name: string;
185
184
  isList: boolean;
185
+ nullable: boolean;
186
186
  };
187
187
  export {};