@arcaelas/dynamite 1.0.17 → 1.0.19

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 (67) hide show
  1. package/package.json +40 -2
  2. package/src/@types/index.d.ts +116 -75
  3. package/src/core/client.d.ts +36 -0
  4. package/src/core/client.js +80 -27
  5. package/src/core/decorator.d.ts +44 -0
  6. package/src/core/decorator.js +133 -0
  7. package/src/core/method.d.ts +73 -0
  8. package/src/core/method.js +140 -0
  9. package/src/core/table.d.ts +44 -86
  10. package/src/core/table.js +510 -310
  11. package/src/decorators/indexes.d.ts +38 -0
  12. package/src/decorators/indexes.js +67 -0
  13. package/src/decorators/relations.d.ts +55 -0
  14. package/src/decorators/relations.js +84 -0
  15. package/src/decorators/timestamps.d.ts +54 -0
  16. package/src/decorators/timestamps.js +67 -0
  17. package/src/decorators/transforms.d.ts +86 -0
  18. package/src/decorators/transforms.js +154 -0
  19. package/src/index.d.ts +10 -16
  20. package/src/index.js +50 -32
  21. package/src/index.test.d.ts +13 -0
  22. package/src/index.test.js +1992 -0
  23. package/src/utils/relations.d.ts +34 -12
  24. package/src/utils/relations.js +109 -133
  25. package/src/@types/index.js +0 -9
  26. package/src/core/wrapper.d.ts +0 -17
  27. package/src/core/wrapper.js +0 -46
  28. package/src/decorators/belongs_to.d.ts +0 -1
  29. package/src/decorators/belongs_to.js +0 -24
  30. package/src/decorators/created_at.d.ts +0 -1
  31. package/src/decorators/created_at.js +0 -11
  32. package/src/decorators/default.d.ts +0 -1
  33. package/src/decorators/default.js +0 -47
  34. package/src/decorators/has_many.d.ts +0 -1
  35. package/src/decorators/has_many.js +0 -24
  36. package/src/decorators/index.d.ts +0 -11
  37. package/src/decorators/index.js +0 -36
  38. package/src/decorators/index_sort.d.ts +0 -12
  39. package/src/decorators/index_sort.js +0 -43
  40. package/src/decorators/mutate.d.ts +0 -2
  41. package/src/decorators/mutate.js +0 -51
  42. package/src/decorators/name.d.ts +0 -1
  43. package/src/decorators/name.js +0 -28
  44. package/src/decorators/not_null.d.ts +0 -1
  45. package/src/decorators/not_null.js +0 -13
  46. package/src/decorators/primary_key.d.ts +0 -6
  47. package/src/decorators/primary_key.js +0 -30
  48. package/src/decorators/updated_at.d.ts +0 -12
  49. package/src/decorators/updated_at.js +0 -26
  50. package/src/decorators/validate.d.ts +0 -1
  51. package/src/decorators/validate.js +0 -53
  52. package/src/utils/batch-relations.d.ts +0 -14
  53. package/src/utils/batch-relations.js +0 -131
  54. package/src/utils/circular-detector.d.ts +0 -82
  55. package/src/utils/circular-detector.js +0 -212
  56. package/src/utils/memory-manager.d.ts +0 -42
  57. package/src/utils/memory-manager.js +0 -107
  58. package/src/utils/naming.d.ts +0 -8
  59. package/src/utils/naming.js +0 -18
  60. package/src/utils/projection.d.ts +0 -12
  61. package/src/utils/projection.js +0 -51
  62. package/src/utils/security-validator.d.ts +0 -49
  63. package/src/utils/security-validator.js +0 -163
  64. package/src/utils/throttle-manager.d.ts +0 -78
  65. package/src/utils/throttle-manager.js +0 -201
  66. package/src/utils/transaction-manager.d.ts +0 -88
  67. package/src/utils/transaction-manager.js +0 -300
@@ -1,17 +1,39 @@
1
1
  /**
2
2
  * @file relations.ts
3
- * @descripcion Sistema de relaciones optimizado
3
+ * @description Sistema de carga de relaciones con batch loading
4
4
  * @autor Miguel Alejandro
5
5
  * @fecha 2025-01-28
6
6
  */
7
- /** Decorador @hasMany para relaciones 1:N */
8
- export declare const hasMany: (targetModel: () => any, foreignKey: string, localKey?: string) => (target: any, propertyKey: string) => void;
9
- /** Decorador @belongsTo para relaciones N:1 */
10
- export declare const belongsTo: (targetModel: () => any, localKey: string, foreignKey?: string) => (target: any, propertyKey: string) => void;
11
- /** Procesamiento optimizado de includes con batch loading transparente */
12
- export declare const processIncludes: (Model: any, items: any[], include: Record<string, any>, depth?: number) => Promise<any[]>;
13
- /** Separar opciones de query e include */
14
- export declare const separateQueryOptions: (options: Record<string, any>) => {
15
- queryOptions: Record<string, any>;
16
- includeOptions: Record<string, any> | undefined;
17
- };
7
+ /**
8
+ * @description Opciones para include de relaciones
9
+ */
10
+ interface IncludeOptions {
11
+ where?: Record<string, any>;
12
+ limit?: number;
13
+ offset?: number;
14
+ order?: 'asc' | 'desc';
15
+ include?: Record<string, IncludeOptions | boolean>;
16
+ }
17
+ /**
18
+ * @description Procesa includes recursivamente para cargar relaciones
19
+ * @param items Array de instancias a poblar
20
+ * @param include Objeto con relaciones a incluir
21
+ * @param TableClass Clase de la tabla actual
22
+ * @param depth Profundidad actual (máximo 10)
23
+ * @returns Items con relaciones pobladas
24
+ * @example
25
+ * ```typescript
26
+ * // Uso interno en Table.where()
27
+ * await processIncludes(users, {
28
+ * posts: {
29
+ * where: { published: true },
30
+ * limit: 5,
31
+ * include: {
32
+ * comments: true
33
+ * }
34
+ * }
35
+ * }, User);
36
+ * ```
37
+ */
38
+ export declare const processIncludes: (items: any[], include: Record<string, IncludeOptions | boolean>, TableClass: any, depth?: number) => Promise<any[]>;
39
+ export {};
@@ -1,165 +1,141 @@
1
1
  "use strict";
2
2
  /**
3
3
  * @file relations.ts
4
- * @descripcion Sistema de relaciones optimizado
4
+ * @description Sistema de carga de relaciones con batch loading
5
5
  * @autor Miguel Alejandro
6
6
  * @fecha 2025-01-28
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.separateQueryOptions = exports.processIncludes = exports.belongsTo = exports.hasMany = void 0;
10
- const wrapper_1 = require("../core/wrapper");
11
- const naming_1 = require("./naming");
12
- // =============================================================================
13
- // DECORATORS
14
- // =============================================================================
15
- /** Decorador @hasMany para relaciones 1:N */
16
- const hasMany = (targetModel, foreignKey, localKey = "id") => (target, propertyKey) => {
17
- (0, wrapper_1.ensureConfig)(target.constructor, (0, naming_1.toSnakePlural)(target.constructor.name)).relations.set(propertyKey, {
18
- type: "hasMany",
19
- targetModel,
20
- foreignKey,
21
- localKey,
22
- });
23
- Object.defineProperty(target, propertyKey, {
24
- get() {
25
- const cached = this[`_${propertyKey}`];
26
- return cached !== undefined
27
- ? cached
28
- : (console.warn(`Relación ${propertyKey} no cargada. Use includes en la consulta.`),
29
- []);
30
- },
31
- configurable: true,
32
- enumerable: false,
33
- });
34
- };
35
- exports.hasMany = hasMany;
36
- /** Decorador @belongsTo para relaciones N:1 */
37
- const belongsTo = (targetModel, localKey, foreignKey = "id") => (target, propertyKey) => {
38
- (0, wrapper_1.ensureConfig)(target.constructor, (0, naming_1.toSnakePlural)(target.constructor.name)).relations.set(propertyKey, {
39
- type: "belongsTo",
40
- targetModel,
41
- localKey,
42
- foreignKey,
43
- });
44
- Object.defineProperty(target, propertyKey, {
45
- get() {
46
- const cached = this[`_${propertyKey}`];
47
- return cached !== undefined
48
- ? cached
49
- : (console.warn(`Relación ${propertyKey} no cargada. Use includes en la consulta.`),
50
- null);
51
- },
52
- configurable: true,
53
- enumerable: false,
54
- });
55
- };
56
- exports.belongsTo = belongsTo;
57
- // =============================================================================
58
- // FUNCTIONS
59
- // =============================================================================
60
- /** Batch loading para relaciones hasMany */
61
- const batchLoadHasMany = async (Model, items, relation, options = {}) => {
62
- const { targetModel, foreignKey, localKey = "id" } = relation;
63
- const parent_keys = items.map((item) => item[localKey]).filter(Boolean);
64
- if (!parent_keys.length)
9
+ exports.processIncludes = void 0;
10
+ const decorator_1 = require("../core/decorator");
11
+ /**
12
+ * @description Batch load para HasMany/HasOne
13
+ * Obtiene items relacionados donde foreignKey IN parent_ids
14
+ */
15
+ const batchLoadHasMany = async (items, relation, options = {}) => {
16
+ const parent_ids = items.map(i => i[relation.localKey]).filter(Boolean);
17
+ if (!parent_ids.length)
65
18
  return new Map();
66
- // Build query with relation options
67
- let query = targetModel().where(foreignKey, "in", parent_keys);
68
- // Apply additional filters if specified
19
+ // Obtener clase del modelo relacionado
20
+ const RelatedModel = relation.model();
21
+ // Query básico
22
+ let related = await RelatedModel.where(relation.foreignKey, 'in', parent_ids);
23
+ // Aplicar filtros adicionales
69
24
  if (options.where) {
70
- const additionalFilters = Object.entries(options.where);
71
- for (const [key, value] of additionalFilters) {
72
- const currentResults = await query;
73
- query = Promise.resolve(currentResults.filter((item) => item[key] === value));
74
- }
25
+ related = related.filter((item) => Object.entries(options.where).every(([k, v]) => item[k] === v));
75
26
  }
76
- const related_items = await query;
77
- // TODO: Apply attributes selection
78
- // For now, skip attributes filtering to ensure basic relations work
79
- let processedItems = related_items;
80
- // Apply other options like limit, order
81
- let filteredItems = processedItems;
82
- if (options.order === "DESC") {
83
- filteredItems.sort((a, b) => b.id.localeCompare(a.id));
27
+ // Ordenar
28
+ if (options.order) {
29
+ related.sort((a, b) => {
30
+ const aId = String(a.id ?? '');
31
+ const bId = String(b.id ?? '');
32
+ return options.order === 'asc' ? aId.localeCompare(bId) : bId.localeCompare(aId);
33
+ });
84
34
  }
85
- else if (options.order === "ASC") {
86
- filteredItems.sort((a, b) => a.id.localeCompare(b.id));
35
+ // Agrupar por foreignKey
36
+ const grouped = new Map();
37
+ for (const item of related) {
38
+ const key = String(item[relation.foreignKey]);
39
+ if (!grouped.has(key))
40
+ grouped.set(key, []);
41
+ grouped.get(key).push(item);
87
42
  }
43
+ // Aplicar limit por grupo
88
44
  if (options.limit) {
89
- filteredItems = filteredItems.slice(0, options.limit);
45
+ for (const [key, groupItems] of grouped) {
46
+ grouped.set(key, groupItems.slice(options.offset ?? 0, (options.offset ?? 0) + options.limit));
47
+ }
90
48
  }
91
- const grouped = new Map();
92
- filteredItems.forEach((item) => {
93
- const key = item[foreignKey];
94
- grouped.has(key) ? grouped.get(key).push(item) : grouped.set(key, [item]);
95
- });
96
49
  return grouped;
97
50
  };
98
- /** Batch loading para relaciones belongsTo */
99
- const batchLoadBelongsTo = async (Model, items, relation, options = {}) => {
100
- const { targetModel, localKey, foreignKey = "id" } = relation;
101
- // Para BelongsTo: obtener valores de localKey (ej: category_id) de los items
102
- const keys = items
103
- .map((item) => (localKey ? item[localKey] : null))
104
- .filter(Boolean);
105
- if (!keys.length)
51
+ /**
52
+ * @description Batch load para BelongsTo
53
+ * Obtiene items donde id IN local_keys
54
+ */
55
+ const batchLoadBelongsTo = async (items, relation, _options = {}) => {
56
+ const local_keys = items.map(i => i[relation.localKey]).filter(Boolean);
57
+ if (!local_keys.length)
106
58
  return new Map();
107
- // Buscar en targetModel donde foreignKey (ej: id) esté en los keys
108
- const fetched_items = await targetModel().where(foreignKey, "in", keys);
109
- // TODO: Apply attributes selection
110
- // For now, skip attributes filtering to ensure basic relations work
111
- let processedItems = fetched_items;
112
- const results = new Map();
113
- // Mapear por foreignKey para que coincida con localKey de los items
114
- processedItems.forEach((item) => results.set(item[foreignKey], item));
115
- return results;
59
+ const RelatedModel = relation.model();
60
+ const related = await RelatedModel.where(relation.foreignKey, 'in', local_keys);
61
+ const result = new Map();
62
+ for (const item of related) {
63
+ result.set(String(item[relation.foreignKey]), item);
64
+ }
65
+ return result;
116
66
  };
117
- /** Procesamiento optimizado de includes con batch loading transparente */
118
- const processIncludes = async (Model, items, include, depth = 0) => {
67
+ /**
68
+ * @description Procesa includes recursivamente para cargar relaciones
69
+ * @param items Array de instancias a poblar
70
+ * @param include Objeto con relaciones a incluir
71
+ * @param TableClass Clase de la tabla actual
72
+ * @param depth Profundidad actual (máximo 10)
73
+ * @returns Items con relaciones pobladas
74
+ * @example
75
+ * ```typescript
76
+ * // Uso interno en Table.where()
77
+ * await processIncludes(users, {
78
+ * posts: {
79
+ * where: { published: true },
80
+ * limit: 5,
81
+ * include: {
82
+ * comments: true
83
+ * }
84
+ * }
85
+ * }, User);
86
+ * ```
87
+ */
88
+ const processIncludes = async (items, include, TableClass, depth = 0) => {
119
89
  if (!include || depth > 10 || !items.length)
120
90
  return items;
121
- const meta = (0, wrapper_1.mustMeta)(Model);
122
- const relation_promises = Object.entries(include).map(async ([relation_key, relation_options]) => {
123
- const relation = meta.relations.get(relation_key);
124
- if (!relation)
91
+ const schema = TableClass[decorator_1.SCHEMA];
92
+ if (!schema)
93
+ return items;
94
+ const promises = Object.entries(include).map(async ([relation_key, options]) => {
95
+ const column = schema.columns[relation_key];
96
+ if (!column?.store?.relation)
125
97
  return;
126
- const related_data = relation.type === "hasMany"
127
- ? await batchLoadHasMany(Model, items, relation, relation_options)
128
- : await batchLoadBelongsTo(Model, items, relation, relation_options);
129
- items.forEach((item) => {
130
- let key;
131
- if (relation.type === "hasMany") {
132
- // Para HasMany: usar localKey (ej: "id") del item actual
133
- key = item[relation.localKey || "id"];
134
- }
135
- else {
136
- // Para BelongsTo: usar localKey (ej: "category_id") del item actual
137
- key = relation.localKey ? item[relation.localKey] : null;
98
+ const relation = column.store.relation;
99
+ const opts = typeof options === 'boolean' ? {} : options;
100
+ // Batch load según tipo
101
+ let data;
102
+ if (relation.type === 'HasMany') {
103
+ data = await batchLoadHasMany(items, relation, opts);
104
+ }
105
+ else if (relation.type === 'HasOne') {
106
+ const hasMany = await batchLoadHasMany(items, relation, { ...opts, limit: 1 });
107
+ data = new Map();
108
+ for (const [k, v] of hasMany) {
109
+ data.set(k, v[0] ?? null);
138
110
  }
139
- const related = related_data.get(key);
140
- // Usar una propiedad temporal para evitar conflictos con getters
111
+ }
112
+ else {
113
+ // BelongsTo
114
+ data = await batchLoadBelongsTo(items, relation, opts);
115
+ }
116
+ // Asignar datos relacionados a cada item
117
+ for (const item of items) {
118
+ const key = String(item[relation.localKey]);
119
+ const value = relation.type === 'HasMany'
120
+ ? data.get(key) ?? []
121
+ : data.get(key) ?? null;
141
122
  Object.defineProperty(item, relation_key, {
142
- value: relation.type === "hasMany" ? related || [] : related || null,
123
+ value,
143
124
  writable: true,
144
125
  enumerable: true,
145
- configurable: true,
126
+ configurable: true
146
127
  });
147
- });
148
- if (relation_options?.include && related_data.size) {
149
- const all_related = Array.from(related_data.values())
150
- .flat()
151
- .filter(Boolean);
152
- await (0, exports.processIncludes)(relation.targetModel(), all_related, relation_options.include, depth + 1);
128
+ }
129
+ // Recursión para includes anidados
130
+ if (opts.include && data.size) {
131
+ const all_related = Array.from(data.values()).flat().filter(Boolean);
132
+ if (all_related.length) {
133
+ await (0, exports.processIncludes)(all_related, opts.include, relation.model(), depth + 1);
134
+ }
153
135
  }
154
136
  });
155
- await Promise.all(relation_promises);
137
+ await Promise.all(promises);
156
138
  return items;
157
139
  };
158
140
  exports.processIncludes = processIncludes;
159
- /** Separar opciones de query e include */
160
- const separateQueryOptions = (options) => {
161
- const { include, ...queryOptions } = options;
162
- return { queryOptions, includeOptions: include };
163
- };
164
- exports.separateQueryOptions = separateQueryOptions;
165
141
  //# sourceMappingURL=relations.js.map
@@ -1,9 +0,0 @@
1
- "use strict";
2
- /*
3
- @file index.ts
4
- @descripcion Tipos públicos de Dynamite ORM
5
- @autor Miguel Alejandro
6
- @fecha 2025-08-07
7
- */
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- //# sourceMappingURL=index.js.map
@@ -1,17 +0,0 @@
1
- /**
2
- * @file wrapper.ts
3
- * @descripcion Sistema de tipos y wrapper optimizado
4
- * @autor Miguel Alejandro
5
- * @fecha 2025-01-28
6
- */
7
- import type { Column, WrapperEntry } from "../@types/index";
8
- export type { BelongsTo, Column, CreationOptional, FilterableAttributes, HasMany, IncludeOptions, IncludeRelationOptions, InferAttributes, Mutate, NonAttribute, QueryOperator, QueryResult, Validate, WhereOptions, WhereOptionsWithoutWhere, WhereQueryOptions, WrapperEntry, } from "../@types/index";
9
- export declare const STORE: unique symbol;
10
- declare const wrapper: Map<Function, WrapperEntry>;
11
- /** Obtener o crear entrada wrapper para constructor */
12
- export declare const ensureConfig: (ctor: Function, table_name: string) => WrapperEntry;
13
- /** Obtener o crear configuración de columna para propiedad */
14
- export declare const ensureColumn: (entry: WrapperEntry, prop: string | symbol, column_name: string) => Column;
15
- /** Obtener metadatos requeridos (throws si no existen) */
16
- export declare const mustMeta: (ctor: Function) => WrapperEntry;
17
- export default wrapper;
@@ -1,46 +0,0 @@
1
- "use strict";
2
- /**
3
- * @file wrapper.ts
4
- * @descripcion Sistema de tipos y wrapper optimizado
5
- * @autor Miguel Alejandro
6
- * @fecha 2025-01-28
7
- */
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.mustMeta = exports.ensureColumn = exports.ensureConfig = exports.STORE = void 0;
10
- exports.STORE = Symbol("dynamite:values");
11
- const wrapper = new Map();
12
- /** Obtener o crear entrada wrapper para constructor */
13
- const ensureConfig = (ctor, table_name) => {
14
- const existing = wrapper.get(ctor);
15
- if (existing)
16
- return existing;
17
- const entry = {
18
- name: table_name,
19
- columns: new Map(),
20
- relations: new Map(),
21
- };
22
- wrapper.set(ctor, entry);
23
- return entry;
24
- };
25
- exports.ensureConfig = ensureConfig;
26
- /** Obtener o crear configuración de columna para propiedad */
27
- const ensureColumn = (entry, prop, column_name) => {
28
- const existing = entry.columns.get(prop);
29
- if (existing)
30
- return existing;
31
- const column = { name: column_name, mutate: [], validate: [] };
32
- entry.columns.set(prop, column);
33
- return column;
34
- };
35
- exports.ensureColumn = ensureColumn;
36
- /** Obtener metadatos requeridos (throws si no existen) */
37
- const mustMeta = (ctor) => {
38
- const meta = wrapper.get(ctor);
39
- if (!meta) {
40
- throw new Error(`Metadatos no encontrados para ${ctor.name}. ¿Usaste decoradores @Index, @PrimaryKey, etc.?`);
41
- }
42
- return meta;
43
- };
44
- exports.mustMeta = mustMeta;
45
- exports.default = wrapper;
46
- //# sourceMappingURL=wrapper.js.map
@@ -1 +0,0 @@
1
- export default function BelongsTo(targetModel: () => any, localKey: string, foreignKey?: string): PropertyDecorator;
@@ -1,24 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.default = BelongsTo;
4
- const wrapper_1 = require("../core/wrapper");
5
- function BelongsTo(targetModel, localKey, foreignKey) {
6
- return (target, prop) => {
7
- const entry = (0, wrapper_1.ensureConfig)(target.constructor, target.constructor.name);
8
- entry.relations.set(prop, {
9
- type: "belongsTo",
10
- targetModel,
11
- foreignKey: foreignKey || "id",
12
- localKey,
13
- });
14
- // Crear getter dinámico para la relación
15
- Object.defineProperty(target, prop, {
16
- get() {
17
- return this[`_${prop.toString()}`] || null;
18
- },
19
- enumerable: true,
20
- configurable: true,
21
- });
22
- };
23
- }
24
- //# sourceMappingURL=belongs_to.js.map
@@ -1 +0,0 @@
1
- export default function CreatedAt(): PropertyDecorator;
@@ -1,11 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.default = CreatedAt;
7
- const default_1 = __importDefault(require("./default"));
8
- function CreatedAt() {
9
- return (0, default_1.default)(() => new Date().toISOString());
10
- }
11
- //# sourceMappingURL=created_at.js.map
@@ -1 +0,0 @@
1
- export default function Default(factory: any): PropertyDecorator;
@@ -1,47 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.default = Default;
4
- const wrapper_1 = require("../core/wrapper");
5
- const naming_1 = require("../utils/naming");
6
- function Default(factory) {
7
- return (target, prop) => {
8
- const ctor = target.constructor;
9
- const entry = (0, wrapper_1.ensureConfig)(ctor, (0, naming_1.toSnakePlural)(ctor.name));
10
- const column = (0, wrapper_1.ensureColumn)(entry, prop, String(prop));
11
- if (column.default)
12
- throw new Error(`@Default duplicado en '${String(prop)}'`);
13
- column.default = typeof factory === "function" ? factory : () => factory;
14
- !Object.getOwnPropertyDescriptor(ctor.prototype, prop)?.set &&
15
- defineVirtual(ctor.prototype, column, prop);
16
- };
17
- }
18
- function defineVirtual(proto, col, prop) {
19
- Object.defineProperty(proto, prop, {
20
- get() {
21
- return (this[wrapper_1.STORE] ?? {})[prop];
22
- },
23
- set(val) {
24
- const buf = (this[wrapper_1.STORE] ??= {});
25
- val =
26
- val === undefined && col.default !== undefined
27
- ? typeof col.default === "function"
28
- ? col.default()
29
- : col.default
30
- : val;
31
- if (col.mutate)
32
- for (const m of col.mutate)
33
- val = m(val);
34
- if (col.validate) {
35
- for (const v of col.validate) {
36
- const r = v(val);
37
- if (r !== true)
38
- throw new Error(typeof r === "string" ? r : "Validación fallida");
39
- }
40
- }
41
- buf[prop] = val;
42
- },
43
- enumerable: true,
44
- configurable: true,
45
- });
46
- }
47
- //# sourceMappingURL=default.js.map
@@ -1 +0,0 @@
1
- export default function HasMany(targetModel: () => any, foreignKey: string, localKey?: string): PropertyDecorator;
@@ -1,24 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.default = HasMany;
4
- const wrapper_1 = require("../core/wrapper");
5
- function HasMany(targetModel, foreignKey, localKey) {
6
- return (target, prop) => {
7
- const entry = (0, wrapper_1.ensureConfig)(target.constructor, target.constructor.name);
8
- entry.relations.set(prop, {
9
- type: "hasMany",
10
- targetModel,
11
- foreignKey,
12
- localKey: localKey || "id",
13
- });
14
- // Crear getter dinámico para la relación
15
- Object.defineProperty(target, prop, {
16
- get() {
17
- return this[`_${prop.toString()}`] || [];
18
- },
19
- enumerable: true,
20
- configurable: true,
21
- });
22
- };
23
- }
24
- //# sourceMappingURL=has_many.js.map
@@ -1,11 +0,0 @@
1
- /**
2
- * @file index.ts
3
- * @descripcion Decorador @Index para Partition Key
4
- * @autor Miguel Alejandro
5
- * @fecha 2025-01-27
6
- */
7
- /**
8
- * Decorador para marcar propiedad como Partition Key.
9
- * Configura la propiedad como índice principal para consultas.
10
- */
11
- export default function Index(): PropertyDecorator;
@@ -1,36 +0,0 @@
1
- "use strict";
2
- /**
3
- * @file index.ts
4
- * @descripcion Decorador @Index para Partition Key
5
- * @autor Miguel Alejandro
6
- * @fecha 2025-01-27
7
- */
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.default = Index;
10
- const wrapper_1 = require("../core/wrapper");
11
- const naming_1 = require("../utils/naming");
12
- /**
13
- * Decorador para marcar propiedad como Partition Key.
14
- * Configura la propiedad como índice principal para consultas.
15
- */
16
- function Index() {
17
- return (target, prop) => {
18
- const ctor = target.constructor;
19
- const tableName = (0, naming_1.toSnakePlural)(ctor.name);
20
- const entry = (0, wrapper_1.ensureConfig)(ctor, tableName);
21
- // Verificar si ya existe un índice primario
22
- const existingIndex = [...entry.columns.values()].find((col) => col.index === true);
23
- if (existingIndex && existingIndex.name !== String(prop)) {
24
- throw new Error(`La tabla ${tableName} ya tiene definida una PartitionKey (${existingIndex.name}). ` +
25
- `No se puede definir otra PartitionKey en '${String(prop)}'`);
26
- }
27
- // Obtener o crear la columna y marcar como índice
28
- const column = (0, wrapper_1.ensureColumn)(entry, prop, String(prop));
29
- column.index = true;
30
- // Asegurar que la columna no sea nula por defecto
31
- if (column.nullable === undefined) {
32
- column.nullable = false;
33
- }
34
- };
35
- }
36
- //# sourceMappingURL=index.js.map
@@ -1,12 +0,0 @@
1
- /**
2
- * @file index_sort.ts
3
- * @descripcion Decorador @IndexSort para Sort Key
4
- * @autor Miguel Alejandro
5
- * @fecha 2025-01-27
6
- */
7
- /**
8
- * Decorador para marcar propiedad como Sort Key.
9
- * Configura la propiedad como clave de ordenación para consultas.
10
- * Requiere que exista una PartitionKey (@Index) definida previamente.
11
- */
12
- export default function IndexSort(): PropertyDecorator;
@@ -1,43 +0,0 @@
1
- "use strict";
2
- /**
3
- * @file index_sort.ts
4
- * @descripcion Decorador @IndexSort para Sort Key
5
- * @autor Miguel Alejandro
6
- * @fecha 2025-01-27
7
- */
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.default = IndexSort;
10
- const wrapper_1 = require("../core/wrapper");
11
- const naming_1 = require("../utils/naming");
12
- /**
13
- * Decorador para marcar propiedad como Sort Key.
14
- * Configura la propiedad como clave de ordenación para consultas.
15
- * Requiere que exista una PartitionKey (@Index) definida previamente.
16
- */
17
- function IndexSort() {
18
- return (target, prop) => {
19
- const ctor = target.constructor;
20
- const tableName = (0, naming_1.toSnakePlural)(ctor.name);
21
- const entry = (0, wrapper_1.ensureConfig)(ctor, tableName);
22
- // Verificar que exista una PartitionKey definida
23
- const hasPartitionKey = [...entry.columns.values()].some((col) => col.index === true);
24
- if (!hasPartitionKey) {
25
- throw new Error(`No se puede definir una SortKey en '${String(prop)}' sin una PartitionKey. ` +
26
- `Asegúrate de marcar una propiedad con @Index primero.`);
27
- }
28
- // Verificar si ya existe una SortKey
29
- const existingSortKey = [...entry.columns.values()].find((col) => col.indexSort === true);
30
- if (existingSortKey && existingSortKey.name !== String(prop)) {
31
- throw new Error(`La tabla ${tableName} ya tiene una SortKey definida (${existingSortKey.name}). ` +
32
- `No se puede definir otra SortKey en '${String(prop)}'`);
33
- }
34
- // Obtener o crear la columna y marcar como índice de ordenación
35
- const column = (0, wrapper_1.ensureColumn)(entry, prop, String(prop));
36
- column.indexSort = true;
37
- // Asegurar que la columna no sea nula por defecto
38
- if (column.nullable === undefined) {
39
- column.nullable = false;
40
- }
41
- };
42
- }
43
- //# sourceMappingURL=index_sort.js.map
@@ -1,2 +0,0 @@
1
- import type { Mutate } from "../core/wrapper";
2
- export default function Mutate(fn: Mutate): PropertyDecorator;