@arcaelas/dynamite 1.0.9 → 1.0.10
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/build/__tests__/crud.spec.d.ts +7 -0
- package/build/__tests__/crud.spec.js +287 -0
- package/build/__tests__/crud.spec.js.map +1 -0
- package/build/__tests__/debug-decorators.spec.d.ts +7 -0
- package/build/__tests__/debug-decorators.spec.js +143 -0
- package/build/__tests__/debug-decorators.spec.js.map +1 -0
- package/build/__tests__/decorators.spec.d.ts +7 -0
- package/build/__tests__/decorators.spec.js +203 -0
- package/build/__tests__/decorators.spec.js.map +1 -0
- package/build/__tests__/instance-crud.spec.d.ts +7 -0
- package/build/__tests__/instance-crud.spec.js +184 -0
- package/build/__tests__/instance-crud.spec.js.map +1 -0
- package/build/src/core/client.d.ts +65 -0
- package/build/src/core/client.js +152 -0
- package/build/src/core/client.js.map +1 -0
- package/build/{core → src/core}/table.d.ts +29 -3
- package/build/src/core/table.js +406 -0
- package/build/src/core/table.js.map +1 -0
- package/build/{core → src/core}/wrapper.d.ts +12 -2
- package/build/src/core/wrapper.js +27 -0
- package/build/src/core/wrapper.js.map +1 -0
- package/build/src/decorators/created_at.d.ts +8 -0
- package/build/{decorators → src/decorators}/created_at.js +6 -10
- package/build/src/decorators/created_at.js.map +1 -0
- package/build/src/decorators/default.d.ts +8 -0
- package/build/{decorators → src/decorators}/default.js +18 -13
- package/build/src/decorators/default.js.map +1 -0
- package/build/src/decorators/index.d.ts +8 -0
- package/build/src/decorators/index.js +26 -0
- package/build/src/decorators/index.js.map +1 -0
- package/build/src/decorators/index_sort.d.ts +8 -0
- package/build/src/decorators/index_sort.js +30 -0
- package/build/src/decorators/index_sort.js.map +1 -0
- package/build/src/decorators/mutate.d.ts +9 -0
- package/build/{decorators → src/decorators}/mutate.js +22 -15
- package/build/src/decorators/mutate.js.map +1 -0
- package/build/src/decorators/name.d.ts +8 -0
- package/build/src/decorators/name.js +42 -0
- package/build/src/decorators/name.js.map +1 -0
- package/build/src/decorators/not_null.d.ts +8 -0
- package/build/src/decorators/not_null.js +20 -0
- package/build/src/decorators/not_null.js.map +1 -0
- package/build/src/decorators/primary_key.d.ts +8 -0
- package/build/src/decorators/primary_key.js +26 -0
- package/build/src/decorators/primary_key.js.map +1 -0
- package/build/src/decorators/updated_at.d.ts +8 -0
- package/build/src/decorators/updated_at.js +18 -0
- package/build/src/decorators/updated_at.js.map +1 -0
- package/build/src/decorators/validate.d.ts +8 -0
- package/build/{decorators → src/decorators}/validate.js +18 -12
- package/build/src/decorators/validate.js.map +1 -0
- package/build/{index.d.ts → src/index.d.ts} +5 -3
- package/build/{index.js → src/index.js} +14 -7
- package/build/src/index.js.map +1 -0
- package/build/src/utils/batch-relations.d.ts +14 -0
- package/build/src/utils/batch-relations.js +130 -0
- package/build/src/utils/batch-relations.js.map +1 -0
- package/build/src/utils/naming.d.ts +8 -0
- package/build/src/utils/naming.js +18 -0
- package/build/src/utils/naming.js.map +1 -0
- package/build/src/utils/projection.d.ts +12 -0
- package/build/src/utils/projection.js +50 -0
- package/build/src/utils/projection.js.map +1 -0
- package/build/src/utils/relations.d.ts +23 -0
- package/build/src/utils/relations.js +205 -0
- package/build/src/utils/relations.js.map +1 -0
- package/package.json +1 -1
- package/build/core/table.js +0 -400
- package/build/core/table.js.map +0 -1
- package/build/core/wrapper.js +0 -26
- package/build/core/wrapper.js.map +0 -1
- package/build/decorators/created_at.d.ts +0 -4
- package/build/decorators/created_at.js.map +0 -1
- package/build/decorators/default.d.ts +0 -2
- package/build/decorators/default.js.map +0 -1
- package/build/decorators/index.d.ts +0 -1
- package/build/decorators/index.js +0 -24
- package/build/decorators/index.js.map +0 -1
- package/build/decorators/index_sort.d.ts +0 -1
- package/build/decorators/index_sort.js +0 -27
- package/build/decorators/index_sort.js.map +0 -1
- package/build/decorators/mutate.d.ts +0 -2
- package/build/decorators/mutate.js.map +0 -1
- package/build/decorators/name.d.ts +0 -1
- package/build/decorators/name.js +0 -41
- package/build/decorators/name.js.map +0 -1
- package/build/decorators/not_null.d.ts +0 -4
- package/build/decorators/not_null.js +0 -28
- package/build/decorators/not_null.js.map +0 -1
- package/build/decorators/primary_key.d.ts +0 -7
- package/build/decorators/primary_key.js +0 -30
- package/build/decorators/primary_key.js.map +0 -1
- package/build/decorators/updated_at.d.ts +0 -4
- package/build/decorators/updated_at.js +0 -23
- package/build/decorators/updated_at.js.map +0 -1
- package/build/decorators/validate.d.ts +0 -1
- package/build/decorators/validate.js.map +0 -1
- package/build/index.js.map +0 -1
- package/build/utils/naming.d.ts +0 -1
- package/build/utils/naming.js +0 -18
- package/build/utils/naming.js.map +0 -1
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file decorators.spec.ts
|
|
4
|
+
* @descripcion Tests de decoradores y metadatos
|
|
5
|
+
* @autor Miguel Alejandro
|
|
6
|
+
* @fecha 2025-01-27
|
|
7
|
+
*/
|
|
8
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
9
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
10
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
11
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
12
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
13
|
+
};
|
|
14
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
15
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
16
|
+
};
|
|
17
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
18
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
19
|
+
};
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
const client_1 = require("../src/core/client");
|
|
22
|
+
const table_1 = __importDefault(require("../src/core/table"));
|
|
23
|
+
const created_at_1 = __importDefault(require("../src/decorators/created_at"));
|
|
24
|
+
const default_1 = __importDefault(require("../src/decorators/default"));
|
|
25
|
+
const mutate_1 = __importDefault(require("../src/decorators/mutate"));
|
|
26
|
+
const primary_key_1 = __importDefault(require("../src/decorators/primary_key"));
|
|
27
|
+
const updated_at_1 = __importDefault(require("../src/decorators/updated_at"));
|
|
28
|
+
const validate_1 = __importDefault(require("../src/decorators/validate"));
|
|
29
|
+
const relations_1 = require("../src/utils/relations");
|
|
30
|
+
// =============================================================================
|
|
31
|
+
// MODELOS DE PRUEBA PARA DECORADORES
|
|
32
|
+
// =============================================================================
|
|
33
|
+
class TestConfig extends table_1.default {
|
|
34
|
+
}
|
|
35
|
+
__decorate([
|
|
36
|
+
(0, primary_key_1.default)(),
|
|
37
|
+
__metadata("design:type", Object)
|
|
38
|
+
], TestConfig.prototype, "id", void 0);
|
|
39
|
+
__decorate([
|
|
40
|
+
(0, default_1.default)(() => new Date().toISOString()),
|
|
41
|
+
__metadata("design:type", Object)
|
|
42
|
+
], TestConfig.prototype, "timestamp", void 0);
|
|
43
|
+
__decorate([
|
|
44
|
+
(0, default_1.default)(() => []),
|
|
45
|
+
__metadata("design:type", Object)
|
|
46
|
+
], TestConfig.prototype, "tags", void 0);
|
|
47
|
+
__decorate([
|
|
48
|
+
(0, default_1.default)(() => ({ active: true, count: 0 })),
|
|
49
|
+
__metadata("design:type", Object)
|
|
50
|
+
], TestConfig.prototype, "status", void 0);
|
|
51
|
+
class Article extends table_1.default {
|
|
52
|
+
}
|
|
53
|
+
__decorate([
|
|
54
|
+
(0, primary_key_1.default)(),
|
|
55
|
+
__metadata("design:type", Object)
|
|
56
|
+
], Article.prototype, "id", void 0);
|
|
57
|
+
__decorate([
|
|
58
|
+
(0, default_1.default)("Default Title"),
|
|
59
|
+
(0, validate_1.default)((v) => (typeof v === "string" && v.length >= 3) || "Título muy corto"),
|
|
60
|
+
(0, mutate_1.default)((v) => typeof v === "string" ? v.trim().toUpperCase() : String(v)),
|
|
61
|
+
__metadata("design:type", Object)
|
|
62
|
+
], Article.prototype, "title", void 0);
|
|
63
|
+
__decorate([
|
|
64
|
+
(0, default_1.default)("draft"),
|
|
65
|
+
(0, mutate_1.default)((v) => (typeof v === "string" ? v.toLowerCase() : String(v))),
|
|
66
|
+
__metadata("design:type", Object)
|
|
67
|
+
], Article.prototype, "status", void 0);
|
|
68
|
+
__decorate([
|
|
69
|
+
(0, default_1.default)(""),
|
|
70
|
+
__metadata("design:type", Object)
|
|
71
|
+
], Article.prototype, "content", void 0);
|
|
72
|
+
__decorate([
|
|
73
|
+
(0, default_1.default)("unknown"),
|
|
74
|
+
__metadata("design:type", Object)
|
|
75
|
+
], Article.prototype, "author", void 0);
|
|
76
|
+
__decorate([
|
|
77
|
+
(0, created_at_1.default)(),
|
|
78
|
+
__metadata("design:type", Object)
|
|
79
|
+
], Article.prototype, "created_at", void 0);
|
|
80
|
+
__decorate([
|
|
81
|
+
(0, updated_at_1.default)(),
|
|
82
|
+
__metadata("design:type", Object)
|
|
83
|
+
], Article.prototype, "updated_at", void 0);
|
|
84
|
+
// =============================================================================
|
|
85
|
+
// CONFIGURACIÓN DE CLIENTE PARA TESTS DE DECORADORES
|
|
86
|
+
// =============================================================================
|
|
87
|
+
const client = new client_1.Dynamite({
|
|
88
|
+
region: "local",
|
|
89
|
+
endpoint: "http://localhost:8000",
|
|
90
|
+
credentials: { accessKeyId: "x", secretAccessKey: "x" },
|
|
91
|
+
tables: [TestConfig, Article],
|
|
92
|
+
});
|
|
93
|
+
// =============================================================================
|
|
94
|
+
// SUITE DE TESTS DE DECORADORES
|
|
95
|
+
// =============================================================================
|
|
96
|
+
describe("🎨 Decorators", () => {
|
|
97
|
+
jest.setTimeout(30_000);
|
|
98
|
+
beforeAll(async () => {
|
|
99
|
+
await client.sync();
|
|
100
|
+
client.connect();
|
|
101
|
+
});
|
|
102
|
+
afterEach(async () => {
|
|
103
|
+
// Limpieza después de cada test
|
|
104
|
+
try {
|
|
105
|
+
await TestConfig.destroy("test1");
|
|
106
|
+
await TestConfig.destroy("test2");
|
|
107
|
+
await Article.destroy("art1");
|
|
108
|
+
await Article.destroy("art2");
|
|
109
|
+
}
|
|
110
|
+
catch (e) {
|
|
111
|
+
// Ignorar errores de limpieza
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
afterAll(() => {
|
|
115
|
+
// Limpiar interval para evitar warning de Jest
|
|
116
|
+
(0, relations_1.stopCleanupInterval)();
|
|
117
|
+
});
|
|
118
|
+
// ===========================================================================
|
|
119
|
+
// TESTS @DEFAULT
|
|
120
|
+
// ===========================================================================
|
|
121
|
+
describe("@Default", () => {
|
|
122
|
+
it("aplica valores por defecto simples", () => {
|
|
123
|
+
const a = new Article({ id: "art1" });
|
|
124
|
+
expect(a.title).toBe("DEFAULT TITLE"); // Valor mutado por @Mutate toUpperCase
|
|
125
|
+
expect(a.status).toBe("draft");
|
|
126
|
+
expect(a.content).toBe("");
|
|
127
|
+
expect(a.author).toBe("unknown");
|
|
128
|
+
});
|
|
129
|
+
it("aplica valores por defecto de funciones", () => {
|
|
130
|
+
const c = new TestConfig({ id: "test1" });
|
|
131
|
+
expect(c.timestamp).toMatch(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/);
|
|
132
|
+
expect(Array.isArray(c.tags)).toBe(true);
|
|
133
|
+
expect(c.tags).toEqual([]);
|
|
134
|
+
expect(typeof c.status).toBe("object");
|
|
135
|
+
expect(c.status.active).toBe(true);
|
|
136
|
+
expect(c.status.count).toBe(0);
|
|
137
|
+
});
|
|
138
|
+
it("valores y mutaciones funcionan correctamente", () => {
|
|
139
|
+
const a = new Article({ id: "test1", title: "Test Title" });
|
|
140
|
+
a.status = undefined;
|
|
141
|
+
a.title = " VALID TITLE ";
|
|
142
|
+
expect(a.status).toBe("draft");
|
|
143
|
+
expect(a.title).toBe("VALID TITLE");
|
|
144
|
+
expect(() => (a.title = "ab")).toThrow("Título muy corto");
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
// ===========================================================================
|
|
148
|
+
// TESTS @MUTATE
|
|
149
|
+
// ===========================================================================
|
|
150
|
+
describe("@Mutate", () => {
|
|
151
|
+
it("transforma valores antes de asignar", () => {
|
|
152
|
+
const a = new Article({ id: "art1", title: "Test Title" });
|
|
153
|
+
a.title = " lower case title ";
|
|
154
|
+
a.status = "PUBLISHED";
|
|
155
|
+
expect(a.title).toBe("LOWER CASE TITLE"); // trim + toUpperCase
|
|
156
|
+
expect(a.status).toBe("published"); // toLowerCase
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
// ===========================================================================
|
|
160
|
+
// TESTS @VALIDATE
|
|
161
|
+
// ===========================================================================
|
|
162
|
+
describe("@Validate", () => {
|
|
163
|
+
it("valida campos correctamente", () => {
|
|
164
|
+
const a = new Article({ id: "art1", title: "Valid Title" });
|
|
165
|
+
expect(() => {
|
|
166
|
+
a.title = "ab"; // Muy corto
|
|
167
|
+
}).toThrow("Título muy corto");
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
// ===========================================================================
|
|
171
|
+
// TESTS @CREATEDAT / @UPDATEDAT
|
|
172
|
+
// ===========================================================================
|
|
173
|
+
describe("@CreatedAt / @UpdatedAt", () => {
|
|
174
|
+
it("@CreatedAt y @UpdatedAt", async () => {
|
|
175
|
+
const a = new Article({ id: "a1" });
|
|
176
|
+
expect(a.created_at).toMatch(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/);
|
|
177
|
+
expect(a.updated_at).toMatch(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/);
|
|
178
|
+
const initialUpdated = a.updated_at;
|
|
179
|
+
// Simular pausa y actualizar updated_at directamente (comportamiento real del decorador)
|
|
180
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
181
|
+
a.updated_at = "trigger"; // Trigger del decorador @UpdatedAt
|
|
182
|
+
expect(a.updated_at).not.toBe(initialUpdated);
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
// ===========================================================================
|
|
186
|
+
// TESTS ORDEN DE EJECUCIÓN
|
|
187
|
+
// ===========================================================================
|
|
188
|
+
describe("orden de ejecución: Default → Mutate → Validate", () => {
|
|
189
|
+
it("ejecuta decoradores en orden correcto", () => {
|
|
190
|
+
const a = new Article({ id: "art1", title: "Test Title" });
|
|
191
|
+
// Default se aplica primero (valor inicial)
|
|
192
|
+
expect(a.status).toBe("draft");
|
|
193
|
+
// Mutate transforma el valor
|
|
194
|
+
a.status = "PUBLISHED";
|
|
195
|
+
expect(a.status).toBe("published"); // toLowerCase
|
|
196
|
+
// Validate puede fallar después de mutación
|
|
197
|
+
expect(() => {
|
|
198
|
+
a.title = "x"; // Muy corto después de trim
|
|
199
|
+
}).toThrow("Título muy corto");
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
//# sourceMappingURL=decorators.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decorators.spec.js","sourceRoot":"","sources":["../../__tests__/decorators.spec.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;;;;;;;AAEH,+CAA8C;AAC9C,8DAAsC;AAEtC,8EAAqD;AACrD,wEAAgD;AAChD,sEAA8C;AAC9C,gFAAuD;AACvD,8EAAqD;AACrD,0EAAkD;AAClD,sDAA6D;AAE7D,gFAAgF;AAChF,qCAAqC;AACrC,gFAAgF;AAEhF,MAAM,UAAW,SAAQ,eAAiB;CAQzC;AAPe;IAAb,IAAA,qBAAU,GAAE;;sCAA8B;AACF;IAAxC,IAAA,iBAAO,EAAC,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;;6CAAqC;AAC1D;IAAlB,IAAA,iBAAO,EAAC,GAAG,EAAE,CAAC,EAAE,CAAC;;wCAAkC;AACP;IAA5C,IAAA,iBAAO,EAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;;0CAGzC;AAGL,MAAM,OAAQ,SAAQ,eAAc;CAkBnC;AAjBe;IAAb,IAAA,qBAAU,GAAE;;mCAA8B;AAS3C;IARC,IAAA,iBAAO,EAAC,eAAe,CAAC;IACxB,IAAA,kBAAQ,EACP,CAAC,CAAU,EAAE,EAAE,CACb,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,kBAAkB,CACjE;IACA,IAAA,gBAAM,EAAC,CAAC,CAAU,EAAE,EAAE,CACrB,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAC3D;;sCAC+B;AAGhC;IAFC,IAAA,iBAAO,EAAC,OAAO,CAAC;IAChB,IAAA,gBAAM,EAAC,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;;uCAC7C;AACpB;IAAZ,IAAA,iBAAO,EAAC,EAAE,CAAC;;wCAAmC;AAC3B;IAAnB,IAAA,iBAAO,EAAC,SAAS,CAAC;;uCAAkC;AACxC;IAAZ,IAAA,oBAAS,GAAE;;2CAAkC;AACjC;IAAZ,IAAA,oBAAS,GAAE;;2CAAkC;AAGhD,gFAAgF;AAChF,qDAAqD;AACrD,gFAAgF;AAEhF,MAAM,MAAM,GAAG,IAAI,iBAAQ,CAAC;IAC1B,MAAM,EAAE,OAAO;IACf,QAAQ,EAAE,uBAAuB;IACjC,WAAW,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE;IACvD,MAAM,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC;CAC9B,CAAC,CAAC;AAEH,gFAAgF;AAChF,gCAAgC;AAChC,gFAAgF;AAEhF,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAExB,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,MAAM,CAAC,OAAO,EAAE,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,gCAAgC;QAChC,IAAI,CAAC;YACH,MAAM,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAClC,MAAM,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAClC,MAAM,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC9B,MAAM,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAChC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,8BAA8B;QAChC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,GAAG,EAAE;QACZ,+CAA+C;QAC/C,IAAA,+BAAmB,GAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,8EAA8E;IAC9E,iBAAiB;IACjB,8EAA8E;IAE9E,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;QACxB,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC5C,MAAM,CAAC,GAAG,IAAI,OAAO,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;YACtC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,uCAAuC;YAC9E,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC/B,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC3B,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;YACjD,MAAM,CAAC,GAAG,IAAI,UAAU,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;YAC1C,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC;YACpE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAC3B,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACvC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;YACtD,MAAM,CAAC,GAAG,IAAI,OAAO,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC;YAC3D,CAAS,CAAC,MAAM,GAAG,SAAS,CAAC;YAC7B,CAAS,CAAC,KAAK,GAAG,iBAAiB,CAAC;YAErC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC/B,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YACpC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,8EAA8E;IAC9E,gBAAgB;IAChB,8EAA8E;IAE9E,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;QACvB,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;YAC7C,MAAM,CAAC,GAAG,IAAI,OAAO,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC;YAC3D,CAAC,CAAC,KAAK,GAAG,sBAAsB,CAAC;YACjC,CAAC,CAAC,MAAM,GAAG,WAAW,CAAC;YAEvB,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,qBAAqB;YAC/D,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,cAAc;QACpD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,8EAA8E;IAC9E,kBAAkB;IAClB,8EAA8E;IAE9E,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;QACzB,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;YACrC,MAAM,CAAC,GAAG,IAAI,OAAO,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,CAAC;YAE5D,MAAM,CAAC,GAAG,EAAE;gBACV,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,YAAY;YAC9B,CAAC,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,8EAA8E;IAC9E,gCAAgC;IAChC,8EAA8E;IAE9E,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACvC,EAAE,CAAC,yBAAyB,EAAE,KAAK,IAAI,EAAE;YACvC,MAAM,CAAC,GAAG,IAAI,OAAO,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;YAEpC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC;YACrE,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC;YAErE,MAAM,cAAc,GAAG,CAAC,CAAC,UAAU,CAAC;YAEpC,yFAAyF;YACzF,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;YACvD,CAAS,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC,mCAAmC;YACtE,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,8EAA8E;IAC9E,2BAA2B;IAC3B,8EAA8E;IAE9E,QAAQ,CAAC,iDAAiD,EAAE,GAAG,EAAE;QAC/D,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;YAC/C,MAAM,CAAC,GAAG,IAAI,OAAO,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC;YAE3D,4CAA4C;YAC5C,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAE/B,6BAA6B;YAC7B,CAAC,CAAC,MAAM,GAAG,WAAW,CAAC;YACvB,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,cAAc;YAElD,4CAA4C;YAC5C,MAAM,CAAC,GAAG,EAAE;gBACV,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,4BAA4B;YAC7C,CAAC,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file instance-crud.spec.ts
|
|
4
|
+
* @descripcion Tests de métodos de instancia y operaciones CRUD
|
|
5
|
+
* @autor Miguel Alejandro
|
|
6
|
+
* @fecha 2025-01-27
|
|
7
|
+
*/
|
|
8
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
9
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
10
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
11
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
12
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
13
|
+
};
|
|
14
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
15
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
16
|
+
};
|
|
17
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
18
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
19
|
+
};
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
const client_1 = require("../src/core/client");
|
|
22
|
+
const relations_1 = require("../src/utils/relations");
|
|
23
|
+
const table_1 = __importDefault(require("../src/core/table"));
|
|
24
|
+
const primary_key_1 = __importDefault(require("../src/decorators/primary_key"));
|
|
25
|
+
const default_1 = __importDefault(require("../src/decorators/default"));
|
|
26
|
+
const created_at_1 = __importDefault(require("../src/decorators/created_at"));
|
|
27
|
+
const updated_at_1 = __importDefault(require("../src/decorators/updated_at"));
|
|
28
|
+
// =============================================================================
|
|
29
|
+
// MODELOS DE PRUEBA PARA INSTANCIAS
|
|
30
|
+
// =============================================================================
|
|
31
|
+
class User extends table_1.default {
|
|
32
|
+
}
|
|
33
|
+
__decorate([
|
|
34
|
+
(0, primary_key_1.default)(),
|
|
35
|
+
__metadata("design:type", Object)
|
|
36
|
+
], User.prototype, "id", void 0);
|
|
37
|
+
__decorate([
|
|
38
|
+
(0, default_1.default)("test@example.com"),
|
|
39
|
+
__metadata("design:type", Object)
|
|
40
|
+
], User.prototype, "email", void 0);
|
|
41
|
+
__decorate([
|
|
42
|
+
(0, default_1.default)(18),
|
|
43
|
+
__metadata("design:type", Object)
|
|
44
|
+
], User.prototype, "age", void 0);
|
|
45
|
+
__decorate([
|
|
46
|
+
(0, created_at_1.default)(),
|
|
47
|
+
__metadata("design:type", Object)
|
|
48
|
+
], User.prototype, "created_at", void 0);
|
|
49
|
+
__decorate([
|
|
50
|
+
(0, updated_at_1.default)(),
|
|
51
|
+
__metadata("design:type", Object)
|
|
52
|
+
], User.prototype, "updated_at", void 0);
|
|
53
|
+
// =============================================================================
|
|
54
|
+
// CONFIGURACIÓN DE CLIENTE PARA TESTS DE INSTANCIA
|
|
55
|
+
// =============================================================================
|
|
56
|
+
const client = new client_1.Dynamite({
|
|
57
|
+
region: "local",
|
|
58
|
+
endpoint: "http://localhost:8000",
|
|
59
|
+
credentials: { accessKeyId: "x", secretAccessKey: "x" },
|
|
60
|
+
tables: [User],
|
|
61
|
+
});
|
|
62
|
+
// =============================================================================
|
|
63
|
+
// SUITE DE TESTS DE INSTANCIA
|
|
64
|
+
// =============================================================================
|
|
65
|
+
describe("🔧 Instance Methods", () => {
|
|
66
|
+
jest.setTimeout(30_000);
|
|
67
|
+
beforeAll(async () => {
|
|
68
|
+
await client.sync();
|
|
69
|
+
client.connect();
|
|
70
|
+
});
|
|
71
|
+
afterEach(async () => {
|
|
72
|
+
// Limpieza después de cada test
|
|
73
|
+
try {
|
|
74
|
+
await User.destroy("inst1");
|
|
75
|
+
await User.destroy("inst2");
|
|
76
|
+
await User.destroy("inst3");
|
|
77
|
+
}
|
|
78
|
+
catch (e) {
|
|
79
|
+
// Ignorar errores de limpieza
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
afterAll(() => {
|
|
83
|
+
// Limpiar interval para evitar warning de Jest
|
|
84
|
+
(0, relations_1.stopCleanupInterval)();
|
|
85
|
+
});
|
|
86
|
+
// ===========================================================================
|
|
87
|
+
// TESTS SAVE()
|
|
88
|
+
// ===========================================================================
|
|
89
|
+
describe("save()", () => {
|
|
90
|
+
it("crea nuevo registro", async () => {
|
|
91
|
+
const user = new User({ id: "inst1", email: "save@test.com", age: 25 });
|
|
92
|
+
await user.save();
|
|
93
|
+
const found = await User.where("id", "inst1");
|
|
94
|
+
expect(found).toHaveLength(1);
|
|
95
|
+
expect(found[0].email).toBe("save@test.com");
|
|
96
|
+
expect(found[0].age).toBe(25);
|
|
97
|
+
});
|
|
98
|
+
it("actualiza registro existente", async () => {
|
|
99
|
+
// Crear registro inicial
|
|
100
|
+
await User.create({ id: "inst1", email: "initial@test.com", age: 20 });
|
|
101
|
+
// Modificar y guardar
|
|
102
|
+
const user = new User({ id: "inst1", email: "updated@test.com", age: 30 });
|
|
103
|
+
await user.save();
|
|
104
|
+
const found = await User.where("id", "inst1");
|
|
105
|
+
expect(found).toHaveLength(1);
|
|
106
|
+
expect(found[0].email).toBe("updated@test.com");
|
|
107
|
+
expect(found[0].age).toBe(30);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
// ===========================================================================
|
|
111
|
+
// TESTS UPDATE()
|
|
112
|
+
// ===========================================================================
|
|
113
|
+
describe("update()", () => {
|
|
114
|
+
it("modifica registro existente", async () => {
|
|
115
|
+
const user = new User({ id: "inst1", email: "original@test.com", age: 25 });
|
|
116
|
+
await user.save();
|
|
117
|
+
await user.update({ email: "modified@test.com" });
|
|
118
|
+
const found = await User.where("id", "inst1");
|
|
119
|
+
expect(found[0].email).toBe("modified@test.com");
|
|
120
|
+
expect(found[0].age).toBe(25); // No cambió
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
// ===========================================================================
|
|
124
|
+
// TESTS DESTROY()
|
|
125
|
+
// ===========================================================================
|
|
126
|
+
describe("destroy()", () => {
|
|
127
|
+
it("elimina instancia", async () => {
|
|
128
|
+
const user = new User({ id: "inst1", email: "delete@test.com", age: 25 });
|
|
129
|
+
await user.save();
|
|
130
|
+
await user.destroy();
|
|
131
|
+
const found = await User.where("id", "inst1");
|
|
132
|
+
expect(found).toHaveLength(0);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
// ===========================================================================
|
|
136
|
+
// TESTS TIMESTAMPS AUTOMÁTICOS
|
|
137
|
+
// ===========================================================================
|
|
138
|
+
describe("timestamps automáticos", () => {
|
|
139
|
+
it("asigna created_at y updated_at automáticamente", async () => {
|
|
140
|
+
const user = new User({ id: "inst1", email: "time@test.com", age: 25 });
|
|
141
|
+
expect(user.created_at).toMatch(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/);
|
|
142
|
+
expect(user.updated_at).toMatch(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/);
|
|
143
|
+
const originalUpdated = user.updated_at;
|
|
144
|
+
// Simular pausa y actualizar updated_at directamente (comportamiento real del decorador)
|
|
145
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
146
|
+
user.updated_at = "trigger"; // Trigger del decorador @UpdatedAt
|
|
147
|
+
expect(user.updated_at).not.toBe(originalUpdated);
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
// ===========================================================================
|
|
151
|
+
// TESTS MÚLTIPLES INSTANCIAS
|
|
152
|
+
// ===========================================================================
|
|
153
|
+
describe("múltiples instancias independientes", () => {
|
|
154
|
+
it("maneja múltiples instancias sin conflictos", async () => {
|
|
155
|
+
const user1 = new User({ id: "inst1", email: "user1@test.com", age: 20 });
|
|
156
|
+
const user2 = new User({ id: "inst2", email: "user2@test.com", age: 30 });
|
|
157
|
+
const user3 = new User({ id: "inst3", email: "user3@test.com", age: 40 });
|
|
158
|
+
await Promise.all([user1.save(), user2.save(), user3.save()]);
|
|
159
|
+
const found = await User.where({});
|
|
160
|
+
expect(found.length).toBeGreaterThanOrEqual(3);
|
|
161
|
+
const emails = found.map(u => u.email);
|
|
162
|
+
expect(emails).toContain("user1@test.com");
|
|
163
|
+
expect(emails).toContain("user2@test.com");
|
|
164
|
+
expect(emails).toContain("user3@test.com");
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
// ===========================================================================
|
|
168
|
+
// TESTS SERIALIZACIÓN
|
|
169
|
+
// ===========================================================================
|
|
170
|
+
describe("serialización", () => {
|
|
171
|
+
it("toJSON() serializa solo campos con decoradores", () => {
|
|
172
|
+
const user = new User({ id: "inst1", email: "json@test.com", age: 25 });
|
|
173
|
+
user.extraField = "no debería aparecer";
|
|
174
|
+
const json = user.toJSON();
|
|
175
|
+
expect(json.id).toBe("inst1");
|
|
176
|
+
expect(json.email).toBe("json@test.com");
|
|
177
|
+
expect(json.age).toBe(25);
|
|
178
|
+
expect(json.created_at).toBeDefined();
|
|
179
|
+
expect(json.updated_at).toBeDefined();
|
|
180
|
+
expect(json.extraField).toBeUndefined();
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
//# sourceMappingURL=instance-crud.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instance-crud.spec.js","sourceRoot":"","sources":["../../__tests__/instance-crud.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
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 { DynamoDBClient, DynamoDBClientConfig } from "@aws-sdk/client-dynamodb";
|
|
8
|
+
/**
|
|
9
|
+
* Configuration for Dynamite client initialization
|
|
10
|
+
*/
|
|
11
|
+
export interface DynamiteConfig extends DynamoDBClientConfig {
|
|
12
|
+
tables: Array<new (...args: any[]) => any>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Centralized Dynamite client for managing DynamoDB connections and table synchronization
|
|
16
|
+
*/
|
|
17
|
+
export declare class Dynamite {
|
|
18
|
+
private client;
|
|
19
|
+
private tables;
|
|
20
|
+
private connected;
|
|
21
|
+
private synced;
|
|
22
|
+
/**
|
|
23
|
+
* Initialize Dynamite client with configuration
|
|
24
|
+
* @param config Dynamite client configuration
|
|
25
|
+
*/
|
|
26
|
+
constructor(config: DynamiteConfig);
|
|
27
|
+
/**
|
|
28
|
+
* Synchronize all declared tables and their GSIs
|
|
29
|
+
*/
|
|
30
|
+
sync(): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Connect the client for Table operations
|
|
33
|
+
*/
|
|
34
|
+
connect(): void;
|
|
35
|
+
/**
|
|
36
|
+
* Get the underlying DynamoDB client
|
|
37
|
+
*/
|
|
38
|
+
getClient(): DynamoDBClient;
|
|
39
|
+
/**
|
|
40
|
+
* Check if client is connected and tables are synced
|
|
41
|
+
*/
|
|
42
|
+
isReady(): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Disconnect and cleanup DynamoDB client
|
|
45
|
+
*/
|
|
46
|
+
disconnect(): void;
|
|
47
|
+
/**
|
|
48
|
+
* Create table with automatic GSI detection and creation
|
|
49
|
+
* @param ctor Table class constructor
|
|
50
|
+
*/
|
|
51
|
+
private createTableWithGSI;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Set global client for Table class operations
|
|
55
|
+
* @param client DynamoDB client instance
|
|
56
|
+
*/
|
|
57
|
+
export declare const setGlobalClient: (client: DynamoDBClient) => void;
|
|
58
|
+
/**
|
|
59
|
+
* Get global client for Table class operations
|
|
60
|
+
*/
|
|
61
|
+
export declare const getGlobalClient: () => DynamoDBClient;
|
|
62
|
+
/**
|
|
63
|
+
* Check if global client is available
|
|
64
|
+
*/
|
|
65
|
+
export declare const hasGlobalClient: () => boolean;
|
|
@@ -0,0 +1,152 @@
|
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.hasGlobalClient = exports.getGlobalClient = exports.setGlobalClient = exports.Dynamite = void 0;
|
|
13
|
+
const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
|
|
14
|
+
const wrapper_1 = __importDefault(require("./wrapper"));
|
|
15
|
+
/**
|
|
16
|
+
* Centralized Dynamite client for managing DynamoDB connections and table synchronization
|
|
17
|
+
*/
|
|
18
|
+
class Dynamite {
|
|
19
|
+
/**
|
|
20
|
+
* Initialize Dynamite client with configuration
|
|
21
|
+
* @param config Dynamite client configuration
|
|
22
|
+
*/
|
|
23
|
+
constructor(config) {
|
|
24
|
+
this.connected = false;
|
|
25
|
+
this.synced = false;
|
|
26
|
+
const { tables, ...clientConfig } = config;
|
|
27
|
+
this.client = new client_dynamodb_1.DynamoDBClient(clientConfig);
|
|
28
|
+
this.tables = tables;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Synchronize all declared tables and their GSIs
|
|
32
|
+
*/
|
|
33
|
+
async sync() {
|
|
34
|
+
if (this.synced && this.connected)
|
|
35
|
+
return;
|
|
36
|
+
await Promise.all(this.tables.map((table) => this.createTableWithGSI(table)));
|
|
37
|
+
this.synced = true;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Connect the client for Table operations
|
|
41
|
+
*/
|
|
42
|
+
connect() {
|
|
43
|
+
if (this.connected)
|
|
44
|
+
return;
|
|
45
|
+
(0, exports.setGlobalClient)(this.client);
|
|
46
|
+
this.connected = true;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Get the underlying DynamoDB client
|
|
50
|
+
*/
|
|
51
|
+
getClient() {
|
|
52
|
+
return this.client;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Check if client is connected and tables are synced
|
|
56
|
+
*/
|
|
57
|
+
isReady() {
|
|
58
|
+
return this.connected && this.synced;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Disconnect and cleanup DynamoDB client
|
|
62
|
+
*/
|
|
63
|
+
disconnect() {
|
|
64
|
+
try {
|
|
65
|
+
this.client.destroy();
|
|
66
|
+
this.connected = false;
|
|
67
|
+
this.synced = false;
|
|
68
|
+
if (globalClient === this.client)
|
|
69
|
+
globalClient = undefined;
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
console.warn("Error during Dynamite disconnect:", error);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Create table with automatic GSI detection and creation
|
|
77
|
+
* @param ctor Table class constructor
|
|
78
|
+
*/
|
|
79
|
+
async createTableWithGSI(ctor) {
|
|
80
|
+
const meta = wrapper_1.default.get(ctor);
|
|
81
|
+
if (!meta)
|
|
82
|
+
throw new Error(`Class ${ctor.name} not registered in wrapper`);
|
|
83
|
+
const cols = [...meta.columns.values()];
|
|
84
|
+
const pk = cols.find((c) => c.index);
|
|
85
|
+
if (!pk)
|
|
86
|
+
throw new Error(`PartitionKey missing in ${ctor.name}`);
|
|
87
|
+
const sk = cols.find((c) => c.indexSort);
|
|
88
|
+
const attr = new Map();
|
|
89
|
+
attr.set(pk.name, "S");
|
|
90
|
+
if (sk)
|
|
91
|
+
attr.set(sk.name, "S");
|
|
92
|
+
let gsiIndex = 1;
|
|
93
|
+
const gsiDefinitions = [...meta.relations.values()]
|
|
94
|
+
.filter((relation) => relation.type === "hasMany")
|
|
95
|
+
.map((relation) => {
|
|
96
|
+
const { foreignKey } = relation;
|
|
97
|
+
if (!attr.has(foreignKey))
|
|
98
|
+
attr.set(foreignKey, "S");
|
|
99
|
+
return {
|
|
100
|
+
IndexName: `GSI${gsiIndex++}_${foreignKey}`,
|
|
101
|
+
KeySchema: [{ AttributeName: foreignKey, KeyType: "HASH" }],
|
|
102
|
+
Projection: { ProjectionType: "ALL" },
|
|
103
|
+
};
|
|
104
|
+
});
|
|
105
|
+
const schema = [{ AttributeName: pk.name, KeyType: "HASH" }];
|
|
106
|
+
if (sk && sk.name !== pk.name)
|
|
107
|
+
schema.push({ AttributeName: sk.name, KeyType: "RANGE" });
|
|
108
|
+
try {
|
|
109
|
+
await this.client.send(new client_dynamodb_1.CreateTableCommand({
|
|
110
|
+
TableName: meta.name,
|
|
111
|
+
BillingMode: "PAY_PER_REQUEST",
|
|
112
|
+
AttributeDefinitions: [...attr].map(([AttributeName, AttributeType]) => ({
|
|
113
|
+
AttributeName,
|
|
114
|
+
AttributeType,
|
|
115
|
+
})),
|
|
116
|
+
KeySchema: schema,
|
|
117
|
+
...(gsiDefinitions.length > 0 && {
|
|
118
|
+
GlobalSecondaryIndexes: gsiDefinitions,
|
|
119
|
+
}),
|
|
120
|
+
}));
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
if (error.name !== "ResourceInUseException")
|
|
124
|
+
throw error;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
exports.Dynamite = Dynamite;
|
|
129
|
+
let globalClient;
|
|
130
|
+
/**
|
|
131
|
+
* Set global client for Table class operations
|
|
132
|
+
* @param client DynamoDB client instance
|
|
133
|
+
*/
|
|
134
|
+
const setGlobalClient = (client) => {
|
|
135
|
+
globalClient = client;
|
|
136
|
+
};
|
|
137
|
+
exports.setGlobalClient = setGlobalClient;
|
|
138
|
+
/**
|
|
139
|
+
* Get global client for Table class operations
|
|
140
|
+
*/
|
|
141
|
+
const getGlobalClient = () => {
|
|
142
|
+
if (!globalClient)
|
|
143
|
+
throw new Error("No global DynamoDB client set. Call setGlobalClient() first.");
|
|
144
|
+
return globalClient;
|
|
145
|
+
};
|
|
146
|
+
exports.getGlobalClient = getGlobalClient;
|
|
147
|
+
/**
|
|
148
|
+
* Check if global client is available
|
|
149
|
+
*/
|
|
150
|
+
const hasGlobalClient = () => globalClient !== undefined;
|
|
151
|
+
exports.hasGlobalClient = hasGlobalClient;
|
|
152
|
+
//# 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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"}
|