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/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
+ });