fluxor-cloud-db 1.0.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/.github/workflows/npm-publish.yml +34 -0
- package/README.md +296 -0
- package/dist/index.d.mts +347 -0
- package/dist/index.d.ts +347 -0
- package/dist/index.js +1844 -0
- package/dist/index.mjs +1811 -0
- package/jest.config.ts +12 -0
- package/package.json +33 -0
- package/src/contracts/database-adapter.ts +161 -0
- package/src/dynamo/dynamo.ts +859 -0
- package/src/dynamo/dynamo.types.ts +8 -0
- package/src/fluentapi.ts +71 -0
- package/src/index.ts +39 -0
- package/src/mongo/mongo.ts +690 -0
- package/src/types/error.ts +13 -0
- package/src/types/query.ts +53 -0
- package/tests/dynamodb.test.ts +547 -0
- package/tests/mongodb.test.ts +486 -0
- package/tsconfig.json +23 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1844 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
20
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
21
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
22
|
+
if (decorator = decorators[i])
|
|
23
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
24
|
+
if (kind && result) __defProp(target, key, result);
|
|
25
|
+
return result;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// src/index.ts
|
|
29
|
+
var index_exports = {};
|
|
30
|
+
__export(index_exports, {
|
|
31
|
+
DynamoService: () => DynamoService,
|
|
32
|
+
MongoService: () => MongoService,
|
|
33
|
+
anyOf: () => anyOf,
|
|
34
|
+
between: () => between,
|
|
35
|
+
eq: () => eq,
|
|
36
|
+
equals: () => equals,
|
|
37
|
+
exists: () => exists,
|
|
38
|
+
gt: () => gt,
|
|
39
|
+
gte: () => gte,
|
|
40
|
+
inList: () => inList,
|
|
41
|
+
like: () => like,
|
|
42
|
+
lt: () => lt,
|
|
43
|
+
lte: () => lte,
|
|
44
|
+
neq: () => neq,
|
|
45
|
+
noneOf: () => noneOf,
|
|
46
|
+
notEquals: () => notEquals,
|
|
47
|
+
notInList: () => notInList,
|
|
48
|
+
startsWith: () => startsWith,
|
|
49
|
+
useDynamo: () => useDynamo,
|
|
50
|
+
useMongo: () => useMongo
|
|
51
|
+
});
|
|
52
|
+
module.exports = __toCommonJS(index_exports);
|
|
53
|
+
var import_fluxor_cloud2 = require("fluxor-cloud");
|
|
54
|
+
|
|
55
|
+
// src/dynamo/dynamo.ts
|
|
56
|
+
var import_lib_dynamodb = require("@aws-sdk/lib-dynamodb");
|
|
57
|
+
var import_fluxor_cloud = require("fluxor-cloud");
|
|
58
|
+
var import_client_dynamodb = require("@aws-sdk/client-dynamodb");
|
|
59
|
+
var import_lib_dynamodb2 = require("@aws-sdk/lib-dynamodb");
|
|
60
|
+
|
|
61
|
+
// src/types/error.ts
|
|
62
|
+
var DatabaseAdapterError = class extends Error {
|
|
63
|
+
constructor(message, code, details) {
|
|
64
|
+
super(message);
|
|
65
|
+
this.code = code;
|
|
66
|
+
this.details = details;
|
|
67
|
+
this.name = "DatabaseAdapterError";
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// src/dynamo/dynamo.ts
|
|
72
|
+
var RESERVED_KEYWORDS = /* @__PURE__ */ new Set([
|
|
73
|
+
"ABORT",
|
|
74
|
+
"ABSOLUTE",
|
|
75
|
+
"ACTION",
|
|
76
|
+
"ADD",
|
|
77
|
+
"AFTER",
|
|
78
|
+
"AGENT",
|
|
79
|
+
"ALL",
|
|
80
|
+
"ALLOCATE",
|
|
81
|
+
"ALTER",
|
|
82
|
+
"ANALYZE",
|
|
83
|
+
"AND",
|
|
84
|
+
"ANY",
|
|
85
|
+
"ARCHIVE",
|
|
86
|
+
"ARE",
|
|
87
|
+
"ARRAY",
|
|
88
|
+
"AS",
|
|
89
|
+
"ASC",
|
|
90
|
+
"ASCII",
|
|
91
|
+
"ASENSITIVE",
|
|
92
|
+
"ASSERTION",
|
|
93
|
+
"ASYMMETRIC",
|
|
94
|
+
"AT",
|
|
95
|
+
"ATOMIC",
|
|
96
|
+
"ATTACH",
|
|
97
|
+
"ATTRIBUTE",
|
|
98
|
+
"AUTH",
|
|
99
|
+
"AUTHORIZATION",
|
|
100
|
+
"AUTHORIZE",
|
|
101
|
+
"AUTO",
|
|
102
|
+
"AVG",
|
|
103
|
+
"BACK",
|
|
104
|
+
"BACKUP",
|
|
105
|
+
"BASE",
|
|
106
|
+
"BATCH",
|
|
107
|
+
"BEFORE",
|
|
108
|
+
"BEGIN",
|
|
109
|
+
"BETWEEN",
|
|
110
|
+
"BIGINT",
|
|
111
|
+
"BINARY",
|
|
112
|
+
"BIT",
|
|
113
|
+
"BLOB",
|
|
114
|
+
"BLOCK",
|
|
115
|
+
"BOOLEAN",
|
|
116
|
+
"BOTH",
|
|
117
|
+
"BREADTH",
|
|
118
|
+
"BUCKET",
|
|
119
|
+
"BULK",
|
|
120
|
+
"BY",
|
|
121
|
+
"CALL",
|
|
122
|
+
"CALLED",
|
|
123
|
+
"CALLING",
|
|
124
|
+
"CAPACITY",
|
|
125
|
+
"CASCADE",
|
|
126
|
+
"CASCADED",
|
|
127
|
+
"CASE",
|
|
128
|
+
"CAST",
|
|
129
|
+
"CATALOG",
|
|
130
|
+
"CHAR",
|
|
131
|
+
"CHARACTER",
|
|
132
|
+
"CHECK",
|
|
133
|
+
"CLASS",
|
|
134
|
+
"CLOB",
|
|
135
|
+
"CLOSE",
|
|
136
|
+
"CLUSTER",
|
|
137
|
+
"CLUSTERED",
|
|
138
|
+
"CLUSTERING",
|
|
139
|
+
"CLUSTERS",
|
|
140
|
+
"COALESCE",
|
|
141
|
+
"COLLATE",
|
|
142
|
+
"COLLATION",
|
|
143
|
+
"COLLECTION",
|
|
144
|
+
"COLUMN",
|
|
145
|
+
"COLUMNS",
|
|
146
|
+
"COMBINE",
|
|
147
|
+
"COMMENT",
|
|
148
|
+
"COMMIT",
|
|
149
|
+
"COMPACT",
|
|
150
|
+
"COMPILE",
|
|
151
|
+
"COMPRESS",
|
|
152
|
+
"CONDITION",
|
|
153
|
+
"CONFLICT",
|
|
154
|
+
"CONNECT",
|
|
155
|
+
"CONNECTION",
|
|
156
|
+
"CONSISTENCY",
|
|
157
|
+
"CONSISTENT",
|
|
158
|
+
"CONSTRAINT",
|
|
159
|
+
"CONSTRAINTS",
|
|
160
|
+
"CONSTRUCTOR",
|
|
161
|
+
"CONSUMED",
|
|
162
|
+
"CONTINUE",
|
|
163
|
+
"CONVERT",
|
|
164
|
+
"COPY",
|
|
165
|
+
"CORRESPONDING",
|
|
166
|
+
"COUNT",
|
|
167
|
+
"COUNTER",
|
|
168
|
+
"CREATE",
|
|
169
|
+
"CROSS",
|
|
170
|
+
"CUBE",
|
|
171
|
+
"CURRENT",
|
|
172
|
+
"CURSOR",
|
|
173
|
+
"CYCLE",
|
|
174
|
+
"DATA",
|
|
175
|
+
"DATABASE",
|
|
176
|
+
"DATE",
|
|
177
|
+
"DATETIME",
|
|
178
|
+
"DAY",
|
|
179
|
+
"DEALLOCATE",
|
|
180
|
+
"DEC",
|
|
181
|
+
"DECIMAL",
|
|
182
|
+
"DECLARE",
|
|
183
|
+
"DEFAULT",
|
|
184
|
+
"DEFERRABLE",
|
|
185
|
+
"DEFERRED",
|
|
186
|
+
"DEFINE",
|
|
187
|
+
"DEFINED",
|
|
188
|
+
"DEFINITION",
|
|
189
|
+
"DELETE",
|
|
190
|
+
"DELIMITED",
|
|
191
|
+
"DEPTH",
|
|
192
|
+
"DEREF",
|
|
193
|
+
"DESC",
|
|
194
|
+
"DESCRIBE",
|
|
195
|
+
"DESCRIPTOR",
|
|
196
|
+
"DETACH",
|
|
197
|
+
"DETERMINISTIC",
|
|
198
|
+
"DIAGNOSTICS",
|
|
199
|
+
"DIRECTORIES",
|
|
200
|
+
"DISABLE",
|
|
201
|
+
"DISCONNECT",
|
|
202
|
+
"DISTINCT",
|
|
203
|
+
"DISTRIBUTE",
|
|
204
|
+
"DO",
|
|
205
|
+
"DOMAIN",
|
|
206
|
+
"DOUBLE",
|
|
207
|
+
"DROP",
|
|
208
|
+
"DUMP",
|
|
209
|
+
"DURATION",
|
|
210
|
+
"DYNAMIC",
|
|
211
|
+
"EACH",
|
|
212
|
+
"ELEMENT",
|
|
213
|
+
"ELSE",
|
|
214
|
+
"ELSEIF",
|
|
215
|
+
"EMPTY",
|
|
216
|
+
"ENABLE",
|
|
217
|
+
"END",
|
|
218
|
+
"EQUAL",
|
|
219
|
+
"EQUALS",
|
|
220
|
+
"ERROR",
|
|
221
|
+
"ESCAPE",
|
|
222
|
+
"EVALUATED",
|
|
223
|
+
"EXCEPT",
|
|
224
|
+
"EXCEPTION",
|
|
225
|
+
"EXCEPTIONS",
|
|
226
|
+
"EXCLUSIVE",
|
|
227
|
+
"EXEC",
|
|
228
|
+
"EXECUTE",
|
|
229
|
+
"EXISTS",
|
|
230
|
+
"EXIT",
|
|
231
|
+
"EXPLAIN",
|
|
232
|
+
"EXPLODE",
|
|
233
|
+
"EXPORT",
|
|
234
|
+
"EXPRESSION",
|
|
235
|
+
"EXTENDED",
|
|
236
|
+
"EXTERNAL",
|
|
237
|
+
"EXTRACT",
|
|
238
|
+
"FAIL",
|
|
239
|
+
"FALSE",
|
|
240
|
+
"FAMILY",
|
|
241
|
+
"FETCH",
|
|
242
|
+
"FIELDS",
|
|
243
|
+
"FILE",
|
|
244
|
+
"FILTER",
|
|
245
|
+
"FILTERING",
|
|
246
|
+
"FINAL",
|
|
247
|
+
"FINISH",
|
|
248
|
+
"FIRST",
|
|
249
|
+
"FIXED",
|
|
250
|
+
"FLATTERN",
|
|
251
|
+
"FLOAT",
|
|
252
|
+
"FOR",
|
|
253
|
+
"FORCE",
|
|
254
|
+
"FOREIGN",
|
|
255
|
+
"FORMAT",
|
|
256
|
+
"FORWARD",
|
|
257
|
+
"FOUND",
|
|
258
|
+
"FREE",
|
|
259
|
+
"FROM",
|
|
260
|
+
"FULL",
|
|
261
|
+
"FUNCTION",
|
|
262
|
+
"FUNCTIONS",
|
|
263
|
+
"GENERAL",
|
|
264
|
+
"GENERATE",
|
|
265
|
+
"GET",
|
|
266
|
+
"GLOB",
|
|
267
|
+
"GO",
|
|
268
|
+
"GOTO",
|
|
269
|
+
"GRANT",
|
|
270
|
+
"GREATER",
|
|
271
|
+
"GROUP",
|
|
272
|
+
"GROUPING",
|
|
273
|
+
"HANDLER",
|
|
274
|
+
"HASH",
|
|
275
|
+
"HAVE",
|
|
276
|
+
"HAVING",
|
|
277
|
+
"HEAP",
|
|
278
|
+
"HIDDEN",
|
|
279
|
+
"HOLD",
|
|
280
|
+
"HOUR",
|
|
281
|
+
"IDENTIFIED",
|
|
282
|
+
"IF",
|
|
283
|
+
"IGNORE",
|
|
284
|
+
"IMMEDIATE",
|
|
285
|
+
"IMPORT",
|
|
286
|
+
"IN",
|
|
287
|
+
"INCLUDING",
|
|
288
|
+
"INCLUSIVE",
|
|
289
|
+
"INCREMENT",
|
|
290
|
+
"INDETERMINATE",
|
|
291
|
+
"INDEX",
|
|
292
|
+
"INDEXED",
|
|
293
|
+
"INDEXES",
|
|
294
|
+
"INDICATOR",
|
|
295
|
+
"INFINITE",
|
|
296
|
+
"INITIALLY",
|
|
297
|
+
"INLINE",
|
|
298
|
+
"INNER",
|
|
299
|
+
"INNTER",
|
|
300
|
+
"INOUT",
|
|
301
|
+
"INPUT",
|
|
302
|
+
"INSENSITIVE",
|
|
303
|
+
"INSERT",
|
|
304
|
+
"INSTEAD",
|
|
305
|
+
"INT",
|
|
306
|
+
"INTEGER",
|
|
307
|
+
"INTERSECT",
|
|
308
|
+
"INTERVAL",
|
|
309
|
+
"INTO",
|
|
310
|
+
"INVALIDATE",
|
|
311
|
+
"IS",
|
|
312
|
+
"ISOLATION",
|
|
313
|
+
"ITEM",
|
|
314
|
+
"ITEMS",
|
|
315
|
+
"ITERATE",
|
|
316
|
+
"JOIN",
|
|
317
|
+
"KEY",
|
|
318
|
+
"KEYS",
|
|
319
|
+
"LAG",
|
|
320
|
+
"LANGUAGE",
|
|
321
|
+
"LARGE",
|
|
322
|
+
"LAST",
|
|
323
|
+
"LATERAL",
|
|
324
|
+
"LEAD",
|
|
325
|
+
"LEADING",
|
|
326
|
+
"LEAVE",
|
|
327
|
+
"LEFT",
|
|
328
|
+
"LENGTH",
|
|
329
|
+
"LESS",
|
|
330
|
+
"LEVEL",
|
|
331
|
+
"LIKE",
|
|
332
|
+
"LIMIT",
|
|
333
|
+
"LIST",
|
|
334
|
+
"LOAD",
|
|
335
|
+
"LOCAL",
|
|
336
|
+
"LOCALTIME",
|
|
337
|
+
"LOCALTIMESTAMP",
|
|
338
|
+
"LOCATION",
|
|
339
|
+
"LOCATOR",
|
|
340
|
+
"LOCK",
|
|
341
|
+
"LOCKS",
|
|
342
|
+
"LOG",
|
|
343
|
+
"LOGED",
|
|
344
|
+
"LONG",
|
|
345
|
+
"LOOP",
|
|
346
|
+
"LOWER",
|
|
347
|
+
"MAP",
|
|
348
|
+
"MATCH",
|
|
349
|
+
"MATERIALIZED",
|
|
350
|
+
"MAX",
|
|
351
|
+
"MAXLEN",
|
|
352
|
+
"MEMBER",
|
|
353
|
+
"MERGE",
|
|
354
|
+
"METHOD",
|
|
355
|
+
"MIN",
|
|
356
|
+
"MINUS",
|
|
357
|
+
"MINUTE",
|
|
358
|
+
"MISSING",
|
|
359
|
+
"MOD",
|
|
360
|
+
"MODE",
|
|
361
|
+
"MODIFIES",
|
|
362
|
+
"MODIFY",
|
|
363
|
+
"MODULE",
|
|
364
|
+
"MONTH",
|
|
365
|
+
"MULTI",
|
|
366
|
+
"MULTISET",
|
|
367
|
+
"NAME",
|
|
368
|
+
"NAMES",
|
|
369
|
+
"NATIONAL",
|
|
370
|
+
"NATURAL",
|
|
371
|
+
"NCHAR",
|
|
372
|
+
"NCLOB",
|
|
373
|
+
"NEW",
|
|
374
|
+
"NEXT",
|
|
375
|
+
"NO",
|
|
376
|
+
"NONE",
|
|
377
|
+
"NOT",
|
|
378
|
+
"NULL",
|
|
379
|
+
"NULLIF",
|
|
380
|
+
"NUMBER",
|
|
381
|
+
"NUMERIC",
|
|
382
|
+
"OBJECT",
|
|
383
|
+
"OF",
|
|
384
|
+
"OFFLINE",
|
|
385
|
+
"OFFSET",
|
|
386
|
+
"OLD",
|
|
387
|
+
"ON",
|
|
388
|
+
"ONLINE",
|
|
389
|
+
"ONLY",
|
|
390
|
+
"OPEN",
|
|
391
|
+
"OPTION",
|
|
392
|
+
"OR",
|
|
393
|
+
"ORDER",
|
|
394
|
+
"ORDINALITY",
|
|
395
|
+
"OUT",
|
|
396
|
+
"OUTER",
|
|
397
|
+
"OUTPUT",
|
|
398
|
+
"OVER",
|
|
399
|
+
"OVERLAPS",
|
|
400
|
+
"OVERRIDE",
|
|
401
|
+
"OWNER",
|
|
402
|
+
"PAD",
|
|
403
|
+
"PARALLEL",
|
|
404
|
+
"PARAMETER",
|
|
405
|
+
"PARAMETERS",
|
|
406
|
+
"PARTIAL",
|
|
407
|
+
"PARTITION",
|
|
408
|
+
"PARTITIONED",
|
|
409
|
+
"PARTITIONS",
|
|
410
|
+
"PATH",
|
|
411
|
+
"PERCENT",
|
|
412
|
+
"PERCENTILE",
|
|
413
|
+
"PERMISSION",
|
|
414
|
+
"PERMISSIONS",
|
|
415
|
+
"PIPE",
|
|
416
|
+
"PIPELINED",
|
|
417
|
+
"PLAN",
|
|
418
|
+
"POOL",
|
|
419
|
+
"POSITION",
|
|
420
|
+
"PRECISION",
|
|
421
|
+
"PREPARE",
|
|
422
|
+
"PRESERVE",
|
|
423
|
+
"PRIMARY",
|
|
424
|
+
"PRIOR",
|
|
425
|
+
"PRIVATE",
|
|
426
|
+
"PRIVILEGES",
|
|
427
|
+
"PROCEDURE",
|
|
428
|
+
"PROCESSED",
|
|
429
|
+
"PROJECT",
|
|
430
|
+
"PROJECTION",
|
|
431
|
+
"PROPERTY",
|
|
432
|
+
"PROVISIONING",
|
|
433
|
+
"PUBLIC",
|
|
434
|
+
"PUT",
|
|
435
|
+
"QUERY",
|
|
436
|
+
"QUIT",
|
|
437
|
+
"QUORUM",
|
|
438
|
+
"RAISE",
|
|
439
|
+
"RANDOM",
|
|
440
|
+
"RANGE",
|
|
441
|
+
"RANK",
|
|
442
|
+
"RAW",
|
|
443
|
+
"READ",
|
|
444
|
+
"READS",
|
|
445
|
+
"REAL",
|
|
446
|
+
"REBUILD",
|
|
447
|
+
"RECORD",
|
|
448
|
+
"RECURSIVE",
|
|
449
|
+
"REDUCE",
|
|
450
|
+
"REF",
|
|
451
|
+
"REFERENCE",
|
|
452
|
+
"REFERENCES",
|
|
453
|
+
"REFERENCING",
|
|
454
|
+
"REGEXP",
|
|
455
|
+
"REINDEX",
|
|
456
|
+
"RELATIVE",
|
|
457
|
+
"RELEASE",
|
|
458
|
+
"REMAINDER",
|
|
459
|
+
"RENAME",
|
|
460
|
+
"REPEAT",
|
|
461
|
+
"REPLACE",
|
|
462
|
+
"REQUEST",
|
|
463
|
+
"RESET",
|
|
464
|
+
"RESIGNAL",
|
|
465
|
+
"RESTRICT",
|
|
466
|
+
"RESULT",
|
|
467
|
+
"RETURN",
|
|
468
|
+
"RETURNING",
|
|
469
|
+
"RETURNS",
|
|
470
|
+
"REVERSE",
|
|
471
|
+
"REVOKE",
|
|
472
|
+
"RIGHT",
|
|
473
|
+
"ROLE",
|
|
474
|
+
"ROLES",
|
|
475
|
+
"ROLLBACK",
|
|
476
|
+
"ROLLUP",
|
|
477
|
+
"ROUTINE",
|
|
478
|
+
"ROW",
|
|
479
|
+
"ROWS",
|
|
480
|
+
"RULE",
|
|
481
|
+
"RULES",
|
|
482
|
+
"SAMPLE",
|
|
483
|
+
"SATISFIES",
|
|
484
|
+
"SAVE",
|
|
485
|
+
"SAVEPOINT",
|
|
486
|
+
"SCAN",
|
|
487
|
+
"SCHEMA",
|
|
488
|
+
"SCOPE",
|
|
489
|
+
"SCROLL",
|
|
490
|
+
"SEARCH",
|
|
491
|
+
"SECOND",
|
|
492
|
+
"SECTION",
|
|
493
|
+
"SEGMENT",
|
|
494
|
+
"SELECT",
|
|
495
|
+
"SELF",
|
|
496
|
+
"SEMI",
|
|
497
|
+
"SENSITIVE",
|
|
498
|
+
"SEPARATE",
|
|
499
|
+
"SEQUENCE",
|
|
500
|
+
"SERIALIZABLE",
|
|
501
|
+
"SESSION",
|
|
502
|
+
"SET",
|
|
503
|
+
"SETS",
|
|
504
|
+
"SHARD",
|
|
505
|
+
"SHARE",
|
|
506
|
+
"SHARED",
|
|
507
|
+
"SHORT",
|
|
508
|
+
"SHOW",
|
|
509
|
+
"SIGNAL",
|
|
510
|
+
"SIMILAR",
|
|
511
|
+
"SIZE",
|
|
512
|
+
"SKEWED",
|
|
513
|
+
"SOME",
|
|
514
|
+
"SOURCE",
|
|
515
|
+
"SPACE",
|
|
516
|
+
"SPACES",
|
|
517
|
+
"SPARSE",
|
|
518
|
+
"SPECIFIC",
|
|
519
|
+
"SPECIFICTYPE",
|
|
520
|
+
"SQL",
|
|
521
|
+
"SQLCODE",
|
|
522
|
+
"SQLERROR",
|
|
523
|
+
"SQLEXCEPTION",
|
|
524
|
+
"SQLSTATE",
|
|
525
|
+
"SQLWARNING",
|
|
526
|
+
"START",
|
|
527
|
+
"STATE",
|
|
528
|
+
"STATIC",
|
|
529
|
+
"STATUS",
|
|
530
|
+
"STORAGE",
|
|
531
|
+
"STORE",
|
|
532
|
+
"STORED",
|
|
533
|
+
"STREAM",
|
|
534
|
+
"STRING",
|
|
535
|
+
"STRUCT",
|
|
536
|
+
"STYLE",
|
|
537
|
+
"SUB",
|
|
538
|
+
"SUBMULTISET",
|
|
539
|
+
"SUBPARTITION",
|
|
540
|
+
"SUBSTRING",
|
|
541
|
+
"SUBTYPE",
|
|
542
|
+
"SUM",
|
|
543
|
+
"SUPER",
|
|
544
|
+
"SYMMETRIC",
|
|
545
|
+
"SYNONYM",
|
|
546
|
+
"SYSTEM",
|
|
547
|
+
"TABLE",
|
|
548
|
+
"TABLESAMPLE",
|
|
549
|
+
"TEMP",
|
|
550
|
+
"TEMPORARY",
|
|
551
|
+
"TERMINATED",
|
|
552
|
+
"TEXT",
|
|
553
|
+
"THAN",
|
|
554
|
+
"THEN",
|
|
555
|
+
"THROUGHPUT",
|
|
556
|
+
"TIME",
|
|
557
|
+
"TIMESTAMP",
|
|
558
|
+
"TIMEZONE",
|
|
559
|
+
"TINYINT",
|
|
560
|
+
"TO",
|
|
561
|
+
"TOKEN",
|
|
562
|
+
"TOTAL",
|
|
563
|
+
"TOUCH",
|
|
564
|
+
"TRAILING",
|
|
565
|
+
"TRANSACTION",
|
|
566
|
+
"TRANSFORM",
|
|
567
|
+
"TRANSLATE",
|
|
568
|
+
"TRANSLATION",
|
|
569
|
+
"TREAT",
|
|
570
|
+
"TRIGGER",
|
|
571
|
+
"TRIM",
|
|
572
|
+
"TRUE",
|
|
573
|
+
"TRUNCATE",
|
|
574
|
+
"TTL",
|
|
575
|
+
"TUPLE",
|
|
576
|
+
"TYPE",
|
|
577
|
+
"UNDER",
|
|
578
|
+
"UNDO",
|
|
579
|
+
"UNION",
|
|
580
|
+
"UNIQUE",
|
|
581
|
+
"UNIT",
|
|
582
|
+
"UNKNOWN",
|
|
583
|
+
"UNLOGGED",
|
|
584
|
+
"UNNEST",
|
|
585
|
+
"UNPROCESSED",
|
|
586
|
+
"UNSIGNED",
|
|
587
|
+
"UNTIL",
|
|
588
|
+
"UPDATE",
|
|
589
|
+
"UPPER",
|
|
590
|
+
"URL",
|
|
591
|
+
"USAGE",
|
|
592
|
+
"USE",
|
|
593
|
+
"USER",
|
|
594
|
+
"USERS",
|
|
595
|
+
"USING",
|
|
596
|
+
"UUID",
|
|
597
|
+
"VACUUM",
|
|
598
|
+
"VALUE",
|
|
599
|
+
"VALUED",
|
|
600
|
+
"VALUES",
|
|
601
|
+
"VARCHAR",
|
|
602
|
+
"VARIABLE",
|
|
603
|
+
"VARIANCE",
|
|
604
|
+
"VARINT",
|
|
605
|
+
"VARYING",
|
|
606
|
+
"VIEW",
|
|
607
|
+
"VIEWS",
|
|
608
|
+
"VIRTUAL",
|
|
609
|
+
"VOID",
|
|
610
|
+
"WAIT",
|
|
611
|
+
"WHEN",
|
|
612
|
+
"WHENEVER",
|
|
613
|
+
"WHERE",
|
|
614
|
+
"WHILE",
|
|
615
|
+
"WINDOW",
|
|
616
|
+
"WITH",
|
|
617
|
+
"WITHIN",
|
|
618
|
+
"WITHOUT",
|
|
619
|
+
"WORK",
|
|
620
|
+
"WRAPPED",
|
|
621
|
+
"WRITE",
|
|
622
|
+
"YEAR",
|
|
623
|
+
"ZONE",
|
|
624
|
+
// Common attribute names that often conflict
|
|
625
|
+
"NAME",
|
|
626
|
+
"STATUS",
|
|
627
|
+
"SCORE",
|
|
628
|
+
"PRICE",
|
|
629
|
+
"CATEGORY"
|
|
630
|
+
]);
|
|
631
|
+
var DynamoService = class {
|
|
632
|
+
constructor() {
|
|
633
|
+
this.isConnectedFlag = false;
|
|
634
|
+
}
|
|
635
|
+
setConfig(config) {
|
|
636
|
+
this.config = config;
|
|
637
|
+
}
|
|
638
|
+
connect() {
|
|
639
|
+
if (!this.config) {
|
|
640
|
+
return Promise.reject(new DatabaseAdapterError(
|
|
641
|
+
"No configuration provided. Call setConfig() first.",
|
|
642
|
+
"INVALID_CONFIG"
|
|
643
|
+
));
|
|
644
|
+
}
|
|
645
|
+
return Promise.resolve().then(() => {
|
|
646
|
+
try {
|
|
647
|
+
this.validateConfig(this.config);
|
|
648
|
+
this.dynamoDBClient = new import_client_dynamodb.DynamoDBClient({
|
|
649
|
+
region: this.config.region,
|
|
650
|
+
endpoint: this.config.endpoint,
|
|
651
|
+
credentials: this.config.accessKeyId ? {
|
|
652
|
+
accessKeyId: this.config.accessKeyId,
|
|
653
|
+
secretAccessKey: this.config.secretAccessKey
|
|
654
|
+
} : void 0
|
|
655
|
+
});
|
|
656
|
+
this.client = import_lib_dynamodb.DynamoDBDocumentClient.from(this.dynamoDBClient);
|
|
657
|
+
this.isConnectedFlag = true;
|
|
658
|
+
} catch (error) {
|
|
659
|
+
this.isConnectedFlag = false;
|
|
660
|
+
if (error instanceof DatabaseAdapterError) {
|
|
661
|
+
throw error;
|
|
662
|
+
}
|
|
663
|
+
if (error instanceof Error) {
|
|
664
|
+
throw new DatabaseAdapterError(
|
|
665
|
+
`Failed to connect to DynamoDB: ${error.message}`,
|
|
666
|
+
"CONNECTION_FAILED"
|
|
667
|
+
);
|
|
668
|
+
}
|
|
669
|
+
throw new DatabaseAdapterError(
|
|
670
|
+
"Failed to connect to DynamoDB: Unknown error",
|
|
671
|
+
"CONNECTION_FAILED"
|
|
672
|
+
);
|
|
673
|
+
}
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
async disconnect() {
|
|
677
|
+
try {
|
|
678
|
+
if (this.dynamoDBClient) {
|
|
679
|
+
this.dynamoDBClient.destroy();
|
|
680
|
+
}
|
|
681
|
+
this.isConnectedFlag = false;
|
|
682
|
+
this.client = void 0;
|
|
683
|
+
this.dynamoDBClient = void 0;
|
|
684
|
+
} catch (error) {
|
|
685
|
+
console.warn("Error disconnecting from DynamoDB:", error);
|
|
686
|
+
this.isConnectedFlag = false;
|
|
687
|
+
this.client = void 0;
|
|
688
|
+
this.dynamoDBClient = void 0;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
isConnected() {
|
|
692
|
+
return this.isConnectedFlag && this.client !== void 0;
|
|
693
|
+
}
|
|
694
|
+
async healthCheck() {
|
|
695
|
+
try {
|
|
696
|
+
const client = this.getClient();
|
|
697
|
+
await client.send(new import_lib_dynamodb2.ScanCommand({ TableName: "fake_table", Limit: 1 }));
|
|
698
|
+
return true;
|
|
699
|
+
} catch (error) {
|
|
700
|
+
if (error instanceof Error && error.message.includes("ResourceNotFoundException")) {
|
|
701
|
+
return true;
|
|
702
|
+
}
|
|
703
|
+
return false;
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
async selectOne(tableName, where, options) {
|
|
707
|
+
try {
|
|
708
|
+
const client = this.getClient();
|
|
709
|
+
const key = this.buildKey(where);
|
|
710
|
+
const params = {
|
|
711
|
+
TableName: tableName,
|
|
712
|
+
Key: key
|
|
713
|
+
};
|
|
714
|
+
if (options == null ? void 0 : options.projection) {
|
|
715
|
+
const { projection, names } = this.buildProjection(options.projection);
|
|
716
|
+
params.ProjectionExpression = projection;
|
|
717
|
+
if (Object.keys(names).length > 0) {
|
|
718
|
+
params.ExpressionAttributeNames = names;
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
const command = new import_lib_dynamodb2.GetCommand(params);
|
|
722
|
+
const result = await client.send(command);
|
|
723
|
+
return result.Item || null;
|
|
724
|
+
} catch (error) {
|
|
725
|
+
throw this.handleError(error, "selectOne");
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
async selectMany(tableName, where, options) {
|
|
729
|
+
var _a, _b, _c;
|
|
730
|
+
try {
|
|
731
|
+
const client = this.getClient();
|
|
732
|
+
let command;
|
|
733
|
+
let items = [];
|
|
734
|
+
let scannedCount = 0;
|
|
735
|
+
const isKeyQuery = where && this.isKeyQuery(where);
|
|
736
|
+
if (isKeyQuery) {
|
|
737
|
+
const { keyConditionExpression, expressionAttributeValues, names } = this.buildKeyConditionExpression(where);
|
|
738
|
+
const params = {
|
|
739
|
+
TableName: tableName,
|
|
740
|
+
KeyConditionExpression: keyConditionExpression,
|
|
741
|
+
ExpressionAttributeValues: expressionAttributeValues,
|
|
742
|
+
Limit: options == null ? void 0 : options.limit,
|
|
743
|
+
ScanIndexForward: ((_b = (_a = options == null ? void 0 : options.orderBy) == null ? void 0 : _a[0]) == null ? void 0 : _b.direction) === "DESC" ? false : true,
|
|
744
|
+
ConsistentRead: options == null ? void 0 : options.consistent
|
|
745
|
+
};
|
|
746
|
+
if (Object.keys(names).length > 0) {
|
|
747
|
+
params.ExpressionAttributeNames = names;
|
|
748
|
+
}
|
|
749
|
+
if (options == null ? void 0 : options.projection) {
|
|
750
|
+
const { projection, names: projNames } = this.buildProjection(options.projection);
|
|
751
|
+
params.ProjectionExpression = projection;
|
|
752
|
+
if (Object.keys(projNames).length > 0) {
|
|
753
|
+
params.ExpressionAttributeNames = { ...params.ExpressionAttributeNames, ...projNames };
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
command = new import_lib_dynamodb2.QueryCommand(params);
|
|
757
|
+
} else {
|
|
758
|
+
const params = {
|
|
759
|
+
TableName: tableName,
|
|
760
|
+
Limit: options == null ? void 0 : options.limit
|
|
761
|
+
};
|
|
762
|
+
if (where && Object.keys(where).length > 0) {
|
|
763
|
+
const { filterExpression, expressionAttributeValues, names } = this.buildFilterExpression(where);
|
|
764
|
+
params.FilterExpression = filterExpression;
|
|
765
|
+
params.ExpressionAttributeValues = expressionAttributeValues;
|
|
766
|
+
if (Object.keys(names).length > 0) {
|
|
767
|
+
params.ExpressionAttributeNames = names;
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
if (options == null ? void 0 : options.projection) {
|
|
771
|
+
const { projection, names: projNames } = this.buildProjection(options.projection);
|
|
772
|
+
params.ProjectionExpression = projection;
|
|
773
|
+
if (Object.keys(projNames).length > 0) {
|
|
774
|
+
params.ExpressionAttributeNames = { ...params.ExpressionAttributeNames, ...projNames };
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
command = new import_lib_dynamodb2.ScanCommand(params);
|
|
778
|
+
}
|
|
779
|
+
const result = await client.send(command);
|
|
780
|
+
items = result.Items || [];
|
|
781
|
+
scannedCount = result.ScannedCount || 0;
|
|
782
|
+
if (!isKeyQuery && ((_c = options == null ? void 0 : options.orderBy) == null ? void 0 : _c.length)) {
|
|
783
|
+
const { field, direction } = options.orderBy[0];
|
|
784
|
+
items = [...items].sort((a, b) => {
|
|
785
|
+
if (a[field] < b[field]) return direction === "DESC" ? 1 : -1;
|
|
786
|
+
if (a[field] > b[field]) return direction === "DESC" ? -1 : 1;
|
|
787
|
+
return 0;
|
|
788
|
+
});
|
|
789
|
+
}
|
|
790
|
+
return {
|
|
791
|
+
items,
|
|
792
|
+
total: items.length,
|
|
793
|
+
hasMore: result.LastEvaluatedKey !== void 0,
|
|
794
|
+
nextOffset: (options == null ? void 0 : options.offset) ? options.offset + items.length : void 0
|
|
795
|
+
};
|
|
796
|
+
} catch (error) {
|
|
797
|
+
throw this.handleError(error, "selectMany");
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
async createOne(tableName, data) {
|
|
801
|
+
try {
|
|
802
|
+
const client = this.getClient();
|
|
803
|
+
const command = new import_lib_dynamodb2.PutCommand({
|
|
804
|
+
TableName: tableName,
|
|
805
|
+
Item: data
|
|
806
|
+
});
|
|
807
|
+
await client.send(command);
|
|
808
|
+
return data;
|
|
809
|
+
} catch (error) {
|
|
810
|
+
throw this.handleError(error, "createOne");
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
async createMany(tableName, data, options) {
|
|
814
|
+
try {
|
|
815
|
+
if (!Array.isArray(data)) {
|
|
816
|
+
throw new DatabaseAdapterError(
|
|
817
|
+
"createMany requires an array of records",
|
|
818
|
+
"INVALID_INPUT"
|
|
819
|
+
);
|
|
820
|
+
}
|
|
821
|
+
const client = this.getClient();
|
|
822
|
+
const batchSize = 25;
|
|
823
|
+
let successful = 0;
|
|
824
|
+
let failed = 0;
|
|
825
|
+
const errors = [];
|
|
826
|
+
const items = [];
|
|
827
|
+
for (let i = 0; i < data.length; i += batchSize) {
|
|
828
|
+
const batch = data.slice(i, i + batchSize);
|
|
829
|
+
const requestItems = batch.map((item) => ({
|
|
830
|
+
PutRequest: { Item: item }
|
|
831
|
+
}));
|
|
832
|
+
try {
|
|
833
|
+
const command = new import_lib_dynamodb2.BatchWriteCommand({
|
|
834
|
+
RequestItems: {
|
|
835
|
+
[tableName]: requestItems
|
|
836
|
+
}
|
|
837
|
+
});
|
|
838
|
+
await client.send(command);
|
|
839
|
+
successful += batch.length;
|
|
840
|
+
items.push(...batch);
|
|
841
|
+
} catch (error) {
|
|
842
|
+
if (options == null ? void 0 : options.stopOnError) {
|
|
843
|
+
throw error;
|
|
844
|
+
}
|
|
845
|
+
failed += batch.length;
|
|
846
|
+
batch.forEach((_, index) => {
|
|
847
|
+
errors.push({
|
|
848
|
+
index: i + index,
|
|
849
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
850
|
+
});
|
|
851
|
+
});
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
return {
|
|
855
|
+
items,
|
|
856
|
+
result: { successful, failed, errors: errors.length > 0 ? errors : void 0 }
|
|
857
|
+
};
|
|
858
|
+
} catch (error) {
|
|
859
|
+
throw this.handleError(error, "createMany");
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
async updateOne(tableName, update, where) {
|
|
863
|
+
try {
|
|
864
|
+
const client = this.getClient();
|
|
865
|
+
const key = this.buildKey(where);
|
|
866
|
+
const existing = await client.send(new import_lib_dynamodb2.GetCommand({ TableName: tableName, Key: key }));
|
|
867
|
+
if (!existing.Item) {
|
|
868
|
+
throw new DatabaseAdapterError(
|
|
869
|
+
`Record not found`,
|
|
870
|
+
"NOT_FOUND"
|
|
871
|
+
);
|
|
872
|
+
}
|
|
873
|
+
const { updateExpression, expressionAttributeValues, names } = this.buildUpdateExpression(update);
|
|
874
|
+
const params = {
|
|
875
|
+
TableName: tableName,
|
|
876
|
+
Key: key,
|
|
877
|
+
UpdateExpression: updateExpression,
|
|
878
|
+
ReturnValues: "ALL_NEW"
|
|
879
|
+
};
|
|
880
|
+
if (Object.keys(expressionAttributeValues).length > 0) {
|
|
881
|
+
params.ExpressionAttributeValues = expressionAttributeValues;
|
|
882
|
+
}
|
|
883
|
+
if (Object.keys(names).length > 0) {
|
|
884
|
+
params.ExpressionAttributeNames = names;
|
|
885
|
+
}
|
|
886
|
+
const command = new import_lib_dynamodb2.UpdateCommand(params);
|
|
887
|
+
const result = await client.send(command);
|
|
888
|
+
return result.Attributes;
|
|
889
|
+
} catch (error) {
|
|
890
|
+
throw this.handleError(error, "updateOne");
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
async updateMany(tableName, update, where, options) {
|
|
894
|
+
try {
|
|
895
|
+
const selectResult = await this.selectMany(
|
|
896
|
+
tableName,
|
|
897
|
+
where,
|
|
898
|
+
{ limit: options == null ? void 0 : options.limit }
|
|
899
|
+
);
|
|
900
|
+
let successful = 0;
|
|
901
|
+
let failed = 0;
|
|
902
|
+
const errors = [];
|
|
903
|
+
const items = [];
|
|
904
|
+
for (let i = 0; i < selectResult.items.length; i++) {
|
|
905
|
+
try {
|
|
906
|
+
const item = selectResult.items[i];
|
|
907
|
+
const key = this.extractKey(item);
|
|
908
|
+
const updated = await this.updateOne(tableName, update, key);
|
|
909
|
+
successful++;
|
|
910
|
+
items.push(updated);
|
|
911
|
+
} catch (error) {
|
|
912
|
+
failed++;
|
|
913
|
+
errors.push({
|
|
914
|
+
index: i,
|
|
915
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
916
|
+
});
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
return {
|
|
920
|
+
items,
|
|
921
|
+
result: { successful, failed, errors: errors.length > 0 ? errors : void 0 }
|
|
922
|
+
};
|
|
923
|
+
} catch (error) {
|
|
924
|
+
throw this.handleError(error, "updateMany");
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
async deleteOne(tableName, where) {
|
|
928
|
+
try {
|
|
929
|
+
const client = this.getClient();
|
|
930
|
+
const key = this.buildKey(where);
|
|
931
|
+
const getResult = await client.send(new import_lib_dynamodb2.GetCommand({
|
|
932
|
+
TableName: tableName,
|
|
933
|
+
Key: key
|
|
934
|
+
}));
|
|
935
|
+
if (!getResult.Item) {
|
|
936
|
+
return { success: false, deletedCount: 0 };
|
|
937
|
+
}
|
|
938
|
+
const command = new import_lib_dynamodb2.DeleteCommand({
|
|
939
|
+
TableName: tableName,
|
|
940
|
+
Key: key
|
|
941
|
+
});
|
|
942
|
+
await client.send(command);
|
|
943
|
+
return { success: true, deletedCount: 1 };
|
|
944
|
+
} catch (error) {
|
|
945
|
+
throw this.handleError(error, "deleteOne");
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
async deleteMany(tableName, where, options) {
|
|
949
|
+
try {
|
|
950
|
+
const selectResult = await this.selectMany(
|
|
951
|
+
tableName,
|
|
952
|
+
where,
|
|
953
|
+
{ limit: options == null ? void 0 : options.limit }
|
|
954
|
+
);
|
|
955
|
+
let successful = 0;
|
|
956
|
+
let failed = 0;
|
|
957
|
+
const errors = [];
|
|
958
|
+
for (let i = 0; i < selectResult.items.length; i++) {
|
|
959
|
+
try {
|
|
960
|
+
const item = selectResult.items[i];
|
|
961
|
+
const key = this.extractKey(item);
|
|
962
|
+
await this.deleteOne(tableName, key);
|
|
963
|
+
successful++;
|
|
964
|
+
} catch (error) {
|
|
965
|
+
failed++;
|
|
966
|
+
errors.push({
|
|
967
|
+
index: i,
|
|
968
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
969
|
+
});
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
return {
|
|
973
|
+
success: failed === 0,
|
|
974
|
+
deletedCount: successful,
|
|
975
|
+
result: { successful, failed, errors: errors.length > 0 ? errors : void 0 }
|
|
976
|
+
};
|
|
977
|
+
} catch (error) {
|
|
978
|
+
throw this.handleError(error, "deleteMany");
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
async executeRaw(query, params) {
|
|
982
|
+
throw new DatabaseAdapterError(
|
|
983
|
+
"executeRaw is not implemented for DynamoDB. Use native DynamoDB syntax instead.",
|
|
984
|
+
"NOT_IMPLEMENTED"
|
|
985
|
+
);
|
|
986
|
+
}
|
|
987
|
+
// ============ Private Helper Methods ============
|
|
988
|
+
validateConfig(config) {
|
|
989
|
+
if (!config) {
|
|
990
|
+
throw new DatabaseAdapterError(
|
|
991
|
+
"DynamoDB configuration is required",
|
|
992
|
+
"INVALID_CONFIG"
|
|
993
|
+
);
|
|
994
|
+
}
|
|
995
|
+
if (!config.region || config.region.trim() === "") {
|
|
996
|
+
throw new DatabaseAdapterError(
|
|
997
|
+
"DynamoDB region is required",
|
|
998
|
+
"MISSING_REGION"
|
|
999
|
+
);
|
|
1000
|
+
}
|
|
1001
|
+
if (config.accessKeyId && !config.secretAccessKey) {
|
|
1002
|
+
throw new DatabaseAdapterError(
|
|
1003
|
+
"secretAccessKey is required when accessKeyId is provided",
|
|
1004
|
+
"INVALID_CREDENTIALS"
|
|
1005
|
+
);
|
|
1006
|
+
}
|
|
1007
|
+
if (config.secretAccessKey && !config.accessKeyId) {
|
|
1008
|
+
throw new DatabaseAdapterError(
|
|
1009
|
+
"accessKeyId is required when secretAccessKey is provided",
|
|
1010
|
+
"INVALID_CREDENTIALS"
|
|
1011
|
+
);
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
getClient() {
|
|
1015
|
+
if (!this.isConnectedFlag || !this.client) {
|
|
1016
|
+
throw new DatabaseAdapterError(
|
|
1017
|
+
"DynamoDB client is not connected. Call connect() first.",
|
|
1018
|
+
"NOT_CONNECTED"
|
|
1019
|
+
);
|
|
1020
|
+
}
|
|
1021
|
+
return this.client;
|
|
1022
|
+
}
|
|
1023
|
+
buildKey(where) {
|
|
1024
|
+
const key = {};
|
|
1025
|
+
for (const [field, condition] of Object.entries(where)) {
|
|
1026
|
+
if (condition == null) {
|
|
1027
|
+
continue;
|
|
1028
|
+
}
|
|
1029
|
+
if (typeof condition === "object" && "value" in condition) {
|
|
1030
|
+
key[field] = condition.value;
|
|
1031
|
+
} else {
|
|
1032
|
+
key[field] = condition;
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
return key;
|
|
1036
|
+
}
|
|
1037
|
+
extractKey(item) {
|
|
1038
|
+
return {
|
|
1039
|
+
id: {
|
|
1040
|
+
operator: "=",
|
|
1041
|
+
value: item.id
|
|
1042
|
+
}
|
|
1043
|
+
};
|
|
1044
|
+
}
|
|
1045
|
+
isKeyQuery(where) {
|
|
1046
|
+
return Object.keys(where).some((key) => {
|
|
1047
|
+
if (key !== "id") return false;
|
|
1048
|
+
const cond = where[key];
|
|
1049
|
+
if (typeof cond === "object" && "operator" in cond) {
|
|
1050
|
+
const unsupportedInKey = ["IN", "NOT_IN"];
|
|
1051
|
+
return !unsupportedInKey.includes(cond.operator);
|
|
1052
|
+
}
|
|
1053
|
+
return true;
|
|
1054
|
+
});
|
|
1055
|
+
}
|
|
1056
|
+
buildProjection(fields) {
|
|
1057
|
+
const names = {};
|
|
1058
|
+
const projectionParts = [];
|
|
1059
|
+
for (const field of fields) {
|
|
1060
|
+
if (RESERVED_KEYWORDS.has(field.toUpperCase())) {
|
|
1061
|
+
const placeholder = `#${field}`;
|
|
1062
|
+
names[placeholder] = field;
|
|
1063
|
+
projectionParts.push(placeholder);
|
|
1064
|
+
} else {
|
|
1065
|
+
projectionParts.push(field);
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
return {
|
|
1069
|
+
projection: projectionParts.join(", "),
|
|
1070
|
+
names
|
|
1071
|
+
};
|
|
1072
|
+
}
|
|
1073
|
+
buildKeyConditionExpression(where) {
|
|
1074
|
+
const parts = [];
|
|
1075
|
+
const values = {};
|
|
1076
|
+
const names = {};
|
|
1077
|
+
let valueIndex = 0;
|
|
1078
|
+
for (const [field, condition] of Object.entries(where)) {
|
|
1079
|
+
const valueKey = `:val${valueIndex}`;
|
|
1080
|
+
const cond = condition;
|
|
1081
|
+
const fieldPlaceholder = RESERVED_KEYWORDS.has(field.toUpperCase()) ? `#${field}` : field;
|
|
1082
|
+
if (RESERVED_KEYWORDS.has(field.toUpperCase())) {
|
|
1083
|
+
names[fieldPlaceholder] = field;
|
|
1084
|
+
}
|
|
1085
|
+
if (typeof cond === "object" && "operator" in cond) {
|
|
1086
|
+
const operator = cond.operator;
|
|
1087
|
+
switch (operator) {
|
|
1088
|
+
case "=":
|
|
1089
|
+
parts.push(`${fieldPlaceholder} = ${valueKey}`);
|
|
1090
|
+
values[valueKey] = cond.value;
|
|
1091
|
+
break;
|
|
1092
|
+
case "!=":
|
|
1093
|
+
parts.push(`${fieldPlaceholder} <> ${valueKey}`);
|
|
1094
|
+
values[valueKey] = cond.value;
|
|
1095
|
+
break;
|
|
1096
|
+
case ">":
|
|
1097
|
+
parts.push(`${fieldPlaceholder} > ${valueKey}`);
|
|
1098
|
+
values[valueKey] = cond.value;
|
|
1099
|
+
break;
|
|
1100
|
+
case ">=":
|
|
1101
|
+
parts.push(`${fieldPlaceholder} >= ${valueKey}`);
|
|
1102
|
+
values[valueKey] = cond.value;
|
|
1103
|
+
break;
|
|
1104
|
+
case "<":
|
|
1105
|
+
parts.push(`${fieldPlaceholder} < ${valueKey}`);
|
|
1106
|
+
values[valueKey] = cond.value;
|
|
1107
|
+
break;
|
|
1108
|
+
case "<=":
|
|
1109
|
+
parts.push(`${fieldPlaceholder} <= ${valueKey}`);
|
|
1110
|
+
values[valueKey] = cond.value;
|
|
1111
|
+
break;
|
|
1112
|
+
case "BEGINS_WITH":
|
|
1113
|
+
parts.push(`begins_with(${fieldPlaceholder}, ${valueKey})`);
|
|
1114
|
+
values[valueKey] = cond.value;
|
|
1115
|
+
break;
|
|
1116
|
+
case "IN":
|
|
1117
|
+
const inValues = cond.value.map((v, i) => `:inval${valueIndex}_${i}`);
|
|
1118
|
+
cond.value.forEach((v, i) => {
|
|
1119
|
+
values[`:inval${valueIndex}_${i}`] = v;
|
|
1120
|
+
});
|
|
1121
|
+
parts.push(`${fieldPlaceholder} IN (${inValues.join(", ")})`);
|
|
1122
|
+
valueIndex += cond.value.length - 1;
|
|
1123
|
+
break;
|
|
1124
|
+
default:
|
|
1125
|
+
throw new DatabaseAdapterError(
|
|
1126
|
+
`Unsupported operator: ${operator}`,
|
|
1127
|
+
"UNSUPPORTED_OPERATOR"
|
|
1128
|
+
);
|
|
1129
|
+
}
|
|
1130
|
+
} else {
|
|
1131
|
+
parts.push(`${fieldPlaceholder} = ${valueKey}`);
|
|
1132
|
+
values[valueKey] = cond;
|
|
1133
|
+
}
|
|
1134
|
+
valueIndex++;
|
|
1135
|
+
}
|
|
1136
|
+
return {
|
|
1137
|
+
keyConditionExpression: parts.join(" AND "),
|
|
1138
|
+
expressionAttributeValues: Object.keys(values).length > 0 ? values : {},
|
|
1139
|
+
names
|
|
1140
|
+
};
|
|
1141
|
+
}
|
|
1142
|
+
buildFilterExpression(where) {
|
|
1143
|
+
const parts = [];
|
|
1144
|
+
const values = {};
|
|
1145
|
+
const names = {};
|
|
1146
|
+
let valueIndex = 0;
|
|
1147
|
+
for (const [field, condition] of Object.entries(where)) {
|
|
1148
|
+
const valueKey = `:val${valueIndex}`;
|
|
1149
|
+
const cond = condition;
|
|
1150
|
+
const fieldPlaceholder = RESERVED_KEYWORDS.has(field.toUpperCase()) ? `#${field}` : field;
|
|
1151
|
+
if (RESERVED_KEYWORDS.has(field.toUpperCase())) {
|
|
1152
|
+
names[fieldPlaceholder] = field;
|
|
1153
|
+
}
|
|
1154
|
+
if (typeof cond === "object" && "operator" in cond) {
|
|
1155
|
+
const operator = cond.operator;
|
|
1156
|
+
switch (operator) {
|
|
1157
|
+
case "=":
|
|
1158
|
+
parts.push(`${fieldPlaceholder} = ${valueKey}`);
|
|
1159
|
+
values[valueKey] = cond.value;
|
|
1160
|
+
break;
|
|
1161
|
+
case "!=":
|
|
1162
|
+
parts.push(`${fieldPlaceholder} <> ${valueKey}`);
|
|
1163
|
+
values[valueKey] = cond.value;
|
|
1164
|
+
break;
|
|
1165
|
+
case ">":
|
|
1166
|
+
parts.push(`${fieldPlaceholder} > ${valueKey}`);
|
|
1167
|
+
values[valueKey] = cond.value;
|
|
1168
|
+
break;
|
|
1169
|
+
case ">=":
|
|
1170
|
+
parts.push(`${fieldPlaceholder} >= ${valueKey}`);
|
|
1171
|
+
values[valueKey] = cond.value;
|
|
1172
|
+
break;
|
|
1173
|
+
case "<":
|
|
1174
|
+
parts.push(`${fieldPlaceholder} < ${valueKey}`);
|
|
1175
|
+
values[valueKey] = cond.value;
|
|
1176
|
+
break;
|
|
1177
|
+
case "<=":
|
|
1178
|
+
parts.push(`${fieldPlaceholder} <= ${valueKey}`);
|
|
1179
|
+
values[valueKey] = cond.value;
|
|
1180
|
+
break;
|
|
1181
|
+
case "BEGINS_WITH":
|
|
1182
|
+
parts.push(`begins_with(${fieldPlaceholder}, ${valueKey})`);
|
|
1183
|
+
values[valueKey] = cond.value;
|
|
1184
|
+
break;
|
|
1185
|
+
case "IN":
|
|
1186
|
+
const inValues = cond.value.map((v, i) => `:inval${valueIndex}_${i}`);
|
|
1187
|
+
cond.value.forEach((v, i) => {
|
|
1188
|
+
values[`:inval${valueIndex}_${i}`] = v;
|
|
1189
|
+
});
|
|
1190
|
+
parts.push(`${fieldPlaceholder} IN (${inValues.join(", ")})`);
|
|
1191
|
+
valueIndex += cond.value.length - 1;
|
|
1192
|
+
break;
|
|
1193
|
+
case "NOT_IN":
|
|
1194
|
+
const notInValues = cond.value.map((v, i) => `:notinval${valueIndex}_${i}`);
|
|
1195
|
+
cond.value.forEach((v, i) => {
|
|
1196
|
+
values[`:notinval${valueIndex}_${i}`] = v;
|
|
1197
|
+
});
|
|
1198
|
+
parts.push(`NOT ${fieldPlaceholder} IN (${notInValues.join(", ")})`);
|
|
1199
|
+
valueIndex += cond.value.length - 1;
|
|
1200
|
+
break;
|
|
1201
|
+
default:
|
|
1202
|
+
throw new DatabaseAdapterError(
|
|
1203
|
+
`Unsupported operator: ${operator}`,
|
|
1204
|
+
"UNSUPPORTED_OPERATOR"
|
|
1205
|
+
);
|
|
1206
|
+
}
|
|
1207
|
+
} else {
|
|
1208
|
+
parts.push(`${fieldPlaceholder} = ${valueKey}`);
|
|
1209
|
+
values[valueKey] = cond;
|
|
1210
|
+
}
|
|
1211
|
+
valueIndex++;
|
|
1212
|
+
}
|
|
1213
|
+
return {
|
|
1214
|
+
filterExpression: parts.join(" AND "),
|
|
1215
|
+
expressionAttributeValues: Object.keys(values).length > 0 ? values : {},
|
|
1216
|
+
names
|
|
1217
|
+
};
|
|
1218
|
+
}
|
|
1219
|
+
buildUpdateExpression(update) {
|
|
1220
|
+
const setParts = [];
|
|
1221
|
+
const values = {};
|
|
1222
|
+
const names = {};
|
|
1223
|
+
let valueIndex = 0;
|
|
1224
|
+
for (const [field, value] of Object.entries(update)) {
|
|
1225
|
+
const valueKey = `:val${valueIndex}`;
|
|
1226
|
+
const fieldPlaceholder = RESERVED_KEYWORDS.has(field.toUpperCase()) ? `#${field}` : field;
|
|
1227
|
+
if (RESERVED_KEYWORDS.has(field.toUpperCase())) {
|
|
1228
|
+
names[fieldPlaceholder] = field;
|
|
1229
|
+
}
|
|
1230
|
+
setParts.push(`${fieldPlaceholder} = ${valueKey}`);
|
|
1231
|
+
values[valueKey] = value;
|
|
1232
|
+
valueIndex++;
|
|
1233
|
+
}
|
|
1234
|
+
return {
|
|
1235
|
+
updateExpression: `SET ${setParts.join(", ")}`,
|
|
1236
|
+
expressionAttributeValues: Object.keys(values).length > 0 ? values : {},
|
|
1237
|
+
names
|
|
1238
|
+
};
|
|
1239
|
+
}
|
|
1240
|
+
handleError(error, operation) {
|
|
1241
|
+
if (error instanceof DatabaseAdapterError) {
|
|
1242
|
+
return error;
|
|
1243
|
+
}
|
|
1244
|
+
if (error instanceof Error) {
|
|
1245
|
+
return new DatabaseAdapterError(
|
|
1246
|
+
`${operation} failed: ${error.message}`,
|
|
1247
|
+
"OPERATION_FAILED",
|
|
1248
|
+
{ originalError: error.message }
|
|
1249
|
+
);
|
|
1250
|
+
}
|
|
1251
|
+
return new DatabaseAdapterError(
|
|
1252
|
+
`${operation} failed: Unknown error`,
|
|
1253
|
+
"OPERATION_FAILED"
|
|
1254
|
+
);
|
|
1255
|
+
}
|
|
1256
|
+
};
|
|
1257
|
+
DynamoService = __decorateClass([
|
|
1258
|
+
(0, import_fluxor_cloud.Service)()
|
|
1259
|
+
], DynamoService);
|
|
1260
|
+
|
|
1261
|
+
// src/mongo/mongo.ts
|
|
1262
|
+
var import_mongodb = require("mongodb");
|
|
1263
|
+
var MongoService = class {
|
|
1264
|
+
constructor() {
|
|
1265
|
+
this.isConnectedFlag = false;
|
|
1266
|
+
}
|
|
1267
|
+
setConfig(config) {
|
|
1268
|
+
this.config = config;
|
|
1269
|
+
}
|
|
1270
|
+
connect() {
|
|
1271
|
+
if (!this.config) {
|
|
1272
|
+
return Promise.reject(new DatabaseAdapterError(
|
|
1273
|
+
"No configuration provided. Call setConfig() first.",
|
|
1274
|
+
"INVALID_CONFIG"
|
|
1275
|
+
));
|
|
1276
|
+
}
|
|
1277
|
+
return Promise.resolve().then(async () => {
|
|
1278
|
+
var _a, _b;
|
|
1279
|
+
try {
|
|
1280
|
+
this.validateConfig(this.config);
|
|
1281
|
+
this.client = new import_mongodb.MongoClient(this.config.uri, {
|
|
1282
|
+
retryWrites: (_a = this.config.retryWrites) != null ? _a : true,
|
|
1283
|
+
w: (_b = this.config.w) != null ? _b : "majority",
|
|
1284
|
+
authSource: this.config.authSource
|
|
1285
|
+
});
|
|
1286
|
+
await this.client.connect();
|
|
1287
|
+
this.db = this.client.db(this.config.dbName);
|
|
1288
|
+
await this.db.admin().ping();
|
|
1289
|
+
this.isConnectedFlag = true;
|
|
1290
|
+
} catch (error) {
|
|
1291
|
+
this.isConnectedFlag = false;
|
|
1292
|
+
throw this.handleError(error, "connect");
|
|
1293
|
+
}
|
|
1294
|
+
});
|
|
1295
|
+
}
|
|
1296
|
+
async disconnect() {
|
|
1297
|
+
try {
|
|
1298
|
+
if (this.client) {
|
|
1299
|
+
await this.client.close();
|
|
1300
|
+
}
|
|
1301
|
+
this.isConnectedFlag = false;
|
|
1302
|
+
this.db = void 0;
|
|
1303
|
+
this.client = void 0;
|
|
1304
|
+
} catch (error) {
|
|
1305
|
+
console.warn("Error disconnecting from MongoDB:", error);
|
|
1306
|
+
this.isConnectedFlag = false;
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
isConnected() {
|
|
1310
|
+
return this.isConnectedFlag && this.client !== void 0;
|
|
1311
|
+
}
|
|
1312
|
+
async healthCheck() {
|
|
1313
|
+
try {
|
|
1314
|
+
const db = this.getDb();
|
|
1315
|
+
await db.admin().ping();
|
|
1316
|
+
return true;
|
|
1317
|
+
} catch (error) {
|
|
1318
|
+
return false;
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
async selectOne(tableName, where, options) {
|
|
1322
|
+
try {
|
|
1323
|
+
const collection = this.getCollection(tableName);
|
|
1324
|
+
const filter = this.buildMongoFilter(where);
|
|
1325
|
+
const findOptions = {};
|
|
1326
|
+
if (Array.isArray(options == null ? void 0 : options.projection)) {
|
|
1327
|
+
const projection = {};
|
|
1328
|
+
for (const field of options.projection) {
|
|
1329
|
+
if (typeof field === "string") {
|
|
1330
|
+
projection[field] = 1;
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
if (Object.keys(projection).length > 0) {
|
|
1334
|
+
findOptions.projection = projection;
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
const result = await collection.findOne(filter, findOptions);
|
|
1338
|
+
if (result === null || result === void 0) {
|
|
1339
|
+
return null;
|
|
1340
|
+
}
|
|
1341
|
+
return result;
|
|
1342
|
+
} catch (error) {
|
|
1343
|
+
throw this.handleError(error, "selectOne");
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
async selectMany(tableName, where, options) {
|
|
1347
|
+
try {
|
|
1348
|
+
const collection = this.getCollection(tableName);
|
|
1349
|
+
const filter = where ? this.buildMongoFilter(where) : {};
|
|
1350
|
+
const findOptions = {};
|
|
1351
|
+
if (typeof (options == null ? void 0 : options.limit) === "number" && options.limit > 0) {
|
|
1352
|
+
findOptions.limit = options.limit;
|
|
1353
|
+
}
|
|
1354
|
+
if (typeof (options == null ? void 0 : options.offset) === "number" && options.offset >= 0) {
|
|
1355
|
+
findOptions.skip = options.offset;
|
|
1356
|
+
}
|
|
1357
|
+
if (Array.isArray(options == null ? void 0 : options.orderBy) && options.orderBy.length > 0) {
|
|
1358
|
+
const sort = {};
|
|
1359
|
+
for (const order of options.orderBy) {
|
|
1360
|
+
if (typeof order === "object" && order !== null && "field" in order && "direction" in order) {
|
|
1361
|
+
const field = order.field;
|
|
1362
|
+
const direction = order.direction;
|
|
1363
|
+
if (typeof field === "string" && (direction === "ASC" || direction === "DESC")) {
|
|
1364
|
+
sort[field] = direction === "DESC" ? -1 : 1;
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
if (Object.keys(sort).length > 0) {
|
|
1369
|
+
findOptions.sort = sort;
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
if (Array.isArray(options == null ? void 0 : options.projection)) {
|
|
1373
|
+
const projection = {};
|
|
1374
|
+
for (const field of options.projection) {
|
|
1375
|
+
if (typeof field === "string") {
|
|
1376
|
+
projection[field] = 1;
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
if (Object.keys(projection).length > 0) {
|
|
1380
|
+
findOptions.projection = projection;
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
const items = await collection.find(filter, findOptions).toArray();
|
|
1384
|
+
const total = await collection.countDocuments(filter);
|
|
1385
|
+
const offset = typeof (options == null ? void 0 : options.offset) === "number" ? options.offset : 0;
|
|
1386
|
+
const hasMore = offset + items.length < total;
|
|
1387
|
+
return {
|
|
1388
|
+
items,
|
|
1389
|
+
total,
|
|
1390
|
+
hasMore
|
|
1391
|
+
};
|
|
1392
|
+
} catch (error) {
|
|
1393
|
+
throw this.handleError(error, "selectMany");
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
async createOne(tableName, data) {
|
|
1397
|
+
try {
|
|
1398
|
+
if (typeof data !== "object" || data === null) {
|
|
1399
|
+
throw new DatabaseAdapterError(
|
|
1400
|
+
"Data must be an object",
|
|
1401
|
+
"INVALID_INPUT"
|
|
1402
|
+
);
|
|
1403
|
+
}
|
|
1404
|
+
const collection = this.getCollection(tableName);
|
|
1405
|
+
const result = await collection.insertOne(data);
|
|
1406
|
+
return { ...data, _id: result.insertedId };
|
|
1407
|
+
} catch (error) {
|
|
1408
|
+
if (error instanceof DatabaseAdapterError) {
|
|
1409
|
+
throw error;
|
|
1410
|
+
}
|
|
1411
|
+
throw this.handleError(error, "createOne");
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
async createMany(tableName, data, options) {
|
|
1415
|
+
try {
|
|
1416
|
+
if (!Array.isArray(data)) {
|
|
1417
|
+
throw new DatabaseAdapterError(
|
|
1418
|
+
"Data must be an array",
|
|
1419
|
+
"INVALID_INPUT"
|
|
1420
|
+
);
|
|
1421
|
+
}
|
|
1422
|
+
if (data.length === 0) {
|
|
1423
|
+
return {
|
|
1424
|
+
items: [],
|
|
1425
|
+
result: {
|
|
1426
|
+
successful: 0,
|
|
1427
|
+
failed: 0
|
|
1428
|
+
}
|
|
1429
|
+
};
|
|
1430
|
+
}
|
|
1431
|
+
const collection = this.getCollection(tableName);
|
|
1432
|
+
const stopOnError = typeof (options == null ? void 0 : options.stopOnError) === "boolean" ? options.stopOnError : false;
|
|
1433
|
+
try {
|
|
1434
|
+
const result = await collection.insertMany(
|
|
1435
|
+
data,
|
|
1436
|
+
{
|
|
1437
|
+
ordered: stopOnError
|
|
1438
|
+
}
|
|
1439
|
+
);
|
|
1440
|
+
const items = data.map((item, index) => {
|
|
1441
|
+
const insertedId = result.insertedIds[index];
|
|
1442
|
+
if (insertedId === null || insertedId === void 0) {
|
|
1443
|
+
return item;
|
|
1444
|
+
}
|
|
1445
|
+
return {
|
|
1446
|
+
...item,
|
|
1447
|
+
_id: insertedId
|
|
1448
|
+
};
|
|
1449
|
+
});
|
|
1450
|
+
return {
|
|
1451
|
+
items,
|
|
1452
|
+
result: {
|
|
1453
|
+
successful: items.length,
|
|
1454
|
+
failed: 0
|
|
1455
|
+
}
|
|
1456
|
+
};
|
|
1457
|
+
} catch (error) {
|
|
1458
|
+
if (stopOnError) {
|
|
1459
|
+
throw this.handleError(error, "createMany");
|
|
1460
|
+
}
|
|
1461
|
+
let insertedCount = 0;
|
|
1462
|
+
if (error instanceof Error) {
|
|
1463
|
+
const errorMsg = error.message;
|
|
1464
|
+
if (errorMsg.includes("insertedCount") || errorMsg.includes("nInserted")) {
|
|
1465
|
+
const match = errorMsg.match(/\d+/);
|
|
1466
|
+
if (match) {
|
|
1467
|
+
insertedCount = parseInt(match[0], 10);
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
const failed = data.length - insertedCount;
|
|
1472
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error during batch insert";
|
|
1473
|
+
return {
|
|
1474
|
+
items: insertedCount > 0 ? data.slice(0, insertedCount) : [],
|
|
1475
|
+
result: {
|
|
1476
|
+
successful: insertedCount,
|
|
1477
|
+
failed,
|
|
1478
|
+
errors: failed > 0 ? [
|
|
1479
|
+
{
|
|
1480
|
+
index: insertedCount,
|
|
1481
|
+
error: errorMessage
|
|
1482
|
+
}
|
|
1483
|
+
] : void 0
|
|
1484
|
+
}
|
|
1485
|
+
};
|
|
1486
|
+
}
|
|
1487
|
+
} catch (error) {
|
|
1488
|
+
throw this.handleError(error, "createMany");
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
async updateOne(tableName, update, where) {
|
|
1492
|
+
try {
|
|
1493
|
+
const collection = this.getCollection(tableName);
|
|
1494
|
+
const filter = this.buildMongoFilter(where);
|
|
1495
|
+
const updateDoc = this.buildMongoUpdate(update);
|
|
1496
|
+
const raw = await collection.findOneAndUpdate(filter, updateDoc, {
|
|
1497
|
+
returnDocument: "after"
|
|
1498
|
+
});
|
|
1499
|
+
const doc = raw && typeof raw === "object" && "value" in raw ? raw.value : raw;
|
|
1500
|
+
if (doc === null || doc === void 0) {
|
|
1501
|
+
throw new DatabaseAdapterError(
|
|
1502
|
+
"Document not found for update",
|
|
1503
|
+
"NOT_FOUND"
|
|
1504
|
+
);
|
|
1505
|
+
}
|
|
1506
|
+
return doc;
|
|
1507
|
+
} catch (error) {
|
|
1508
|
+
if (error instanceof DatabaseAdapterError) {
|
|
1509
|
+
throw error;
|
|
1510
|
+
}
|
|
1511
|
+
throw this.handleError(error, "updateOne");
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1514
|
+
async updateMany(tableName, update, where, options) {
|
|
1515
|
+
try {
|
|
1516
|
+
const collection = this.getCollection(tableName);
|
|
1517
|
+
const filter = where ? this.buildMongoFilter(where) : {};
|
|
1518
|
+
const updateDoc = this.buildMongoUpdate(update);
|
|
1519
|
+
const limit = typeof (options == null ? void 0 : options.limit) === "number" && options.limit > 0 ? options.limit : void 0;
|
|
1520
|
+
if (limit) {
|
|
1521
|
+
const matchingDocs = await collection.find(filter).limit(limit).toArray();
|
|
1522
|
+
if (matchingDocs.length === 0) {
|
|
1523
|
+
return {
|
|
1524
|
+
items: [],
|
|
1525
|
+
result: { successful: 0, failed: 0 }
|
|
1526
|
+
};
|
|
1527
|
+
}
|
|
1528
|
+
const ids = matchingDocs.map((doc) => {
|
|
1529
|
+
const docWithId = doc;
|
|
1530
|
+
return docWithId._id;
|
|
1531
|
+
}).filter((id) => id !== null && id !== void 0);
|
|
1532
|
+
if (ids.length === 0) {
|
|
1533
|
+
return {
|
|
1534
|
+
items: [],
|
|
1535
|
+
result: { successful: 0, failed: 0 }
|
|
1536
|
+
};
|
|
1537
|
+
}
|
|
1538
|
+
const idFilter = { _id: { $in: ids } };
|
|
1539
|
+
const updateResult = await collection.updateMany(idFilter, updateDoc);
|
|
1540
|
+
return {
|
|
1541
|
+
items: matchingDocs,
|
|
1542
|
+
result: {
|
|
1543
|
+
successful: updateResult.modifiedCount,
|
|
1544
|
+
failed: 0
|
|
1545
|
+
}
|
|
1546
|
+
};
|
|
1547
|
+
} else {
|
|
1548
|
+
const updateResult = await collection.updateMany(filter, updateDoc);
|
|
1549
|
+
const updatedDocs = await collection.find(filter).toArray();
|
|
1550
|
+
return {
|
|
1551
|
+
items: updatedDocs,
|
|
1552
|
+
result: {
|
|
1553
|
+
successful: updateResult.modifiedCount,
|
|
1554
|
+
failed: 0
|
|
1555
|
+
}
|
|
1556
|
+
};
|
|
1557
|
+
}
|
|
1558
|
+
} catch (error) {
|
|
1559
|
+
throw this.handleError(error, "updateMany");
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1562
|
+
async deleteOne(tableName, where) {
|
|
1563
|
+
try {
|
|
1564
|
+
const collection = this.getCollection(tableName);
|
|
1565
|
+
const filter = this.buildMongoFilter(where);
|
|
1566
|
+
const result = await collection.deleteOne(filter);
|
|
1567
|
+
return {
|
|
1568
|
+
success: result.deletedCount > 0,
|
|
1569
|
+
deletedCount: result.deletedCount
|
|
1570
|
+
};
|
|
1571
|
+
} catch (error) {
|
|
1572
|
+
throw this.handleError(error, "deleteOne");
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
async deleteMany(tableName, where, options) {
|
|
1576
|
+
try {
|
|
1577
|
+
const collection = this.getCollection(tableName);
|
|
1578
|
+
const filter = where ? this.buildMongoFilter(where) : {};
|
|
1579
|
+
let deletedCount = 0;
|
|
1580
|
+
if (typeof (options == null ? void 0 : options.limit) === "number" && options.limit > 0) {
|
|
1581
|
+
const docsToDelete = await collection.find(filter).limit(options.limit).toArray();
|
|
1582
|
+
if (docsToDelete.length === 0) {
|
|
1583
|
+
return {
|
|
1584
|
+
success: true,
|
|
1585
|
+
deletedCount: 0,
|
|
1586
|
+
result: {
|
|
1587
|
+
successful: 0,
|
|
1588
|
+
failed: 0
|
|
1589
|
+
}
|
|
1590
|
+
};
|
|
1591
|
+
}
|
|
1592
|
+
const ids = docsToDelete.map((doc) => {
|
|
1593
|
+
const docWithId = doc;
|
|
1594
|
+
return docWithId._id;
|
|
1595
|
+
}).filter((id) => id !== null && id !== void 0);
|
|
1596
|
+
if (ids.length === 0) {
|
|
1597
|
+
return {
|
|
1598
|
+
success: true,
|
|
1599
|
+
deletedCount: 0,
|
|
1600
|
+
result: {
|
|
1601
|
+
successful: 0,
|
|
1602
|
+
failed: 0
|
|
1603
|
+
}
|
|
1604
|
+
};
|
|
1605
|
+
}
|
|
1606
|
+
const idFilter = { _id: { $in: ids } };
|
|
1607
|
+
const result = await collection.deleteMany(idFilter);
|
|
1608
|
+
deletedCount = result.deletedCount;
|
|
1609
|
+
} else {
|
|
1610
|
+
const result = await collection.deleteMany(filter);
|
|
1611
|
+
deletedCount = result.deletedCount;
|
|
1612
|
+
}
|
|
1613
|
+
return {
|
|
1614
|
+
success: true,
|
|
1615
|
+
deletedCount,
|
|
1616
|
+
result: {
|
|
1617
|
+
successful: deletedCount,
|
|
1618
|
+
failed: 0
|
|
1619
|
+
}
|
|
1620
|
+
};
|
|
1621
|
+
} catch (error) {
|
|
1622
|
+
throw this.handleError(error, "deleteMany");
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1625
|
+
async executeRaw(query, params) {
|
|
1626
|
+
throw new DatabaseAdapterError(
|
|
1627
|
+
"executeRaw not fully implemented for this example",
|
|
1628
|
+
"NOT_IMPLEMENTED"
|
|
1629
|
+
);
|
|
1630
|
+
}
|
|
1631
|
+
// ============ Private Helpers ============
|
|
1632
|
+
validateConfig(config) {
|
|
1633
|
+
if (!config || !config.uri || !config.dbName) {
|
|
1634
|
+
throw new DatabaseAdapterError(
|
|
1635
|
+
"MongoDB configuration requires uri and dbName",
|
|
1636
|
+
"INVALID_CONFIG"
|
|
1637
|
+
);
|
|
1638
|
+
}
|
|
1639
|
+
}
|
|
1640
|
+
getDb() {
|
|
1641
|
+
if (!this.isConnectedFlag || !this.db) {
|
|
1642
|
+
throw new DatabaseAdapterError(
|
|
1643
|
+
"MongoDB client is not connected. Call connect() first.",
|
|
1644
|
+
"NOT_CONNECTED"
|
|
1645
|
+
);
|
|
1646
|
+
}
|
|
1647
|
+
return this.db;
|
|
1648
|
+
}
|
|
1649
|
+
getCollection(tableName) {
|
|
1650
|
+
if (typeof tableName !== "string" || !tableName) {
|
|
1651
|
+
throw new DatabaseAdapterError(
|
|
1652
|
+
"Table name must be a non-empty string",
|
|
1653
|
+
"INVALID_TABLE_NAME"
|
|
1654
|
+
);
|
|
1655
|
+
}
|
|
1656
|
+
return this.getDb().collection(tableName);
|
|
1657
|
+
}
|
|
1658
|
+
buildMongoFilter(where) {
|
|
1659
|
+
const filter = {};
|
|
1660
|
+
if (typeof where !== "object" || where === null) {
|
|
1661
|
+
return filter;
|
|
1662
|
+
}
|
|
1663
|
+
for (const [field, condition] of Object.entries(where)) {
|
|
1664
|
+
if (!field || typeof field !== "string") {
|
|
1665
|
+
continue;
|
|
1666
|
+
}
|
|
1667
|
+
if (condition === null || condition === void 0) {
|
|
1668
|
+
continue;
|
|
1669
|
+
}
|
|
1670
|
+
if (typeof condition === "object" && "operator" in condition) {
|
|
1671
|
+
const condObj = condition;
|
|
1672
|
+
const operator = condObj["operator"];
|
|
1673
|
+
const value = condObj["value"];
|
|
1674
|
+
if (typeof operator !== "string" || !this.isValidOperator(operator)) {
|
|
1675
|
+
continue;
|
|
1676
|
+
}
|
|
1677
|
+
if (value === null || value === void 0) {
|
|
1678
|
+
continue;
|
|
1679
|
+
}
|
|
1680
|
+
const op = operator;
|
|
1681
|
+
switch (op) {
|
|
1682
|
+
case "=":
|
|
1683
|
+
filter[field] = value;
|
|
1684
|
+
break;
|
|
1685
|
+
case "!=":
|
|
1686
|
+
filter[field] = { $ne: value };
|
|
1687
|
+
break;
|
|
1688
|
+
case ">":
|
|
1689
|
+
filter[field] = { $gt: value };
|
|
1690
|
+
break;
|
|
1691
|
+
case ">=":
|
|
1692
|
+
filter[field] = { $gte: value };
|
|
1693
|
+
break;
|
|
1694
|
+
case "<":
|
|
1695
|
+
filter[field] = { $lt: value };
|
|
1696
|
+
break;
|
|
1697
|
+
case "<=":
|
|
1698
|
+
filter[field] = { $lte: value };
|
|
1699
|
+
break;
|
|
1700
|
+
case "IN":
|
|
1701
|
+
if (Array.isArray(value)) {
|
|
1702
|
+
filter[field] = { $in: value };
|
|
1703
|
+
} else {
|
|
1704
|
+
filter[field] = { $in: [value] };
|
|
1705
|
+
}
|
|
1706
|
+
break;
|
|
1707
|
+
case "NOT_IN":
|
|
1708
|
+
if (Array.isArray(value)) {
|
|
1709
|
+
filter[field] = { $nin: value };
|
|
1710
|
+
} else {
|
|
1711
|
+
filter[field] = { $nin: [value] };
|
|
1712
|
+
}
|
|
1713
|
+
break;
|
|
1714
|
+
case "BETWEEN":
|
|
1715
|
+
if (Array.isArray(value) && value.length === 2) {
|
|
1716
|
+
const [min, max] = value;
|
|
1717
|
+
if (min !== null && min !== void 0 && max !== null && max !== void 0) {
|
|
1718
|
+
filter[field] = { $gte: min, $lte: max };
|
|
1719
|
+
}
|
|
1720
|
+
}
|
|
1721
|
+
break;
|
|
1722
|
+
case "LIKE":
|
|
1723
|
+
if (typeof value === "string") {
|
|
1724
|
+
filter[field] = { $regex: value, $options: "i" };
|
|
1725
|
+
}
|
|
1726
|
+
break;
|
|
1727
|
+
case "BEGINS_WITH":
|
|
1728
|
+
if (typeof value === "string") {
|
|
1729
|
+
filter[field] = { $regex: `^${value}`, $options: "i" };
|
|
1730
|
+
}
|
|
1731
|
+
break;
|
|
1732
|
+
case "EXISTS":
|
|
1733
|
+
if (typeof value === "boolean") {
|
|
1734
|
+
filter[field] = { $exists: value };
|
|
1735
|
+
}
|
|
1736
|
+
break;
|
|
1737
|
+
}
|
|
1738
|
+
} else {
|
|
1739
|
+
filter[field] = condition;
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
return filter;
|
|
1743
|
+
}
|
|
1744
|
+
isValidOperator(op) {
|
|
1745
|
+
const validOperators = ["=", "!=", ">", ">=", "<", "<=", "IN", "NOT_IN", "BETWEEN", "LIKE", "BEGINS_WITH", "EXISTS"];
|
|
1746
|
+
return validOperators.includes(op);
|
|
1747
|
+
}
|
|
1748
|
+
buildMongoUpdate(update) {
|
|
1749
|
+
const mongoUpdate = {};
|
|
1750
|
+
const setFields = {};
|
|
1751
|
+
const incrementFields = {};
|
|
1752
|
+
if (typeof update !== "object" || update === null) {
|
|
1753
|
+
return mongoUpdate;
|
|
1754
|
+
}
|
|
1755
|
+
for (const [field, value] of Object.entries(update)) {
|
|
1756
|
+
if (!field || typeof field !== "string") {
|
|
1757
|
+
continue;
|
|
1758
|
+
}
|
|
1759
|
+
if (value === null || value === void 0) {
|
|
1760
|
+
continue;
|
|
1761
|
+
}
|
|
1762
|
+
if (typeof value === "object" && "$increment" in value) {
|
|
1763
|
+
const val = value;
|
|
1764
|
+
if (typeof val["$increment"] === "number") {
|
|
1765
|
+
incrementFields[field] = val["$increment"];
|
|
1766
|
+
}
|
|
1767
|
+
} else {
|
|
1768
|
+
setFields[field] = value;
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
if (Object.keys(setFields).length > 0) {
|
|
1772
|
+
mongoUpdate.$set = setFields;
|
|
1773
|
+
}
|
|
1774
|
+
if (Object.keys(incrementFields).length > 0) {
|
|
1775
|
+
mongoUpdate.$inc = incrementFields;
|
|
1776
|
+
}
|
|
1777
|
+
return mongoUpdate;
|
|
1778
|
+
}
|
|
1779
|
+
handleError(error, operation) {
|
|
1780
|
+
if (error instanceof DatabaseAdapterError) {
|
|
1781
|
+
return error;
|
|
1782
|
+
}
|
|
1783
|
+
if (error instanceof Error) {
|
|
1784
|
+
return new DatabaseAdapterError(
|
|
1785
|
+
`${operation} failed: ${error.message}`,
|
|
1786
|
+
"OPERATION_FAILED",
|
|
1787
|
+
{ originalError: error.message }
|
|
1788
|
+
);
|
|
1789
|
+
}
|
|
1790
|
+
return new DatabaseAdapterError(
|
|
1791
|
+
`${operation} failed: Unknown error`,
|
|
1792
|
+
"OPERATION_FAILED"
|
|
1793
|
+
);
|
|
1794
|
+
}
|
|
1795
|
+
};
|
|
1796
|
+
|
|
1797
|
+
// src/fluentapi.ts
|
|
1798
|
+
var eq = (value) => ({ operator: "=", value });
|
|
1799
|
+
var neq = (value) => ({ operator: "!=", value });
|
|
1800
|
+
var gt = (value) => ({ operator: ">", value });
|
|
1801
|
+
var gte = (value) => ({ operator: ">=", value });
|
|
1802
|
+
var lt = (value) => ({ operator: "<", value });
|
|
1803
|
+
var lte = (value) => ({ operator: "<=", value });
|
|
1804
|
+
var between = (min, max) => ({ operator: "BETWEEN", value: [min, max] });
|
|
1805
|
+
var anyOf = (values) => ({ operator: "IN", value: values });
|
|
1806
|
+
var noneOf = (values) => ({ operator: "NOT_IN", value: values });
|
|
1807
|
+
var startsWith = (value) => ({ operator: "BEGINS_WITH", value });
|
|
1808
|
+
var like = (value) => ({ operator: "LIKE", value });
|
|
1809
|
+
var exists = (value = true) => ({ operator: "EXISTS", value });
|
|
1810
|
+
var equals = eq;
|
|
1811
|
+
var notEquals = neq;
|
|
1812
|
+
var inList = anyOf;
|
|
1813
|
+
var notInList = noneOf;
|
|
1814
|
+
|
|
1815
|
+
// src/index.ts
|
|
1816
|
+
var useDynamo = () => {
|
|
1817
|
+
return (0, import_fluxor_cloud2.resolveService)(DynamoService);
|
|
1818
|
+
};
|
|
1819
|
+
var useMongo = () => {
|
|
1820
|
+
return (0, import_fluxor_cloud2.resolveService)(MongoService);
|
|
1821
|
+
};
|
|
1822
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1823
|
+
0 && (module.exports = {
|
|
1824
|
+
DynamoService,
|
|
1825
|
+
MongoService,
|
|
1826
|
+
anyOf,
|
|
1827
|
+
between,
|
|
1828
|
+
eq,
|
|
1829
|
+
equals,
|
|
1830
|
+
exists,
|
|
1831
|
+
gt,
|
|
1832
|
+
gte,
|
|
1833
|
+
inList,
|
|
1834
|
+
like,
|
|
1835
|
+
lt,
|
|
1836
|
+
lte,
|
|
1837
|
+
neq,
|
|
1838
|
+
noneOf,
|
|
1839
|
+
notEquals,
|
|
1840
|
+
notInList,
|
|
1841
|
+
startsWith,
|
|
1842
|
+
useDynamo,
|
|
1843
|
+
useMongo
|
|
1844
|
+
});
|