@arcaelas/dynamite 1.0.29 → 2.1.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.
Files changed (130) hide show
  1. package/README.md +13 -13
  2. package/{src → build/cjs}/@types/index.d.ts +26 -1
  3. package/build/cjs/@types/index.js.map +1 -0
  4. package/{src → build/cjs}/core/client.d.ts +22 -19
  5. package/build/cjs/core/client.js +384 -0
  6. package/build/cjs/core/client.js.map +1 -0
  7. package/build/cjs/core/decorator.d.ts +38 -0
  8. package/build/cjs/core/decorator.js +38 -0
  9. package/build/cjs/core/decorator.js.map +1 -0
  10. package/build/cjs/core/table.d.ts +55 -0
  11. package/build/cjs/core/table.js +851 -0
  12. package/build/cjs/core/table.js.map +1 -0
  13. package/build/cjs/decorators/indexes.d.ts +20 -0
  14. package/build/cjs/decorators/indexes.js +45 -0
  15. package/build/cjs/decorators/indexes.js.map +1 -0
  16. package/{src → build/cjs}/decorators/relations.d.ts +8 -7
  17. package/{src → build/cjs}/decorators/relations.js +9 -8
  18. package/build/cjs/decorators/relations.js.map +1 -0
  19. package/build/cjs/decorators/timestamps.d.ts +20 -0
  20. package/build/cjs/decorators/timestamps.js +34 -0
  21. package/build/cjs/decorators/timestamps.js.map +1 -0
  22. package/build/cjs/decorators/transforms.d.ts +41 -0
  23. package/build/cjs/decorators/transforms.js +98 -0
  24. package/build/cjs/decorators/transforms.js.map +1 -0
  25. package/{src → build/cjs}/index.d.ts +5 -3
  26. package/{src → build/cjs}/index.js +7 -6
  27. package/build/cjs/index.js.map +1 -0
  28. package/build/cjs/package.json +1 -0
  29. package/build/cjs/test/basic.d.ts +1 -0
  30. package/build/cjs/test/basic.js +248 -0
  31. package/build/cjs/test/basic.js.map +1 -0
  32. package/build/cjs/test/bulk.d.ts +1 -0
  33. package/build/cjs/test/bulk.js +108 -0
  34. package/build/cjs/test/bulk.js.map +1 -0
  35. package/build/cjs/test/contracts.d.ts +1 -0
  36. package/build/cjs/test/contracts.js +343 -0
  37. package/build/cjs/test/contracts.js.map +1 -0
  38. package/build/cjs/test/filters.d.ts +1 -0
  39. package/build/cjs/test/filters.js +190 -0
  40. package/build/cjs/test/filters.js.map +1 -0
  41. package/build/cjs/test/index.js +36 -0
  42. package/build/cjs/test/index.js.map +1 -0
  43. package/build/cjs/test/query_scan.d.ts +1 -0
  44. package/build/cjs/test/query_scan.js +195 -0
  45. package/build/cjs/test/query_scan.js.map +1 -0
  46. package/build/cjs/test/relations.d.ts +1 -0
  47. package/build/cjs/test/relations.js +246 -0
  48. package/build/cjs/test/relations.js.map +1 -0
  49. package/build/cjs/test/transactions.d.ts +1 -0
  50. package/build/cjs/test/transactions.js +145 -0
  51. package/build/cjs/test/transactions.js.map +1 -0
  52. package/{src → build/cjs}/utils/relations.js +1 -8
  53. package/build/cjs/utils/relations.js.map +1 -0
  54. package/build/cjs/utils/ulid.d.ts +10 -0
  55. package/build/cjs/utils/ulid.js +55 -0
  56. package/build/cjs/utils/ulid.js.map +1 -0
  57. package/build/esm/@types/index.d.ts +213 -0
  58. package/build/esm/@types/index.js +8 -0
  59. package/build/esm/@types/index.js.map +1 -0
  60. package/build/esm/core/client.d.ts +96 -0
  61. package/build/esm/core/client.js +375 -0
  62. package/build/esm/core/client.js.map +1 -0
  63. package/build/esm/core/decorator.d.ts +38 -0
  64. package/build/esm/core/decorator.js +34 -0
  65. package/build/esm/core/decorator.js.map +1 -0
  66. package/build/esm/core/table.d.ts +55 -0
  67. package/build/esm/core/table.js +848 -0
  68. package/build/esm/core/table.js.map +1 -0
  69. package/build/esm/decorators/indexes.d.ts +20 -0
  70. package/build/esm/decorators/indexes.js +42 -0
  71. package/build/esm/decorators/indexes.js.map +1 -0
  72. package/build/esm/decorators/relations.d.ts +75 -0
  73. package/build/esm/decorators/relations.js +112 -0
  74. package/build/esm/decorators/relations.js.map +1 -0
  75. package/build/esm/decorators/timestamps.d.ts +20 -0
  76. package/build/esm/decorators/timestamps.js +31 -0
  77. package/build/esm/decorators/timestamps.js.map +1 -0
  78. package/build/esm/decorators/transforms.d.ts +41 -0
  79. package/build/esm/decorators/transforms.js +92 -0
  80. package/build/esm/decorators/transforms.js.map +1 -0
  81. package/build/esm/index.d.ts +17 -0
  82. package/build/esm/index.js +24 -0
  83. package/build/esm/index.js.map +1 -0
  84. package/build/esm/package.json +1 -0
  85. package/build/esm/test/basic.d.ts +1 -0
  86. package/build/esm/test/basic.js +245 -0
  87. package/build/esm/test/basic.js.map +1 -0
  88. package/build/esm/test/bulk.d.ts +1 -0
  89. package/build/esm/test/bulk.js +105 -0
  90. package/build/esm/test/bulk.js.map +1 -0
  91. package/build/esm/test/contracts.d.ts +1 -0
  92. package/build/esm/test/contracts.js +340 -0
  93. package/build/esm/test/contracts.js.map +1 -0
  94. package/build/esm/test/filters.d.ts +1 -0
  95. package/build/esm/test/filters.js +187 -0
  96. package/build/esm/test/filters.js.map +1 -0
  97. package/build/esm/test/index.d.ts +1 -0
  98. package/build/esm/test/index.js +31 -0
  99. package/build/esm/test/index.js.map +1 -0
  100. package/build/esm/test/query_scan.d.ts +1 -0
  101. package/build/esm/test/query_scan.js +192 -0
  102. package/build/esm/test/query_scan.js.map +1 -0
  103. package/build/esm/test/relations.d.ts +1 -0
  104. package/build/esm/test/relations.js +243 -0
  105. package/build/esm/test/relations.js.map +1 -0
  106. package/build/esm/test/transactions.d.ts +1 -0
  107. package/build/esm/test/transactions.js +142 -0
  108. package/build/esm/test/transactions.js.map +1 -0
  109. package/build/esm/utils/relations.d.ts +42 -0
  110. package/build/esm/utils/relations.js +207 -0
  111. package/build/esm/utils/relations.js.map +1 -0
  112. package/build/esm/utils/ulid.d.ts +10 -0
  113. package/build/esm/utils/ulid.js +52 -0
  114. package/build/esm/utils/ulid.js.map +1 -0
  115. package/package.json +31 -9
  116. package/src/core/client.js +0 -296
  117. package/src/core/decorator.d.ts +0 -29
  118. package/src/core/decorator.js +0 -103
  119. package/src/core/table.d.ts +0 -81
  120. package/src/core/table.js +0 -892
  121. package/src/decorators/indexes.d.ts +0 -38
  122. package/src/decorators/indexes.js +0 -59
  123. package/src/decorators/timestamps.d.ts +0 -54
  124. package/src/decorators/timestamps.js +0 -72
  125. package/src/decorators/transforms.d.ts +0 -99
  126. package/src/decorators/transforms.js +0 -166
  127. package/src/index.test.js +0 -37
  128. /package/{src → build/cjs}/@types/index.js +0 -0
  129. /package/{src/index.test.d.ts → build/cjs/test/index.d.ts} +0 -0
  130. /package/{src → build/cjs}/utils/relations.d.ts +0 -0
@@ -0,0 +1,375 @@
1
+ /**
2
+ * @file client.ts
3
+ * @description Centralized Dynamite client with multi-client support and table sync
4
+ * @autor Miguel Alejandro
5
+ * @fecha 2025-01-27
6
+ */
7
+ import { CreateTableCommand, DescribeTableCommand, DynamoDBClient, TransactWriteItemsCommand, UpdateTableCommand, } from "@aws-sdk/client-dynamodb";
8
+ import { marshall } from "@aws-sdk/util-dynamodb";
9
+ import { SCHEMA } from "./decorator.js";
10
+ /**
11
+ * Centralized Dynamite client for managing DynamoDB connections and table synchronization
12
+ */
13
+ export class Dynamite {
14
+ /**
15
+ * Initialize Dynamite client with configuration
16
+ * @param config Dynamite client configuration
17
+ */
18
+ constructor(config) {
19
+ this.connected = false;
20
+ this.synced = false;
21
+ const { tables, ...options } = config;
22
+ this.client = new DynamoDBClient({
23
+ ...options,
24
+ });
25
+ this.tables = tables;
26
+ }
27
+ /**
28
+ * @description Configure the DynamoDB client. Does not create tables or GSIs -- use sync() for that.
29
+ * @description Configura el cliente DynamoDB. No crea tablas ni GSIs -- usar sync() para eso.
30
+ */
31
+ async connect() {
32
+ if (this.connected)
33
+ return;
34
+ setGlobalClient(this.client);
35
+ this.connected = true;
36
+ // Computar GSIs esperados desde los schemas (sin llamadas API)
37
+ const pk_by_table = new Map();
38
+ for (const tc of this.tables) {
39
+ const s = tc[SCHEMA];
40
+ if (!s)
41
+ continue;
42
+ const pk_col = Object.values(s.columns).find(c => c.store.index || c.store.primaryKey);
43
+ pk_by_table.set(s.name, pk_col?.name ?? 'id');
44
+ }
45
+ for (const tc of this.tables) {
46
+ const s = tc[SCHEMA];
47
+ if (!s)
48
+ continue;
49
+ for (const col_name in s.columns) {
50
+ const rel = s.columns[col_name].store.relation;
51
+ if (!rel || (rel.type !== 'HasMany' && rel.type !== 'HasOne'))
52
+ continue;
53
+ const related = rel.model()?.[SCHEMA];
54
+ if (!related)
55
+ continue;
56
+ const related_pk = pk_by_table.get(related.name);
57
+ if (rel.foreignKey !== related_pk) {
58
+ related.gsis.add(rel.foreignKey);
59
+ }
60
+ }
61
+ }
62
+ }
63
+ /**
64
+ * @description Synchronize all tables, GSIs and pivot tables with DynamoDB.
65
+ * @description Sincroniza tablas, GSIs y pivot tables con DynamoDB.
66
+ */
67
+ async sync() {
68
+ if (!this.connected)
69
+ throw new Error('Call connect() before sync()');
70
+ if (this.synced)
71
+ return;
72
+ // Phase 1: Collect requirements
73
+ const tables = new Map();
74
+ const pivots = new Map();
75
+ for (const table_class of this.tables) {
76
+ const schema = table_class[SCHEMA];
77
+ if (!schema)
78
+ throw new Error(`Class ${table_class.name} not registered. Use decorators.`);
79
+ const cols = Object.values(schema.columns);
80
+ const pk = cols.find(c => c.store.index || c.store.primaryKey);
81
+ if (!pk)
82
+ throw new Error(`PartitionKey missing in ${table_class.name}`);
83
+ const sk = cols.find(c => c.store.indexSort) ?? null;
84
+ tables.set(schema.name, { pk: pk.name, sk: sk?.name ?? null, gsis: new Set() });
85
+ }
86
+ for (const table_class of this.tables) {
87
+ const schema = table_class[SCHEMA];
88
+ for (const col_name in schema.columns) {
89
+ const relation = schema.columns[col_name].store.relation;
90
+ if (!relation)
91
+ continue;
92
+ if (relation.type === 'HasMany' || relation.type === 'HasOne') {
93
+ const related_schema = relation.model()?.[SCHEMA];
94
+ if (related_schema && tables.has(related_schema.name)) {
95
+ const entry = tables.get(related_schema.name);
96
+ if (relation.foreignKey !== entry.pk) {
97
+ entry.gsis.add(relation.foreignKey);
98
+ }
99
+ }
100
+ }
101
+ if (relation.type === 'ManyToMany' && relation.pivotTable) {
102
+ pivots.set(relation.pivotTable, {
103
+ foreignKey: relation.foreignKey,
104
+ relatedKey: relation.relatedKey,
105
+ });
106
+ }
107
+ }
108
+ }
109
+ // Phase 2: Describe all tables + pivots in parallel
110
+ const all_table_names = [...tables.keys()];
111
+ const all_pivot_names = [...pivots.keys()];
112
+ const all_names = [...all_table_names, ...all_pivot_names];
113
+ const descriptions = await Promise.all(all_names.map(async (name) => {
114
+ try {
115
+ const result = await this.client.send(new DescribeTableCommand({ TableName: name }));
116
+ const existing_gsis = new Set((result.Table?.GlobalSecondaryIndexes ?? []).map(g => g.IndexName));
117
+ return { name, exists: true, existing_gsis };
118
+ }
119
+ catch (e) {
120
+ if (e.name === 'ResourceNotFoundException')
121
+ return { name, exists: false, existing_gsis: new Set() };
122
+ throw e;
123
+ }
124
+ }));
125
+ const described = new Map(descriptions.map(d => [d.name, d]));
126
+ // Phase 3: Create missing tables in parallel
127
+ const to_create = [];
128
+ for (const [name, entry] of tables) {
129
+ const desc = described.get(name);
130
+ if (desc.exists)
131
+ continue;
132
+ const attrs = new Map([[entry.pk, 'S']]);
133
+ if (entry.sk)
134
+ attrs.set(entry.sk, 'S');
135
+ for (const gsi_field of entry.gsis)
136
+ attrs.set(gsi_field, 'S');
137
+ const key_schema = [
138
+ { AttributeName: entry.pk, KeyType: 'HASH' },
139
+ ];
140
+ if (entry.sk)
141
+ key_schema.push({ AttributeName: entry.sk, KeyType: 'RANGE' });
142
+ const gsi_defs = [...entry.gsis].map(field => ({
143
+ IndexName: `${field}_index`,
144
+ KeySchema: [{ AttributeName: field, KeyType: 'HASH' }],
145
+ Projection: { ProjectionType: 'ALL' },
146
+ }));
147
+ to_create.push(this.client.send(new CreateTableCommand({
148
+ TableName: name,
149
+ BillingMode: 'PAY_PER_REQUEST',
150
+ AttributeDefinitions: [...attrs].map(([AttributeName, AttributeType]) => ({ AttributeName, AttributeType })),
151
+ KeySchema: key_schema,
152
+ ...(gsi_defs.length > 0 && { GlobalSecondaryIndexes: gsi_defs }),
153
+ })).then(() => { }));
154
+ }
155
+ for (const [name, meta] of pivots) {
156
+ const desc = described.get(name);
157
+ if (desc.exists)
158
+ continue;
159
+ to_create.push(this.client.send(new CreateTableCommand({
160
+ TableName: name,
161
+ BillingMode: 'PAY_PER_REQUEST',
162
+ KeySchema: [{ AttributeName: 'id', KeyType: 'HASH' }],
163
+ AttributeDefinitions: [
164
+ { AttributeName: 'id', AttributeType: 'S' },
165
+ { AttributeName: meta.foreignKey, AttributeType: 'S' },
166
+ { AttributeName: meta.relatedKey, AttributeType: 'S' },
167
+ ],
168
+ GlobalSecondaryIndexes: [
169
+ { IndexName: `${meta.foreignKey}_index`, KeySchema: [{ AttributeName: meta.foreignKey, KeyType: 'HASH' }], Projection: { ProjectionType: 'ALL' } },
170
+ { IndexName: `${meta.relatedKey}_index`, KeySchema: [{ AttributeName: meta.relatedKey, KeyType: 'HASH' }], Projection: { ProjectionType: 'ALL' } },
171
+ ],
172
+ })).then(() => { }));
173
+ }
174
+ await Promise.all(to_create);
175
+ // Phase 4: Add missing GSIs to existing tables (round-robin, parallel across tables)
176
+ const pending_gsis = new Map();
177
+ for (const [name, entry] of tables) {
178
+ const desc = described.get(name);
179
+ if (!desc.exists)
180
+ continue;
181
+ const missing = [...entry.gsis].filter(field => !desc.existing_gsis.has(`${field}_index`));
182
+ if (missing.length > 0)
183
+ pending_gsis.set(name, missing);
184
+ }
185
+ for (const [name, meta] of pivots) {
186
+ const desc = described.get(name);
187
+ if (!desc.exists)
188
+ continue;
189
+ const expected = [`${meta.foreignKey}_index`, `${meta.relatedKey}_index`];
190
+ const missing_fields = [];
191
+ if (!desc.existing_gsis.has(expected[0]))
192
+ missing_fields.push(meta.foreignKey);
193
+ if (!desc.existing_gsis.has(expected[1]))
194
+ missing_fields.push(meta.relatedKey);
195
+ if (missing_fields.length > 0)
196
+ pending_gsis.set(name, missing_fields);
197
+ }
198
+ while (pending_gsis.size > 0) {
199
+ const round = [];
200
+ for (const [table_name, fields] of pending_gsis) {
201
+ const field = fields.shift();
202
+ if (fields.length === 0)
203
+ pending_gsis.delete(table_name);
204
+ round.push(this.client.send(new UpdateTableCommand({
205
+ TableName: table_name,
206
+ AttributeDefinitions: [{ AttributeName: field, AttributeType: 'S' }],
207
+ GlobalSecondaryIndexUpdates: [{
208
+ Create: {
209
+ IndexName: `${field}_index`,
210
+ KeySchema: [{ AttributeName: field, KeyType: 'HASH' }],
211
+ Projection: { ProjectionType: 'ALL' },
212
+ },
213
+ }],
214
+ })).then(() => { }));
215
+ }
216
+ await Promise.all(round);
217
+ // Wait for all GSIs in this round to become ACTIVE
218
+ const tables_in_round = round.length;
219
+ if (tables_in_round > 0) {
220
+ const active_checks = [...pending_gsis.keys()];
221
+ // Also check tables that just had their last GSI added
222
+ for (const [table_name] of tables) {
223
+ if (!pending_gsis.has(table_name))
224
+ active_checks.push(table_name);
225
+ }
226
+ for (const [pivot_name] of pivots) {
227
+ if (!pending_gsis.has(pivot_name))
228
+ active_checks.push(pivot_name);
229
+ }
230
+ await this.waitForActiveGSIs([...new Set(active_checks)]);
231
+ }
232
+ }
233
+ this.synced = true;
234
+ }
235
+ /**
236
+ * @description Poll DescribeTable until all GSIs on the given tables are ACTIVE.
237
+ * @description Polling de DescribeTable hasta que todos los GSIs de las tablas dadas estén ACTIVE.
238
+ */
239
+ async waitForActiveGSIs(table_names) {
240
+ const pending = new Set(table_names);
241
+ while (pending.size > 0) {
242
+ await new Promise(r => setTimeout(r, 3000));
243
+ const checks = await Promise.all([...pending].map(async (name) => {
244
+ const result = await this.client.send(new DescribeTableCommand({ TableName: name }));
245
+ const all_active = (result.Table?.GlobalSecondaryIndexes ?? [])
246
+ .every(g => g.IndexStatus === 'ACTIVE');
247
+ return { name, all_active };
248
+ }));
249
+ for (const { name, all_active } of checks) {
250
+ if (all_active)
251
+ pending.delete(name);
252
+ }
253
+ }
254
+ }
255
+ /**
256
+ * Ejecutar operaciones en una transacción atómica.
257
+ * Si cualquier operación falla, todas se revierten automáticamente.
258
+ *
259
+ * @param callback Función que recibe el contexto de transacción
260
+ * @returns Resultado del callback
261
+ *
262
+ * @example
263
+ * await dynamite.tx(async (tx) => {
264
+ * const user = await User.create({ name: "Juan" }, tx);
265
+ * await Order.create({ user_id: user.id, total: 100 }, tx);
266
+ * });
267
+ */
268
+ async tx(callback) {
269
+ const ctx = new TransactionContext(this.client);
270
+ const result = await callback(ctx);
271
+ await ctx.commit();
272
+ return result;
273
+ }
274
+ }
275
+ let globalClient;
276
+ /**
277
+ * Set global client for Table class operations
278
+ * @param client DynamoDB client instance
279
+ */
280
+ export const setGlobalClient = (client) => {
281
+ globalClient = client;
282
+ };
283
+ /**
284
+ * Get global client for Table class operations
285
+ */
286
+ export const getGlobalClient = () => {
287
+ if (!globalClient)
288
+ throw new Error("No global DynamoDB client set. Call setGlobalClient() first.");
289
+ return globalClient;
290
+ };
291
+ /**
292
+ * Check if global client is available
293
+ */
294
+ export const hasGlobalClient = () => {
295
+ return globalClient !== undefined;
296
+ };
297
+ /**
298
+ * Require global client for Table operations (throws if not available)
299
+ */
300
+ export const requireClient = () => {
301
+ if (!globalClient) {
302
+ throw new Error("DynamoDB client no configurado. Use Dynamite.connect() primero.");
303
+ }
304
+ return globalClient;
305
+ };
306
+ /**
307
+ * @description Transaction context for grouping atomic operations. Max 100 operations (auto-chunked in batches of 25).
308
+ * @description Contexto de transacción para operaciones atómicas. Máximo 100 operaciones (auto-divididas en lotes de 25).
309
+ */
310
+ export class TransactionContext {
311
+ constructor(client) {
312
+ this.operations = [];
313
+ this.after_commit = [];
314
+ this.client = client;
315
+ }
316
+ addPut(table_name, item, condition) {
317
+ this.guard();
318
+ const op = {
319
+ Put: {
320
+ TableName: table_name,
321
+ Item: marshall(item, { removeUndefinedValues: true }),
322
+ },
323
+ };
324
+ if (condition) {
325
+ op.Put.ConditionExpression = condition.expression;
326
+ op.Put.ExpressionAttributeNames = condition.names;
327
+ }
328
+ this.operations.push(op);
329
+ }
330
+ addDelete(table_name, key) {
331
+ this.guard();
332
+ this.operations.push({
333
+ Delete: {
334
+ TableName: table_name,
335
+ Key: marshall(key),
336
+ },
337
+ });
338
+ }
339
+ addUpdate(table_name, key, expression, names, values) {
340
+ this.guard();
341
+ this.operations.push({
342
+ Update: {
343
+ TableName: table_name,
344
+ Key: marshall(key),
345
+ UpdateExpression: expression,
346
+ ExpressionAttributeNames: names,
347
+ ExpressionAttributeValues: marshall(values, { removeUndefinedValues: true }),
348
+ },
349
+ });
350
+ }
351
+ /**
352
+ * @description Register a callback to run after successful commit.
353
+ * @description Registra un callback que se ejecuta después de un commit exitoso.
354
+ */
355
+ onCommit(fn) {
356
+ this.after_commit.push(fn);
357
+ }
358
+ async commit() {
359
+ if (this.operations.length === 0)
360
+ return;
361
+ // DynamoDB limit: 25 per TransactWriteItems. Chunk if needed.
362
+ for (let i = 0; i < this.operations.length; i += 25) {
363
+ const chunk = this.operations.slice(i, i + 25);
364
+ await this.client.send(new TransactWriteItemsCommand({ TransactItems: chunk }));
365
+ }
366
+ for (const fn of this.after_commit)
367
+ fn();
368
+ }
369
+ guard() {
370
+ if (this.operations.length >= 100) {
371
+ throw new Error(`Transaction exceeds 100 operations limit (has ${this.operations.length})`);
372
+ }
373
+ }
374
+ }
375
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/core/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @file decorator.ts
3
+ * @description Minimal decorator system with Symbol storage
4
+ * @description Sistema de decoradores minimalista con Symbol storage
5
+ */
6
+ export declare const SCHEMA: unique symbol;
7
+ export interface Schema {
8
+ name: string;
9
+ primary_key: string;
10
+ gsis: Set<string>;
11
+ columns: Record<string, {
12
+ name: string;
13
+ get: ((value: any) => any)[];
14
+ set: ((current: any, next: any) => any)[];
15
+ store: {
16
+ index?: boolean;
17
+ indexSort?: boolean;
18
+ primaryKey?: boolean;
19
+ softDelete?: boolean;
20
+ createdAt?: boolean;
21
+ updatedAt?: boolean;
22
+ relation?: {
23
+ type: 'HasMany' | 'HasOne' | 'BelongsTo' | 'ManyToMany';
24
+ model: () => any;
25
+ foreignKey: string;
26
+ localKey: string;
27
+ relatedKey?: string;
28
+ pivotTable?: string;
29
+ relatedPK?: string;
30
+ };
31
+ };
32
+ }>;
33
+ }
34
+ /**
35
+ * @description Factory to create decorators with argument support and composition
36
+ * @description Factory para crear decoradores con soporte de argumentos y composición
37
+ */
38
+ export declare function decorator(callback: (table_class: any, col: Schema['columns'][string], params: any[]) => void): (...params: any[]) => (target: any, propertyKey: string | symbol) => void;
@@ -0,0 +1,34 @@
1
+ /**
2
+ * @file decorator.ts
3
+ * @description Minimal decorator system with Symbol storage
4
+ * @description Sistema de decoradores minimalista con Symbol storage
5
+ */
6
+ export const SCHEMA = Symbol('dynamite:schema');
7
+ function toSnakePlural(str) {
8
+ const snake = str
9
+ .replace(/([A-Z])/g, "_$1")
10
+ .toLowerCase()
11
+ .replace(/^_/, "");
12
+ return snake.endsWith("s") ? snake : snake + "s";
13
+ }
14
+ function resolve(target, propertyKey) {
15
+ const ctor = target.constructor;
16
+ if (!Object.prototype.hasOwnProperty.call(ctor, SCHEMA)) {
17
+ ctor[SCHEMA] = { name: toSnakePlural(ctor.name), primary_key: 'id', gsis: new Set(), columns: {} };
18
+ }
19
+ const key = String(propertyKey);
20
+ const schema = ctor[SCHEMA];
21
+ schema.columns[key] ||= { name: key, get: [], set: [], store: {} };
22
+ return [schema, schema.columns[key]];
23
+ }
24
+ /**
25
+ * @description Factory to create decorators with argument support and composition
26
+ * @description Factory para crear decoradores con soporte de argumentos y composición
27
+ */
28
+ export function decorator(callback) {
29
+ return (...params) => (target, propertyKey) => {
30
+ const [, col] = resolve(target, propertyKey);
31
+ callback(target.constructor, col, params);
32
+ };
33
+ }
34
+ //# sourceMappingURL=decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decorator.js","sourceRoot":"","sources":["../../../src/core/decorator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;AA8BhD,SAAS,aAAa,CAAC,GAAW;IAChC,MAAM,KAAK,GAAG,GAAG;SACd,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC;SAC1B,WAAW,EAAE;SACb,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACrB,OAAO,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC;AACnD,CAAC;AAED,SAAS,OAAO,CAAC,MAAW,EAAE,WAA4B;IACxD,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC;IAChC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;QACxD,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,GAAG,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACrG,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;IAChC,MAAM,MAAM,GAAW,IAAI,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IACnE,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;AACvC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,QAAmF;IAC3G,OAAO,CAAC,GAAG,MAAa,EAAE,EAAE,CAAC,CAAC,MAAW,EAAE,WAA4B,EAAE,EAAE;QACzE,MAAM,CAAC,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QAC7C,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IAC5C,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,55 @@
1
+ import type { InferAttributes, PickByType, QueryOperator, WhereOptions } from "../@types/index.js";
2
+ import { TransactionContext } from "./client.js";
3
+ import type { Schema } from "./decorator.js";
4
+ import { SCHEMA } from "./decorator.js";
5
+ type WhereFilters<M> = {
6
+ [K in keyof InferAttributes<M>]?: InferAttributes<M>[K] | {
7
+ [N in QueryOperator]?: InferAttributes<M>[K];
8
+ };
9
+ };
10
+ export default class Table<T = any> {
11
+ static [SCHEMA]: Schema;
12
+ constructor(props?: Partial<T>);
13
+ toJSON(): Record<string, unknown>;
14
+ /**
15
+ * @description Convierte la instancia a un payload listo para DynamoDB
16
+ * @returns Objeto con nombres de columnas de DB y valores apropiados
17
+ */
18
+ private _toDBPayload;
19
+ toString(): string;
20
+ save(): Promise<boolean>;
21
+ update(data: Partial<InferAttributes<T>>): Promise<boolean>;
22
+ destroy(): Promise<null>;
23
+ forceDestroy(): Promise<null>;
24
+ attach<R>(RelatedModel: new () => R, related_id: string, pivot_data?: Record<string, any>): Promise<void>;
25
+ detach<R>(RelatedModel: new () => R, related_id: string): Promise<void>;
26
+ /**
27
+ * Sincronizar relación ManyToMany reemplazando todas las relaciones existentes
28
+ * @param RelatedModel Modelo relacionado
29
+ * @param related_ids Array de IDs a sincronizar
30
+ */
31
+ sync<R>(RelatedModel: new () => R, related_ids: string[]): Promise<void>;
32
+ static create<M extends Table>(this: new (data: any) => M, data: Partial<InferAttributes<M>>, tx?: TransactionContext): Promise<M>;
33
+ /**
34
+ * @description Extract PK value from filters if the filter is a simple PK equality. Returns null otherwise.
35
+ * @description Extrae el valor de PK de los filtros si es una igualdad simple por PK. Retorna null en otro caso.
36
+ */
37
+ private static _extractPK;
38
+ static update<M extends Table>(this: new (data: any) => M, updates: Partial<InferAttributes<M>>, filters: Partial<InferAttributes<M>>, tx?: TransactionContext): Promise<number>;
39
+ static delete<M extends Table>(this: new (data: any) => M, filters: Partial<InferAttributes<M>>, tx?: TransactionContext): Promise<number>;
40
+ /**
41
+ * @description Atomically increment a numeric field by amount. Uses DynamoDB SET expression.
42
+ * @description Incrementa atómicamente un campo numérico. Usa expresión SET de DynamoDB.
43
+ */
44
+ private static _atomicAdd;
45
+ static increment<M extends Table>(this: new (data: any) => M, field: keyof PickByType<InferAttributes<M>, number>, amount: number, filters: WhereFilters<M>, tx?: TransactionContext): Promise<number>;
46
+ static decrement<M extends Table>(this: new (data: any) => M, field: keyof PickByType<InferAttributes<M>, number>, amount: number, filters: WhereFilters<M>, tx?: TransactionContext): Promise<number>;
47
+ increment<K extends keyof PickByType<InferAttributes<T>, number>>(field: K, amount?: number): Promise<void>;
48
+ decrement<K extends keyof PickByType<InferAttributes<T>, number>>(field: K, amount?: number): Promise<void>;
49
+ static where<M extends Table>(this: new (props?: any) => M, key: keyof InferAttributes<M>, value: InferAttributes<M>[typeof key], options?: WhereOptions<M>): Promise<M[]>;
50
+ static where<M extends Table>(this: new (props?: any) => M, key: keyof InferAttributes<M>, operator: QueryOperator, value: any, options?: WhereOptions<M>): Promise<M[]>;
51
+ static where<M extends Table>(this: new (props?: any) => M, filters: WhereFilters<M>, options?: WhereOptions<M>): Promise<M[]>;
52
+ static first<M extends Table>(this: new (props?: any) => M, filters: WhereFilters<M>, options?: WhereOptions<M>): Promise<M | undefined>;
53
+ static last<M extends Table>(this: new (props?: any) => M, filters?: WhereFilters<M>, options?: WhereOptions<M>): Promise<M | undefined>;
54
+ }
55
+ export {};