@forklaunch/core 0.8.7 → 0.9.1

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.
@@ -60,12 +60,14 @@ var BaseEntity2 = class extends import_core2.BaseEntity {
60
60
  * @param {...Parameters<Entity['create']>} args - Arguments for entity creation
61
61
  * @returns {Entity} A new entity instance
62
62
  */
63
- static create(...args) {
63
+ static async create(...args) {
64
64
  const [data, ...additionalArgs] = args;
65
- return new this().create(
65
+ const entity = new this();
66
+ await entity.create(
66
67
  data,
67
68
  ...additionalArgs
68
69
  );
70
+ return entity;
69
71
  }
70
72
  /**
71
73
  * Static method to update an entity instance.
@@ -75,12 +77,14 @@ var BaseEntity2 = class extends import_core2.BaseEntity {
75
77
  * @param {...Parameters<Entity['update']>} args - Arguments for entity update
76
78
  * @returns {Entity} The updated entity instance
77
79
  */
78
- static update(...args) {
80
+ static async update(...args) {
79
81
  const [data, ...additionalArgs] = args;
80
- return new this().update(
82
+ const entity = new this();
83
+ await entity.update(
81
84
  data,
82
85
  ...additionalArgs
83
86
  );
87
+ return entity;
84
88
  }
85
89
  /**
86
90
  * Static method to map data to an entity instance.
@@ -90,8 +94,10 @@ var BaseEntity2 = class extends import_core2.BaseEntity {
90
94
  * @param {Partial<EntityDTO<FromEntityType<Entity>>>} data - The data to map
91
95
  * @returns {Entity} A new entity instance with mapped data
92
96
  */
93
- static map(data) {
94
- return new this().map(data);
97
+ static async map(data) {
98
+ const entity = new this();
99
+ await entity.map(data);
100
+ return entity;
95
101
  }
96
102
  /**
97
103
  * Creates a new entity instance with the provided data.
@@ -99,8 +105,13 @@ var BaseEntity2 = class extends import_core2.BaseEntity {
99
105
  * @param {CreateShape<BaseEntityWithId, this>} data - The data to create the entity with
100
106
  * @returns {this} The created entity instance
101
107
  */
102
- create(data) {
103
- return Object.assign(this, transformRawDto(data, this));
108
+ async create(data) {
109
+ Object.assign(this, transformRawDto(data, this));
110
+ const entity = await (0, import_core2.wrap)(this).init();
111
+ if (!entity) {
112
+ throw new Error("Entity not initialized");
113
+ }
114
+ return entity.toObject();
104
115
  }
105
116
  /**
106
117
  * Updates the entity instance with the provided data.
@@ -108,22 +119,24 @@ var BaseEntity2 = class extends import_core2.BaseEntity {
108
119
  * @param {UpdateShape<BaseEntityWithId, this>} data - The data to update the entity with
109
120
  * @returns {this} The updated entity instance
110
121
  */
111
- update(data) {
112
- (0, import_core2.wrap)(this).assign(
122
+ async update(data) {
123
+ const entity = (0, import_core2.wrap)(this);
124
+ entity.assign(
113
125
  (0, import_common.stripUndefinedProperties)(transformRawDto(data, this))
114
126
  );
115
- return this;
127
+ return entity.toObject();
116
128
  }
117
129
  /**
118
130
  * Reads the entity data as a plain object.
119
131
  *
120
132
  * @returns {EntityDTO<this> | this} The entity data as a plain object
121
133
  */
122
- read() {
123
- if (typeof (0, import_core2.wrap)(this).toPOJO === "function") {
124
- return (0, import_core2.wrap)(this).toPOJO();
134
+ async read() {
135
+ const entity = await (0, import_core2.wrap)(this).init();
136
+ if (!entity) {
137
+ throw new Error("Entity not initialized");
125
138
  }
126
- return this;
139
+ return entity.toObject();
127
140
  }
128
141
  /**
129
142
  * Maps data to the entity instance.
@@ -131,9 +144,13 @@ var BaseEntity2 = class extends import_core2.BaseEntity {
131
144
  * @param {Partial<EntityDTO<FromEntityType<this>>>} data - The data to map
132
145
  * @returns {this} The entity instance with mapped data
133
146
  */
134
- map(data) {
135
- (0, import_core2.wrap)(this).assign(data);
136
- return this;
147
+ async map(data) {
148
+ const entity = await (0, import_core2.wrap)(this).init();
149
+ if (!entity) {
150
+ throw new Error("Entity not initialized");
151
+ }
152
+ entity.assign(data);
153
+ return entity;
137
154
  }
138
155
  };
139
156
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/persistence/index.ts","../../../src/persistence/base.entity.ts","../../../src/persistence/transformRawDto.ts","../../../src/persistence/guards/isMarkedCollection.ts","../../../src/persistence/collection.ts"],"sourcesContent":["export * from './base.entity';\nexport * from './collection';\n","import { stripUndefinedProperties } from '@forklaunch/common';\nimport {\n Constructor,\n EntityDTO,\n FromEntityType,\n BaseEntity as MikroOrmBaseEntity,\n wrap\n} from '@mikro-orm/core';\nimport { transformRawDto } from './transformRawDto';\nimport { CreateShape, UpdateShape } from './types/shapes.types';\n\n/**\n * Type representing a base entity with common fields.\n * Extends BaseEntity with optional id, _id, createdAt, and updatedAt fields.\n */\ntype BaseEntityWithId = BaseEntity & {\n id?: unknown;\n _id?: unknown;\n createdAt?: unknown;\n updatedAt?: unknown;\n};\n\n/**\n * Abstract base class for all entities in the system.\n * Extends MikroORM's BaseEntity and provides common CRUD operations.\n */\nexport abstract class BaseEntity extends MikroOrmBaseEntity {\n /**\n * Static factory method to create a new entity instance.\n *\n * @template Entity - The type of entity being created\n * @param {Constructor<Entity>} this - The entity constructor\n * @param {...Parameters<Entity['create']>} args - Arguments for entity creation\n * @returns {Entity} A new entity instance\n */\n static create<Entity extends BaseEntityWithId>(\n this: Constructor<Entity>,\n ...args: Parameters<Entity['create']>\n ): Entity {\n const [data, ...additionalArgs] = args;\n return new this().create(\n data as CreateShape<BaseEntityWithId, Entity>,\n ...additionalArgs\n );\n }\n\n /**\n * Static method to update an entity instance.\n *\n * @template Entity - The type of entity being updated\n * @param {Constructor<Entity>} this - The entity constructor\n * @param {...Parameters<Entity['update']>} args - Arguments for entity update\n * @returns {Entity} The updated entity instance\n */\n static update<Entity extends BaseEntityWithId>(\n this: Constructor<Entity>,\n ...args: Parameters<Entity['update']>\n ): Entity {\n const [data, ...additionalArgs] = args;\n return new this().update(\n data as UpdateShape<BaseEntity, Entity>,\n ...additionalArgs\n );\n }\n\n /**\n * Static method to map data to an entity instance.\n *\n * @template Entity - The type of entity being mapped\n * @param {Constructor<Entity>} this - The entity constructor\n * @param {Partial<EntityDTO<FromEntityType<Entity>>>} data - The data to map\n * @returns {Entity} A new entity instance with mapped data\n */\n static map<Entity extends BaseEntity>(\n this: Constructor<Entity>,\n data: Partial<EntityDTO<FromEntityType<Entity>>>\n ): Entity {\n return new this().map(data);\n }\n\n /**\n * Creates a new entity instance with the provided data.\n *\n * @param {CreateShape<BaseEntityWithId, this>} data - The data to create the entity with\n * @returns {this} The created entity instance\n */\n create(data: CreateShape<BaseEntityWithId, this>): this {\n return Object.assign(this, transformRawDto(data, this));\n }\n\n /**\n * Updates the entity instance with the provided data.\n *\n * @param {UpdateShape<BaseEntityWithId, this>} data - The data to update the entity with\n * @returns {this} The updated entity instance\n */\n update(data: UpdateShape<BaseEntityWithId, this>): this {\n wrap(this).assign(\n stripUndefinedProperties(transformRawDto(data, this)) as Partial<\n EntityDTO<FromEntityType<this>>\n >\n );\n return this;\n }\n\n /**\n * Reads the entity data as a plain object.\n *\n * @returns {EntityDTO<this> | this} The entity data as a plain object\n */\n read(): EntityDTO<this> | this {\n if (typeof wrap(this).toPOJO === 'function') {\n return wrap(this).toPOJO();\n }\n return this;\n }\n\n /**\n * Maps data to the entity instance.\n *\n * @param {Partial<EntityDTO<FromEntityType<this>>>} data - The data to map\n * @returns {this} The entity instance with mapped data\n */\n map(data: Partial<EntityDTO<FromEntityType<this>>>): this {\n wrap(this).assign(data);\n return this;\n }\n}\n","import { BaseEntity, Collection } from '@mikro-orm/core';\nimport { isMarkedCollection } from './guards/isMarkedCollection';\n\n/**\n * Transforms a raw DTO (Data Transfer Object) by converting marked collections into MikroORM collections.\n * This function is used to properly handle collections when converting between DTOs and entities.\n *\n * @template T - The type of the DTO being transformed\n * @template U - The type of the entity being transformed into\n * @param {T} data - The raw DTO data to transform\n * @param {U} entity - The entity instance to associate collections with\n * @returns {T} The transformed DTO with collections properly initialized\n * @example\n * const dto = { users: { _collection: true, items: [{ id: 1 }] } };\n * const entity = new UserEntity();\n * const transformed = transformRawDto(dto, entity);\n * // transformed.users is now a MikroORM Collection\n */\nexport function transformRawDto<\n T extends Record<string, unknown>,\n U extends BaseEntity\n>(data: T, entity: U): T {\n const transformedObject: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n if (isMarkedCollection<object>(value)) {\n transformedObject[key] = new Collection(entity, value.items);\n } else {\n transformedObject[key] = value;\n }\n }\n return transformedObject as T;\n}\n","import { MarkedCollection } from '../types/markedCollection.types';\n\n/**\n * Type guard function that checks if a value is a marked collection.\n *\n * @template T - The type of items in the collection\n * @param {unknown} value - The value to check\n * @returns {value is MarkedCollection<T>} True if the value is a marked collection, false otherwise\n * @example\n * const value = { _collection: true, items: [1, 2, 3] };\n * if (isMarkedCollection<number>(value)) {\n * // value is now typed as MarkedCollection<number>\n * console.log(value.items); // [1, 2, 3]\n * }\n */\nexport function isMarkedCollection<T>(\n value: unknown\n): value is MarkedCollection<T> {\n return (\n typeof value === 'object' &&\n value !== null &&\n '_collection' in value &&\n typeof value._collection === 'boolean' &&\n value._collection\n );\n}\n","import { MarkedCollection } from './types/markedCollection.types';\n\n/**\n * Creates a marked collection from an array of items.\n * A marked collection is a wrapper around an array that indicates it should be treated as a collection.\n *\n * @template T - The type of items in the collection\n * @param {T[]} items - The array of items to wrap in a collection\n * @returns {MarkedCollection<T>} A marked collection containing the provided items\n * @example\n * const users = collection([{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }]);\n */\nexport function collection<T>(items: T[]): MarkedCollection<T> {\n return {\n _collection: true,\n items\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA,oBAAAA;AAAA,EAAA;AAAA;AAAA;;;ACAA,oBAAyC;AACzC,IAAAC,eAMO;;;ACPP,kBAAuC;;;ACehC,SAAS,mBACd,OAC8B;AAC9B,SACE,OAAO,UAAU,YACjB,UAAU,QACV,iBAAiB,SACjB,OAAO,MAAM,gBAAgB,aAC7B,MAAM;AAEV;;;ADPO,SAAS,gBAGd,MAAS,QAAc;AACvB,QAAM,oBAA6C,CAAC;AACpD,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,QAAI,mBAA2B,KAAK,GAAG;AACrC,wBAAkB,GAAG,IAAI,IAAI,uBAAW,QAAQ,MAAM,KAAK;AAAA,IAC7D,OAAO;AACL,wBAAkB,GAAG,IAAI;AAAA,IAC3B;AAAA,EACF;AACA,SAAO;AACT;;;ADLO,IAAeC,cAAf,cAAkC,aAAAC,WAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAS1D,OAAO,UAEF,MACK;AACR,UAAM,CAAC,MAAM,GAAG,cAAc,IAAI;AAClC,WAAO,IAAI,KAAK,EAAE;AAAA,MAChB;AAAA,MACA,GAAG;AAAA,IACL;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,OAAO,UAEF,MACK;AACR,UAAM,CAAC,MAAM,GAAG,cAAc,IAAI;AAClC,WAAO,IAAI,KAAK,EAAE;AAAA,MAChB;AAAA,MACA,GAAG;AAAA,IACL;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,OAAO,IAEL,MACQ;AACR,WAAO,IAAI,KAAK,EAAE,IAAI,IAAI;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,MAAiD;AACtD,WAAO,OAAO,OAAO,MAAM,gBAAgB,MAAM,IAAI,CAAC;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,MAAiD;AACtD,2BAAK,IAAI,EAAE;AAAA,UACT,wCAAyB,gBAAgB,MAAM,IAAI,CAAC;AAAA,IAGtD;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAA+B;AAC7B,QAAI,WAAO,mBAAK,IAAI,EAAE,WAAW,YAAY;AAC3C,iBAAO,mBAAK,IAAI,EAAE,OAAO;AAAA,IAC3B;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAI,MAAsD;AACxD,2BAAK,IAAI,EAAE,OAAO,IAAI;AACtB,WAAO;AAAA,EACT;AACF;;;AGnHO,SAAS,WAAc,OAAiC;AAC7D,SAAO;AAAA,IACL,aAAa;AAAA,IACb;AAAA,EACF;AACF;","names":["BaseEntity","import_core","BaseEntity","MikroOrmBaseEntity"]}
1
+ {"version":3,"sources":["../../../src/persistence/index.ts","../../../src/persistence/base.entity.ts","../../../src/persistence/transformRawDto.ts","../../../src/persistence/guards/isMarkedCollection.ts","../../../src/persistence/collection.ts"],"sourcesContent":["export * from './base.entity';\nexport * from './collection';\n","import { stripUndefinedProperties } from '@forklaunch/common';\nimport {\n Constructor,\n EntityDTO,\n FromEntityType,\n BaseEntity as MikroOrmBaseEntity,\n wrap\n} from '@mikro-orm/core';\nimport { transformRawDto } from './transformRawDto';\nimport { CreateShape, UpdateShape } from './types/shapes.types';\n\n/**\n * Type representing a base entity with common fields.\n * Extends BaseEntity with optional id, _id, createdAt, and updatedAt fields.\n */\ntype BaseEntityWithId = BaseEntity & {\n id?: unknown;\n _id?: unknown;\n createdAt?: unknown;\n updatedAt?: unknown;\n};\n\n/**\n * Abstract base class for all entities in the system.\n * Extends MikroORM's BaseEntity and provides common CRUD operations.\n */\nexport abstract class BaseEntity extends MikroOrmBaseEntity {\n /**\n * Static factory method to create a new entity instance.\n *\n * @template Entity - The type of entity being created\n * @param {Constructor<Entity>} this - The entity constructor\n * @param {...Parameters<Entity['create']>} args - Arguments for entity creation\n * @returns {Entity} A new entity instance\n */\n static async create<Entity extends BaseEntityWithId>(\n this: Constructor<Entity>,\n ...args: Parameters<Entity['create']>\n ): Promise<Entity> {\n const [data, ...additionalArgs] = args;\n const entity = new this();\n await entity.create(\n data as CreateShape<BaseEntityWithId, Entity>,\n ...additionalArgs\n );\n return entity;\n }\n\n /**\n * Static method to update an entity instance.\n *\n * @template Entity - The type of entity being updated\n * @param {Constructor<Entity>} this - The entity constructor\n * @param {...Parameters<Entity['update']>} args - Arguments for entity update\n * @returns {Entity} The updated entity instance\n */\n static async update<Entity extends BaseEntityWithId>(\n this: Constructor<Entity>,\n ...args: Parameters<Entity['update']>\n ): Promise<Entity> {\n const [data, ...additionalArgs] = args;\n const entity = new this();\n await entity.update(\n data as UpdateShape<BaseEntity, Entity>,\n ...additionalArgs\n );\n return entity;\n }\n\n /**\n * Static method to map data to an entity instance.\n *\n * @template Entity - The type of entity being mapped\n * @param {Constructor<Entity>} this - The entity constructor\n * @param {Partial<EntityDTO<FromEntityType<Entity>>>} data - The data to map\n * @returns {Entity} A new entity instance with mapped data\n */\n static async map<Entity extends BaseEntity>(\n this: Constructor<Entity>,\n data: Partial<EntityDTO<FromEntityType<Entity>>>\n ): Promise<Entity> {\n const entity = new this();\n await entity.map(data);\n return entity;\n }\n\n /**\n * Creates a new entity instance with the provided data.\n *\n * @param {CreateShape<BaseEntityWithId, this>} data - The data to create the entity with\n * @returns {this} The created entity instance\n */\n async create(\n data: CreateShape<BaseEntityWithId, this>\n ): Promise<EntityDTO<this>> {\n Object.assign(this, transformRawDto(data, this));\n const entity = await wrap(this).init();\n if (!entity) {\n throw new Error('Entity not initialized');\n }\n return entity.toObject();\n }\n\n /**\n * Updates the entity instance with the provided data.\n *\n * @param {UpdateShape<BaseEntityWithId, this>} data - The data to update the entity with\n * @returns {this} The updated entity instance\n */\n async update(\n data: UpdateShape<BaseEntityWithId, this>\n ): Promise<EntityDTO<this>> {\n const entity = wrap(this);\n entity.assign(\n stripUndefinedProperties(transformRawDto(data, this)) as Partial<\n EntityDTO<FromEntityType<this>>\n >\n );\n return entity.toObject();\n }\n\n /**\n * Reads the entity data as a plain object.\n *\n * @returns {EntityDTO<this> | this} The entity data as a plain object\n */\n async read(): Promise<EntityDTO<this>> {\n const entity = await wrap(this).init();\n if (!entity) {\n throw new Error('Entity not initialized');\n }\n return entity.toObject();\n }\n\n /**\n * Maps data to the entity instance.\n *\n * @param {Partial<EntityDTO<FromEntityType<this>>>} data - The data to map\n * @returns {this} The entity instance with mapped data\n */\n async map(data: Partial<EntityDTO<FromEntityType<this>>>): Promise<this> {\n const entity = await wrap(this).init();\n\n if (!entity) {\n throw new Error('Entity not initialized');\n }\n entity.assign(data);\n return entity;\n }\n}\n","import { BaseEntity, Collection } from '@mikro-orm/core';\nimport { isMarkedCollection } from './guards/isMarkedCollection';\n\n/**\n * Transforms a raw DTO (Data Transfer Object) by converting marked collections into MikroORM collections.\n * This function is used to properly handle collections when converting between DTOs and entities.\n *\n * @template T - The type of the DTO being transformed\n * @template U - The type of the entity being transformed into\n * @param {T} data - The raw DTO data to transform\n * @param {U} entity - The entity instance to associate collections with\n * @returns {T} The transformed DTO with collections properly initialized\n * @example\n * const dto = { users: { _collection: true, items: [{ id: 1 }] } };\n * const entity = new UserEntity();\n * const transformed = transformRawDto(dto, entity);\n * // transformed.users is now a MikroORM Collection\n */\nexport function transformRawDto<\n T extends Record<string, unknown>,\n U extends BaseEntity\n>(data: T, entity: U): T {\n const transformedObject: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n if (isMarkedCollection<object>(value)) {\n transformedObject[key] = new Collection(entity, value.items);\n } else {\n transformedObject[key] = value;\n }\n }\n return transformedObject as T;\n}\n","import { MarkedCollection } from '../types/markedCollection.types';\n\n/**\n * Type guard function that checks if a value is a marked collection.\n *\n * @template T - The type of items in the collection\n * @param {unknown} value - The value to check\n * @returns {value is MarkedCollection<T>} True if the value is a marked collection, false otherwise\n * @example\n * const value = { _collection: true, items: [1, 2, 3] };\n * if (isMarkedCollection<number>(value)) {\n * // value is now typed as MarkedCollection<number>\n * console.log(value.items); // [1, 2, 3]\n * }\n */\nexport function isMarkedCollection<T>(\n value: unknown\n): value is MarkedCollection<T> {\n return (\n typeof value === 'object' &&\n value !== null &&\n '_collection' in value &&\n typeof value._collection === 'boolean' &&\n value._collection\n );\n}\n","import { MarkedCollection } from './types/markedCollection.types';\n\n/**\n * Creates a marked collection from an array of items.\n * A marked collection is a wrapper around an array that indicates it should be treated as a collection.\n *\n * @template T - The type of items in the collection\n * @param {T[]} items - The array of items to wrap in a collection\n * @returns {MarkedCollection<T>} A marked collection containing the provided items\n * @example\n * const users = collection([{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }]);\n */\nexport function collection<T>(items: T[]): MarkedCollection<T> {\n return {\n _collection: true,\n items\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA,oBAAAA;AAAA,EAAA;AAAA;AAAA;;;ACAA,oBAAyC;AACzC,IAAAC,eAMO;;;ACPP,kBAAuC;;;ACehC,SAAS,mBACd,OAC8B;AAC9B,SACE,OAAO,UAAU,YACjB,UAAU,QACV,iBAAiB,SACjB,OAAO,MAAM,gBAAgB,aAC7B,MAAM;AAEV;;;ADPO,SAAS,gBAGd,MAAS,QAAc;AACvB,QAAM,oBAA6C,CAAC;AACpD,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,QAAI,mBAA2B,KAAK,GAAG;AACrC,wBAAkB,GAAG,IAAI,IAAI,uBAAW,QAAQ,MAAM,KAAK;AAAA,IAC7D,OAAO;AACL,wBAAkB,GAAG,IAAI;AAAA,IAC3B;AAAA,EACF;AACA,SAAO;AACT;;;ADLO,IAAeC,cAAf,cAAkC,aAAAC,WAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAS1D,aAAa,UAER,MACc;AACjB,UAAM,CAAC,MAAM,GAAG,cAAc,IAAI;AAClC,UAAM,SAAS,IAAI,KAAK;AACxB,UAAM,OAAO;AAAA,MACX;AAAA,MACA,GAAG;AAAA,IACL;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,aAAa,UAER,MACc;AACjB,UAAM,CAAC,MAAM,GAAG,cAAc,IAAI;AAClC,UAAM,SAAS,IAAI,KAAK;AACxB,UAAM,OAAO;AAAA,MACX;AAAA,MACA,GAAG;AAAA,IACL;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,aAAa,IAEX,MACiB;AACjB,UAAM,SAAS,IAAI,KAAK;AACxB,UAAM,OAAO,IAAI,IAAI;AACrB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OACJ,MAC0B;AAC1B,WAAO,OAAO,MAAM,gBAAgB,MAAM,IAAI,CAAC;AAC/C,UAAM,SAAS,UAAM,mBAAK,IAAI,EAAE,KAAK;AACrC,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,wBAAwB;AAAA,IAC1C;AACA,WAAO,OAAO,SAAS;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OACJ,MAC0B;AAC1B,UAAM,aAAS,mBAAK,IAAI;AACxB,WAAO;AAAA,UACL,wCAAyB,gBAAgB,MAAM,IAAI,CAAC;AAAA,IAGtD;AACA,WAAO,OAAO,SAAS;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,OAAiC;AACrC,UAAM,SAAS,UAAM,mBAAK,IAAI,EAAE,KAAK;AACrC,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,wBAAwB;AAAA,IAC1C;AACA,WAAO,OAAO,SAAS;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,IAAI,MAA+D;AACvE,UAAM,SAAS,UAAM,mBAAK,IAAI,EAAE,KAAK;AAErC,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,wBAAwB;AAAA,IAC1C;AACA,WAAO,OAAO,IAAI;AAClB,WAAO;AAAA,EACT;AACF;;;AGzIO,SAAS,WAAc,OAAiC;AAC7D,SAAO;AAAA,IACL,aAAa;AAAA,IACb;AAAA,EACF;AACF;","names":["BaseEntity","import_core","BaseEntity","MikroOrmBaseEntity"]}
@@ -36,12 +36,14 @@ var BaseEntity2 = class extends MikroOrmBaseEntity {
36
36
  * @param {...Parameters<Entity['create']>} args - Arguments for entity creation
37
37
  * @returns {Entity} A new entity instance
38
38
  */
39
- static create(...args) {
39
+ static async create(...args) {
40
40
  const [data, ...additionalArgs] = args;
41
- return new this().create(
41
+ const entity = new this();
42
+ await entity.create(
42
43
  data,
43
44
  ...additionalArgs
44
45
  );
46
+ return entity;
45
47
  }
46
48
  /**
47
49
  * Static method to update an entity instance.
@@ -51,12 +53,14 @@ var BaseEntity2 = class extends MikroOrmBaseEntity {
51
53
  * @param {...Parameters<Entity['update']>} args - Arguments for entity update
52
54
  * @returns {Entity} The updated entity instance
53
55
  */
54
- static update(...args) {
56
+ static async update(...args) {
55
57
  const [data, ...additionalArgs] = args;
56
- return new this().update(
58
+ const entity = new this();
59
+ await entity.update(
57
60
  data,
58
61
  ...additionalArgs
59
62
  );
63
+ return entity;
60
64
  }
61
65
  /**
62
66
  * Static method to map data to an entity instance.
@@ -66,8 +70,10 @@ var BaseEntity2 = class extends MikroOrmBaseEntity {
66
70
  * @param {Partial<EntityDTO<FromEntityType<Entity>>>} data - The data to map
67
71
  * @returns {Entity} A new entity instance with mapped data
68
72
  */
69
- static map(data) {
70
- return new this().map(data);
73
+ static async map(data) {
74
+ const entity = new this();
75
+ await entity.map(data);
76
+ return entity;
71
77
  }
72
78
  /**
73
79
  * Creates a new entity instance with the provided data.
@@ -75,8 +81,13 @@ var BaseEntity2 = class extends MikroOrmBaseEntity {
75
81
  * @param {CreateShape<BaseEntityWithId, this>} data - The data to create the entity with
76
82
  * @returns {this} The created entity instance
77
83
  */
78
- create(data) {
79
- return Object.assign(this, transformRawDto(data, this));
84
+ async create(data) {
85
+ Object.assign(this, transformRawDto(data, this));
86
+ const entity = await wrap(this).init();
87
+ if (!entity) {
88
+ throw new Error("Entity not initialized");
89
+ }
90
+ return entity.toObject();
80
91
  }
81
92
  /**
82
93
  * Updates the entity instance with the provided data.
@@ -84,22 +95,24 @@ var BaseEntity2 = class extends MikroOrmBaseEntity {
84
95
  * @param {UpdateShape<BaseEntityWithId, this>} data - The data to update the entity with
85
96
  * @returns {this} The updated entity instance
86
97
  */
87
- update(data) {
88
- wrap(this).assign(
98
+ async update(data) {
99
+ const entity = wrap(this);
100
+ entity.assign(
89
101
  stripUndefinedProperties(transformRawDto(data, this))
90
102
  );
91
- return this;
103
+ return entity.toObject();
92
104
  }
93
105
  /**
94
106
  * Reads the entity data as a plain object.
95
107
  *
96
108
  * @returns {EntityDTO<this> | this} The entity data as a plain object
97
109
  */
98
- read() {
99
- if (typeof wrap(this).toPOJO === "function") {
100
- return wrap(this).toPOJO();
110
+ async read() {
111
+ const entity = await wrap(this).init();
112
+ if (!entity) {
113
+ throw new Error("Entity not initialized");
101
114
  }
102
- return this;
115
+ return entity.toObject();
103
116
  }
104
117
  /**
105
118
  * Maps data to the entity instance.
@@ -107,9 +120,13 @@ var BaseEntity2 = class extends MikroOrmBaseEntity {
107
120
  * @param {Partial<EntityDTO<FromEntityType<this>>>} data - The data to map
108
121
  * @returns {this} The entity instance with mapped data
109
122
  */
110
- map(data) {
111
- wrap(this).assign(data);
112
- return this;
123
+ async map(data) {
124
+ const entity = await wrap(this).init();
125
+ if (!entity) {
126
+ throw new Error("Entity not initialized");
127
+ }
128
+ entity.assign(data);
129
+ return entity;
113
130
  }
114
131
  };
115
132
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/persistence/base.entity.ts","../../../src/persistence/transformRawDto.ts","../../../src/persistence/guards/isMarkedCollection.ts","../../../src/persistence/collection.ts"],"sourcesContent":["import { stripUndefinedProperties } from '@forklaunch/common';\nimport {\n Constructor,\n EntityDTO,\n FromEntityType,\n BaseEntity as MikroOrmBaseEntity,\n wrap\n} from '@mikro-orm/core';\nimport { transformRawDto } from './transformRawDto';\nimport { CreateShape, UpdateShape } from './types/shapes.types';\n\n/**\n * Type representing a base entity with common fields.\n * Extends BaseEntity with optional id, _id, createdAt, and updatedAt fields.\n */\ntype BaseEntityWithId = BaseEntity & {\n id?: unknown;\n _id?: unknown;\n createdAt?: unknown;\n updatedAt?: unknown;\n};\n\n/**\n * Abstract base class for all entities in the system.\n * Extends MikroORM's BaseEntity and provides common CRUD operations.\n */\nexport abstract class BaseEntity extends MikroOrmBaseEntity {\n /**\n * Static factory method to create a new entity instance.\n *\n * @template Entity - The type of entity being created\n * @param {Constructor<Entity>} this - The entity constructor\n * @param {...Parameters<Entity['create']>} args - Arguments for entity creation\n * @returns {Entity} A new entity instance\n */\n static create<Entity extends BaseEntityWithId>(\n this: Constructor<Entity>,\n ...args: Parameters<Entity['create']>\n ): Entity {\n const [data, ...additionalArgs] = args;\n return new this().create(\n data as CreateShape<BaseEntityWithId, Entity>,\n ...additionalArgs\n );\n }\n\n /**\n * Static method to update an entity instance.\n *\n * @template Entity - The type of entity being updated\n * @param {Constructor<Entity>} this - The entity constructor\n * @param {...Parameters<Entity['update']>} args - Arguments for entity update\n * @returns {Entity} The updated entity instance\n */\n static update<Entity extends BaseEntityWithId>(\n this: Constructor<Entity>,\n ...args: Parameters<Entity['update']>\n ): Entity {\n const [data, ...additionalArgs] = args;\n return new this().update(\n data as UpdateShape<BaseEntity, Entity>,\n ...additionalArgs\n );\n }\n\n /**\n * Static method to map data to an entity instance.\n *\n * @template Entity - The type of entity being mapped\n * @param {Constructor<Entity>} this - The entity constructor\n * @param {Partial<EntityDTO<FromEntityType<Entity>>>} data - The data to map\n * @returns {Entity} A new entity instance with mapped data\n */\n static map<Entity extends BaseEntity>(\n this: Constructor<Entity>,\n data: Partial<EntityDTO<FromEntityType<Entity>>>\n ): Entity {\n return new this().map(data);\n }\n\n /**\n * Creates a new entity instance with the provided data.\n *\n * @param {CreateShape<BaseEntityWithId, this>} data - The data to create the entity with\n * @returns {this} The created entity instance\n */\n create(data: CreateShape<BaseEntityWithId, this>): this {\n return Object.assign(this, transformRawDto(data, this));\n }\n\n /**\n * Updates the entity instance with the provided data.\n *\n * @param {UpdateShape<BaseEntityWithId, this>} data - The data to update the entity with\n * @returns {this} The updated entity instance\n */\n update(data: UpdateShape<BaseEntityWithId, this>): this {\n wrap(this).assign(\n stripUndefinedProperties(transformRawDto(data, this)) as Partial<\n EntityDTO<FromEntityType<this>>\n >\n );\n return this;\n }\n\n /**\n * Reads the entity data as a plain object.\n *\n * @returns {EntityDTO<this> | this} The entity data as a plain object\n */\n read(): EntityDTO<this> | this {\n if (typeof wrap(this).toPOJO === 'function') {\n return wrap(this).toPOJO();\n }\n return this;\n }\n\n /**\n * Maps data to the entity instance.\n *\n * @param {Partial<EntityDTO<FromEntityType<this>>>} data - The data to map\n * @returns {this} The entity instance with mapped data\n */\n map(data: Partial<EntityDTO<FromEntityType<this>>>): this {\n wrap(this).assign(data);\n return this;\n }\n}\n","import { BaseEntity, Collection } from '@mikro-orm/core';\nimport { isMarkedCollection } from './guards/isMarkedCollection';\n\n/**\n * Transforms a raw DTO (Data Transfer Object) by converting marked collections into MikroORM collections.\n * This function is used to properly handle collections when converting between DTOs and entities.\n *\n * @template T - The type of the DTO being transformed\n * @template U - The type of the entity being transformed into\n * @param {T} data - The raw DTO data to transform\n * @param {U} entity - The entity instance to associate collections with\n * @returns {T} The transformed DTO with collections properly initialized\n * @example\n * const dto = { users: { _collection: true, items: [{ id: 1 }] } };\n * const entity = new UserEntity();\n * const transformed = transformRawDto(dto, entity);\n * // transformed.users is now a MikroORM Collection\n */\nexport function transformRawDto<\n T extends Record<string, unknown>,\n U extends BaseEntity\n>(data: T, entity: U): T {\n const transformedObject: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n if (isMarkedCollection<object>(value)) {\n transformedObject[key] = new Collection(entity, value.items);\n } else {\n transformedObject[key] = value;\n }\n }\n return transformedObject as T;\n}\n","import { MarkedCollection } from '../types/markedCollection.types';\n\n/**\n * Type guard function that checks if a value is a marked collection.\n *\n * @template T - The type of items in the collection\n * @param {unknown} value - The value to check\n * @returns {value is MarkedCollection<T>} True if the value is a marked collection, false otherwise\n * @example\n * const value = { _collection: true, items: [1, 2, 3] };\n * if (isMarkedCollection<number>(value)) {\n * // value is now typed as MarkedCollection<number>\n * console.log(value.items); // [1, 2, 3]\n * }\n */\nexport function isMarkedCollection<T>(\n value: unknown\n): value is MarkedCollection<T> {\n return (\n typeof value === 'object' &&\n value !== null &&\n '_collection' in value &&\n typeof value._collection === 'boolean' &&\n value._collection\n );\n}\n","import { MarkedCollection } from './types/markedCollection.types';\n\n/**\n * Creates a marked collection from an array of items.\n * A marked collection is a wrapper around an array that indicates it should be treated as a collection.\n *\n * @template T - The type of items in the collection\n * @param {T[]} items - The array of items to wrap in a collection\n * @returns {MarkedCollection<T>} A marked collection containing the provided items\n * @example\n * const users = collection([{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }]);\n */\nexport function collection<T>(items: T[]): MarkedCollection<T> {\n return {\n _collection: true,\n items\n };\n}\n"],"mappings":";AAAA,SAAS,gCAAgC;AACzC;AAAA,EAIE,cAAc;AAAA,EACd;AAAA,OACK;;;ACPP,SAAqB,kBAAkB;;;ACehC,SAAS,mBACd,OAC8B;AAC9B,SACE,OAAO,UAAU,YACjB,UAAU,QACV,iBAAiB,SACjB,OAAO,MAAM,gBAAgB,aAC7B,MAAM;AAEV;;;ADPO,SAAS,gBAGd,MAAS,QAAc;AACvB,QAAM,oBAA6C,CAAC;AACpD,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,QAAI,mBAA2B,KAAK,GAAG;AACrC,wBAAkB,GAAG,IAAI,IAAI,WAAW,QAAQ,MAAM,KAAK;AAAA,IAC7D,OAAO;AACL,wBAAkB,GAAG,IAAI;AAAA,IAC3B;AAAA,EACF;AACA,SAAO;AACT;;;ADLO,IAAeA,cAAf,cAAkC,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAS1D,OAAO,UAEF,MACK;AACR,UAAM,CAAC,MAAM,GAAG,cAAc,IAAI;AAClC,WAAO,IAAI,KAAK,EAAE;AAAA,MAChB;AAAA,MACA,GAAG;AAAA,IACL;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,OAAO,UAEF,MACK;AACR,UAAM,CAAC,MAAM,GAAG,cAAc,IAAI;AAClC,WAAO,IAAI,KAAK,EAAE;AAAA,MAChB;AAAA,MACA,GAAG;AAAA,IACL;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,OAAO,IAEL,MACQ;AACR,WAAO,IAAI,KAAK,EAAE,IAAI,IAAI;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,MAAiD;AACtD,WAAO,OAAO,OAAO,MAAM,gBAAgB,MAAM,IAAI,CAAC;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,MAAiD;AACtD,SAAK,IAAI,EAAE;AAAA,MACT,yBAAyB,gBAAgB,MAAM,IAAI,CAAC;AAAA,IAGtD;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAA+B;AAC7B,QAAI,OAAO,KAAK,IAAI,EAAE,WAAW,YAAY;AAC3C,aAAO,KAAK,IAAI,EAAE,OAAO;AAAA,IAC3B;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAI,MAAsD;AACxD,SAAK,IAAI,EAAE,OAAO,IAAI;AACtB,WAAO;AAAA,EACT;AACF;;;AGnHO,SAAS,WAAc,OAAiC;AAC7D,SAAO;AAAA,IACL,aAAa;AAAA,IACb;AAAA,EACF;AACF;","names":["BaseEntity"]}
1
+ {"version":3,"sources":["../../../src/persistence/base.entity.ts","../../../src/persistence/transformRawDto.ts","../../../src/persistence/guards/isMarkedCollection.ts","../../../src/persistence/collection.ts"],"sourcesContent":["import { stripUndefinedProperties } from '@forklaunch/common';\nimport {\n Constructor,\n EntityDTO,\n FromEntityType,\n BaseEntity as MikroOrmBaseEntity,\n wrap\n} from '@mikro-orm/core';\nimport { transformRawDto } from './transformRawDto';\nimport { CreateShape, UpdateShape } from './types/shapes.types';\n\n/**\n * Type representing a base entity with common fields.\n * Extends BaseEntity with optional id, _id, createdAt, and updatedAt fields.\n */\ntype BaseEntityWithId = BaseEntity & {\n id?: unknown;\n _id?: unknown;\n createdAt?: unknown;\n updatedAt?: unknown;\n};\n\n/**\n * Abstract base class for all entities in the system.\n * Extends MikroORM's BaseEntity and provides common CRUD operations.\n */\nexport abstract class BaseEntity extends MikroOrmBaseEntity {\n /**\n * Static factory method to create a new entity instance.\n *\n * @template Entity - The type of entity being created\n * @param {Constructor<Entity>} this - The entity constructor\n * @param {...Parameters<Entity['create']>} args - Arguments for entity creation\n * @returns {Entity} A new entity instance\n */\n static async create<Entity extends BaseEntityWithId>(\n this: Constructor<Entity>,\n ...args: Parameters<Entity['create']>\n ): Promise<Entity> {\n const [data, ...additionalArgs] = args;\n const entity = new this();\n await entity.create(\n data as CreateShape<BaseEntityWithId, Entity>,\n ...additionalArgs\n );\n return entity;\n }\n\n /**\n * Static method to update an entity instance.\n *\n * @template Entity - The type of entity being updated\n * @param {Constructor<Entity>} this - The entity constructor\n * @param {...Parameters<Entity['update']>} args - Arguments for entity update\n * @returns {Entity} The updated entity instance\n */\n static async update<Entity extends BaseEntityWithId>(\n this: Constructor<Entity>,\n ...args: Parameters<Entity['update']>\n ): Promise<Entity> {\n const [data, ...additionalArgs] = args;\n const entity = new this();\n await entity.update(\n data as UpdateShape<BaseEntity, Entity>,\n ...additionalArgs\n );\n return entity;\n }\n\n /**\n * Static method to map data to an entity instance.\n *\n * @template Entity - The type of entity being mapped\n * @param {Constructor<Entity>} this - The entity constructor\n * @param {Partial<EntityDTO<FromEntityType<Entity>>>} data - The data to map\n * @returns {Entity} A new entity instance with mapped data\n */\n static async map<Entity extends BaseEntity>(\n this: Constructor<Entity>,\n data: Partial<EntityDTO<FromEntityType<Entity>>>\n ): Promise<Entity> {\n const entity = new this();\n await entity.map(data);\n return entity;\n }\n\n /**\n * Creates a new entity instance with the provided data.\n *\n * @param {CreateShape<BaseEntityWithId, this>} data - The data to create the entity with\n * @returns {this} The created entity instance\n */\n async create(\n data: CreateShape<BaseEntityWithId, this>\n ): Promise<EntityDTO<this>> {\n Object.assign(this, transformRawDto(data, this));\n const entity = await wrap(this).init();\n if (!entity) {\n throw new Error('Entity not initialized');\n }\n return entity.toObject();\n }\n\n /**\n * Updates the entity instance with the provided data.\n *\n * @param {UpdateShape<BaseEntityWithId, this>} data - The data to update the entity with\n * @returns {this} The updated entity instance\n */\n async update(\n data: UpdateShape<BaseEntityWithId, this>\n ): Promise<EntityDTO<this>> {\n const entity = wrap(this);\n entity.assign(\n stripUndefinedProperties(transformRawDto(data, this)) as Partial<\n EntityDTO<FromEntityType<this>>\n >\n );\n return entity.toObject();\n }\n\n /**\n * Reads the entity data as a plain object.\n *\n * @returns {EntityDTO<this> | this} The entity data as a plain object\n */\n async read(): Promise<EntityDTO<this>> {\n const entity = await wrap(this).init();\n if (!entity) {\n throw new Error('Entity not initialized');\n }\n return entity.toObject();\n }\n\n /**\n * Maps data to the entity instance.\n *\n * @param {Partial<EntityDTO<FromEntityType<this>>>} data - The data to map\n * @returns {this} The entity instance with mapped data\n */\n async map(data: Partial<EntityDTO<FromEntityType<this>>>): Promise<this> {\n const entity = await wrap(this).init();\n\n if (!entity) {\n throw new Error('Entity not initialized');\n }\n entity.assign(data);\n return entity;\n }\n}\n","import { BaseEntity, Collection } from '@mikro-orm/core';\nimport { isMarkedCollection } from './guards/isMarkedCollection';\n\n/**\n * Transforms a raw DTO (Data Transfer Object) by converting marked collections into MikroORM collections.\n * This function is used to properly handle collections when converting between DTOs and entities.\n *\n * @template T - The type of the DTO being transformed\n * @template U - The type of the entity being transformed into\n * @param {T} data - The raw DTO data to transform\n * @param {U} entity - The entity instance to associate collections with\n * @returns {T} The transformed DTO with collections properly initialized\n * @example\n * const dto = { users: { _collection: true, items: [{ id: 1 }] } };\n * const entity = new UserEntity();\n * const transformed = transformRawDto(dto, entity);\n * // transformed.users is now a MikroORM Collection\n */\nexport function transformRawDto<\n T extends Record<string, unknown>,\n U extends BaseEntity\n>(data: T, entity: U): T {\n const transformedObject: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n if (isMarkedCollection<object>(value)) {\n transformedObject[key] = new Collection(entity, value.items);\n } else {\n transformedObject[key] = value;\n }\n }\n return transformedObject as T;\n}\n","import { MarkedCollection } from '../types/markedCollection.types';\n\n/**\n * Type guard function that checks if a value is a marked collection.\n *\n * @template T - The type of items in the collection\n * @param {unknown} value - The value to check\n * @returns {value is MarkedCollection<T>} True if the value is a marked collection, false otherwise\n * @example\n * const value = { _collection: true, items: [1, 2, 3] };\n * if (isMarkedCollection<number>(value)) {\n * // value is now typed as MarkedCollection<number>\n * console.log(value.items); // [1, 2, 3]\n * }\n */\nexport function isMarkedCollection<T>(\n value: unknown\n): value is MarkedCollection<T> {\n return (\n typeof value === 'object' &&\n value !== null &&\n '_collection' in value &&\n typeof value._collection === 'boolean' &&\n value._collection\n );\n}\n","import { MarkedCollection } from './types/markedCollection.types';\n\n/**\n * Creates a marked collection from an array of items.\n * A marked collection is a wrapper around an array that indicates it should be treated as a collection.\n *\n * @template T - The type of items in the collection\n * @param {T[]} items - The array of items to wrap in a collection\n * @returns {MarkedCollection<T>} A marked collection containing the provided items\n * @example\n * const users = collection([{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }]);\n */\nexport function collection<T>(items: T[]): MarkedCollection<T> {\n return {\n _collection: true,\n items\n };\n}\n"],"mappings":";AAAA,SAAS,gCAAgC;AACzC;AAAA,EAIE,cAAc;AAAA,EACd;AAAA,OACK;;;ACPP,SAAqB,kBAAkB;;;ACehC,SAAS,mBACd,OAC8B;AAC9B,SACE,OAAO,UAAU,YACjB,UAAU,QACV,iBAAiB,SACjB,OAAO,MAAM,gBAAgB,aAC7B,MAAM;AAEV;;;ADPO,SAAS,gBAGd,MAAS,QAAc;AACvB,QAAM,oBAA6C,CAAC;AACpD,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,QAAI,mBAA2B,KAAK,GAAG;AACrC,wBAAkB,GAAG,IAAI,IAAI,WAAW,QAAQ,MAAM,KAAK;AAAA,IAC7D,OAAO;AACL,wBAAkB,GAAG,IAAI;AAAA,IAC3B;AAAA,EACF;AACA,SAAO;AACT;;;ADLO,IAAeA,cAAf,cAAkC,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAS1D,aAAa,UAER,MACc;AACjB,UAAM,CAAC,MAAM,GAAG,cAAc,IAAI;AAClC,UAAM,SAAS,IAAI,KAAK;AACxB,UAAM,OAAO;AAAA,MACX;AAAA,MACA,GAAG;AAAA,IACL;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,aAAa,UAER,MACc;AACjB,UAAM,CAAC,MAAM,GAAG,cAAc,IAAI;AAClC,UAAM,SAAS,IAAI,KAAK;AACxB,UAAM,OAAO;AAAA,MACX;AAAA,MACA,GAAG;AAAA,IACL;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,aAAa,IAEX,MACiB;AACjB,UAAM,SAAS,IAAI,KAAK;AACxB,UAAM,OAAO,IAAI,IAAI;AACrB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OACJ,MAC0B;AAC1B,WAAO,OAAO,MAAM,gBAAgB,MAAM,IAAI,CAAC;AAC/C,UAAM,SAAS,MAAM,KAAK,IAAI,EAAE,KAAK;AACrC,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,wBAAwB;AAAA,IAC1C;AACA,WAAO,OAAO,SAAS;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OACJ,MAC0B;AAC1B,UAAM,SAAS,KAAK,IAAI;AACxB,WAAO;AAAA,MACL,yBAAyB,gBAAgB,MAAM,IAAI,CAAC;AAAA,IAGtD;AACA,WAAO,OAAO,SAAS;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,OAAiC;AACrC,UAAM,SAAS,MAAM,KAAK,IAAI,EAAE,KAAK;AACrC,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,wBAAwB;AAAA,IAC1C;AACA,WAAO,OAAO,SAAS;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,IAAI,MAA+D;AACvE,UAAM,SAAS,MAAM,KAAK,IAAI,EAAE,KAAK;AAErC,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,wBAAwB;AAAA,IAC1C;AACA,WAAO,OAAO,IAAI;AAClB,WAAO;AAAA,EACT;AACF;;;AGzIO,SAAS,WAAc,OAAiC;AAC7D,SAAO;AAAA,IACL,aAAa;AAAA,IACb;AAAA,EACF;AACF;","names":["BaseEntity"]}
@@ -1,6 +1,8 @@
1
1
  import { AnySchemaValidator, IdiomaticSchema, Schema, ParseResult } from '@forklaunch/validator';
2
2
  import { EntityManager as EntityManager$1, Collection } from '@mikro-orm/core';
3
3
 
4
+ declare function getEnvVar(name: string): string;
5
+
4
6
  declare enum Lifetime {
5
7
  Singleton = 0,
6
8
  Transient = 1,
@@ -74,8 +76,6 @@ declare class ValidConfigInjector<SV extends AnySchemaValidator, CV extends Conf
74
76
  validConfigInjector: void;
75
77
  }
76
78
 
77
- declare function getEnvVar(name: string): string;
78
-
79
79
  /**
80
80
  * Interface representing a base service.
81
81
  *
@@ -1,6 +1,8 @@
1
1
  import { AnySchemaValidator, IdiomaticSchema, Schema, ParseResult } from '@forklaunch/validator';
2
2
  import { EntityManager as EntityManager$1, Collection } from '@mikro-orm/core';
3
3
 
4
+ declare function getEnvVar(name: string): string;
5
+
4
6
  declare enum Lifetime {
5
7
  Singleton = 0,
6
8
  Transient = 1,
@@ -74,8 +76,6 @@ declare class ValidConfigInjector<SV extends AnySchemaValidator, CV extends Conf
74
76
  validConfigInjector: void;
75
77
  }
76
78
 
77
- declare function getEnvVar(name: string): string;
78
-
79
79
  /**
80
80
  * Interface representing a base service.
81
81
  *
@@ -26,6 +26,12 @@ __export(services_exports, {
26
26
  });
27
27
  module.exports = __toCommonJS(services_exports);
28
28
 
29
+ // ../common/src/getEnvVar.ts
30
+ function getEnvVar(name) {
31
+ const value = process.env[name];
32
+ return value;
33
+ }
34
+
29
35
  // src/services/configInjector.ts
30
36
  var import_common = require("@forklaunch/common");
31
37
  var import_validator = require("@forklaunch/validator");
@@ -304,12 +310,6 @@ var ConfigInjector = class _ConfigInjector {
304
310
  var ValidConfigInjector = class extends ConfigInjector {
305
311
  validConfigInjector;
306
312
  };
307
-
308
- // src/services/getEnvVar.ts
309
- function getEnvVar(name) {
310
- const value = process.env[name];
311
- return value;
312
- }
313
313
  // Annotate the CommonJS export names for ESM import in node:
314
314
  0 && (module.exports = {
315
315
  Lifetime,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/index.ts","../../../src/services/configInjector.ts","../../../src/services/guards/isConstructed.ts","../../../src/services/types/configInjector.types.ts","../../../src/services/guards/isConstructedSingleton.ts","../../../src/services/guards/isConstructor.ts","../../../src/services/getEnvVar.ts"],"sourcesContent":["export { createConfigInjector } from './configInjector';\nexport type { ConfigInjector, ValidConfigInjector } from './configInjector';\nexport * from './getEnvVar';\nexport * from './interfaces/baseService';\nexport * from './types/configInjector.types';\nexport * from './types/entityManager.types';\nexport * from './types/service.types';\n","import { extractArgumentNames, isNever } from '@forklaunch/common';\nimport {\n AnySchemaValidator,\n IdiomaticSchema,\n ParseResult,\n prettyPrintParseErrors,\n SchemaValidator\n} from '@forklaunch/validator';\nimport { isConstructed } from './guards/isConstructed';\nimport { isConstructedSingleton } from './guards/isConstructedSingleton';\nimport { isConstructor } from './guards/isConstructor';\nimport {\n ConfigValidator,\n Constructed,\n ConstructedSingleton,\n Lifetime,\n ResolvedConfigValidator,\n SchemaConstructor,\n SchemaFunction,\n Singleton\n} from './types/configInjector.types';\n\nexport function createConfigInjector<\n SV extends AnySchemaValidator,\n CV extends ConfigValidator<SV>\n>(\n schemaValidator: SV,\n dependenciesDefinition: {\n [K in keyof CV]:\n | Singleton<\n CV[K],\n Omit<ResolvedConfigValidator<SV, CV>, K>,\n ResolvedConfigValidator<SV, CV>[K]\n >\n | Constructed<\n CV[K],\n Omit<ResolvedConfigValidator<SV, CV>, K>,\n ResolvedConfigValidator<SV, CV>[K]\n >;\n }\n) {\n return new ConfigInjector<SV, CV>(\n schemaValidator,\n dependenciesDefinition\n ).load();\n}\n\nexport class ConfigInjector<\n SV extends AnySchemaValidator,\n CV extends ConfigValidator<SV>\n> {\n instances: {\n [K in keyof CV]?: ResolvedConfigValidator<SV, CV>[K];\n } = {};\n\n readonly configShapes: CV;\n\n load(inheritedScopeInstances?: {\n [K in keyof CV]?: ResolvedConfigValidator<SV, CV>[K];\n }): this {\n for (const token in inheritedScopeInstances) {\n this.instances[token] = inheritedScopeInstances[token];\n }\n\n for (const token in this.dependenciesDefinition) {\n const definition = this.dependenciesDefinition[token];\n if (\n definition.lifetime === Lifetime.Singleton &&\n !this.instances[token]\n ) {\n if (\n isConstructedSingleton<\n CV[typeof token],\n Omit<ResolvedConfigValidator<SV, CV>, typeof token>,\n ResolvedConfigValidator<SV, CV>[typeof token]\n >(definition)\n ) {\n this.instances[token] = this.resolveInstance<typeof token>(\n token,\n definition\n );\n } else {\n this.instances[token] = definition.value;\n }\n }\n }\n return this;\n }\n\n private resolveInstance<T extends keyof CV>(\n token: T,\n definition:\n | ConstructedSingleton<\n CV[T],\n Omit<ResolvedConfigValidator<SV, CV>, T>,\n ResolvedConfigValidator<SV, CV>[T]\n >\n | Constructed<\n CV[T],\n Omit<ResolvedConfigValidator<SV, CV>, T>,\n ResolvedConfigValidator<SV, CV>[T]\n >,\n context?: Record<string, unknown>,\n resolutionPath: (keyof CV)[] = []\n ): ResolvedConfigValidator<SV, CV>[T] {\n const injectorArgument = extractArgumentNames(definition.factory)[0];\n // short circuit as no args\n if (!injectorArgument || injectorArgument === '_args') {\n return definition.factory(\n {} as Omit<ResolvedConfigValidator<SV, CV>, T>,\n this.resolve.bind(this),\n context ?? ({} as Record<string, unknown>)\n );\n }\n\n if (!injectorArgument.startsWith('{') || !injectorArgument.endsWith('}')) {\n throw new Error(\n `Invalid injector argument for ${String(\n token\n )}: ${injectorArgument}. Please use object destructuring syntax: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment.`\n );\n }\n const resolvedArguments = Object.fromEntries(\n injectorArgument\n .replace('{', '')\n .replace('}', '')\n .split(',')\n .map((arg) => arg.split(':')[0].trim())\n .map((arg) => {\n const newResolutionPath = [...resolutionPath, token];\n if (resolutionPath.includes(arg)) {\n throw new Error(\n `Circular dependency detected: ${newResolutionPath.join(\n ' -> '\n )} -> ${arg}`\n );\n }\n const resolvedArg = this.resolve(arg, context, newResolutionPath);\n return [arg, resolvedArg];\n })\n ) as unknown as Omit<ResolvedConfigValidator<SV, CV>, T>;\n return definition.factory(\n resolvedArguments,\n this.resolve.bind(this),\n context ?? ({} as Record<string, unknown>)\n );\n }\n\n constructor(\n private schemaValidator: SV,\n private dependenciesDefinition: {\n [K in keyof CV]: (\n | Singleton<\n CV[K],\n Omit<ResolvedConfigValidator<SV, CV>, K>,\n ResolvedConfigValidator<SV, CV>[K]\n >\n | Constructed<\n CV[K],\n Omit<ResolvedConfigValidator<SV, CV>, K>,\n ResolvedConfigValidator<SV, CV>[K]\n >\n ) & {\n type: CV[K];\n };\n }\n ) {\n this.configShapes = Object.entries(this.dependenciesDefinition).reduce(\n (acc, [key, { type }]) => ({\n ...acc,\n [key]: type\n }),\n {} as Record<keyof CV, CV[keyof CV]>\n ) as CV;\n }\n\n safeValidateConfigSingletons(): ParseResult<ValidConfigInjector<SV, CV>> {\n const validNonSchemaSingletons = Object.entries(this.configShapes).reduce<\n ParseResult<ResolvedConfigValidator<SV, CV>>\n >(\n (acc, [key, value]) => {\n if (\n this.dependenciesDefinition[key].lifetime === Lifetime.Singleton &&\n !(this.schemaValidator as SchemaValidator).isSchema<\n SchemaFunction<SV> | SchemaConstructor<SV> | IdiomaticSchema<SV>\n >(value) &&\n isConstructor(value)\n ) {\n if (!(this.instances[key] instanceof value)) {\n const expected = value.name;\n const receivedValue: unknown = this.instances[key];\n const received = isConstructed(receivedValue)\n ? receivedValue.constructor.name\n : typeof receivedValue;\n\n if (acc.ok) {\n acc = {\n ok: false,\n errors: []\n };\n }\n acc.errors?.push({\n message: `Expected ${expected}, received ${received}`,\n path: [key]\n });\n } else {\n if (acc.ok) {\n acc = {\n ok: true,\n value: {\n ...acc.value,\n [key]: this.instances[key]\n }\n };\n }\n }\n return acc;\n }\n return acc;\n },\n {\n ok: true,\n value: {} as ResolvedConfigValidator<SV, CV>\n }\n );\n\n const singletons = Object.fromEntries(\n Object.entries(this.configShapes).filter(\n ([key, value]) =>\n this.dependenciesDefinition[key].lifetime === Lifetime.Singleton &&\n (this.schemaValidator as SchemaValidator).isSchema(value)\n )\n );\n const schemaSingletonParseResult = (\n this.schemaValidator as SchemaValidator\n ).parse(\n (this.schemaValidator as SchemaValidator).schemify(singletons),\n Object.fromEntries(\n Object.keys(singletons).map((key) => {\n const dependency = this.dependenciesDefinition[key];\n return [\n key,\n dependency.lifetime === Lifetime.Singleton\n ? this.instances[key]\n : undefined\n ];\n })\n )\n );\n\n const configKeys = Object.keys(this.configShapes);\n\n return validNonSchemaSingletons.ok && schemaSingletonParseResult.ok\n ? {\n ok: true as const,\n value: new ValidConfigInjector<SV, CV>(\n this.schemaValidator,\n this.dependenciesDefinition\n ).load({ ...this.instances })\n }\n : {\n ok: false as const,\n errors: [\n ...(!validNonSchemaSingletons.ok && validNonSchemaSingletons.errors\n ? validNonSchemaSingletons.errors\n : []),\n ...(!schemaSingletonParseResult.ok &&\n schemaSingletonParseResult.errors\n ? schemaSingletonParseResult.errors\n : [])\n ].sort(\n (a, b) =>\n configKeys.indexOf(a.path[0]) - configKeys.indexOf(b.path[0])\n )\n };\n }\n\n validateConfigSingletons(configName: string): ValidConfigInjector<SV, CV> {\n const safeValidateResult = this.safeValidateConfigSingletons();\n\n if (safeValidateResult.ok) {\n return safeValidateResult.value;\n }\n\n throw new Error(\n prettyPrintParseErrors(safeValidateResult.errors, configName)\n );\n }\n\n resolve<T extends keyof CV>(\n token: T,\n context?: Record<string, unknown>,\n resolutionPath: (keyof CV)[] = []\n ): ResolvedConfigValidator<SV, CV>[T] {\n const instance = this.instances[token];\n if (!instance) {\n const definition = this.dependenciesDefinition[token];\n\n if (!definition) {\n throw new Error(`Unable to resolve dependency ${String(token)}`);\n }\n\n switch (definition.lifetime) {\n case Lifetime.Singleton: {\n if (\n isConstructedSingleton<\n CV[T],\n Omit<ResolvedConfigValidator<SV, CV>, T>,\n ResolvedConfigValidator<SV, CV>[T]\n >(definition) &&\n !this.instances[token]\n ) {\n this.instances[token] = this.resolveInstance<T>(\n token,\n definition,\n context,\n resolutionPath\n );\n }\n return this.instances[token] as ResolvedConfigValidator<SV, CV>[T];\n }\n case Lifetime.Scoped: {\n if (\n !isConstructed<\n CV[T],\n Omit<ResolvedConfigValidator<SV, CV>, T>,\n ResolvedConfigValidator<SV, CV>[T]\n >(definition)\n ) {\n throw new Error(\n `Invalid dependency definition for ${String(token)}`\n );\n }\n\n const scopedInstance = this.resolveInstance<T>(\n token,\n definition,\n context,\n resolutionPath\n );\n this.instances[token] = scopedInstance;\n return scopedInstance;\n }\n case Lifetime.Transient: {\n if (\n !isConstructed<\n CV[T],\n Omit<ResolvedConfigValidator<SV, CV>, T>,\n ResolvedConfigValidator<SV, CV>[T]\n >(definition)\n ) {\n throw new Error(\n `Invalid dependency definition for ${String(token)}`\n );\n }\n\n return this.resolveInstance<T>(\n token,\n definition,\n context,\n resolutionPath\n );\n }\n default: {\n isNever(definition);\n throw new Error(\n `Unable to resolve lifetime for dependency ${String(\n token\n )}, ${resolutionPath}`\n );\n }\n }\n } else {\n return instance;\n }\n }\n\n scopedResolver<T extends keyof CV>(\n token: T,\n context?: Record<string, unknown>,\n resolutionPath: (keyof CV)[] = []\n ): (scope?: ConfigInjector<SV, CV>) => ResolvedConfigValidator<SV, CV>[T] {\n return (scope) =>\n (scope ?? this.createScope()).resolve<T>(token, context, resolutionPath);\n }\n\n createScope(): ConfigInjector<SV, CV> {\n const singletons: Record<string, unknown> = {};\n for (const dependency in this.dependenciesDefinition) {\n if (\n this.dependenciesDefinition[dependency].lifetime === Lifetime.Singleton\n ) {\n singletons[dependency] = this.instances[dependency];\n }\n }\n return new ConfigInjector<SV, CV>(\n this.schemaValidator,\n this.dependenciesDefinition\n ).load(singletons as ResolvedConfigValidator<SV, CV>);\n }\n\n dispose(): void {\n this.instances = {};\n this.load();\n }\n\n chain<ChainedCV extends ConfigValidator<SV>>(dependenciesDefinition: {\n [K in keyof ChainedCV]: {\n type: ChainedCV[K];\n } & (\n | Singleton<\n ChainedCV[K],\n Omit<ResolvedConfigValidator<SV, CV & ChainedCV>, K>,\n ResolvedConfigValidator<SV, ChainedCV>[K]\n >\n | Constructed<\n ChainedCV[K],\n Omit<ResolvedConfigValidator<SV, CV & ChainedCV>, K>,\n ResolvedConfigValidator<SV, ChainedCV>[K]\n >\n );\n }): ConfigInjector<SV, CV & ChainedCV> {\n return new ConfigInjector<SV, CV>(this.schemaValidator, {\n ...this.dependenciesDefinition,\n ...dependenciesDefinition\n }).load({ ...this.instances }) as unknown as ConfigInjector<\n SV,\n CV & ChainedCV\n >;\n }\n\n tokens(): {\n [K in keyof CV]: K;\n } {\n return Object.fromEntries(\n Object.keys(this.dependenciesDefinition).map((key) => [key, key])\n ) as {\n [K in keyof CV]: K;\n };\n }\n}\n\nexport class ValidConfigInjector<\n SV extends AnySchemaValidator,\n CV extends ConfigValidator<SV>\n> extends ConfigInjector<SV, CV> {\n validConfigInjector!: void;\n}\n","import { Constructed } from '../types/configInjector.types';\n\nexport function isConstructed<Type, Args, Return>(\n value: unknown\n): value is Constructed<Type, Args, Return> {\n return (\n typeof value === 'object' &&\n value != null &&\n 'constructor' in value &&\n value.constructor != null\n );\n}\n","import {\n AnySchemaValidator,\n IdiomaticSchema,\n Schema\n} from '@forklaunch/validator';\nimport { ConfigInjector } from '../configInjector';\n\nexport enum Lifetime {\n Singleton,\n Transient,\n Scoped\n}\n\nexport type Singleton<Type, Args, Value> =\n | {\n lifetime: Lifetime.Singleton;\n type: Type;\n value: Value;\n }\n | ConstructedSingleton<Type, Args, Value>;\n\nexport type ConstructedSingleton<Type, Args, Return> = {\n lifetime: Lifetime.Singleton;\n type: Type;\n factory: (\n args: Args,\n resolve: <T extends keyof Args>(\n token: T,\n context?: Record<string, unknown>\n ) => Args[T],\n context: Record<string, unknown>\n ) => Return;\n};\n\nexport type Constructed<Type, Args, Return> = {\n lifetime: Lifetime.Transient | Lifetime.Scoped;\n type: Type;\n factory: (\n args: Args,\n resolve: <T extends keyof Args>(\n token: T,\n context?: Record<string, unknown>\n ) => Args[T],\n context: Record<string, unknown>\n ) => Return;\n};\n\nexport type Constructor = new (...args: never[]) => unknown;\nexport type SchemaConstructor<SV extends AnySchemaValidator> = new (\n ...args: unknown[]\n) => IdiomaticSchema<SV>;\nexport type Function = (...args: never[]) => unknown;\nexport type FunctionToConstructor = (\n ...args: never[]\n) => new (...args: never[]) => unknown;\nexport type SchemaFunction<SV extends AnySchemaValidator> = (\n args: unknown\n) => IdiomaticSchema<SV>;\n\nexport type ConfigTypes<SV extends AnySchemaValidator> =\n | Function\n | SchemaFunction<SV>\n | Constructor\n | SchemaConstructor<SV>\n | IdiomaticSchema<SV>;\n\nexport type ConfigValidator<SV extends AnySchemaValidator> = Record<\n string,\n ConfigTypes<SV> | Record<string, ConfigTypes<SV>>\n>;\n\ntype ResolveConfigValue<SV extends AnySchemaValidator, T> =\n T extends SchemaConstructor<SV>\n ? Schema<InstanceType<T>, SV>\n : T extends SchemaFunction<SV>\n ? (...args: Parameters<T>) => Schema<ReturnType<T>, SV>\n : T extends FunctionToConstructor\n ? (...args: Parameters<T>) => InstanceType<ReturnType<T>>\n : T extends Function\n ? (...args: Parameters<T>) => ReturnType<T>\n : T extends Constructor\n ? InstanceType<T>\n : T extends IdiomaticSchema<SV>\n ? Schema<T, SV>\n : T extends Record<string, ConfigTypes<SV>>\n ? {\n [K in keyof T]: ResolveConfigValue<SV, T[K]>;\n }\n : Schema<T, SV>;\n\nexport type ResolvedConfigValidator<\n SV extends AnySchemaValidator,\n CV extends ConfigValidator<SV>\n> = {\n [M in keyof CV]: ResolveConfigValue<SV, CV[M]>;\n};\n\nexport type ScopedDependencyFactory<\n SV extends AnySchemaValidator,\n CV extends ConfigValidator<SV>,\n M extends keyof CV\n> = (scope?: ConfigInjector<SV, CV>) => ResolvedConfigValidator<SV, CV>[M];\n","import { ConstructedSingleton, Lifetime } from '../types/configInjector.types';\n\nexport function isConstructedSingleton<Type, Args, Return>(\n value: unknown\n): value is ConstructedSingleton<Type, Args, Return> {\n return (\n typeof value === 'object' &&\n value != null &&\n 'lifetime' in value &&\n value.lifetime === Lifetime.Singleton &&\n 'factory' in value\n );\n}\n","import { Constructor } from '../types/configInjector.types';\n\nexport function isConstructor(value: unknown): value is Constructor {\n return (\n typeof value === 'function' &&\n value.constructor != null &&\n value.prototype != null\n );\n}\n","// This is a simple function that returns the value of an environment variable.\n// It casts a potentially undefined value to a string, since it will be validated in order to be bootstrapped.\n\nexport function getEnvVar(name: string): string {\n const value = process.env[name];\n return value as string;\n}\n"],"mappings":"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","names":["Lifetime"]}
1
+ {"version":3,"sources":["../../../src/services/index.ts","../../../../common/src/getEnvVar.ts","../../../src/services/configInjector.ts","../../../src/services/guards/isConstructed.ts","../../../src/services/types/configInjector.types.ts","../../../src/services/guards/isConstructedSingleton.ts","../../../src/services/guards/isConstructor.ts"],"sourcesContent":["export * from '../../../common/src/getEnvVar';\nexport { createConfigInjector } from './configInjector';\nexport type { ConfigInjector, ValidConfigInjector } from './configInjector';\nexport * from './interfaces/baseService';\nexport * from './types/configInjector.types';\nexport * from './types/entityManager.types';\nexport * from './types/service.types';\n","// This is a simple function that returns the value of an environment variable.\n// It casts a potentially undefined value to a string, since it will be validated in order to be bootstrapped.\n\nexport function getEnvVar(name: string): string {\n const value = process.env[name];\n return value as string;\n}\n","import { extractArgumentNames, isNever } from '@forklaunch/common';\nimport {\n AnySchemaValidator,\n IdiomaticSchema,\n ParseResult,\n prettyPrintParseErrors,\n SchemaValidator\n} from '@forklaunch/validator';\nimport { isConstructed } from './guards/isConstructed';\nimport { isConstructedSingleton } from './guards/isConstructedSingleton';\nimport { isConstructor } from './guards/isConstructor';\nimport {\n ConfigValidator,\n Constructed,\n ConstructedSingleton,\n Lifetime,\n ResolvedConfigValidator,\n SchemaConstructor,\n SchemaFunction,\n Singleton\n} from './types/configInjector.types';\n\nexport function createConfigInjector<\n SV extends AnySchemaValidator,\n CV extends ConfigValidator<SV>\n>(\n schemaValidator: SV,\n dependenciesDefinition: {\n [K in keyof CV]:\n | Singleton<\n CV[K],\n Omit<ResolvedConfigValidator<SV, CV>, K>,\n ResolvedConfigValidator<SV, CV>[K]\n >\n | Constructed<\n CV[K],\n Omit<ResolvedConfigValidator<SV, CV>, K>,\n ResolvedConfigValidator<SV, CV>[K]\n >;\n }\n) {\n return new ConfigInjector<SV, CV>(\n schemaValidator,\n dependenciesDefinition\n ).load();\n}\n\nexport class ConfigInjector<\n SV extends AnySchemaValidator,\n CV extends ConfigValidator<SV>\n> {\n instances: {\n [K in keyof CV]?: ResolvedConfigValidator<SV, CV>[K];\n } = {};\n\n readonly configShapes: CV;\n\n load(inheritedScopeInstances?: {\n [K in keyof CV]?: ResolvedConfigValidator<SV, CV>[K];\n }): this {\n for (const token in inheritedScopeInstances) {\n this.instances[token] = inheritedScopeInstances[token];\n }\n\n for (const token in this.dependenciesDefinition) {\n const definition = this.dependenciesDefinition[token];\n if (\n definition.lifetime === Lifetime.Singleton &&\n !this.instances[token]\n ) {\n if (\n isConstructedSingleton<\n CV[typeof token],\n Omit<ResolvedConfigValidator<SV, CV>, typeof token>,\n ResolvedConfigValidator<SV, CV>[typeof token]\n >(definition)\n ) {\n this.instances[token] = this.resolveInstance<typeof token>(\n token,\n definition\n );\n } else {\n this.instances[token] = definition.value;\n }\n }\n }\n return this;\n }\n\n private resolveInstance<T extends keyof CV>(\n token: T,\n definition:\n | ConstructedSingleton<\n CV[T],\n Omit<ResolvedConfigValidator<SV, CV>, T>,\n ResolvedConfigValidator<SV, CV>[T]\n >\n | Constructed<\n CV[T],\n Omit<ResolvedConfigValidator<SV, CV>, T>,\n ResolvedConfigValidator<SV, CV>[T]\n >,\n context?: Record<string, unknown>,\n resolutionPath: (keyof CV)[] = []\n ): ResolvedConfigValidator<SV, CV>[T] {\n const injectorArgument = extractArgumentNames(definition.factory)[0];\n // short circuit as no args\n if (!injectorArgument || injectorArgument === '_args') {\n return definition.factory(\n {} as Omit<ResolvedConfigValidator<SV, CV>, T>,\n this.resolve.bind(this),\n context ?? ({} as Record<string, unknown>)\n );\n }\n\n if (!injectorArgument.startsWith('{') || !injectorArgument.endsWith('}')) {\n throw new Error(\n `Invalid injector argument for ${String(\n token\n )}: ${injectorArgument}. Please use object destructuring syntax: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment.`\n );\n }\n const resolvedArguments = Object.fromEntries(\n injectorArgument\n .replace('{', '')\n .replace('}', '')\n .split(',')\n .map((arg) => arg.split(':')[0].trim())\n .map((arg) => {\n const newResolutionPath = [...resolutionPath, token];\n if (resolutionPath.includes(arg)) {\n throw new Error(\n `Circular dependency detected: ${newResolutionPath.join(\n ' -> '\n )} -> ${arg}`\n );\n }\n const resolvedArg = this.resolve(arg, context, newResolutionPath);\n return [arg, resolvedArg];\n })\n ) as unknown as Omit<ResolvedConfigValidator<SV, CV>, T>;\n return definition.factory(\n resolvedArguments,\n this.resolve.bind(this),\n context ?? ({} as Record<string, unknown>)\n );\n }\n\n constructor(\n private schemaValidator: SV,\n private dependenciesDefinition: {\n [K in keyof CV]: (\n | Singleton<\n CV[K],\n Omit<ResolvedConfigValidator<SV, CV>, K>,\n ResolvedConfigValidator<SV, CV>[K]\n >\n | Constructed<\n CV[K],\n Omit<ResolvedConfigValidator<SV, CV>, K>,\n ResolvedConfigValidator<SV, CV>[K]\n >\n ) & {\n type: CV[K];\n };\n }\n ) {\n this.configShapes = Object.entries(this.dependenciesDefinition).reduce(\n (acc, [key, { type }]) => ({\n ...acc,\n [key]: type\n }),\n {} as Record<keyof CV, CV[keyof CV]>\n ) as CV;\n }\n\n safeValidateConfigSingletons(): ParseResult<ValidConfigInjector<SV, CV>> {\n const validNonSchemaSingletons = Object.entries(this.configShapes).reduce<\n ParseResult<ResolvedConfigValidator<SV, CV>>\n >(\n (acc, [key, value]) => {\n if (\n this.dependenciesDefinition[key].lifetime === Lifetime.Singleton &&\n !(this.schemaValidator as SchemaValidator).isSchema<\n SchemaFunction<SV> | SchemaConstructor<SV> | IdiomaticSchema<SV>\n >(value) &&\n isConstructor(value)\n ) {\n if (!(this.instances[key] instanceof value)) {\n const expected = value.name;\n const receivedValue: unknown = this.instances[key];\n const received = isConstructed(receivedValue)\n ? receivedValue.constructor.name\n : typeof receivedValue;\n\n if (acc.ok) {\n acc = {\n ok: false,\n errors: []\n };\n }\n acc.errors?.push({\n message: `Expected ${expected}, received ${received}`,\n path: [key]\n });\n } else {\n if (acc.ok) {\n acc = {\n ok: true,\n value: {\n ...acc.value,\n [key]: this.instances[key]\n }\n };\n }\n }\n return acc;\n }\n return acc;\n },\n {\n ok: true,\n value: {} as ResolvedConfigValidator<SV, CV>\n }\n );\n\n const singletons = Object.fromEntries(\n Object.entries(this.configShapes).filter(\n ([key, value]) =>\n this.dependenciesDefinition[key].lifetime === Lifetime.Singleton &&\n (this.schemaValidator as SchemaValidator).isSchema(value)\n )\n );\n const schemaSingletonParseResult = (\n this.schemaValidator as SchemaValidator\n ).parse(\n (this.schemaValidator as SchemaValidator).schemify(singletons),\n Object.fromEntries(\n Object.keys(singletons).map((key) => {\n const dependency = this.dependenciesDefinition[key];\n return [\n key,\n dependency.lifetime === Lifetime.Singleton\n ? this.instances[key]\n : undefined\n ];\n })\n )\n );\n\n const configKeys = Object.keys(this.configShapes);\n\n return validNonSchemaSingletons.ok && schemaSingletonParseResult.ok\n ? {\n ok: true as const,\n value: new ValidConfigInjector<SV, CV>(\n this.schemaValidator,\n this.dependenciesDefinition\n ).load({ ...this.instances })\n }\n : {\n ok: false as const,\n errors: [\n ...(!validNonSchemaSingletons.ok && validNonSchemaSingletons.errors\n ? validNonSchemaSingletons.errors\n : []),\n ...(!schemaSingletonParseResult.ok &&\n schemaSingletonParseResult.errors\n ? schemaSingletonParseResult.errors\n : [])\n ].sort(\n (a, b) =>\n configKeys.indexOf(a.path[0]) - configKeys.indexOf(b.path[0])\n )\n };\n }\n\n validateConfigSingletons(configName: string): ValidConfigInjector<SV, CV> {\n const safeValidateResult = this.safeValidateConfigSingletons();\n\n if (safeValidateResult.ok) {\n return safeValidateResult.value;\n }\n\n throw new Error(\n prettyPrintParseErrors(safeValidateResult.errors, configName)\n );\n }\n\n resolve<T extends keyof CV>(\n token: T,\n context?: Record<string, unknown>,\n resolutionPath: (keyof CV)[] = []\n ): ResolvedConfigValidator<SV, CV>[T] {\n const instance = this.instances[token];\n if (!instance) {\n const definition = this.dependenciesDefinition[token];\n\n if (!definition) {\n throw new Error(`Unable to resolve dependency ${String(token)}`);\n }\n\n switch (definition.lifetime) {\n case Lifetime.Singleton: {\n if (\n isConstructedSingleton<\n CV[T],\n Omit<ResolvedConfigValidator<SV, CV>, T>,\n ResolvedConfigValidator<SV, CV>[T]\n >(definition) &&\n !this.instances[token]\n ) {\n this.instances[token] = this.resolveInstance<T>(\n token,\n definition,\n context,\n resolutionPath\n );\n }\n return this.instances[token] as ResolvedConfigValidator<SV, CV>[T];\n }\n case Lifetime.Scoped: {\n if (\n !isConstructed<\n CV[T],\n Omit<ResolvedConfigValidator<SV, CV>, T>,\n ResolvedConfigValidator<SV, CV>[T]\n >(definition)\n ) {\n throw new Error(\n `Invalid dependency definition for ${String(token)}`\n );\n }\n\n const scopedInstance = this.resolveInstance<T>(\n token,\n definition,\n context,\n resolutionPath\n );\n this.instances[token] = scopedInstance;\n return scopedInstance;\n }\n case Lifetime.Transient: {\n if (\n !isConstructed<\n CV[T],\n Omit<ResolvedConfigValidator<SV, CV>, T>,\n ResolvedConfigValidator<SV, CV>[T]\n >(definition)\n ) {\n throw new Error(\n `Invalid dependency definition for ${String(token)}`\n );\n }\n\n return this.resolveInstance<T>(\n token,\n definition,\n context,\n resolutionPath\n );\n }\n default: {\n isNever(definition);\n throw new Error(\n `Unable to resolve lifetime for dependency ${String(\n token\n )}, ${resolutionPath}`\n );\n }\n }\n } else {\n return instance;\n }\n }\n\n scopedResolver<T extends keyof CV>(\n token: T,\n context?: Record<string, unknown>,\n resolutionPath: (keyof CV)[] = []\n ): (scope?: ConfigInjector<SV, CV>) => ResolvedConfigValidator<SV, CV>[T] {\n return (scope) =>\n (scope ?? this.createScope()).resolve<T>(token, context, resolutionPath);\n }\n\n createScope(): ConfigInjector<SV, CV> {\n const singletons: Record<string, unknown> = {};\n for (const dependency in this.dependenciesDefinition) {\n if (\n this.dependenciesDefinition[dependency].lifetime === Lifetime.Singleton\n ) {\n singletons[dependency] = this.instances[dependency];\n }\n }\n return new ConfigInjector<SV, CV>(\n this.schemaValidator,\n this.dependenciesDefinition\n ).load(singletons as ResolvedConfigValidator<SV, CV>);\n }\n\n dispose(): void {\n this.instances = {};\n this.load();\n }\n\n chain<ChainedCV extends ConfigValidator<SV>>(dependenciesDefinition: {\n [K in keyof ChainedCV]: {\n type: ChainedCV[K];\n } & (\n | Singleton<\n ChainedCV[K],\n Omit<ResolvedConfigValidator<SV, CV & ChainedCV>, K>,\n ResolvedConfigValidator<SV, ChainedCV>[K]\n >\n | Constructed<\n ChainedCV[K],\n Omit<ResolvedConfigValidator<SV, CV & ChainedCV>, K>,\n ResolvedConfigValidator<SV, ChainedCV>[K]\n >\n );\n }): ConfigInjector<SV, CV & ChainedCV> {\n return new ConfigInjector<SV, CV>(this.schemaValidator, {\n ...this.dependenciesDefinition,\n ...dependenciesDefinition\n }).load({ ...this.instances }) as unknown as ConfigInjector<\n SV,\n CV & ChainedCV\n >;\n }\n\n tokens(): {\n [K in keyof CV]: K;\n } {\n return Object.fromEntries(\n Object.keys(this.dependenciesDefinition).map((key) => [key, key])\n ) as {\n [K in keyof CV]: K;\n };\n }\n}\n\nexport class ValidConfigInjector<\n SV extends AnySchemaValidator,\n CV extends ConfigValidator<SV>\n> extends ConfigInjector<SV, CV> {\n validConfigInjector!: void;\n}\n","import { Constructed } from '../types/configInjector.types';\n\nexport function isConstructed<Type, Args, Return>(\n value: unknown\n): value is Constructed<Type, Args, Return> {\n return (\n typeof value === 'object' &&\n value != null &&\n 'constructor' in value &&\n value.constructor != null\n );\n}\n","import {\n AnySchemaValidator,\n IdiomaticSchema,\n Schema\n} from '@forklaunch/validator';\nimport { ConfigInjector } from '../configInjector';\n\nexport enum Lifetime {\n Singleton,\n Transient,\n Scoped\n}\n\nexport type Singleton<Type, Args, Value> =\n | {\n lifetime: Lifetime.Singleton;\n type: Type;\n value: Value;\n }\n | ConstructedSingleton<Type, Args, Value>;\n\nexport type ConstructedSingleton<Type, Args, Return> = {\n lifetime: Lifetime.Singleton;\n type: Type;\n factory: (\n args: Args,\n resolve: <T extends keyof Args>(\n token: T,\n context?: Record<string, unknown>\n ) => Args[T],\n context: Record<string, unknown>\n ) => Return;\n};\n\nexport type Constructed<Type, Args, Return> = {\n lifetime: Lifetime.Transient | Lifetime.Scoped;\n type: Type;\n factory: (\n args: Args,\n resolve: <T extends keyof Args>(\n token: T,\n context?: Record<string, unknown>\n ) => Args[T],\n context: Record<string, unknown>\n ) => Return;\n};\n\nexport type Constructor = new (...args: never[]) => unknown;\nexport type SchemaConstructor<SV extends AnySchemaValidator> = new (\n ...args: unknown[]\n) => IdiomaticSchema<SV>;\nexport type Function = (...args: never[]) => unknown;\nexport type FunctionToConstructor = (\n ...args: never[]\n) => new (...args: never[]) => unknown;\nexport type SchemaFunction<SV extends AnySchemaValidator> = (\n args: unknown\n) => IdiomaticSchema<SV>;\n\nexport type ConfigTypes<SV extends AnySchemaValidator> =\n | Function\n | SchemaFunction<SV>\n | Constructor\n | SchemaConstructor<SV>\n | IdiomaticSchema<SV>;\n\nexport type ConfigValidator<SV extends AnySchemaValidator> = Record<\n string,\n ConfigTypes<SV> | Record<string, ConfigTypes<SV>>\n>;\n\ntype ResolveConfigValue<SV extends AnySchemaValidator, T> =\n T extends SchemaConstructor<SV>\n ? Schema<InstanceType<T>, SV>\n : T extends SchemaFunction<SV>\n ? (...args: Parameters<T>) => Schema<ReturnType<T>, SV>\n : T extends FunctionToConstructor\n ? (...args: Parameters<T>) => InstanceType<ReturnType<T>>\n : T extends Function\n ? (...args: Parameters<T>) => ReturnType<T>\n : T extends Constructor\n ? InstanceType<T>\n : T extends IdiomaticSchema<SV>\n ? Schema<T, SV>\n : T extends Record<string, ConfigTypes<SV>>\n ? {\n [K in keyof T]: ResolveConfigValue<SV, T[K]>;\n }\n : Schema<T, SV>;\n\nexport type ResolvedConfigValidator<\n SV extends AnySchemaValidator,\n CV extends ConfigValidator<SV>\n> = {\n [M in keyof CV]: ResolveConfigValue<SV, CV[M]>;\n};\n\nexport type ScopedDependencyFactory<\n SV extends AnySchemaValidator,\n CV extends ConfigValidator<SV>,\n M extends keyof CV\n> = (scope?: ConfigInjector<SV, CV>) => ResolvedConfigValidator<SV, CV>[M];\n","import { ConstructedSingleton, Lifetime } from '../types/configInjector.types';\n\nexport function isConstructedSingleton<Type, Args, Return>(\n value: unknown\n): value is ConstructedSingleton<Type, Args, Return> {\n return (\n typeof value === 'object' &&\n value != null &&\n 'lifetime' in value &&\n value.lifetime === Lifetime.Singleton &&\n 'factory' in value\n );\n}\n","import { Constructor } from '../types/configInjector.types';\n\nexport function isConstructor(value: unknown): value is Constructor {\n return (\n typeof value === 'function' &&\n value.constructor != null &&\n value.prototype != null\n );\n}\n"],"mappings":"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","names":["Lifetime"]}
@@ -1,3 +1,9 @@
1
+ // ../common/src/getEnvVar.ts
2
+ function getEnvVar(name) {
3
+ const value = process.env[name];
4
+ return value;
5
+ }
6
+
1
7
  // src/services/configInjector.ts
2
8
  import { extractArgumentNames, isNever } from "@forklaunch/common";
3
9
  import {
@@ -278,12 +284,6 @@ var ConfigInjector = class _ConfigInjector {
278
284
  var ValidConfigInjector = class extends ConfigInjector {
279
285
  validConfigInjector;
280
286
  };
281
-
282
- // src/services/getEnvVar.ts
283
- function getEnvVar(name) {
284
- const value = process.env[name];
285
- return value;
286
- }
287
287
  export {
288
288
  Lifetime,
289
289
  createConfigInjector,