sasat 0.22.0 → 0.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,3959 +1,10 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- //#region \0rolldown/runtime.js
3
- var __create = Object.create;
4
- var __defProp = Object.defineProperty;
5
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
- var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __getProtoOf = Object.getPrototypeOf;
8
- var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
- key = keys[i];
12
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
- get: ((k) => from[k]).bind(null, key),
14
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
- });
16
- }
17
- return to;
18
- };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
- value: mod,
21
- enumerable: true
22
- }) : target, mod));
23
- //#endregion
24
- let node_fs = require("node:fs");
25
- node_fs = __toESM(node_fs, 1);
26
- let node_path = require("node:path");
27
- node_path = __toESM(node_path, 1);
28
- let node_fs_promises = require("node:fs/promises");
29
- let js_yaml = require("js-yaml");
30
- js_yaml = __toESM(js_yaml, 1);
31
- require("pluralize");
32
- let typescript = require("typescript");
33
- typescript = __toESM(typescript, 1);
34
- let chalk = require("chalk");
35
- chalk = __toESM(chalk, 1);
2
+ const require_migrate = require("./migrate-Cc47Mufl.cjs");
36
3
  let sqlstring = require("sqlstring");
37
- sqlstring = __toESM(sqlstring, 1);
4
+ sqlstring = require_migrate.__toESM(sqlstring, 1);
38
5
  let mysql2_promise = require("mysql2/promise");
39
- let esbuild = require("esbuild");
40
- //#region src/util/assignDeep.ts
41
- const assignDeep = (base, ...objects) => {
42
- const assign = (target, key, value) => {
43
- if (key === "__proto__" || key === "constructor") return;
44
- if (Array.isArray(target[key]) && Array.isArray(value)) target[key] = [...target[key], ...value];
45
- else if (typeof target[key] === "object" && typeof value === "object") assignDeep(target[key], value);
46
- else target[key] = value;
47
- };
48
- objects.forEach((obj) => {
49
- if (typeof obj === "object") Object.entries(obj).forEach(([key, value]) => {
50
- assign(base, key, value);
51
- });
52
- });
53
- return base;
54
- };
55
- //#endregion
56
- //#region src/util/fsUtil.ts
57
- const readYmlFile = (filepath) => js_yaml.default.load((0, node_fs.readFileSync)(filepath, "utf8"));
58
- const mkDirIfNotExist = (path) => {
59
- if (!(0, node_fs.existsSync)(path)) (0, node_fs.mkdirSync)(path);
60
- };
61
- const writeFileIfNotExist = (path, data) => {
62
- if ((0, node_fs.existsSync)(path)) return Promise.resolve();
63
- return (0, node_fs_promises.writeFile)(path, data);
64
- };
65
- const writeYmlFile = (path, fileName, obj) => {
66
- mkDirIfNotExist(path);
67
- (0, node_fs.writeFileSync)((0, node_path.join)(path, fileName), js_yaml.default.dump(obj, {
68
- skipInvalid: true,
69
- noRefs: true,
70
- sortKeys: (a, b) => {
71
- if (b === "tableName") return 1;
72
- if (a === "tableName") return -1;
73
- if (a > b) return 1;
74
- if (a < b) return -1;
75
- return 0;
76
- }
77
- }));
78
- };
79
- const readInitialSchema = () => {
80
- return readYmlFile((0, node_path.join)(config().migration.dir, "initialSchema.yml"));
81
- };
82
- const writeCurrentSchema = (schema) => {
83
- writeYmlFile(config().migration.dir, "currentSchema.yml", schema);
84
- };
85
- //#endregion
86
- //#region src/config/loader.ts
87
- var SasatConfigLoader = class SasatConfigLoader {
88
- static loadConfig() {
89
- const filepath = node_path.default.join(process.cwd(), "sasat.yml");
90
- if (!(0, node_fs.existsSync)(filepath)) return defaultConf;
91
- return readYmlFile(filepath);
92
- }
93
- constructor() {
94
- const conf = this.readValue({
95
- ...defaultConf,
96
- ...SasatConfigLoader.loadConfig()
97
- });
98
- this.conf = { ...conf };
99
- }
100
- getConfig() {
101
- return this.conf;
102
- }
103
- readValue(value) {
104
- if (!value) return value;
105
- if (Array.isArray(value)) return value.map((it) => this.readValue(it));
106
- if (typeof value === "string" && value.startsWith("$")) return process.env[value.slice(1)];
107
- if (typeof value === "object") {
108
- for (const key in value) if (Object.hasOwn(value, key)) value[key] = this.readValue(value[key]);
109
- return value;
110
- }
111
- return value;
112
- }
113
- };
114
- const defaultConf = {
115
- db: {
116
- host: "127.0.0.1",
117
- port: 3306,
118
- user: "root",
119
- database: "sasat",
120
- password: ""
121
- },
122
- migration: {
123
- table: "__migrate__",
124
- dir: "migrations",
125
- out: "sasat"
126
- },
127
- generator: {
128
- addJsExtToImportStatement: false,
129
- gql: { subscription: true }
130
- }
131
- };
132
- let conf;
133
- const config = () => {
134
- if (conf === void 0) conf = new SasatConfigLoader().getConfig();
135
- return conf;
136
- };
137
- function setConfig(update) {
138
- conf = assignDeep(config(), update);
139
- return conf;
140
- }
141
- //#endregion
142
- //#region src/generatorv2/fs/emptyDir.ts
143
- async function emptyDir(dir) {
144
- let items;
145
- try {
146
- items = await (0, node_fs_promises.readdir)(dir);
147
- } catch {
148
- return (0, node_fs_promises.mkdir)(dir, { mode: 511 });
149
- }
150
- return Promise.all(items.map((item) => (0, node_fs_promises.rm)(node_path.default.join(dir, item), {
151
- recursive: true,
152
- force: true
153
- })));
154
- }
155
- //#endregion
156
- //#region src/generatorv2/codegen/ts/tsFileNames.ts
157
- const tsFileNames = {
158
- encoder: "idEncoder",
159
- conditions: "conditions",
160
- middleware: "middlewares"
161
- };
162
- //#endregion
163
- //#region src/migration/column/columnTypes.ts
164
- const columnTypeToTsType = (type) => {
165
- switch (type) {
166
- case "tinyint":
167
- case "smallint":
168
- case "mediumint":
169
- case "int":
170
- case "bigint":
171
- case "float":
172
- case "double":
173
- case "decimal":
174
- case "year": return "number";
175
- case "char":
176
- case "varchar":
177
- case "text":
178
- case "time":
179
- case "date":
180
- case "datetime":
181
- case "timestamp": return "string";
182
- case "boolean": return "boolean";
183
- }
184
- };
185
- //#endregion
186
- //#region src/tsg/importDeclaration.ts
187
- var ImportDeclaration = class {
188
- constructor(types, module) {
189
- this.types = types;
190
- this.module = module;
191
- }
192
- toString() {
193
- const addJsExt = config().generator.addJsExtToImportStatement && this.module.startsWith(".");
194
- return `import {${this.types.join(",")}} from "${addJsExt ? this.module + ".js" : this.module}";`;
195
- }
196
- };
197
- //#endregion
198
- //#region src/tsg/abstruct/tsCode.ts
199
- var TsCode = class {
200
- constructor() {
201
- this.importDeclarations = [];
202
- }
203
- addImport(types, module) {
204
- this.importDeclarations.push(new ImportDeclaration(types, module));
205
- return this;
206
- }
207
- toString() {
208
- return this.codePrefix() + this.toTsString();
209
- }
210
- codePrefix() {
211
- return "";
212
- }
213
- mergeImport(...code) {
214
- code.forEach((it) => {
215
- if (it) this.importDeclarations.push(...it.importDeclarations);
216
- });
217
- }
218
- };
219
- //#endregion
220
- //#region src/tsg/abstruct/statement.ts
221
- var TsStatement = class extends TsCode {
222
- constructor(..._args) {
223
- super(..._args);
224
- this.codeType = "statement";
225
- }
226
- };
227
- //#endregion
228
- //#region src/tsg/node/block.ts
229
- const notNull = (v) => {
230
- return v !== null;
231
- };
232
- var Block = class extends TsStatement {
233
- constructor(...statements) {
234
- super();
235
- const sts = statements.filter(notNull);
236
- this.mergeImport(...sts);
237
- this.statements = sts;
238
- }
239
- toTsString() {
240
- return `{${this.statements.map((it) => it.toString()).join("\n")}}`;
241
- }
242
- };
243
- //#endregion
244
- //#region src/tsg/abstruct/exportableDeclaration.ts
245
- var ExportableDeclaration = class extends TsStatement {
246
- constructor(..._args) {
247
- super(..._args);
248
- this.isExported = false;
249
- }
250
- codePrefix() {
251
- return this.isExported ? "export " : "";
252
- }
253
- export() {
254
- this.isExported = true;
255
- return this;
256
- }
257
- };
258
- //#endregion
259
- //#region src/tsg/node/class.ts
260
- var Class = class extends ExportableDeclaration {
261
- constructor(name) {
262
- super();
263
- this.name = name;
264
- this.properties = [];
265
- this.methods = [];
266
- this.isAbstract = false;
267
- }
268
- abstract() {
269
- this.isAbstract = true;
270
- return this;
271
- }
272
- extends(value) {
273
- this._extends = value;
274
- this.mergeImport(value);
275
- return this;
276
- }
277
- implements(value) {
278
- this._implements = value;
279
- this.mergeImport(value);
280
- return this;
281
- }
282
- addProperty(...properties) {
283
- this.properties.push(...properties);
284
- this.mergeImport(...properties);
285
- return this;
286
- }
287
- addMethod(...methods) {
288
- this.methods.push(...methods);
289
- this.mergeImport(...methods);
290
- return this;
291
- }
292
- toTsString() {
293
- const properties = this.properties.map((it) => it.toString()).join("");
294
- const methods = this.methods.map((it) => it.toString()).join("");
295
- const implement = this._implements ? this._implements.toString() + " " : "";
296
- const extend = this._extends ? this._extends.toString() + "" : "";
297
- return (this.isAbstract ? "abstract " : "") + `class ${this.name} ${implement}${extend}{${properties}${methods}}`;
298
- }
299
- };
300
- //#endregion
301
- //#region src/tsg/node/enumDeclaration.ts
302
- var EnumDeclaration = class extends ExportableDeclaration {
303
- constructor(identifier, members) {
304
- super();
305
- this.identifier = identifier;
306
- this.members = members;
307
- this.mergeImport(identifier, ...members);
308
- }
309
- addMembers(...members) {
310
- this.members.push(...members);
311
- this.mergeImport(...members);
312
- return this;
313
- }
314
- toTsString() {
315
- return `enum ${this.identifier}{${this.members.map((it) => it.toString() + ",").join("")}}`;
316
- }
317
- };
318
- //#endregion
319
- //#region src/tsg/node/enumMember.ts
320
- var EnumMember = class extends TsCode {
321
- constructor(identifier, value) {
322
- super();
323
- this.identifier = identifier;
324
- this.value = value;
325
- this.mergeImport(identifier);
326
- if (value) this.mergeImport(value);
327
- }
328
- toTsString() {
329
- if (!this.value) return this.identifier.toString();
330
- return this.identifier + "=" + this.value;
331
- }
332
- };
333
- //#endregion
334
- //#region src/tsg/node/expressionStatement.ts
335
- var ExpressionStatement = class extends TsStatement {
336
- constructor(expression) {
337
- super();
338
- this.expression = expression;
339
- this.mergeImport(expression);
340
- }
341
- toTsString() {
342
- return this.expression.toString() + ";";
343
- }
344
- };
345
- //#endregion
346
- //#region src/tsg/tsValueString.ts
347
- const tsValueString = (value) => {
348
- if (value === null) return "null";
349
- if (value === void 0) return "undefined";
350
- if (typeof value === "number") return "" + value;
351
- if (typeof value === "boolean") return "" + value;
352
- if (typeof value === "string") return `'${value.replaceAll("'", "\\'")}'`;
353
- if (typeof value === "bigint") return "" + value;
354
- if (typeof value === "function") return value.toString();
355
- if (Array.isArray(value)) return `[${value.map(tsValueString).join(",")}]`;
356
- if (typeof value === "object") return `{${Object.entries(value).map(([key, value]) => [key, tsValueString(value)]).map(([key, value]) => `${key}: ${value}`).join(",")}}`;
357
- throw new TypeError(`tsValueString::unsupported data type ${typeof value}`);
358
- };
359
- //#endregion
360
- //#region src/tsg/node/parameter.ts
361
- var Parameter = class extends TsCode {
362
- constructor(paramName, type) {
363
- super();
364
- this.paramName = paramName;
365
- this.type = type;
366
- this.mergeImport(type);
367
- }
368
- toTsString() {
369
- if (!this.type) return this.paramName;
370
- return `${this.paramName}: ${this.type.toString()}`;
371
- }
372
- static arrayToString(params) {
373
- return params.map((it) => it.toString()).join(",");
374
- }
375
- };
376
- //#endregion
377
- //#region src/tsg/node/expressions.ts
378
- var TsExpression = class extends TsCode {
379
- constructor(..._args) {
380
- super(..._args);
381
- this._codeType = "expression";
382
- }
383
- toStatement() {
384
- return new ExpressionStatement(this);
385
- }
386
- call(...args) {
387
- return new CallExpression(this, ...args);
388
- }
389
- nonNull() {
390
- return new NonNullExpression(this);
391
- }
392
- property(propertyName) {
393
- return new PropertyAccessExpression(this, propertyName);
394
- }
395
- as(type) {
396
- return new AsExpression(this, type);
397
- }
398
- };
399
- var CallExpression = class extends TsExpression {
400
- constructor(identifier, ...args) {
401
- super();
402
- this.identifier = identifier;
403
- this._typeArgs = [];
404
- this.mergeImport(identifier, ...args);
405
- this.args = args;
406
- }
407
- typeArgs(...typeArgs) {
408
- this._typeArgs = typeArgs;
409
- this.mergeImport(...typeArgs);
410
- return this;
411
- }
412
- toTsString() {
413
- return this.identifier.toString() + (this._typeArgs.length !== 0 ? `<${this._typeArgs.map((it) => it.toString()).join(",")}>` : "") + `(${this.args.map((it) => it.toString()).join(",")})`;
414
- }
415
- };
416
- var Literal = class extends TsExpression {};
417
- var StringLiteral = class extends Literal {
418
- constructor(value) {
419
- super();
420
- this.value = value;
421
- }
422
- toTsString() {
423
- return tsValueString(this.value);
424
- }
425
- };
426
- var NumericLiteral = class extends Literal {
427
- constructor(value) {
428
- super();
429
- this.value = value;
430
- }
431
- toTsString() {
432
- return this.value.toString();
433
- }
434
- };
435
- var Boolean = class extends Literal {
436
- constructor(value) {
437
- super();
438
- this.value = value;
439
- }
440
- toTsString() {
441
- return this.value.toString();
442
- }
443
- };
444
- var ArrayLiteral = class extends Literal {
445
- constructor(literals) {
446
- super();
447
- this.literals = literals;
448
- this.mergeImport(...literals);
449
- }
450
- toTsString() {
451
- return `[${this.literals.map((it) => it.toString()).join(",")}]`;
452
- }
453
- };
454
- var ObjectLiteral = class extends Literal {
455
- constructor(...properties) {
456
- super();
457
- this.properties = [];
458
- this.addProperties(...properties);
459
- }
460
- addProperties(...properties) {
461
- this.properties.push(...properties);
462
- this.mergeImport(...properties);
463
- return this;
464
- }
465
- toTsString() {
466
- return `{${this.properties.map((it) => it.toString()).join(",")}}`;
467
- }
468
- };
469
- var ArrowFunction = class extends Literal {
470
- constructor(params, returnType, body) {
471
- super();
472
- this.params = params;
473
- this.returnType = returnType;
474
- this.body = body;
475
- this.mergeImport(...params, body, returnType);
476
- }
477
- toTsString() {
478
- const returnType = this.returnType ? `: ${this.returnType}` : "";
479
- return `(${Parameter.arrayToString(this.params)})${returnType} => ${this.body.toString()}`;
480
- }
481
- toAsync() {
482
- return new AsyncExpression(this);
483
- }
484
- };
485
- var AsyncExpression = class extends TsExpression {
486
- constructor(expression) {
487
- super();
488
- this.expression = expression;
489
- this.mergeImport(expression);
490
- }
491
- toTsString() {
492
- return "async " + this.expression.toString();
493
- }
494
- };
495
- var AwaitExpression = class extends TsExpression {
496
- constructor(expression) {
497
- super();
498
- this.expression = expression;
499
- this.mergeImport(expression);
500
- }
501
- toTsString() {
502
- return "await " + this.expression.toString();
503
- }
504
- };
505
- var BinaryExpression = class extends TsExpression {
506
- constructor(left, operator, right) {
507
- super();
508
- this.left = left;
509
- this.operator = operator;
510
- this.right = right;
511
- this.mergeImport(left, right);
512
- }
513
- toTsString() {
514
- return this.left + this.operator + this.right;
515
- }
516
- };
517
- var Identifier = class extends TsExpression {
518
- constructor(name) {
519
- super();
520
- this.name = name;
521
- }
522
- toTsString() {
523
- return this.name;
524
- }
525
- importFrom(path) {
526
- this.addImport([this.name], path);
527
- return this;
528
- }
529
- };
530
- var NewExpression = class extends CallExpression {
531
- toTsString() {
532
- return "new " + super.toTsString();
533
- }
534
- };
535
- var ParenthesizedExpression = class extends TsExpression {
536
- constructor(expression) {
537
- super();
538
- this.expression = expression;
539
- this.mergeImport(expression);
540
- }
541
- toTsString() {
542
- return `(${this.expression})`;
543
- }
544
- };
545
- var NonNullExpression = class extends TsExpression {
546
- constructor(expression) {
547
- super();
548
- this.expression = expression;
549
- this.mergeImport(expression);
550
- }
551
- toTsString() {
552
- return `${this.expression}!`;
553
- }
554
- };
555
- var PropertyAccessExpression = class extends TsExpression {
556
- constructor(expression, propertyName) {
557
- super();
558
- this.expression = expression;
559
- this.propertyName = propertyName;
560
- this.mergeImport(expression);
561
- }
562
- toTsString() {
563
- return `${this.expression.toString()}.${this.propertyName}`;
564
- }
565
- };
566
- var AsExpression = class extends TsExpression {
567
- constructor(expression, asType) {
568
- super();
569
- this.expression = expression;
570
- this.asType = asType;
571
- this.mergeImport(expression, asType);
572
- }
573
- toTsString() {
574
- return this.expression.toString() + " as " + this.asType.toString();
575
- }
576
- };
577
- var TernaryExpression = class extends TsExpression {
578
- constructor(condition, left, right) {
579
- super();
580
- this.condition = condition;
581
- this.left = left;
582
- this.right = right;
583
- this.mergeImport(condition, left, right);
584
- }
585
- toTsString() {
586
- return `(${this.condition})?${this.left}:${this.right}`;
587
- }
588
- };
589
- var SpreadElement = class extends TsExpression {
590
- constructor(expression) {
591
- super();
592
- this.expression = expression;
593
- this.mergeImport(expression);
594
- }
595
- toTsString() {
596
- return `...${this.expression}`;
597
- }
598
- };
599
- //#endregion
600
- //#region src/tsg/node/extendsClause.ts
601
- var ExtendsClause = class extends TsCode {
602
- constructor(type) {
603
- super();
604
- this.type = type;
605
- this.mergeImport(type);
606
- }
607
- toTsString() {
608
- return `extends ${this.type}`;
609
- }
610
- };
611
- //#endregion
612
- //#region src/tsg/node/ifStatement.ts
613
- var IfStatement = class extends TsStatement {
614
- constructor(condition, statement) {
615
- super();
616
- this.condition = condition;
617
- this.statement = statement;
618
- this.mergeImport(condition, statement);
619
- }
620
- toTsString() {
621
- return `if(${this.condition})${this.statement}`;
622
- }
623
- };
624
- //#endregion
625
- //#region src/tsg/node/implementsClause.ts
626
- var ImplementsClause = class extends TsCode {
627
- constructor(...types) {
628
- super();
629
- this.types = types;
630
- this.mergeImport(...types);
631
- }
632
- toTsString() {
633
- return `implements ${this.types.join(",")}`;
634
- }
635
- };
636
- //#endregion
637
- //#region src/tsg/tsUtil.ts
638
- const TsUtil = {
639
- readonly: (isReadonly) => isReadonly ? "readonly " : "",
640
- questionToken: (isOptional) => isOptional ? "?" : ""
641
- };
642
- //#endregion
643
- //#region src/tsg/node/propertySignature.ts
644
- var PropertySignature = class extends TsCode {
645
- constructor(propertyName, type, isOptional = false, isReadOnly = false) {
646
- super();
647
- this.propertyName = propertyName;
648
- this.type = type;
649
- this.isOptional = isOptional;
650
- this.isReadOnly = isReadOnly;
651
- this.mergeImport(type);
652
- }
653
- codePrefix() {
654
- return TsUtil.readonly(this.isReadOnly);
655
- }
656
- toTsString() {
657
- return `${this.propertyName}${TsUtil.questionToken(this.isOptional)}: ${this.type}`;
658
- }
659
- };
660
- //#endregion
661
- //#region src/tsg/node/interface.ts
662
- var TsInterface = class extends ExportableDeclaration {
663
- constructor(name) {
664
- super();
665
- this.name = name;
666
- this.properties = [];
667
- }
668
- addProperty(propertyName, type, isOptional = false, isReadOnly = false) {
669
- this.properties.push(new PropertySignature(propertyName, type, isOptional, isReadOnly));
670
- return this;
671
- }
672
- addProperties(properties) {
673
- this.properties.push(...properties);
674
- this.mergeImport(...properties);
675
- return this;
676
- }
677
- extends(value) {
678
- this._extends = value;
679
- this.mergeImport(value);
680
- return this;
681
- }
682
- toTsString() {
683
- const extend = this._extends ? this._extends.toString() + " " : "";
684
- return `interface ${this.name} ${extend}{${this.properties.map((it) => it.toString()).join(";")}}`;
685
- }
686
- };
687
- //#endregion
688
- //#region src/tsg/node/modifier/modifiers.ts
689
- var Modifiers = class extends TsCode {
690
- constructor(..._args) {
691
- super(..._args);
692
- this._accessor = "";
693
- this.isReadOnly = false;
694
- this.isStatic = false;
695
- this.isAbstract = false;
696
- this.isAsync = false;
697
- }
698
- accessor(accessor) {
699
- this._accessor = accessor;
700
- return this;
701
- }
702
- private() {
703
- return this.accessor("private");
704
- }
705
- protected() {
706
- return this.accessor("protected ");
707
- }
708
- abstract() {
709
- this.isAbstract = true;
710
- return this;
711
- }
712
- readonly() {
713
- this.isReadOnly = true;
714
- return this;
715
- }
716
- static() {
717
- this.isStatic = true;
718
- return this;
719
- }
720
- async() {
721
- this.isAsync = true;
722
- return this;
723
- }
724
- toTsString() {
725
- const optional = (bool, string) => bool ? string : "";
726
- return this._accessor + " " + optional(this.isAbstract, "abstract ") + optional(this.isStatic, "static ") + optional(this.isReadOnly, "readonly ") + optional(this.isAsync, "async ");
727
- }
728
- };
729
- //#endregion
730
- //#region src/tsg/node/modifier/methodModifiers.ts
731
- var MethodModifiers = class extends Modifiers {
732
- private() {
733
- return super.private();
734
- }
735
- protected() {
736
- return super.protected();
737
- }
738
- abstract() {
739
- return super.abstract();
740
- }
741
- static() {
742
- return super.static();
743
- }
744
- async() {
745
- return super.async();
746
- }
747
- };
748
- //#endregion
749
- //#region src/tsg/node/type/type.ts
750
- const isCode = (t) => t instanceof TsCode;
751
- const pickCode = (types) => types.filter((it) => it instanceof TsCode);
752
- //#endregion
753
- //#region src/tsg/node/methodDeclaration.ts
754
- var MethodDeclaration = class extends TsCode {
755
- constructor(methodName, params, returnType, body) {
756
- super();
757
- this.methodName = methodName;
758
- this.params = params;
759
- this.returnType = returnType;
760
- this.body = body;
761
- this._modifiers = new MethodModifiers();
762
- this.mergeImport(...params, ...body);
763
- if (isCode(returnType)) this.mergeImport(returnType);
764
- }
765
- modifiers(modifiers) {
766
- this._modifiers = modifiers;
767
- return this;
768
- }
769
- importFrom(from) {
770
- this.addImport([this.methodName], from);
771
- return this;
772
- }
773
- toTsString() {
774
- const params = this.params.map((it) => it.toString()).join(",");
775
- return this._modifiers.toString() + `${this.methodName}(${params}): ${this.returnType}{${this.body.map((it) => it.toString()).join("")}}\n`;
776
- }
777
- };
778
- //#endregion
779
- //#region src/tsg/node/modifier/propertyModifiers.ts
780
- var PropertyModifiers = class extends Modifiers {
781
- accessor(accessor) {
782
- return super.accessor(accessor);
783
- }
784
- private() {
785
- return super.private();
786
- }
787
- protected() {
788
- return super.protected();
789
- }
790
- abstract() {
791
- return super.abstract();
792
- }
793
- readonly() {
794
- return super.readonly();
795
- }
796
- static() {
797
- return super.static();
798
- }
799
- };
800
- //#endregion
801
- //#region src/tsg/node/propertyAssignment.ts
802
- var PropertyAssignment = class extends TsCode {
803
- constructor(key, value) {
804
- super();
805
- this.key = key;
806
- this.value = value;
807
- this.mergeImport(value);
808
- }
809
- toTsString() {
810
- if (!this.value) return this.key;
811
- return `${this.key}: ${this.value.toString()}`;
812
- }
813
- };
814
- //#endregion
815
- //#region src/tsg/node/propertyDeclaration.ts
816
- var PropertyDeclaration = class extends TsCode {
817
- constructor(propertyName, type, optional = false) {
818
- super();
819
- this.propertyName = propertyName;
820
- this.type = type;
821
- this.optional = optional;
822
- this._modifiers = new PropertyModifiers();
823
- this._initializer = void 0;
824
- if (isCode(type)) this.mergeImport(type);
825
- }
826
- modifiers(modifiers) {
827
- this._modifiers = modifiers;
828
- return this;
829
- }
830
- initializer(initializer) {
831
- this._initializer = initializer;
832
- this.mergeImport(initializer);
833
- return this;
834
- }
835
- toTsString() {
836
- const initializer = this._initializer ? ` = ${this._initializer.toString()}` : "";
837
- return this._modifiers.toString() + `${this.propertyName}${TsUtil.questionToken(this.optional)}: ${this.type}` + initializer + ";";
838
- }
839
- };
840
- //#endregion
841
- //#region src/tsg/node/returnStatement.ts
842
- var ReturnStatement = class extends TsStatement {
843
- constructor(expression) {
844
- super();
845
- this.expression = expression;
846
- this.mergeImport(expression);
847
- }
848
- toTsString() {
849
- return `return ${this.expression.toString()};`;
850
- }
851
- };
852
- //#endregion
853
- //#region src/tsg/node/spreadAssignment.ts
854
- var SpreadAssignment = class extends TsCode {
855
- constructor(identifier) {
856
- super();
857
- this.identifier = identifier;
858
- this.mergeImport(identifier);
859
- }
860
- toTsString() {
861
- return `...${this.identifier.toString()}`;
862
- }
863
- };
864
- //#endregion
865
- //#region src/tsg/node/throwStatement.ts
866
- var ThrowStatement = class extends TsStatement {
867
- constructor(expression) {
868
- super();
869
- this.expression = expression;
870
- this.mergeImport(expression);
871
- }
872
- toTsString() {
873
- return "throw " + this.expression.toString() + ";";
874
- }
875
- };
876
- //#endregion
877
- //#region src/tsg/node/type/arrayType.ts
878
- var ArrayType = class extends TsCode {
879
- constructor(type) {
880
- super();
881
- this.type = type;
882
- if (isCode(type)) this.mergeImport(type);
883
- }
884
- toTsString() {
885
- return `Array<${this.type.toString()}>`;
886
- }
887
- };
888
- //#endregion
889
- //#region src/tsg/node/type/intersectionType.ts
890
- var IntersectionType = class extends TsCode {
891
- constructor(...types) {
892
- super();
893
- this.types = types;
894
- this.mergeImport(...types);
895
- }
896
- toTsString() {
897
- return this.types.map((it) => it.toString()).join(" & ");
898
- }
899
- };
900
- //#endregion
901
- //#region src/tsg/node/type/typeAliasDeclaration.ts
902
- var TypeAliasDeclaration = class extends ExportableDeclaration {
903
- constructor(alias, type) {
904
- super();
905
- this.alias = alias;
906
- this.type = type;
907
- if (isCode(type)) this.mergeImport(type);
908
- }
909
- toTsString() {
910
- return `type ${this.alias} = ${this.type.toString()}`;
911
- }
912
- };
913
- //#endregion
914
- //#region src/tsg/node/type/typeLiteral.ts
915
- var TypeLiteral = class extends TsCode {
916
- constructor(properties = []) {
917
- super();
918
- this.properties = properties;
919
- this.mergeImport(...properties);
920
- }
921
- addProperty(propertyName, type, isOptional = false, isReadOnly = false) {
922
- this.properties.push(new PropertySignature(propertyName, type, isOptional, isReadOnly));
923
- return this;
924
- }
925
- toTsString() {
926
- return `{${this.properties.map((it) => it.toString()).join(";")}}`;
927
- }
928
- };
929
- //#endregion
930
- //#region src/tsg/node/type/typeReference.ts
931
- var TypeReference = class TypeReference extends TsCode {
932
- constructor(typeName, typeArguments = []) {
933
- super();
934
- this.typeName = typeName;
935
- this.typeArguments = typeArguments;
936
- this.mergeImport(...pickCode(typeArguments));
937
- }
938
- importFrom(path) {
939
- this.addImport([this.typeName], path);
940
- return this;
941
- }
942
- partial() {
943
- return new TypeReference("Partial", [this]);
944
- }
945
- pick(...properties) {
946
- return new TypeReference("Pick", [this, new Identifier(properties.map((it) => `'${it}'`).join("|"))]);
947
- }
948
- toTsString() {
949
- const typeArgs = this.typeArguments.length === 0 ? "" : `<${this.typeArguments.join(",")}>`;
950
- return `${this.typeName}${typeArgs}`;
951
- }
952
- };
953
- //#endregion
954
- //#region src/tsg/node/type/unionType.ts
955
- var UnionType = class extends TsCode {
956
- constructor(...types) {
957
- super();
958
- this.types = types;
959
- const codeTypes = types.filter((it) => isCode(it));
960
- this.mergeImport(...codeTypes);
961
- }
962
- toTsString() {
963
- return this.types.map((it) => it.toString()).join(" | ");
964
- }
965
- };
966
- //#endregion
967
- //#region src/tsg/node/variableDeclaration.ts
968
- var VariableDeclaration = class extends ExportableDeclaration {
969
- constructor(flag, variableName, expression, type) {
970
- super();
971
- this.flag = flag;
972
- this.expression = expression;
973
- this.type = type;
974
- this.variableName = typeof variableName === "string" ? new Identifier(variableName) : variableName;
975
- this.mergeImport(expression, this.variableName, type);
976
- }
977
- toTsString() {
978
- const type = this.type ? ": " + this.type.toString() : "";
979
- return `${this.flag} ${this.variableName}${type} = ${this.expression.toString()};`;
980
- }
981
- };
982
- //#endregion
983
- //#region src/tsg/factory.ts
984
- const createFactory = (Constructor) => {
985
- return (...args) => new Constructor(...args);
986
- };
987
- const expressions = {
988
- arrowFunc: createFactory(ArrowFunction),
989
- async: createFactory(AsyncExpression),
990
- await: createFactory(AwaitExpression),
991
- binary: createFactory(BinaryExpression),
992
- call: createFactory(CallExpression),
993
- identifier: createFactory(Identifier),
994
- new: createFactory(NewExpression),
995
- nonNull: createFactory(NonNullExpression),
996
- parenthesis: createFactory(ParenthesizedExpression),
997
- propertyAccess: createFactory(PropertyAccessExpression),
998
- string: createFactory(StringLiteral),
999
- number: createFactory(NumericLiteral),
1000
- boolean: createFactory(Boolean),
1001
- array: createFactory(ArrayLiteral),
1002
- object: createFactory(ObjectLiteral),
1003
- as: createFactory(AsExpression),
1004
- ternary: createFactory(TernaryExpression)
1005
- };
1006
- const types = {
1007
- arrayType: createFactory(ArrayType),
1008
- intersectionType: createFactory(IntersectionType),
1009
- unionType: createFactory(UnionType),
1010
- typeAlias: createFactory(TypeAliasDeclaration),
1011
- typeLiteral: createFactory(TypeLiteral),
1012
- typeRef: createFactory(TypeReference)
1013
- };
1014
- const others = {
1015
- block: createFactory(Block),
1016
- class: createFactory(Class),
1017
- enum: createFactory(EnumDeclaration),
1018
- enumMember: createFactory(EnumMember),
1019
- ExpStatement: createFactory(ExpressionStatement),
1020
- extends: createFactory(ExtendsClause),
1021
- if: createFactory(IfStatement),
1022
- implements: createFactory(ImplementsClause),
1023
- interface: createFactory(TsInterface),
1024
- method: createFactory(MethodDeclaration),
1025
- parameter: createFactory(Parameter),
1026
- propertyAssign: createFactory(PropertyAssignment),
1027
- propertyDeclaration: createFactory(PropertyDeclaration),
1028
- propertySignature: createFactory(PropertySignature),
1029
- return: createFactory(ReturnStatement),
1030
- spreadAssign: createFactory(SpreadAssignment),
1031
- variable: createFactory(VariableDeclaration),
1032
- methodModifiers: createFactory(MethodModifiers),
1033
- propertyModifiers: createFactory(PropertyModifiers),
1034
- throw: createFactory(ThrowStatement),
1035
- spread: createFactory(SpreadElement)
1036
- };
1037
- const tsg = {
1038
- ...expressions,
1039
- ...types,
1040
- ...others
1041
- };
1042
- //#endregion
1043
- //#region src/tsg/file.ts
1044
- var TsFile = class extends TsCode {
1045
- constructor(...statements) {
1046
- super();
1047
- this.esLintDisabled = false;
1048
- this.mergeImport(...statements);
1049
- this.statements = statements;
1050
- }
1051
- toTsString() {
1052
- const string = [...this.resolveImport(this.importDeclarations), ...this.statements].map((it) => it.toString()).join("\n");
1053
- return (this.esLintDisabled ? "/* eslint-disable */\n" : "") + string;
1054
- }
1055
- resolveImport(imports) {
1056
- const map = {};
1057
- imports.forEach((it) => {
1058
- if (!map[it.module]) map[it.module] = it.types;
1059
- else map[it.module] = [...map[it.module], ...it.types];
1060
- });
1061
- return Object.entries(map).map(([module, types]) => new ImportDeclaration([...new Set(types)], module));
1062
- }
1063
- disableEsLint() {
1064
- this.esLintDisabled = true;
1065
- return this;
1066
- }
1067
- enableEsLint() {
1068
- this.esLintDisabled = false;
1069
- return this;
1070
- }
1071
- async generate() {
1072
- return this.toString();
1073
- }
1074
- };
1075
- //#endregion
1076
- //#region src/tsg/node/type/typeKeyword.ts
1077
- const KeywordTypeNode = {
1078
- any: new TypeReference("any"),
1079
- unknown: new TypeReference("unknown"),
1080
- number: new TypeReference("number"),
1081
- bigInt: new TypeReference("BigInt"),
1082
- boolean: new TypeReference("boolean"),
1083
- string: new TypeReference("string"),
1084
- symbol: new TypeReference("Symbol"),
1085
- this: new TypeReference("this"),
1086
- void: new TypeReference("void"),
1087
- undefined: new TypeReference("undefined"),
1088
- null: new TypeReference("null"),
1089
- never: new TypeReference("never")
1090
- };
1091
- //#endregion
1092
- //#region src/generatorv2/directory.ts
1093
- const GeneratedDirName = "__generated__";
1094
- const EntityDirName = "entities";
1095
- const DataSourceDirName = "dataSources";
1096
- const relative = (from, to) => {
1097
- const result = node_path.posix.relative(from, to);
1098
- if (result.startsWith("../")) return result;
1099
- return "./" + result;
1100
- };
1101
- const GENERATED_PATH = `/${GeneratedDirName}/`;
1102
- const paths = {
1103
- BASE: "/",
1104
- GENERATED: GENERATED_PATH,
1105
- ENTITIES: `${GENERATED_PATH}${EntityDirName}/`,
1106
- DATA_SOURCES: `/${DataSourceDirName}/db/`,
1107
- GENERATED_DS: `${GENERATED_PATH}${DataSourceDirName}/db/`
1108
- };
1109
- const resolve = (from, source, fileName) => {
1110
- return relative(paths[from], paths[source] + fileName);
1111
- };
1112
- const Directory = {
1113
- paths,
1114
- resolve
1115
- };
1116
- //#endregion
1117
- //#region src/generatorv2/codegen/ts/scripts/getEntityTypeRefs.ts
1118
- const typeRefs = {
1119
- entity: {
1120
- name: (entity) => entity.name,
1121
- dir: "ENTITIES",
1122
- file: (entity) => entity.name
1123
- },
1124
- creatable: {
1125
- name: (entity) => entity.creatableInterface(),
1126
- dir: "ENTITIES",
1127
- file: (entity) => entity.name
1128
- },
1129
- updatable: {
1130
- name: (entity) => entity.updatable(),
1131
- dir: "ENTITIES",
1132
- file: (entity) => entity.name
1133
- },
1134
- identifiable: {
1135
- name: (entity) => entity.identifiableInterfaceName(),
1136
- dir: "ENTITIES",
1137
- file: (entity) => entity.name
1138
- },
1139
- fields: {
1140
- name: (entity) => entity.fieldsTypeName(),
1141
- dir: "GENERATED",
1142
- file: () => "fields"
1143
- },
1144
- withRelation: {
1145
- name: (entity) => entity.entityWithRelationTypeName(),
1146
- dir: "GENERATED",
1147
- file: () => "relationMap"
1148
- },
1149
- result: {
1150
- name: (entity) => entity.resultType(),
1151
- dir: "GENERATED",
1152
- file: () => "relationMap"
1153
- }
1154
- };
1155
- const makeTypeRef = (entity, type, importFrom) => {
1156
- const info = typeRefs[type];
1157
- return tsg.typeRef(info.name(entity)).importFrom(Directory.resolve(importFrom, info.dir, info.file(entity)));
1158
- };
1159
- const makeContextTypeRef = (importFrom) => {
1160
- return tsg.typeRef("GQLContext").importFrom(Directory.resolve(importFrom, "BASE", "context"));
1161
- };
1162
- //#endregion
1163
- //#region src/generatorv2/codegen/ts/scripts/sqlValueToTsExpression.ts
1164
- const sqlValueToTsExpression = (value) => {
1165
- if (typeof value === "string") return tsg.string(value);
1166
- if (typeof value === "number") return tsg.number(value);
1167
- return tsg.identifier("null");
1168
- };
1169
- //#endregion
1170
- //#region src/generatorv2/codegen/ts/generateAutoGeneratedDatasource.ts
1171
- const DIR$2 = "GENERATED_DS";
1172
- const generateAutoGeneratedDatasource = (node) => {
1173
- return new TsFile(tsg.typeAlias("QueryResult", tsg.intersectionType(makeTypeRef(node.name, "withRelation", DIR$2).partial(), makeTypeRef(node.name, "identifiable", DIR$2))), tsg.class(node.name.generatedDataSourceName()).export().abstract().extends(tsg.extends(tsg.typeRef("BaseDBDataSource", [
1174
- makeTypeRef(node.name, "entity", DIR$2),
1175
- makeTypeRef(node.name, "identifiable", DIR$2),
1176
- makeTypeRef(node.name, "creatable", DIR$2),
1177
- makeTypeRef(node.name, "updatable", DIR$2),
1178
- makeTypeRef(node.name, "fields", DIR$2),
1179
- tsg.typeRef("QueryResult")
1180
- ])).addImport(["BaseDBDataSource"], Directory.resolve(DIR$2, "BASE", "baseDBDataSource"))).addProperty(...makeClassProperties(node)).addMethod(makeDefaultValueMethod(node), ...makeFindMethods(node))).disableEsLint();
1181
- };
1182
- const makeClassProperties = (node) => {
1183
- const ai = node.fields.find((it) => it.isAutoIncrement);
1184
- return [
1185
- tsg.propertyDeclaration("tableName", KeywordTypeNode.string, false).modifiers(tsg.propertyModifiers().readonly()).initializer(tsg.string(node.tableName)),
1186
- tsg.propertyDeclaration("fields", tsg.arrayType(KeywordTypeNode.string), false).modifiers(tsg.propertyModifiers().readonly()).initializer(tsg.array(node.fields.map((it) => tsg.string(it.fieldName)))),
1187
- tsg.propertyDeclaration("primaryKeys", tsg.arrayType(KeywordTypeNode.string), false).modifiers(tsg.propertyModifiers().readonly().protected()).initializer(tsg.array(node.identifyKeys.map((it) => tsg.string(it)))),
1188
- tsg.propertyDeclaration("identifyFields", tsg.arrayType(KeywordTypeNode.string), false).modifiers(tsg.propertyModifiers().readonly().protected()).initializer(tsg.array(node.identifyKeys.map((it) => node.fields.find((f) => it === f.columnName).fieldName).map(tsg.string))),
1189
- tsg.propertyDeclaration("autoIncrementColumn", tsg.unionType(KeywordTypeNode.string, KeywordTypeNode.undefined), true).modifiers(tsg.propertyModifiers().readonly().protected()).initializer(ai ? tsg.string(ai.fieldName) : tsg.identifier("undefined"))
1190
- ];
1191
- };
1192
- const fieldToExpression = (node) => {
1193
- if (node.column.defaultCurrentTimeStamp) return tsg.identifier("getCurrentDateTimeString").addImport(["getCurrentDateTimeString"], "sasat").call();
1194
- return sqlValueToTsExpression(node.column.default);
1195
- };
1196
- const makeDefaultValueMethod = (node) => {
1197
- const columns = node.fields.filter((it) => it.column.defaultCurrentTimeStamp || it.column.default !== void 0);
1198
- const properties = columns.map((it) => {
1199
- return tsg.propertyAssign(it.fieldName, fieldToExpression(it));
1200
- });
1201
- const body = tsg.return(tsg.object(...properties));
1202
- return tsg.method("getDefaultValueString", [], columns.length !== 0 ? tsg.typeRef(node.name.name).pick(...columns.map((it) => it.fieldName)) : tsg.typeRef(node.name.name).partial(), [body]).modifiers(tsg.methodModifiers().protected());
1203
- };
1204
- const makeFindMethods = (node) => {
1205
- const qExpr = tsg.identifier("qe").importFrom("sasat");
1206
- return node.findMethods.map((it) => {
1207
- const bve = it.params.flatMap((it) => {
1208
- if (!it.entity) return qExpr.property("eq").call(qExpr.property("field").call(tsg.identifier("tableName"), tsg.string(it.columnName.toString())), qExpr.property("value").call(tsg.identifier(it.fieldName.toString())));
1209
- return it.fields.map((field) => {
1210
- return qExpr.property("eq").call(qExpr.property("field").call(tsg.identifier("tableName"), tsg.string(field.columnName)), qExpr.property("value").call(tsg.identifier(it.name).property(field.fieldName)));
1211
- });
1212
- });
1213
- const body = [tsg.variable("const", "tableName", tsg.identifier("fields?.tableAlias || \"t0\"")), tsg.return(tsg.identifier(it.isArray ? "this.find" : "this.first").call(tsg.identifier("fields"), tsg.object().addProperties(tsg.spreadAssign(tsg.identifier("options")), tsg.propertyAssign("where", qExpr.property("and").call(...bve, tsg.identifier("options?").property("where")))), tsg.identifier("context")))];
1214
- const returnType = tsg.typeRef("QueryResult");
1215
- return tsg.method(it.name, [
1216
- ...it.params.map((it) => tsg.parameter(it.entity ? it.name.toString() : it.fieldName, it.entity ? makeTypeRef(it.entityName, "identifiable", "GENERATED_DS") : tsg.typeRef(columnTypeToTsType(it.dbtype)))),
1217
- tsg.parameter(`fields?`, makeTypeRef(node.name, "fields", DIR$2)),
1218
- tsg.parameter("options?", it.isArray ? tsg.typeRef("QueryOptions").importFrom("sasat") : tsg.typeRef("Omit", [tsg.typeRef("QueryOptions").importFrom("sasat"), tsg.typeRef("\"offset\" | \"limit\" | \"sort\"")])),
1219
- tsg.parameter("context?", makeContextTypeRef(DIR$2))
1220
- ], tsg.typeRef("Promise", [it.isArray ? tsg.arrayType(returnType) : tsg.unionType(returnType, tsg.typeRef("null"))]), body);
1221
- });
1222
- };
1223
- //#endregion
1224
- //#region src/generatorv2/codegen/ts/generateContext.ts
1225
- const generateContext = (root) => {
1226
- return new TsFile(tsg.interface("BaseGQLContext").addProperties(root.contexts.map((it) => tsg.propertySignature(it.name, tsg.typeRef(columnTypeToTsType(it.dbtype))))).export()).disableEsLint();
1227
- };
1228
- //#endregion
1229
- //#region src/generatorv2/codegen/ts/generateDatasource.ts
1230
- const generateDatasource = (node) => {
1231
- return new TsFile(tsg.class(node.name.dataSourceName()).extends(tsg.extends(tsg.typeRef(node.name.generatedDataSourceName()).importFrom(Directory.resolve("DATA_SOURCES", "GENERATED_DS", node.name.name)))).export());
1232
- };
1233
- //#endregion
1234
- //#region src/generatorv2/codegen/ts/scripts/fieldToProperty.ts
1235
- const fieldToPropertySignature = (field) => {
1236
- const type = tsg.typeRef(columnTypeToTsType(field.dbType));
1237
- return tsg.propertySignature(field.fieldName, field.isNullable ? tsg.unionType(type, KeywordTypeNode.null) : type, field.isNullable, true);
1238
- };
1239
- //#endregion
1240
- //#region src/generatorv2/codegen/ts/generateEntity.ts
1241
- const generateEntityFile = (node) => {
1242
- return new TsFile(generateEntity(node), generateCreatable(node), generateUpdatable(node), generateIdentifiable(node)).disableEsLint();
1243
- };
1244
- const generateEntity = (node) => {
1245
- return tsg.typeAlias(node.name.name, tsg.typeLiteral(node.fields.map(fieldToPropertySignature))).export();
1246
- };
1247
- const generateCreatable = (node) => {
1248
- return tsg.typeAlias(node.name.creatableInterface(), node.creatable.fields.length === 0 ? tsg.typeRef("Record<string, never>") : tsg.typeLiteral(node.creatable.fields.map(fieldToPropertySignature))).export();
1249
- };
1250
- const generateUpdatable = (node) => {
1251
- return tsg.typeAlias(node.name.updatable(), node.updateInput.fields.length === 0 ? tsg.typeRef("Record<string, never>") : tsg.typeLiteral(node.updateInput.fields.map(fieldToPropertySignature))).export();
1252
- };
1253
- const generateIdentifiable = (node) => {
1254
- return tsg.typeAlias(node.name.identifiableInterfaceName(), tsg.typeLiteral(node.fields.filter((it) => it.isPrimary).map(fieldToPropertySignature))).export();
1255
- };
1256
- //#endregion
1257
- //#region src/util/stringUtil.ts
1258
- const capitalizeFirstLetter = (str) => str.slice(0, 1).toUpperCase() + str.slice(1);
1259
- const lowercaseFirstLetter = (str) => str.slice(0, 1).toLowerCase() + str.slice(1);
1260
- const camelize = (str) => str.replace(/(?:^\w|[A-Z]|_\w|\b\w)/g, (word, index) => index === 0 ? word.toLowerCase() : word.toUpperCase()).replace(/\s|_|-+/g, "");
1261
- //#endregion
1262
- //#region src/generatorv2/nodes/entityName.ts
1263
- var EntityName = class EntityName {
1264
- static fromTableName(tableName) {
1265
- return new EntityName(capitalizeFirstLetter(camelize(tableName)));
1266
- }
1267
- constructor(name) {
1268
- this.name = name;
1269
- }
1270
- toString() {
1271
- return this.name;
1272
- }
1273
- creatableInterface() {
1274
- return `${this.name}Creatable`;
1275
- }
1276
- updatable() {
1277
- return `${this.name}Updatable`;
1278
- }
1279
- identifiableInterfaceName() {
1280
- return `${this.name}Identifiable`;
1281
- }
1282
- relationTypeName() {
1283
- return this.name + "Relations";
1284
- }
1285
- entityWithRelationTypeName() {
1286
- return this.name + "WithRelations";
1287
- }
1288
- resultType() {
1289
- return this.name + "Result";
1290
- }
1291
- fieldsTypeName() {
1292
- return this.name + "Fields";
1293
- }
1294
- dataSourceName() {
1295
- return `${this.name}DBDataSource`;
1296
- }
1297
- generatedDataSourceName() {
1298
- return `Generated${this.name}DBDataSource`;
1299
- }
1300
- lowerCase() {
1301
- return lowercaseFirstLetter(this.name);
1302
- }
1303
- createInputName() {
1304
- return this.name + "CreateInput";
1305
- }
1306
- updateInputName() {
1307
- return this.name + "UpdateInput";
1308
- }
1309
- identifyInputName() {
1310
- return `${this.name}IdentifyInput`;
1311
- }
1312
- IDEncoderName() {
1313
- return `${this.name}HashId`;
1314
- }
1315
- };
1316
- //#endregion
1317
- //#region src/generatorv2/codegen/ts/generateFields.ts
1318
- const generateFields = (root) => {
1319
- return new TsFile(...root.entities.map((it) => tsg.typeAlias(it.name.fieldsTypeName(), tsg.typeRef("Fields", [makeTypeRef(it.name, "entity", "GENERATED"), makeTypeLiteral(it)]).importFrom("sasat")).export())).disableEsLint();
1320
- };
1321
- const makeTypeLiteral = (entity) => {
1322
- return tsg.typeLiteral([...entity.references.map((it) => tsg.propertySignature(`${it.fieldName}?`, tsg.typeRef(EntityName.fromTableName(it.parentTableName).fieldsTypeName()))), ...entity.referencedBy.map((it) => tsg.propertySignature(`${it.fieldName}?`, tsg.typeRef(EntityName.fromTableName(it.childTable).fieldsTypeName())))]);
1323
- };
1324
- //#endregion
1325
- //#region src/runtime/util.ts
1326
- const pick = (target, keys) => Object.fromEntries(keys.map((key) => [key, target[key]]));
1327
- const unique = (array) => {
1328
- const result = [];
1329
- for (let i = 0, l = array.length; i < l; i += 1) if (!result.includes(array[i])) result.push(array[i]);
1330
- return result;
1331
- };
1332
- const nonNullable = (value) => value != null;
1333
- //#endregion
1334
- //#region src/generatorv2/codegen/ts/scripts/ast/getExportedVariables.ts
1335
- const { SyntaxKind: SyntaxKind$1 } = typescript.default;
1336
- const getExportedVariables = (sourceFile) => {
1337
- return sourceFile.statements.filter((it) => it.kind === SyntaxKind$1.VariableStatement && it.modifiers?.some((it) => it.kind === SyntaxKind$1.ExportKeyword));
1338
- };
1339
- //#endregion
1340
- //#region src/generatorv2/codegen/ts/scripts/ast/isImported.ts
1341
- const { SyntaxKind } = typescript.default;
1342
- const isImported = (sourceFile, type, paths) => {
1343
- return sourceFile.statements.filter((it) => it.kind === SyntaxKind.ImportDeclaration).some((it) => {
1344
- if (!paths.some((path) => {
1345
- const text = it.moduleSpecifier.getText(sourceFile);
1346
- return `'${path}'` === text || `"${path}"` === text;
1347
- })) return false;
1348
- const binding = it.importClause?.namedBindings;
1349
- if (it.importClause?.name?.getText(sourceFile) === type) return true;
1350
- if (binding?.kind !== SyntaxKind.NamedImports) return false;
1351
- return binding.elements.some((it) => {
1352
- return it.name.text.trim() === type;
1353
- });
1354
- });
1355
- };
1356
- //#endregion
1357
- //#region src/generatorv2/codegen/ts/generateIDEncoder.ts
1358
- const { createSourceFile: createSourceFile$2, ScriptTarget: ScriptTarget$2 } = typescript.default;
1359
- const hashIds = "HashIds";
1360
- const generateIDEncoder = (root, content) => {
1361
- const fields = root.entities.map((it) => it.fields.find((it) => it.column.option.autoIncrementHashId)).filter(nonNullable);
1362
- if (fields.length === 0) return null;
1363
- const sourceFile = createSourceFile$2(tsFileNames.encoder + ".ts", content, ScriptTarget$2.ESNext);
1364
- sourceFile.getChildren().map((it) => it);
1365
- const exportedVariables = getExportedVariables(sourceFile);
1366
- const hashIdImported = isImported(sourceFile, hashIds, ["hashids"]);
1367
- const statements = [];
1368
- fields.forEach((field) => {
1369
- const name = field.entity.name.IDEncoderName();
1370
- if (exportedVariables.some((it) => {
1371
- return it.declarationList.declarations[0].name.getText(sourceFile) === name;
1372
- })) return;
1373
- statements.push(tsg.variable("const", name, tsg.identifier("makeNumberIdEncoder").call(tsg.new(tsg.identifier(hashIds), tsg.string(field.column.option.hashSalt || field.entity.name.name)))).export());
1374
- });
1375
- const imports = hashIdImported ? "" : "import HashIds from \"hashids\";\n";
1376
- const makeEncoder = isImported(sourceFile, "makeNumberIdEncoder", ["sasat"]) ? "" : new ImportDeclaration(["makeNumberIdEncoder"], "sasat").toString();
1377
- const addition = statements.length === 0 ? "" : "\n" + new TsFile(...statements).toString();
1378
- return imports + makeEncoder + content + addition;
1379
- };
1380
- //#endregion
1381
- //#region src/generatorv2/codegen/ts/generateMiddlewares.ts
1382
- const { createSourceFile: createSourceFile$1, ScriptTarget: ScriptTarget$1 } = typescript.default;
1383
- const generateMiddlewares = (root, content) => {
1384
- const middlewares = unique(root.entities.flatMap((it) => [...it.queries.flatMap((it) => it.middlewares), ...it.mutations.flatMap((it) => it.middlewares)]));
1385
- if (middlewares.length === 0) return null;
1386
- const sourceFile = createSourceFile$1(tsFileNames.middleware + ".ts", content, ScriptTarget$1.ESNext);
1387
- const exportedVariables = getExportedVariables(sourceFile);
1388
- const statements = [];
1389
- middlewares.forEach((middleware) => {
1390
- if (exportedVariables.some((it) => {
1391
- return it.declarationList.declarations[0].name.getText(sourceFile) === middleware;
1392
- })) return;
1393
- statements.push(tsg.variable("const", middleware, tsg.arrowFunc([tsg.parameter("args")], void 0, tsg.block(tsg.throw(tsg.new(tsg.identifier("Error"), tsg.string("TODO: Not implemented"))), tsg.return(tsg.identifier("args")))), tsg.typeRef("ResolverMiddleware", [tsg.typeRef("GQLContext")])).export());
1394
- });
1395
- const contextImported = isImported(sourceFile, "GQLContext", ["./context", "./context.js"]);
1396
- const resolverMiddlewareImported = isImported(sourceFile, "ResolverMiddleware", ["sasat"]);
1397
- const imports = [contextImported ? "" : new ImportDeclaration(["GQLContext"], "./context").toString() + "\n", resolverMiddlewareImported ? "" : new ImportDeclaration(["ResolverMiddleware"], "sasat").toString() + "\n"].join("");
1398
- const addition = statements.length === 0 ? "" : "\n" + new TsFile(...statements).toString();
1399
- return imports + content + addition;
1400
- };
1401
- //#endregion
1402
- //#region src/generatorv2/codegen/names.ts
1403
- const map = {
1404
- create: "Created",
1405
- update: "Updated",
1406
- delete: "Deleted"
1407
- };
1408
- const publishFunctionName = (entityName, type) => {
1409
- return `publish${entityName}${map[type]}`;
1410
- };
1411
- const makeFindQueryName = (keys) => "findBy" + keys.map(capitalizeFirstLetter).join("And");
1412
- //#endregion
1413
- //#region src/generatorv2/codegen/ts/mutation/makeMutationInputDecoder.ts
1414
- const DIR$1 = "GENERATED";
1415
- const makeMutationMiddlewareAndTypes = (entity) => {
1416
- return entity.mutations.map((node) => makeMutationResolverMiddleware(entity, node));
1417
- };
1418
- const makeParamType = (node) => {
1419
- if (node.mutationType === "create") return makeTypeRef(node.entityName, "creatable", "GENERATED");
1420
- if (node.mutationType === "update") return tsg.intersectionType(makeTypeRef(node.entityName, "identifiable", "GENERATED"), makeTypeRef(node.entityName, "updatable", "GENERATED"));
1421
- return makeTypeRef(node.entityName, "identifiable", "GENERATED");
1422
- };
1423
- const makeEncoder = (name) => tsg.identifier(name).importFrom(Directory.resolve(DIR$1, "BASE", tsFileNames.encoder));
1424
- const makeIdDecodeMiddleware = (fields, node) => {
1425
- const params = tsg.identifier("args[1]");
1426
- const entityName = node.entity.name.lowerCase();
1427
- return tsg.arrowFunc([tsg.parameter("args")], void 0, tsg.block(tsg.binary(params, "=", tsg.object(tsg.spreadAssign(params), tsg.propertyAssign(entityName, tsg.object(tsg.spreadAssign(params.property(entityName)), ...fields.filter((it) => it.hashId).map((it) => tsg.propertyAssign(it.fieldName, makeEncoder(it.hashId.encoder).property("decode").call(params.property(entityName).property(it.fieldName).as(tsg.typeRef("string"))))))))).toStatement(), tsg.return(tsg.identifier("args"))));
1428
- };
1429
- const makeResolverMiddleware = (typeName, entity, fields, node) => {
1430
- const sig = fields.map((it) => tsg.propertySignature(it.fieldName, tsg.typeRef(it.hashId ? "string" : columnTypeToTsType(it.dbType))));
1431
- const requiredType = tsg.typeAlias(typeName, tsg.typeLiteral([tsg.propertySignature(entity.name.lowerCase(), makeParamType(node))]));
1432
- const middlewareName = node.mutationName + "Middleware";
1433
- if (!node.requireIdDecodeMiddleware) return [requiredType, tsg.variable("const", middlewareName, tsg.array(node.middlewares.map((it) => tsg.identifier(it).importFrom("../" + tsFileNames.middleware))), tsg.arrayType(tsg.typeRef("ResolverMiddleware", [makeContextTypeRef(DIR$1), tsg.identifier(typeName)]).importFrom("sasat")))];
1434
- return [
1435
- tsg.typeAlias("GQL" + typeName, tsg.typeLiteral([tsg.propertySignature(entity.name.lowerCase(), tsg.typeLiteral(sig))])),
1436
- requiredType,
1437
- tsg.variable("const", node.mutationName + "Middleware", tsg.array([makeIdDecodeMiddleware(fields, node), ...node.middlewares.map((it) => tsg.identifier(it).importFrom("../" + tsFileNames.middleware))]), tsg.arrayType(tsg.typeRef("ResolverMiddleware", [
1438
- makeContextTypeRef(DIR$1),
1439
- tsg.identifier(typeName),
1440
- tsg.identifier("GQL" + typeName)
1441
- ]).importFrom("sasat")))
1442
- ];
1443
- };
1444
- const makeMutationResolverMiddleware = (entity, node) => {
1445
- switch (node.mutationType) {
1446
- case "create": return makeResolverMiddleware(entity.name.createInputName(), entity, entity.creatable.fields, node);
1447
- case "update": return makeResolverMiddleware(entity.name.updateInputName(), entity, entity.updateInput.fields, node);
1448
- case "delete": return makeResolverMiddleware(entity.name.identifyInputName(), entity, entity.identifyFields(), node);
1449
- }
1450
- };
1451
- //#endregion
1452
- //#region src/generatorv2/codegen/ts/scripts/makeDatasource.ts
1453
- const makeDatasource = (entity, importFrom, args) => {
1454
- return tsg.new(tsg.identifier(entity.dataSourceName()).importFrom(Directory.resolve(importFrom, "DATA_SOURCES", entity.name)), ...args || []);
1455
- };
1456
- //#endregion
1457
- //#region src/generatorv2/codegen/ts/generateMutationResolver.ts
1458
- const generateMutationResolver = (root) => {
1459
- return new TsFile(...root.entities.flatMap(makeMutationMiddlewareAndTypes).flat(), tsg.variable("const", "mutation", tsg.object(...root.entities.flatMap((it) => it.mutations).map(makeMutation$1))).export()).disableEsLint();
1460
- };
1461
- const result = tsg.identifier("result");
1462
- const refetched = tsg.identifier("fetched");
1463
- const ds = tsg.identifier("ds");
1464
- const ident$1 = tsg.identifier("identifiable");
1465
- const makeMutation$1 = (node) => {
1466
- return tsg.propertyAssign(node.mutationName, makeResolver$2.call(tsg.arrowFunc(makeResolverArgs(node), void 0, makeMutationBody(node)).toAsync(), tsg.identifier(node.mutationName + "Middleware")).typeArgs(...[
1467
- context,
1468
- tsg.typeRef(node.inputName),
1469
- node.requireIdDecodeMiddleware ? tsg.typeRef("GQL" + node.inputName) : null
1470
- ].filter(nonNullable)));
1471
- };
1472
- const makeMutationBody = (node) => {
1473
- if (node.mutationType === "create") return makeCreateMutationBody(node);
1474
- if (node.mutationType === "update") return makeUpdateMutationBody(node);
1475
- return makeDeleteMutationBody(node);
1476
- };
1477
- const makeResolver$2 = tsg.identifier("makeResolver").importFrom("sasat");
1478
- const context = tsg.typeRef("GQLContext").importFrom(Directory.resolve("GENERATED", "BASE", "context"));
1479
- const makeResolverArgs = (node) => [
1480
- tsg.parameter("_"),
1481
- tsg.parameter(`{${node.entityName.lowerCase()}}`),
1482
- node.contextFields.length === 0 ? null : tsg.parameter("context")
1483
- ].filter(nonNullable);
1484
- const makeCreateMutationBody = (node) => {
1485
- const entity = tsg.identifier(node.entityName.lowerCase());
1486
- const dsVariable = tsg.variable("const", ds, makeDatasource(node.entityName, "GENERATED"));
1487
- const createCall = ds.property("create").call(entity);
1488
- if (!node.subscription && !node.refetch) return tsg.block(dsVariable, tsg.return(createCall));
1489
- if (!node.refetch) return tsg.block(dsVariable, tsg.variable("const", result, tsg.await(createCall)), node.subscription ? makePublishCall(node, result) : null, tsg.return(result));
1490
- return tsg.block(dsVariable, tsg.variable("const", result, tsg.await(createCall)), ...makeRefetched(node), node.subscription ? makePublishCall(node, refetched) : null, tsg.return(refetched));
1491
- };
1492
- const makeRefetched = (node) => {
1493
- return [tsg.variable("const", ident$1, tsg.identifier("pick").importFrom("sasat").call(node.mutationType === "create" ? result : tsg.identifier(node.entityName.lowerCase()), tsg.array(node.identifyFields.map(tsg.string))).as(tsg.typeRef("unknown")).as(makeTypeRef(node.entityName, "identifiable", "GENERATED"))), tsg.variable("const", refetched, tsg.await(ds.property(makeFindQueryName(node.identifyFields)).call(...node.identifyFields.map((it) => ident$1.property(it)))))];
1494
- };
1495
- const makePublishCall = (node, identifier) => {
1496
- return tsg.await(tsg.identifier(publishFunctionName(node.entityName, node.mutationType)).importFrom("./subscription").call(identifier.as(makeTypeRef(node.entityName, "entity", "GENERATED")))).toStatement();
1497
- };
1498
- const makeDatasourceParam = (entity, contextParams) => {
1499
- if (contextParams.length === 0) return entity;
1500
- return tsg.object(tsg.spreadAssign(entity), ...contextParams.map((it) => tsg.propertyAssign(it.fieldName, tsg.identifier(`context.${it.contextName}`))));
1501
- };
1502
- const makeUpdateMutationBody = (node) => {
1503
- const entity = tsg.identifier(node.entityName.lowerCase());
1504
- const statements = [tsg.variable("const", ds, makeDatasource(node.entityName, "GENERATED")), tsg.variable("const", result, tsg.await(ds.property("update").call(makeDatasourceParam(entity, node.contextFields)).property("then").call(tsg.arrowFunc([tsg.parameter("it", tsg.typeRef("CommandResponse").importFrom("sasat"))], KeywordTypeNode.boolean, tsg.binary(tsg.identifier("it.changedRows"), "===", tsg.number(1))))))];
1505
- if (!node.refetch && !node.subscription) return tsg.block(...statements, tsg.return(result));
1506
- return tsg.block(...statements, ...makeRefetched(node), node.subscription ? makePublishCall(node, refetched) : null, tsg.return(node.refetch ? refetched : result));
1507
- };
1508
- const makeDeleteMutationBody = (node) => {
1509
- const entity = tsg.identifier(node.entityName.lowerCase());
1510
- const dsV = tsg.variable("const", ds, makeDatasource(node.entityName, "GENERATED"));
1511
- const deleteCall = ds.property("delete").call(entity).property("then").call(tsg.arrowFunc([tsg.parameter("it", tsg.typeRef("CommandResponse").importFrom("sasat"))], KeywordTypeNode.boolean, tsg.binary(tsg.identifier("it.affectedRows"), "===", new NumericLiteral(1))));
1512
- return tsg.block(dsV, tsg.variable("const", result, tsg.await(deleteCall)), node.subscription ? tsg.if(result, tsg.block(makePublishCall(node, entity))) : null, tsg.return(result));
1513
- };
1514
- //#endregion
1515
- //#region src/cli/console.ts
1516
- const Console = {
1517
- success: (msg) => {
1518
- console.log(chalk.default.green(msg));
1519
- },
1520
- error: (msg) => {
1521
- console.error(chalk.default.bold.red(msg));
1522
- },
1523
- log: (msg) => {
1524
- console.log(msg);
1525
- },
1526
- debug: (msg) => {
1527
- console.debug("debug:: " + msg);
1528
- }
1529
- };
1530
- //#endregion
1531
- //#region src/migration/data/GQLOption.ts
1532
- const defaultGQLOption = () => ({
1533
- enabled: false,
1534
- queries: [],
1535
- mutations: []
1536
- });
1537
- const getArgs = (query, entity) => {
1538
- if (query.type === "primary") return entity.fields.filter((it) => it.isPrimary).map((it) => ({
1539
- kind: "arg",
1540
- name: it.fieldName,
1541
- type: it.gqlType
1542
- }));
1543
- const r = [];
1544
- if (query.type === "list-paging") r.push({
1545
- kind: "arg",
1546
- name: "option",
1547
- type: "PagingOption"
1548
- });
1549
- query.conditions.forEach((it) => {
1550
- if (it.left.kind === "arg") r.push(it.left);
1551
- if (it.kind === "between") {
1552
- if (it.begin.kind === "arg") r.push(it.begin);
1553
- if (it.end.kind === "arg") r.push(it.end);
1554
- } else if (it.right.kind === "arg") r.push(it.right);
1555
- });
1556
- return r;
1557
- };
1558
- //#endregion
1559
- //#region src/tsg/node/rawCodeStatement.ts
1560
- var RawCodeStatement = class extends TsStatement {
1561
- constructor(code) {
1562
- super();
1563
- this.code = code;
1564
- }
1565
- toTsString() {
1566
- return this.code;
1567
- }
1568
- };
1569
- //#endregion
1570
- //#region src/generatorv2/scripts/gqlTypes.ts
1571
- const toTsType = (type) => {
1572
- switch (type) {
1573
- case "Int":
1574
- case "Float": return "number";
1575
- case "ID":
1576
- case "String": return "string";
1577
- case "Boolean": return "boolean";
1578
- default: return type;
1579
- }
1580
- };
1581
- //#endregion
1582
- //#region src/generatorv2/codegen/ts/scripts/makeConditonValueExpr.ts
1583
- const qExpr$3 = tsg.identifier("qe").importFrom("sasat");
1584
- const makeConditionValueRaw = (cv) => {
1585
- const context = tsg.identifier("arg").property("context?");
1586
- switch (cv.kind) {
1587
- case "context": {
1588
- const value = context.property(cv.field);
1589
- if (cv.onNotDefined.action !== "defaultValue") return value;
1590
- return tsg.binary(context.property(cv.field), "||", typeof cv.onNotDefined.value === "string" ? tsg.string(cv.onNotDefined.value) : tsg.number(cv.onNotDefined.value));
1591
- }
1592
- case "fixed": return typeof cv.value === "string" ? tsg.string(cv.value) : tsg.number(cv.value);
1593
- case "today": return tsg.identifier(cv.type === "datetime" ? "getTodayDateTimeString" : "getTodayDateString").importFrom("sasat").call();
1594
- case "now": return tsg.identifier("dateString").importFrom("sasat").call(tsg.new(tsg.identifier("Date")));
1595
- default: throw Error(`not implemented: makeConditionValue.${cv.kind}`);
1596
- }
1597
- };
1598
- const makeConditionValueQExpr = (cv) => {
1599
- const context = tsg.identifier("arg").property("context?");
1600
- switch (cv.kind) {
1601
- case "context": {
1602
- const value = context.property(cv.field);
1603
- if (cv.onNotDefined.action !== "defaultValue") return qExpr$3.property("value").call(value);
1604
- return qExpr$3.property("value").call(tsg.binary(context.property(cv.field), "||", typeof cv.onNotDefined.value === "string" ? tsg.string(cv.onNotDefined.value) : tsg.number(cv.onNotDefined.value)));
1605
- }
1606
- case "fixed": return qExpr$3.property("value").call(typeof cv.value === "string" ? tsg.string(cv.value) : tsg.number(cv.value));
1607
- case "today": return qExpr$3.property("value").call(tsg.identifier(cv.type === "datetime" ? "getTodayDateTimeString" : "getTodayDateString").importFrom("sasat").call());
1608
- case "now": return qExpr$3.property("value").call(tsg.identifier("dateString").importFrom("sasat").call(tsg.new(tsg.identifier("Date"))));
1609
- case "arg": return qExpr$3.property("value").call(tsg.identifier(cv.name));
1610
- case "field": return qExpr$3.property("field").call(tsg.string("t0"), tsg.string(cv.column));
1611
- }
1612
- };
1613
- //#endregion
1614
- //#region src/generatorv2/codegen/ts/scripts/makeQueryConditionExpr.ts
1615
- const qExpr$2 = tsg.identifier("qe").importFrom("sasat");
1616
- const makeQueryConditionExpr = (condition) => {
1617
- if (condition.kind === "between") return qExpr$2.property("between").call(makeConditionValueQExpr(condition.left), makeConditionValueQExpr(condition.begin), makeConditionValueQExpr(condition.end));
1618
- return qExpr$2.property("comparison").call(makeConditionValueQExpr(condition.left), tsg.string(condition.operator), makeConditionValueQExpr(condition.right));
1619
- };
1620
- //#endregion
1621
- //#region src/generatorv2/codegen/ts/generateQueryResolver.ts
1622
- const DIR = "GENERATED";
1623
- const generateQueryResolver = (root) => {
1624
- return new TsFile(tsg.variable("const", "query", tsg.object(...root.entities.flatMap((entity) => entity.queries.map((query) => makeGQLQuery(entity, query))).filter(nonNullable))).export()).disableEsLint();
1625
- };
1626
- const makeResolver$1 = () => tsg.identifier("makeResolver").importFrom("sasat");
1627
- const makeGQLQuery = (entity, query) => {
1628
- if (!entity.gqlEnabled) {
1629
- Console.log(`Query.${query.name || entity.name.lowerCase()} generation skipped. Reason: Entity:${entity.name.name} is not Open to GQL.`);
1630
- return null;
1631
- }
1632
- const args = getArgs(query, entity);
1633
- return tsg.propertyAssign(query.type === "primary" ? entity.name.lowerCase() : query.name, makeResolver$1().call(...[tsg.arrowFunc([
1634
- tsg.parameter("_"),
1635
- tsg.parameter(`{${args.map((it) => it.name).join(",")}}`),
1636
- tsg.parameter("context"),
1637
- tsg.parameter("info")
1638
- ], void 0, makeGQLQueryBody(entity, query)).toAsync(), makeMiddlewares(entity, query)].filter(nonNullable)).typeArgs(...makeTypeArgs(args)));
1639
- };
1640
- const getHashIdArgs = (entity, query) => {
1641
- if (query.type === "primary") {
1642
- const hashIDs = entity.identifyFields().filter((it) => it.option.autoIncrementHashId);
1643
- if (hashIDs.length === 0) return null;
1644
- return hashIDs.map((it) => ({
1645
- encoder: it.hashId.encoder,
1646
- name: it.fieldName
1647
- }));
1648
- }
1649
- const getHashIdArg = (arg, field) => {
1650
- const columnName = field.column;
1651
- const hashIdOpt = entity.fields.find((e) => e.columnName === columnName)?.hashId;
1652
- if (!hashIdOpt) return null;
1653
- return {
1654
- name: arg.name,
1655
- encoder: hashIdOpt.encoder
1656
- };
1657
- };
1658
- return query.conditions.map((it) => {
1659
- if (it.kind === "comparison") {
1660
- if (it.left.kind === "arg") {
1661
- if (it.right.kind === "field") return getHashIdArg(it.left, it.right);
1662
- }
1663
- if (it.right.kind === "arg") {
1664
- if (it.left.kind === "field") return getHashIdArg(it.right, it.left);
1665
- }
1666
- }
1667
- return null;
1668
- }).filter(nonNullable);
1669
- };
1670
- const makeHashIdMiddleware = (entity, query) => {
1671
- const args = getHashIdArgs(entity, query);
1672
- if (!args || args?.length === 0) return null;
1673
- return tsg.arrowFunc([tsg.parameter("args")], void 0, tsg.block(new RawCodeStatement(`args[1] = {...args[1], ${args.map((it) => `${it.name}: ${it.encoder}.decode(args[1].${it.name} as string),`).join("")}};`).addImport(args.map((it) => it.encoder), Directory.resolve(DIR, "BASE", tsFileNames.encoder)), tsg.return(tsg.identifier("args"))));
1674
- };
1675
- const makeMiddlewares = (entity, query) => {
1676
- const hashId = makeHashIdMiddleware(entity, query);
1677
- if (!hashId && query.middlewares.length === 0) return null;
1678
- if (query.middlewares.length === 0) return tsg.array([hashId]);
1679
- const middlewares = query.middlewares.map((it) => tsg.identifier(it).importFrom("../" + tsFileNames.middleware));
1680
- if (!hashId) return tsg.array(middlewares);
1681
- return tsg.array([hashId, ...middlewares]);
1682
- };
1683
- const makeTypeArgs = (args) => {
1684
- let hashIds = false;
1685
- const getType = (arg, checkHashId) => {
1686
- if (arg.type === "PagingOption") return tsg.typeRef(arg.type).importFrom("sasat");
1687
- if (checkHashId && arg.type === "ID") {
1688
- hashIds = true;
1689
- return tsg.typeRef("number");
1690
- }
1691
- return tsg.typeRef(toTsType(arg.type));
1692
- };
1693
- const params = tsg.typeLiteral(args.map((it) => tsg.propertySignature(it.name, getType(it, true))));
1694
- if (!hashIds) return [makeContextTypeRef("GENERATED"), params];
1695
- return [
1696
- makeContextTypeRef("GENERATED"),
1697
- params,
1698
- tsg.typeLiteral(args.map((it) => tsg.propertySignature(it.name, getType(it, false))))
1699
- ];
1700
- };
1701
- const qExpr$1 = tsg.identifier("qe").importFrom("sasat");
1702
- const makeGQLQueryBody = (entity, query) => {
1703
- const fields = tsg.variable("const", "fields", tsg.identifier("gqlResolveInfoToField").importFrom("sasat").call(tsg.identifier("info")).as(makeTypeRef(entity.name, "fields", "GENERATED")));
1704
- const where = query.conditions && query.conditions.length !== 0 ? tsg.variable("const", "where", qExpr$1.property("and").call(...(query.conditions || []).map(makeQueryConditionExpr))) : null;
1705
- const method = {
1706
- single: "first",
1707
- primary: entity.primaryQueryName(),
1708
- "list-all": "find",
1709
- "list-paging": "findPageable"
1710
- };
1711
- const queryArgs = getArgs(query, entity);
1712
- const args = [
1713
- ...query.type === "primary" ? queryArgs.map((it) => tsg.identifier(it.name)) : [],
1714
- query.type === "list-paging" ? tsg.identifier("pagingOption").importFrom("sasat").call(tsg.identifier("option")) : null,
1715
- tsg.identifier("fields"),
1716
- tsg.identifier(where ? "{ where }" : "undefined"),
1717
- tsg.identifier("context")
1718
- ].filter(nonNullable);
1719
- const result = makeDatasource(entity.name, DIR).property(method[query.type]).call(...args);
1720
- return tsg.block(fields, where, tsg.return(result));
1721
- };
1722
- //#endregion
1723
- //#region src/generatorv2/codegen/ts/generateResolver.ts
1724
- const generateResolver = (root) => {
1725
- const hasSubscription = root.subscriptions.some((it) => it.gqlEnabled);
1726
- const properties = [tsg.propertyAssign("Query", tsg.identifier("query").importFrom("./query")), tsg.propertyAssign("Mutation", tsg.identifier("mutation").importFrom("./mutation"))];
1727
- if (hasSubscription) properties.push(tsg.propertyAssign("Subscription", tsg.identifier("subscription").importFrom("./subscription")));
1728
- return new TsFile(tsg.variable("const", tsg.identifier("resolvers"), tsg.object(...properties, tsg.spreadAssign(tsg.object(...root.entities.filter((it) => it.gqlEnabled).map(makeEntityResolver))))).export()).disableEsLint();
1729
- };
1730
- const makeEntityResolver = (node) => {
1731
- return tsg.propertyAssign(node.name.name, tsg.object(...node.fields.filter((it) => it.hashId).map(makeHashIdProperty).filter(nonNullable), ...node.references.filter((it) => it.isGQLOpen).map((ref) => makeRelationProperty(ref)), ...node.referencedBy.filter((it) => it.isGQLOpen).map((ref) => makeReferencedByProperty(ref))));
1732
- };
1733
- const makeHashIdProperty = (field) => {
1734
- if (!field.hashId) return null;
1735
- const paramName = field.entity.name.lowerCase();
1736
- return tsg.propertyAssign(field.fieldName, tsg.arrowFunc([tsg.parameter(paramName, makeTypeRef(field.entity.name, "result", "GENERATED"))], void 0, tsg.binary(tsg.identifier(paramName).property(field.fieldName), "&&", tsg.identifier(field.hashId.encoder).importFrom(Directory.resolve("GENERATED", "BASE", tsFileNames.encoder)).property("encode").call(tsg.identifier(paramName).property(field.fieldName)))));
1737
- };
1738
- const makeRelationProperty = (ref) => {
1739
- const paramName = ref.entity.name.lowerCase();
1740
- return tsg.propertyAssign(ref.fieldName, tsg.arrowFunc([tsg.parameter(paramName, makeTypeRef(ref.entity.name, "result", "GENERATED")), tsg.parameter("context", makeContextTypeRef("GENERATED"))], void 0, tsg.block(tsg.if(tsg.binary(tsg.identifier(paramName).property(ref.fieldName), "!==", tsg.identifier("undefined")), tsg.return(tsg.identifier(paramName).property(ref.fieldName))), tsg.variable("const", "ds", makeDatasource(EntityName.fromTableName(ref.parentTableName), "GENERATED")), tsg.variable("const", "where", tsg.identifier("ds").property("getRelationMap").call().property(ref.fieldName).property("condition").call(tsg.object(tsg.propertyAssign("parent", tsg.identifier(paramName)), tsg.propertyAssign("childTableAlias", tsg.string("t0")), tsg.propertyAssign("context")))), tsg.return(tsg.identifier("ds").property("first").call(tsg.identifier("undefined"), tsg.object(tsg.propertyAssign("where")))))));
1741
- };
1742
- const makeReferencedByProperty = (ref) => {
1743
- const paramName = ref.entity.name.lowerCase();
1744
- const propertyName = ref.fieldName;
1745
- return tsg.propertyAssign(propertyName, tsg.arrowFunc([tsg.parameter(paramName, makeTypeRef(ref.entity.name, "result", "GENERATED")), tsg.parameter("context", makeContextTypeRef("GENERATED"))], void 0, tsg.block(tsg.if(tsg.binary(tsg.identifier(paramName).property(propertyName), "!==", tsg.identifier("undefined")), tsg.return(tsg.identifier(paramName).property(propertyName))), tsg.variable("const", "ds", makeDatasource(EntityName.fromTableName(ref.childTable), "GENERATED")), tsg.variable("const", "where", tsg.identifier("ds").property("getRelationMap").call().property(propertyName).property("condition").call(tsg.object(tsg.propertyAssign("parent", tsg.identifier(paramName)), tsg.propertyAssign("childTableAlias", tsg.string("t0")), tsg.propertyAssign("context")))), tsg.return(tsg.identifier("ds").property(ref.isArray ? "find" : "first").call(tsg.identifier("undefined"), tsg.object(tsg.propertyAssign("where")))))));
1746
- };
1747
- //#endregion
1748
- //#region src/generatorv2/codegen/ts/generateSubscription.ts
1749
- const generateSubscription = (root) => {
1750
- const subscriptionEnum = tsg.enum(tsg.identifier("SubscriptionName"), []).export();
1751
- const subscriptions = tsg.object();
1752
- const publishFunctions = [];
1753
- root.subscriptions.forEach((it) => {
1754
- subscriptionEnum.addMembers(tsg.enumMember(tsg.identifier(it.subscriptionName), tsg.string(it.subscriptionName)));
1755
- if (it.gqlEnabled) {
1756
- const fn = it.filters.length === 0 ? makeAsyncIteratorCall(it.subscriptionName) : makeWithFilter(it.subscriptionName, it.filters);
1757
- subscriptions.addProperties(tsg.propertyAssign(it.subscriptionName, tsg.object(tsg.propertyAssign("subscribe", fn))));
1758
- }
1759
- publishFunctions.push(tsg.variable("const", tsg.identifier(it.publishFunctionName), tsg.arrowFunc([tsg.parameter("entity", makeTypeRef(it.entity, it.mutationType === "delete" ? "identifiable" : "entity", "GENERATED"))], tsg.typeRef("Promise", [KeywordTypeNode.void]), tsg.identifier("pubsub.publish").call(tsg.identifier(`SubscriptionName.${it.subscriptionName}`), tsg.object(tsg.propertyAssign(it.subscriptionName, tsg.identifier("entity")))))).export());
1760
- });
1761
- return new TsFile(subscriptionEnum, tsg.variable("const", tsg.identifier("subscription"), subscriptions).export(), ...publishFunctions).disableEsLint();
1762
- };
1763
- const makeAsyncIteratorCall = (event) => {
1764
- return tsg.arrowFunc([], void 0, tsg.identifier("pubsub").importFrom("../pubsub").property("asyncIterator").call(tsg.array([tsg.identifier(`SubscriptionName.${event}`)])));
1765
- };
1766
- const makeWithFilter = (event, filters) => {
1767
- const binaryExpressions = filters.map((it) => tsg.binary(tsg.identifier(`result.${it.field}`), "===", tsg.identifier(`variables.${it.field}`))).reduce((previousValue, currentValue) => tsg.binary(previousValue, "&&", currentValue));
1768
- return tsg.identifier("withFilter").importFrom("graphql-subscriptions").call(makeAsyncIteratorCall(event), tsg.arrowFunc([tsg.parameter("payload", KeywordTypeNode.any), tsg.parameter("variables", KeywordTypeNode.any)], tsg.typeRef("Promise", [KeywordTypeNode.boolean]), tsg.block(tsg.variable("const", tsg.identifier("result"), tsg.await(tsg.identifier(`payload.${event}`))), tsg.return(binaryExpressions))).toAsync());
1769
- };
1770
- //#endregion
1771
- //#region src/generatorv2/codegen/ts/scripts/gqlString.ts
1772
- const GQLString = {
1773
- args: (args) => {
1774
- if (args.length === 0) return "";
1775
- return `(${args.map((arg) => `${arg.name}: ${GQLString.type(arg.type)}`).join(",")})`;
1776
- },
1777
- field: (field) => {
1778
- return `${field.fieldName}: ${fieldGqlType(field)}`;
1779
- },
1780
- referenceField: (ref) => {
1781
- return `${ref.fieldName}: ${makeGQLType(EntityName.fromTableName(ref.parentTableName).name, ref.isNullable, ref.isArray)}`;
1782
- },
1783
- referencedField: (ref) => {
1784
- return `${ref.fieldName}: ${makeGQLType(EntityName.fromTableName(ref.childTable).name, ref.isNullable, ref.isArray)}`;
1785
- },
1786
- query: (node) => {
1787
- return `${node.queryName}${GQLString.args(node.args)}: ${GQLString.type(node.returnType)}`;
1788
- },
1789
- mutation: (node) => {
1790
- return `${node.mutationName}${GQLString.args(node.args)}: ${GQLString.type(node.returnType)}`;
1791
- },
1792
- subscription: (node) => {
1793
- return `${node.subscriptionName}${GQLString.args(node.args)}: ${GQLString.type(node.returnType)}`;
1794
- },
1795
- type: (node) => {
1796
- const type = node.nullable ? node.typeName : node.typeName + "!";
1797
- if (node.array) return `[${type}]!`;
1798
- return type;
1799
- }
1800
- };
1801
- const fieldGqlType = (field) => {
1802
- return makeGQLType(field.gqlType, field.isNullable, field.isArray);
1803
- };
1804
- const makeGQLType = (typeName, isNullable, isArray) => {
1805
- const type = isNullable ? typeName : typeName + "!";
1806
- if (isArray) return `[${type}]!`;
1807
- return type;
1808
- };
1809
- //#endregion
1810
- //#region src/generatorv2/codegen/ts/scripts/typeDefinition.ts
1811
- const typeFieldDefinitionToTsg = (def) => {
1812
- const properties = [tsg.propertyAssign("return", tsg.string(def.return)), def.args ? tsg.propertyAssign("args", tsg.array(def.args.map((it) => {
1813
- return tsg.object(tsg.propertyAssign("name", tsg.string(it.name)), tsg.propertyAssign("type", tsg.string(it.type)));
1814
- }))) : null];
1815
- return tsg.object(...properties.filter(nonNullable));
1816
- };
1817
- //#endregion
1818
- //#region src/generatorv2/codegen/ts/generateTypeDefs.ts
1819
- const generateTypeDefs = (root) => {
1820
- const types = [
1821
- ...root.entities.map(makeEntityType),
1822
- makeQuery(root),
1823
- makeMutation(root.entities.flatMap((it) => it.mutations)),
1824
- makeSubscription(root.subscriptions.filter((it) => it.gqlEnabled))
1825
- ].filter(nonNullable);
1826
- const inputs = [
1827
- tsg.propertyAssign("PagingOption", tsg.object(tsg.propertyAssign("numberOfItem", typeFieldDefinitionToTsg({ return: "Int!" })), tsg.propertyAssign("offset", typeFieldDefinitionToTsg({ return: "Int" })), tsg.propertyAssign("order", typeFieldDefinitionToTsg({ return: "String" })), tsg.propertyAssign("asc", typeFieldDefinitionToTsg({ return: "Boolean" })))),
1828
- ...root.entities.map(makeCreateInput),
1829
- ...root.entities.map(makeUpdateInput),
1830
- ...root.entities.map(makeIdentifyInput)
1831
- ].filter(nonNullable);
1832
- return new TsFile(tsg.variable("const", tsg.identifier("typeDefs"), tsg.object(...types)).export(), tsg.variable("const", tsg.identifier("inputs"), tsg.object(...inputs)).export()).disableEsLint();
1833
- };
1834
- const makeEntityType = (node) => {
1835
- if (!node.gqlEnabled) return null;
1836
- return tsg.propertyAssign(node.name.name, tsg.object(...node.fields.filter((it) => it.isGQLOpen).map((it) => {
1837
- return tsg.propertyAssign(it.fieldName, typeFieldDefinitionToTsg({ return: makeGQLType(it.gqlType, it.isNullable, it.isArray) }));
1838
- }), ...node.references.filter((it) => it.isGQLOpen).map((it) => {
1839
- return tsg.propertyAssign(it.fieldName, typeFieldDefinitionToTsg({ return: makeGQLType(EntityName.fromTableName(it.parentTableName).name, it.isNullable, it.isArray) }));
1840
- }), ...node.referencedBy.filter((it) => it.isGQLOpen).map((it) => {
1841
- return tsg.propertyAssign(it.fieldName, typeFieldDefinitionToTsg({ return: makeGQLType(EntityName.fromTableName(it.childTable).name, it.isNullable, it.isArray) }));
1842
- })));
1843
- };
1844
- const makeInput = (inputName, fields) => {
1845
- return tsg.propertyAssign(inputName, tsg.object(...fields.filter((it) => it.isGQLOpen).map((it) => tsg.propertyAssign(it.fieldName, typeFieldDefinitionToTsg({ return: makeGQLType(it.gqlType, it.isNullable, it.isArray) })))));
1846
- };
1847
- const makeCreateInput = (node) => {
1848
- if (!node.gqlEnabled || !node.creatable.gqlEnabled) return null;
1849
- return makeInput(node.name.createInputName(), node.creatable.fields);
1850
- };
1851
- const makeUpdateInput = (node) => {
1852
- if (!node.gqlEnabled || !node.updateInput.gqlEnabled) return null;
1853
- return makeInput(node.name.updateInputName(), node.updateInput.fields);
1854
- };
1855
- const makeIdentifyInput = (node) => {
1856
- if (!node.gqlEnabled || !node.mutations.find((it) => it.mutationType === "delete")) return null;
1857
- return makeInput(node.name.identifyInputName(), node.fields.filter((it) => it.isPrimary));
1858
- };
1859
- const makeQueryTypeDef = (entity, query) => {
1860
- const args = getArgs(query, entity);
1861
- return tsg.propertyAssign(query.type === "primary" ? entity.name.lowerCase() : query.name, typeFieldDefinitionToTsg({
1862
- return: GQLString.type({
1863
- typeName: entity.name.name,
1864
- entity: true,
1865
- array: query.type === "list-paging" || query.type === "list-all",
1866
- nullable: query.type !== "list-paging" && query.type !== "list-all"
1867
- }),
1868
- args: args.map((it) => ({
1869
- name: it.name,
1870
- type: it.type + "!"
1871
- }))
1872
- }));
1873
- };
1874
- const makeQueryProperties = (root) => {
1875
- return root.entities.filter((it) => it.gqlEnabled).flatMap((entity) => entity.queries.map((it) => makeQueryTypeDef(entity, it)));
1876
- };
1877
- const makeQuery = (root) => {
1878
- const properties = makeQueryProperties(root);
1879
- if (properties.length === 0) return null;
1880
- return tsg.propertyAssign("Query", tsg.object(...properties));
1881
- };
1882
- const makeMutation = (mutations) => {
1883
- if (mutations.length === 0) return null;
1884
- return tsg.propertyAssign("Mutation", tsg.object(...mutations.map((mutation) => {
1885
- return tsg.propertyAssign(mutation.mutationName, typeFieldDefinitionToTsg({
1886
- return: GQLString.type(mutation.returnType),
1887
- args: mutation.args.map((arg) => ({
1888
- name: arg.name,
1889
- type: GQLString.type(arg.type)
1890
- }))
1891
- }));
1892
- })));
1893
- };
1894
- const makeSubscription = (subscriptions) => {
1895
- if (subscriptions.length === 0) return null;
1896
- return tsg.propertyAssign("Subscription", tsg.object(...subscriptions.map((subscription) => {
1897
- return tsg.propertyAssign(subscription.subscriptionName, typeFieldDefinitionToTsg({
1898
- return: GQLString.type(subscription.returnType),
1899
- args: subscription.args.map((arg) => ({
1900
- name: arg.name,
1901
- type: GQLString.type(arg.type)
1902
- }))
1903
- }));
1904
- })));
1905
- };
1906
- //#endregion
1907
- //#region src/generatorv2/codegen/ts/generateUserDefinedCondition.ts
1908
- const { createSourceFile, ScriptTarget } = typescript.default;
1909
- const generateUserDefinedCondition = (root, content) => {
1910
- const customConditionNames = unique(root.entities.flatMap((it) => [...it.references.flatMap((it) => it.joinCondition.filter((it) => it.kind === "custom").map((it) => it.conditionName)), ...it.referencedBy.flatMap((it) => it.joinCondition.filter((it) => it.kind === "custom").map((it) => it.conditionName))]));
1911
- if (customConditionNames.length === 0) return null;
1912
- const sourceFile = createSourceFile(tsFileNames.conditions + ".ts", content, ScriptTarget.ESNext);
1913
- const exportedVariables = getExportedVariables(sourceFile);
1914
- const contextImported = isImported(sourceFile, "GQLContext", ["./context", "./context.js"]);
1915
- const customConditionImported = isImported(sourceFile, "CustomCondition", ["sasat"]);
1916
- const statements = [];
1917
- customConditionNames.forEach((conditionName) => {
1918
- if (!exportedVariables.some((it) => {
1919
- return it.declarationList.declarations[0].name.getText(sourceFile) === conditionName;
1920
- })) statements.push(tsg.variable("const", conditionName, tsg.arrowFunc([], void 0, tsg.block(tsg.throw(tsg.new(tsg.identifier("Error"), tsg.string("TODO: Not Implemented"))))), tsg.typeRef("CustomCondition", [tsg.typeRef("GQLContext")])).export());
1921
- });
1922
- const context = contextImported ? "" : new ImportDeclaration(["GQLContext"], "./context").toString() + "\n";
1923
- const condition = customConditionImported ? "" : new ImportDeclaration(["CustomCondition"], "sasat").toString() + "\n";
1924
- const addition = statements.length === 0 ? "" : "\n" + new TsFile(...statements).toString();
1925
- return context + condition + content + addition;
1926
- };
1927
- //#endregion
1928
- //#region src/generatorv2/codegen/ts/relationMap/getRequiredColumnNames.ts
1929
- const getChildConditionValue = (cv) => {
1930
- if (cv.kind === "child") return cv.field;
1931
- return null;
1932
- };
1933
- const getConditionChildColumnNames = (getConditionValue) => (c) => {
1934
- if (c.kind === "custom") return c.childRequiredFields || [];
1935
- if (c.kind === "isNull") return [];
1936
- const result = [getConditionValue(c.left)];
1937
- if (c.operator === "IN") {
1938
- result.push(getConditionValue(c.left));
1939
- c.right.forEach((it) => {
1940
- result.push(getConditionValue(it));
1941
- });
1942
- }
1943
- if (c.operator !== "BETWEEN") result.push(getConditionValue(c.right));
1944
- else if (c.right.kind === "range") result.push(getConditionValue(c.right.begin), getConditionValue(c.right.end));
1945
- return result;
1946
- };
1947
- const getChildRequiredNames = (ref) => {
1948
- const getNames = getConditionChildColumnNames(getChildConditionValue);
1949
- return ref.joinCondition.flatMap(getNames).filter(nonNullable);
1950
- };
1951
- //#endregion
1952
- //#region src/generatorv2/codegen/ts/relationMap/makeNoContexError.ts
1953
- const makeJoinRangeConditionThrowExpressions = (cv) => {
1954
- if (cv.kind === "range") {
1955
- const result = [];
1956
- if (cv.begin.kind === "context") result.push(makeJoinConditionThrowExpressions(cv.begin));
1957
- if (cv.end.kind === "context") result.push(makeJoinConditionThrowExpressions(cv.end));
1958
- return result;
1959
- }
1960
- return [];
1961
- };
1962
- const makeJoinConditionThrowExpressions = (cv) => {
1963
- if (cv.kind !== "context") return null;
1964
- if (cv.onNotDefined.action !== "error") return null;
1965
- return tsg.if(tsg.binary(tsg.identifier("!arg.context"), "||", tsg.binary(tsg.identifier("arg.context").property(cv.field), "===", tsg.identifier("undefined"))), tsg.throw(tsg.new(tsg.identifier("Error"), tsg.string(cv.onNotDefined.message))));
1966
- };
1967
- const makeThrowExpressions = (condition) => {
1968
- if (condition.kind === "custom") return [];
1969
- if (condition.kind === "isNull") return [makeJoinConditionThrowExpressions(condition.value)];
1970
- if (condition.operator === "BETWEEN") return [makeJoinConditionThrowExpressions(condition.left), ...condition.right.kind === "range" ? makeJoinRangeConditionThrowExpressions(condition.right) : []];
1971
- if (condition.operator === "IN") return [makeJoinConditionThrowExpressions(condition.left), ...condition.right.map(makeJoinConditionThrowExpressions)];
1972
- return [makeJoinConditionThrowExpressions(condition.left), makeJoinConditionThrowExpressions(condition.right)];
1973
- };
1974
- //#endregion
1975
- //#region src/generatorv2/codegen/ts/relationMap/makeJoinConditionValue.ts
1976
- const qExpr = tsg.identifier("qe").importFrom("sasat");
1977
- const parentTableAlias = "parentTableAlias";
1978
- const childTableAlias = "childTableAlias";
1979
- const makeJoinConditionValueQExpr = (node, cv) => {
1980
- const arg = tsg.identifier("arg");
1981
- switch (cv.kind) {
1982
- case "parent": {
1983
- const columnName = node.fields.find((it) => it.fieldName === cv.field)?.columnName || cv.field;
1984
- return qExpr.property("field").call(arg.property(childTableAlias), tsg.string(columnName));
1985
- }
1986
- case "child": {
1987
- const columnName = node.fields.find((it) => it.fieldName === cv.field)?.columnName || cv.field;
1988
- return tsg.ternary(arg.property(parentTableAlias), qExpr.property("field").call(arg.property(parentTableAlias), tsg.string(columnName)), qExpr.property("value").call(arg.property("parent?").property(cv.field)));
1989
- }
1990
- default: return makeConditionValueQExpr(cv);
1991
- }
1992
- };
1993
- const makeRangeCondition = (entity, range) => {
1994
- if (range.kind === "range") return [makeJoinConditionValueQExpr(entity, range.begin), makeJoinConditionValueQExpr(entity, range.end)];
1995
- return [tsg.spread(tsg.identifier("getDayRangeQExpr").importFrom("sasat").call(tsg.new(tsg.identifier("Date")), range.thresholdHour ? tsg.number(range.thresholdHour) : tsg.identifier("undefined")))];
1996
- };
1997
- const makeConditionExpr = (entity, condition) => {
1998
- if (condition.kind === "custom") return tsg.identifier(condition.conditionName).importFrom("../conditions").call(tsg.identifier("arg"));
1999
- if (condition.kind === "isNull") return qExpr.property(condition.not ? "isNotNull" : "isNull").call(makeJoinConditionValueQExpr(entity, condition.value));
2000
- if (condition.operator === "BETWEEN") return qExpr.property("between").call(makeJoinConditionValueQExpr(entity, condition.left), ...makeRangeCondition(entity, condition.right));
2001
- if (condition.operator === "IN") return qExpr.property("in").call(makeJoinConditionValueQExpr(entity, condition.left), tsg.array(condition.right.map((it) => makeConditionValueRaw(it))));
2002
- return qExpr.property("comparison").call(makeJoinConditionValueQExpr(entity, condition.left), tsg.string(condition.operator), makeJoinConditionValueQExpr(entity, condition.right));
2003
- };
2004
- const makeJoinConditionValue = (node, ref) => {
2005
- const arg = tsg.identifier("arg");
2006
- return tsg.propertyAssign("condition", tsg.arrowFunc([tsg.parameter(arg.toString())], tsg.typeRef("BooleanValueExpression").importFrom("sasat"), tsg.block(...ref.joinCondition.flatMap((it) => makeThrowExpressions(it)).filter(nonNullable), tsg.return(qExpr.property("and").call(...ref.joinCondition.map((it) => makeConditionExpr(node, it)))))));
2007
- };
2008
- //#endregion
2009
- //#region src/generatorv2/codegen/ts/relationMap/index.ts
2010
- const generateRelationMap = (root) => {
2011
- return new TsFile(makeRelationMap(root), makeTableInfo(root), ...root.entities.flatMap(entityRelationType)).disableEsLint();
2012
- };
2013
- const makeRelationMap = (root) => {
2014
- return tsg.variable("const", tsg.identifier("relationMap"), tsg.object(...root.entities.map((it) => makeEntityRelationMap(it))), tsg.typeRef("RelationMap", [makeContextTypeRef("GENERATED")]).importFrom("sasat")).export();
2015
- };
2016
- const fieldNameToColumnNameAndFilterPrimary = (node) => (field) => {
2017
- const column = node.fields.find((it) => it.fieldName === field || it.columnName === field);
2018
- if (!column) throw new Error(`${node.name.name}.${field} Not Found`);
2019
- if (column.isPrimary) return null;
2020
- return column.columnName;
2021
- };
2022
- const makeEntityRelationMap = (node) => {
2023
- return tsg.propertyAssign(node.tableName, tsg.object(...node.references.map((ref) => {
2024
- const toColumnName = fieldNameToColumnNameAndFilterPrimary(ref.entity);
2025
- return tsg.propertyAssign(ref.fieldName, tsg.object(tsg.propertyAssign("table", tsg.string(ref.parentTableName)), makeJoinConditionValue(node, ref), tsg.propertyAssign("array", tsg.boolean(ref.isArray)), tsg.propertyAssign("nullable", tsg.boolean(ref.isNullable)), tsg.propertyAssign("requiredColumns", tsg.array(getChildRequiredNames(ref).map(toColumnName).filter(nonNullable).map(tsg.string)))));
2026
- }), ...node.referencedBy.map((rel) => {
2027
- const toColumnName = fieldNameToColumnNameAndFilterPrimary(rel.entity);
2028
- return tsg.propertyAssign(rel.fieldName, tsg.object(tsg.propertyAssign("table", tsg.string(rel.childTable)), makeJoinConditionValue(node, rel), tsg.propertyAssign("array", tsg.boolean(rel.isArray)), tsg.propertyAssign("nullable", tsg.boolean(rel.isNullable)), tsg.propertyAssign("requiredColumns", tsg.array(getChildRequiredNames(rel).map(toColumnName).filter(nonNullable).map(tsg.string)))));
2029
- })));
2030
- };
2031
- const makeTableInfo = (root) => {
2032
- const columnMap = (entity) => tsg.propertyAssign("columnMap", tsg.object(...entity.fields.map((field) => tsg.propertyAssign(field.fieldName, tsg.string(field.columnName)))));
2033
- return tsg.variable("const", "tableInfo", tsg.object(...root.entities.map((entity) => tsg.propertyAssign(entity.tableName, tsg.object(tsg.propertyAssign("identifiableKeys", tsg.array(entity.identifyKeys.map(tsg.string))), tsg.propertyAssign("identifiableFields", tsg.array(entity.fields.filter((it) => it.isPrimary).map((it) => it.fieldName).map(tsg.string))), columnMap(entity))))), tsg.typeRef("TableInfo").importFrom("sasat")).export();
2034
- };
2035
- const referenceRelationType = (ref) => {
2036
- const parentEntityName = EntityName.fromTableName(ref.parentTableName);
2037
- const type = tsg.typeRef("EntityResult", [tsg.typeRef(parentEntityName.entityWithRelationTypeName()), tsg.typeRef(parentEntityName.relationTypeName())]).importFrom("sasat");
2038
- return tsg.propertySignature(ref.fieldName, ref.isArray ? tsg.arrayType(type) : type);
2039
- };
2040
- const referencedRelationType = (node) => {
2041
- const child = EntityName.fromTableName(node.childTable);
2042
- const type = tsg.typeRef("EntityResult", [tsg.typeRef(child.entityWithRelationTypeName()), makeTypeRef(child, "identifiable", "GENERATED")]).importFrom("sasat");
2043
- return tsg.propertySignature(node.fieldName, node.isArray ? tsg.arrayType(type) : type);
2044
- };
2045
- const entityRelationType = (node) => {
2046
- const typeProperties = [...node.references.map(referenceRelationType), ...node.referencedBy.map(referencedRelationType)];
2047
- return [
2048
- tsg.typeAlias(node.name.relationTypeName(), typeProperties.length !== 0 ? tsg.typeLiteral(typeProperties) : tsg.typeRef("Record<never, never>")).export(),
2049
- tsg.typeAlias(node.name.entityWithRelationTypeName(), tsg.intersectionType(makeTypeRef(node.name, "entity", "GENERATED"), tsg.typeRef(node.name.relationTypeName()))).export(),
2050
- tsg.typeAlias(node.name.resultType(), tsg.typeRef("EntityResult", [tsg.typeRef(node.name.entityWithRelationTypeName()), makeTypeRef(node.name, "identifiable", "GENERATED")]).importFrom("sasat")).export()
2051
- ];
2052
- };
2053
- //#endregion
2054
- //#region src/generatorv2/codegen/ts/staticFiles.ts
2055
- const contextFile = `\
2056
- ${new ImportDeclaration(["BaseGQLContext"], "./__generated__/context").toString()}
2057
- export type GQLContext = BaseGQLContext & Record<string, never>;
2058
- `;
2059
- const pubsubFile = `\
2060
- ${new ImportDeclaration(["PubSub", "PubSubEngine"], "graphql-subscriptions").toString()}
2061
-
2062
- export const pubsub: PubSubEngine = new PubSub();
2063
- `;
2064
- const schemaFile = `\
2065
- ${new ImportDeclaration(["assignDeep", "createTypeDef"], "sasat").toString()}
2066
- ${new ImportDeclaration(["typeDefs", "inputs"], "./__generated__/typeDefs").toString()}
2067
- ${new ImportDeclaration(["resolvers"], "./__generated__/resolver").toString()}
2068
-
2069
- export const schema = {
2070
- typeDefs: createTypeDef(
2071
- assignDeep(typeDefs, {}),
2072
- assignDeep(inputs, {}),
2073
- ),
2074
- resolvers: assignDeep(resolvers, {}),
2075
- };
2076
- `;
2077
- const baseDBDataSourceFile = `\
2078
- ${new ImportDeclaration([
2079
- "Fields",
2080
- "SasatDBDatasource",
2081
- "EntityType"
2082
- ], "sasat").toString()}
2083
- ${new ImportDeclaration(["relationMap", "tableInfo"], "./__generated__/relationMap").toString()}
2084
-
2085
- export abstract class BaseDBDataSource<
2086
- Entity extends EntityType,
2087
- Identifiable extends object,
2088
- Creatable extends EntityType,
2089
- Updatable extends Identifiable,
2090
- EntityFields extends Fields<Entity>,
2091
- QueryResult extends Partial<Entity> & Identifiable,
2092
- > extends SasatDBDatasource<Entity, Identifiable, Creatable, Updatable, EntityFields, QueryResult> {
2093
- protected relationMap = relationMap;
2094
- protected tableInfo = tableInfo;
2095
- }
2096
- `;
2097
- const staticFiles = [
2098
- {
2099
- name: "context",
2100
- body: contextFile
2101
- },
2102
- {
2103
- name: "pubsub",
2104
- body: pubsubFile
2105
- },
2106
- {
2107
- name: "schema",
2108
- body: schemaFile
2109
- },
2110
- {
2111
- name: "baseDBDataSource",
2112
- body: baseDBDataSourceFile
2113
- }
2114
- ];
2115
- //#endregion
2116
- //#region src/generatorv2/codegen/tscodegen_v2.ts
2117
- var TsCodegen_v2 = class {
2118
- constructor() {
2119
- this.fileExtension = "ts";
2120
- this.generateEntity = (node) => generateEntityFile(node).generate();
2121
- this.generateDatasource = (node) => generateDatasource(node).generate();
2122
- this.generateGeneratedDatasource = (node) => generateAutoGeneratedDatasource(node).generate();
2123
- this.generateGqlTypeDefs = (root) => generateTypeDefs(root).generate();
2124
- this.generateGqlResolver = (root) => generateResolver(root).generate();
2125
- this.generateGqlQuery = (root) => generateQueryResolver(root).generate();
2126
- this.generateGqlMutation = (root) => generateMutationResolver(root).generate();
2127
- this.generateGqlSubscription = (root) => generateSubscription(root).generate();
2128
- this.generateGQLContext = (root) => generateContext(root).generate();
2129
- this.generateFiles = async (root) => {
2130
- return [{
2131
- name: "relationMap",
2132
- body: await generateRelationMap(root).generate()
2133
- }, {
2134
- name: "fields",
2135
- body: await generateFields(root).generate()
2136
- }];
2137
- };
2138
- this.generateOnceFiles = () => {
2139
- return staticFiles;
2140
- };
2141
- this.generateConditions = (root, currentFile) => {
2142
- return generateUserDefinedCondition(root, currentFile);
2143
- };
2144
- this.generateIDEncoders = (root, currentFile) => {
2145
- return generateIDEncoder(root, currentFile);
2146
- };
2147
- this.generateMiddlewares = (root, currentFile) => {
2148
- return generateMiddlewares(root, currentFile);
2149
- };
2150
- }
2151
- };
2152
- //#endregion
2153
- //#region src/generatorv2/parser/makeContextNodes.ts
2154
- const makeContextNodes = (store) => {
2155
- return store.tables.flatMap((table) => {
2156
- return table.gqlOption.mutations.flatMap((mutation) => mutation.contextFields.map((it) => ({
2157
- name: it.contextName || it.column,
2158
- dbtype: table.column(it.column).dataType()
2159
- })));
2160
- });
2161
- };
2162
- //#endregion
2163
- //#region src/generatorv2/parser/makeMutationNodes.ts
2164
- const makeEntityMutationNodes = (table, entity) => {
2165
- if (!table.gqlOption.enabled) return [];
2166
- return table.gqlOption.mutations.map((mutation) => {
2167
- switch (mutation.type) {
2168
- case "create": return makeCreateMutationNode(table, entity, mutation);
2169
- case "update": return makeUpdateMutationNode(table, entity, mutation);
2170
- case "delete": return makeDeleteMutationNode(table, entity, mutation);
2171
- default: throw new Error(`invalid mutation type: ${mutation.type}`);
2172
- }
2173
- });
2174
- };
2175
- const makeContextField = (params) => ({
2176
- fieldName: params.column,
2177
- contextName: params.contextName || params.column
2178
- });
2179
- const makeCreateMutationNode = (table, entity, mutation) => {
2180
- return {
2181
- entity,
2182
- contextFields: mutation.contextFields.map(makeContextField),
2183
- entityName: table.getEntityName(),
2184
- identifyFields: table.getPrimaryKeyColumns().map((it) => it.fieldName()),
2185
- mutationName: `create${table.getEntityName().name}`,
2186
- inputName: entity.name.createInputName(),
2187
- refetch: !mutation.noReFetch,
2188
- returnType: {
2189
- typeName: table.getEntityName().name,
2190
- nullable: false,
2191
- array: false,
2192
- entity: true
2193
- },
2194
- args: [{
2195
- name: table.getEntityName().lowerCase(),
2196
- type: {
2197
- typeName: table.getEntityName().createInputName(),
2198
- nullable: false,
2199
- array: false,
2200
- entity: true
2201
- }
2202
- }],
2203
- mutationType: "create",
2204
- subscription: mutation.subscription.enabled,
2205
- requireIdDecodeMiddleware: entity.creatable.fields.some((it) => it.hashId),
2206
- middlewares: mutation.middlewares
2207
- };
2208
- };
2209
- const makeUpdateMutationNode = (table, entity, mutation) => {
2210
- return {
2211
- entity,
2212
- contextFields: mutation.contextFields.map(makeContextField),
2213
- entityName: table.getEntityName(),
2214
- identifyFields: table.getPrimaryKeyColumns().map((it) => it.fieldName()),
2215
- mutationName: `update${table.getEntityName().name}`,
2216
- inputName: entity.name.updateInputName(),
2217
- refetch: !mutation.noReFetch,
2218
- returnType: {
2219
- typeName: mutation.noReFetch ? "Boolean" : table.getEntityName().name,
2220
- dbType: mutation.noReFetch ? "boolean" : void 0,
2221
- nullable: false,
2222
- array: false,
2223
- entity: !mutation.noReFetch
2224
- },
2225
- args: [{
2226
- name: table.getEntityName().lowerCase(),
2227
- type: {
2228
- typeName: table.getEntityName().updateInputName(),
2229
- nullable: false,
2230
- array: false,
2231
- entity: true
2232
- }
2233
- }],
2234
- mutationType: "update",
2235
- subscription: mutation.subscription.enabled,
2236
- requireIdDecodeMiddleware: entity.updateInput.fields.some((it) => it.hashId),
2237
- middlewares: mutation.middlewares
2238
- };
2239
- };
2240
- const makeDeleteMutationNode = (table, entity, mutation) => {
2241
- return {
2242
- entity,
2243
- mutationName: `delete${table.getEntityName().name}`,
2244
- inputName: entity.name.identifyInputName(),
2245
- contextFields: mutation.contextFields.map(makeContextField),
2246
- entityName: table.getEntityName(),
2247
- identifyFields: table.getPrimaryKeyColumns().map((it) => it.fieldName()),
2248
- refetch: false,
2249
- returnType: {
2250
- typeName: "Boolean",
2251
- dbType: "boolean",
2252
- nullable: false,
2253
- array: false,
2254
- entity: false
2255
- },
2256
- args: [{
2257
- name: table.getEntityName().lowerCase(),
2258
- type: {
2259
- typeName: table.getEntityName().identifyInputName(),
2260
- nullable: false,
2261
- array: false,
2262
- entity: true
2263
- }
2264
- }],
2265
- mutationType: "delete",
2266
- subscription: mutation.subscription.enabled,
2267
- requireIdDecodeMiddleware: entity.identifyFields().some((it) => it.hashId),
2268
- middlewares: mutation.middlewares
2269
- };
2270
- };
2271
- //#endregion
2272
- //#region src/generatorv2/scripts/columnToGqlType.ts
2273
- const columnTypeToGqlPrimitive = (type) => {
2274
- switch (type) {
2275
- case "tinyint":
2276
- case "smallint":
2277
- case "mediumint":
2278
- case "int":
2279
- case "bigint":
2280
- case "decimal":
2281
- case "year": return "Int";
2282
- case "float":
2283
- case "double": return "Float";
2284
- case "char":
2285
- case "varchar":
2286
- case "text":
2287
- case "time":
2288
- case "date":
2289
- case "datetime":
2290
- case "timestamp": return "String";
2291
- case "boolean": return "Boolean";
2292
- }
2293
- };
2294
- //#endregion
2295
- //#region src/generatorv2/nodes/FieldNode.ts
2296
- const getHashId = (store, entity, column) => {
2297
- if (!column.isReference()) {
2298
- if (column.data.option.autoIncrementHashId) return { encoder: entity.IDEncoderName() };
2299
- return;
2300
- }
2301
- const ref = column.data.reference;
2302
- const parent = store.table(ref.parentTable);
2303
- if (!parent.column(ref.parentColumn).data.option.autoIncrementHashId) return void 0;
2304
- return { encoder: parent.getEntityName().IDEncoderName() };
2305
- };
2306
- const makeFieldNode = (store, entity, column) => {
2307
- const hashId = getHashId(store, entity.name, column);
2308
- return {
2309
- entity,
2310
- fieldName: column.fieldName(),
2311
- columnName: column.columnName(),
2312
- gqlType: hashId ? "ID" : column.gqlType(),
2313
- dbType: column.dataType(),
2314
- isAutoIncrement: column.data.autoIncrement,
2315
- isArray: false,
2316
- isPrimary: column.isPrimary(),
2317
- isNullable: column.isNullable(),
2318
- isUpdatable: !(column.data.onUpdateCurrentTimeStamp || column.isPrimary()) && column.data.option.updatable,
2319
- isGQLOpen: true,
2320
- column: column.data,
2321
- option: column.data.option,
2322
- hashId
2323
- };
2324
- };
2325
- const makeCreatableFieldNode = (store, entity, column) => {
2326
- if (column.data.autoIncrement || column.data.defaultCurrentTimeStamp) return null;
2327
- const hashId = getHashId(store, entity.name, column);
2328
- return {
2329
- entity,
2330
- fieldName: column.fieldName(),
2331
- columnName: column.columnName(),
2332
- gqlType: hashId ? "ID" : column.gqlType(),
2333
- dbType: column.dataType(),
2334
- isAutoIncrement: column.data.autoIncrement,
2335
- isArray: false,
2336
- isPrimary: column.isPrimary(),
2337
- isNullable: column.isNullableOnCreate(),
2338
- isUpdatable: column.isUpdatable(),
2339
- isGQLOpen: !(column.table.gqlOption.mutations.find((it) => it.type === "create")?.contextFields || []).some((it) => it.column === column.columnName()),
2340
- column: column.data,
2341
- option: column.data.option,
2342
- hashId: getHashId(store, entity.name, column)
2343
- };
2344
- };
2345
- const makeUpdatableFieldNode = (store, entity, column) => {
2346
- if (!column.isUpdatable() || !column.data.option.updatable) return null;
2347
- const hashId = getHashId(store, entity.name, column);
2348
- return {
2349
- entity,
2350
- fieldName: column.fieldName(),
2351
- columnName: column.columnName(),
2352
- gqlType: hashId ? "ID" : column.gqlType(),
2353
- dbType: column.dataType(),
2354
- isAutoIncrement: column.data.autoIncrement,
2355
- isArray: false,
2356
- isNullable: true,
2357
- isPrimary: false,
2358
- isUpdatable: true,
2359
- isGQLOpen: !(column.table.gqlOption.mutations.find((it) => it.type === "update")?.contextFields || []).some((it) => it.column === column.columnName()),
2360
- column: column.data,
2361
- option: column.data.option,
2362
- hashId: getHashId(store, entity.name, column)
2363
- };
2364
- };
2365
- //#endregion
2366
- //#region src/migration/makeCondition.ts
2367
- const parent = (field) => ({
2368
- kind: "parent",
2369
- field
2370
- });
2371
- const child = (field) => ({
2372
- kind: "child",
2373
- field
2374
- });
2375
- const contextOrError = (field, errorMessage) => ({
2376
- kind: "context",
2377
- field,
2378
- onNotDefined: {
2379
- action: "error",
2380
- message: errorMessage
2381
- }
2382
- });
2383
- const contextOrDefault = (field, defaultValue) => ({
2384
- kind: "context",
2385
- field,
2386
- onNotDefined: {
2387
- action: "defaultValue",
2388
- value: defaultValue
2389
- }
2390
- });
2391
- const fixed = (value) => ({
2392
- kind: "fixed",
2393
- value
2394
- });
2395
- const today = (thresholdHour, date) => ({
2396
- kind: "today",
2397
- type: date ? "date" : "datetime",
2398
- thresholdHour
2399
- });
2400
- const now = () => ({ kind: "now" });
2401
- const values = (begin, end) => ({
2402
- kind: "range",
2403
- begin,
2404
- end
2405
- });
2406
- const betweenToday = (thresholdHour) => ({
2407
- kind: "date-range",
2408
- range: "today",
2409
- thresholdHour
2410
- });
2411
- const custom = (conditionName, parentRequiredFields, childRequiredFields) => ({
2412
- kind: "custom",
2413
- conditionName,
2414
- parentRequiredFields,
2415
- childRequiredFields
2416
- });
2417
- const field$1 = (column) => ({
2418
- kind: "field",
2419
- column
2420
- });
2421
- const arg = (name, type) => ({
2422
- kind: "arg",
2423
- name,
2424
- type
2425
- });
2426
- const betweenRel = (left, range) => ({
2427
- kind: "comparison",
2428
- left,
2429
- operator: "BETWEEN",
2430
- right: range
2431
- });
2432
- const betweenQuery = (left, begin, end) => ({
2433
- kind: "between",
2434
- operator: "BETWEEN",
2435
- left,
2436
- begin,
2437
- end
2438
- });
2439
- const comparisonRel = (left, operator, right) => ({
2440
- kind: "comparison",
2441
- left,
2442
- right,
2443
- operator
2444
- });
2445
- const inRel = (left, right) => ({
2446
- kind: "comparison",
2447
- left,
2448
- right,
2449
- operator: "IN"
2450
- });
2451
- const isNullRel = (value) => ({
2452
- kind: "isNull",
2453
- value,
2454
- not: false
2455
- });
2456
- const isNotNullRel = (value) => ({
2457
- kind: "isNull",
2458
- value,
2459
- not: true
2460
- });
2461
- const comparisonQuery = (left, operator, right) => ({
2462
- kind: "comparison",
2463
- left,
2464
- right,
2465
- operator
2466
- });
2467
- const Conditions = {
2468
- betweenRel,
2469
- betweenQuery,
2470
- custom,
2471
- rel: {
2472
- between: betweenRel,
2473
- comparison: comparisonRel,
2474
- in: inRel,
2475
- isNull: isNullRel,
2476
- isNotNull: isNotNullRel
2477
- },
2478
- query: {
2479
- between: betweenQuery,
2480
- comparison: comparisonQuery
2481
- },
2482
- value: {
2483
- parent,
2484
- child,
2485
- contextOrError,
2486
- contextOrDefault,
2487
- fixed,
2488
- today,
2489
- now,
2490
- field: field$1,
2491
- arg
2492
- },
2493
- range: {
2494
- values,
2495
- today: betweenToday
2496
- }
2497
- };
2498
- //#endregion
2499
- //#region src/generatorv2/nodes/ReferencedNode.ts
2500
- var ReferenceNode = class ReferenceNode {
2501
- static fromReference(entity, column, parentTable) {
2502
- const ref = column.data.reference;
2503
- if (!ref.fieldName) return null;
2504
- return new ReferenceNode(entity, ref.fieldName, column.table.tableName, ref.parentTable, makeJoinCondition(ref.parentColumn, column.columnName()), false, column.isNullable(), column.isPrimary(), column.table.gqlOption.enabled && parentTable.gqlOption.enabled);
2505
- }
2506
- static formVirtualRelation(ds, entity, rel) {
2507
- if (!rel.childFieldName) return null;
2508
- return new ReferenceNode(entity, rel.childFieldName, rel.childTable, rel.parentTable, rel.conditions, rel.childType === void 0 || rel.childType === "array", rel.childType === "nullable", false, ds.table(rel.parentTable).gqlOption.enabled && ds.table(rel.childTable).gqlOption.enabled);
2509
- }
2510
- constructor(entity, fieldName, tableName, parentTableName, joinCondition, isArray, isNullable, isPrimary, isGQLOpen) {
2511
- this.entity = entity;
2512
- this.fieldName = fieldName;
2513
- this.tableName = tableName;
2514
- this.parentTableName = parentTableName;
2515
- this.joinCondition = joinCondition;
2516
- this.isArray = isArray;
2517
- this.isNullable = isNullable;
2518
- this.isPrimary = isPrimary;
2519
- this.isGQLOpen = isGQLOpen;
2520
- }
2521
- };
2522
- var ReferencedNode = class ReferencedNode {
2523
- static fromReference(entity, parentTable, column) {
2524
- const ref = column.data.reference;
2525
- if (!ref.parentFieldName) return null;
2526
- return new ReferencedNode(entity, ref.parentFieldName, column.table.tableName, makeJoinCondition(column.columnName(), ref.parentColumn), ref.relation === "Many", ref.relation === "OneOrZero", column.isPrimary(), parentTable.gqlOption.enabled && column.table.gqlOption.enabled);
2527
- }
2528
- static fromVirtualRelation(ds, entity, rel) {
2529
- if (!rel.parentFieldName) return null;
2530
- return new ReferencedNode(entity, rel.parentFieldName, rel.childTable, rel.conditions.map(reverseConditionNode), rel.parentType === void 0 || rel.parentType === "array", rel.parentType === "nullable", false, ds.table(rel.parentTable).gqlOption.enabled && ds.table(rel.childTable).gqlOption.enabled);
2531
- }
2532
- constructor(entity, fieldName, childTable, joinCondition, isArray, isNullable, isPrimary, isGQLOpen) {
2533
- this.entity = entity;
2534
- this.fieldName = fieldName;
2535
- this.childTable = childTable;
2536
- this.joinCondition = joinCondition;
2537
- this.isArray = isArray;
2538
- this.isNullable = isNullable;
2539
- this.isPrimary = isPrimary;
2540
- this.isGQLOpen = isGQLOpen;
2541
- }
2542
- };
2543
- const reverseConditionValue = (cv) => {
2544
- if (cv.kind === "parent") return {
2545
- ...cv,
2546
- kind: "child"
2547
- };
2548
- else if (cv.kind === "child") return {
2549
- ...cv,
2550
- kind: "parent"
2551
- };
2552
- return cv;
2553
- };
2554
- const reverseRangeCondition = (condition) => {
2555
- if (condition.kind === "range") return {
2556
- kind: condition.kind,
2557
- begin: reverseConditionValue(condition.begin),
2558
- end: reverseConditionValue(condition.end)
2559
- };
2560
- return condition;
2561
- };
2562
- const reverseConditionNode = (condition) => {
2563
- if (condition.kind === "custom") return {
2564
- ...condition,
2565
- parentRequiredFields: condition.childRequiredFields,
2566
- childRequiredFields: condition.parentRequiredFields
2567
- };
2568
- if (condition.kind === "isNull") {
2569
- if (condition.not) return Conditions.rel.isNotNull(reverseConditionValue(condition.value));
2570
- return Conditions.rel.isNull(reverseConditionValue(condition.value));
2571
- }
2572
- if (condition.operator === "BETWEEN") return Conditions.rel.between(reverseConditionValue(condition.left), reverseRangeCondition(condition.right));
2573
- if (condition.operator === "IN") return Conditions.rel.in(reverseConditionValue(condition.left), condition.right.map(reverseConditionValue));
2574
- return Conditions.rel.comparison(reverseConditionValue(condition.right), condition.operator, reverseConditionValue(condition.left));
2575
- };
2576
- const makeJoinCondition = (parentColumn, childColumn) => {
2577
- return [Conditions.rel.comparison(Conditions.value.parent(parentColumn), "=", Conditions.value.child(childColumn))];
2578
- };
2579
- //#endregion
2580
- //#region src/generatorv2/nodes/entityNode.ts
2581
- var EntityNode = class {
2582
- constructor(store, table) {
2583
- this.name = EntityName.fromTableName(table.tableName);
2584
- this.fields = table.columns.map((it) => makeFieldNode(store, this, it));
2585
- this.tableName = table.tableName;
2586
- this.gqlEnabled = table.gqlOption.enabled;
2587
- this.identifyKeys = table.primaryKey;
2588
- this.queries = table.gqlOption.queries;
2589
- this.creatable = {
2590
- gqlEnabled: table.gqlOption.enabled && table.gqlOption.mutations.find((it) => it.type === "create") !== void 0,
2591
- fields: table.columns.map((it) => makeCreatableFieldNode(store, this, it)).filter(nonNullable)
2592
- };
2593
- this.updateInput = {
2594
- gqlEnabled: table.gqlOption.enabled && table.gqlOption.mutations.find((it) => it.type === "update") !== void 0,
2595
- fields: [...this.fields.filter((it) => it.isPrimary), ...table.columns.map((it) => makeUpdatableFieldNode(store, this, it)).filter(nonNullable)]
2596
- };
2597
- this.references = table.getReferenceColumns().map((column) => ReferenceNode.fromReference(this, column, store.table(column.data.reference.parentTable))).concat(table.virtualRelations.map((it) => ReferenceNode.formVirtualRelation(store, this, it))).filter(nonNullable);
2598
- this.referencedBy = store.referencedBy(table.tableName).map((column) => ReferencedNode.fromReference(this, table, column)).concat(store.virtualReferencedBy(table.tableName).map((rel) => ReferencedNode.fromVirtualRelation(store, this, rel))).filter(nonNullable);
2599
- const makeFindMethodNode = (columns, isArray) => {
2600
- const fields = columns.map((column) => this.fields.find((it) => it.columnName === column));
2601
- return {
2602
- name: makeFindQueryName(fields.map((it) => it.fieldName)),
2603
- params: fields.map((it) => makePrimitiveParameterNode(it.fieldName, it.columnName, it.dbType)),
2604
- isArray
2605
- };
2606
- };
2607
- this.findMethods = [makeFindMethodNode(table.primaryKey, false)];
2608
- this.mutations = makeEntityMutationNodes(table, this);
2609
- }
2610
- identifyFields() {
2611
- return this.fields.filter((it) => it.isPrimary);
2612
- }
2613
- primaryQueryName() {
2614
- return makeFindQueryName(this.identifyFields().map((it) => it.fieldName));
2615
- }
2616
- };
2617
- const makePrimitiveParameterNode = (fieldName, columnName, dbtype) => ({
2618
- entity: false,
2619
- fieldName,
2620
- columnName,
2621
- dbtype,
2622
- gqltype: columnTypeToGqlPrimitive(dbtype)
2623
- });
2624
- //#endregion
2625
- //#region src/generatorv2/parser/makeEntityNodes.ts
2626
- const makeEntityNodes = (store) => {
2627
- const make = makeEntityNode(store);
2628
- return store.tables.map(make);
2629
- };
2630
- const makeEntityNode = (store) => (table) => {
2631
- return new EntityNode(store, table);
2632
- };
2633
- //#endregion
2634
- //#region src/generatorv2/parser/makeSubscriptionNode.ts
2635
- const makeSubscriptionNodes = (store) => {
2636
- return store.tables.flatMap((table) => {
2637
- return table.gqlOption.mutations.map((it) => {
2638
- return makeSubscriptionNode(table, it);
2639
- });
2640
- }).filter(nonNullable);
2641
- };
2642
- const subscriptionNamePostfix = {
2643
- create: "Created",
2644
- update: "Updated",
2645
- delete: "Deleted"
2646
- };
2647
- const makeSubscriptionNode = (table, mutation) => {
2648
- if (!mutation.subscription.enabled) return null;
2649
- const subscriptionName = table.getEntityName().name + subscriptionNamePostfix[mutation.type];
2650
- return {
2651
- subscriptionName,
2652
- entity: table.getEntityName(),
2653
- publishFunctionName: "publish" + subscriptionName,
2654
- returnType: {
2655
- typeName: table.getEntityName().name,
2656
- nullable: false,
2657
- array: false,
2658
- entity: true
2659
- },
2660
- args: mutation.subscription.subscriptionFilter.map((it) => {
2661
- const column = table.column(it);
2662
- return {
2663
- name: it,
2664
- type: {
2665
- typeName: column.gqlType(),
2666
- dbType: column.dataType(),
2667
- nullable: false,
2668
- array: false,
2669
- entity: false
2670
- }
2671
- };
2672
- }),
2673
- filters: (mutation.subscription?.subscriptionFilter || []).map((it) => {
2674
- const column = table.column(it);
2675
- return {
2676
- field: column.fieldName(),
2677
- gqlType: column.gqlType()
2678
- };
2679
- }),
2680
- mutationType: mutation.type,
2681
- gqlEnabled: table.gqlOption.enabled && mutation.subscription.enabled
2682
- };
2683
- };
2684
- //#endregion
2685
- //#region src/generatorv2/parse.ts
2686
- const parse = (store) => {
2687
- store.tables.forEach((it) => {
2688
- if (it.primaryKey.length === 0) throw new Error(`Table: ${it.tableName} has no primary key.`);
2689
- });
2690
- return {
2691
- entities: makeEntityNodes(store),
2692
- subscriptions: makeSubscriptionNodes(store),
2693
- contexts: makeContextNodes(store)
2694
- };
2695
- };
2696
- //#endregion
2697
- //#region src/generatorv2/codegen_v2.ts
2698
- var CodeGen_v2 = class {
2699
- constructor(store) {
2700
- this.codeGen = new TsCodegen_v2();
2701
- this.outDir = config().migration.out;
2702
- this.dbDataSourceDir = node_path.join(this.outDir, Directory.paths.DATA_SOURCES);
2703
- this.generateDir = node_path.join(this.outDir, Directory.paths.GENERATED);
2704
- this.generateEntityDir = node_path.join(this.outDir, Directory.paths.ENTITIES);
2705
- this.generateDbDataSourceDir = node_path.join(this.outDir, Directory.paths.GENERATED_DS);
2706
- this.root = parse(store);
2707
- }
2708
- async generate() {
2709
- await this.prepareDirs();
2710
- await Promise.all([
2711
- ...this.root.entities.map((it) => this.generateEntity(it)),
2712
- ...this.root.entities.map((it) => this.generateDatasource(it)),
2713
- ...this.root.entities.map((it) => this.generateGeneratedDatasource(it)),
2714
- this.generateGql(this.root),
2715
- this.generateFiles(this.root),
2716
- ...this.generateOnceFiles(),
2717
- this.generateCondition(this.root),
2718
- this.generateIDEncoders(this.root),
2719
- this.generateMiddleware(this.root)
2720
- ]);
2721
- }
2722
- async prepareDirs() {
2723
- mkDirIfNotExist(this.generateDir);
2724
- await emptyDir(this.generateDir);
2725
- mkDirIfNotExist(this.generateEntityDir);
2726
- mkDirIfNotExist(this.generateDbDataSourceDir);
2727
- mkDirIfNotExist(this.dbDataSourceDir);
2728
- }
2729
- getFullPath(basePath, entityName) {
2730
- return node_path.join(basePath, `${entityName}.${this.codeGen.fileExtension}`);
2731
- }
2732
- async generateEntity(node) {
2733
- return (0, node_fs_promises.writeFile)(this.getFullPath(this.generateEntityDir, node.name.name), await this.codeGen.generateEntity(node));
2734
- }
2735
- async generateDatasource(node) {
2736
- return writeFileIfNotExist(this.getFullPath(this.dbDataSourceDir, node.name.name), await this.codeGen.generateDatasource(node));
2737
- }
2738
- async generateGeneratedDatasource(node) {
2739
- return (0, node_fs_promises.writeFile)(this.getFullPath(this.generateDbDataSourceDir, node.name.name), await this.codeGen.generateGeneratedDatasource(node));
2740
- }
2741
- async generateGql(rootNode) {
2742
- return Promise.all([
2743
- (0, node_fs_promises.writeFile)(this.getFullPath(this.generateDir, "typeDefs"), await this.codeGen.generateGqlTypeDefs(rootNode)),
2744
- (0, node_fs_promises.writeFile)(this.getFullPath(this.generateDir, "resolver"), await this.codeGen.generateGqlResolver(rootNode)),
2745
- (0, node_fs_promises.writeFile)(this.getFullPath(this.generateDir, "query"), await this.codeGen.generateGqlQuery(rootNode)),
2746
- (0, node_fs_promises.writeFile)(this.getFullPath(this.generateDir, "mutation"), await this.codeGen.generateGqlMutation(rootNode)),
2747
- (0, node_fs_promises.writeFile)(this.getFullPath(this.generateDir, "subscription"), await this.codeGen.generateGqlSubscription(rootNode)),
2748
- (0, node_fs_promises.writeFile)(this.getFullPath(this.generateDir, "context"), await this.codeGen.generateGQLContext(rootNode))
2749
- ]);
2750
- }
2751
- async generateFiles(rootNode) {
2752
- const files = await this.codeGen.generateFiles(rootNode);
2753
- return Promise.all(files.map((it) => writeFileIfNotExist(this.getFullPath(this.generateDir, it.name), it.body)));
2754
- }
2755
- generateOnceFiles() {
2756
- return this.codeGen.generateOnceFiles().map((it) => writeFileIfNotExist(this.getFullPath(this.outDir, it.name), it.body));
2757
- }
2758
- async generateCondition(rootNode) {
2759
- const filePath = this.getFullPath(this.outDir, tsFileNames.conditions);
2760
- const content = (0, node_fs.existsSync)(filePath) ? (0, node_fs.readFileSync)(filePath).toString() : "";
2761
- const nextContent = this.codeGen.generateConditions(rootNode, content);
2762
- if (nextContent) (0, node_fs.writeFileSync)(filePath, nextContent);
2763
- }
2764
- async generateIDEncoders(rootNode) {
2765
- const filePath = this.getFullPath(this.outDir, tsFileNames.encoder);
2766
- const content = (0, node_fs.existsSync)(filePath) ? (0, node_fs.readFileSync)(filePath).toString() : "";
2767
- const nextContent = this.codeGen.generateIDEncoders(rootNode, content);
2768
- if (nextContent) (0, node_fs.writeFileSync)(filePath, nextContent);
2769
- }
2770
- async generateMiddleware(rootNode) {
2771
- const filePath = this.getFullPath(this.outDir, tsFileNames.middleware);
2772
- const content = (0, node_fs.existsSync)(filePath) ? (0, node_fs.readFileSync)(filePath).toString() : "";
2773
- const nextContent = this.codeGen.generateMiddlewares(rootNode, content);
2774
- if (nextContent) (0, node_fs.writeFileSync)(filePath, nextContent);
2775
- }
2776
- };
2777
- //#endregion
2778
- //#region src/migration/exec/getMigrationFiles.ts
2779
- const getMigrationFileDir = () => {
2780
- return node_path.default.join(process.cwd(), config().migration.dir);
2781
- };
2782
- const getMigrationFileNames = () => {
2783
- return node_fs.default.readdirSync(getMigrationFileDir()).filter((it) => it.split(".").pop() === "ts");
2784
- };
2785
- //#endregion
2786
- //#region src/error.ts
2787
- var SasatError = class extends Error {
2788
- constructor(message) {
2789
- super(message);
2790
- Object.setPrototypeOf(this, new.target.prototype);
2791
- this.name = "SasatError";
2792
- }
2793
- };
2794
- //#endregion
2795
- //#region src/runtime/sql/sqlString.ts
2796
- const { escape, escapeId: escapeId$1 } = sqlstring.default;
2797
- const SqlString = {
2798
- escape: (value) => escape(value, true),
2799
- escapeId: (name) => escapeId$1(name)
2800
- };
2801
- //#endregion
2802
- //#region src/db/sql/columnToSql.ts
2803
- const columnToSql = (column) => {
2804
- const words = [SqlString.escapeId(column.columnName), column.type];
2805
- if (column.length) words.push(`(${[column.length, column.scale].filter((it) => it !== void 0).join(",")})`);
2806
- if (column.signed === true) words.push("SIGNED");
2807
- else if (column.signed === false) words.push("UNSIGNED");
2808
- if (column.zerofill) words.push("ZEROFILL");
2809
- if (column.autoIncrement) words.push("AUTO_INCREMENT");
2810
- if (column.notNull) words.push("NOT NULL");
2811
- else if (!column.notNull) words.push("NULL");
2812
- if ((column.type === "timestamp" || column.type === "datetime") && column.default === "CURRENT_TIMESTAMP") words.push("DEFAULT CURRENT_TIMESTAMP");
2813
- else if (column.default !== void 0) words.push("DEFAULT " + SqlString.escape(column.default));
2814
- if (column.onUpdateCurrentTimeStamp) words.push("ON UPDATE CURRENT_TIMESTAMP");
2815
- return words.join(" ");
2816
- };
2817
- //#endregion
2818
- //#region src/migration/serializable/column.ts
2819
- var BaseColumn = class {
2820
- constructor(data, table) {
2821
- this.data = data;
2822
- this.table = table;
2823
- }
2824
- fieldName() {
2825
- return this.data.fieldName;
2826
- }
2827
- columnName() {
2828
- return this.data.columnName;
2829
- }
2830
- dataType() {
2831
- return this.data.type;
2832
- }
2833
- tsType() {
2834
- return columnTypeToTsType(this.dataType());
2835
- }
2836
- gqlType() {
2837
- return columnTypeToGqlPrimitive(this.dataType());
2838
- }
2839
- isNullable() {
2840
- return !this.data.notNull;
2841
- }
2842
- isNullableOnCreate() {
2843
- return !this.data.notNull || this.data.default !== void 0 || this.data.autoIncrement;
2844
- }
2845
- isReference() {
2846
- return this.data.hasReference;
2847
- }
2848
- serialize() {
2849
- return JSON.parse(JSON.stringify(this.data));
2850
- }
2851
- toSql() {
2852
- return columnToSql(this.data);
2853
- }
2854
- isPrimary() {
2855
- return this.table.primaryKey.includes(this.columnName());
2856
- }
2857
- isUpdatable() {
2858
- return !(this.isPrimary() || this.data.onUpdateCurrentTimeStamp);
2859
- }
2860
- };
2861
- var NormalColumn = class extends BaseColumn {
2862
- constructor(data, table) {
2863
- super(data, table);
2864
- this.data = data;
2865
- }
2866
- addReference(reference) {
2867
- return new ReferenceColumn({
2868
- ...this.data,
2869
- hasReference: true,
2870
- reference
2871
- }, this.table);
2872
- }
2873
- };
2874
- var ReferenceColumn = class extends BaseColumn {
2875
- constructor(data, table) {
2876
- super(data, table);
2877
- this.data = data;
2878
- }
2879
- getConstraintName() {
2880
- return `ref_${this.table.tableName}_${this.fieldName()}__${this.data.reference.parentTable}_${this.data.reference.parentColumn}`;
2881
- }
2882
- };
2883
- //#endregion
2884
- //#region src/migration/data/index.ts
2885
- var DBIndex = class {
2886
- constructor(tableName, columns) {
2887
- this.tableName = tableName;
2888
- this.columns = columns;
2889
- this.constraintName = this.toConstraintName(columns);
2890
- }
2891
- toConstraintName(columns) {
2892
- return `index_${this.tableName}__${columns.join("_")}`;
2893
- }
2894
- addSql() {
2895
- return `ALTER TABLE ${this.tableName} ADD INDEX ${this.constraintName}(${this.columns.join(",")})`;
2896
- }
2897
- dropSql() {
2898
- return `DROP INDEX ${this.constraintName} ON ${this.tableName}`;
2899
- }
2900
- serialize() {
2901
- return {
2902
- constraintName: this.constraintName,
2903
- columns: this.columns
2904
- };
2905
- }
2906
- };
2907
- //#endregion
2908
- //#region src/migration/functions/assembleColumn.ts
2909
- const assembleColumn = (data, table) => {
2910
- if (data.hasReference) return new ReferenceColumn(data, table);
2911
- return new NormalColumn(data, table);
2912
- };
2913
- //#endregion
2914
- //#region src/migration/serialized/serializedColumn.ts
2915
- const defaultColumnOption = {
2916
- updatable: true,
2917
- autoIncrementHashId: false
2918
- };
2919
- const referenceToSql = (constraintName, ref) => {
2920
- const onUpdate = ref.onUpdate ? ` ON UPDATE ${ref.onUpdate}` : "";
2921
- const onDelete = ref.onDelete ? ` ON DELETE ${ref.onDelete}` : "";
2922
- return `CONSTRAINT ${constraintName} FOREIGN KEY(${ref.columnName}) REFERENCES ${SqlString.escapeId(ref.parentTable)}(${SqlString.escapeId(ref.parentColumn)})` + onUpdate + onDelete;
2923
- };
2924
- //#endregion
2925
- //#region src/migration/serializable/table.ts
2926
- var TableHandler = class {
2927
- get index() {
2928
- return this.indexes;
2929
- }
2930
- get columns() {
2931
- return this._columns;
2932
- }
2933
- get virtualRelations() {
2934
- return this._virtualRelations;
2935
- }
2936
- addVirtualRelation(relation) {
2937
- this._virtualRelations.push({
2938
- ...relation,
2939
- childTable: this.tableName
2940
- });
2941
- }
2942
- get gqlOption() {
2943
- return this._gqlOption;
2944
- }
2945
- constructor(table, store) {
2946
- this.store = store;
2947
- this._gqlOption = defaultGQLOption();
2948
- this.tableName = table.tableName;
2949
- this.primaryKey = table.primaryKey || [];
2950
- this.uniqueKeys = table.uniqueKeys || [];
2951
- this.indexes = table.indexes?.map((it) => new DBIndex(this.tableName, it.columns)) || [];
2952
- this._gqlOption = table.gqlOption || defaultGQLOption();
2953
- this._columns = (table.columns || []).map((it) => assembleColumn(it, this));
2954
- this._virtualRelations = table.virtualRelations || [];
2955
- }
2956
- column(columnName) {
2957
- const column = this.columns.find((it) => it.columnName() === columnName);
2958
- if (!column) throw new Error(`${this.tableName}.${columnName} is Not Found`);
2959
- return column;
2960
- }
2961
- addColumn(column, isPrimary = false, isUnique = false) {
2962
- this.columns.push(column);
2963
- if (isPrimary) this.setPrimaryKey(column.columnName());
2964
- if (isUnique) this.addUniqueKey(column.columnName());
2965
- }
2966
- dropColumn(columnName) {
2967
- this._columns = this._columns.filter((it) => it.fieldName() !== columnName);
2968
- }
2969
- serialize() {
2970
- return {
2971
- columns: this.columns.map((it) => it.serialize()),
2972
- primaryKey: this.primaryKey,
2973
- uniqueKeys: this.uniqueKeys,
2974
- indexes: this.indexes,
2975
- tableName: this.tableName,
2976
- gqlOption: JSON.parse(JSON.stringify(this.gqlOption)),
2977
- virtualRelations: this._virtualRelations
2978
- };
2979
- }
2980
- addReferences(ref, fieldName, notNull = true) {
2981
- const data = {
2982
- ...this.store.table(ref.parentTable).column(ref.parentColumn).serialize(),
2983
- hasReference: true,
2984
- fieldName: fieldName || ref.columnName,
2985
- columnName: ref.columnName,
2986
- notNull,
2987
- default: void 0,
2988
- zerofill: false,
2989
- autoIncrement: false,
2990
- defaultCurrentTimeStamp: false,
2991
- onUpdateCurrentTimeStamp: false,
2992
- reference: ref
2993
- };
2994
- this.columns.push(new ReferenceColumn(data, this));
2995
- return this;
2996
- }
2997
- getIndexConstraintName(columns) {
2998
- return `index_${this.tableName}__${columns.join("_")}`;
2999
- }
3000
- addIndex(...columns) {
3001
- this.indexes.push(new DBIndex(this.tableName, columns));
3002
- return this;
3003
- }
3004
- removeIndex(...columns) {
3005
- const constraint = this.getIndexConstraintName(columns);
3006
- this.indexes = this.indexes.filter((it) => it.constraintName !== constraint);
3007
- return this;
3008
- }
3009
- addUniqueKey(...columnNames) {
3010
- if (columnNames.length === 0) throw new SasatError("No column name specified");
3011
- this.uniqueKeys.push(columnNames);
3012
- return this;
3013
- }
3014
- setPrimaryKey(...columnNames) {
3015
- if (columnNames.length === 0) throw new Error("Primary key is required");
3016
- this.primaryKey = columnNames;
3017
- return this;
3018
- }
3019
- showCreateTable() {
3020
- const rows = [...this.columns.map((it) => it.toSql())];
3021
- if (this.primaryKey.length !== 0) rows.push(`PRIMARY KEY (${this.primaryKey.map(SqlString.escapeId).join(",")})`);
3022
- this.uniqueKeys.forEach((it) => {
3023
- if (this.uniqueKeys.length !== 0) rows.push(`UNIQUE KEY (${it.join(",")})`);
3024
- });
3025
- rows.push(...this._columns.filter((it) => it.isReference() && !it.data.reference.noFKey).map((it) => {
3026
- const ref = it;
3027
- return referenceToSql(ref.getConstraintName(), ref.data.reference);
3028
- }));
3029
- return `CREATE TABLE ${SqlString.escapeId(this.tableName)}
3030
- (
3031
- ${rows.join(", ")}
3032
- )`;
3033
- }
3034
- hasColumn(columnName) {
3035
- return !!this.columns.find((it) => it.columnName() === columnName);
3036
- }
3037
- isColumnPrimary(columnName) {
3038
- return this.primaryKey.includes(columnName);
3039
- }
3040
- getEntityName() {
3041
- return EntityName.fromTableName(this.tableName);
3042
- }
3043
- setGQLOption(option) {
3044
- this._gqlOption = {
3045
- ...this.gqlOption,
3046
- ...option
3047
- };
3048
- }
3049
- getReferenceColumns() {
3050
- return this.columns.filter((it) => it.isReference());
3051
- }
3052
- addForeignKey(reference) {
3053
- const columnName = reference.columnName;
3054
- const column1 = this.column(columnName);
3055
- if (!column1) throw new Error("Column: `" + columnName + "` Not Found");
3056
- if (column1.isReference()) throw new Error("Column: `" + columnName + "`already has reference, multiple reference is not supported");
3057
- const ref = column1.addReference(reference);
3058
- this._columns = this.columns.map((it) => it.columnName() === columnName ? ref : it);
3059
- }
3060
- changeType(columnName, type) {
3061
- this.updateColumn(columnName, { type });
3062
- }
3063
- setDefault(columnName, value) {
3064
- this.updateColumn(columnName, { default: value });
3065
- }
3066
- updateColumn(columnName, diff) {
3067
- const update = (column) => {
3068
- if (column.isReference()) return new ReferenceColumn({
3069
- ...column.serialize(),
3070
- ...diff
3071
- }, this);
3072
- return new NormalColumn({
3073
- ...column.serialize(),
3074
- ...diff
3075
- }, this);
3076
- };
3077
- if (!this.column(columnName)) throw new Error(this.tableName + "." + columnName + " Not Found");
3078
- this._columns = this.columns.map((it) => it.columnName() === columnName ? update(it) : it);
3079
- }
3080
- getPrimaryKeyColumns() {
3081
- return this.columns.filter((it) => this.primaryKey.includes(it.columnName()));
3082
- }
3083
- };
3084
- //#endregion
3085
- //#region src/migration/creators/columnBuilder.ts
3086
- var ColumnBuilderBase = class {
3087
- constructor(columnName) {
3088
- this.columnName = columnName;
3089
- this._primary = false;
3090
- this._notNull = true;
3091
- this._unique = false;
3092
- this._option = defaultColumnOption;
3093
- this._fieldName = columnName;
3094
- }
3095
- fieldName(fieldName) {
3096
- this._fieldName = fieldName;
3097
- return this;
3098
- }
3099
- notNull() {
3100
- this._notNull = true;
3101
- return this;
3102
- }
3103
- nullable() {
3104
- this._notNull = false;
3105
- return this;
3106
- }
3107
- primary() {
3108
- this._primary = true;
3109
- return this;
3110
- }
3111
- unique() {
3112
- this._unique = true;
3113
- return this;
3114
- }
3115
- updatable(updatable) {
3116
- this._option = {
3117
- ...this._option,
3118
- updatable
3119
- };
3120
- return this;
3121
- }
3122
- };
3123
- var ColumnBuilder = class extends ColumnBuilderBase {
3124
- constructor(name, type, length, scale) {
3125
- super(name);
3126
- this.type = type;
3127
- this.length = length;
3128
- this.scale = scale;
3129
- this._zerofill = false;
3130
- this._autoIncrement = false;
3131
- this._defaultCurrentTimeStamp = false;
3132
- this._onUpdateCurrentTimeStamp = false;
3133
- this._fieldName = name;
3134
- }
3135
- default(value) {
3136
- this._default = value;
3137
- return this;
3138
- }
3139
- build() {
3140
- return {
3141
- data: {
3142
- hasReference: false,
3143
- columnName: this.columnName,
3144
- fieldName: this._fieldName,
3145
- type: this.type,
3146
- length: this.length,
3147
- scale: this.scale,
3148
- notNull: this._notNull,
3149
- zerofill: this._zerofill,
3150
- signed: this._signed,
3151
- autoIncrement: this._autoIncrement,
3152
- default: this._default,
3153
- defaultCurrentTimeStamp: this._defaultCurrentTimeStamp,
3154
- onUpdateCurrentTimeStamp: this._onUpdateCurrentTimeStamp,
3155
- option: this._option
3156
- },
3157
- isPrimary: this._primary,
3158
- isUnique: this._unique
3159
- };
3160
- }
3161
- };
3162
- var StringColumnBuilder = class extends ColumnBuilder {
3163
- constructor(name, type, length) {
3164
- super(name, type);
3165
- this.name = name;
3166
- this.type = type;
3167
- this.length = length;
3168
- }
3169
- default(value) {
3170
- this._default = value;
3171
- return this;
3172
- }
3173
- };
3174
- var TextColumnBuilder = class extends ColumnBuilder {
3175
- constructor(name, type) {
3176
- super(name, type);
3177
- this.name = name;
3178
- this.type = type;
3179
- }
3180
- default(value) {
3181
- this._default = value;
3182
- return this;
3183
- }
3184
- };
3185
- var NumberColumnBuilder = class extends ColumnBuilder {
3186
- signed() {
3187
- this._signed = true;
3188
- return this;
3189
- }
3190
- unsigned() {
3191
- this._signed = false;
3192
- return this;
3193
- }
3194
- zerofill() {
3195
- this._zerofill = true;
3196
- return this;
3197
- }
3198
- default(value) {
3199
- this._default = value;
3200
- return this;
3201
- }
3202
- };
3203
- var IntegerColumnBuilder = class extends NumberColumnBuilder {
3204
- constructor(name, type, length) {
3205
- super(name, type, length);
3206
- this.name = name;
3207
- this.type = type;
3208
- this.length = length;
3209
- }
3210
- autoIncrement() {
3211
- this._autoIncrement = true;
3212
- return this;
3213
- }
3214
- };
3215
- var FloatColumnBuilder = class extends NumberColumnBuilder {
3216
- constructor(name, type, length, scale) {
3217
- super(name, type, length, scale);
3218
- this.name = name;
3219
- this.type = type;
3220
- this.length = length;
3221
- this.scale = scale;
3222
- }
3223
- autoIncrement() {
3224
- this._autoIncrement = true;
3225
- return this;
3226
- }
3227
- };
3228
- var DecimalColumnBuilder = class extends NumberColumnBuilder {
3229
- constructor(name, type, length, scale) {
3230
- super(name, type, length, scale);
3231
- this.name = name;
3232
- this.type = type;
3233
- this.length = length;
3234
- this.scale = scale;
3235
- }
3236
- };
3237
- var DateColumnBuilder = class extends ColumnBuilder {
3238
- constructor(name, type) {
3239
- super(name, type);
3240
- this.name = name;
3241
- this.type = type;
3242
- }
3243
- default(value) {
3244
- this._default = value;
3245
- return this;
3246
- }
3247
- };
3248
- var TimeStampColumnBuilder = class extends ColumnBuilder {
3249
- constructor(name, type) {
3250
- super(name, type);
3251
- this.name = name;
3252
- this.type = type;
3253
- }
3254
- default(value) {
3255
- this._default = value;
3256
- return this;
3257
- }
3258
- defaultCurrentTimeStamp() {
3259
- this._defaultCurrentTimeStamp = true;
3260
- return this.default("CURRENT_TIMESTAMP");
3261
- }
3262
- onUpdateCurrentTimeStamp() {
3263
- this._onUpdateCurrentTimeStamp = true;
3264
- return this;
3265
- }
3266
- };
3267
- var ReferenceColumnBuilder = class extends ColumnBuilderBase {
3268
- constructor(ref, parent) {
3269
- super(ref.columnName);
3270
- this.ref = ref;
3271
- this.parent = parent;
3272
- this._option = {
3273
- ...this._option,
3274
- updatable: false
3275
- };
3276
- }
3277
- notNull() {
3278
- this._notNull = true;
3279
- return this;
3280
- }
3281
- nullable() {
3282
- this._notNull = false;
3283
- return this;
3284
- }
3285
- primary() {
3286
- this._primary = true;
3287
- return this;
3288
- }
3289
- unique() {
3290
- this._unique = true;
3291
- return this;
3292
- }
3293
- build() {
3294
- return {
3295
- data: {
3296
- ...this.parent.serialize(),
3297
- hasReference: true,
3298
- fieldName: this._fieldName,
3299
- columnName: this.columnName,
3300
- notNull: this._notNull,
3301
- default: void 0,
3302
- autoIncrement: false,
3303
- defaultCurrentTimeStamp: false,
3304
- onUpdateCurrentTimeStamp: false,
3305
- reference: this.ref,
3306
- option: this._option
3307
- },
3308
- isPrimary: this._primary,
3309
- isUnique: this._unique
3310
- };
3311
- }
3312
- };
3313
- var AutoIncrementIDColumnBuilder = class extends ColumnBuilderBase {
3314
- constructor(columnName, option) {
3315
- super(columnName);
3316
- this.option = option;
3317
- this._option = {
3318
- ...this._option,
3319
- updatable: false,
3320
- autoIncrementHashId: true,
3321
- hashSalt: option?.salt
3322
- };
3323
- }
3324
- build() {
3325
- return {
3326
- data: {
3327
- hasReference: false,
3328
- fieldName: this._fieldName,
3329
- columnName: this.columnName,
3330
- type: this.option?.bigint ? "bigint" : "int",
3331
- notNull: true,
3332
- default: void 0,
3333
- zerofill: false,
3334
- signed: false,
3335
- autoIncrement: true,
3336
- length: void 0,
3337
- scale: void 0,
3338
- defaultCurrentTimeStamp: false,
3339
- onUpdateCurrentTimeStamp: false,
3340
- option: this._option
3341
- },
3342
- isPrimary: true,
3343
- isUnique: false
3344
- };
3345
- }
3346
- };
3347
- //#endregion
3348
- //#region src/migration/creators/columnCreator.ts
3349
- var ColumnCreator = class {
3350
- constructor(table, name) {
3351
- this.table = table;
3352
- this.name = name;
3353
- this.char = (length) => this.create(new StringColumnBuilder(this.name, "char", length));
3354
- this.varchar = (length) => this.create(new StringColumnBuilder(this.name, "varchar", length));
3355
- this.text = () => this.create(new TextColumnBuilder(this.name, "text"));
3356
- this.tinyInt = (length) => this.create(new IntegerColumnBuilder(this.name, "tinyint", length));
3357
- this.smallInt = (length) => this.create(new IntegerColumnBuilder(this.name, "smallint", length));
3358
- this.mediumInt = (length) => this.create(new IntegerColumnBuilder(this.name, "mediumint", length));
3359
- this.int = (length) => this.create(new IntegerColumnBuilder(this.name, "int", length));
3360
- this.bigInt = (length) => this.create(new IntegerColumnBuilder(this.name, "bigint", length));
3361
- this.float = (length, scale) => this.create(new FloatColumnBuilder(this.name, "float", length, scale));
3362
- this.double = (length, scale) => this.create(new FloatColumnBuilder(this.name, "double", length, scale));
3363
- this.decimal = (length, scale) => this.create(new DecimalColumnBuilder(this.name, "decimal", length, scale));
3364
- this.year = () => this.create(new DateColumnBuilder(this.name, "year"));
3365
- this.date = () => this.create(new DateColumnBuilder(this.name, "date"));
3366
- this.time = () => this.create(new DateColumnBuilder(this.name, "time"));
3367
- this.dateTime = () => this.create(new TimeStampColumnBuilder(this.name, "datetime"));
3368
- this.timestamp = () => this.create(new TimeStampColumnBuilder(this.name, "timestamp"));
3369
- }
3370
- create(column) {
3371
- this.table.addColumn(column);
3372
- return column;
3373
- }
3374
- };
3375
- //#endregion
3376
- //#region src/migration/creators/tableCreator.ts
3377
- var TableCreator = class {
3378
- constructor(tableName, store) {
3379
- this.tableName = tableName;
3380
- this.store = store;
3381
- this.columns = [];
3382
- this.table = new TableHandler({ tableName }, store);
3383
- }
3384
- autoIncrementHashId(columnName, option) {
3385
- this.addColumn(new AutoIncrementIDColumnBuilder(columnName, option));
3386
- return this;
3387
- }
3388
- column(name) {
3389
- return new ColumnCreator(this, name);
3390
- }
3391
- addVirtualRelation(relation) {
3392
- this.table.addVirtualRelation(relation);
3393
- return this;
3394
- }
3395
- addColumn(column) {
3396
- if (this.table.hasColumn(column.columnName)) throw new Error(`${this.tableName}.${column.columnName} already exists`);
3397
- this.columns.push(column);
3398
- }
3399
- addUniqueKey(...columnNames) {
3400
- this.table.addUniqueKey(...columnNames);
3401
- return this;
3402
- }
3403
- references(ref) {
3404
- const column = new ReferenceColumnBuilder(ref, this.store.table(ref.parentTable).column(ref.parentColumn));
3405
- this.addColumn(column);
3406
- return column;
3407
- }
3408
- setPrimaryKey(...columnNames) {
3409
- this.table.setPrimaryKey(...columnNames);
3410
- return this;
3411
- }
3412
- create() {
3413
- this.columns.forEach((column) => {
3414
- const { data, isPrimary, isUnique } = column.build();
3415
- this.table.addColumn(data.hasReference ? new ReferenceColumn(data, this.table) : new NormalColumn(data, this.table), isPrimary, isUnique);
3416
- });
3417
- return this.table;
3418
- }
3419
- createdAt() {
3420
- this.column("createdAt").timestamp().defaultCurrentTimeStamp().notNull().updatable(false);
3421
- return this;
3422
- }
3423
- updatedAt() {
3424
- this.column("updatedAt").timestamp().defaultCurrentTimeStamp().onUpdateCurrentTimeStamp().notNull().updatable(false);
3425
- return this;
3426
- }
3427
- addIndex(...columns) {
3428
- this.table.addIndex(`index_${this.tableName}__${columns.join("_")}`, ...columns);
3429
- return this;
3430
- }
3431
- enableGQL() {
3432
- this.table.setGQLOption({
3433
- ...this.table.gqlOption,
3434
- enabled: true
3435
- });
3436
- return this;
3437
- }
3438
- setGQLOption(option) {
3439
- this.table.setGQLOption(option);
3440
- return this;
3441
- }
3442
- addGQLQuery(...query) {
3443
- this.table.setGQLOption({ queries: [...this.table.gqlOption.queries, ...query] });
3444
- return this;
3445
- }
3446
- addGQLMutation(...mutation) {
3447
- this.table.setGQLOption({ mutations: [...this.table.gqlOption.mutations, ...mutation] });
3448
- return this;
3449
- }
3450
- };
3451
- //#endregion
3452
- //#region src/db/sql/sqlCreater.ts
3453
- const SqlCreator = {
3454
- addColumn: (tableName, column) => `ALTER TABLE ${tableName} ADD COLUMN ${columnToSql(column)}`,
3455
- dropColumn: (tableName, columnName) => `ALTER TABLE ${tableName} DROP COLUMN ${columnName}`,
3456
- addUniqueKey: (tableName, columns) => `ALTER TABLE ${tableName} ADD UNIQUE ${columns.join("__")}(${columns.join(",")})`,
3457
- addPrimaryKey: (tableName, columns) => `ALTER TABLE ${tableName} ADD PRIMARY KEY ${columns.join("__")}(${columns.join(",")})`,
3458
- addForeignKey: (tableName, constraintName, reference) => {
3459
- const onUpdate = reference.onUpdate ? " ON UPDATE " + reference.onUpdate : "";
3460
- const onDelete = reference.onDelete ? " ON DELETE " + reference.onDelete : "";
3461
- return `ALTER TABLE ${tableName} ADD CONSTRAINT '${constraintName}' FOREIGN KEY (${reference.columnName}) REFERENCES ${reference.parentTable}(${reference.parentColumn})${onUpdate}${onDelete}`;
3462
- }
3463
- };
3464
- //#endregion
3465
- //#region src/migration/creators/createColumn.ts
3466
- const createColumn = (name) => ({
3467
- char: (length) => new StringColumnBuilder(name, "char", length),
3468
- varchar: (length) => new StringColumnBuilder(name, "varchar", length),
3469
- text: () => new TextColumnBuilder(name, "text"),
3470
- tinyInt: (length) => new IntegerColumnBuilder(name, "tinyint", length),
3471
- smallInt: (length) => new IntegerColumnBuilder(name, "smallint", length),
3472
- mediumInt: (length) => new IntegerColumnBuilder(name, "mediumint", length),
3473
- int: (length) => new IntegerColumnBuilder(name, "int", length),
3474
- bigInt: (length) => new IntegerColumnBuilder(name, "bigint", length),
3475
- float: (length, scale) => new FloatColumnBuilder(name, "float", length, scale),
3476
- double: (length, scale) => new FloatColumnBuilder(name, "double", length, scale),
3477
- decimal: (length, scale) => new DecimalColumnBuilder(name, "decimal", length, scale),
3478
- year: () => new DateColumnBuilder(name, "year"),
3479
- date: () => new DateColumnBuilder(name, "date"),
3480
- time: () => new DateColumnBuilder(name, "time"),
3481
- dateTime: () => new TimeStampColumnBuilder(name, "datetime"),
3482
- timestamp: () => new TimeStampColumnBuilder(name, "timestamp")
3483
- });
3484
- //#endregion
3485
- //#region src/migration/front/tableMigrator.ts
3486
- var TableMigrator = class TableMigrator {
3487
- constructor(table, store) {
3488
- this.table = table;
3489
- this.store = store;
3490
- }
3491
- get primaryKey() {
3492
- return this.table.primaryKey;
3493
- }
3494
- static deserialize(data, store) {
3495
- return new TableMigrator(new TableHandler(data, store), store);
3496
- }
3497
- get tableName() {
3498
- return this.table.tableName;
3499
- }
3500
- column(columnName) {
3501
- return this.table.column(columnName);
3502
- }
3503
- showCreateTable() {
3504
- return this.table.showCreateTable();
3505
- }
3506
- getIndexes() {
3507
- return this.table.index;
3508
- }
3509
- serialize() {
3510
- return this.table.serialize();
3511
- }
3512
- addIndex(...columns) {
3513
- this.table.addIndex(...columns);
3514
- const index = new DBIndex(this.tableName, columns);
3515
- this.store.addQuery(index.addSql());
3516
- return this;
3517
- }
3518
- removeIndex(...columns) {
3519
- this.table.removeIndex(...columns);
3520
- this.store.addQuery(new DBIndex(this.tableName, columns).dropSql());
3521
- return this;
3522
- }
3523
- _addColumn(column) {
3524
- this.table.addColumn(new NormalColumn(column, this.table));
3525
- this.store.addQuery(SqlCreator.addColumn(this.tableName, column));
3526
- return this;
3527
- }
3528
- addColumn(name, create) {
3529
- const column = create(createColumn(name)).build();
3530
- return this._addColumn(column.data);
3531
- }
3532
- dropColumn(columnName) {
3533
- this.table.dropColumn(columnName);
3534
- this.store.addQuery(SqlCreator.dropColumn(this.tableName, columnName));
3535
- return this;
3536
- }
3537
- enableGQL() {
3538
- this.table.setGQLOption({
3539
- ...this.table.gqlOption,
3540
- enabled: true
3541
- });
3542
- return this;
3543
- }
3544
- setGQLOption(option) {
3545
- this.table.setGQLOption(option);
3546
- return this;
3547
- }
3548
- addForeignKey(reference) {
3549
- this.tableExists(reference.parentTable);
3550
- this.table.addForeignKey(reference);
3551
- const column = this.table.column(reference.columnName);
3552
- const targetColumn = this.store.table(reference.parentTable).column(reference.parentColumn);
3553
- if (!targetColumn) throw new Error("Column: " + reference.parentTable + "." + reference.parentColumn + " Not Exists");
3554
- if (column.dataType() !== targetColumn.dataType()) throw new Error(`${this.tableName}.${reference.columnName} AND ${reference.parentTable}.${reference.parentColumn} is different Type( ${column.dataType()} != ${targetColumn.dataType()} )`);
3555
- this.store.addQuery(SqlCreator.addForeignKey(this.tableName, column.getConstraintName(), reference));
3556
- return this;
3557
- }
3558
- changeColumnType(columnName, type) {
3559
- this.table.changeType(columnName, type);
3560
- this.store.addQuery(`ALTER TABLE ${this.tableName} MODIFY ${columnName} ${type}`);
3561
- return this;
3562
- }
3563
- tableExists(tableName) {
3564
- if (!this.store.table(tableName)) throw new Error("QueryTable: " + tableName + " Not Exists");
3565
- return true;
3566
- }
3567
- setDefault(columnName, value) {
3568
- this.table.setDefault(columnName, value);
3569
- this.store.addQuery(`ALTER TABLE ${this.tableName} ALTER ${columnName} SET DEFAULT ${SqlString.escape(value)}`);
3570
- return this;
3571
- }
3572
- get gqlOption() {
3573
- return this.table.gqlOption;
3574
- }
3575
- addGQLQuery(...queries) {
3576
- this.table.setGQLOption({
3577
- ...this.table.gqlOption,
3578
- queries: [...this.table.gqlOption.queries, ...queries]
3579
- });
3580
- return this;
3581
- }
3582
- addGQLMutation(...mutations) {
3583
- this.table.setGQLOption({
3584
- ...this.table.gqlOption,
3585
- mutations: [...this.table.gqlOption.mutations, ...mutations]
3586
- });
3587
- return this;
3588
- }
3589
- };
3590
- //#endregion
3591
- //#region src/migration/front/storeMigrator.ts
3592
- var StoreMigrator = class StoreMigrator {
3593
- constructor() {
3594
- this.tables = [];
3595
- this.migrationQueue = [];
3596
- }
3597
- static new() {
3598
- if (node_fs.default.existsSync(node_path.default.join(config().migration.dir, "initialSchema.yml"))) return StoreMigrator.deserialize(readInitialSchema());
3599
- return new StoreMigrator();
3600
- }
3601
- static deserialize(data) {
3602
- const store = new StoreMigrator();
3603
- store.tables = data.tables.map((it) => TableMigrator.deserialize(it, store));
3604
- store.resetQueue();
3605
- return store;
3606
- }
3607
- table(tableName) {
3608
- const table = this.tables.find((it) => it.tableName === tableName);
3609
- if (!table) throw new Error("QueryTable: " + tableName + " Not Found");
3610
- return table;
3611
- }
3612
- addQuery(...query) {
3613
- this.migrationQueue.push(...query);
3614
- }
3615
- createTable(tableName, tableCreator) {
3616
- if (this.tables.find((it) => it.tableName === tableName)) throw new SasatError(`${tableName} is already exist`);
3617
- const creator = new TableCreator(tableName, this);
3618
- tableCreator(creator);
3619
- const table = new TableMigrator(creator.create(), this);
3620
- this.tables.push(table);
3621
- this.addQuery(table.showCreateTable());
3622
- this.addQuery(...table.getIndexes().map((it) => it.addSql()));
3623
- return this;
3624
- }
3625
- dropTable(tableName) {
3626
- this.addQuery(`DROP TABLE ${tableName}`);
3627
- this.tables = this.tables.filter((it) => it.tableName !== tableName);
3628
- return this;
3629
- }
3630
- sql(...sql) {
3631
- this.addQuery(...sql);
3632
- return this;
3633
- }
3634
- getSql() {
3635
- return this.migrationQueue;
3636
- }
3637
- resetQueue() {
3638
- this.migrationQueue = [];
3639
- }
3640
- serialize() {
3641
- return { tables: this.tables.map((it) => it.serialize()) };
3642
- }
3643
- setConfig(conf) {
3644
- this.conf = conf;
3645
- return this;
3646
- }
3647
- getUpdateConfig() {
3648
- return this.conf;
3649
- }
3650
- };
3651
- //#endregion
3652
- //#region src/db/formatQuery.ts
3653
- const formatQuery = (str, ...params) => {
3654
- let ret = str[0];
3655
- for (let i = 0; i < params.length; i++) {
3656
- if (typeof params[i] === "function") ret += params[i]();
3657
- else if (Array.isArray(params[i])) ret += params[i].map((it) => SqlString.escape(it)).join(", ");
3658
- else ret += SqlString.escape(params[i]);
3659
- ret += str[i + 1];
3660
- }
3661
- return ret;
3662
- };
3663
- //#endregion
3664
- //#region src/db/connectors/dbClient.ts
3665
- const noop = () => {};
3666
- var SQLClient = class {
3667
- constructor() {
3668
- this.logger = noop;
3669
- }
3670
- rawQuery(sql) {
3671
- this.logger(sql);
3672
- return this.execSql(sql);
3673
- }
3674
- rawCommand(sql) {
3675
- this.logger(sql);
3676
- return this.execSql(sql);
3677
- }
3678
- query(templateString, ...params) {
3679
- return this.rawQuery(formatQuery(templateString, ...params));
3680
- }
3681
- command(templateString, ...params) {
3682
- return this.rawCommand(formatQuery(templateString, ...params));
3683
- }
3684
- };
3685
- var SQLTransaction = class extends SQLClient {};
3686
- var DBClient = class extends SQLClient {
3687
- constructor(logger = noop) {
3688
- super();
3689
- this._released = false;
3690
- this.logger = logger;
3691
- }
3692
- isReleased() {
3693
- return this._released;
3694
- }
3695
- };
3696
- //#endregion
3697
- //#region src/db/connectors/mysql/transaction.ts
3698
- var MySqlTransaction = class extends SQLTransaction {
3699
- constructor(connection) {
3700
- super();
3701
- this.connection = connection;
3702
- }
3703
- async commit() {
3704
- const result = await this.connection.commit();
3705
- await this.connection.end();
3706
- return result;
3707
- }
3708
- async rollback() {
3709
- await this.connection.rollback();
3710
- await this.connection.end();
3711
- }
3712
- async execSql(sql) {
3713
- return (await this.connection.query(sql))[0];
3714
- }
3715
- };
3716
- //#endregion
3717
- //#region src/db/connectors/mysql/poolClient.ts
3718
- var MysqlPoolClient = class extends DBClient {
3719
- constructor(poolOption, logger) {
3720
- super(logger);
3721
- this.poolOption = poolOption;
3722
- this.pool = (0, mysql2_promise.createPool)({
3723
- dateStrings: true,
3724
- ...poolOption
3725
- });
3726
- this.release = this.release.bind(this);
3727
- }
3728
- async transaction() {
3729
- const connection = await (0, mysql2_promise.createConnection)({
3730
- ...config().db,
3731
- dateStrings: true,
3732
- ...this.poolOption
3733
- });
3734
- await connection.beginTransaction();
3735
- return new MySqlTransaction(connection);
3736
- }
3737
- async release() {
3738
- await this.pool.end();
3739
- this._released = true;
3740
- }
3741
- async execSql(sql) {
3742
- return (await this.pool.query(sql))[0];
3743
- }
3744
- };
3745
- //#endregion
3746
- //#region src/db/getDbClient.ts
3747
- let client;
3748
- const getDbClient = (option, logger) => {
3749
- if (client && !client.isReleased()) return client;
3750
- client = new MysqlPoolClient({
3751
- ...config().db,
3752
- ...option
3753
- }, logger);
3754
- return client;
3755
- };
3756
- //#endregion
3757
- //#region src/migration/exec/getCurrentMigration.ts
3758
- const calcRunMigrationFileNames = (records) => {
3759
- const result = [];
3760
- records.forEach((it) => {
3761
- if (it.direction === "down") {
3762
- if (result[result.length] !== it.name) throw new Error("Invalid migration history: `down` migration must be the same migration as the last `up` migration ");
3763
- result.pop();
3764
- return;
3765
- }
3766
- result.push(it.name);
3767
- });
3768
- return result;
3769
- };
3770
- const getCurrentMigration = async (options) => {
3771
- const migrationTable = SqlString.escapeId(config().migration.table);
3772
- const files = getMigrationFileNames();
3773
- const client = getDbClient();
3774
- const query = `CREATE TABLE IF NOT EXISTS ${migrationTable} (id int auto_increment primary key , name varchar(100) not null,direction enum('up', 'down') not null, migrated_at timestamp default current_timestamp)`;
3775
- if (!options.silent) {
3776
- Console.log(`creating migration table: ${migrationTable} :: ${Buffer.from(migrationTable).toString("base64")}`);
3777
- Console.log(query);
3778
- }
3779
- await client.rawQuery(query);
3780
- const q = `SELECT name, direction FROM ${migrationTable} ORDER BY id ASC`;
3781
- if (!options.silent) Console.debug(q);
3782
- const result = await client.rawQuery(q);
3783
- console.debug(result);
3784
- if (!result.length) return;
3785
- const runs = calcRunMigrationFileNames(result);
3786
- if (runs.length === 0) return;
3787
- runs.forEach((run, i) => {
3788
- if (files[i] !== run) throw new Error(`\
3789
- Invalid migration order: Migration must be performed in the same order
3790
- Found : ${files[i]}
3791
- in migration history: ${run}`);
3792
- });
3793
- return runs[runs.length - 1];
3794
- };
3795
- //#endregion
3796
- //#region src/migration/exec/migrationFileCompiler.ts
3797
- const changeExtTsToJs = (fileName) => fileName.slice(0, -3) + ".mjs";
3798
- const compileMigrationFiles = () => {
3799
- const compiles = getMigrationFileNames().map(async (fileName) => {
3800
- const filePath = node_path.default.join(getMigrationFileDir(), fileName);
3801
- const r = await (0, esbuild.build)({
3802
- entryPoints: [filePath],
3803
- bundle: true,
3804
- outfile: changeExtTsToJs(filePath),
3805
- platform: "node",
3806
- format: "esm",
3807
- outExtension: { ".js": ".mjs" },
3808
- banner: { js: `import { createRequire as topLevelCreateRequire } from 'module';
3809
- const require = topLevelCreateRequire(import.meta.url);
3810
- import { fileURLToPath as __topLevelFileURLToPath } from 'url';
3811
- import { dirname as __topLevelDirname } from 'path';
3812
- const __filename = __topLevelFileURLToPath(import.meta.url);
3813
- const __dirname = __topLevelDirname(__filename);
3814
- ` }
3815
- });
3816
- if (r.errors.length !== 0) throw r.errors;
3817
- return fileName;
3818
- });
3819
- return Promise.all(compiles);
3820
- };
3821
- //#endregion
3822
- //#region src/migration/exec/readMigrationFile.ts
3823
- const readMigration = async (store, tsFileName, direction) => {
3824
- const instance = new (await (import(node_path.default.join(process.cwd(), config().migration.dir, changeExtTsToJs(tsFileName))))).default();
3825
- if (direction === "up") {
3826
- if (instance.beforeUp) await instance.beforeUp();
3827
- await instance.up(store);
3828
- if (instance.afterUp) await instance.afterUp();
3829
- } else {
3830
- if (instance.beforeDown) await instance.beforeDown();
3831
- await instance.down(store);
3832
- if (instance.afterDown) await instance.afterDown();
3833
- }
3834
- return store;
3835
- };
3836
- //#endregion
3837
- //#region src/migration/exec/createCurrentMigrationDataStore.ts
3838
- const createCurrentMigrationDataStore = async (targetMigrationName) => {
3839
- const allFiles = getMigrationFileNames();
3840
- let store = StoreMigrator.new();
3841
- if (!targetMigrationName) return store;
3842
- const files = allFiles.slice(0, allFiles.indexOf(targetMigrationName) + 1);
3843
- for (const tsFileName of files) store = await readMigration(store, tsFileName, "up");
3844
- store.resetQueue();
3845
- return store;
3846
- };
3847
- //#endregion
3848
- //#region src/migration/exec/getMigrationTarget.ts
3849
- const getMigrationTargets = (files, current) => {
3850
- const currentIndex = current ? files.indexOf(current) + 1 : 0;
3851
- const targetIndex = files.indexOf(config().migration.target || files[files.length - 1]) + 1;
3852
- if (currentIndex === -1 || targetIndex === -1) throw new Error("migration target not found");
3853
- if (targetIndex >= currentIndex) return {
3854
- direction: "up",
3855
- files: files.slice(currentIndex, targetIndex)
3856
- };
3857
- return {
3858
- direction: "down",
3859
- files: files.slice(targetIndex, currentIndex).reverse()
3860
- };
3861
- };
3862
- //#endregion
3863
- //#region src/migration/exec/runMigration.ts
3864
- const runMigration = async (client, store, migrationName, direction, options) => {
3865
- const sqls = store.getSql();
3866
- const conf = store.getUpdateConfig();
3867
- if (conf) setConfig(conf);
3868
- store.resetQueue();
3869
- if (!options.silent) sqls.forEach(Console.log);
3870
- if (options.dry) return;
3871
- const transaction = await client.transaction();
3872
- try {
3873
- for (const sql of sqls) await transaction.rawQuery(sql).catch((e) => {
3874
- Console.error(`ERROR ON ${migrationName}`);
3875
- Console.error(`SQL: ${sql}`);
3876
- Console.error(`MESSAGE: ${e.message}`);
3877
- process.exit(1);
3878
- });
3879
- await transaction.query`insert into ${() => config().migration.table} (name, direction) values (${[migrationName, direction]})`;
3880
- return await transaction.commit();
3881
- } catch (e) {
3882
- await transaction.rollback();
3883
- throw e;
3884
- }
3885
- };
3886
- //#endregion
3887
- //#region src/migration/controller.ts
3888
- var MigrationController = class {
3889
- async migrate(client, options) {
3890
- const fileNames = getMigrationFileNames();
3891
- console.log(4, options);
3892
- const currentMigration = await getCurrentMigration(options);
3893
- if (!options.silent) Console.log("--current migration--: " + currentMigration);
3894
- console.log(2);
3895
- let store = await createCurrentMigrationDataStore(currentMigration);
3896
- if (store.getUpdateConfig()) setConfig(store.getUpdateConfig());
3897
- console.log(1);
3898
- const target = getMigrationTargets(fileNames, currentMigration);
3899
- console.log(2);
3900
- for (const tsFileName of target.files) {
3901
- if (!options.silent) Console.log("---------\n" + tsFileName);
3902
- console.log(3, tsFileName);
3903
- store = await readMigration(store, tsFileName, target.direction);
3904
- console.log(4);
3905
- await runMigration(client, store, tsFileName, target.direction, options);
3906
- store.resetQueue();
3907
- }
3908
- return {
3909
- store: store.serialize(),
3910
- currentMigration: config().migration.target || fileNames[fileNames.length - 1]
3911
- };
3912
- }
3913
- };
3914
- //#endregion
3915
- //#region src/migration/dataStore.ts
3916
- var DataStoreHandler = class {
3917
- constructor(store) {
3918
- this.tables = store.tables.map((it) => new TableHandler(it, this));
3919
- }
3920
- table(tableName) {
3921
- const table = this.tables.find((it) => it.tableName === tableName);
3922
- if (!table) throw new Error(`Table: ${tableName} is Not Found`);
3923
- return table;
3924
- }
3925
- referencedBy(tableName) {
3926
- return this.tables.flatMap((it) => it.columns.filter((it) => it.isReference() && it.data.reference.parentTable === tableName));
3927
- }
3928
- virtualReferencedBy(tableName) {
3929
- return this.tables.flatMap((it) => it.virtualRelations.filter((it) => it.parentTable === tableName));
3930
- }
3931
- };
3932
- //#endregion
3933
- //#region src/cli/commands/migrate.ts
3934
- const migrate = async (client, options) => {
3935
- let current;
3936
- if (!options.silent) Console.log("--migration started--");
3937
- try {
3938
- if (!options.skipBuild) await compileMigrationFiles();
3939
- const conf = config();
3940
- if (conf.migration.db) setConfig({ db: conf.migration.db });
3941
- const result = await new MigrationController().migrate(client, options);
3942
- current = result.currentMigration;
3943
- if (options.generateFiles) {
3944
- const storeHandler = new DataStoreHandler(result.store);
3945
- writeCurrentSchema(result.store);
3946
- await new CodeGen_v2(storeHandler).generate();
3947
- }
3948
- if (!options.silent) Console.success(`current migration is ${current}`);
3949
- } catch (e) {
3950
- Console.error(e.message);
3951
- throw e;
3952
- }
3953
- };
3954
- //#endregion
3955
6
  //#region src/db/connectors/mysql/client.ts
3956
- var MysqlClient = class extends DBClient {
7
+ var MysqlClient = class extends require_migrate.DBClient {
3957
8
  async release() {}
3958
9
  constructor(connectionOption, logger) {
3959
10
  super(logger);
@@ -3968,7 +19,7 @@ var MysqlClient = class extends DBClient {
3968
19
  async transaction() {
3969
20
  const connection = await this.getConnection();
3970
21
  await connection.beginTransaction();
3971
- return new MySqlTransaction(connection);
22
+ return new require_migrate.MySqlTransaction(connection);
3972
23
  }
3973
24
  async execSql(sql) {
3974
25
  const connection = await this.getConnection();
@@ -4009,14 +60,14 @@ const Sql = {
4009
60
  case 1: return Sql.fn(expr);
4010
61
  }
4011
62
  },
4012
- literal: (literal) => SqlString.escape(literal.value),
4013
- fieldInCondition: (identifier) => SqlString.escapeId(identifier.table) + "." + SqlString.escapeId(identifier.name),
63
+ literal: (literal) => require_migrate.SqlString.escape(literal.value),
64
+ fieldInCondition: (identifier) => require_migrate.SqlString.escapeId(identifier.table) + "." + require_migrate.SqlString.escapeId(identifier.name),
4014
65
  fieldInSelect: (identifier) => {
4015
- const alias = identifier.alias && identifier.name !== identifier.alias ? " AS " + SqlString.escapeId(identifier.alias) : "";
4016
- return SqlString.escapeId(identifier.table) + "." + SqlString.escapeId(identifier.name) + alias;
66
+ const alias = identifier.alias && identifier.name !== identifier.alias ? " AS " + require_migrate.SqlString.escapeId(identifier.alias) : "";
67
+ return require_migrate.SqlString.escapeId(identifier.table) + "." + require_migrate.SqlString.escapeId(identifier.name) + alias;
4017
68
  },
4018
69
  identifier: (ident) => {
4019
- return SqlString.escapeId(ident.identifier);
70
+ return require_migrate.SqlString.escapeId(ident.identifier);
4020
71
  },
4021
72
  fn: (fn) => `${fn.fnName}(${fn.args.map(Sql.value).join(",")})${over(fn.over)}${fn.alias ? ` AS ${fn.alias}` : ""}`,
4022
73
  value: (v) => {
@@ -4033,7 +84,7 @@ const Sql = {
4033
84
  if (type === "start") return "%" + value;
4034
85
  return value + "%";
4035
86
  };
4036
- return `${Sql.value(expr.left)} ${operator} ${SqlString.escape(val(expr.right, expr.type))}`;
87
+ return `${Sql.value(expr.left)} ${operator} ${require_migrate.SqlString.escape(val(expr.right, expr.type))}`;
4037
88
  },
4038
89
  in: (expr) => {
4039
90
  if ("right" in expr) return `${Sql.value(expr.left)} ${expr.operator} (${expr.right.map(Sql.value).join(", ")})`;
@@ -4045,10 +96,10 @@ const Sql = {
4045
96
  paren: (expr) => "(" + Sql.booleanValue(expr.expression) + ")",
4046
97
  table: (table) => {
4047
98
  if (!table.subquery) {
4048
- if (table.alias === table.name) return SqlString.escapeId(table.name);
4049
- return SqlString.escapeId(table.name) + " AS " + SqlString.escapeId(table.alias);
99
+ if (table.alias === table.name) return require_migrate.SqlString.escapeId(table.name);
100
+ return require_migrate.SqlString.escapeId(table.name) + " AS " + require_migrate.SqlString.escapeId(table.alias);
4050
101
  }
4051
- return `(${queryToSql(table.query)}) AS ${SqlString.escapeId(table.alias)}`;
102
+ return `(${queryToSql(table.query)}) AS ${require_migrate.SqlString.escapeId(table.alias)}`;
4052
103
  },
4053
104
  join: (join) => `${join.type ? join.type + " " : ""}JOIN ${Sql.table(join.table)} ON ` + Sql.booleanValue(join.conditions),
4054
105
  booleanValue: (expr) => {
@@ -4131,7 +182,7 @@ const comparisonExpressionToSql = (exp) => {
4131
182
  }
4132
183
  if (value[0] === "BETWEEN") return `${column} BETWEEN ${sqlstring.escape(value[1])} AND ${sqlstring.escape(value[2])}`;
4133
184
  if (Object.keys(Comparison).includes(value[0])) return `${column} ${value[0]} ${sqlstring.escape(value[1])}`;
4134
- throw new SasatError("SQL PARSE ERROR");
185
+ throw new require_migrate.SasatError("SQL PARSE ERROR");
4135
186
  }).join(` ${type} `);
4136
187
  };
4137
188
  //#endregion
@@ -4243,7 +294,7 @@ const createTypeDef = (typeDefs, inputs) => {
4243
294
  //#endregion
4244
295
  //#region src/runtime/dsl/factory.ts
4245
296
  const compound = (expr, operator) => {
4246
- const active = expr.filter(nonNullable);
297
+ const active = expr.filter(require_migrate.nonNullable);
4247
298
  if (active.length === 0) return conditions.eq(literal(1), literal(1));
4248
299
  return active.reduce((acc, current) => ({
4249
300
  kind: 4,
@@ -4513,19 +564,19 @@ const makeParamsMiddleware = (update) => {
4513
564
  };
4514
565
  //#endregion
4515
566
  //#region src/runtime/dsl/mutation/mutation.ts
4516
- const escapeId = SqlString.escapeId;
567
+ const escapeId = require_migrate.SqlString.escapeId;
4517
568
  const onDuplicateKeyUpdate = (columns) => {
4518
569
  if (!columns || columns.length === 0) return "";
4519
570
  return " ON DUPLICATE KEY UPDATE " + columns.map(escapeId).map((it) => `${it} = VALUES(${it})`).join(",");
4520
571
  };
4521
572
  const createToSql = (dsl, tableInfo) => {
4522
573
  const map = tableInfo[dsl.table].columnMap;
4523
- const values = dsl.entities.map((it) => `(${it.map((it) => SqlString.escape(it)).join(",")})`).join(",");
574
+ const values = dsl.entities.map((it) => `(${it.map((it) => require_migrate.SqlString.escape(it)).join(",")})`).join(",");
4524
575
  return `INSERT ${dsl.ignore ? "IGNORE " : ""}INTO ${escapeId(dsl.table)}(${dsl.fields.map((it) => escapeId(map[it]))}) VALUES ${values} ${onDuplicateKeyUpdate(dsl.upsert)}`;
4525
576
  };
4526
577
  const updateToSql = (dsl, tableInfo) => {
4527
578
  const map = tableInfo[dsl.table].columnMap;
4528
- return `UPDATE ${escapeId(dsl.table)} SET ${dsl.values.map((it) => escapeId(map[it.field]) + " = " + SqlString.escape(it.value)).join(", ")} WHERE ${Sql.booleanValue(dsl.where)}`;
579
+ return `UPDATE ${escapeId(dsl.table)} SET ${dsl.values.map((it) => escapeId(map[it.field]) + " = " + require_migrate.SqlString.escape(it.value)).join(", ")} WHERE ${Sql.booleanValue(dsl.where)}`;
4529
580
  };
4530
581
  const deleteToSql = (dsl) => {
4531
582
  return `DELETE FROM ${escapeId(dsl.table)} WHERE ${Sql.booleanValue(dsl.where)}`;
@@ -4539,7 +590,7 @@ const joinToQueryResolveInfo = (parentTableAlias, property, fields, map, tableIn
4539
590
  tableAlias: fields.tableAlias || info.table,
4540
591
  isArray: info.array,
4541
592
  keyAliases: tableInfo[info.table].identifiableFields,
4542
- joins: Object.entries(fields.relations || {}).filter(([, value]) => value).map(([key, value]) => joinToQueryResolveInfo(info.table, key, value, map, tableInfo)).filter(nonNullable),
593
+ joins: Object.entries(fields.relations || {}).filter(([, value]) => value).map(([key, value]) => joinToQueryResolveInfo(info.table, key, value, map, tableInfo)).filter(require_migrate.nonNullable),
4543
594
  property
4544
595
  };
4545
596
  };
@@ -4548,7 +599,7 @@ const createQueryResolveInfo = (tableName, fields, map, tableInfo) => {
4548
599
  tableAlias: fields.tableAlias || tableName,
4549
600
  isArray: true,
4550
601
  keyAliases: tableInfo[tableName].identifiableFields,
4551
- joins: Object.entries(fields.relations || {}).filter(([, value]) => value).map(([key, value]) => joinToQueryResolveInfo(tableName, key, value, map, tableInfo)).filter(nonNullable),
602
+ joins: Object.entries(fields.relations || {}).filter(([, value]) => value).map(([key, value]) => joinToQueryResolveInfo(tableName, key, value, map, tableInfo)).filter(require_migrate.nonNullable),
4552
603
  property: ""
4553
604
  };
4554
605
  };
@@ -4620,7 +671,7 @@ const createQuery = (baseTableName, fields, options, tableInfo, relationMap, con
4620
671
  table.tableAlias = tableAlias;
4621
672
  tableCount++;
4622
673
  const info = tableInfo[tableName];
4623
- select.push(...unique([...table.fields.filter((it) => {
674
+ select.push(...require_migrate.unique([...table.fields.filter((it) => {
4624
675
  return notTypeName(it) && info.columnMap[it];
4625
676
  }), ...info.identifiableFields]).map((it) => {
4626
677
  const realName = info.columnMap[it] || it;
@@ -4635,7 +686,7 @@ const createQuery = (baseTableName, fields, options, tableInfo, relationMap, con
4635
686
  childTableAlias: table.tableAlias || "t" + current,
4636
687
  context
4637
688
  }), table.joinOn), "LEFT");
4638
- }).filter(nonNullable), tableAlias);
689
+ }).filter(require_migrate.nonNullable), tableAlias);
4639
690
  };
4640
691
  return {
4641
692
  select,
@@ -4646,7 +697,7 @@ const createQuery = (baseTableName, fields, options, tableInfo, relationMap, con
4646
697
  const createPagingInnerQuery = (tableName, tableAlias, fields, option, tableInfo, relationMap) => {
4647
698
  const map = tableInfo[tableName].columnMap;
4648
699
  return {
4649
- select: unique([
700
+ select: require_migrate.unique([
4650
701
  ...tableInfo[tableName].identifiableKeys,
4651
702
  ...Object.keys(fields.relations || {}).flatMap((key) => {
4652
703
  return relationMap[tableName][key]?.requiredColumns || [];
@@ -4675,7 +726,7 @@ const createPagingFieldQuery = ({ baseTableName, fields, queryOption, pagingOpti
4675
726
  //#endregion
4676
727
  //#region src/runtime/sasatDBDatasource.ts
4677
728
  var SasatDBDatasource = class {
4678
- constructor(client = getDbClient()) {
729
+ constructor(client = require_migrate.getDbClient()) {
4679
730
  this.client = client;
4680
731
  }
4681
732
  async create(entity, option) {
@@ -4812,33 +863,33 @@ const pagingOption = (option) => {
4812
863
  };
4813
864
  //#endregion
4814
865
  exports.CompositeCondition = CompositeCondition;
4815
- exports.Conditions = Conditions;
866
+ exports.Conditions = require_migrate.Conditions;
4816
867
  exports.Mutations = Mutations;
4817
868
  exports.MysqlClient = MysqlClient;
4818
869
  exports.QExpr = QExpr;
4819
870
  exports.Queries = Queries;
4820
871
  exports.SasatDBDatasource = SasatDBDatasource;
4821
872
  exports.Sql = Sql;
4822
- exports.SqlString = SqlString;
4823
- exports.assignDeep = assignDeep;
873
+ exports.SqlString = require_migrate.SqlString;
874
+ exports.assignDeep = require_migrate.assignDeep;
4824
875
  exports.createTypeDef = createTypeDef;
4825
876
  exports.dateOffset = dateOffset;
4826
877
  exports.dateToDateString = dateToDateString;
4827
878
  exports.dateToDatetimeString = dateToDatetimeString;
4828
- exports.formatQuery = formatQuery;
879
+ exports.formatQuery = require_migrate.formatQuery;
4829
880
  exports.getCurrentDateTimeString = getCurrentDateTimeString;
4830
881
  exports.getDayRange = getDayRange;
4831
882
  exports.getDayRangeQExpr = getDayRangeQExpr;
4832
- exports.getDbClient = getDbClient;
883
+ exports.getDbClient = require_migrate.getDbClient;
4833
884
  exports.getTodayDateString = getTodayDateString;
4834
885
  exports.getTodayDateTimeString = getTodayDateTimeString;
4835
886
  exports.gqlResolveInfoToField = gqlResolveInfoToField;
4836
887
  exports.makeNumberIdEncoder = makeNumberIdEncoder;
4837
888
  exports.makeParamsMiddleware = makeParamsMiddleware;
4838
889
  exports.makeResolver = makeResolver;
4839
- exports.migrate = migrate;
890
+ exports.migrate = require_migrate.migrate;
4840
891
  exports.pagingOption = pagingOption;
4841
- exports.pick = pick;
892
+ exports.pick = require_migrate.pick;
4842
893
  exports.qe = QExpr;
4843
894
  exports.queryToSql = queryToSql;
4844
- exports.setConfig = setConfig;
895
+ exports.setConfig = require_migrate.setConfig;