sasat 0.21.21 → 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.mjs CHANGED
@@ -1,1022 +1,863 @@
1
- import { S as SqlString$1, n as nonNullable, u as unique, g as getDbClient, a as SasatError } from './shared/sasat.CFfsuShk.mjs';
2
- export { C as Conditions, b as assignDeep, f as formatQuery, p as pick, s as setConfig } from './shared/sasat.CFfsuShk.mjs';
3
- import 'path';
4
- import 'fs-extra';
5
- import 'js-yaml';
6
- import * as SqlString from 'sqlstring';
7
- import 'mysql2';
8
- import 'util';
9
-
10
- var QueryNodeKind = /* @__PURE__ */ ((QueryNodeKind2) => {
11
- QueryNodeKind2[QueryNodeKind2["Field"] = 0] = "Field";
12
- QueryNodeKind2[QueryNodeKind2["Function"] = 1] = "Function";
13
- QueryNodeKind2[QueryNodeKind2["Table"] = 2] = "Table";
14
- QueryNodeKind2[QueryNodeKind2["Join"] = 3] = "Join";
15
- QueryNodeKind2[QueryNodeKind2["CompoundExpr"] = 4] = "CompoundExpr";
16
- QueryNodeKind2[QueryNodeKind2["ComparisonExpr"] = 5] = "ComparisonExpr";
17
- QueryNodeKind2[QueryNodeKind2["IsNullExpr"] = 6] = "IsNullExpr";
18
- QueryNodeKind2[QueryNodeKind2["Parenthesis"] = 7] = "Parenthesis";
19
- QueryNodeKind2[QueryNodeKind2["InExpr"] = 8] = "InExpr";
20
- QueryNodeKind2[QueryNodeKind2["BetweenExpr"] = 9] = "BetweenExpr";
21
- QueryNodeKind2[QueryNodeKind2["ContainsExpr"] = 10] = "ContainsExpr";
22
- QueryNodeKind2[QueryNodeKind2["Literal"] = 11] = "Literal";
23
- QueryNodeKind2[QueryNodeKind2["Sort"] = 12] = "Sort";
24
- QueryNodeKind2[QueryNodeKind2["Identifier"] = 13] = "Identifier";
25
- QueryNodeKind2[QueryNodeKind2["Exists"] = 14] = "Exists";
26
- QueryNodeKind2[QueryNodeKind2["Raw"] = 15] = "Raw";
27
- QueryNodeKind2[QueryNodeKind2["GroupBy"] = 16] = "GroupBy";
28
- QueryNodeKind2[QueryNodeKind2["Over"] = 17] = "Over";
29
- QueryNodeKind2[QueryNodeKind2["Window"] = 18] = "Window";
30
- return QueryNodeKind2;
31
- })(QueryNodeKind || {});
32
-
1
+ import { D as setConfig, a as getDbClient, b as unique, c as formatQuery, d as SasatError, j as assignDeep, m as Conditions, o as MySqlTransaction, s as DBClient, t as migrate, u as SqlString, v as nonNullable, y as pick } from "./migrate-DfAkhVPb.mjs";
2
+ import * as SqlString$1 from "sqlstring";
3
+ import { createConnection } from "mysql2/promise";
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
33
31
  function partitionBy(ids) {
34
- if (!ids || ids.length === 0) return "";
35
- return `PARTITION BY ${ids.map(Sql.identifier).join(",")} `;
32
+ if (!ids || ids.length === 0) return "";
33
+ return `PARTITION BY ${ids.map(Sql.identifier).join(",")} `;
36
34
  }
37
35
  function orderBy(sorts) {
38
- if (!sorts || sorts.length === 0) return "";
39
- return `ORDER BY ${sorts.map(Sql.sort).join(",")} `;
36
+ if (!sorts || sorts.length === 0) return "";
37
+ return `ORDER BY ${sorts.map(Sql.sort).join(",")} `;
40
38
  }
41
39
  function windowValue(value) {
42
- if (value.type === "FOLLOWING" || value.type === "PRECEDING") {
43
- return `${value.value} ${value.type}`;
44
- }
45
- return value.type;
40
+ if (value.type === "FOLLOWING" || value.type === "PRECEDING") return `${value.value} ${value.type}`;
41
+ return value.type;
46
42
  }
47
- function window$1(window2) {
48
- if (!window2) return "";
49
- if (window2.between) {
50
- return `${window2.type} BETWEEN ${windowValue(window2.start)} AND ${window2.end}`;
51
- }
52
- return `${window2.type} ${windowValue(window2.value)}`;
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)}`;
53
47
  }
54
48
  function over(v) {
55
- if (!v) return "";
56
- return `OVER (${partitionBy(v.partitionBy)}${orderBy(v.orderBy)}${window$1(v.window)})`;
49
+ if (!v) return "";
50
+ return `OVER (${partitionBy(v.partitionBy)}${orderBy(v.orderBy)}${window$1(v.window)})`;
57
51
  }
58
- const SELECT_ALIAS_SEPARATOR = "__";
59
52
  const Sql = {
60
- select: (expr) => {
61
- switch (expr.kind) {
62
- case QueryNodeKind.Raw:
63
- return expr.expr;
64
- case QueryNodeKind.Field:
65
- return Sql.fieldInSelect(expr);
66
- case QueryNodeKind.Identifier:
67
- return Sql.identifier(expr);
68
- case QueryNodeKind.Function:
69
- return Sql.fn(expr);
70
- }
71
- },
72
- literal: (literal) => SqlString$1.escape(literal.value),
73
- fieldInCondition: (identifier) => SqlString$1.escapeId(identifier.table) + "." + SqlString$1.escapeId(identifier.name),
74
- fieldInSelect: (identifier) => {
75
- const alias = identifier.alias && identifier.name !== identifier.alias ? " AS " + SqlString$1.escapeId(identifier.alias) : "";
76
- return SqlString$1.escapeId(identifier.table) + "." + SqlString$1.escapeId(identifier.name) + alias;
77
- },
78
- identifier: (ident) => {
79
- return SqlString$1.escapeId(ident.identifier);
80
- },
81
- fn: (fn) => `${fn.fnName}(${fn.args.map(Sql.value).join(",")})${over(fn.over)}${fn.alias ? ` AS ${fn.alias}` : ""}`,
82
- value: (v) => {
83
- if (v.kind === QueryNodeKind.Function) return Sql.fn(v);
84
- if (v.kind === QueryNodeKind.Field) return Sql.fieldInCondition(v);
85
- if (v.kind === QueryNodeKind.Identifier) return Sql.identifier(v);
86
- return Sql.literal(v);
87
- },
88
- between: (expr) => `${Sql.value(expr.left)} BETWEEN ${Sql.value(expr.begin)} AND ${Sql.value(
89
- expr.end
90
- )}`,
91
- contains: (expr) => {
92
- const operator = expr.isNot ? "NOT LIKE" : "LIKE";
93
- const val = (value, type) => {
94
- if (type === "contains") return "%" + value + "%";
95
- if (type === "start") return "%" + value;
96
- return value + "%";
97
- };
98
- return `${Sql.value(expr.left)} ${operator} ${SqlString$1.escape(
99
- val(expr.right, expr.type)
100
- )}`;
101
- },
102
- in: (expr) => {
103
- if ("right" in expr)
104
- return `${Sql.value(expr.left)} ${expr.operator} (${expr.right.map(Sql.value).join(", ")})`;
105
- return `${Sql.value(expr.left)} ${expr.operator} (${Sql.queryOrRaw(
106
- expr.query
107
- )})`;
108
- },
109
- comparison: (expr) => `${Sql.value(expr.left)} ${expr.operator} ${Sql.value(expr.right)}`,
110
- compound: (expr) => `${Sql.booleanValue(expr.left)} ${expr.operator} ${Sql.booleanValue(
111
- expr.right
112
- )}`,
113
- isNull: (expr) => `${Sql.value(expr.expr)} ${expr.isNot ? "IS NOT NULL" : "IS NULL"}`,
114
- paren: (expr) => "(" + Sql.booleanValue(expr.expression) + ")",
115
- table: (table) => {
116
- if (!table.subquery) {
117
- if (table.alias === table.name) return SqlString$1.escapeId(table.name);
118
- return SqlString$1.escapeId(table.name) + " AS " + SqlString$1.escapeId(table.alias);
119
- }
120
- return `(${queryToSql(table.query)}) AS ${SqlString$1.escapeId(table.alias)}`;
121
- },
122
- join: (join) => `${join.type ? join.type + " " : ""}JOIN ${Sql.table(join.table)} ON ` + Sql.booleanValue(join.conditions),
123
- booleanValue: (expr) => {
124
- switch (expr.kind) {
125
- case QueryNodeKind.BetweenExpr:
126
- return Sql.between(expr);
127
- case QueryNodeKind.CompoundExpr:
128
- return Sql.compound(expr);
129
- case QueryNodeKind.ComparisonExpr:
130
- return Sql.comparison(expr);
131
- case QueryNodeKind.ContainsExpr:
132
- return Sql.contains(expr);
133
- case QueryNodeKind.Parenthesis:
134
- return Sql.paren(expr);
135
- case QueryNodeKind.InExpr:
136
- return Sql.in(expr);
137
- case QueryNodeKind.IsNullExpr:
138
- return Sql.isNull(expr);
139
- case QueryNodeKind.Exists:
140
- return Sql.exists(expr);
141
- }
142
- },
143
- exists: (expr) => {
144
- return `EXISTS (${Sql.queryOrRaw(expr.query)})`;
145
- },
146
- sort: (expr) => {
147
- const field = () => {
148
- switch (expr.field.kind) {
149
- case QueryNodeKind.Field:
150
- return Sql.fieldInCondition(expr.field);
151
- case QueryNodeKind.Identifier:
152
- return Sql.identifier(expr.field);
153
- default:
154
- return Sql.fn(expr.field);
155
- }
156
- };
157
- if (expr.direction)
158
- return `${field()} ${expr.direction === "DESC" ? "DESC" : "ASC"}`;
159
- return field();
160
- },
161
- sorts: (sorts) => sorts.map(Sql.sort).join(", "),
162
- queryOrRaw: (expr) => {
163
- if ("kind" in expr) {
164
- return expr.expr;
165
- }
166
- return queryToSql(expr);
167
- }
168
- };
169
-
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.escape(literal.value),
62
+ fieldInCondition: (identifier) => SqlString.escapeId(identifier.table) + "." + SqlString.escapeId(identifier.name),
63
+ fieldInSelect: (identifier) => {
64
+ const alias = identifier.alias && identifier.name !== identifier.alias ? " AS " + SqlString.escapeId(identifier.alias) : "";
65
+ return SqlString.escapeId(identifier.table) + "." + SqlString.escapeId(identifier.name) + alias;
66
+ },
67
+ identifier: (ident) => {
68
+ return SqlString.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.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.escapeId(table.name);
98
+ return SqlString.escapeId(table.name) + " AS " + SqlString.escapeId(table.alias);
99
+ }
100
+ return `(${queryToSql(table.query)}) AS ${SqlString.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
+ }
114
+ },
115
+ exists: (expr) => {
116
+ return `EXISTS (${Sql.queryOrRaw(expr.query)})`;
117
+ },
118
+ sort: (expr) => {
119
+ const field = () => {
120
+ switch (expr.field.kind) {
121
+ case 0: return Sql.fieldInCondition(expr.field);
122
+ case 13: return Sql.identifier(expr.field);
123
+ default: return Sql.fn(expr.field);
124
+ }
125
+ };
126
+ if (expr.direction) return `${field()} ${expr.direction === "DESC" ? "DESC" : "ASC"}`;
127
+ return field();
128
+ },
129
+ sorts: (sorts) => sorts.map(Sql.sort).join(", "),
130
+ queryOrRaw: (expr) => {
131
+ if ("kind" in expr) return expr.expr;
132
+ return queryToSql(expr);
133
+ }
134
+ };
135
+ //#endregion
136
+ //#region src/runtime/dsl/query/sql/queryToSql.ts
170
137
  const getJoin = (from) => {
171
- return from.joins.flatMap((join) => [join, ...getJoin(join.table)]);
138
+ return from.joins.flatMap((join) => [join, ...getJoin(join.table)]);
172
139
  };
173
140
  const getLock = (lock) => {
174
- if (!lock) return "";
175
- if (lock === "FOR UPDATE") return " FOR UPDATE";
176
- return " FOR SHARE";
141
+ if (!lock) return "";
142
+ if (lock === "FOR UPDATE") return " FOR UPDATE";
143
+ return " FOR SHARE";
177
144
  };
178
145
  const queryToSql = (query) => {
179
- const select = query.select.map(Sql.select).join(", ");
180
- const join = getJoin(query.from).map(Sql.join).join(" ");
181
- const where = query.where ? " WHERE " + Sql.booleanValue(query.where) : "";
182
- const groupBy = query.groupBy ? " GROUP BY" + query.groupBy.cols.map(Sql.value).join(",") : "";
183
- const having = query.having ? "HAVING " + Sql.booleanValue(query.having) : "";
184
- const sort = query.sort && query.sort.length !== 0 ? " ORDER BY " + Sql.sorts(query.sort) : "";
185
- const limit = query.limit ? " LIMIT " + query.limit : "";
186
- const offset = query.offset ? " OFFSET " + query.offset : "";
187
- if (offset && !limit) throw new Error("LIMIT is required to use OFFSET.");
188
- return `SELECT ${select} FROM ${Sql.table(query.from)}` + join + where + groupBy + having + sort + limit + offset + getLock(query.lock);
189
- };
190
-
191
- const makeParamsMiddleware = (update) => {
192
- return (args) => {
193
- args[1] = update(args[1]);
194
- return args;
195
- };
146
+ const select = query.select.map(Sql.select).join(", ");
147
+ const join = getJoin(query.from).map(Sql.join).join(" ");
148
+ const where = query.where ? " WHERE " + Sql.booleanValue(query.where) : "";
149
+ const groupBy = query.groupBy ? " GROUP BY" + query.groupBy.cols.map(Sql.value).join(",") : "";
150
+ const having = query.having ? "HAVING " + Sql.booleanValue(query.having) : "";
151
+ const sort = query.sort && query.sort.length !== 0 ? " ORDER BY " + Sql.sorts(query.sort) : "";
152
+ const limit = query.limit ? " LIMIT " + query.limit : "";
153
+ const offset = query.offset ? " OFFSET " + query.offset : "";
154
+ if (offset && !limit) throw new Error("LIMIT is required to use OFFSET.");
155
+ return `SELECT ${select} FROM ${Sql.table(query.from)}` + join + where + groupBy + having + sort + limit + offset + getLock(query.lock);
156
+ };
157
+ //#endregion
158
+ //#region src/db/sql/expression/comparison.ts
159
+ let Comparison = /* @__PURE__ */ function(Comparison) {
160
+ Comparison["eq"] = "=";
161
+ Comparison["gt"] = ">";
162
+ Comparison["lt"] = "<";
163
+ Comparison["gte"] = ">=";
164
+ Comparison["lte"] = "<=";
165
+ Comparison["neq"] = "<>";
166
+ Comparison["like"] = "LIKE";
167
+ Comparison["notLike"] = "NOT LIKE";
168
+ return Comparison;
169
+ }({});
170
+ const comparisonExpressionToSql = (exp) => {
171
+ const type = Object.hasOwn(exp, "__type") ? exp.__type || "AND" : "AND";
172
+ return Object.entries(exp).map(([key, value]) => {
173
+ const column = SqlString$1.escapeId(key);
174
+ if (!Array.isArray(value)) return `${column} = ${SqlString$1.escape(value)}`;
175
+ if (value[0] === "IS NULL") return `${column} IS NULL`;
176
+ if (value[0] === "IS NOT NULL") return `${column} IS NOT NULL`;
177
+ if (value[0] === "IN") {
178
+ const [, ...columns] = value;
179
+ return `${column} IN (${[columns.map((column) => SqlString$1.escape(column)).join(", ")]})`;
180
+ }
181
+ if (value[0] === "BETWEEN") return `${column} BETWEEN ${SqlString$1.escape(value[1])} AND ${SqlString$1.escape(value[2])}`;
182
+ if (Object.keys(Comparison).includes(value[0])) return `${column} ${value[0]} ${SqlString$1.escape(value[1])}`;
183
+ throw new SasatError("SQL PARSE ERROR");
184
+ }).join(` ${type} `);
185
+ };
186
+ //#endregion
187
+ //#region src/db/sql/expression/conditionExpression.ts
188
+ const conditionExpressionToSql = (exp) => {
189
+ if (Array.isArray(exp)) return CompositeCondition.and(exp).toSQL();
190
+ if (exp instanceof CompositeCondition) return exp.toSQL();
191
+ return comparisonExpressionToSql(exp);
192
+ };
193
+ //#endregion
194
+ //#region src/db/sql/expression/compositeCondition.ts
195
+ var CompositeCondition = class CompositeCondition {
196
+ constructor(type, conditions) {
197
+ this.type = type;
198
+ this.conditions = conditions;
199
+ }
200
+ static or(conditions) {
201
+ return new CompositeCondition("OR", conditions);
202
+ }
203
+ static and(conditions) {
204
+ return new CompositeCondition("AND", conditions);
205
+ }
206
+ toSQL() {
207
+ return "(" + this.conditions.map(conditionExpressionToSql).join(this.type) + ")";
208
+ }
209
+ };
210
+ //#endregion
211
+ //#region src/migration/makeMutaion.ts
212
+ const formatSubscription = (subscription) => {
213
+ if (subscription === void 0 || subscription === false) return {
214
+ enabled: false,
215
+ subscriptionFilter: []
216
+ };
217
+ if (subscription === true) return {
218
+ enabled: true,
219
+ subscriptionFilter: []
220
+ };
221
+ return {
222
+ enabled: subscription.enabled,
223
+ subscriptionFilter: subscription.subscriptionFilter || []
224
+ };
196
225
  };
197
-
198
- const makeNumberIdEncoder = (hashId) => {
199
- return {
200
- encode: (id) => hashId.encode(id),
201
- decode: (id) => hashId.decode(id)[0]
202
- };
226
+ const formatOptions = (type, option) => ({
227
+ type,
228
+ noReFetch: option?.noRefetch || false,
229
+ middlewares: option?.middlewares || [],
230
+ contextFields: option?.contextFields || [],
231
+ subscription: formatSubscription(option?.subscription)
232
+ });
233
+ const Mutations = {
234
+ create: (options) => formatOptions("create", options),
235
+ update: (options) => formatOptions("update", options),
236
+ delete: (options) => formatOptions("delete", options)
203
237
  };
204
-
238
+ //#endregion
239
+ //#region src/migration/makeQuery.ts
205
240
  const single = (name, options) => ({
206
- type: "single",
207
- name,
208
- conditions: options?.conditions || [],
209
- middlewares: options?.middlewares || []
241
+ type: "single",
242
+ name,
243
+ conditions: options?.conditions || [],
244
+ middlewares: options?.middlewares || []
210
245
  });
211
246
  const listAll = (name, options) => ({
212
- type: "list-all",
213
- name,
214
- conditions: options?.conditions || [],
215
- middlewares: options?.middlewares || []
247
+ type: "list-all",
248
+ name,
249
+ conditions: options?.conditions || [],
250
+ middlewares: options?.middlewares || []
216
251
  });
217
252
  const paging = (name, options) => ({
218
- type: "list-paging",
219
- name,
220
- conditions: options?.conditions || [],
221
- middlewares: options?.middlewares || []
253
+ type: "list-paging",
254
+ name,
255
+ conditions: options?.conditions || [],
256
+ middlewares: options?.middlewares || []
222
257
  });
223
258
  const primary = (middlewares = []) => ({
224
- type: "primary",
225
- conditions: [],
226
- middlewares
259
+ type: "primary",
260
+ conditions: [],
261
+ middlewares
227
262
  });
228
263
  const Queries = {
229
- single,
230
- listAll,
231
- paging,
232
- primary
264
+ single,
265
+ listAll,
266
+ paging,
267
+ primary
233
268
  };
234
-
235
- const formatSubscription = (subscription) => {
236
- if (subscription === void 0 || subscription === false) {
237
- return {
238
- enabled: false,
239
- subscriptionFilter: []
240
- };
241
- }
242
- if (subscription === true)
243
- return {
244
- enabled: true,
245
- subscriptionFilter: []
246
- };
247
- return {
248
- enabled: subscription.enabled,
249
- subscriptionFilter: subscription.subscriptionFilter || []
250
- };
269
+ //#endregion
270
+ //#region src/runtime/createTypeDef.ts
271
+ const makeArgs = (args) => {
272
+ if (!args || args.length === 0) return "";
273
+ return `(${args.map((arg) => `${arg.name}: ${arg.type}`).join(", ")})`;
251
274
  };
252
- const formatOptions = (type, option) => ({
253
- type,
254
- noReFetch: option?.noRefetch || false,
255
- middlewares: option?.middlewares || [],
256
- contextFields: option?.contextFields || [],
257
- subscription: formatSubscription(option?.subscription)
258
- });
259
- const Mutations = {
260
- create: (options) => formatOptions("create", options),
261
- update: (options) => formatOptions("update", options),
262
- delete: (options) => formatOptions("delete", options)
275
+ const makeTypedefString = (typeName, typedef, type) => {
276
+ const entries = Object.entries(typedef);
277
+ if (entries.length === 0) return "";
278
+ return `\
279
+ ${type} ${typeName} {
280
+ ${entries.map(([field, value]) => {
281
+ if (!value.return) throw new Error(`Return type required: ${typeName}.${field}`);
282
+ return ` ${field}${makeArgs(value.args)}: ${value.return}`;
283
+ }).join("\n")}
284
+ }
285
+ `;
263
286
  };
264
-
287
+ const createTypeDef = (typeDefs, inputs) => {
288
+ const types = Object.entries(typeDefs).map(([type, fields]) => makeTypedefString(type, fields, "type"));
289
+ const input = Object.entries(inputs).map(([type, fields]) => makeTypedefString(type, fields, "input"));
290
+ return types.join("\n") + input.join("\n");
291
+ };
292
+ //#endregion
293
+ //#region src/runtime/dsl/factory.ts
265
294
  const compound = (expr, operator) => {
266
- const active = expr.filter(nonNullable);
267
- if (active.length === 0) return conditions.eq(literal(1), literal(1));
268
- return active.reduce((acc, current) => ({
269
- kind: QueryNodeKind.CompoundExpr,
270
- left: acc,
271
- operator,
272
- right: current
273
- }));
295
+ const active = expr.filter(nonNullable);
296
+ if (active.length === 0) return conditions.eq(literal(1), literal(1));
297
+ return active.reduce((acc, current) => ({
298
+ kind: 4,
299
+ left: acc,
300
+ operator,
301
+ right: current
302
+ }));
274
303
  };
275
304
  const containsExpr = (isNot, type) => (left, right) => ({
276
- kind: QueryNodeKind.ContainsExpr,
277
- type,
278
- left,
279
- isNot,
280
- right
305
+ kind: 10,
306
+ type,
307
+ left,
308
+ isNot,
309
+ right
281
310
  });
282
311
  const comparison = (operator) => (left, right) => ({
283
- kind: QueryNodeKind.ComparisonExpr,
284
- left,
285
- operator,
286
- right
312
+ kind: 5,
313
+ left,
314
+ operator,
315
+ right
287
316
  });
288
317
  const and = (...expr) => compound(expr, "AND");
289
318
  const or = (...expr) => compound(expr, "OR");
290
- const field = (table2, name, alias) => ({
291
- kind: QueryNodeKind.Field,
292
- table: table2,
293
- name,
294
- alias
319
+ const field = (table, name, alias) => ({
320
+ kind: 0,
321
+ table,
322
+ name,
323
+ alias
295
324
  });
296
325
  const fn = (fnName, args, alias) => ({
297
- kind: QueryNodeKind.Function,
298
- fnName,
299
- args,
300
- alias
326
+ kind: 1,
327
+ fnName,
328
+ args,
329
+ alias
301
330
  });
302
331
  const window = (type, value) => ({
303
- kind: QueryNodeKind.Window,
304
- type,
305
- between: false,
306
- value
332
+ kind: 18,
333
+ type,
334
+ between: false,
335
+ value
307
336
  });
308
337
  const windowBetween = (type, start, end) => ({
309
- kind: QueryNodeKind.Window,
310
- type,
311
- between: true,
312
- start,
313
- end
338
+ kind: 18,
339
+ type,
340
+ between: true,
341
+ start,
342
+ end
314
343
  });
315
344
  const paren = (expression) => ({
316
- kind: QueryNodeKind.Parenthesis,
317
- expression
345
+ kind: 7,
346
+ expression
318
347
  });
319
348
  const In = (left, right) => {
320
- if (Array.isArray(right)) {
321
- if (right.length === 0) return conditions.eq(literal(0), literal(1));
322
- return {
323
- kind: QueryNodeKind.InExpr,
324
- left,
325
- operator: "IN",
326
- right: right.map(literal)
327
- };
328
- }
329
- return {
330
- kind: QueryNodeKind.InExpr,
331
- left,
332
- operator: "IN",
333
- query: right
334
- };
349
+ if (Array.isArray(right)) {
350
+ if (right.length === 0) return conditions.eq(literal(0), literal(1));
351
+ return {
352
+ kind: 8,
353
+ left,
354
+ operator: "IN",
355
+ right: right.map(literal)
356
+ };
357
+ }
358
+ return {
359
+ kind: 8,
360
+ left,
361
+ operator: "IN",
362
+ query: right
363
+ };
335
364
  };
336
365
  const notIn = (left, values) => ({
337
- kind: QueryNodeKind.InExpr,
338
- left,
339
- operator: "NOT IN",
340
- right: values.map(literal)
366
+ kind: 8,
367
+ left,
368
+ operator: "NOT IN",
369
+ right: values.map(literal)
341
370
  });
342
371
  const between = (left, begin, end) => ({
343
- kind: QueryNodeKind.BetweenExpr,
344
- left,
345
- begin,
346
- end
372
+ kind: 9,
373
+ left,
374
+ begin,
375
+ end
347
376
  });
348
377
  const isNull = (isNot) => (expr) => ({
349
- kind: QueryNodeKind.IsNullExpr,
350
- expr,
351
- isNot
378
+ kind: 6,
379
+ expr,
380
+ isNot
352
381
  });
353
382
  const simpleWhere = (tableNameOrAlias, where, isOr = false) => {
354
- const compound2 = isOr ? or : and;
355
- return compound2(
356
- ...Object.entries(where).map(([f, value]) => {
357
- const fe = field(tableNameOrAlias, f);
358
- if (Array.isArray(value))
359
- return comparison(value[0])(fe, literal(value[1]));
360
- return conditions.eq(fe, literal(value));
361
- })
362
- );
383
+ return (isOr ? or : and)(...Object.entries(where).map(([f, value]) => {
384
+ const fe = field(tableNameOrAlias, f);
385
+ if (Array.isArray(value)) return comparison(value[0])(fe, literal(value[1]));
386
+ return conditions.eq(fe, literal(value));
387
+ }));
363
388
  };
364
389
  const exists = (query) => ({
365
- kind: QueryNodeKind.Exists,
366
- query
390
+ kind: 14,
391
+ query
367
392
  });
368
393
  const raw = (sql) => ({
369
- kind: QueryNodeKind.Raw,
370
- expr: sql
394
+ kind: 15,
395
+ expr: sql
371
396
  });
372
397
  const conditions = {
373
- simpleWhere,
374
- and,
375
- or,
376
- eq: comparison("="),
377
- neq: comparison("<>"),
378
- gt: comparison(">"),
379
- gte: comparison(">="),
380
- lt: comparison("<"),
381
- lte: comparison("<="),
382
- comparison: (left, operator, right) => comparison(operator)(left, right),
383
- contains: containsExpr(false, "contains"),
384
- notContains: containsExpr(true, "contains"),
385
- startsWith: containsExpr(false, "start"),
386
- notStartsWith: containsExpr(true, "start"),
387
- endsWith: containsExpr(false, "end"),
388
- notEndsWith: containsExpr(true, "end"),
389
- in: In,
390
- notIn,
391
- between,
392
- isNull: isNull(false),
393
- isNotNull: isNull(true),
394
- exists
398
+ simpleWhere,
399
+ and,
400
+ or,
401
+ eq: comparison("="),
402
+ neq: comparison("<>"),
403
+ gt: comparison(">"),
404
+ gte: comparison(">="),
405
+ lt: comparison("<"),
406
+ lte: comparison("<="),
407
+ comparison: (left, operator, right) => comparison(operator)(left, right),
408
+ contains: containsExpr(false, "contains"),
409
+ notContains: containsExpr(true, "contains"),
410
+ startsWith: containsExpr(false, "start"),
411
+ notStartsWith: containsExpr(true, "start"),
412
+ endsWith: containsExpr(false, "end"),
413
+ notEndsWith: containsExpr(true, "end"),
414
+ in: In,
415
+ notIn,
416
+ between,
417
+ isNull: isNull(false),
418
+ isNotNull: isNull(true),
419
+ exists
395
420
  };
396
421
  const table = (name, joins, alias) => ({
397
- kind: QueryNodeKind.Table,
398
- subquery: false,
399
- name,
400
- alias,
401
- joins
422
+ kind: 2,
423
+ subquery: false,
424
+ name,
425
+ alias,
426
+ joins
402
427
  });
403
428
  const subQueryTable = (query, joins, alias) => ({
404
- kind: QueryNodeKind.Table,
405
- subquery: true,
406
- query,
407
- alias,
408
- joins
429
+ kind: 2,
430
+ subquery: true,
431
+ query,
432
+ alias,
433
+ joins
409
434
  });
410
- const join = (table2, conditions2, type) => ({
411
- kind: QueryNodeKind.Join,
412
- type,
413
- table: table2,
414
- conditions: conditions2
435
+ const join = (table, conditions, type) => ({
436
+ kind: 3,
437
+ type,
438
+ table,
439
+ conditions
415
440
  });
416
441
  const literal = (value) => ({
417
- kind: QueryNodeKind.Literal,
418
- value
442
+ kind: 11,
443
+ value
419
444
  });
420
- const sort = (field2, direction) => ({
421
- kind: QueryNodeKind.Sort,
422
- field: field2,
423
- direction
445
+ const sort = (field, direction) => ({
446
+ kind: 12,
447
+ field,
448
+ direction
424
449
  });
425
450
  const ident = (identifier) => ({
426
- kind: QueryNodeKind.Identifier,
427
- identifier
451
+ kind: 13,
452
+ identifier
428
453
  });
429
454
  const QExpr = {
430
- conditions,
431
- ...conditions,
432
- field,
433
- fn,
434
- window,
435
- windowBetween,
436
- paren,
437
- table,
438
- subQueryTable,
439
- join,
440
- value: literal,
441
- sort,
442
- order: sort,
443
- ident,
444
- id: ident,
445
- raw
446
- };
447
-
455
+ conditions,
456
+ ...conditions,
457
+ field,
458
+ fn,
459
+ window,
460
+ windowBetween,
461
+ paren,
462
+ table,
463
+ subQueryTable,
464
+ join,
465
+ value: literal,
466
+ sort,
467
+ order: sort,
468
+ ident,
469
+ id: ident,
470
+ raw
471
+ };
472
+ //#endregion
473
+ //#region src/runtime/date.ts
474
+ const dateOffset = (date, timeZoneHour) => {
475
+ const offset = timeZoneHour ? timeZoneHour * 60 * 60 * 1e3 : date.getTimezoneOffset() * 6e4;
476
+ return new Date(date.getTime() + offset);
477
+ };
478
+ const zeroPad = (v, len) => v.toString().padStart(len, "0");
479
+ const dateToDatetimeString = (d) => {
480
+ const year = d.getUTCFullYear();
481
+ const month = d.getUTCMonth() + 1;
482
+ const day = d.getUTCDate();
483
+ const hour = d.getUTCHours();
484
+ const minute = d.getUTCMinutes();
485
+ const second = d.getUTCSeconds();
486
+ const millisecond = d.getUTCMilliseconds();
487
+ return zeroPad(year, 4) + "-" + zeroPad(month, 2) + "-" + zeroPad(day, 2) + " " + zeroPad(hour, 2) + ":" + zeroPad(minute, 2) + ":" + zeroPad(second, 2) + "." + zeroPad(millisecond, 3);
488
+ };
489
+ const dateToDateString = (d) => {
490
+ const year = d.getUTCFullYear();
491
+ const month = d.getUTCMonth() + 1;
492
+ const day = d.getUTCDate();
493
+ return zeroPad(year, 4) + "-" + zeroPad(month, 2) + "-" + zeroPad(day, 2);
494
+ };
495
+ const getTodayDateString = (timeZoneHour) => {
496
+ const date = /* @__PURE__ */ new Date();
497
+ date.setHours(0, 0, 0, 0);
498
+ return dateToDateString(dateOffset(date, timeZoneHour));
499
+ };
500
+ const getTodayDateTimeString = (timeZoneHour) => {
501
+ const date = /* @__PURE__ */ new Date();
502
+ date.setHours(0, 0, 0, 0);
503
+ return dateToDatetimeString(dateOffset(date, timeZoneHour));
504
+ };
505
+ const getDayRange = (date, timeZoneHour) => {
506
+ date.setHours(0, 0, 0, 0);
507
+ const d = dateOffset(date, timeZoneHour || 0);
508
+ const begin = dateToDatetimeString(d);
509
+ d.setDate(d.getDate() + 1);
510
+ return [begin, dateToDatetimeString(d)];
511
+ };
512
+ const getDayRangeQExpr = (date, timeZoneHour) => {
513
+ return getDayRange(date, timeZoneHour).map(QExpr.value);
514
+ };
515
+ //#endregion
516
+ //#region src/runtime/gqlResolveInfoToField.ts
448
517
  const selectionSetToField = (selections, number) => {
449
- const result = {
450
- fields: [],
451
- relations: {},
452
- tableAlias: "t" + number
453
- };
454
- let num = number;
455
- for (const it of selections) {
456
- if (it.kind !== "Field") continue;
457
- if (it.selectionSet) {
458
- num += 1;
459
- const field = selectionSetToField(it.selectionSet.selections, num);
460
- result.relations[it.name.value] = field[0];
461
- num = field[1];
462
- } else {
463
- if (it.name.value !== "__typename") result.fields.push(it.name.value);
464
- }
465
- }
466
- return [result, num];
518
+ const result = {
519
+ fields: [],
520
+ relations: {},
521
+ tableAlias: "t" + number
522
+ };
523
+ let num = number;
524
+ for (const it of selections) {
525
+ if (it.kind !== "Field") continue;
526
+ if (it.selectionSet) {
527
+ num += 1;
528
+ const field = selectionSetToField(it.selectionSet.selections, num);
529
+ result.relations[it.name.value] = field[0];
530
+ num = field[1];
531
+ } else if (it.name.value !== "__typename") result.fields.push(it.name.value);
532
+ }
533
+ return [result, num];
467
534
  };
468
535
  const gqlResolveInfoToField = (info) => {
469
- return selectionSetToField(
470
- info.fieldNodes[0].selectionSet.selections,
471
- 0
472
- )[0];
473
- };
474
-
475
- const escape = SqlString$1.escape;
476
- const escapeId = SqlString$1.escapeId;
536
+ return selectionSetToField(info.fieldNodes[0].selectionSet.selections, 0)[0];
537
+ };
538
+ //#endregion
539
+ //#region src/runtime/id.ts
540
+ const makeNumberIdEncoder = (hashId) => {
541
+ return {
542
+ encode: (id) => hashId.encode(id),
543
+ decode: (id) => hashId.decode(id)[0]
544
+ };
545
+ };
546
+ //#endregion
547
+ //#region src/runtime/makeResolver.ts
548
+ const makeResolver = (resolver, middlewares = []) => {
549
+ return (...args) => {
550
+ return resolver(...middlewares.reduce((args, middleware) => {
551
+ return middleware(args);
552
+ }, args));
553
+ };
554
+ };
555
+ //#endregion
556
+ //#region src/runtime/resolverMiddleware.ts
557
+ const makeParamsMiddleware = (update) => {
558
+ return (args) => {
559
+ args[1] = update(args[1]);
560
+ return args;
561
+ };
562
+ };
563
+ //#endregion
564
+ //#region src/runtime/dsl/mutation/mutation.ts
565
+ const escapeId = SqlString.escapeId;
477
566
  const onDuplicateKeyUpdate = (columns) => {
478
- if (!columns || columns.length === 0) return "";
479
- return " ON DUPLICATE KEY UPDATE " + columns.map(escapeId).map((it) => `${it} = VALUES(${it})`).join(",");
567
+ if (!columns || columns.length === 0) return "";
568
+ return " ON DUPLICATE KEY UPDATE " + columns.map(escapeId).map((it) => `${it} = VALUES(${it})`).join(",");
480
569
  };
481
570
  const createToSql = (dsl, tableInfo) => {
482
- const map = tableInfo[dsl.table].columnMap;
483
- const values = dsl.entities.map((it) => `(${it.map((it2) => escape(it2)).join(",")})`).join(",");
484
- return `INSERT ${dsl.ignore ? "IGNORE " : ""}INTO ${escapeId(
485
- dsl.table
486
- )}(${dsl.fields.map((it) => escapeId(map[it]))}) VALUES ${values} ${onDuplicateKeyUpdate(dsl.upsert)}`;
571
+ const map = tableInfo[dsl.table].columnMap;
572
+ const values = dsl.entities.map((it) => `(${it.map((it) => SqlString.escape(it)).join(",")})`).join(",");
573
+ return `INSERT ${dsl.ignore ? "IGNORE " : ""}INTO ${escapeId(dsl.table)}(${dsl.fields.map((it) => escapeId(map[it]))}) VALUES ${values} ${onDuplicateKeyUpdate(dsl.upsert)}`;
487
574
  };
488
575
  const updateToSql = (dsl, tableInfo) => {
489
- const map = tableInfo[dsl.table].columnMap;
490
- return `UPDATE ${escapeId(dsl.table)} SET ${dsl.values.map((it) => escapeId(map[it.field]) + " = " + escape(it.value)).join(", ")} WHERE ${Sql.booleanValue(dsl.where)}`;
576
+ const map = tableInfo[dsl.table].columnMap;
577
+ return `UPDATE ${escapeId(dsl.table)} SET ${dsl.values.map((it) => escapeId(map[it.field]) + " = " + SqlString.escape(it.value)).join(", ")} WHERE ${Sql.booleanValue(dsl.where)}`;
491
578
  };
492
579
  const deleteToSql = (dsl) => {
493
- return `DELETE FROM ${escapeId(dsl.table)} WHERE ${Sql.booleanValue(
494
- dsl.where
495
- )}`;
580
+ return `DELETE FROM ${escapeId(dsl.table)} WHERE ${Sql.booleanValue(dsl.where)}`;
496
581
  };
497
-
582
+ //#endregion
583
+ //#region src/runtime/dsl/query/createQueryResolveInfo.ts
498
584
  const joinToQueryResolveInfo = (parentTableAlias, property, fields, map, tableInfo) => {
499
- const info = map[parentTableAlias][property];
500
- if (!info) return void 0;
501
- const tableAlias = fields.tableAlias || info.table;
502
- return {
503
- tableAlias,
504
- isArray: info.array,
505
- keyAliases: tableInfo[info.table].identifiableFields,
506
- joins: Object.entries(fields.relations || {}).filter(([, value]) => value).map(
507
- ([key, value]) => joinToQueryResolveInfo(
508
- info.table,
509
- key,
510
- value,
511
- map,
512
- tableInfo
513
- )
514
- ).filter(nonNullable),
515
- property
516
- };
585
+ const info = map[parentTableAlias][property];
586
+ if (!info) return void 0;
587
+ return {
588
+ tableAlias: fields.tableAlias || info.table,
589
+ isArray: info.array,
590
+ keyAliases: tableInfo[info.table].identifiableFields,
591
+ joins: Object.entries(fields.relations || {}).filter(([, value]) => value).map(([key, value]) => joinToQueryResolveInfo(info.table, key, value, map, tableInfo)).filter(nonNullable),
592
+ property
593
+ };
517
594
  };
518
595
  const createQueryResolveInfo = (tableName, fields, map, tableInfo) => {
519
- const tableAlias = fields.tableAlias || tableName;
520
- return {
521
- tableAlias,
522
- isArray: true,
523
- keyAliases: tableInfo[tableName].identifiableFields,
524
- joins: Object.entries(fields.relations || {}).filter(([, value]) => value).map(
525
- ([key, value]) => joinToQueryResolveInfo(
526
- tableName,
527
- key,
528
- value,
529
- map,
530
- tableInfo
531
- )
532
- ).filter(nonNullable),
533
- property: ""
534
- };
535
- };
536
-
596
+ return {
597
+ tableAlias: fields.tableAlias || tableName,
598
+ isArray: true,
599
+ keyAliases: tableInfo[tableName].identifiableFields,
600
+ joins: Object.entries(fields.relations || {}).filter(([, value]) => value).map(([key, value]) => joinToQueryResolveInfo(tableName, key, value, map, tableInfo)).filter(nonNullable),
601
+ property: ""
602
+ };
603
+ };
604
+ //#endregion
605
+ //#region src/runtime/dsl/query/sql/hydrate.ts
537
606
  const rowToObjs = (row) => {
538
- const objs = {};
539
- for (const [key, value] of Object.entries(row)) {
540
- const [table, column] = key.split(SELECT_ALIAS_SEPARATOR);
541
- if (!objs[table]) {
542
- objs[table] = {};
543
- }
544
- objs[table][column] = value;
545
- }
546
- return objs;
607
+ const objs = {};
608
+ for (const [key, value] of Object.entries(row)) {
609
+ const [table, column] = key.split("__");
610
+ if (!objs[table]) objs[table] = {};
611
+ objs[table][column] = value;
612
+ }
613
+ return objs;
547
614
  };
548
615
  const getUnique = (obj, info) => info.keyAliases.map((it) => obj[it]).join("_~_");
549
616
  const execTable = (info, objs, current) => {
550
- let entity = objs[info.tableAlias];
551
- if (entity[info.keyAliases[0]] == null) entity = null;
552
- let result;
553
- let currentTarget;
554
- if (info.isArray) {
555
- if (!current) {
556
- result = entity == null ? [] : [entity];
557
- currentTarget = entity;
558
- } else {
559
- currentTarget = entity == null ? null : current.find(
560
- (item) => item && info.keyAliases.every((key) => item[key] === entity[key])
561
- );
562
- if (currentTarget) {
563
- result = current;
564
- } else {
565
- currentTarget = entity;
566
- result = current;
567
- if (currentTarget) result.push(currentTarget);
568
- }
569
- }
570
- } else {
571
- currentTarget = current || entity;
572
- result = currentTarget;
573
- }
574
- if (currentTarget !== null) {
575
- for (const it of info.joins) {
576
- currentTarget[it.property] = execTable(
577
- it,
578
- objs,
579
- currentTarget[it.property]
580
- );
581
- }
582
- }
583
- return result;
584
- };
617
+ let entity = objs[info.tableAlias];
618
+ if (entity[info.keyAliases[0]] == null) entity = null;
619
+ let result;
620
+ let currentTarget;
621
+ if (info.isArray) if (!current) {
622
+ result = entity == null ? [] : [entity];
623
+ currentTarget = entity;
624
+ } else {
625
+ currentTarget = entity == null ? null : current.find((item) => item && info.keyAliases.every((key) => item[key] === entity[key]));
626
+ if (currentTarget) result = current;
627
+ else {
628
+ currentTarget = entity;
629
+ result = current;
630
+ if (currentTarget) result.push(currentTarget);
631
+ }
632
+ }
633
+ else {
634
+ currentTarget = current || entity;
635
+ result = currentTarget;
636
+ }
637
+ if (currentTarget !== null) for (const it of info.joins) currentTarget[it.property] = execTable(it, objs, currentTarget[it.property]);
638
+ return result;
639
+ };
640
+ /**
641
+ * to use this function require to select primary keys for every table
642
+ */
585
643
  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
-
644
+ const result = [];
645
+ const t0mapper = {};
646
+ info.isArray = false;
647
+ for (const row of data) {
648
+ const objs = rowToObjs(row);
649
+ const currentObj = objs[info.tableAlias];
650
+ const unique = getUnique(currentObj, info);
651
+ if (t0mapper[unique] === void 0) {
652
+ t0mapper[unique] = result.length;
653
+ result.push(execTable(info, objs, currentObj));
654
+ continue;
655
+ }
656
+ const base = result[t0mapper[unique]];
657
+ execTable(info, objs, base);
658
+ }
659
+ return result;
660
+ };
661
+ //#endregion
662
+ //#region src/runtime/sql/runQuery.ts
604
663
  const notTypeName = (fieldName) => fieldName !== "__typename";
605
664
  const createQuery = (baseTableName, fields, options, tableInfo, relationMap, context) => {
606
- let tableCount = 0;
607
- const select = [];
608
- const resolveFields = (tableName, table) => {
609
- const tableAlias = table.tableAlias || "t" + tableCount;
610
- table.tableAlias = tableAlias;
611
- tableCount++;
612
- const info = tableInfo[tableName];
613
- select.push(
614
- ...unique([
615
- ...table.fields.filter((it) => {
616
- return notTypeName(it) && info.columnMap[it];
617
- }),
618
- ...info.identifiableFields
619
- ]).map((it) => {
620
- const realName = info.columnMap[it] || it;
621
- return QExpr.field(
622
- tableAlias,
623
- realName,
624
- tableAlias + SELECT_ALIAS_SEPARATOR + it
625
- );
626
- })
627
- );
628
- return QExpr.table(
629
- tableName,
630
- Object.entries(table.relations || {}).map(([relationName, table2]) => {
631
- const current = tableCount;
632
- const rel = relationMap[tableName][relationName];
633
- if (!rel) return void 0;
634
- return QExpr.join(
635
- resolveFields(rel.table, table2),
636
- QExpr.and(
637
- rel.condition({
638
- parentTableAlias: tableAlias,
639
- childTableAlias: table2.tableAlias || "t" + current,
640
- context
641
- }),
642
- table2.joinOn
643
- ),
644
- "LEFT"
645
- );
646
- }).filter(nonNullable),
647
- tableAlias
648
- );
649
- };
650
- const from = resolveFields(baseTableName, fields);
651
- return {
652
- select,
653
- from,
654
- ...options
655
- };
665
+ let tableCount = 0;
666
+ const select = [];
667
+ const resolveFields = (tableName, table) => {
668
+ const tableAlias = table.tableAlias || "t" + tableCount;
669
+ table.tableAlias = tableAlias;
670
+ tableCount++;
671
+ const info = tableInfo[tableName];
672
+ select.push(...unique([...table.fields.filter((it) => {
673
+ return notTypeName(it) && info.columnMap[it];
674
+ }), ...info.identifiableFields]).map((it) => {
675
+ const realName = info.columnMap[it] || it;
676
+ return QExpr.field(tableAlias, realName, tableAlias + "__" + it);
677
+ }));
678
+ return QExpr.table(tableName, Object.entries(table.relations || {}).map(([relationName, table]) => {
679
+ const current = tableCount;
680
+ const rel = relationMap[tableName][relationName];
681
+ if (!rel) return void 0;
682
+ return QExpr.join(resolveFields(rel.table, table), QExpr.and(rel.condition({
683
+ parentTableAlias: tableAlias,
684
+ childTableAlias: table.tableAlias || "t" + current,
685
+ context
686
+ }), table.joinOn), "LEFT");
687
+ }).filter(nonNullable), tableAlias);
688
+ };
689
+ return {
690
+ select,
691
+ from: resolveFields(baseTableName, fields),
692
+ ...options
693
+ };
656
694
  };
657
695
  const createPagingInnerQuery = (tableName, tableAlias, fields, option, tableInfo, relationMap) => {
658
- const map = tableInfo[tableName].columnMap;
659
- return {
660
- select: unique([
661
- ...tableInfo[tableName].identifiableKeys,
662
- ...Object.keys(fields.relations || {}).flatMap((key) => {
663
- return relationMap[tableName][key]?.requiredColumns || [];
664
- }),
665
- ...fields.fields.filter((it) => notTypeName(it) && map[it]).map((it) => map[it] || it)
666
- ]).map((it) => QExpr.field(tableAlias, it)),
667
- from: QExpr.table(tableName, option.join || [], tableAlias),
668
- limit: option.numberOfItem,
669
- offset: option.offset,
670
- where: option.where,
671
- sort: option.sort
672
- };
673
- };
674
- const createPagingFieldQuery = ({
675
- baseTableName,
676
- fields,
677
- queryOption,
678
- pagingOption,
679
- tableInfo,
680
- relationMap,
681
- context
682
- }) => {
683
- const tableAlias = fields.tableAlias || "t0";
684
- const innerQuery = createPagingInnerQuery(
685
- baseTableName,
686
- tableAlias,
687
- fields,
688
- pagingOption,
689
- tableInfo,
690
- relationMap
691
- );
692
- const main = createQuery(
693
- baseTableName,
694
- fields,
695
- queryOption,
696
- tableInfo,
697
- relationMap,
698
- context
699
- );
700
- return {
701
- select: main.select,
702
- from: {
703
- ...main.from,
704
- subquery: true,
705
- query: innerQuery
706
- }
707
- };
708
- };
709
-
710
- class SasatDBDatasource {
711
- constructor(client = getDbClient()) {
712
- this.client = client;
713
- }
714
- queryLogger = noop;
715
- commandLogger = noop;
716
- async create(entity, option) {
717
- const obj = {
718
- ...this.getDefaultValueString(),
719
- ...entity
720
- };
721
- const fields = Object.keys(obj);
722
- const dsl = {
723
- table: this.tableName,
724
- fields,
725
- entities: [fields.map((key) => obj[key])],
726
- upsert: option?.upsert?.updateColumns,
727
- ignore: option?.ignore
728
- };
729
- const sql = createToSql(dsl, this.tableInfo);
730
- this.commandLogger(sql);
731
- const response = await this.client.rawCommand(sql);
732
- if (!this.autoIncrementColumn) return obj;
733
- return {
734
- ...obj,
735
- [this.autoIncrementColumn]: response.insertId
736
- };
737
- }
738
- async createBulk(entities, option) {
739
- const objects = entities.map((it) => ({
740
- ...this.getDefaultValueString(),
741
- ...it
742
- }));
743
- const keys = Object.keys(objects[0]);
744
- const values = objects.map((it) => keys.map((key) => it[key]));
745
- const dsl = {
746
- table: this.tableName,
747
- fields: keys,
748
- entities: values,
749
- upsert: option?.upsert?.updateColumns,
750
- ignore: option?.ignore
751
- };
752
- const sql = createToSql(dsl, this.tableInfo);
753
- this.commandLogger(sql);
754
- return await this.client.rawCommand(sql);
755
- }
756
- async upsert(entity, updateFields = this.primaryKeys) {
757
- return this.create(entity, {
758
- upsert: {
759
- updateColumns: this.fieldToColumn(updateFields)
760
- }
761
- });
762
- }
763
- update(entity) {
764
- const dsl = {
765
- table: this.tableName,
766
- values: Object.entries(entity).filter(([, value]) => value !== void 0).map(([column, value]) => ({
767
- field: column,
768
- value
769
- })),
770
- where: this.createIdentifiableExpression(entity)
771
- };
772
- const sql = updateToSql(dsl, this.tableInfo);
773
- this.commandLogger(sql);
774
- return this.client.rawCommand(sql);
775
- }
776
- updateWhere(update, condition) {
777
- const dsl = {
778
- table: this.tableName,
779
- values: Object.entries(update).filter(([, value]) => value !== void 0).map(([column, value]) => ({
780
- field: column,
781
- value
782
- })),
783
- where: condition
784
- };
785
- const sql = updateToSql(dsl, this.tableInfo);
786
- this.commandLogger(sql);
787
- return this.client.rawCommand(sql);
788
- }
789
- async delete(entity) {
790
- return this.deleteWhere(this.createIdentifiableExpression(entity));
791
- }
792
- async deleteWhere(condition) {
793
- const dsl = {
794
- table: this.tableName,
795
- where: condition
796
- };
797
- const sql = deleteToSql(dsl);
798
- this.commandLogger(sql);
799
- return this.client.rawCommand(sql);
800
- }
801
- async first(fields, option, context) {
802
- const result = await this.find(fields, option, context);
803
- if (result.length !== 0) return result[0];
804
- return null;
805
- }
806
- async find(fields = { fields: this.fields }, options, context) {
807
- const query = createQuery(
808
- this.tableName,
809
- fields,
810
- options,
811
- this.tableInfo,
812
- this.relationMap,
813
- context
814
- );
815
- return this.executeQuery(query, fields);
816
- }
817
- async findPageable(paging, fields = { fields: this.fields }, options, context) {
818
- const query = createPagingFieldQuery({
819
- baseTableName: this.tableName,
820
- fields,
821
- tableInfo: this.tableInfo,
822
- relationMap: this.relationMap,
823
- pagingOption: paging,
824
- queryOption: options,
825
- context
826
- });
827
- return this.executeQuery(query, fields);
828
- }
829
- async executeQuery(query, fields) {
830
- const info = createQueryResolveInfo(
831
- this.tableName,
832
- fields,
833
- this.relationMap,
834
- this.tableInfo
835
- );
836
- const sql = queryToSql(query);
837
- this.queryLogger(sql);
838
- const resultRows = await this.client.rawQuery(sql);
839
- return hydrate(resultRows, info);
840
- }
841
- createIdentifiableExpression(entity) {
842
- const expr = this.identifyFields.map((it) => {
843
- const value = entity[it];
844
- if (!value) throw new Error(`field ${it} is required`);
845
- return QExpr.eq(
846
- QExpr.field(this.tableName, this.tableInfo[this.tableName].columnMap[it]),
847
- QExpr.value(value)
848
- );
849
- });
850
- return QExpr.and(...expr);
851
- }
852
- getRelationMap() {
853
- return this.relationMap[this.tableName];
854
- }
855
- fieldToColumn(fields) {
856
- return fields.map((it) => this.tableInfo[this.tableName].columnMap[it] || it);
857
- }
858
- }
859
- const noop = () => {
860
- };
861
-
696
+ const map = tableInfo[tableName].columnMap;
697
+ return {
698
+ select: unique([
699
+ ...tableInfo[tableName].identifiableKeys,
700
+ ...Object.keys(fields.relations || {}).flatMap((key) => {
701
+ return relationMap[tableName][key]?.requiredColumns || [];
702
+ }),
703
+ ...fields.fields.filter((it) => notTypeName(it) && map[it]).map((it) => map[it] || it)
704
+ ]).map((it) => QExpr.field(tableAlias, it)),
705
+ from: QExpr.table(tableName, option.join || [], tableAlias),
706
+ limit: option.numberOfItem,
707
+ offset: option.offset,
708
+ where: option.where,
709
+ sort: option.sort
710
+ };
711
+ };
712
+ const createPagingFieldQuery = ({ baseTableName, fields, queryOption, pagingOption, tableInfo, relationMap, context }) => {
713
+ const innerQuery = createPagingInnerQuery(baseTableName, fields.tableAlias || "t0", fields, pagingOption, tableInfo, relationMap);
714
+ const main = createQuery(baseTableName, fields, queryOption, tableInfo, relationMap, context);
715
+ return {
716
+ select: main.select,
717
+ from: {
718
+ ...main.from,
719
+ subquery: true,
720
+ query: innerQuery
721
+ }
722
+ };
723
+ };
724
+ //#endregion
725
+ //#region src/runtime/sasatDBDatasource.ts
726
+ var SasatDBDatasource = class {
727
+ constructor(client = getDbClient()) {
728
+ this.client = client;
729
+ }
730
+ async create(entity, option) {
731
+ const obj = {
732
+ ...this.getDefaultValueString(),
733
+ ...entity
734
+ };
735
+ const fields = Object.keys(obj);
736
+ const sql = createToSql({
737
+ table: this.tableName,
738
+ fields,
739
+ entities: [fields.map((key) => obj[key])],
740
+ upsert: option?.upsert?.updateColumns,
741
+ ignore: option?.ignore
742
+ }, this.tableInfo);
743
+ const response = await this.client.rawCommand(sql);
744
+ if (!this.autoIncrementColumn) return obj;
745
+ return {
746
+ ...obj,
747
+ [this.autoIncrementColumn]: response.insertId
748
+ };
749
+ }
750
+ async createBulk(entities, option) {
751
+ const objects = entities.map((it) => ({
752
+ ...this.getDefaultValueString(),
753
+ ...it
754
+ }));
755
+ const keys = Object.keys(objects[0]);
756
+ const values = objects.map((it) => keys.map((key) => it[key]));
757
+ const sql = createToSql({
758
+ table: this.tableName,
759
+ fields: keys,
760
+ entities: values,
761
+ upsert: option?.upsert?.updateColumns,
762
+ ignore: option?.ignore
763
+ }, this.tableInfo);
764
+ return await this.client.rawCommand(sql);
765
+ }
766
+ async upsert(entity, updateFields = this.primaryKeys) {
767
+ return this.create(entity, { upsert: { updateColumns: this.fieldToColumn(updateFields) } });
768
+ }
769
+ update(entity) {
770
+ const sql = updateToSql({
771
+ table: this.tableName,
772
+ values: Object.entries(entity).filter(([, value]) => value !== void 0).map(([column, value]) => ({
773
+ field: column,
774
+ value
775
+ })),
776
+ where: this.createIdentifiableExpression(entity)
777
+ }, this.tableInfo);
778
+ return this.client.rawCommand(sql);
779
+ }
780
+ updateWhere(update, condition) {
781
+ const sql = updateToSql({
782
+ table: this.tableName,
783
+ values: Object.entries(update).filter(([, value]) => value !== void 0).map(([column, value]) => ({
784
+ field: column,
785
+ value
786
+ })),
787
+ where: condition
788
+ }, this.tableInfo);
789
+ return this.client.rawCommand(sql);
790
+ }
791
+ async delete(entity) {
792
+ return this.deleteWhere(this.createIdentifiableExpression(entity));
793
+ }
794
+ async deleteWhere(condition) {
795
+ const sql = deleteToSql({
796
+ table: this.tableName,
797
+ where: condition
798
+ });
799
+ return this.client.rawCommand(sql);
800
+ }
801
+ async first(fields, option, context) {
802
+ const result = await this.find(fields, option, context);
803
+ if (result.length !== 0) return result[0];
804
+ return null;
805
+ }
806
+ async find(fields = { fields: this.fields }, options, context) {
807
+ const query = createQuery(this.tableName, fields, options, this.tableInfo, this.relationMap, context);
808
+ return this.executeQuery(query, fields);
809
+ }
810
+ async findPageable(paging, fields = { fields: this.fields }, options, context) {
811
+ const query = createPagingFieldQuery({
812
+ baseTableName: this.tableName,
813
+ fields,
814
+ tableInfo: this.tableInfo,
815
+ relationMap: this.relationMap,
816
+ pagingOption: paging,
817
+ queryOption: options,
818
+ context
819
+ });
820
+ return this.executeQuery(query, fields);
821
+ }
822
+ async executeQuery(query, fields) {
823
+ const info = createQueryResolveInfo(this.tableName, fields, this.relationMap, this.tableInfo);
824
+ const sql = queryToSql(query);
825
+ return hydrate(await this.client.rawQuery(sql), info);
826
+ }
827
+ createIdentifiableExpression(entity) {
828
+ const expr = this.identifyFields.map((it) => {
829
+ const value = entity[it];
830
+ if (!value) throw new Error(`field ${it} is required`);
831
+ return QExpr.eq(QExpr.field(this.tableName, this.tableInfo[this.tableName].columnMap[it]), QExpr.value(value));
832
+ });
833
+ return QExpr.and(...expr);
834
+ }
835
+ getRelationMap() {
836
+ return this.relationMap[this.tableName];
837
+ }
838
+ fieldToColumn(fields) {
839
+ return fields.map((it) => this.tableInfo[this.tableName].columnMap[it] || it);
840
+ }
841
+ };
842
+ //#endregion
843
+ //#region src/util/dateUtil.ts
862
844
  const getCurrentDateTimeString = () => {
863
- const pad = (number) => {
864
- if (number < 10) {
865
- return "0" + number;
866
- }
867
- return number;
868
- };
869
- const date = /* @__PURE__ */ new Date();
870
- return date.getFullYear() + "-" + pad(date.getMonth() + 1) + "-" + pad(date.getDate()) + " " + pad(date.getHours()) + ":" + pad(date.getMinutes()) + ":" + pad(date.getSeconds());
871
- };
872
-
873
- const makeArgs = (args) => {
874
- if (!args || args.length === 0) return "";
875
- return `(${args.map((arg) => `${arg.name}: ${arg.type}`).join(", ")})`;
876
- };
877
- const makeTypedefString = (typeName, typedef, type) => {
878
- const entries = Object.entries(typedef);
879
- if (entries.length === 0) return "";
880
- return `${type} ${typeName} {
881
- ${entries.map(([field, value]) => {
882
- if (!value.return)
883
- throw new Error(`Return type required: ${typeName}.${field}`);
884
- return ` ${field}${makeArgs(value.args)}: ${value.return}`;
885
- }).join("\n")}
886
- }
887
- `;
888
- };
889
- const createTypeDef = (typeDefs, inputs) => {
890
- const types = Object.entries(typeDefs).map(
891
- ([type, fields]) => makeTypedefString(type, fields, "type")
892
- );
893
- const input = Object.entries(inputs).map(
894
- ([type, fields]) => makeTypedefString(type, fields, "input")
895
- );
896
- return types.join("\n") + input.join("\n");
897
- };
898
-
899
- var Comparison = /* @__PURE__ */ ((Comparison2) => {
900
- Comparison2["eq"] = "=";
901
- Comparison2["gt"] = ">";
902
- Comparison2["lt"] = "<";
903
- Comparison2["gte"] = ">=";
904
- Comparison2["lte"] = "<=";
905
- Comparison2["neq"] = "<>";
906
- Comparison2["like"] = "LIKE";
907
- Comparison2["notLike"] = "NOT LIKE";
908
- return Comparison2;
909
- })(Comparison || {});
910
- const comparisonExpressionToSql = (exp) => {
911
- const type = Object.prototype.hasOwnProperty.call(exp, "__type") ? exp.__type || "AND" : "AND";
912
- return Object.entries(exp).map(([key, value]) => {
913
- const column = SqlString.escapeId(key);
914
- if (!Array.isArray(value))
915
- return `${column} = ${SqlString.escape(value)}`;
916
- if (value[0] === "IS NULL") return `${column} IS NULL`;
917
- if (value[0] === "IS NOT NULL") return `${column} IS NOT NULL`;
918
- if (value[0] === "IN") {
919
- const [, ...columns] = value;
920
- return `${column} IN (${[
921
- columns.map((column2) => SqlString.escape(column2)).join(", ")
922
- ]})`;
923
- }
924
- if (value[0] === "BETWEEN")
925
- return `${column} BETWEEN ${SqlString.escape(
926
- value[1]
927
- )} AND ${SqlString.escape(value[2])}`;
928
- if (Object.keys(Comparison).includes(value[0]))
929
- return `${column} ${value[0]} ${SqlString.escape(value[1])}`;
930
- throw new SasatError("SQL PARSE ERROR");
931
- }).join(` ${type} `);
932
- };
933
-
934
- const conditionExpressionToSql = (exp) => {
935
- if (Array.isArray(exp)) {
936
- return CompositeCondition.and(exp).toSQL();
937
- }
938
- if (exp instanceof CompositeCondition) return exp.toSQL();
939
- return comparisonExpressionToSql(exp);
940
- };
941
-
942
- class CompositeCondition {
943
- constructor(type, conditions) {
944
- this.type = type;
945
- this.conditions = conditions;
946
- }
947
- static or(conditions) {
948
- return new CompositeCondition("OR", conditions);
949
- }
950
- static and(conditions) {
951
- return new CompositeCondition("AND", conditions);
952
- }
953
- toSQL() {
954
- return "(" + this.conditions.map(conditionExpressionToSql).join(this.type) + ")";
955
- }
956
- }
957
-
958
- const dateOffset = (date, timeZoneHour) => {
959
- const offset = timeZoneHour ? timeZoneHour * 60 * 60 * 1e3 : date.getTimezoneOffset() * 6e4;
960
- return new Date(date.getTime() + offset);
961
- };
962
- const zeroPad = (v, len) => v.toString().padStart(len, "0");
963
- const dateToDatetimeString = (d) => {
964
- const year = d.getUTCFullYear();
965
- const month = d.getUTCMonth() + 1;
966
- const day = d.getUTCDate();
967
- const hour = d.getUTCHours();
968
- const minute = d.getUTCMinutes();
969
- const second = d.getUTCSeconds();
970
- const millisecond = d.getUTCMilliseconds();
971
- return zeroPad(year, 4) + "-" + zeroPad(month, 2) + "-" + zeroPad(day, 2) + " " + zeroPad(hour, 2) + ":" + zeroPad(minute, 2) + ":" + zeroPad(second, 2) + "." + zeroPad(millisecond, 3);
972
- };
973
- const dateToDateString = (d) => {
974
- const year = d.getUTCFullYear();
975
- const month = d.getUTCMonth() + 1;
976
- const day = d.getUTCDate();
977
- return zeroPad(year, 4) + "-" + zeroPad(month, 2) + "-" + zeroPad(day, 2);
978
- };
979
- const getTodayDateString = (timeZoneHour) => {
980
- const date = /* @__PURE__ */ new Date();
981
- date.setHours(0, 0, 0, 0);
982
- return dateToDateString(dateOffset(date, timeZoneHour));
983
- };
984
- const getTodayDateTimeString = (timeZoneHour) => {
985
- const date = /* @__PURE__ */ new Date();
986
- date.setHours(0, 0, 0, 0);
987
- return dateToDatetimeString(dateOffset(date, timeZoneHour));
988
- };
989
- const getDayRange = (date, timeZoneHour) => {
990
- date.setHours(0, 0, 0, 0);
991
- const d = dateOffset(date, timeZoneHour || 0);
992
- const begin = dateToDatetimeString(d);
993
- d.setDate(d.getDate() + 1);
994
- return [begin, dateToDatetimeString(d)];
995
- };
996
- const getDayRangeQExpr = (date, timeZoneHour) => {
997
- return getDayRange(date, timeZoneHour).map(QExpr.value);
998
- };
999
-
1000
- const makeResolver = (resolver, middlewares = []) => {
1001
- return (...args) => {
1002
- const newArgs = middlewares.reduce(
1003
- (args2, middleware) => {
1004
- return middleware(args2);
1005
- },
1006
- args
1007
- );
1008
- return resolver(...newArgs);
1009
- };
1010
- };
1011
-
845
+ const pad = (number) => {
846
+ if (number < 10) return "0" + number;
847
+ return number;
848
+ };
849
+ const date = /* @__PURE__ */ new Date();
850
+ return date.getFullYear() + "-" + pad(date.getMonth() + 1) + "-" + pad(date.getDate()) + " " + pad(date.getHours()) + ":" + pad(date.getMinutes()) + ":" + pad(date.getSeconds());
851
+ };
852
+ //#endregion
853
+ //#region src/runtime/pagingOption.ts
1012
854
  const pagingOption = (option) => {
1013
- const sort = option.order ? [
1014
- QExpr.sort(
1015
- QExpr.field("t1", option.order),
1016
- option?.asc === false ? "DESC" : "ASC"
1017
- )
1018
- ] : [];
1019
- return { numberOfItem: option.numberOfItem, offset: option.offset, sort };
1020
- };
1021
-
1022
- export { CompositeCondition, Mutations, QExpr, Queries, SasatDBDatasource, Sql, SqlString$1 as SqlString, createTypeDef, dateOffset, dateToDateString, dateToDatetimeString, getCurrentDateTimeString, getDayRange, getDayRangeQExpr, getDbClient, getTodayDateString, getTodayDateTimeString, gqlResolveInfoToField, makeNumberIdEncoder, makeParamsMiddleware, makeResolver, pagingOption, QExpr as qe, queryToSql };
855
+ const sort = option.order ? [QExpr.sort(QExpr.field("t1", option.order), option?.asc === false ? "DESC" : "ASC")] : [];
856
+ return {
857
+ numberOfItem: option.numberOfItem,
858
+ offset: option.offset,
859
+ sort
860
+ };
861
+ };
862
+ //#endregion
863
+ export { CompositeCondition, Conditions, Mutations, MysqlClient, QExpr, QExpr as qe, Queries, SasatDBDatasource, Sql, SqlString, assignDeep, createTypeDef, dateOffset, dateToDateString, dateToDatetimeString, formatQuery, getCurrentDateTimeString, getDayRange, getDayRangeQExpr, getDbClient, getTodayDateString, getTodayDateTimeString, gqlResolveInfoToField, makeNumberIdEncoder, makeParamsMiddleware, makeResolver, migrate, pagingOption, pick, queryToSql, setConfig };