@carno.js/orm 0.2.3

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 (98) hide show
  1. package/LICENSE +674 -0
  2. package/dist/SqlBuilder.d.ts +103 -0
  3. package/dist/SqlBuilder.js +618 -0
  4. package/dist/cache/cache-key-generator.d.ts +13 -0
  5. package/dist/cache/cache-key-generator.js +66 -0
  6. package/dist/cache/query-cache-manager.d.ts +14 -0
  7. package/dist/cache/query-cache-manager.js +44 -0
  8. package/dist/common/email.vo.d.ts +4 -0
  9. package/dist/common/email.vo.js +11 -0
  10. package/dist/common/uuid.d.ts +4 -0
  11. package/dist/common/uuid.js +10 -0
  12. package/dist/common/value-object.d.ts +95 -0
  13. package/dist/common/value-object.js +99 -0
  14. package/dist/constants.d.ts +6 -0
  15. package/dist/constants.js +9 -0
  16. package/dist/decorators/computed.decorator.d.ts +1 -0
  17. package/dist/decorators/computed.decorator.js +12 -0
  18. package/dist/decorators/entity.decorator.d.ts +3 -0
  19. package/dist/decorators/entity.decorator.js +12 -0
  20. package/dist/decorators/enum.decorator.d.ts +2 -0
  21. package/dist/decorators/enum.decorator.js +16 -0
  22. package/dist/decorators/event-hook.decorator.d.ts +4 -0
  23. package/dist/decorators/event-hook.decorator.js +31 -0
  24. package/dist/decorators/index.decorator.d.ts +17 -0
  25. package/dist/decorators/index.decorator.js +36 -0
  26. package/dist/decorators/one-many.decorator.d.ts +6 -0
  27. package/dist/decorators/one-many.decorator.js +42 -0
  28. package/dist/decorators/primary-key.decorator.d.ts +2 -0
  29. package/dist/decorators/primary-key.decorator.js +8 -0
  30. package/dist/decorators/property.decorator.d.ts +24 -0
  31. package/dist/decorators/property.decorator.js +44 -0
  32. package/dist/decorators/unique.decorator.d.ts +9 -0
  33. package/dist/decorators/unique.decorator.js +44 -0
  34. package/dist/domain/base-entity.d.ts +57 -0
  35. package/dist/domain/base-entity.js +198 -0
  36. package/dist/domain/collection.d.ts +6 -0
  37. package/dist/domain/collection.js +15 -0
  38. package/dist/domain/entities.d.ts +49 -0
  39. package/dist/domain/entities.js +259 -0
  40. package/dist/domain/reference.d.ts +86 -0
  41. package/dist/domain/reference.js +86 -0
  42. package/dist/driver/bun-driver.base.d.ts +72 -0
  43. package/dist/driver/bun-driver.base.js +270 -0
  44. package/dist/driver/bun-mysql.driver.d.ts +53 -0
  45. package/dist/driver/bun-mysql.driver.js +256 -0
  46. package/dist/driver/bun-pg.driver.d.ts +52 -0
  47. package/dist/driver/bun-pg.driver.js +263 -0
  48. package/dist/driver/driver.interface.d.ts +333 -0
  49. package/dist/driver/driver.interface.js +2 -0
  50. package/dist/entry.d.ts +2 -0
  51. package/dist/entry.js +13 -0
  52. package/dist/identity-map/entity-key-generator.d.ts +10 -0
  53. package/dist/identity-map/entity-key-generator.js +45 -0
  54. package/dist/identity-map/entity-registry.d.ts +11 -0
  55. package/dist/identity-map/entity-registry.js +41 -0
  56. package/dist/identity-map/identity-map-context.d.ts +9 -0
  57. package/dist/identity-map/identity-map-context.js +22 -0
  58. package/dist/identity-map/identity-map-integration.d.ts +5 -0
  59. package/dist/identity-map/identity-map-integration.js +37 -0
  60. package/dist/identity-map/identity-map.d.ts +11 -0
  61. package/dist/identity-map/identity-map.js +35 -0
  62. package/dist/identity-map/index.d.ts +5 -0
  63. package/dist/identity-map/index.js +14 -0
  64. package/dist/index.d.ts +28 -0
  65. package/dist/index.js +48 -0
  66. package/dist/middleware/identity-map.middleware.d.ts +4 -0
  67. package/dist/middleware/identity-map.middleware.js +22 -0
  68. package/dist/orm-session-context.d.ts +16 -0
  69. package/dist/orm-session-context.js +22 -0
  70. package/dist/orm.d.ts +20 -0
  71. package/dist/orm.js +69 -0
  72. package/dist/orm.service.d.ts +13 -0
  73. package/dist/orm.service.js +361 -0
  74. package/dist/query/index-condition-builder.d.ts +41 -0
  75. package/dist/query/index-condition-builder.js +235 -0
  76. package/dist/query/model-transformer.d.ts +27 -0
  77. package/dist/query/model-transformer.js +201 -0
  78. package/dist/query/sql-column-manager.d.ts +28 -0
  79. package/dist/query/sql-column-manager.js +157 -0
  80. package/dist/query/sql-condition-builder.d.ts +51 -0
  81. package/dist/query/sql-condition-builder.js +264 -0
  82. package/dist/query/sql-join-manager.d.ts +39 -0
  83. package/dist/query/sql-join-manager.js +242 -0
  84. package/dist/query/sql-subquery-builder.d.ts +20 -0
  85. package/dist/query/sql-subquery-builder.js +119 -0
  86. package/dist/repository/Repository.d.ts +121 -0
  87. package/dist/repository/Repository.js +174 -0
  88. package/dist/testing/index.d.ts +1 -0
  89. package/dist/testing/index.js +17 -0
  90. package/dist/testing/with-database.d.ts +20 -0
  91. package/dist/testing/with-database.js +311 -0
  92. package/dist/transaction/transaction-context.d.ts +10 -0
  93. package/dist/transaction/transaction-context.js +19 -0
  94. package/dist/utils/value-processor.d.ts +14 -0
  95. package/dist/utils/value-processor.js +94 -0
  96. package/dist/utils.d.ts +3 -0
  97. package/dist/utils.js +24 -0
  98. package/package.json +59 -0
@@ -0,0 +1,14 @@
1
+ import { CacheService } from '@carno.js/core';
2
+ import { Statement } from '../driver/driver.interface';
3
+ export declare class QueryCacheManager {
4
+ private cacheService;
5
+ private keyGenerator;
6
+ private namespaceKeys;
7
+ constructor(cacheService: CacheService);
8
+ get<T>(statement: Statement<T>): Promise<any>;
9
+ set<T>(statement: Statement<T>, value: any, ttl?: number): Promise<void>;
10
+ invalidate<T>(statement: Statement<T>): Promise<void>;
11
+ private registerKeyInNamespace;
12
+ private getNamespace;
13
+ private generateKey;
14
+ }
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.QueryCacheManager = void 0;
4
+ const cache_key_generator_1 = require("./cache-key-generator");
5
+ class QueryCacheManager {
6
+ constructor(cacheService) {
7
+ this.cacheService = cacheService;
8
+ this.namespaceKeys = new Map();
9
+ this.keyGenerator = new cache_key_generator_1.CacheKeyGenerator();
10
+ }
11
+ async get(statement) {
12
+ const key = this.generateKey(statement);
13
+ return this.cacheService.get(key);
14
+ }
15
+ async set(statement, value, ttl) {
16
+ const key = this.generateKey(statement);
17
+ const namespace = this.getNamespace(statement);
18
+ this.registerKeyInNamespace(namespace, key);
19
+ await this.cacheService.set(key, value, ttl);
20
+ }
21
+ async invalidate(statement) {
22
+ const namespace = this.getNamespace(statement);
23
+ const keys = this.namespaceKeys.get(namespace);
24
+ if (!keys || keys.size === 0) {
25
+ return;
26
+ }
27
+ const deletePromises = Array.from(keys).map(key => this.cacheService.del(key));
28
+ await Promise.all(deletePromises);
29
+ this.namespaceKeys.delete(namespace);
30
+ }
31
+ registerKeyInNamespace(namespace, key) {
32
+ if (!this.namespaceKeys.has(namespace)) {
33
+ this.namespaceKeys.set(namespace, new Set());
34
+ }
35
+ this.namespaceKeys.get(namespace).add(key);
36
+ }
37
+ getNamespace(statement) {
38
+ return statement.table || 'unknown';
39
+ }
40
+ generateKey(statement) {
41
+ return `orm:${this.keyGenerator.generate(statement)}`;
42
+ }
43
+ }
44
+ exports.QueryCacheManager = QueryCacheManager;
@@ -0,0 +1,4 @@
1
+ import { ValueObject } from "./value-object";
2
+ export declare class Email extends ValueObject<string, Email> {
3
+ protected validate(value: string): boolean;
4
+ }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Email = void 0;
4
+ const value_object_1 = require("./value-object");
5
+ const REGEX = /^[a-z0-9.]+@[a-z0-9]+\.[a-z]+(\.[a-z]+)?$/i;
6
+ class Email extends value_object_1.ValueObject {
7
+ validate(value) {
8
+ return REGEX.test(value);
9
+ }
10
+ }
11
+ exports.Email = Email;
@@ -0,0 +1,4 @@
1
+ import { ValueObject } from './value-object';
2
+ export declare class Uuid extends ValueObject<string, Uuid> {
3
+ protected validate(value: string): boolean;
4
+ }
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Uuid = void 0;
4
+ const value_object_1 = require("./value-object");
5
+ class Uuid extends value_object_1.ValueObject {
6
+ validate(value) {
7
+ return /^[a-f\d]{8}(-[a-f\d]{4}){4}[a-f\d]{8}$/i.test(value);
8
+ }
9
+ }
10
+ exports.Uuid = Uuid;
@@ -0,0 +1,95 @@
1
+ type VoExtended<T, Vo> = Vo extends ValueObject<T, Vo> ? Vo : ValueObject<T, Vo>;
2
+ type DatabaseValues = {
3
+ max?: number;
4
+ min?: number;
5
+ precision?: number;
6
+ scale?: number;
7
+ };
8
+ export declare abstract class ValueObject<T, Vo> {
9
+ /**
10
+ * Validates the value of the Value Object.
11
+ * It is abstract so that each Value Object can implement its own validation.
12
+ * It is protected from being called directly.
13
+ *
14
+ * @param value
15
+ * @protected
16
+ */
17
+ protected abstract validate(value: T): boolean;
18
+ /**
19
+ * The maximum length of the Value Object.
20
+ * It value is optional and will be used in database if this Value Object is used as a column.
21
+ * If the value is string, it will be the maximum number of characters.
22
+ * If the value is number, it will be the maximum number.
23
+ */
24
+ protected max?: number;
25
+ /**
26
+ * The minimum length of the Value Object.
27
+ * It value is optional.
28
+ * If the value is string, it will be the minimum number of characters.
29
+ * If the value is number, it will be the minimum number.
30
+ */
31
+ protected min?: number;
32
+ /**
33
+ * The precision of the Value Object.
34
+ * It value is optional and will be used in database if this Value Object is used as a column.
35
+ * It is the number of digits in a number.
36
+ */
37
+ protected precision?: number;
38
+ /**
39
+ * The scale of the Value Object.
40
+ * It value is optional and will be used in database if this Value Object is used as a column.
41
+ * It is the number of digits to the right of the decimal point in a number.
42
+ */
43
+ protected scale?: number;
44
+ /**
45
+ * Valor do Value Object.
46
+ * É privado para não ser alterado diretamente.
47
+ * O valor também é imutável.
48
+ *
49
+ * @private
50
+ */
51
+ private value;
52
+ constructor(value: T, skipValidation?: boolean);
53
+ /**
54
+ * Creates a Value Object instance from a value.
55
+ *
56
+ * @example
57
+ * Email.from('test@test.com');
58
+ *
59
+ * @param value
60
+ */
61
+ static from<T, Vo>(this: new (value: T) => VoExtended<T, Vo>, value: T): VoExtended<T, Vo>;
62
+ /**
63
+ * Returns the scalar value of the Value Object.
64
+ *
65
+ */
66
+ getValue(): T;
67
+ /**
68
+ * Compares the value of the Value Object with another Value Object.
69
+ *
70
+ * @param vo
71
+ */
72
+ equals(vo: ValueObject<T, Vo>): boolean;
73
+ /**
74
+ * Returns the database settings of the Value Object.
75
+ *
76
+ * @returns
77
+ */
78
+ getDatabaseValues(): DatabaseValues;
79
+ /**
80
+ * Sets the value of the Value Object.
81
+ *
82
+ * @param value
83
+ * @private
84
+ */
85
+ private setValue;
86
+ /**
87
+ * Validates the value of the Value Object.
88
+ * It is private so that it can only be called by the constructor.
89
+ *
90
+ * @param value
91
+ * @returns
92
+ */
93
+ private validateDatabase;
94
+ }
95
+ export {};
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ValueObject = void 0;
4
+ const core_1 = require("@carno.js/core");
5
+ class ValueObject {
6
+ constructor(value, skipValidation = false) {
7
+ if (!skipValidation && (!this.validate(value) || !this.validateDatabase(value))) {
8
+ throw new core_1.HttpException(`Invalid value for ${this.constructor.name}`, 400);
9
+ }
10
+ this.setValue(value);
11
+ }
12
+ /**
13
+ * Creates a Value Object instance from a value.
14
+ *
15
+ * @example
16
+ * Email.from('test@test.com');
17
+ *
18
+ * @param value
19
+ */
20
+ static from(value) {
21
+ return new this(value);
22
+ }
23
+ /**
24
+ * Returns the scalar value of the Value Object.
25
+ *
26
+ */
27
+ getValue() {
28
+ return this.value;
29
+ }
30
+ /**
31
+ * Compares the value of the Value Object with another Value Object.
32
+ *
33
+ * @param vo
34
+ */
35
+ equals(vo) {
36
+ return this.getValue() === vo.getValue();
37
+ }
38
+ /**
39
+ * Returns the database settings of the Value Object.
40
+ *
41
+ * @returns
42
+ */
43
+ getDatabaseValues() {
44
+ return {
45
+ max: this.max,
46
+ min: this.min,
47
+ precision: this.precision,
48
+ scale: this.scale,
49
+ };
50
+ }
51
+ /**
52
+ * Sets the value of the Value Object.
53
+ *
54
+ * @param value
55
+ * @private
56
+ */
57
+ setValue(value) {
58
+ this.value = value;
59
+ }
60
+ /**
61
+ * Validates the value of the Value Object.
62
+ * It is private so that it can only be called by the constructor.
63
+ *
64
+ * @param value
65
+ * @returns
66
+ */
67
+ validateDatabase(value) {
68
+ if (typeof value === "string") {
69
+ if (this.max !== undefined && value.length > this.max) {
70
+ throw new core_1.HttpException(`Value exceeds maximum length of ${this.max}`, 400);
71
+ }
72
+ if (this.min !== undefined && value.length < this.min) {
73
+ throw new core_1.HttpException(`Value is less than minimum length of ${this.min}`, 400);
74
+ }
75
+ }
76
+ else if (typeof value === "number") {
77
+ if (this.max !== undefined && value > this.max) {
78
+ throw new core_1.HttpException(`Value exceeds maximum value of ${this.max}`, 400);
79
+ }
80
+ if (this.min !== undefined && value < this.min) {
81
+ throw new core_1.HttpException(`Value is less than minimum value of ${this.min}`, 400);
82
+ }
83
+ if (this.precision !== undefined) {
84
+ const totalDigits = value.toString().replace(".", "").length;
85
+ if (totalDigits > this.precision) {
86
+ throw new core_1.HttpException(`Value exceeds precision of ${this.precision}`, 400);
87
+ }
88
+ }
89
+ if (this.scale !== undefined) {
90
+ const decimalDigits = (value.toString().split(".")[1] || "").length;
91
+ if (decimalDigits > this.scale) {
92
+ throw new core_1.HttpException(`Value exceeds scale of ${this.scale}`, 400);
93
+ }
94
+ }
95
+ }
96
+ return true;
97
+ }
98
+ }
99
+ exports.ValueObject = ValueObject;
@@ -0,0 +1,6 @@
1
+ export declare const ENTITIES = "carno:entities";
2
+ export declare const PROPERTIES = "carno:properties";
3
+ export declare const PROPERTIES_METADATA = "carno:properties:metadata";
4
+ export declare const PROPERTIES_RELATIONS = "carno:properties:relations";
5
+ export declare const EVENTS_METADATA = "carno:events:metadata";
6
+ export declare const COMPUTED_PROPERTIES = "carno:computed:properties";
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.COMPUTED_PROPERTIES = exports.EVENTS_METADATA = exports.PROPERTIES_RELATIONS = exports.PROPERTIES_METADATA = exports.PROPERTIES = exports.ENTITIES = void 0;
4
+ exports.ENTITIES = 'carno:entities';
5
+ exports.PROPERTIES = 'carno:properties';
6
+ exports.PROPERTIES_METADATA = 'carno:properties:metadata';
7
+ exports.PROPERTIES_RELATIONS = 'carno:properties:relations';
8
+ exports.EVENTS_METADATA = 'carno:events:metadata';
9
+ exports.COMPUTED_PROPERTIES = 'carno:computed:properties';
@@ -0,0 +1 @@
1
+ export declare function Computed(): PropertyDecorator;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Computed = Computed;
4
+ const core_1 = require("@carno.js/core");
5
+ const constants_1 = require("../constants");
6
+ function Computed() {
7
+ return (target, propertyKey) => {
8
+ const computedProperties = core_1.Metadata.get(constants_1.COMPUTED_PROPERTIES, target.constructor) || [];
9
+ computedProperties.push(propertyKey);
10
+ core_1.Metadata.set(constants_1.COMPUTED_PROPERTIES, computedProperties, target.constructor);
11
+ };
12
+ }
@@ -0,0 +1,3 @@
1
+ export declare function Entity(options?: {
2
+ tableName?: string;
3
+ }): ClassDecorator;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Entity = Entity;
4
+ const constants_1 = require("../constants");
5
+ const core_1 = require("@carno.js/core");
6
+ function Entity(options) {
7
+ return (target) => {
8
+ const entities = core_1.Metadata.get(constants_1.ENTITIES, Reflect) || [];
9
+ entities.push({ target, options });
10
+ core_1.Metadata.set(constants_1.ENTITIES, entities, Reflect);
11
+ };
12
+ }
@@ -0,0 +1,2 @@
1
+ import { ClassType, EnumOptions } from '../driver/driver.interface';
2
+ export declare function Enum(options?: EnumOptions<any> | (() => ClassType)): PropertyDecorator;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Enum = Enum;
4
+ const property_decorator_1 = require("./property.decorator");
5
+ function Enum(options) {
6
+ const isEnum = true;
7
+ if (!options) {
8
+ return (0, property_decorator_1.Property)({ isEnum, enumItems: '__AUTO_DETECT__', dbType: 'enum' });
9
+ }
10
+ //@ts-ignore
11
+ let enumItems = typeof options === 'function' ? options() : (typeof options.items === 'function' ? options.items() : options.items);
12
+ if (typeof enumItems === 'object') {
13
+ enumItems = Object.keys(enumItems).map(key => enumItems[key]);
14
+ }
15
+ return (0, property_decorator_1.Property)({ ...options, isEnum, enumItems, dbType: 'enum' });
16
+ }
@@ -0,0 +1,4 @@
1
+ export declare function BeforeCreate(): (target: any, propertyName: any) => void;
2
+ export declare function AfterCreate(): (target: any, propertyName: any) => void;
3
+ export declare function BeforeUpdate(): (target: any, propertyName: any) => void;
4
+ export declare function AfterUpdate(): (target: any, propertyName: any) => void;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BeforeCreate = BeforeCreate;
4
+ exports.AfterCreate = AfterCreate;
5
+ exports.BeforeUpdate = BeforeUpdate;
6
+ exports.AfterUpdate = AfterUpdate;
7
+ const constants_1 = require("../constants");
8
+ function BeforeCreate() {
9
+ return function (target, propertyName) {
10
+ const metadata = Reflect.getMetadata(constants_1.EVENTS_METADATA, target.constructor) || [];
11
+ Reflect.defineMetadata(constants_1.EVENTS_METADATA, [...metadata, { type: 'beforeCreate', propertyName }], target.constructor);
12
+ };
13
+ }
14
+ function AfterCreate() {
15
+ return function (target, propertyName) {
16
+ const metadata = Reflect.getMetadata(constants_1.EVENTS_METADATA, target.constructor) || [];
17
+ Reflect.defineMetadata(constants_1.EVENTS_METADATA, [...metadata, { type: 'afterCreate', propertyName }], target.constructor);
18
+ };
19
+ }
20
+ function BeforeUpdate() {
21
+ return function (target, propertyName) {
22
+ const metadata = Reflect.getMetadata(constants_1.EVENTS_METADATA, target.constructor) || [];
23
+ Reflect.defineMetadata(constants_1.EVENTS_METADATA, [...metadata, { type: 'beforeUpdate', propertyName }], target.constructor);
24
+ };
25
+ }
26
+ function AfterUpdate() {
27
+ return function (target, propertyName) {
28
+ const metadata = Reflect.getMetadata(constants_1.EVENTS_METADATA, target.constructor) || [];
29
+ Reflect.defineMetadata(constants_1.EVENTS_METADATA, [...metadata, { type: 'afterUpdate', propertyName }], target.constructor);
30
+ };
31
+ }
@@ -0,0 +1,17 @@
1
+ import { FilterQuery } from "../driver/driver.interface";
2
+ export type IndexColumnMap<T> = {
3
+ [K in keyof T as K extends symbol ? never : K]: string;
4
+ };
5
+ export type IndexPredicate<T> = string | ((columns: IndexColumnMap<T>) => string);
6
+ export type IndexWhere<T> = IndexPredicate<T> | FilterQuery<T>;
7
+ export type IndexDefinition = {
8
+ name: string;
9
+ properties: string[];
10
+ where?: IndexWhere<any>;
11
+ };
12
+ type IndexOptions<T> = {
13
+ properties: (keyof T)[];
14
+ where?: IndexWhere<T>;
15
+ } | (keyof T)[] | undefined;
16
+ export declare function Index<T>(options?: IndexOptions<T>): ClassDecorator & PropertyDecorator;
17
+ export {};
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Index = Index;
4
+ const core_1 = require("@carno.js/core");
5
+ function getCtor(target) {
6
+ return typeof target === "function" ? target : target.constructor;
7
+ }
8
+ function buildFromOptions(options) {
9
+ const props = Array.isArray(options) ? options : options?.properties;
10
+ if (!props || props.length === 0)
11
+ return null;
12
+ const keys = props;
13
+ const where = Array.isArray(options) ? undefined : options?.where;
14
+ return { name: `${keys.join('_')}_index`, properties: keys, where };
15
+ }
16
+ function buildFromProperty(propertyKey) {
17
+ const name = String(propertyKey);
18
+ return { name: `${name}_index`, properties: [name] };
19
+ }
20
+ function resolveIndex(options, propertyKey) {
21
+ const fromOptions = buildFromOptions(options);
22
+ if (fromOptions)
23
+ return fromOptions;
24
+ if (!propertyKey)
25
+ throw new Error("@Index on class requires properties option");
26
+ return buildFromProperty(propertyKey);
27
+ }
28
+ function Index(options) {
29
+ return (target, propertyKey) => {
30
+ const ctor = getCtor(target);
31
+ const indexes = [...(core_1.Metadata.get("indexes", ctor) || [])];
32
+ const index = resolveIndex(options, propertyKey);
33
+ indexes.push(index);
34
+ core_1.Metadata.set("indexes", indexes, ctor);
35
+ };
36
+ }
@@ -0,0 +1,6 @@
1
+ import { EntityName } from '../driver/driver.interface';
2
+ import { PropertyOptions } from './property.decorator';
3
+ export declare function OneToMany<T>(entity: () => EntityName<T>, fkKey: (string & keyof T) | ((e: T) => any)): PropertyDecorator;
4
+ type ManyToOneOptions = Partial<PropertyOptions>;
5
+ export declare function ManyToOne<T>(entityOrOptions?: (() => EntityName<T>) | ManyToOneOptions, maybeOptions?: ManyToOneOptions): PropertyDecorator;
6
+ export {};
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OneToMany = OneToMany;
4
+ exports.ManyToOne = ManyToOne;
5
+ const constants_1 = require("../constants");
6
+ const core_1 = require("@carno.js/core");
7
+ const utils_1 = require("../utils");
8
+ const index_decorator_1 = require("./index.decorator");
9
+ function OneToMany(entity, fkKey) {
10
+ return (target, propertyKey) => {
11
+ const existing = core_1.Metadata.get(constants_1.PROPERTIES_RELATIONS, target.constructor) || [];
12
+ const options = { relation: 'one-to-many', propertyKey, isRelation: true, entity, fkKey, type: core_1.Metadata.getType(target, propertyKey), originalEntity: target.constructor };
13
+ options['columnName'] = `${(0, utils_1.toSnakeCase)(propertyKey)}_id`;
14
+ // @ts-ignore
15
+ existing.push(options);
16
+ core_1.Metadata.set(constants_1.PROPERTIES_RELATIONS, existing, target.constructor);
17
+ };
18
+ }
19
+ function ManyToOne(entityOrOptions, maybeOptions) {
20
+ return (target, propertyKey) => {
21
+ const existing = core_1.Metadata.get(constants_1.PROPERTIES_RELATIONS, target.constructor) || [];
22
+ const hasEntity = typeof entityOrOptions === 'function';
23
+ const entity = hasEntity ? entityOrOptions : undefined;
24
+ const options = (!hasEntity ? entityOrOptions : maybeOptions) || {};
25
+ const columnName = options.columnName || `${(0, utils_1.toSnakeCase)(propertyKey)}_id`;
26
+ const relationOptions = {
27
+ relation: 'many-to-one',
28
+ propertyKey,
29
+ isRelation: true,
30
+ entity: entity || '__AUTO_DETECT__',
31
+ type: core_1.Metadata.getType(target, propertyKey),
32
+ originalEntity: target.constructor,
33
+ columnName,
34
+ ...options,
35
+ };
36
+ if (options.index) {
37
+ (0, index_decorator_1.Index)({ properties: [propertyKey] })(target, propertyKey);
38
+ }
39
+ existing.push(relationOptions);
40
+ core_1.Metadata.set(constants_1.PROPERTIES_RELATIONS, existing, target.constructor);
41
+ };
42
+ }
@@ -0,0 +1,2 @@
1
+ import { PropertyOptions } from './property.decorator';
2
+ export declare function PrimaryKey(options?: Omit<PropertyOptions, 'isPrimary'>): PropertyDecorator;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PrimaryKey = PrimaryKey;
4
+ const property_decorator_1 = require("./property.decorator");
5
+ function PrimaryKey(options) {
6
+ const isPrimary = true;
7
+ return (0, property_decorator_1.Property)({ ...options, isPrimary });
8
+ }
@@ -0,0 +1,24 @@
1
+ export type PropertyOptions = {
2
+ isPrimary?: boolean;
3
+ nullable?: boolean;
4
+ default?: any;
5
+ length?: number;
6
+ hidden?: boolean;
7
+ unique?: boolean;
8
+ index?: boolean;
9
+ precision?: number;
10
+ scale?: number;
11
+ dbType?: "varchar" | "text" | "int" | "bigint" | "float" | "double" | "decimal" | "date" | "datetime" | "time" | "timestamp" | "boolean" | "json" | "jsonb" | "enum" | "array" | "uuid";
12
+ autoIncrement?: boolean;
13
+ columnName?: string;
14
+ isEnum?: boolean;
15
+ enumItems?: string[] | number[] | '__AUTO_DETECT__';
16
+ array?: boolean;
17
+ onUpdate?: () => any;
18
+ onInsert?: () => any;
19
+ };
20
+ export type Prop = {
21
+ propertyKey: any;
22
+ options: PropertyOptions | undefined;
23
+ };
24
+ export declare function Property(options?: PropertyOptions): PropertyDecorator;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Property = Property;
4
+ const constants_1 = require("../constants");
5
+ const utils_1 = require("../utils");
6
+ const core_1 = require("@carno.js/core");
7
+ const index_decorator_1 = require("./index.decorator");
8
+ const __1 = require("..");
9
+ function Property(options) {
10
+ return (target, propertyKey) => {
11
+ const properties = core_1.Metadata.get(constants_1.PROPERTIES, target.constructor) || [];
12
+ // 1) Resolva o tipo logo no início
13
+ const propType = core_1.Metadata.getType(target, propertyKey);
14
+ const length = (options && options.length) || (0, utils_1.getDefaultLength)(propType?.name);
15
+ if ((0, core_1.isObject)(propType) && options.dbType !== "enum") {
16
+ throw new Error(`Property ${String(propertyKey)} has unknown type`);
17
+ }
18
+ options = { length, ...options };
19
+ options["columnName"] = options?.columnName || (0, utils_1.toSnakeCase)(propertyKey);
20
+ if (propType && (0, utils_1.extendsFrom)(__1.ValueObject, propType.prototype)) {
21
+ let instance = new propType(null, true).getDatabaseValues();
22
+ options["length"] = instance.max;
23
+ options["precision"] = instance.precision;
24
+ options["scale"] = instance.scale;
25
+ instance = null; // Garbage collector
26
+ }
27
+ properties.push({ propertyKey, options });
28
+ core_1.Metadata.set(constants_1.PROPERTIES, properties, target.constructor);
29
+ if (options.isPrimary) {
30
+ const indexes = core_1.Metadata.get("indexes", target.constructor) || [];
31
+ indexes.push({ name: `[TABLE]_pkey`, properties: [propertyKey] });
32
+ core_1.Metadata.set("indexes", indexes, target.constructor);
33
+ }
34
+ if (options.index) {
35
+ (0, index_decorator_1.Index)({ properties: [propertyKey] })(target, propertyKey);
36
+ }
37
+ // 2) Atualize PROPERTIES_METADATA apenas para esta propriedade
38
+ const existingTypes = core_1.Metadata.get(constants_1.PROPERTIES_METADATA, target.constructor) || {};
39
+ // Cria uma cópia para evitar mutação compartilhada entre entidades
40
+ const types = { ...existingTypes };
41
+ types[propertyKey] = { type: propType, options };
42
+ core_1.Metadata.set(constants_1.PROPERTIES_METADATA, types, target.constructor);
43
+ };
44
+ }
@@ -0,0 +1,9 @@
1
+ export type UniqueDefinition = {
2
+ name: string;
3
+ properties: string[];
4
+ };
5
+ type UniqueOptions<T> = {
6
+ properties: (keyof T)[];
7
+ } | (keyof T)[] | undefined;
8
+ export declare function Unique<T>(options?: UniqueOptions<T>): ClassDecorator & PropertyDecorator;
9
+ export {};
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Unique = Unique;
4
+ const core_1 = require("@carno.js/core");
5
+ function getCtor(target) {
6
+ return typeof target === "function" ? target : target.constructor;
7
+ }
8
+ function buildFromOptions(options) {
9
+ const props = Array.isArray(options) ? options : options?.properties;
10
+ if (!props || props.length === 0) {
11
+ return null;
12
+ }
13
+ const keys = props;
14
+ return {
15
+ name: `${keys.join('_')}_unique`,
16
+ properties: keys,
17
+ };
18
+ }
19
+ function buildFromProperty(propertyKey) {
20
+ const name = String(propertyKey);
21
+ return {
22
+ name: `${name}_unique`,
23
+ properties: [name],
24
+ };
25
+ }
26
+ function resolveUnique(options, propertyKey) {
27
+ const fromOptions = buildFromOptions(options);
28
+ if (fromOptions) {
29
+ return fromOptions;
30
+ }
31
+ if (!propertyKey) {
32
+ throw new Error("@Unique on class requires properties option");
33
+ }
34
+ return buildFromProperty(propertyKey);
35
+ }
36
+ function Unique(options) {
37
+ return (target, propertyKey) => {
38
+ const ctor = getCtor(target);
39
+ const uniques = [...(core_1.Metadata.get("uniques", ctor) || [])];
40
+ const unique = resolveUnique(options, propertyKey);
41
+ uniques.push(unique);
42
+ core_1.Metadata.set("uniques", uniques, ctor);
43
+ };
44
+ }