@technicity/data-service-generator 0.8.5 → 0.10.0-next.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.
@@ -9,6 +9,7 @@ const prettier = require("prettier");
9
9
  const changeCase = require("change-case");
10
10
  const fse = require("fs-extra");
11
11
  const _ = require("lodash/fp");
12
+ const uuid_1 = require("uuid");
12
13
  const mssql = require("mssql");
13
14
  // @ts-ignore
14
15
  const TSqlString = require("tsqlstring");
@@ -83,7 +84,7 @@ async function generate(input) {
83
84
  typescript: require("../../package.json").devDependencies.typescript,
84
85
  },
85
86
  };
86
- const tmpDirPath = path.join(os.tmpdir(), `dsg-${Date.now()}`);
87
+ const tmpDirPath = path.join(os.tmpdir(), `dsg-${(0, uuid_1.v4)()}`);
87
88
  fse.mkdirpSync(tmpDirPath);
88
89
  fs.writeFileSync(path.join(tmpDirPath, sdkFilename), sdkSource);
89
90
  fs.writeFileSync(path.join(tmpDirPath, artifactsFilename), artifactsSource);
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export { generate } from "./generation/generate";
2
2
  export { SDKNotFoundError } from "./runtime/lib/SDKNotFoundError";
3
+ export { SDKBadWhereError } from "./runtime/lib/SDKBadWhereError";
3
4
  export { traverseFieldArgs } from "./traverseFieldArgs";
package/dist/index.js CHANGED
@@ -1,9 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.traverseFieldArgs = exports.SDKNotFoundError = exports.generate = void 0;
3
+ exports.traverseFieldArgs = exports.SDKBadWhereError = exports.SDKNotFoundError = exports.generate = void 0;
4
4
  var generate_1 = require("./generation/generate");
5
5
  Object.defineProperty(exports, "generate", { enumerable: true, get: function () { return generate_1.generate; } });
6
6
  var SDKNotFoundError_1 = require("./runtime/lib/SDKNotFoundError");
7
7
  Object.defineProperty(exports, "SDKNotFoundError", { enumerable: true, get: function () { return SDKNotFoundError_1.SDKNotFoundError; } });
8
+ var SDKBadWhereError_1 = require("./runtime/lib/SDKBadWhereError");
9
+ Object.defineProperty(exports, "SDKBadWhereError", { enumerable: true, get: function () { return SDKBadWhereError_1.SDKBadWhereError; } });
8
10
  var traverseFieldArgs_1 = require("./traverseFieldArgs");
9
11
  Object.defineProperty(exports, "traverseFieldArgs", { enumerable: true, get: function () { return traverseFieldArgs_1.traverseFieldArgs; } });
@@ -0,0 +1,18 @@
1
+ import { RedisClientType } from 'redis';
2
+ import { TResolveParams } from './IRuntime';
3
+ declare class Cache {
4
+ protected logs?: boolean | undefined;
5
+ client: RedisClientType;
6
+ waiting?: Set<() => void> | undefined;
7
+ constructor(url: string, logs?: boolean | undefined);
8
+ log(message: string): void;
9
+ pending(): Promise<void>;
10
+ from(input: TResolveParams): Promise<{
11
+ request: string;
12
+ cached: any;
13
+ }>;
14
+ insert(key: string, payload: any): Promise<void>;
15
+ read(key: string): Promise<any>;
16
+ purge(...uuids: string[]): Promise<void>;
17
+ }
18
+ export default Cache;
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const crypto_1 = require("crypto");
4
+ const redis_1 = require("redis");
5
+ const utility_1 = require("./lib/utility");
6
+ class Cache {
7
+ constructor(url, logs) {
8
+ this.logs = logs;
9
+ this.waiting = new Set();
10
+ this.client = (0, redis_1.createClient)({ url: `redis://${url}` });
11
+ this.client.connect();
12
+ this.client.on("connect", () => {
13
+ if (this.waiting)
14
+ this.waiting.forEach(x => x());
15
+ this.waiting = undefined;
16
+ });
17
+ }
18
+ log(message) {
19
+ if (this.logs)
20
+ console.log(message);
21
+ }
22
+ async pending() {
23
+ if (this.waiting)
24
+ return new Promise(res => this.waiting.add(res));
25
+ }
26
+ async from(input) {
27
+ let { action, args, fields, resource } = input;
28
+ const request = JSON.stringify({
29
+ action, resource, args, fields
30
+ });
31
+ const key = (0, crypto_1.createHash)('sha256')
32
+ .update(request)
33
+ .digest('hex');
34
+ const cached = await this.read(key);
35
+ return {
36
+ request: key,
37
+ cached
38
+ };
39
+ }
40
+ async insert(key, payload) {
41
+ const redis = this.client;
42
+ const json = JSON.stringify(payload);
43
+ const regex = /"uuid":"(.+?)"/g;
44
+ const pending = [];
45
+ for (let result; result = regex.exec(json);) {
46
+ const uuid = result[1];
47
+ if (!uuid)
48
+ continue;
49
+ pending.push(redis.sAdd(`deps:${uuid}`, [key]), redis.sAdd(`cached:${key}`, [uuid]));
50
+ }
51
+ if (!pending.length)
52
+ return;
53
+ this.log(`Cache insert: ${key.substring(0, 6)}`);
54
+ await Promise.all([
55
+ redis.set(`cache:${key}`, json),
56
+ ...pending
57
+ ]);
58
+ }
59
+ async read(key) {
60
+ await this.pending();
61
+ const data = await this.client.get(`cache:${key}`);
62
+ const shorthand = key.substring(0, 6);
63
+ if (data) {
64
+ this.log(`Cache hit: ${shorthand}`);
65
+ return JSON.parse(data);
66
+ }
67
+ else {
68
+ this.log(`Cache miss: ${shorthand}`);
69
+ return undefined;
70
+ }
71
+ }
72
+ async purge(...uuids) {
73
+ const redis = this.client;
74
+ await (0, utility_1.mapAsync)(uuids, uuid => {
75
+ const getDependancies = redis.sMembers(`deps:${uuid}`);
76
+ return [
77
+ (0, utility_1.mapAsync)(getDependancies, key => {
78
+ const getDependants = redis.sMembers(`cached:${key}`);
79
+ return [
80
+ (0, utility_1.mapAsync)(getDependants, uuid => (redis.sRem(`deps:${uuid}`, [key]))),
81
+ redis.del(`cache:${key}`),
82
+ redis.del(`cached:${key}`)
83
+ ];
84
+ }),
85
+ redis.del(`deps:${uuid}`)
86
+ ];
87
+ });
88
+ }
89
+ }
90
+ exports.default = Cache;
@@ -5,6 +5,7 @@ export declare class RuntimeMySQL implements IRuntime {
5
5
  [k: string]: any;
6
6
  }, otherOpts: {
7
7
  supplementClientOpts?: ISupplementClientOpts;
8
+ redisHost?: string;
8
9
  }, artifacts: IArtifacts);
9
10
  resolve(input: TResolveParams): Promise<any>;
10
11
  $queryRaw(sql: string, values?: any[]): Promise<any>;
@@ -10,18 +10,23 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
10
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
11
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
12
  };
13
- var _RuntimeMySQL_dialect, _RuntimeMySQL_mysqlClient, _RuntimeMySQL_middlewareHandler;
13
+ var _RuntimeMySQL_dialect, _RuntimeMySQL_mysqlClient, _RuntimeMySQL_clientCache, _RuntimeMySQL_middlewareHandler;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.RuntimeMySQL = void 0;
16
16
  const SqlString = require("sqlstring");
17
+ const Cache_1 = require("./Cache");
17
18
  const MySQL_1 = require("./lib/MySQL");
18
19
  const shared_1 = require("./lib/shared");
19
20
  class RuntimeMySQL {
20
21
  constructor(clientOpts, otherOpts, artifacts) {
21
22
  _RuntimeMySQL_dialect.set(this, "mysql");
22
23
  _RuntimeMySQL_mysqlClient.set(this, void 0);
24
+ _RuntimeMySQL_clientCache.set(this, void 0);
23
25
  _RuntimeMySQL_middlewareHandler.set(this, void 0);
24
26
  __classPrivateFieldSet(this, _RuntimeMySQL_middlewareHandler, new shared_1.MiddlewareHandler(), "f");
27
+ const debugCache = clientOpts?.debug?.includes("Cache");
28
+ if (otherOpts.redisHost)
29
+ __classPrivateFieldSet(this, _RuntimeMySQL_clientCache, new Cache_1.default(otherOpts.redisHost, debugCache), "f");
25
30
  if (otherOpts.supplementClientOpts) {
26
31
  clientOpts = {
27
32
  supportBigNumbers: true,
@@ -64,7 +69,7 @@ class RuntimeMySQL {
64
69
  __classPrivateFieldSet(this, _RuntimeMySQL_mysqlClient, new MySQL_1.MySQL(clientOpts), "f");
65
70
  }
66
71
  async resolve(input) {
67
- return (0, shared_1.resolve)(input, this.dbCall.bind(this), this.formatQuery.bind(this), this.beginTransaction.bind(this), __classPrivateFieldGet(this, _RuntimeMySQL_dialect, "f"), __classPrivateFieldGet(this, _RuntimeMySQL_middlewareHandler, "f"), input.context ?? {});
72
+ return (0, shared_1.resolve)(input, this.dbCall.bind(this), this.formatQuery.bind(this), this.beginTransaction.bind(this), __classPrivateFieldGet(this, _RuntimeMySQL_dialect, "f"), __classPrivateFieldGet(this, _RuntimeMySQL_middlewareHandler, "f"), input.context ?? {}, __classPrivateFieldGet(this, _RuntimeMySQL_clientCache, "f"));
68
73
  }
69
74
  async $queryRaw(sql, values) {
70
75
  return this.dbCall(this.formatQuery(sql, values ?? []));
@@ -92,4 +97,4 @@ class RuntimeMySQL {
92
97
  }
93
98
  }
94
99
  exports.RuntimeMySQL = RuntimeMySQL;
95
- _RuntimeMySQL_dialect = new WeakMap(), _RuntimeMySQL_mysqlClient = new WeakMap(), _RuntimeMySQL_middlewareHandler = new WeakMap();
100
+ _RuntimeMySQL_dialect = new WeakMap(), _RuntimeMySQL_mysqlClient = new WeakMap(), _RuntimeMySQL_clientCache = new WeakMap(), _RuntimeMySQL_middlewareHandler = new WeakMap();
@@ -0,0 +1,4 @@
1
+ import { CustomError } from "../../lib/CustomError";
2
+ export declare class SDKBadWhereError extends CustomError {
3
+ constructor(message?: string);
4
+ }
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SDKBadWhereError = void 0;
4
+ const CustomError_1 = require("../../lib/CustomError");
5
+ class SDKBadWhereError extends CustomError_1.CustomError {
6
+ constructor(message) {
7
+ super(message || "Invalid $where");
8
+ }
9
+ }
10
+ exports.SDKBadWhereError = SDKBadWhereError;
@@ -1,6 +1,7 @@
1
1
  import type { IGetSQLASTInput, IArtifacts, IDialect, TDbCall, TFormatQuery, TBeginTransaction, TContext } from "../IRuntime";
2
2
  import type { TMiddleware, TResolveParams } from "../IRuntime";
3
- export declare function resolve(input: TResolveParams, dbCall: TDbCall, formatQuery: TFormatQuery, beginTransaction: TBeginTransaction, dialect: IDialect, middlewareHandler: MiddlewareHandler<TMiddleware>, context: TContext): Promise<any>;
3
+ import Cache from "../Cache";
4
+ export declare function resolve(input: TResolveParams, dbCall: TDbCall, formatQuery: TFormatQuery, beginTransaction: TBeginTransaction, dialect: IDialect, middlewareHandler: MiddlewareHandler<TMiddleware>, context: TContext, cache?: Cache): Promise<any>;
4
5
  export declare class MiddlewareHandler<M extends Function> {
5
6
  private _middlewares;
6
7
  register(middleware: M): void;
@@ -19,9 +19,10 @@ const cursor_1 = require("./cursor");
19
19
  const runTransforms_1 = require("./runTransforms");
20
20
  const addNullFallbacks_1 = require("./addNullFallbacks");
21
21
  const SDKNotFoundError_1 = require("./SDKNotFoundError");
22
+ const SDKBadWhereError_1 = require("./SDKBadWhereError");
22
23
  const stringifyWhere_1 = require("./stringifyWhere");
23
24
  const getOrderBy_1 = require("./getOrderBy");
24
- async function resolve(input, dbCall, formatQuery, beginTransaction, dialect, middlewareHandler, context) {
25
+ async function resolve(input, dbCall, formatQuery, beginTransaction, dialect, middlewareHandler, context, cache) {
25
26
  // https://github.com/prisma/prisma/blob/822198e5ba21535364d20c86901b8c3778ebf6a3/packages/client/src/runtime/getPrismaClient.ts#L1087
26
27
  let index = -1;
27
28
  if (middlewareHandler.length() > 0) {
@@ -33,39 +34,34 @@ async function resolve(input, dbCall, formatQuery, beginTransaction, dialect, mi
33
34
  return nextMiddleware(paramsMaybeMutated, consumer);
34
35
  }
35
36
  const paramsChanged = { ...input, ...params };
36
- return _resolve(paramsChanged, dbCall, formatQuery, beginTransaction, dialect, context);
37
+ return _resolve(paramsChanged, dbCall, formatQuery, beginTransaction, dialect, context, cache);
37
38
  };
38
39
  return resource.runInAsyncScope(() => consumer(params));
39
40
  }
40
- return _resolve(input, dbCall, formatQuery, beginTransaction, dialect, context);
41
+ return _resolve(input, dbCall, formatQuery, beginTransaction, dialect, context, cache);
41
42
  }
42
43
  exports.resolve = resolve;
43
- function _resolve(input, dbCall, formatQuery, beginTransaction, dialect, context) {
44
- if (input.action === "findUnique") {
45
- return getData(input, dbCall, formatQuery, dialect);
44
+ function _resolve(input, dbCall, formatQuery, beginTransaction, dialect, context, cache) {
45
+ switch (input.action) {
46
+ case "findUnique":
47
+ case "findMany":
48
+ case "findManyPaginated":
49
+ return cache ?
50
+ getCached(input, dbCall, formatQuery, dialect, cache) :
51
+ getData(input, dbCall, formatQuery, dialect);
52
+ case "create":
53
+ return create(input, dbCall, formatQuery, beginTransaction, dialect, context);
54
+ case "update":
55
+ return update(input, dbCall, formatQuery, dialect, cache);
56
+ case "updateMany":
57
+ return updateMany(input, dbCall, formatQuery, dialect, cache);
58
+ case "delete":
59
+ return deleteOne(input, dbCall, formatQuery, dialect, cache);
60
+ case "deleteMany":
61
+ return deleteMany(input, dbCall, formatQuery, dialect, cache);
62
+ default:
63
+ throw new Error("Invalid action: " + input.action);
46
64
  }
47
- if (input.action === "findMany") {
48
- return getData(input, dbCall, formatQuery, dialect);
49
- }
50
- if (input.action === "findManyPaginated") {
51
- return getData(input, dbCall, formatQuery, dialect);
52
- }
53
- if (input.action === "create") {
54
- return create(input, dbCall, formatQuery, beginTransaction, dialect, context);
55
- }
56
- if (input.action === "update") {
57
- return update(input, dbCall, formatQuery, dialect);
58
- }
59
- if (input.action === "updateMany") {
60
- return updateMany(input, dbCall, formatQuery, dialect);
61
- }
62
- if (input.action === "delete") {
63
- return del(input, dbCall, formatQuery, dialect);
64
- }
65
- if (input.action === "deleteMany") {
66
- return deleteMany(input, dbCall, formatQuery, dialect);
67
- }
68
- throw new Error("Invalid action: " + input.action);
69
65
  }
70
66
  class MiddlewareHandler {
71
67
  constructor() {
@@ -269,6 +265,32 @@ async function getData(input, dbCall, formatQuery, dialect) {
269
265
  }
270
266
  return data;
271
267
  }
268
+ async function getCached(input, dbCall, formatQuery, dialect, cache) {
269
+ const { request, cached } = await cache.from(input);
270
+ if (cached)
271
+ return cached;
272
+ ensureUuidSelect(input);
273
+ const results = await getData(input, dbCall, formatQuery, dialect);
274
+ cache.insert(request, results);
275
+ return results;
276
+ }
277
+ function ensureUuidSelect(input) {
278
+ const { resource, artifacts } = input;
279
+ ensure(resource, input);
280
+ function ensure(type, input) {
281
+ const { scalarFields, relationFields } = artifacts[type];
282
+ if (!scalarFields.includes("uuid"))
283
+ return;
284
+ const fields = input.fields;
285
+ if (!fields.includes("uuid"))
286
+ fields.unshift("uuid");
287
+ for (const field of fields)
288
+ if (typeof field == "object") {
289
+ const { table } = relationFields[field.name];
290
+ ensure(table, field);
291
+ }
292
+ }
293
+ }
272
294
  function wrapListPaginationLimitOffset(data, totalCount) {
273
295
  return { paginationInfo: { totalCount }, results: data };
274
296
  }
@@ -485,7 +507,7 @@ function getCreateTree(data, table, referencedKey, specialCaseUuidColumn, dialec
485
507
  }
486
508
  return out;
487
509
  }
488
- async function update(input, dbCall, formatQuery, dialect) {
510
+ async function update(input, dbCall, formatQuery, dialect, cache) {
489
511
  async function _update() {
490
512
  const escapeId = (0, stringifyWhere_1.getEscapeId)(dialect);
491
513
  const tableArtifacts = input.artifacts[input.resource];
@@ -497,6 +519,8 @@ async function update(input, dbCall, formatQuery, dialect) {
497
519
  if (current == null) {
498
520
  throw new SDKNotFoundError_1.SDKNotFoundError();
499
521
  }
522
+ if (cache && current.uuid)
523
+ cache.purge(current.uuid);
500
524
  // Shallow clone, as we're going to mutate later
501
525
  const data = { ...input.data };
502
526
  if (hasMappedFields(input.artifacts, input.resource, data)) {
@@ -574,7 +598,7 @@ function getUpdateQuery(table, data, where, dialect, formatQuery) {
574
598
  q += ` WHERE ${where}`;
575
599
  return formatQuery(q, values);
576
600
  }
577
- async function updateMany(input, dbCall, formatQuery, dialect) {
601
+ async function updateMany(input, dbCall, formatQuery, dialect, cache) {
578
602
  async function _updateMany() {
579
603
  const escapeId = (0, stringifyWhere_1.getEscapeId)(dialect);
580
604
  const tableArtifacts = input.artifacts[input.resource];
@@ -582,6 +606,14 @@ async function updateMany(input, dbCall, formatQuery, dialect) {
582
606
  if (where == null) {
583
607
  throw new Error("Null where");
584
608
  }
609
+ if (cache)
610
+ try {
611
+ const query = formatQuery(`SELECT uuid FROM ?? WHERE ${where}`, [input.resource]);
612
+ const matches = await dbCall(query);
613
+ const uuids = matches.map((x) => x.uuid);
614
+ cache.purge(...uuids);
615
+ }
616
+ catch (err) { }
585
617
  // Shallow clone, as we're going to mutate later
586
618
  const data = { ...input.data };
587
619
  if (hasMappedFields(input.artifacts, input.resource, data)) {
@@ -610,7 +642,7 @@ async function updateMany(input, dbCall, formatQuery, dialect) {
610
642
  await _updateMany();
611
643
  return getData(input, dbCall, formatQuery, dialect);
612
644
  }
613
- async function del(input, dbCall, formatQuery, dialect) {
645
+ async function deleteOne(input, dbCall, formatQuery, dialect, cache) {
614
646
  const _findOne = Object.entries(input.args.$where)[0];
615
647
  const findOne = { key: _findOne[0], value: _findOne[1] };
616
648
  const current = await dbCall(formatQuery("SELECT * FROM ?? WHERE ?? = ?", [
@@ -621,6 +653,8 @@ async function del(input, dbCall, formatQuery, dialect) {
621
653
  if (current == null) {
622
654
  throw new SDKNotFoundError_1.SDKNotFoundError();
623
655
  }
656
+ if (cache && current.uuid)
657
+ cache.purge(current.uuid);
624
658
  await dbCall(formatQuery("DELETE FROM ?? WHERE ?? = ?", [
625
659
  input.resource,
626
660
  findOne.key,
@@ -628,12 +662,20 @@ async function del(input, dbCall, formatQuery, dialect) {
628
662
  ]));
629
663
  return true;
630
664
  }
631
- async function deleteMany(input, dbCall, formatQuery, dialect) {
665
+ async function deleteMany(input, dbCall, formatQuery, dialect, cache) {
632
666
  const escapeId = (0, stringifyWhere_1.getEscapeId)(dialect);
633
667
  const where = (0, getWhere_1.getWhere)(escapeId(input.resource), input.args, dialect);
634
668
  if (where == null) {
635
669
  throw new Error("Null where");
636
670
  }
671
+ if (cache)
672
+ try {
673
+ const query = formatQuery(`SELECT uuid FROM ?? WHERE ${where}`, [input.resource]);
674
+ const matches = await dbCall(query);
675
+ const uuids = matches.map((x) => x.uuid);
676
+ cache.purge(...uuids);
677
+ }
678
+ catch (err) { }
637
679
  const sql = "DELETE FROM ?? WHERE " + where;
638
680
  const values = [input.resource];
639
681
  await dbCall(formatQuery(sql, values));
@@ -776,7 +818,14 @@ async function _prepareWhere(artifacts, table, data, dbCall, formatQuery) {
776
818
  v,
777
819
  ])).then((xs) => xs[0]?.[mappedField.referencedKey])));
778
820
  if (newVal.some((x) => x == null)) {
779
- throw new SDKNotFoundError_1.SDKNotFoundError();
821
+ const index = newVal.findIndex((x) => x == null);
822
+ if (index === -1) {
823
+ throw new SDKBadWhereError_1.SDKBadWhereError();
824
+ }
825
+ else {
826
+ const v = where[index];
827
+ throw new SDKBadWhereError_1.SDKBadWhereError(getPrepareWhereNotFoundMessage(mappedField, v));
828
+ }
780
829
  }
781
830
  out = _.set(newPath, newVal, out);
782
831
  }
@@ -788,7 +837,7 @@ async function _prepareWhere(artifacts, table, data, dbCall, formatQuery) {
788
837
  where,
789
838
  ])).then((xs) => xs[0]?.[mappedField.referencedKey]);
790
839
  if (newVal == null) {
791
- throw new SDKNotFoundError_1.SDKNotFoundError();
840
+ throw new SDKBadWhereError_1.SDKBadWhereError(getPrepareWhereNotFoundMessage(mappedField, where));
792
841
  }
793
842
  out = _.set(newPath, newVal, out);
794
843
  }
@@ -811,7 +860,14 @@ async function _prepareWhere(artifacts, table, data, dbCall, formatQuery) {
811
860
  v,
812
861
  ])).then((xs) => xs[0]?.[mappedField.referencedKey])));
813
862
  if (newVal.some((x) => x == null)) {
814
- throw new SDKNotFoundError_1.SDKNotFoundError();
863
+ const index = newVal.findIndex((x) => x == null);
864
+ if (index === -1) {
865
+ throw new SDKBadWhereError_1.SDKBadWhereError();
866
+ }
867
+ else {
868
+ const v = where[index];
869
+ throw new SDKBadWhereError_1.SDKBadWhereError(getPrepareWhereNotFoundMessage(mappedField, v));
870
+ }
815
871
  }
816
872
  out = _.set(newPath, newVal, out);
817
873
  }
@@ -823,7 +879,7 @@ async function _prepareWhere(artifacts, table, data, dbCall, formatQuery) {
823
879
  where,
824
880
  ])).then((xs) => xs[0]?.[mappedField.referencedKey]);
825
881
  if (newVal == null) {
826
- throw new SDKNotFoundError_1.SDKNotFoundError();
882
+ throw new SDKBadWhereError_1.SDKBadWhereError(getPrepareWhereNotFoundMessage(mappedField, where));
827
883
  }
828
884
  out = _.set(newPath, newVal, out);
829
885
  }
@@ -837,6 +893,9 @@ async function _prepareWhere(artifacts, table, data, dbCall, formatQuery) {
837
893
  return out;
838
894
  }
839
895
  exports._prepareWhere = _prepareWhere;
896
+ function getPrepareWhereNotFoundMessage(mappedField, value) {
897
+ return `Not found: unable to map \`${mappedField.referencedTable}\`.\`${mappedField.name}\` to \`${mappedField.referencedTable}\`.\`${mappedField.referencedKey}\` for the value \`${value}\`.`;
898
+ }
840
899
  const ops = [
841
900
  "$eq",
842
901
  "$neq",
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Eagerly resolve and map input values then concatinate.
3
+ */
4
+ export declare function mapAsync<T, R>(source: T[] | Promise<T[]>, mapFunction: (item: T) => R | R[] | Promise<R>[] | Promise<R | R[]>): Promise<R[]>;
5
+ export declare function flatten<T>(array: (T | T[])[]): T[];
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.flatten = exports.mapAsync = void 0;
4
+ /**
5
+ * Eagerly resolve and map input values then concatinate.
6
+ */
7
+ async function mapAsync(source, mapFunction) {
8
+ const output = (await source).map(mapFunction);
9
+ return Promise.all(flatten(output)).then(flatten);
10
+ }
11
+ exports.mapAsync = mapAsync;
12
+ function flatten(array) {
13
+ return [].concat(...array);
14
+ }
15
+ exports.flatten = flatten;
package/package.json CHANGED
@@ -1,17 +1,16 @@
1
1
  {
2
2
  "name": "@technicity/data-service-generator",
3
- "version": "0.8.5",
3
+ "version": "0.10.0-next.1",
4
4
  "main": "./dist/index.js",
5
5
  "files": [
6
6
  "dist"
7
7
  ],
8
8
  "scripts": {
9
9
  "compile": "rm -rf dist && tsc",
10
- "create-database": "env-cmd node ./test/mysql/create-database.js && env-cmd node ./test/mysql8/create-database.js && env-cmd node ./test/mssql/create-database.js",
11
- "generate": "npm run compile && npm run create-database && env-cmd node ./test/mysql/generate.js && env-cmd node ./test/mysql8/generate.js && env-cmd node ./test/mssql/generate.js",
12
- "test": "npm run generate && env-cmd mocha ./test/addNullFallbacks.test.js && env-cmd mocha ./test/stringifyWhere.test.js && npm run test:sdk",
13
- "test:sdk": "env-cmd mocha ./test/test.js",
14
- "test:only": "npm run create-database && npm run test:sdk"
10
+ "generate": "npm run compile && concurrently \"node ./test/mysql/generate.js\" \"node ./test/mysql8/generate.js\"",
11
+ "test": "npm run generate && mocha ./test/addNullFallbacks.test.js && mocha ./test/stringifyWhere.test.js && npm run test:sdk",
12
+ "test:prepare": "docker-compose down --volumes && docker-compose up -d --build",
13
+ "test:sdk": "mocha ./test/test.js"
15
14
  },
16
15
  "dependencies": {
17
16
  "bluebird": "^3.7.2",
@@ -25,6 +24,7 @@
25
24
  "mssql": "^6.3.1",
26
25
  "mysql": "^2.18.1",
27
26
  "prettier": "^2.1.2",
27
+ "redis": "^4.3.0",
28
28
  "sqlstring": "^2.3.2",
29
29
  "tsqlstring": "^1.0.1",
30
30
  "uuid": "^8.3.2"
@@ -37,6 +37,7 @@
37
37
  "@types/prettier": "^2.1.5",
38
38
  "@types/sqlstring": "^2.2.1",
39
39
  "@types/uuid": "^8.3.1",
40
+ "concurrently": "^7.1.0",
40
41
  "env-cmd": "^10.1.0",
41
42
  "mocha": "9.1.3",
42
43
  "sinon": "12.0.1",