@technicity/data-service-generator 0.22.2 → 0.23.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/generation/generate.d.ts +21 -0
- package/dist/src/generation/generate.js +2349 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.js +11 -0
- package/dist/src/lib/CustomError.d.ts +3 -0
- package/dist/src/lib/CustomError.js +10 -0
- package/dist/src/lib/capitalizeFirstLetter.d.ts +1 -0
- package/dist/src/lib/capitalizeFirstLetter.js +6 -0
- package/dist/src/lib/getDuplicates.d.ts +1 -0
- package/dist/src/lib/getDuplicates.js +9 -0
- package/dist/src/lib/isNotNullOrUndefined.d.ts +1 -0
- package/dist/src/lib/isNotNullOrUndefined.js +7 -0
- package/dist/src/runtime/Cache.d.ts +28 -0
- package/dist/src/runtime/Cache.js +142 -0
- package/dist/src/runtime/IRuntime.d.ts +209 -0
- package/dist/src/runtime/IRuntime.js +12 -0
- package/dist/src/runtime/RuntimeMySQL.d.ts +26 -0
- package/dist/src/runtime/RuntimeMySQL.js +132 -0
- package/dist/src/runtime/RuntimePostgreSQL.d.ts +30 -0
- package/dist/src/runtime/RuntimePostgreSQL.js +73 -0
- package/dist/src/runtime/RuntimeSQLite.d.ts +42 -0
- package/dist/src/runtime/RuntimeSQLite.js +150 -0
- package/dist/src/runtime/Stats.d.ts +8 -0
- package/dist/src/runtime/Stats.js +31 -0
- package/dist/src/runtime/lib/MySQL.d.ts +13 -0
- package/dist/src/runtime/lib/MySQL.js +116 -0
- package/dist/src/runtime/lib/PostgreSQL.d.ts +14 -0
- package/dist/src/runtime/lib/PostgreSQL.js +110 -0
- package/dist/src/runtime/lib/SDKBadWhereError.d.ts +4 -0
- package/dist/src/runtime/lib/SDKBadWhereError.js +10 -0
- package/dist/src/runtime/lib/SDKNotFoundError.d.ts +4 -0
- package/dist/src/runtime/lib/SDKNotFoundError.js +10 -0
- package/dist/src/runtime/lib/addNullFallbacks.d.ts +1 -0
- package/dist/src/runtime/lib/addNullFallbacks.js +32 -0
- package/dist/src/runtime/lib/addNullFallbacks.test.d.ts +1 -0
- package/dist/src/runtime/lib/addNullFallbacks.test.js +206 -0
- package/dist/src/runtime/lib/cursor.d.ts +2 -0
- package/dist/src/runtime/lib/cursor.js +10 -0
- package/dist/src/runtime/lib/getDateTimeStringMySQL.d.ts +1 -0
- package/dist/src/runtime/lib/getDateTimeStringMySQL.js +7 -0
- package/dist/src/runtime/lib/getOrderBy.d.ts +5 -0
- package/dist/src/runtime/lib/getOrderBy.js +52 -0
- package/dist/src/runtime/lib/getSqlAst.d.ts +2 -0
- package/dist/src/runtime/lib/getSqlAst.js +245 -0
- package/dist/src/runtime/lib/getWhere.d.ts +2 -0
- package/dist/src/runtime/lib/getWhere.js +20 -0
- package/dist/src/runtime/lib/shared.d.ts +13 -0
- package/dist/src/runtime/lib/shared.js +1118 -0
- package/dist/src/runtime/lib/stringifyWhere.d.ts +18 -0
- package/dist/src/runtime/lib/stringifyWhere.js +257 -0
- package/dist/src/runtime/lib/stringifyWhere.test.d.ts +1 -0
- package/dist/src/runtime/lib/stringifyWhere.test.js +245 -0
- package/dist/src/runtime/lib/utility.d.ts +5 -0
- package/dist/src/runtime/lib/utility.js +14 -0
- package/dist/src/traverseFieldArgs.d.ts +2 -0
- package/dist/src/traverseFieldArgs.js +17 -0
- package/dist/src/traverseFieldArgs.test.d.ts +1 -0
- package/dist/src/traverseFieldArgs.test.js +56 -0
- package/dist/test/addWhereValidTrue.d.ts +1 -0
- package/dist/test/addWhereValidTrue.js +39 -0
- package/dist/test/globalSetup.d.ts +13 -0
- package/dist/test/globalSetup.js +436 -0
- package/dist/test/postgres/__generated__/sdk-ts/artifacts.d.ts +8425 -0
- package/dist/test/postgres/__generated__/sdk-ts/artifacts.js +10469 -0
- package/dist/test/postgres/__generated__/sdk-ts/index.js +12162 -0
- package/package.json +5 -1
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { IOrderBy, IDialect } from "../IRuntime";
|
|
2
|
+
type IWhere = {
|
|
3
|
+
[k: string]: any;
|
|
4
|
+
};
|
|
5
|
+
type IArgs = {
|
|
6
|
+
[k: string]: any;
|
|
7
|
+
};
|
|
8
|
+
export declare function stringifyWhere(input: {
|
|
9
|
+
where: IWhere;
|
|
10
|
+
table: string;
|
|
11
|
+
dialect: IDialect;
|
|
12
|
+
args: IArgs;
|
|
13
|
+
orderBy?: IOrderBy | undefined;
|
|
14
|
+
rowWithMatchingCursor?: any;
|
|
15
|
+
}): string;
|
|
16
|
+
export declare function getEscapeId(dialect: IDialect): any;
|
|
17
|
+
export declare function getEscape(dialect: IDialect): any;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.stringifyWhere = stringifyWhere;
|
|
27
|
+
exports.getEscapeId = getEscapeId;
|
|
28
|
+
exports.getEscape = getEscape;
|
|
29
|
+
const _ = __importStar(require("lodash/fp"));
|
|
30
|
+
const MySqlString = __importStar(require("sqlstring"));
|
|
31
|
+
// @ts-expect-error
|
|
32
|
+
const SqliteString = __importStar(require("sqlstring-sqlite"));
|
|
33
|
+
const pgFormat = __importStar(require("pg-format"));
|
|
34
|
+
function stringifyWhere(input) {
|
|
35
|
+
const { where, table, dialect, args, orderBy, rowWithMatchingCursor } = input;
|
|
36
|
+
const escapeId = getEscapeId(dialect);
|
|
37
|
+
const escape = getEscape(dialect);
|
|
38
|
+
let result = _stringifyWhere(where, table, escapeId, escape, "");
|
|
39
|
+
const paginationWhere = stringifyPaginationWhere({
|
|
40
|
+
table,
|
|
41
|
+
args,
|
|
42
|
+
orderBy,
|
|
43
|
+
escapeId,
|
|
44
|
+
escape,
|
|
45
|
+
rowWithMatchingCursor
|
|
46
|
+
});
|
|
47
|
+
if (paginationWhere) {
|
|
48
|
+
result =
|
|
49
|
+
result.length === 0 ? paginationWhere : result + " AND " + paginationWhere;
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
function _stringifyWhere(where, table, escapeId, escape, result) {
|
|
54
|
+
if (Object.prototype.hasOwnProperty.call(where, "$and")) {
|
|
55
|
+
if (Object.keys(where).length !== 1) {
|
|
56
|
+
throw new Error("Must have 1 key: " + JSON.stringify(where, null, 2));
|
|
57
|
+
}
|
|
58
|
+
const _xs = where.$and.filter((x) => x != null);
|
|
59
|
+
if (_xs.length === 0) {
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
const xs = _xs
|
|
63
|
+
.map((x) => _stringifyWhere(x, table, escapeId, escape, result))
|
|
64
|
+
.filter(Boolean);
|
|
65
|
+
if (xs.length === 0) {
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
return `(${xs.join(" AND ")})`;
|
|
69
|
+
}
|
|
70
|
+
if (Object.prototype.hasOwnProperty.call(where, "$or")) {
|
|
71
|
+
if (Object.keys(where).length !== 1) {
|
|
72
|
+
throw new Error("Must have 1 key: " + JSON.stringify(where, null, 2));
|
|
73
|
+
}
|
|
74
|
+
const _xs = where.$or.filter((x) => x != null);
|
|
75
|
+
if (_xs.length === 0) {
|
|
76
|
+
return result;
|
|
77
|
+
}
|
|
78
|
+
const xs = _xs
|
|
79
|
+
.map((x) => _stringifyWhere(x, table, escapeId, escape, result))
|
|
80
|
+
.filter(Boolean);
|
|
81
|
+
if (xs.length === 0) {
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
return `(${xs.join(" OR ")})`;
|
|
85
|
+
}
|
|
86
|
+
function printValue(v) {
|
|
87
|
+
if (v === true) {
|
|
88
|
+
v = 1;
|
|
89
|
+
}
|
|
90
|
+
if (v === false) {
|
|
91
|
+
v = 0;
|
|
92
|
+
}
|
|
93
|
+
return escape(v);
|
|
94
|
+
}
|
|
95
|
+
return Object.keys(where)
|
|
96
|
+
.map((k) => {
|
|
97
|
+
let v = where[k];
|
|
98
|
+
if (v === void 0) {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
// Can't do this, since we need this function to be sync
|
|
102
|
+
// if (relationMap[k] !== null) {
|
|
103
|
+
// const relationData = await getRelationData(k, v, relationMap);
|
|
104
|
+
// k = relationData.k;
|
|
105
|
+
// v = relationData.v;
|
|
106
|
+
// }
|
|
107
|
+
if (v === null) {
|
|
108
|
+
return `${table}.${escapeId(k)} IS NULL`;
|
|
109
|
+
}
|
|
110
|
+
if (typeof v === "string" || typeof v === "number" || typeof v === "boolean") {
|
|
111
|
+
return `${table}.${escapeId(k)} = ${printValue(v)}`;
|
|
112
|
+
}
|
|
113
|
+
if (_.isPlainObject(v)) {
|
|
114
|
+
const keys = Object.keys(v);
|
|
115
|
+
if (keys.length !== 1) {
|
|
116
|
+
throw new Error("Must have 1 key: " + JSON.stringify(v, null, 2));
|
|
117
|
+
}
|
|
118
|
+
const operator = keys[0];
|
|
119
|
+
const operand = v[operator];
|
|
120
|
+
if (operator === "$neq") {
|
|
121
|
+
return `${table}.${escapeId(k)} ${getOperatorNeq(operand)} ${printValue(operand)}`;
|
|
122
|
+
}
|
|
123
|
+
if (operator === "$gt") {
|
|
124
|
+
return `${table}.${escapeId(k)} > ${printValue(operand)}`;
|
|
125
|
+
}
|
|
126
|
+
if (operator === "$gte") {
|
|
127
|
+
return `${table}.${escapeId(k)} >= ${printValue(operand)}`;
|
|
128
|
+
}
|
|
129
|
+
if (operator === "$lt") {
|
|
130
|
+
return `${table}.${escapeId(k)} < ${printValue(operand)}`;
|
|
131
|
+
}
|
|
132
|
+
if (operator === "$lte") {
|
|
133
|
+
return `${table}.${escapeId(k)} <= ${printValue(operand)}`;
|
|
134
|
+
}
|
|
135
|
+
if (operator === "$like") {
|
|
136
|
+
return `${table}.${escapeId(k)} LIKE ${printValue(operand)}`;
|
|
137
|
+
}
|
|
138
|
+
if (operator === "$nlike") {
|
|
139
|
+
return `${table}.${escapeId(k)} NOT LIKE ${printValue(operand)}`;
|
|
140
|
+
}
|
|
141
|
+
if (operator === "$in") {
|
|
142
|
+
if (operand.length === 0) {
|
|
143
|
+
// Edit: no longer relevant, since the MSSQL dialect was
|
|
144
|
+
// removed, but keep the same for stability.
|
|
145
|
+
// Would do "FALSE" instead, as it's more readable, but it
|
|
146
|
+
// causes a RequestError in MSSQL.
|
|
147
|
+
return "(1=0)";
|
|
148
|
+
}
|
|
149
|
+
return `${table}.${escapeId(k)} IN (${operand
|
|
150
|
+
.map((x) => printValue(x))
|
|
151
|
+
.join(",")})`;
|
|
152
|
+
}
|
|
153
|
+
if (operator === "$nin") {
|
|
154
|
+
if (operand.length === 0) {
|
|
155
|
+
// Edit: no longer relevant, since the MSSQL dialect was
|
|
156
|
+
// removed, but keep the same for stability.
|
|
157
|
+
// Would do "TRUE" instead, as it's more readable, but it
|
|
158
|
+
// causes a RequestError in MSSQL.
|
|
159
|
+
return "(1=1)";
|
|
160
|
+
}
|
|
161
|
+
return `${table}.${escapeId(k)} NOT IN (${operand
|
|
162
|
+
.map((x) => printValue(x))
|
|
163
|
+
.join(",")})`;
|
|
164
|
+
}
|
|
165
|
+
if (operator === "$btwn") {
|
|
166
|
+
if (operand.length !== 2) {
|
|
167
|
+
throw new Error("Expected length of 2, got: " + operand.length);
|
|
168
|
+
}
|
|
169
|
+
return `${table}.${escapeId(k)} BETWEEN ${printValue(operand[0])} AND ${printValue(operand[1])}`;
|
|
170
|
+
}
|
|
171
|
+
if (operator === "$nbtwn") {
|
|
172
|
+
if (operand.length !== 2) {
|
|
173
|
+
throw new Error("Expected length of 2, got: " + operand.length);
|
|
174
|
+
}
|
|
175
|
+
return `${table}.${escapeId(k)} NOT BETWEEN ${printValue(operand[0])} AND ${printValue(operand[1])}`;
|
|
176
|
+
}
|
|
177
|
+
throw new Error("Invalid operator: " + operator);
|
|
178
|
+
}
|
|
179
|
+
throw new Error("Invalid value: " + v);
|
|
180
|
+
})
|
|
181
|
+
.filter((x) => x != null)
|
|
182
|
+
.join(" AND ");
|
|
183
|
+
}
|
|
184
|
+
const valuesThatUseIsOrIsNot = new Set([null]);
|
|
185
|
+
function getOperatorNeq(value) {
|
|
186
|
+
return valuesThatUseIsOrIsNot.has(value) ? "IS NOT" : "!=";
|
|
187
|
+
}
|
|
188
|
+
// async function getRelationData(k: string, v: any, relationMap: IRelationMap) {
|
|
189
|
+
// // TODO
|
|
190
|
+
// return { k, v };
|
|
191
|
+
// }
|
|
192
|
+
function stringifyPaginationWhere(input) {
|
|
193
|
+
const { table, args, orderBy, escapeId, escape, rowWithMatchingCursor } = input;
|
|
194
|
+
if (args?.$paginate?.after == null && args?.$paginate?.before == null) {
|
|
195
|
+
return "";
|
|
196
|
+
}
|
|
197
|
+
if (rowWithMatchingCursor == null) {
|
|
198
|
+
return "";
|
|
199
|
+
}
|
|
200
|
+
// orderBy should never be null because of getOrderBy, but add a check.
|
|
201
|
+
if (orderBy == null) {
|
|
202
|
+
throw new Error("orderBy cannot be null when paginating");
|
|
203
|
+
}
|
|
204
|
+
function getCompOp(dir) {
|
|
205
|
+
return dir === "asc" ? ">" : "<";
|
|
206
|
+
}
|
|
207
|
+
function printValue(v) {
|
|
208
|
+
if (v === true) {
|
|
209
|
+
v = 1;
|
|
210
|
+
}
|
|
211
|
+
if (v === false) {
|
|
212
|
+
v = 0;
|
|
213
|
+
}
|
|
214
|
+
return escape(v);
|
|
215
|
+
}
|
|
216
|
+
// https://gist.github.com/pcattori/2bb645d587e45c9fdbcabf5cef7a7106
|
|
217
|
+
const cond = orderBy
|
|
218
|
+
.map(({ column, direction }, i) => {
|
|
219
|
+
let a = orderBy.slice(0, i).map(({ column: col2 }) => {
|
|
220
|
+
const field = `${table}.${escapeId(col2)}`;
|
|
221
|
+
const op = "=";
|
|
222
|
+
const v = printValue(rowWithMatchingCursor[col2]);
|
|
223
|
+
return `${field} ${op} ${v}`;
|
|
224
|
+
});
|
|
225
|
+
const field = `${table}.${escapeId(column)}`;
|
|
226
|
+
const op = getCompOp(direction);
|
|
227
|
+
const v = printValue(rowWithMatchingCursor[column]);
|
|
228
|
+
a.push(`${field} ${op} ${v}`);
|
|
229
|
+
return "(" + a.join(" AND ") + ")";
|
|
230
|
+
})
|
|
231
|
+
.join(" OR ");
|
|
232
|
+
return "(" + cond + ")";
|
|
233
|
+
}
|
|
234
|
+
function getEscapeId(dialect) {
|
|
235
|
+
if (dialect === "mysql") {
|
|
236
|
+
return MySqlString.escapeId.bind(MySqlString);
|
|
237
|
+
}
|
|
238
|
+
if (dialect === "sqlite") {
|
|
239
|
+
return SqliteString.escapeId.bind(SqliteString);
|
|
240
|
+
}
|
|
241
|
+
if (dialect === "postgresql") {
|
|
242
|
+
return (id) => pgFormat.ident(id);
|
|
243
|
+
}
|
|
244
|
+
throw new Error("Unsupported dialect: " + dialect);
|
|
245
|
+
}
|
|
246
|
+
function getEscape(dialect) {
|
|
247
|
+
if (dialect === "mysql") {
|
|
248
|
+
return MySqlString.escape.bind(MySqlString);
|
|
249
|
+
}
|
|
250
|
+
if (dialect === "sqlite") {
|
|
251
|
+
return SqliteString.escape.bind(SqliteString);
|
|
252
|
+
}
|
|
253
|
+
if (dialect === "postgresql") {
|
|
254
|
+
return (value) => pgFormat.literal(value);
|
|
255
|
+
}
|
|
256
|
+
throw new Error("Unsupported dialect: " + dialect);
|
|
257
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const globals_1 = require("@jest/globals");
|
|
7
|
+
const strict_1 = __importDefault(require("node:assert/strict"));
|
|
8
|
+
const stringifyWhere_1 = require("./stringifyWhere");
|
|
9
|
+
(0, globals_1.describe)("stringifyWhere", () => {
|
|
10
|
+
const table = "Usr";
|
|
11
|
+
const dialect = "mysql";
|
|
12
|
+
const args = {};
|
|
13
|
+
(0, globals_1.test)("should work", () => {
|
|
14
|
+
const result = (0, stringifyWhere_1.stringifyWhere)({
|
|
15
|
+
where: { userId: 2, text: "foo" },
|
|
16
|
+
table,
|
|
17
|
+
dialect,
|
|
18
|
+
args
|
|
19
|
+
});
|
|
20
|
+
strict_1.default.deepEqual(result, "Usr.`userId` = 2 AND Usr.`text` = 'foo'");
|
|
21
|
+
});
|
|
22
|
+
(0, globals_1.test)("should handle empty object", () => {
|
|
23
|
+
const result = (0, stringifyWhere_1.stringifyWhere)({ where: {}, table, dialect, args });
|
|
24
|
+
strict_1.default.deepEqual(result, "");
|
|
25
|
+
});
|
|
26
|
+
(0, globals_1.test)("should handle $and", () => {
|
|
27
|
+
const result = (0, stringifyWhere_1.stringifyWhere)({
|
|
28
|
+
where: { $and: [{ valid: true }, { text: "foo" }] },
|
|
29
|
+
table,
|
|
30
|
+
dialect,
|
|
31
|
+
args
|
|
32
|
+
});
|
|
33
|
+
strict_1.default.deepEqual(result, "(Usr.`valid` = 1 AND Usr.`text` = 'foo')");
|
|
34
|
+
});
|
|
35
|
+
(0, globals_1.test)("should handle $or", () => {
|
|
36
|
+
const result = (0, stringifyWhere_1.stringifyWhere)({
|
|
37
|
+
where: { $or: [{ valid: true }, { text: "foo" }] },
|
|
38
|
+
table,
|
|
39
|
+
dialect,
|
|
40
|
+
args
|
|
41
|
+
});
|
|
42
|
+
strict_1.default.deepEqual(result, "(Usr.`valid` = 1 OR Usr.`text` = 'foo')");
|
|
43
|
+
});
|
|
44
|
+
(0, globals_1.test)("should handle null", () => {
|
|
45
|
+
const result = (0, stringifyWhere_1.stringifyWhere)({
|
|
46
|
+
where: { userId: null },
|
|
47
|
+
table,
|
|
48
|
+
dialect,
|
|
49
|
+
args
|
|
50
|
+
});
|
|
51
|
+
strict_1.default.deepEqual(result, "Usr.`userId` IS NULL");
|
|
52
|
+
});
|
|
53
|
+
(0, globals_1.test)("should handle $neq", () => {
|
|
54
|
+
const result = (0, stringifyWhere_1.stringifyWhere)({
|
|
55
|
+
where: { userId: { $neq: 2 }, text: "foo" },
|
|
56
|
+
table,
|
|
57
|
+
dialect,
|
|
58
|
+
args
|
|
59
|
+
});
|
|
60
|
+
strict_1.default.deepEqual(result, "Usr.`userId` != 2 AND Usr.`text` = 'foo'");
|
|
61
|
+
});
|
|
62
|
+
(0, globals_1.test)("should handle $neq null", () => {
|
|
63
|
+
const result = (0, stringifyWhere_1.stringifyWhere)({
|
|
64
|
+
where: { userId: { $neq: null }, text: "foo" },
|
|
65
|
+
table,
|
|
66
|
+
dialect,
|
|
67
|
+
args
|
|
68
|
+
});
|
|
69
|
+
strict_1.default.deepEqual(result, "Usr.`userId` IS NOT NULL AND Usr.`text` = 'foo'");
|
|
70
|
+
});
|
|
71
|
+
(0, globals_1.test)("should handle $gt", () => {
|
|
72
|
+
const result = (0, stringifyWhere_1.stringifyWhere)({
|
|
73
|
+
where: { userId: { $gt: 2 }, text: "foo" },
|
|
74
|
+
table,
|
|
75
|
+
dialect,
|
|
76
|
+
args
|
|
77
|
+
});
|
|
78
|
+
strict_1.default.deepEqual(result, "Usr.`userId` > 2 AND Usr.`text` = 'foo'");
|
|
79
|
+
});
|
|
80
|
+
(0, globals_1.test)("should handle $gte", () => {
|
|
81
|
+
const result = (0, stringifyWhere_1.stringifyWhere)({
|
|
82
|
+
where: { userId: { $gte: 2 }, text: "foo" },
|
|
83
|
+
table,
|
|
84
|
+
dialect,
|
|
85
|
+
args
|
|
86
|
+
});
|
|
87
|
+
strict_1.default.deepEqual(result, "Usr.`userId` >= 2 AND Usr.`text` = 'foo'");
|
|
88
|
+
});
|
|
89
|
+
(0, globals_1.test)("should handle $lt", () => {
|
|
90
|
+
const result = (0, stringifyWhere_1.stringifyWhere)({
|
|
91
|
+
where: { userId: { $lt: 2 }, text: "foo" },
|
|
92
|
+
table,
|
|
93
|
+
dialect,
|
|
94
|
+
args
|
|
95
|
+
});
|
|
96
|
+
strict_1.default.deepEqual(result, "Usr.`userId` < 2 AND Usr.`text` = 'foo'");
|
|
97
|
+
});
|
|
98
|
+
(0, globals_1.test)("should handle $lte", () => {
|
|
99
|
+
const result = (0, stringifyWhere_1.stringifyWhere)({
|
|
100
|
+
where: { userId: { $lte: 2 }, text: "foo" },
|
|
101
|
+
table,
|
|
102
|
+
dialect,
|
|
103
|
+
args
|
|
104
|
+
});
|
|
105
|
+
strict_1.default.deepEqual(result, "Usr.`userId` <= 2 AND Usr.`text` = 'foo'");
|
|
106
|
+
});
|
|
107
|
+
(0, globals_1.test)("should handle $like", () => {
|
|
108
|
+
const result = (0, stringifyWhere_1.stringifyWhere)({
|
|
109
|
+
where: { text: { $like: "%foo%" } },
|
|
110
|
+
table,
|
|
111
|
+
dialect,
|
|
112
|
+
args
|
|
113
|
+
});
|
|
114
|
+
strict_1.default.deepEqual(result, "Usr.`text` LIKE '%foo%'");
|
|
115
|
+
});
|
|
116
|
+
(0, globals_1.test)("should handle $nlike", () => {
|
|
117
|
+
const result = (0, stringifyWhere_1.stringifyWhere)({
|
|
118
|
+
where: { text: { $nlike: "%foo%" } },
|
|
119
|
+
table,
|
|
120
|
+
dialect,
|
|
121
|
+
args
|
|
122
|
+
});
|
|
123
|
+
strict_1.default.deepEqual(result, "Usr.`text` NOT LIKE '%foo%'");
|
|
124
|
+
});
|
|
125
|
+
(0, globals_1.test)("should handle $in", () => {
|
|
126
|
+
const result = (0, stringifyWhere_1.stringifyWhere)({
|
|
127
|
+
where: { userId: { $in: [1, 2] }, text: "foo" },
|
|
128
|
+
table,
|
|
129
|
+
dialect,
|
|
130
|
+
args
|
|
131
|
+
});
|
|
132
|
+
strict_1.default.deepEqual(result, "Usr.`userId` IN (1,2) AND Usr.`text` = 'foo'");
|
|
133
|
+
});
|
|
134
|
+
(0, globals_1.test)("should handle empty $in", () => {
|
|
135
|
+
const result = (0, stringifyWhere_1.stringifyWhere)({
|
|
136
|
+
where: { userId: { $in: [] }, text: "foo" },
|
|
137
|
+
table,
|
|
138
|
+
dialect,
|
|
139
|
+
args
|
|
140
|
+
});
|
|
141
|
+
strict_1.default.deepEqual(result, "(1=0) AND Usr.`text` = 'foo'");
|
|
142
|
+
});
|
|
143
|
+
(0, globals_1.test)("should handle $nin", () => {
|
|
144
|
+
const result = (0, stringifyWhere_1.stringifyWhere)({
|
|
145
|
+
where: { userId: { $nin: [1, 2] }, text: "foo" },
|
|
146
|
+
table,
|
|
147
|
+
dialect,
|
|
148
|
+
args
|
|
149
|
+
});
|
|
150
|
+
strict_1.default.deepEqual(result, "Usr.`userId` NOT IN (1,2) AND Usr.`text` = 'foo'");
|
|
151
|
+
});
|
|
152
|
+
(0, globals_1.test)("should handle empty $nin", () => {
|
|
153
|
+
const result = (0, stringifyWhere_1.stringifyWhere)({
|
|
154
|
+
where: { userId: { $nin: [] }, text: "foo" },
|
|
155
|
+
table,
|
|
156
|
+
dialect,
|
|
157
|
+
args
|
|
158
|
+
});
|
|
159
|
+
strict_1.default.deepEqual(result, "(1=1) AND Usr.`text` = 'foo'");
|
|
160
|
+
});
|
|
161
|
+
(0, globals_1.test)("should handle $btwn", () => {
|
|
162
|
+
const result = (0, stringifyWhere_1.stringifyWhere)({
|
|
163
|
+
where: { userId: { $btwn: [1, 20] }, text: "foo" },
|
|
164
|
+
table,
|
|
165
|
+
dialect,
|
|
166
|
+
args
|
|
167
|
+
});
|
|
168
|
+
strict_1.default.deepEqual(result, "Usr.`userId` BETWEEN 1 AND 20 AND Usr.`text` = 'foo'");
|
|
169
|
+
});
|
|
170
|
+
(0, globals_1.test)("should handle $nbtwn", () => {
|
|
171
|
+
const result = (0, stringifyWhere_1.stringifyWhere)({
|
|
172
|
+
where: { userId: { $nbtwn: [1, 20] }, text: "foo" },
|
|
173
|
+
table,
|
|
174
|
+
dialect,
|
|
175
|
+
args
|
|
176
|
+
});
|
|
177
|
+
strict_1.default.deepEqual(result, "Usr.`userId` NOT BETWEEN 1 AND 20 AND Usr.`text` = 'foo'");
|
|
178
|
+
});
|
|
179
|
+
(0, globals_1.test)("should handle nested $and and $or", () => {
|
|
180
|
+
const result = (0, stringifyWhere_1.stringifyWhere)({
|
|
181
|
+
where: {
|
|
182
|
+
$and: [
|
|
183
|
+
{ userId: { $gt: 2 } },
|
|
184
|
+
{ $or: [{ text: { $like: "foo" } }, { text: { $like: "bar" } }] },
|
|
185
|
+
{ $and: [{ lala: "lala" }, { oioi: "oioi" }] }
|
|
186
|
+
]
|
|
187
|
+
},
|
|
188
|
+
table,
|
|
189
|
+
dialect,
|
|
190
|
+
args
|
|
191
|
+
});
|
|
192
|
+
strict_1.default.deepEqual(result, "(Usr.`userId` > 2 AND (Usr.`text` LIKE 'foo' OR Usr.`text` LIKE 'bar') AND (Usr.`lala` = 'lala' AND Usr.`oioi` = 'oioi'))");
|
|
193
|
+
});
|
|
194
|
+
(0, globals_1.test)("should throw on invalid operator", () => {
|
|
195
|
+
strict_1.default.throws(() => (0, stringifyWhere_1.stringifyWhere)({
|
|
196
|
+
where: { foo: { $foo: 3 } },
|
|
197
|
+
table,
|
|
198
|
+
dialect,
|
|
199
|
+
args
|
|
200
|
+
}), (error) => {
|
|
201
|
+
(0, strict_1.default)(error instanceof Error);
|
|
202
|
+
(0, strict_1.default)(error.message.startsWith("Invalid operator:"));
|
|
203
|
+
return true;
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
(0, globals_1.test)("should throw on more than 1 key for $and", () => {
|
|
207
|
+
strict_1.default.throws(() => (0, stringifyWhere_1.stringifyWhere)({
|
|
208
|
+
where: { $and: [{ foo: "bar" }, { bar: "baz" }], foo: "bar" },
|
|
209
|
+
table,
|
|
210
|
+
dialect,
|
|
211
|
+
args
|
|
212
|
+
}), (error) => {
|
|
213
|
+
(0, strict_1.default)(error instanceof Error);
|
|
214
|
+
(0, strict_1.default)(error.message.startsWith("Must have 1 key:"));
|
|
215
|
+
return true;
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
(0, globals_1.test)("ignores undefined values", () => {
|
|
219
|
+
const result = (0, stringifyWhere_1.stringifyWhere)({
|
|
220
|
+
where: { $or: [{ foo: "bar" }, { bar: null }, { baz: undefined }] },
|
|
221
|
+
table,
|
|
222
|
+
dialect,
|
|
223
|
+
args
|
|
224
|
+
});
|
|
225
|
+
strict_1.default.deepEqual(result, "(Usr.`foo` = 'bar' OR Usr.`bar` IS NULL)");
|
|
226
|
+
});
|
|
227
|
+
(0, globals_1.test)("handles empty $and", () => {
|
|
228
|
+
const result = (0, stringifyWhere_1.stringifyWhere)({
|
|
229
|
+
where: { $and: [] },
|
|
230
|
+
table,
|
|
231
|
+
dialect,
|
|
232
|
+
args
|
|
233
|
+
});
|
|
234
|
+
strict_1.default.deepEqual(result, "");
|
|
235
|
+
});
|
|
236
|
+
(0, globals_1.test)("handles empty $or", () => {
|
|
237
|
+
const result = (0, stringifyWhere_1.stringifyWhere)({
|
|
238
|
+
where: { $or: [] },
|
|
239
|
+
table,
|
|
240
|
+
dialect,
|
|
241
|
+
args
|
|
242
|
+
});
|
|
243
|
+
strict_1.default.deepEqual(result, "");
|
|
244
|
+
});
|
|
245
|
+
});
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Eagerly resolve and map input values then concatinate.
|
|
3
|
+
*/
|
|
4
|
+
export declare function mapAsync<T, R>(source: T[] | Promise<T[]>, mapFunction: (item: T) => R | R[] | Promise<R>[] | Promise<R | R[]>): Promise<R[]>;
|
|
5
|
+
export declare function flatten<T>(array: (T | T[])[]): T[];
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mapAsync = mapAsync;
|
|
4
|
+
exports.flatten = flatten;
|
|
5
|
+
/**
|
|
6
|
+
* Eagerly resolve and map input values then concatinate.
|
|
7
|
+
*/
|
|
8
|
+
async function mapAsync(source, mapFunction) {
|
|
9
|
+
const output = (await source).map(mapFunction);
|
|
10
|
+
return Promise.all(flatten(output)).then(flatten);
|
|
11
|
+
}
|
|
12
|
+
function flatten(array) {
|
|
13
|
+
return [].concat(...array);
|
|
14
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.traverseFieldArgs = traverseFieldArgs;
|
|
4
|
+
function traverseFieldArgs(fields, cb) {
|
|
5
|
+
const values = Object.values(fields);
|
|
6
|
+
for (let x of values) {
|
|
7
|
+
if (typeof x !== "object") {
|
|
8
|
+
continue;
|
|
9
|
+
}
|
|
10
|
+
const fields = x.$fields;
|
|
11
|
+
if (fields == null) {
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
cb(x);
|
|
15
|
+
traverseFieldArgs(fields, cb);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const globals_1 = require("@jest/globals");
|
|
7
|
+
const strict_1 = __importDefault(require("node:assert/strict"));
|
|
8
|
+
const _1 = require(".");
|
|
9
|
+
const addWhereValidTrue_1 = require("../test/addWhereValidTrue");
|
|
10
|
+
(0, globals_1.describe)("traverseFieldArgs", () => {
|
|
11
|
+
(0, globals_1.test)("should work", () => {
|
|
12
|
+
const fields = {
|
|
13
|
+
id: true,
|
|
14
|
+
uuid: true,
|
|
15
|
+
business: { $fields: { id: true, uuid: true, name: true } },
|
|
16
|
+
sessionList: {
|
|
17
|
+
$fields: {
|
|
18
|
+
id: true,
|
|
19
|
+
archived: true,
|
|
20
|
+
fooList: { $fields: { id: true, uuid: true } }
|
|
21
|
+
},
|
|
22
|
+
$where: { archived: false },
|
|
23
|
+
$orderBy: { id: "desc" }
|
|
24
|
+
},
|
|
25
|
+
usrList: {
|
|
26
|
+
$fields: { firstName: true, lastName: true, password: true },
|
|
27
|
+
$where: { valid: false, archived: false },
|
|
28
|
+
$orderBy: { id: "desc" }
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
(0, _1.traverseFieldArgs)(fields, addWhereValidTrue_1.addWhereValidTrue);
|
|
32
|
+
strict_1.default.deepEqual(fields, {
|
|
33
|
+
id: true,
|
|
34
|
+
uuid: true,
|
|
35
|
+
business: {
|
|
36
|
+
$fields: { id: true, uuid: true, name: true },
|
|
37
|
+
$where: { valid: true }
|
|
38
|
+
},
|
|
39
|
+
sessionList: {
|
|
40
|
+
$fields: {
|
|
41
|
+
id: true,
|
|
42
|
+
archived: true,
|
|
43
|
+
fooList: { $fields: { id: true, uuid: true }, $where: { valid: true } }
|
|
44
|
+
},
|
|
45
|
+
$where: { valid: true, archived: false },
|
|
46
|
+
$orderBy: { id: "desc" }
|
|
47
|
+
},
|
|
48
|
+
usrList: {
|
|
49
|
+
$fields: { firstName: true, lastName: true, password: true },
|
|
50
|
+
// Should not be overwritten
|
|
51
|
+
$where: { valid: false, archived: false },
|
|
52
|
+
$orderBy: { id: "desc" }
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function addWhereValidTrue(args: any): any;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
function addWhereValidTrue(args) {
|
|
3
|
+
const key = "valid";
|
|
4
|
+
if (args == null) {
|
|
5
|
+
args = { $where: { [key]: true } };
|
|
6
|
+
}
|
|
7
|
+
else if (args.$where == null) {
|
|
8
|
+
args.$where = { [key]: true };
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
// Only set if not explicitly set
|
|
12
|
+
if (!Object.prototype.hasOwnProperty.call(args.$where, key)) {
|
|
13
|
+
if (Array.isArray(args.$where)) {
|
|
14
|
+
for (let x of args.$where) {
|
|
15
|
+
if (x.$and) {
|
|
16
|
+
x.$and.push({ [key]: true });
|
|
17
|
+
}
|
|
18
|
+
else if (x.$or) {
|
|
19
|
+
x.$or = x.$or.map((y) => ({ ...y, [key]: true }));
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
x.$where[key] = true;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
else if (args.$where.$and) {
|
|
27
|
+
args.$where.$and.push({ [key]: true });
|
|
28
|
+
}
|
|
29
|
+
else if (args.$where.$or) {
|
|
30
|
+
args.$where.$or = args.$where.$or.map((y) => ({ ...y, [key]: true }));
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
args.$where[key] = true;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return args;
|
|
38
|
+
}
|
|
39
|
+
module.exports.addWhereValidTrue = addWhereValidTrue;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { StartedTestContainer } from "testcontainers";
|
|
2
|
+
import { type SDK } from "./mysql80/__generated__/sdk-ts";
|
|
3
|
+
export default function globalSetup(): Promise<void>;
|
|
4
|
+
export type TTestItem = {
|
|
5
|
+
displayName: string;
|
|
6
|
+
dialect: string;
|
|
7
|
+
sdk: SDK;
|
|
8
|
+
SDK: typeof SDK;
|
|
9
|
+
sdkOpts: any;
|
|
10
|
+
sdkPath: string;
|
|
11
|
+
artifacts: any;
|
|
12
|
+
containers: StartedTestContainer[];
|
|
13
|
+
};
|