sasat 0.22.8 → 0.22.9

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.
@@ -0,0 +1,806 @@
1
+ import { a as getDbClient, i as SasatError, l as SqlString$1, o as MySqlTransaction, r as unique, s as DBClient, t as nonNullable } from "./util-Dkw5bD7a.mjs";
2
+ import { createConnection } from "mysql2/promise";
3
+ import * as SqlString from "sqlstring";
4
+ //#region src/db/connectors/mysql/client.ts
5
+ var MysqlClient = class extends DBClient {
6
+ async release() {}
7
+ constructor(connectionOption, logger) {
8
+ super(logger);
9
+ this.connectionOption = connectionOption;
10
+ }
11
+ getConnection() {
12
+ return createConnection({
13
+ dateStrings: true,
14
+ ...this.connectionOption
15
+ });
16
+ }
17
+ async transaction() {
18
+ const connection = await this.getConnection();
19
+ await connection.beginTransaction();
20
+ return new MySqlTransaction(connection);
21
+ }
22
+ async execSql(sql) {
23
+ const connection = await this.getConnection();
24
+ const r = await connection.query(sql);
25
+ await connection.end();
26
+ return r[0];
27
+ }
28
+ };
29
+ //#endregion
30
+ //#region src/runtime/dsl/query/sql/nodeToSql.ts
31
+ function partitionBy(ids) {
32
+ if (!ids || ids.length === 0) return "";
33
+ return `PARTITION BY ${ids.map(Sql.identifier).join(",")} `;
34
+ }
35
+ function orderBy(sorts) {
36
+ if (!sorts || sorts.length === 0) return "";
37
+ return `ORDER BY ${sorts.map(Sql.sort).join(",")} `;
38
+ }
39
+ function windowValue(value) {
40
+ if (value.type === "FOLLOWING" || value.type === "PRECEDING") return `${value.value} ${value.type}`;
41
+ return value.type;
42
+ }
43
+ function window$1(window) {
44
+ if (!window) return "";
45
+ if (window.between) return `${window.type} BETWEEN ${windowValue(window.start)} AND ${window.end}`;
46
+ return `${window.type} ${windowValue(window.value)}`;
47
+ }
48
+ function over(v) {
49
+ if (!v) return "";
50
+ return `OVER (${partitionBy(v.partitionBy)}${orderBy(v.orderBy)}${window$1(v.window)})`;
51
+ }
52
+ const Sql = {
53
+ select: (expr) => {
54
+ switch (expr.kind) {
55
+ case 15: return expr.expr;
56
+ case 0: return Sql.fieldInSelect(expr);
57
+ case 13: return Sql.identifier(expr);
58
+ case 1: return Sql.fn(expr);
59
+ }
60
+ },
61
+ literal: (literal) => SqlString$1.escape(literal.value),
62
+ fieldInCondition: (identifier) => SqlString$1.escapeId(identifier.table) + "." + SqlString$1.escapeId(identifier.name),
63
+ fieldInSelect: (identifier) => {
64
+ const alias = identifier.alias && identifier.name !== identifier.alias ? " AS " + SqlString$1.escapeId(identifier.alias) : "";
65
+ return SqlString$1.escapeId(identifier.table) + "." + SqlString$1.escapeId(identifier.name) + alias;
66
+ },
67
+ identifier: (ident) => {
68
+ return SqlString$1.escapeId(ident.identifier);
69
+ },
70
+ fn: (fn) => `${fn.fnName}(${fn.args.map(Sql.value).join(",")})${over(fn.over)}${fn.alias ? ` AS ${fn.alias}` : ""}`,
71
+ value: (v) => {
72
+ if (v.kind === 1) return Sql.fn(v);
73
+ if (v.kind === 0) return Sql.fieldInCondition(v);
74
+ if (v.kind === 13) return Sql.identifier(v);
75
+ return Sql.literal(v);
76
+ },
77
+ between: (expr) => `${Sql.value(expr.left)} BETWEEN ${Sql.value(expr.begin)} AND ${Sql.value(expr.end)}`,
78
+ contains: (expr) => {
79
+ const operator = expr.isNot ? "NOT LIKE" : "LIKE";
80
+ const val = (value, type) => {
81
+ if (type === "contains") return "%" + value + "%";
82
+ if (type === "start") return "%" + value;
83
+ return value + "%";
84
+ };
85
+ return `${Sql.value(expr.left)} ${operator} ${SqlString$1.escape(val(expr.right, expr.type))}`;
86
+ },
87
+ in: (expr) => {
88
+ if ("right" in expr) return `${Sql.value(expr.left)} ${expr.operator} (${expr.right.map(Sql.value).join(", ")})`;
89
+ return `${Sql.value(expr.left)} ${expr.operator} (${Sql.queryOrRaw(expr.query)})`;
90
+ },
91
+ comparison: (expr) => `${Sql.value(expr.left)} ${expr.operator} ${Sql.value(expr.right)}`,
92
+ compound: (expr) => `${Sql.booleanValue(expr.left)} ${expr.operator} ${Sql.booleanValue(expr.right)}`,
93
+ isNull: (expr) => `${Sql.value(expr.expr)} ${expr.isNot ? "IS NOT NULL" : "IS NULL"}`,
94
+ paren: (expr) => "(" + Sql.booleanValue(expr.expression) + ")",
95
+ table: (table) => {
96
+ if (!table.subquery) {
97
+ if (table.alias === table.name) return SqlString$1.escapeId(table.name);
98
+ return SqlString$1.escapeId(table.name) + " AS " + SqlString$1.escapeId(table.alias);
99
+ }
100
+ return `(${queryToSql(table.query)}) AS ${SqlString$1.escapeId(table.alias)}`;
101
+ },
102
+ join: (join) => `${join.type ? join.type + " " : ""}JOIN ${Sql.table(join.table)} ON ` + Sql.booleanValue(join.conditions),
103
+ booleanValue: (expr) => {
104
+ switch (expr.kind) {
105
+ case 9: return Sql.between(expr);
106
+ case 4: return Sql.compound(expr);
107
+ case 5: return Sql.comparison(expr);
108
+ case 10: return Sql.contains(expr);
109
+ case 7: return Sql.paren(expr);
110
+ case 8: return Sql.in(expr);
111
+ case 6: return Sql.isNull(expr);
112
+ case 14: return Sql.exists(expr);
113
+ case 15: return expr.expr;
114
+ }
115
+ },
116
+ exists: (expr) => {
117
+ return `EXISTS (${Sql.queryOrRaw(expr.query)})`;
118
+ },
119
+ sort: (expr) => {
120
+ const field = () => {
121
+ switch (expr.field.kind) {
122
+ case 0: return Sql.fieldInCondition(expr.field);
123
+ case 13: return Sql.identifier(expr.field);
124
+ default: return Sql.fn(expr.field);
125
+ }
126
+ };
127
+ if (expr.direction) return `${field()} ${expr.direction === "DESC" ? "DESC" : "ASC"}`;
128
+ return field();
129
+ },
130
+ sorts: (sorts) => sorts.map(Sql.sort).join(", "),
131
+ queryOrRaw: (expr) => {
132
+ if ("kind" in expr) return expr.expr;
133
+ return queryToSql(expr);
134
+ }
135
+ };
136
+ //#endregion
137
+ //#region src/runtime/dsl/query/sql/queryToSql.ts
138
+ const getJoin = (from) => {
139
+ return from.joins.flatMap((join) => [join, ...getJoin(join.table)]);
140
+ };
141
+ const getLock = (lock) => {
142
+ if (!lock) return "";
143
+ if (lock === "FOR UPDATE") return " FOR UPDATE";
144
+ return " FOR SHARE";
145
+ };
146
+ const queryToSql = (query) => {
147
+ const select = query.select.map(Sql.select).join(", ");
148
+ const join = [...getJoin(query.from), ...query.join ?? []].map(Sql.join).join(" ");
149
+ const where = query.where ? " WHERE " + Sql.booleanValue(query.where) : "";
150
+ const groupBy = query.groupBy ? " GROUP BY" + query.groupBy.cols.map(Sql.value).join(",") : "";
151
+ const having = query.having ? "HAVING " + Sql.booleanValue(query.having) : "";
152
+ const sort = query.sort && query.sort.length !== 0 ? " ORDER BY " + Sql.sorts(query.sort) : "";
153
+ const limit = query.limit ? " LIMIT " + query.limit : "";
154
+ const offset = query.offset ? " OFFSET " + query.offset : "";
155
+ if (offset && !limit) throw new Error("LIMIT is required to use OFFSET.");
156
+ return `SELECT ${select} FROM ${Sql.table(query.from)}` + join + where + groupBy + having + sort + limit + offset + getLock(query.lock);
157
+ };
158
+ //#endregion
159
+ //#region src/db/sql/expression/comparison.ts
160
+ let Comparison = /* @__PURE__ */ function(Comparison) {
161
+ Comparison["eq"] = "=";
162
+ Comparison["gt"] = ">";
163
+ Comparison["lt"] = "<";
164
+ Comparison["gte"] = ">=";
165
+ Comparison["lte"] = "<=";
166
+ Comparison["neq"] = "<>";
167
+ Comparison["like"] = "LIKE";
168
+ Comparison["notLike"] = "NOT LIKE";
169
+ return Comparison;
170
+ }({});
171
+ const comparisonExpressionToSql = (exp) => {
172
+ const type = Object.hasOwn(exp, "__type") ? exp.__type || "AND" : "AND";
173
+ return Object.entries(exp).map(([key, value]) => {
174
+ const column = SqlString.escapeId(key);
175
+ if (!Array.isArray(value)) return `${column} = ${SqlString.escape(value)}`;
176
+ if (value[0] === "IS NULL") return `${column} IS NULL`;
177
+ if (value[0] === "IS NOT NULL") return `${column} IS NOT NULL`;
178
+ if (value[0] === "IN") {
179
+ const [, ...columns] = value;
180
+ return `${column} IN (${[columns.map((column) => SqlString.escape(column)).join(", ")]})`;
181
+ }
182
+ if (value[0] === "BETWEEN") return `${column} BETWEEN ${SqlString.escape(value[1])} AND ${SqlString.escape(value[2])}`;
183
+ if (Object.keys(Comparison).includes(value[0])) return `${column} ${value[0]} ${SqlString.escape(value[1])}`;
184
+ throw new SasatError("SQL PARSE ERROR");
185
+ }).join(` ${type} `);
186
+ };
187
+ //#endregion
188
+ //#region src/db/sql/expression/conditionExpression.ts
189
+ const conditionExpressionToSql = (exp) => {
190
+ if (Array.isArray(exp)) return CompositeCondition.and(exp).toSQL();
191
+ if (exp instanceof CompositeCondition) return exp.toSQL();
192
+ return comparisonExpressionToSql(exp);
193
+ };
194
+ //#endregion
195
+ //#region src/db/sql/expression/compositeCondition.ts
196
+ var CompositeCondition = class CompositeCondition {
197
+ constructor(type, conditions) {
198
+ this.type = type;
199
+ this.conditions = conditions;
200
+ }
201
+ static or(conditions) {
202
+ return new CompositeCondition("OR", conditions);
203
+ }
204
+ static and(conditions) {
205
+ return new CompositeCondition("AND", conditions);
206
+ }
207
+ toSQL() {
208
+ return "(" + this.conditions.map(conditionExpressionToSql).join(this.type) + ")";
209
+ }
210
+ };
211
+ //#endregion
212
+ //#region src/runtime/createTypeDef.ts
213
+ const makeArgs = (args) => {
214
+ if (!args || args.length === 0) return "";
215
+ return `(${args.map((arg) => `${arg.name}: ${arg.type}`).join(", ")})`;
216
+ };
217
+ const makeTypedefString = (typeName, typedef, type) => {
218
+ const entries = Object.entries(typedef);
219
+ if (entries.length === 0) return "";
220
+ return `\
221
+ ${type} ${typeName} {
222
+ ${entries.map(([field, value]) => {
223
+ if (!value.return) throw new Error(`Return type required: ${typeName}.${field}`);
224
+ return ` ${field}${makeArgs(value.args)}: ${value.return}`;
225
+ }).join("\n")}
226
+ }
227
+ `;
228
+ };
229
+ const createTypeDef = (typeDefs, inputs) => {
230
+ const types = Object.entries(typeDefs).map(([type, fields]) => makeTypedefString(type, fields, "type"));
231
+ const input = Object.entries(inputs).map(([type, fields]) => makeTypedefString(type, fields, "input"));
232
+ return types.join("\n") + input.join("\n");
233
+ };
234
+ //#endregion
235
+ //#region src/runtime/dsl/factory.ts
236
+ const compound = (expr, operator) => {
237
+ const active = expr.filter(nonNullable);
238
+ if (active.length === 0) return conditions.eq(literal(1), literal(1));
239
+ return active.reduce((acc, current) => ({
240
+ kind: 4,
241
+ left: acc,
242
+ operator,
243
+ right: current
244
+ }));
245
+ };
246
+ const containsExpr = (isNot, type) => (left, right) => ({
247
+ kind: 10,
248
+ type,
249
+ left,
250
+ isNot,
251
+ right
252
+ });
253
+ const comparison = (operator) => (left, right) => ({
254
+ kind: 5,
255
+ left,
256
+ operator,
257
+ right
258
+ });
259
+ const and = (...expr) => compound(expr, "AND");
260
+ const or = (...expr) => compound(expr, "OR");
261
+ const field = (table, name, alias) => ({
262
+ kind: 0,
263
+ table,
264
+ name,
265
+ alias
266
+ });
267
+ const fn = (fnName, args, alias) => ({
268
+ kind: 1,
269
+ fnName,
270
+ args,
271
+ alias
272
+ });
273
+ const window = (type, value) => ({
274
+ kind: 18,
275
+ type,
276
+ between: false,
277
+ value
278
+ });
279
+ const windowBetween = (type, start, end) => ({
280
+ kind: 18,
281
+ type,
282
+ between: true,
283
+ start,
284
+ end
285
+ });
286
+ const paren = (expression) => ({
287
+ kind: 7,
288
+ expression
289
+ });
290
+ const In = (left, right) => {
291
+ if (Array.isArray(right)) {
292
+ if (right.length === 0) return conditions.eq(literal(0), literal(1));
293
+ return {
294
+ kind: 8,
295
+ left,
296
+ operator: "IN",
297
+ right: right.map(literal)
298
+ };
299
+ }
300
+ return {
301
+ kind: 8,
302
+ left,
303
+ operator: "IN",
304
+ query: right
305
+ };
306
+ };
307
+ const notIn = (left, values) => ({
308
+ kind: 8,
309
+ left,
310
+ operator: "NOT IN",
311
+ right: values.map(literal)
312
+ });
313
+ const between = (left, begin, end) => ({
314
+ kind: 9,
315
+ left,
316
+ begin,
317
+ end
318
+ });
319
+ const isNull = (isNot) => (expr) => ({
320
+ kind: 6,
321
+ expr,
322
+ isNot
323
+ });
324
+ const simpleWhere = (tableNameOrAlias, where, isOr = false) => {
325
+ return (isOr ? or : and)(...Object.entries(where).map(([f, value]) => {
326
+ const fe = field(tableNameOrAlias, f);
327
+ if (Array.isArray(value)) return comparison(value[0])(fe, literal(value[1]));
328
+ return conditions.eq(fe, literal(value));
329
+ }));
330
+ };
331
+ const exists = (query) => ({
332
+ kind: 14,
333
+ query
334
+ });
335
+ const raw = (sql) => ({
336
+ kind: 15,
337
+ expr: sql
338
+ });
339
+ const conditions = {
340
+ simpleWhere,
341
+ and,
342
+ or,
343
+ eq: comparison("="),
344
+ neq: comparison("<>"),
345
+ gt: comparison(">"),
346
+ gte: comparison(">="),
347
+ lt: comparison("<"),
348
+ lte: comparison("<="),
349
+ comparison: (left, operator, right) => comparison(operator)(left, right),
350
+ contains: containsExpr(false, "contains"),
351
+ notContains: containsExpr(true, "contains"),
352
+ startsWith: containsExpr(false, "start"),
353
+ notStartsWith: containsExpr(true, "start"),
354
+ endsWith: containsExpr(false, "end"),
355
+ notEndsWith: containsExpr(true, "end"),
356
+ in: In,
357
+ notIn,
358
+ between,
359
+ isNull: isNull(false),
360
+ isNotNull: isNull(true),
361
+ exists
362
+ };
363
+ const table = (name, joins, alias) => ({
364
+ kind: 2,
365
+ subquery: false,
366
+ name,
367
+ alias,
368
+ joins
369
+ });
370
+ const subQueryTable = (query, joins, alias) => ({
371
+ kind: 2,
372
+ subquery: true,
373
+ query,
374
+ alias,
375
+ joins
376
+ });
377
+ const join = (table, conditions, type) => ({
378
+ kind: 3,
379
+ type,
380
+ table,
381
+ conditions
382
+ });
383
+ const literal = (value) => ({
384
+ kind: 11,
385
+ value
386
+ });
387
+ const sort = (field, direction) => ({
388
+ kind: 12,
389
+ field,
390
+ direction
391
+ });
392
+ const ident = (identifier) => ({
393
+ kind: 13,
394
+ identifier
395
+ });
396
+ const QExpr = {
397
+ conditions,
398
+ ...conditions,
399
+ field,
400
+ fn,
401
+ window,
402
+ windowBetween,
403
+ paren,
404
+ table,
405
+ subQueryTable,
406
+ join,
407
+ value: literal,
408
+ sort,
409
+ order: sort,
410
+ ident,
411
+ id: ident,
412
+ raw
413
+ };
414
+ //#endregion
415
+ //#region src/runtime/date.ts
416
+ const dateOffset = (date, timeZoneHour) => {
417
+ const offset = timeZoneHour ? timeZoneHour * 60 * 60 * 1e3 : date.getTimezoneOffset() * 6e4;
418
+ return new Date(date.getTime() + offset);
419
+ };
420
+ const zeroPad = (v, len) => v.toString().padStart(len, "0");
421
+ const dateToDatetimeString = (d) => {
422
+ const year = d.getUTCFullYear();
423
+ const month = d.getUTCMonth() + 1;
424
+ const day = d.getUTCDate();
425
+ const hour = d.getUTCHours();
426
+ const minute = d.getUTCMinutes();
427
+ const second = d.getUTCSeconds();
428
+ const millisecond = d.getUTCMilliseconds();
429
+ return zeroPad(year, 4) + "-" + zeroPad(month, 2) + "-" + zeroPad(day, 2) + " " + zeroPad(hour, 2) + ":" + zeroPad(minute, 2) + ":" + zeroPad(second, 2) + "." + zeroPad(millisecond, 3);
430
+ };
431
+ const dateToDateString = (d) => {
432
+ const year = d.getUTCFullYear();
433
+ const month = d.getUTCMonth() + 1;
434
+ const day = d.getUTCDate();
435
+ return zeroPad(year, 4) + "-" + zeroPad(month, 2) + "-" + zeroPad(day, 2);
436
+ };
437
+ const getTodayDateString = (timeZoneHour) => {
438
+ const date = /* @__PURE__ */ new Date();
439
+ date.setHours(0, 0, 0, 0);
440
+ return dateToDateString(dateOffset(date, timeZoneHour));
441
+ };
442
+ const getTodayDateTimeString = (timeZoneHour) => {
443
+ const date = /* @__PURE__ */ new Date();
444
+ date.setHours(0, 0, 0, 0);
445
+ return dateToDatetimeString(dateOffset(date, timeZoneHour));
446
+ };
447
+ const getDayRange = (date, timeZoneHour) => {
448
+ date.setHours(0, 0, 0, 0);
449
+ const d = dateOffset(date, timeZoneHour || 0);
450
+ const begin = dateToDatetimeString(d);
451
+ d.setDate(d.getDate() + 1);
452
+ return [begin, dateToDatetimeString(d)];
453
+ };
454
+ const getDayRangeQExpr = (date, timeZoneHour) => {
455
+ return getDayRange(date, timeZoneHour).map(QExpr.value);
456
+ };
457
+ //#endregion
458
+ //#region src/runtime/gqlResolveInfoToField.ts
459
+ const selectionSetToField = (selections, number) => {
460
+ const result = {
461
+ fields: [],
462
+ relations: {},
463
+ tableAlias: "t" + number
464
+ };
465
+ let num = number;
466
+ for (const it of selections) {
467
+ if (it.kind !== "Field") continue;
468
+ if (it.selectionSet) {
469
+ num += 1;
470
+ const field = selectionSetToField(it.selectionSet.selections, num);
471
+ result.relations[it.name.value] = field[0];
472
+ num = field[1];
473
+ } else if (it.name.value !== "__typename") result.fields.push(it.name.value);
474
+ }
475
+ return [result, num];
476
+ };
477
+ const gqlResolveInfoToField = (info) => {
478
+ return selectionSetToField(info.fieldNodes[0].selectionSet.selections, 0)[0];
479
+ };
480
+ //#endregion
481
+ //#region src/runtime/id.ts
482
+ const makeNumberIdEncoder = (hashId) => {
483
+ return {
484
+ encode: (id) => hashId.encode(id),
485
+ decode: (id) => hashId.decode(id)[0]
486
+ };
487
+ };
488
+ //#endregion
489
+ //#region src/runtime/makeResolver.ts
490
+ const makeResolver = (resolver, middlewares = []) => {
491
+ return (...args) => {
492
+ return resolver(...middlewares.reduce((args, middleware) => {
493
+ return middleware(args);
494
+ }, args));
495
+ };
496
+ };
497
+ //#endregion
498
+ //#region src/runtime/resolverMiddleware.ts
499
+ const makeParamsMiddleware = (update) => {
500
+ return (args) => {
501
+ args[1] = update(args[1]);
502
+ return args;
503
+ };
504
+ };
505
+ //#endregion
506
+ //#region src/runtime/dsl/mutation/mutation.ts
507
+ const escapeId = SqlString$1.escapeId;
508
+ const onDuplicateKeyUpdate = (columns) => {
509
+ if (!columns || columns.length === 0) return "";
510
+ return " ON DUPLICATE KEY UPDATE " + columns.map(escapeId).map((it) => `${it} = VALUES(${it})`).join(",");
511
+ };
512
+ const createToSql = (dsl, tableInfo) => {
513
+ const map = tableInfo[dsl.table].columnMap;
514
+ const values = dsl.entities.map((it) => `(${it.map((it) => SqlString$1.escape(it)).join(",")})`).join(",");
515
+ return `INSERT ${dsl.ignore ? "IGNORE " : ""}INTO ${escapeId(dsl.table)}(${dsl.fields.map((it) => escapeId(map[it]))}) VALUES ${values} ${onDuplicateKeyUpdate(dsl.upsert)}`;
516
+ };
517
+ const updateToSql = (dsl, tableInfo) => {
518
+ const map = tableInfo[dsl.table].columnMap;
519
+ return `UPDATE ${escapeId(dsl.table)} SET ${dsl.values.map((it) => escapeId(map[it.field]) + " = " + SqlString$1.escape(it.value)).join(", ")} WHERE ${Sql.booleanValue(dsl.where)}`;
520
+ };
521
+ const deleteToSql = (dsl) => {
522
+ return `DELETE FROM ${escapeId(dsl.table)} WHERE ${Sql.booleanValue(dsl.where)}`;
523
+ };
524
+ //#endregion
525
+ //#region src/runtime/dsl/query/createQueryResolveInfo.ts
526
+ const joinToQueryResolveInfo = (parentTableAlias, property, fields, map, tableInfo) => {
527
+ const info = map[parentTableAlias][property];
528
+ if (!info) return void 0;
529
+ return {
530
+ tableAlias: fields.tableAlias || info.table,
531
+ isArray: info.array,
532
+ keyAliases: tableInfo[info.table].identifiableFields,
533
+ joins: Object.entries(fields.relations || {}).filter(([, value]) => value).map(([key, value]) => joinToQueryResolveInfo(info.table, key, value, map, tableInfo)).filter(nonNullable),
534
+ property
535
+ };
536
+ };
537
+ const createQueryResolveInfo = (tableName, fields, map, tableInfo) => {
538
+ return {
539
+ tableAlias: fields.tableAlias || tableName,
540
+ isArray: true,
541
+ keyAliases: tableInfo[tableName].identifiableFields,
542
+ joins: Object.entries(fields.relations || {}).filter(([, value]) => value).map(([key, value]) => joinToQueryResolveInfo(tableName, key, value, map, tableInfo)).filter(nonNullable),
543
+ property: ""
544
+ };
545
+ };
546
+ //#endregion
547
+ //#region src/runtime/dsl/query/sql/hydrate.ts
548
+ const rowToObjs = (row) => {
549
+ const objs = {};
550
+ for (const [key, value] of Object.entries(row)) {
551
+ const [table, column] = key.split("__");
552
+ if (!objs[table]) objs[table] = {};
553
+ objs[table][column] = value;
554
+ }
555
+ return objs;
556
+ };
557
+ const getUnique = (obj, info) => info.keyAliases.map((it) => obj[it]).join("_~_");
558
+ const execTable = (info, objs, current) => {
559
+ let entity = objs[info.tableAlias];
560
+ if (entity[info.keyAliases[0]] == null) entity = null;
561
+ let result;
562
+ let currentTarget;
563
+ if (info.isArray) if (!current) {
564
+ result = entity == null ? [] : [entity];
565
+ currentTarget = entity;
566
+ } else {
567
+ currentTarget = entity == null ? null : current.find((item) => item && info.keyAliases.every((key) => item[key] === entity[key]));
568
+ if (currentTarget) result = current;
569
+ else {
570
+ currentTarget = entity;
571
+ result = current;
572
+ if (currentTarget) result.push(currentTarget);
573
+ }
574
+ }
575
+ else {
576
+ currentTarget = current || entity;
577
+ result = currentTarget;
578
+ }
579
+ if (currentTarget !== null) for (const it of info.joins) currentTarget[it.property] = execTable(it, objs, currentTarget[it.property]);
580
+ return result;
581
+ };
582
+ /**
583
+ * to use this function require to select primary keys for every table
584
+ */
585
+ const hydrate = (data, info) => {
586
+ const result = [];
587
+ const t0mapper = {};
588
+ info.isArray = false;
589
+ for (const row of data) {
590
+ const objs = rowToObjs(row);
591
+ const currentObj = objs[info.tableAlias];
592
+ const unique = getUnique(currentObj, info);
593
+ if (t0mapper[unique] === void 0) {
594
+ t0mapper[unique] = result.length;
595
+ result.push(execTable(info, objs, currentObj));
596
+ continue;
597
+ }
598
+ const base = result[t0mapper[unique]];
599
+ execTable(info, objs, base);
600
+ }
601
+ return result;
602
+ };
603
+ //#endregion
604
+ //#region src/runtime/sql/runQuery.ts
605
+ const notTypeName = (fieldName) => fieldName !== "__typename";
606
+ const createQuery = (baseTableName, fields, options, tableInfo, relationMap, context) => {
607
+ let tableCount = 0;
608
+ const select = [];
609
+ const resolveFields = (tableName, table) => {
610
+ const tableAlias = table.tableAlias || "t" + tableCount;
611
+ table.tableAlias = tableAlias;
612
+ tableCount++;
613
+ const info = tableInfo[tableName];
614
+ select.push(...unique([...table.fields.filter((it) => {
615
+ return notTypeName(it) && info.columnMap[it];
616
+ }), ...info.identifiableFields]).map((it) => {
617
+ const realName = info.columnMap[it] || it;
618
+ return QExpr.field(tableAlias, realName, tableAlias + "__" + it);
619
+ }));
620
+ return QExpr.table(tableName, Object.entries(table.relations || {}).map(([relationName, table]) => {
621
+ const current = tableCount;
622
+ const rel = relationMap[tableName][relationName];
623
+ if (!rel) return void 0;
624
+ return QExpr.join(resolveFields(rel.table, table), QExpr.and(rel.condition({
625
+ parentTableAlias: tableAlias,
626
+ childTableAlias: table.tableAlias || "t" + current,
627
+ context
628
+ }), table.joinOn), table.joinType ?? "LEFT");
629
+ }).filter(nonNullable), tableAlias);
630
+ };
631
+ return {
632
+ select,
633
+ from: resolveFields(baseTableName, fields),
634
+ ...options
635
+ };
636
+ };
637
+ const createPagingInnerQuery = (tableName, tableAlias, fields, option, tableInfo, relationMap) => {
638
+ const map = tableInfo[tableName].columnMap;
639
+ return {
640
+ select: unique([
641
+ ...tableInfo[tableName].identifiableKeys,
642
+ ...Object.keys(fields.relations || {}).flatMap((key) => {
643
+ return relationMap[tableName][key]?.requiredColumns || [];
644
+ }),
645
+ ...fields.fields.filter((it) => notTypeName(it) && map[it]).map((it) => map[it] || it)
646
+ ]).map((it) => QExpr.field(tableAlias, it)),
647
+ from: QExpr.table(tableName, option.join || [], tableAlias),
648
+ limit: option.numberOfItem,
649
+ offset: option.offset,
650
+ where: option.where,
651
+ sort: option.sort
652
+ };
653
+ };
654
+ const createPagingFieldQuery = ({ baseTableName, fields, queryOption, pagingOption, tableInfo, relationMap, context }) => {
655
+ const innerQuery = createPagingInnerQuery(baseTableName, fields.tableAlias || "t0", fields, pagingOption, tableInfo, relationMap);
656
+ const main = createQuery(baseTableName, fields, queryOption, tableInfo, relationMap, context);
657
+ return {
658
+ select: main.select,
659
+ from: {
660
+ ...main.from,
661
+ subquery: true,
662
+ query: innerQuery
663
+ }
664
+ };
665
+ };
666
+ //#endregion
667
+ //#region src/runtime/sasatDBDatasource.ts
668
+ var SasatDBDatasource = class {
669
+ constructor(client = getDbClient()) {
670
+ this.client = client;
671
+ }
672
+ async create(entity, option) {
673
+ const obj = {
674
+ ...this.getDefaultValueString(),
675
+ ...entity
676
+ };
677
+ const fields = Object.keys(obj);
678
+ const sql = createToSql({
679
+ table: this.tableName,
680
+ fields,
681
+ entities: [fields.map((key) => obj[key])],
682
+ upsert: option?.upsert?.updateColumns,
683
+ ignore: option?.ignore
684
+ }, this.tableInfo);
685
+ const response = await this.client.rawCommand(sql);
686
+ if (!this.autoIncrementColumn) return obj;
687
+ return {
688
+ ...obj,
689
+ [this.autoIncrementColumn]: response.insertId
690
+ };
691
+ }
692
+ async createBulk(entities, option) {
693
+ if (entities.length === 0) return null;
694
+ const objects = entities.map((it) => ({
695
+ ...this.getDefaultValueString(),
696
+ ...it
697
+ }));
698
+ const keys = Object.keys(objects[0]);
699
+ const values = objects.map((it) => keys.map((key) => it[key]));
700
+ const sql = createToSql({
701
+ table: this.tableName,
702
+ fields: keys,
703
+ entities: values,
704
+ upsert: option?.upsert?.updateColumns,
705
+ ignore: option?.ignore
706
+ }, this.tableInfo);
707
+ return await this.client.rawCommand(sql);
708
+ }
709
+ async upsert(entity, updateFields = this.primaryKeys) {
710
+ return this.create(entity, { upsert: { updateColumns: this.fieldToColumn(updateFields) } });
711
+ }
712
+ update(entity) {
713
+ const sql = updateToSql({
714
+ table: this.tableName,
715
+ values: Object.entries(entity).filter(([, value]) => value !== void 0).map(([column, value]) => ({
716
+ field: column,
717
+ value
718
+ })),
719
+ where: this.createIdentifiableExpression(entity)
720
+ }, this.tableInfo);
721
+ return this.client.rawCommand(sql);
722
+ }
723
+ updateWhere(update, condition) {
724
+ const sql = updateToSql({
725
+ table: this.tableName,
726
+ values: Object.entries(update).filter(([, value]) => value !== void 0).map(([column, value]) => ({
727
+ field: column,
728
+ value
729
+ })),
730
+ where: condition
731
+ }, this.tableInfo);
732
+ return this.client.rawCommand(sql);
733
+ }
734
+ async delete(entity) {
735
+ return this.deleteWhere(this.createIdentifiableExpression(entity));
736
+ }
737
+ async deleteWhere(condition) {
738
+ const sql = deleteToSql({
739
+ table: this.tableName,
740
+ where: condition
741
+ });
742
+ return this.client.rawCommand(sql);
743
+ }
744
+ async first(fields, option, context) {
745
+ const result = await this.find(fields, option, context);
746
+ if (result.length !== 0) return result[0];
747
+ return null;
748
+ }
749
+ async find(fields = { fields: this.fields }, options, context) {
750
+ const query = createQuery(this.tableName, fields, options, this.tableInfo, this.relationMap, context);
751
+ return this.executeQuery(query, fields);
752
+ }
753
+ async findPageable(paging, fields = { fields: this.fields }, options, context) {
754
+ const query = createPagingFieldQuery({
755
+ baseTableName: this.tableName,
756
+ fields,
757
+ tableInfo: this.tableInfo,
758
+ relationMap: this.relationMap,
759
+ pagingOption: paging,
760
+ queryOption: options,
761
+ context
762
+ });
763
+ return this.executeQuery(query, fields);
764
+ }
765
+ async executeQuery(query, fields) {
766
+ const info = createQueryResolveInfo(this.tableName, fields, this.relationMap, this.tableInfo);
767
+ const sql = queryToSql(query);
768
+ return hydrate(await this.client.rawQuery(sql), info);
769
+ }
770
+ createIdentifiableExpression(entity) {
771
+ const expr = this.identifyFields.map((it) => {
772
+ const value = entity[it];
773
+ if (!value) throw new Error(`field ${it} is required`);
774
+ return QExpr.eq(QExpr.field(this.tableName, this.tableInfo[this.tableName].columnMap[it]), QExpr.value(value));
775
+ });
776
+ return QExpr.and(...expr);
777
+ }
778
+ getRelationMap() {
779
+ return this.relationMap[this.tableName];
780
+ }
781
+ fieldToColumn(fields) {
782
+ return fields.map((it) => this.tableInfo[this.tableName].columnMap[it] || it);
783
+ }
784
+ };
785
+ //#endregion
786
+ //#region src/util/dateUtil.ts
787
+ const getCurrentDateTimeString = () => {
788
+ const pad = (number) => {
789
+ if (number < 10) return "0" + number;
790
+ return number;
791
+ };
792
+ const date = /* @__PURE__ */ new Date();
793
+ return date.getFullYear() + "-" + pad(date.getMonth() + 1) + "-" + pad(date.getDate()) + " " + pad(date.getHours()) + ":" + pad(date.getMinutes()) + ":" + pad(date.getSeconds());
794
+ };
795
+ //#endregion
796
+ //#region src/runtime/pagingOption.ts
797
+ const pagingOption = (option) => {
798
+ const sort = option.order ? [QExpr.sort(QExpr.field("t1", option.order), option?.asc === false ? "DESC" : "ASC")] : [];
799
+ return {
800
+ numberOfItem: option.numberOfItem,
801
+ offset: option.offset,
802
+ sort
803
+ };
804
+ };
805
+ //#endregion
806
+ export { CompositeCondition as _, makeResolver as a, MysqlClient as b, dateOffset as c, getDayRange as d, getDayRangeQExpr as f, createTypeDef as g, QExpr as h, makeParamsMiddleware as i, dateToDateString as l, getTodayDateTimeString as m, getCurrentDateTimeString as n, makeNumberIdEncoder as o, getTodayDateString as p, SasatDBDatasource as r, gqlResolveInfoToField as s, pagingOption as t, dateToDatetimeString as u, queryToSql as v, Sql as y };