@technicity/data-service-generator 0.14.5 → 0.15.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,6 +43,7 @@ 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 capitalizeFirstLetter_1 = require("../lib/capitalizeFirstLetter");
46
47
  // json-schema-to-typescript inlines everything. We don't want that,
47
48
  // so use `tsType`, and add imports manually.
48
49
  // https://github.com/bcherny/json-schema-to-typescript#custom-schema-properties
@@ -256,13 +257,18 @@ async function getSDKSource(input, specialCaseUuidColumn, supplementClientOpts,
256
257
  .concat(Array.from(set).sort())
257
258
  .join(",\n")} } from "./types";`;
258
259
  }
259
- const src = `import type { IRuntime, TMiddleware, TContext } from "./IRuntime"
260
+ const src = `import { AsyncLocalStorage } from "node:async_hooks";
261
+ import type { IRuntime, TMiddleware, TContext, TOnHandler, EventOnHandlerError } from "./IRuntime"
260
262
  import { artifacts } from "./artifacts";
261
263
 
262
264
  ${getTypeImports()}
263
265
 
266
+ const asyncLocalStorage = new AsyncLocalStorage<{ isInOnHandler: boolean }>();
267
+
264
268
  export class SDK {
265
269
  runtime: IRuntime;
270
+ onHandlerMap: Map<string, TOnHandler>;
271
+ eventTarget: EventTarget;
266
272
 
267
273
  constructor(opts: {
268
274
  runtime: any;
@@ -276,6 +282,8 @@ async function getSDKSource(input, specialCaseUuidColumn, supplementClientOpts,
276
282
  this.runtime = new opts.runtime(opts.clientOpts, ${supplementClientOpts === true
277
283
  ? "{ supplementClientOpts: true, ...otherOpts }"
278
284
  : "otherOpts"}, artifacts);
285
+ this.onHandlerMap = new Map();
286
+ this.eventTarget = new EventTarget();
279
287
  }
280
288
 
281
289
  $use(middleware: TMiddleware) {
@@ -310,6 +318,8 @@ async function getSDKSource(input, specialCaseUuidColumn, supplementClientOpts,
310
318
  }) {
311
319
  const { dbCall, commit, rollback } = await this.runtime.$startTransaction(input);
312
320
  const runtime = this.runtime;
321
+ const eventTarget = this.eventTarget;
322
+ const onHandlerMap = this.onHandlerMap;
313
323
  return {
314
324
  $commit: commit,
315
325
  $rollback: rollback,
@@ -345,6 +355,10 @@ async function getSDKSource(input, specialCaseUuidColumn, supplementClientOpts,
345
355
  }
346
356
  }
347
357
 
358
+ onOnHandlerError(cb: (event: EventOnHandlerError<unknown>) => void) {
359
+ this.eventTarget.addEventListener("error", cb);
360
+ }
361
+
348
362
  ${(await Promise.all(input.flatMap(async (x) => {
349
363
  if (x.kind === "getOne") {
350
364
  const findOnes = await getFindOnes(x, specialCaseUuidColumn);
@@ -374,6 +388,15 @@ async function getSDKSource(input, specialCaseUuidColumn, supplementClientOpts,
374
388
  return getMethodSourceDeleteList(x, false);
375
389
  }
376
390
  }))).join("\n\n")}
391
+
392
+ ${(await Promise.all(input.flatMap(async (x) => {
393
+ if (x.kind === "patchOne") {
394
+ const findOnes = await getFindOnes(x, specialCaseUuidColumn);
395
+ return getMethodSourceOnHandlerPatchOne(x, findOnes);
396
+ }
397
+ })))
398
+ .filter(Boolean)
399
+ .join("\n\n")}
377
400
  }
378
401
 
379
402
  ${await Promise.all(Object.entries(artifacts).map(async ([table, tableArtifacts]) => {
@@ -490,6 +513,7 @@ function getMethodSourceGetOne(x, findOnes, isTransaction) {
490
513
  artifacts,
491
514
  context: param2?.context,
492
515
  skipCache: param2?.skipCache,
516
+ eventTarget: ${isTransaction ? "eventTarget" : "this.eventTarget"},
493
517
  ${isTransaction ? "dbCall" : ""}
494
518
  }
495
519
  );
@@ -510,6 +534,7 @@ function getMethodSourceGetList(x, isTransaction) {
510
534
  artifacts,
511
535
  context: param2?.context,
512
536
  skipCache: param2?.skipCache,
537
+ eventTarget: ${isTransaction ? "eventTarget" : "this.eventTarget"},
513
538
  ${isTransaction ? "dbCall" : ""}
514
539
  }
515
540
  );
@@ -530,6 +555,7 @@ function getMethodSourceGetListPaginated(x, isTransaction) {
530
555
  artifacts,
531
556
  context: param2?.context,
532
557
  skipCache: param2?.skipCache,
558
+ eventTarget: ${isTransaction ? "eventTarget" : "this.eventTarget"},
533
559
  ${isTransaction ? "dbCall" : ""}
534
560
  }
535
561
  );
@@ -548,6 +574,10 @@ function getMethodSourcePostOne(x, specialCaseUuidColumn, isTransaction) {
548
574
  artifacts,
549
575
  fields: param2?.$fields as any,
550
576
  context: {...param2?.context, specialCaseUuidColumn: ${JSON.stringify(specialCaseUuidColumn)}},
577
+ eventTarget: ${isTransaction ? "eventTarget" : "this.eventTarget"},
578
+ onHandler: ${isTransaction ? "onHandlerMap" : "this.onHandlerMap"}.get("${mapKindToAction(x.kind)}-${x.table}"),
579
+ asyncLocalStorage,
580
+ sdk: this,
551
581
  ${isTransaction ? "dbCall" : ""}
552
582
  });
553
583
  }`;
@@ -569,10 +599,25 @@ return ${isTransaction ? "runtime" : "this.runtime"}.resolve({
569
599
  artifacts,
570
600
  fields: param2?.$fields as any,
571
601
  context: param2?.context,
602
+ eventTarget: ${isTransaction ? "eventTarget" : "this.eventTarget"},
603
+ onHandler: ${isTransaction ? "onHandlerMap" : "this.onHandlerMap"}.get("${mapKindToAction(x.kind)}-${x.table}"),
604
+ asyncLocalStorage,
605
+ sdk: this,
572
606
  ${isTransaction ? "dbCall" : ""}
573
607
  });
574
608
  }`;
575
609
  }
610
+ function getMethodSourceOnHandlerPatchOne(x, findOnes) {
611
+ return `on${(0, capitalizeFirstLetter_1.capitalizeFirstLetter)(x.methodName)}(handler:
612
+ (sdk: InstanceType<typeof SDK>, input: { $where: ${findOnes
613
+ .map((findOne) => `{ ${findOne.name}: ${findOne.type}${findOne.nullable ? " | null" : ""} }`)
614
+ .join(" | ")}, data: ${x.typeDataName} },
615
+ output: Partial<${getTypeReturnName(x.table)}>
616
+ ) => Promise<void>
617
+ ): void {
618
+ this.onHandlerMap.set("${mapKindToAction(x.kind)}-${x.table}", handler);
619
+ }`;
620
+ }
576
621
  function getMethodSourcePatchList(x, isTransaction) {
577
622
  const param2 = `{ ${keyFields}?: ${x.typeFieldsName}, correlationId?: string, context?: TContext }`;
578
623
  return `async ${x.methodName}<T extends ${param2}>(
@@ -588,6 +633,10 @@ function getMethodSourcePatchList(x, isTransaction) {
588
633
  artifacts,
589
634
  fields: param2?.$fields as any,
590
635
  context: param2?.context,
636
+ eventTarget: ${isTransaction ? "eventTarget" : "this.eventTarget"},
637
+ onHandler: ${isTransaction ? "onHandlerMap" : "this.onHandlerMap"}.get("${mapKindToAction(x.kind)}-${x.table}"),
638
+ asyncLocalStorage,
639
+ sdk: this,
591
640
  ${isTransaction ? "dbCall" : ""}
592
641
  });
593
642
  }`;
@@ -605,6 +654,10 @@ function getMethodSourceDeleteOne(x, findOnes, isTransaction) {
605
654
  args: { $where: param1 },
606
655
  artifacts,
607
656
  context: param2?.context,
657
+ eventTarget: ${isTransaction ? "eventTarget" : "this.eventTarget"},
658
+ onHandler: ${isTransaction ? "onHandlerMap" : "this.onHandlerMap"}.get("${mapKindToAction(x.kind)}-${x.table}"),
659
+ asyncLocalStorage,
660
+ sdk: this,
608
661
  ${isTransaction ? "dbCall" : ""}
609
662
  });
610
663
  }`;
@@ -620,6 +673,10 @@ function getMethodSourceDeleteList(x, isTransaction) {
620
673
  args: param1,
621
674
  artifacts,
622
675
  context: param2?.context,
676
+ eventTarget: ${isTransaction ? "eventTarget" : "this.eventTarget"},
677
+ onHandler: ${isTransaction ? "onHandlerMap" : "this.onHandlerMap"}.get("${mapKindToAction(x.kind)}-${x.table}"),
678
+ asyncLocalStorage,
679
+ sdk: this,
623
680
  ${isTransaction ? "dbCall" : ""}
624
681
  });
625
682
  }`;
@@ -0,0 +1 @@
1
+ export declare function capitalizeFirstLetter(str: string): string;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.capitalizeFirstLetter = void 0;
4
+ function capitalizeFirstLetter(str) {
5
+ return str.charAt(0).toUpperCase() + str.slice(1);
6
+ }
7
+ exports.capitalizeFirstLetter = capitalizeFirstLetter;
@@ -1,3 +1,5 @@
1
+ /// <reference types="node" />
2
+ import { AsyncLocalStorage } from "node:async_hooks";
1
3
  export interface IRuntime {
2
4
  resolve(input: TResolveParams): Promise<any>;
3
5
  $queryRaw(sql: string, values?: any[]): Promise<any>;
@@ -20,7 +22,21 @@ export declare type TResolveParams = {
20
22
  context?: TContext;
21
23
  skipCache?: boolean;
22
24
  dbCall?: TDbCall;
23
- };
25
+ eventTarget: EventTarget;
26
+ onHandler?: TOnHandler;
27
+ asyncLocalStorage?: AsyncLocalStorage<{
28
+ isInOnHandler?: boolean;
29
+ isTransaction?: boolean;
30
+ }>;
31
+ sdk?: unknown;
32
+ };
33
+ export declare type TOnHandler = (sdk: unknown, input: unknown, output: unknown) => Promise<void>;
34
+ export declare class EventOnHandlerError<T> extends Event {
35
+ error: T;
36
+ constructor(message: string, data: ConstructorParameters<typeof Event>[1] & {
37
+ error: T;
38
+ });
39
+ }
24
40
  export declare type TContext = {
25
41
  [k: string]: any;
26
42
  };
@@ -1,2 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EventOnHandlerError = void 0;
4
+ class EventOnHandlerError extends Event {
5
+ constructor(message, data) {
6
+ super(message, data);
7
+ this.error = data.error;
8
+ }
9
+ }
10
+ exports.EventOnHandlerError = EventOnHandlerError;
@@ -128,7 +128,12 @@ class RuntimeSQLite {
128
128
  }
129
129
  }
130
130
  async rollback() {
131
- __classPrivateFieldGet(this, _RuntimeSQLite_db, "f").prepare("ROLLBACK").run();
131
+ try {
132
+ __classPrivateFieldGet(this, _RuntimeSQLite_db, "f").prepare("ROLLBACK").run();
133
+ }
134
+ catch (e) {
135
+ console.log(e);
136
+ }
132
137
  }
133
138
  }
134
139
  exports.RuntimeSQLite = RuntimeSQLite;
@@ -1,4 +1,4 @@
1
- import type { IGetSQLASTInput, IArtifacts, IDialect, TDbCall, TFormatQuery, TBeginTransaction, TContext, TMiddleware, TResolveParams } from "../IRuntime";
1
+ import { type IGetSQLASTInput, type IArtifacts, type IDialect, type TDbCall, type TFormatQuery, type TBeginTransaction, type TContext, type TMiddleware, type TResolveParams } from "../IRuntime";
2
2
  import Cache from "../Cache";
3
3
  export declare function resolve(input: TResolveParams, dbCall: TDbCall, formatQuery: TFormatQuery, beginTransaction: TBeginTransaction, dialect: IDialect, middlewareHandler: MiddlewareHandler<TMiddleware>, context: TContext, cache?: Cache): Promise<any>;
4
4
  export declare class MiddlewareHandler<M extends Function> {
@@ -39,6 +39,7 @@ const async_hooks_1 = require("async_hooks");
39
39
  const _ = __importStar(require("lodash/fp"));
40
40
  const uuid_1 = require("uuid");
41
41
  const getSqlAst_1 = require("./getSqlAst");
42
+ const IRuntime_1 = require("../IRuntime");
42
43
  const getWhere_1 = require("./getWhere");
43
44
  const getDateTimeStringMySQL_1 = require("./getDateTimeStringMySQL");
44
45
  const cursor_1 = require("./cursor");
@@ -60,11 +61,39 @@ async function resolve(input, dbCall, formatQuery, beginTransaction, dialect, mi
60
61
  return nextMiddleware(paramsMaybeMutated, consumer);
61
62
  }
62
63
  const paramsChanged = { ...input, ...params };
63
- return _resolve(paramsChanged, dbCall, formatQuery, beginTransaction, dialect, context, cache);
64
+ const p = _resolve(paramsChanged, dbCall, formatQuery, beginTransaction, dialect, context, cache);
65
+ const onHandler = input.onHandler;
66
+ const asyncLocalStorage = input.asyncLocalStorage;
67
+ if (typeof onHandler === "function" &&
68
+ asyncLocalStorage != null &&
69
+ asyncLocalStorage?.getStore()?.isInOnHandler !== true) {
70
+ return p.then((output) => asyncLocalStorage
71
+ .run({ isInOnHandler: true }, async () => onHandler(input.sdk, { ...input.args, data: input.data }, output))
72
+ .then(() => output)
73
+ .catch((error) => {
74
+ input.eventTarget.dispatchEvent(new IRuntime_1.EventOnHandlerError("error", { error }));
75
+ return output;
76
+ }));
77
+ }
78
+ return p;
64
79
  };
65
80
  return resource.runInAsyncScope(() => consumer(params));
66
81
  }
67
- return _resolve(input, dbCall, formatQuery, beginTransaction, dialect, context, cache);
82
+ const p = _resolve(input, dbCall, formatQuery, beginTransaction, dialect, context, cache);
83
+ const onHandler = input.onHandler;
84
+ const asyncLocalStorage = input.asyncLocalStorage;
85
+ if (typeof onHandler === "function" &&
86
+ asyncLocalStorage != null &&
87
+ asyncLocalStorage?.getStore()?.isInOnHandler !== true) {
88
+ return p.then((output) => asyncLocalStorage
89
+ .run({ isInOnHandler: true }, async () => onHandler(input.sdk, { ...input.args, data: input.data }, output))
90
+ .then(() => output)
91
+ .catch((error) => {
92
+ input.eventTarget.dispatchEvent(new IRuntime_1.EventOnHandlerError("error", { error }));
93
+ return output;
94
+ }));
95
+ }
96
+ return p;
68
97
  }
69
98
  exports.resolve = resolve;
70
99
  function _resolve(input, dbCall, formatQuery, beginTransaction, dialect, context, cache) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@technicity/data-service-generator",
3
- "version": "0.14.5",
3
+ "version": "0.15.0",
4
4
  "main": "./dist/index.js",
5
5
  "files": [
6
6
  "dist"