@arcaelas/dynamite 1.0.25 → 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 (129) 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.d.ts +1 -0
  42. package/build/cjs/test/index.js +36 -0
  43. package/build/cjs/test/index.js.map +1 -0
  44. package/build/cjs/test/query_scan.d.ts +1 -0
  45. package/build/cjs/test/query_scan.js +195 -0
  46. package/build/cjs/test/query_scan.js.map +1 -0
  47. package/build/cjs/test/relations.d.ts +1 -0
  48. package/build/cjs/test/relations.js +246 -0
  49. package/build/cjs/test/relations.js.map +1 -0
  50. package/build/cjs/test/transactions.d.ts +1 -0
  51. package/build/cjs/test/transactions.js +145 -0
  52. package/build/cjs/test/transactions.js.map +1 -0
  53. package/{src → build/cjs}/utils/relations.d.ts +1 -0
  54. package/{src → build/cjs}/utils/relations.js +5 -10
  55. package/build/cjs/utils/relations.js.map +1 -0
  56. package/build/cjs/utils/ulid.d.ts +10 -0
  57. package/build/cjs/utils/ulid.js +55 -0
  58. package/build/cjs/utils/ulid.js.map +1 -0
  59. package/build/esm/@types/index.d.ts +213 -0
  60. package/build/esm/@types/index.js +8 -0
  61. package/build/esm/@types/index.js.map +1 -0
  62. package/build/esm/core/client.d.ts +96 -0
  63. package/build/esm/core/client.js +375 -0
  64. package/build/esm/core/client.js.map +1 -0
  65. package/build/esm/core/decorator.d.ts +38 -0
  66. package/build/esm/core/decorator.js +34 -0
  67. package/build/esm/core/decorator.js.map +1 -0
  68. package/build/esm/core/table.d.ts +55 -0
  69. package/build/esm/core/table.js +848 -0
  70. package/build/esm/core/table.js.map +1 -0
  71. package/build/esm/decorators/indexes.d.ts +20 -0
  72. package/build/esm/decorators/indexes.js +42 -0
  73. package/build/esm/decorators/indexes.js.map +1 -0
  74. package/build/esm/decorators/relations.d.ts +75 -0
  75. package/build/esm/decorators/relations.js +112 -0
  76. package/build/esm/decorators/relations.js.map +1 -0
  77. package/build/esm/decorators/timestamps.d.ts +20 -0
  78. package/build/esm/decorators/timestamps.js +31 -0
  79. package/build/esm/decorators/timestamps.js.map +1 -0
  80. package/build/esm/decorators/transforms.d.ts +41 -0
  81. package/build/esm/decorators/transforms.js +92 -0
  82. package/build/esm/decorators/transforms.js.map +1 -0
  83. package/build/esm/index.d.ts +17 -0
  84. package/build/esm/index.js +24 -0
  85. package/build/esm/index.js.map +1 -0
  86. package/build/esm/package.json +1 -0
  87. package/build/esm/test/basic.d.ts +1 -0
  88. package/build/esm/test/basic.js +245 -0
  89. package/build/esm/test/basic.js.map +1 -0
  90. package/build/esm/test/bulk.d.ts +1 -0
  91. package/build/esm/test/bulk.js +105 -0
  92. package/build/esm/test/bulk.js.map +1 -0
  93. package/build/esm/test/contracts.d.ts +1 -0
  94. package/build/esm/test/contracts.js +340 -0
  95. package/build/esm/test/contracts.js.map +1 -0
  96. package/build/esm/test/filters.d.ts +1 -0
  97. package/build/esm/test/filters.js +187 -0
  98. package/build/esm/test/filters.js.map +1 -0
  99. package/build/esm/test/index.d.ts +1 -0
  100. package/build/esm/test/index.js +31 -0
  101. package/build/esm/test/index.js.map +1 -0
  102. package/build/esm/test/query_scan.d.ts +1 -0
  103. package/build/esm/test/query_scan.js +192 -0
  104. package/build/esm/test/query_scan.js.map +1 -0
  105. package/build/esm/test/relations.d.ts +1 -0
  106. package/build/esm/test/relations.js +243 -0
  107. package/build/esm/test/relations.js.map +1 -0
  108. package/build/esm/test/transactions.d.ts +1 -0
  109. package/build/esm/test/transactions.js +142 -0
  110. package/build/esm/test/transactions.js.map +1 -0
  111. package/build/esm/utils/relations.d.ts +42 -0
  112. package/build/esm/utils/relations.js +207 -0
  113. package/build/esm/utils/relations.js.map +1 -0
  114. package/build/esm/utils/ulid.d.ts +10 -0
  115. package/build/esm/utils/ulid.js +52 -0
  116. package/build/esm/utils/ulid.js.map +1 -0
  117. package/package.json +31 -9
  118. package/src/core/client.js +0 -294
  119. package/src/core/decorator.d.ts +0 -29
  120. package/src/core/decorator.js +0 -103
  121. package/src/core/table.d.ts +0 -81
  122. package/src/core/table.js +0 -892
  123. package/src/decorators/indexes.d.ts +0 -38
  124. package/src/decorators/indexes.js +0 -59
  125. package/src/decorators/timestamps.d.ts +0 -54
  126. package/src/decorators/timestamps.js +0 -72
  127. package/src/decorators/transforms.d.ts +0 -99
  128. package/src/decorators/transforms.js +0 -166
  129. /package/{src → build/cjs}/@types/index.js +0 -0
package/README.md CHANGED
@@ -102,10 +102,10 @@ npm install @arcaelas/dynamite
102
102
 
103
103
  | Decorator | Description |
104
104
  |-----------|-------------|
105
- | `@HasMany(() => Model, "foreign_key")` | One-to-many |
106
- | `@HasOne(() => Model, "foreign_key")` | One-to-one |
107
- | `@BelongsTo(() => Model, "local_key")` | Many-to-one |
108
- | `@ManyToMany(() => Model, config)` | Many-to-many with pivot table |
105
+ | `@HasMany(() => Model, foreignKey, localKey?)` | One-to-many |
106
+ | `@HasOne(() => Model, foreignKey, localKey?)` | One-to-one |
107
+ | `@BelongsTo(() => Model, localKey, foreignKey?)` | Many-to-one |
108
+ | `@ManyToMany(() => Model, pivotTable, foreignKey, relatedKey, localKey?, relatedPK?)` | Many-to-many |
109
109
 
110
110
  ---
111
111
 
@@ -193,7 +193,7 @@ await User.where("role", "in", ["admin", "moderator"]);
193
193
  await User.where("email", "$include", "gmail");
194
194
  ```
195
195
 
196
- **Available operators:** `=`, `!=`, `<>`, `<`, `<=`, `>`, `>=`, `in`, `$include`
196
+ **Available operators:** `=`, `!=`, `<>`, `<`, `<=`, `>`, `>=`, `in`, `$include` (aliases: `$eq`, `$ne`, `$lt`, `$lte`, `$gt`, `$gte`, `$in`, `include`)
197
197
 
198
198
  ### Query Options
199
199
 
@@ -223,17 +223,16 @@ class User extends Table<User> {
223
223
  @PrimaryKey()
224
224
  declare id: string;
225
225
 
226
- @HasMany(() => Order, "user_id")
226
+ // HasMany(model, foreignKey, localKey = 'id')
227
+ @HasMany(() => Order, "user_id", "id")
227
228
  declare orders: NonAttribute<Order[]>;
228
229
 
229
- @HasOne(() => Profile, "user_id")
230
+ // HasOne(model, foreignKey, localKey = 'id')
231
+ @HasOne(() => Profile, "user_id", "id")
230
232
  declare profile: NonAttribute<Profile | null>;
231
233
 
232
- @ManyToMany(() => Role, {
233
- pivotTable: "user_roles",
234
- foreignKey: "user_id",
235
- relatedKey: "role_id"
236
- })
234
+ // ManyToMany(model, pivotTable, foreignKey, relatedKey, localKey = 'id', relatedPK = 'id')
235
+ @ManyToMany(() => Role, "user_roles", "user_id", "role_id")
237
236
  declare roles: NonAttribute<Role[]>;
238
237
  }
239
238
 
@@ -243,7 +242,8 @@ class Order extends Table<Order> {
243
242
 
244
243
  declare user_id: string;
245
244
 
246
- @BelongsTo(() => User, "user_id")
245
+ // BelongsTo(model, localKey, foreignKey = 'id')
246
+ @BelongsTo(() => User, "user_id", "id")
247
247
  declare user: NonAttribute<User | null>;
248
248
  }
249
249
  ```
@@ -146,7 +146,9 @@ export interface WhereOptions<T, A = InferAttributes<T>, R = InferRelations<T>>
146
146
  };
147
147
  };
148
148
  /** Orden de resultados */
149
- order?: "ASC" | "DESC";
149
+ order?: "ASC" | "DESC" | {
150
+ [K in keyof A]?: "ASC" | "DESC";
151
+ };
150
152
  /** Número de items a saltar */
151
153
  offset?: number;
152
154
  /** Alias de offset */
@@ -185,4 +187,27 @@ export type CreateInput<T> = InferAttributes<T>;
185
187
  * ```
186
188
  */
187
189
  export type UpdateInput<T> = Partial<InferAttributes<T>>;
190
+ /**
191
+ * Picks only keys from T whose value extends V.
192
+ * Selecciona solo las keys de T cuyo valor extiende V.
193
+ * @example
194
+ * ```typescript
195
+ * class User { name: string; age: number; score: number; }
196
+ * // PickByType<InferAttributes<User>, number> = { age: number, score: number }
197
+ * ```
198
+ */
199
+ type StripBrands<T> = T extends number & {
200
+ [NonAttributeBrand]?: any;
201
+ } ? number : T extends string & {
202
+ [NonAttributeBrand]?: any;
203
+ } ? string : T extends number & {
204
+ [CreationOptionalBrand]?: any;
205
+ } ? number : T extends string & {
206
+ [CreationOptionalBrand]?: any;
207
+ } ? string : T extends boolean & {
208
+ [CreationOptionalBrand]?: any;
209
+ } ? boolean : T;
210
+ export type PickByType<T, V> = {
211
+ [K in keyof T as StripBrands<NonNullable<T[K]>> extends V ? K : never]: T[K];
212
+ };
188
213
  export {};
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/@types/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG"}
@@ -25,13 +25,20 @@ export declare class Dynamite {
25
25
  */
26
26
  constructor(config: DynamiteConfig);
27
27
  /**
28
- * Connect client and synchronize all declared tables and their GSIs (upsert pattern)
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.
29
30
  */
30
31
  connect(): Promise<void>;
31
32
  /**
32
- * Auto-crear pivot tables para relaciones ManyToMany
33
+ * @description Synchronize all tables, GSIs and pivot tables with DynamoDB.
34
+ * @description Sincroniza tablas, GSIs y pivot tables con DynamoDB.
33
35
  */
34
- private createPivotTables;
36
+ sync(): Promise<void>;
37
+ /**
38
+ * @description Poll DescribeTable until all GSIs on the given tables are ACTIVE.
39
+ * @description Polling de DescribeTable hasta que todos los GSIs de las tablas dadas estén ACTIVE.
40
+ */
41
+ private waitForActiveGSIs;
35
42
  /**
36
43
  * Ejecutar operaciones en una transacción atómica.
37
44
  * Si cualquier operación falla, todas se revierten automáticamente.
@@ -46,11 +53,6 @@ export declare class Dynamite {
46
53
  * });
47
54
  */
48
55
  tx<R>(callback: (tx: TransactionContext) => Promise<R>): Promise<R>;
49
- /**
50
- * Create table with automatic GSI detection and creation
51
- * @param ctor Table class constructor
52
- */
53
- private createTableWithGSI;
54
56
  }
55
57
  /**
56
58
  * Set global client for Table class operations
@@ -70,24 +72,25 @@ export declare const hasGlobalClient: () => boolean;
70
72
  */
71
73
  export declare const requireClient: () => DynamoDBClient;
72
74
  /**
73
- * Contexto de transacción para agrupar operaciones atómicas.
74
- * Máximo 25 operaciones por transacción (límite DynamoDB).
75
+ * @description Transaction context for grouping atomic operations. Max 100 operations (auto-chunked in batches of 25).
76
+ * @description Contexto de transacción para operaciones atómicas. Máximo 100 operaciones (auto-divididas en lotes de 25).
75
77
  */
76
78
  export declare class TransactionContext {
77
79
  private operations;
80
+ private after_commit;
78
81
  private client;
79
82
  constructor(client: DynamoDBClient);
80
- /**
81
- * Agregar operación Put a la transacción
82
- */
83
- addPut(table_name: string, item: Record<string, any>): void;
84
- /**
85
- * Agregar operación Delete a la transacción
86
- */
83
+ addPut(table_name: string, item: Record<string, any>, condition?: {
84
+ expression: string;
85
+ names: Record<string, string>;
86
+ }): void;
87
87
  addDelete(table_name: string, key: Record<string, any>): void;
88
+ addUpdate(table_name: string, key: Record<string, any>, expression: string, names: Record<string, string>, values: Record<string, any>): void;
88
89
  /**
89
- * Confirmar todas las operaciones de la transacción.
90
- * Si alguna falla, todas se revierten.
90
+ * @description Register a callback to run after successful commit.
91
+ * @description Registra un callback que se ejecuta después de un commit exitoso.
91
92
  */
93
+ onCommit(fn: () => void): void;
92
94
  commit(): Promise<void>;
95
+ private guard;
93
96
  }
@@ -0,0 +1,384 @@
1
+ "use strict";
2
+ /**
3
+ * @file client.ts
4
+ * @description Centralized Dynamite client with multi-client support and table sync
5
+ * @autor Miguel Alejandro
6
+ * @fecha 2025-01-27
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.TransactionContext = exports.requireClient = exports.hasGlobalClient = exports.getGlobalClient = exports.setGlobalClient = exports.Dynamite = void 0;
10
+ const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
11
+ const util_dynamodb_1 = require("@aws-sdk/util-dynamodb");
12
+ const decorator_1 = require("./decorator");
13
+ /**
14
+ * Centralized Dynamite client for managing DynamoDB connections and table synchronization
15
+ */
16
+ class Dynamite {
17
+ /**
18
+ * Initialize Dynamite client with configuration
19
+ * @param config Dynamite client configuration
20
+ */
21
+ constructor(config) {
22
+ this.connected = false;
23
+ this.synced = false;
24
+ const { tables, ...options } = config;
25
+ this.client = new client_dynamodb_1.DynamoDBClient({
26
+ ...options,
27
+ });
28
+ this.tables = tables;
29
+ }
30
+ /**
31
+ * @description Configure the DynamoDB client. Does not create tables or GSIs -- use sync() for that.
32
+ * @description Configura el cliente DynamoDB. No crea tablas ni GSIs -- usar sync() para eso.
33
+ */
34
+ async connect() {
35
+ if (this.connected)
36
+ return;
37
+ (0, exports.setGlobalClient)(this.client);
38
+ this.connected = true;
39
+ // Computar GSIs esperados desde los schemas (sin llamadas API)
40
+ const pk_by_table = new Map();
41
+ for (const tc of this.tables) {
42
+ const s = tc[decorator_1.SCHEMA];
43
+ if (!s)
44
+ continue;
45
+ const pk_col = Object.values(s.columns).find(c => c.store.index || c.store.primaryKey);
46
+ pk_by_table.set(s.name, pk_col?.name ?? 'id');
47
+ }
48
+ for (const tc of this.tables) {
49
+ const s = tc[decorator_1.SCHEMA];
50
+ if (!s)
51
+ continue;
52
+ for (const col_name in s.columns) {
53
+ const rel = s.columns[col_name].store.relation;
54
+ if (!rel || (rel.type !== 'HasMany' && rel.type !== 'HasOne'))
55
+ continue;
56
+ const related = rel.model()?.[decorator_1.SCHEMA];
57
+ if (!related)
58
+ continue;
59
+ const related_pk = pk_by_table.get(related.name);
60
+ if (rel.foreignKey !== related_pk) {
61
+ related.gsis.add(rel.foreignKey);
62
+ }
63
+ }
64
+ }
65
+ }
66
+ /**
67
+ * @description Synchronize all tables, GSIs and pivot tables with DynamoDB.
68
+ * @description Sincroniza tablas, GSIs y pivot tables con DynamoDB.
69
+ */
70
+ async sync() {
71
+ if (!this.connected)
72
+ throw new Error('Call connect() before sync()');
73
+ if (this.synced)
74
+ return;
75
+ // Phase 1: Collect requirements
76
+ const tables = new Map();
77
+ const pivots = new Map();
78
+ for (const table_class of this.tables) {
79
+ const schema = table_class[decorator_1.SCHEMA];
80
+ if (!schema)
81
+ throw new Error(`Class ${table_class.name} not registered. Use decorators.`);
82
+ const cols = Object.values(schema.columns);
83
+ const pk = cols.find(c => c.store.index || c.store.primaryKey);
84
+ if (!pk)
85
+ throw new Error(`PartitionKey missing in ${table_class.name}`);
86
+ const sk = cols.find(c => c.store.indexSort) ?? null;
87
+ tables.set(schema.name, { pk: pk.name, sk: sk?.name ?? null, gsis: new Set() });
88
+ }
89
+ for (const table_class of this.tables) {
90
+ const schema = table_class[decorator_1.SCHEMA];
91
+ for (const col_name in schema.columns) {
92
+ const relation = schema.columns[col_name].store.relation;
93
+ if (!relation)
94
+ continue;
95
+ if (relation.type === 'HasMany' || relation.type === 'HasOne') {
96
+ const related_schema = relation.model()?.[decorator_1.SCHEMA];
97
+ if (related_schema && tables.has(related_schema.name)) {
98
+ const entry = tables.get(related_schema.name);
99
+ if (relation.foreignKey !== entry.pk) {
100
+ entry.gsis.add(relation.foreignKey);
101
+ }
102
+ }
103
+ }
104
+ if (relation.type === 'ManyToMany' && relation.pivotTable) {
105
+ pivots.set(relation.pivotTable, {
106
+ foreignKey: relation.foreignKey,
107
+ relatedKey: relation.relatedKey,
108
+ });
109
+ }
110
+ }
111
+ }
112
+ // Phase 2: Describe all tables + pivots in parallel
113
+ const all_table_names = [...tables.keys()];
114
+ const all_pivot_names = [...pivots.keys()];
115
+ const all_names = [...all_table_names, ...all_pivot_names];
116
+ const descriptions = await Promise.all(all_names.map(async (name) => {
117
+ try {
118
+ const result = await this.client.send(new client_dynamodb_1.DescribeTableCommand({ TableName: name }));
119
+ const existing_gsis = new Set((result.Table?.GlobalSecondaryIndexes ?? []).map(g => g.IndexName));
120
+ return { name, exists: true, existing_gsis };
121
+ }
122
+ catch (e) {
123
+ if (e.name === 'ResourceNotFoundException')
124
+ return { name, exists: false, existing_gsis: new Set() };
125
+ throw e;
126
+ }
127
+ }));
128
+ const described = new Map(descriptions.map(d => [d.name, d]));
129
+ // Phase 3: Create missing tables in parallel
130
+ const to_create = [];
131
+ for (const [name, entry] of tables) {
132
+ const desc = described.get(name);
133
+ if (desc.exists)
134
+ continue;
135
+ const attrs = new Map([[entry.pk, 'S']]);
136
+ if (entry.sk)
137
+ attrs.set(entry.sk, 'S');
138
+ for (const gsi_field of entry.gsis)
139
+ attrs.set(gsi_field, 'S');
140
+ const key_schema = [
141
+ { AttributeName: entry.pk, KeyType: 'HASH' },
142
+ ];
143
+ if (entry.sk)
144
+ key_schema.push({ AttributeName: entry.sk, KeyType: 'RANGE' });
145
+ const gsi_defs = [...entry.gsis].map(field => ({
146
+ IndexName: `${field}_index`,
147
+ KeySchema: [{ AttributeName: field, KeyType: 'HASH' }],
148
+ Projection: { ProjectionType: 'ALL' },
149
+ }));
150
+ to_create.push(this.client.send(new client_dynamodb_1.CreateTableCommand({
151
+ TableName: name,
152
+ BillingMode: 'PAY_PER_REQUEST',
153
+ AttributeDefinitions: [...attrs].map(([AttributeName, AttributeType]) => ({ AttributeName, AttributeType })),
154
+ KeySchema: key_schema,
155
+ ...(gsi_defs.length > 0 && { GlobalSecondaryIndexes: gsi_defs }),
156
+ })).then(() => { }));
157
+ }
158
+ for (const [name, meta] of pivots) {
159
+ const desc = described.get(name);
160
+ if (desc.exists)
161
+ continue;
162
+ to_create.push(this.client.send(new client_dynamodb_1.CreateTableCommand({
163
+ TableName: name,
164
+ BillingMode: 'PAY_PER_REQUEST',
165
+ KeySchema: [{ AttributeName: 'id', KeyType: 'HASH' }],
166
+ AttributeDefinitions: [
167
+ { AttributeName: 'id', AttributeType: 'S' },
168
+ { AttributeName: meta.foreignKey, AttributeType: 'S' },
169
+ { AttributeName: meta.relatedKey, AttributeType: 'S' },
170
+ ],
171
+ GlobalSecondaryIndexes: [
172
+ { IndexName: `${meta.foreignKey}_index`, KeySchema: [{ AttributeName: meta.foreignKey, KeyType: 'HASH' }], Projection: { ProjectionType: 'ALL' } },
173
+ { IndexName: `${meta.relatedKey}_index`, KeySchema: [{ AttributeName: meta.relatedKey, KeyType: 'HASH' }], Projection: { ProjectionType: 'ALL' } },
174
+ ],
175
+ })).then(() => { }));
176
+ }
177
+ await Promise.all(to_create);
178
+ // Phase 4: Add missing GSIs to existing tables (round-robin, parallel across tables)
179
+ const pending_gsis = new Map();
180
+ for (const [name, entry] of tables) {
181
+ const desc = described.get(name);
182
+ if (!desc.exists)
183
+ continue;
184
+ const missing = [...entry.gsis].filter(field => !desc.existing_gsis.has(`${field}_index`));
185
+ if (missing.length > 0)
186
+ pending_gsis.set(name, missing);
187
+ }
188
+ for (const [name, meta] of pivots) {
189
+ const desc = described.get(name);
190
+ if (!desc.exists)
191
+ continue;
192
+ const expected = [`${meta.foreignKey}_index`, `${meta.relatedKey}_index`];
193
+ const missing_fields = [];
194
+ if (!desc.existing_gsis.has(expected[0]))
195
+ missing_fields.push(meta.foreignKey);
196
+ if (!desc.existing_gsis.has(expected[1]))
197
+ missing_fields.push(meta.relatedKey);
198
+ if (missing_fields.length > 0)
199
+ pending_gsis.set(name, missing_fields);
200
+ }
201
+ while (pending_gsis.size > 0) {
202
+ const round = [];
203
+ for (const [table_name, fields] of pending_gsis) {
204
+ const field = fields.shift();
205
+ if (fields.length === 0)
206
+ pending_gsis.delete(table_name);
207
+ round.push(this.client.send(new client_dynamodb_1.UpdateTableCommand({
208
+ TableName: table_name,
209
+ AttributeDefinitions: [{ AttributeName: field, AttributeType: 'S' }],
210
+ GlobalSecondaryIndexUpdates: [{
211
+ Create: {
212
+ IndexName: `${field}_index`,
213
+ KeySchema: [{ AttributeName: field, KeyType: 'HASH' }],
214
+ Projection: { ProjectionType: 'ALL' },
215
+ },
216
+ }],
217
+ })).then(() => { }));
218
+ }
219
+ await Promise.all(round);
220
+ // Wait for all GSIs in this round to become ACTIVE
221
+ const tables_in_round = round.length;
222
+ if (tables_in_round > 0) {
223
+ const active_checks = [...pending_gsis.keys()];
224
+ // Also check tables that just had their last GSI added
225
+ for (const [table_name] of tables) {
226
+ if (!pending_gsis.has(table_name))
227
+ active_checks.push(table_name);
228
+ }
229
+ for (const [pivot_name] of pivots) {
230
+ if (!pending_gsis.has(pivot_name))
231
+ active_checks.push(pivot_name);
232
+ }
233
+ await this.waitForActiveGSIs([...new Set(active_checks)]);
234
+ }
235
+ }
236
+ this.synced = true;
237
+ }
238
+ /**
239
+ * @description Poll DescribeTable until all GSIs on the given tables are ACTIVE.
240
+ * @description Polling de DescribeTable hasta que todos los GSIs de las tablas dadas estén ACTIVE.
241
+ */
242
+ async waitForActiveGSIs(table_names) {
243
+ const pending = new Set(table_names);
244
+ while (pending.size > 0) {
245
+ await new Promise(r => setTimeout(r, 3000));
246
+ const checks = await Promise.all([...pending].map(async (name) => {
247
+ const result = await this.client.send(new client_dynamodb_1.DescribeTableCommand({ TableName: name }));
248
+ const all_active = (result.Table?.GlobalSecondaryIndexes ?? [])
249
+ .every(g => g.IndexStatus === 'ACTIVE');
250
+ return { name, all_active };
251
+ }));
252
+ for (const { name, all_active } of checks) {
253
+ if (all_active)
254
+ pending.delete(name);
255
+ }
256
+ }
257
+ }
258
+ /**
259
+ * Ejecutar operaciones en una transacción atómica.
260
+ * Si cualquier operación falla, todas se revierten automáticamente.
261
+ *
262
+ * @param callback Función que recibe el contexto de transacción
263
+ * @returns Resultado del callback
264
+ *
265
+ * @example
266
+ * await dynamite.tx(async (tx) => {
267
+ * const user = await User.create({ name: "Juan" }, tx);
268
+ * await Order.create({ user_id: user.id, total: 100 }, tx);
269
+ * });
270
+ */
271
+ async tx(callback) {
272
+ const ctx = new TransactionContext(this.client);
273
+ const result = await callback(ctx);
274
+ await ctx.commit();
275
+ return result;
276
+ }
277
+ }
278
+ exports.Dynamite = Dynamite;
279
+ let globalClient;
280
+ /**
281
+ * Set global client for Table class operations
282
+ * @param client DynamoDB client instance
283
+ */
284
+ const setGlobalClient = (client) => {
285
+ globalClient = client;
286
+ };
287
+ exports.setGlobalClient = setGlobalClient;
288
+ /**
289
+ * Get global client for Table class operations
290
+ */
291
+ const getGlobalClient = () => {
292
+ if (!globalClient)
293
+ throw new Error("No global DynamoDB client set. Call setGlobalClient() first.");
294
+ return globalClient;
295
+ };
296
+ exports.getGlobalClient = getGlobalClient;
297
+ /**
298
+ * Check if global client is available
299
+ */
300
+ const hasGlobalClient = () => {
301
+ return globalClient !== undefined;
302
+ };
303
+ exports.hasGlobalClient = hasGlobalClient;
304
+ /**
305
+ * Require global client for Table operations (throws if not available)
306
+ */
307
+ const requireClient = () => {
308
+ if (!globalClient) {
309
+ throw new Error("DynamoDB client no configurado. Use Dynamite.connect() primero.");
310
+ }
311
+ return globalClient;
312
+ };
313
+ exports.requireClient = requireClient;
314
+ /**
315
+ * @description Transaction context for grouping atomic operations. Max 100 operations (auto-chunked in batches of 25).
316
+ * @description Contexto de transacción para operaciones atómicas. Máximo 100 operaciones (auto-divididas en lotes de 25).
317
+ */
318
+ class TransactionContext {
319
+ constructor(client) {
320
+ this.operations = [];
321
+ this.after_commit = [];
322
+ this.client = client;
323
+ }
324
+ addPut(table_name, item, condition) {
325
+ this.guard();
326
+ const op = {
327
+ Put: {
328
+ TableName: table_name,
329
+ Item: (0, util_dynamodb_1.marshall)(item, { removeUndefinedValues: true }),
330
+ },
331
+ };
332
+ if (condition) {
333
+ op.Put.ConditionExpression = condition.expression;
334
+ op.Put.ExpressionAttributeNames = condition.names;
335
+ }
336
+ this.operations.push(op);
337
+ }
338
+ addDelete(table_name, key) {
339
+ this.guard();
340
+ this.operations.push({
341
+ Delete: {
342
+ TableName: table_name,
343
+ Key: (0, util_dynamodb_1.marshall)(key),
344
+ },
345
+ });
346
+ }
347
+ addUpdate(table_name, key, expression, names, values) {
348
+ this.guard();
349
+ this.operations.push({
350
+ Update: {
351
+ TableName: table_name,
352
+ Key: (0, util_dynamodb_1.marshall)(key),
353
+ UpdateExpression: expression,
354
+ ExpressionAttributeNames: names,
355
+ ExpressionAttributeValues: (0, util_dynamodb_1.marshall)(values, { removeUndefinedValues: true }),
356
+ },
357
+ });
358
+ }
359
+ /**
360
+ * @description Register a callback to run after successful commit.
361
+ * @description Registra un callback que se ejecuta después de un commit exitoso.
362
+ */
363
+ onCommit(fn) {
364
+ this.after_commit.push(fn);
365
+ }
366
+ async commit() {
367
+ if (this.operations.length === 0)
368
+ return;
369
+ // DynamoDB limit: 25 per TransactWriteItems. Chunk if needed.
370
+ for (let i = 0; i < this.operations.length; i += 25) {
371
+ const chunk = this.operations.slice(i, i + 25);
372
+ await this.client.send(new client_dynamodb_1.TransactWriteItemsCommand({ TransactItems: chunk }));
373
+ }
374
+ for (const fn of this.after_commit)
375
+ fn();
376
+ }
377
+ guard() {
378
+ if (this.operations.length >= 100) {
379
+ throw new Error(`Transaction exceeds 100 operations limit (has ${this.operations.length})`);
380
+ }
381
+ }
382
+ }
383
+ exports.TransactionContext = TransactionContext;
384
+ //# 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,38 @@
1
+ "use strict";
2
+ /**
3
+ * @file decorator.ts
4
+ * @description Minimal decorator system with Symbol storage
5
+ * @description Sistema de decoradores minimalista con Symbol storage
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.SCHEMA = void 0;
9
+ exports.decorator = decorator;
10
+ exports.SCHEMA = Symbol('dynamite:schema');
11
+ function toSnakePlural(str) {
12
+ const snake = str
13
+ .replace(/([A-Z])/g, "_$1")
14
+ .toLowerCase()
15
+ .replace(/^_/, "");
16
+ return snake.endsWith("s") ? snake : snake + "s";
17
+ }
18
+ function resolve(target, propertyKey) {
19
+ const ctor = target.constructor;
20
+ if (!Object.prototype.hasOwnProperty.call(ctor, exports.SCHEMA)) {
21
+ ctor[exports.SCHEMA] = { name: toSnakePlural(ctor.name), primary_key: 'id', gsis: new Set(), columns: {} };
22
+ }
23
+ const key = String(propertyKey);
24
+ const schema = ctor[exports.SCHEMA];
25
+ schema.columns[key] ||= { name: key, get: [], set: [], store: {} };
26
+ return [schema, schema.columns[key]];
27
+ }
28
+ /**
29
+ * @description Factory to create decorators with argument support and composition
30
+ * @description Factory para crear decoradores con soporte de argumentos y composición
31
+ */
32
+ function decorator(callback) {
33
+ return (...params) => (target, propertyKey) => {
34
+ const [, col] = resolve(target, propertyKey);
35
+ callback(target.constructor, col, params);
36
+ };
37
+ }
38
+ //# sourceMappingURL=decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decorator.js","sourceRoot":"","sources":["../../../src/core/decorator.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAuDH,8BAKC;AA1DY,QAAA,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,cAAM,CAAC,EAAE,CAAC;QACxD,IAAI,CAAC,cAAM,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,cAAM,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,SAAgB,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"}