@mikro-orm/core 7.1.0-dev.1 → 7.1.0-dev.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/EntityManager.d.ts +63 -11
- package/EntityManager.js +163 -18
- package/drivers/DatabaseDriver.d.ts +1 -0
- package/drivers/DatabaseDriver.js +3 -0
- package/drivers/IDatabaseDriver.d.ts +30 -1
- package/entity/BaseEntity.d.ts +70 -3
- package/entity/BaseEntity.js +18 -0
- package/entity/Collection.d.ts +6 -3
- package/entity/Collection.js +15 -4
- package/entity/EntityFactory.js +20 -1
- package/entity/EntityLoader.d.ts +3 -1
- package/entity/EntityLoader.js +39 -16
- package/entity/EntityRepository.d.ts +27 -9
- package/entity/EntityRepository.js +12 -0
- package/entity/Reference.d.ts +42 -1
- package/entity/Reference.js +9 -0
- package/entity/WrappedEntity.d.ts +2 -2
- package/entity/defineEntity.d.ts +81 -14
- package/entity/defineEntity.js +10 -6
- package/entity/utils.js +4 -5
- package/errors.d.ts +2 -0
- package/errors.js +4 -0
- package/index.d.ts +2 -2
- package/index.js +1 -1
- package/metadata/MetadataDiscovery.d.ts +11 -0
- package/metadata/MetadataDiscovery.js +127 -9
- package/metadata/MetadataValidator.js +9 -0
- package/metadata/types.d.ts +10 -2
- package/naming-strategy/AbstractNamingStrategy.d.ts +1 -1
- package/naming-strategy/NamingStrategy.d.ts +1 -1
- package/package.json +1 -1
- package/platforms/Platform.d.ts +5 -0
- package/platforms/Platform.js +7 -0
- package/serialization/EntitySerializer.d.ts +18 -6
- package/serialization/EntitySerializer.js +31 -5
- package/typings.d.ts +152 -14
- package/typings.js +19 -2
- package/utils/AbstractMigrator.d.ts +11 -1
- package/utils/AbstractMigrator.js +203 -0
- package/utils/Configuration.d.ts +7 -0
- package/utils/Configuration.js +1 -0
- package/utils/DataloaderUtils.d.ts +10 -1
- package/utils/DataloaderUtils.js +78 -0
- package/utils/QueryHelper.d.ts +16 -0
- package/utils/QueryHelper.js +15 -0
- package/utils/Utils.d.ts +1 -1
- package/utils/Utils.js +1 -1
- package/utils/fs-utils.d.ts +2 -0
- package/utils/fs-utils.js +7 -1
package/platforms/Platform.d.ts
CHANGED
|
@@ -211,6 +211,11 @@ export declare abstract class Platform {
|
|
|
211
211
|
getFullTextWhereClause(prop: EntityProperty): string;
|
|
212
212
|
supportsCreatingFullTextIndex(): boolean;
|
|
213
213
|
getFullTextIndexExpression(indexName: string, schemaName: string | undefined, tableName: string, columns: SimpleColumnMeta[]): string;
|
|
214
|
+
/**
|
|
215
|
+
* Generates the SQL index hint clause for the given index names.
|
|
216
|
+
* Returns `undefined` when the platform does not support index hints (e.g. PostgreSQL, SQLite).
|
|
217
|
+
*/
|
|
218
|
+
formatIndexHint(indexNames: string[]): string | undefined;
|
|
214
219
|
/** Whether the driver automatically parses JSON columns into JS objects. */
|
|
215
220
|
convertsJsonAutomatically(): boolean;
|
|
216
221
|
/** Converts a JS value to its JSON database representation (typically JSON.stringify). */
|
package/platforms/Platform.js
CHANGED
|
@@ -415,6 +415,13 @@ export class Platform {
|
|
|
415
415
|
getFullTextIndexExpression(indexName, schemaName, tableName, columns) {
|
|
416
416
|
throw new Error('Full text searching is not supported by this driver.');
|
|
417
417
|
}
|
|
418
|
+
/**
|
|
419
|
+
* Generates the SQL index hint clause for the given index names.
|
|
420
|
+
* Returns `undefined` when the platform does not support index hints (e.g. PostgreSQL, SQLite).
|
|
421
|
+
*/
|
|
422
|
+
formatIndexHint(indexNames) {
|
|
423
|
+
return undefined;
|
|
424
|
+
}
|
|
418
425
|
/** Whether the driver automatically parses JSON columns into JS objects. */
|
|
419
426
|
convertsJsonAutomatically() {
|
|
420
427
|
return true;
|
|
@@ -1,21 +1,33 @@
|
|
|
1
|
-
import type { ArrayElement, AutoPath, CleanTypeConfig, ExtractFieldsHint, FromEntityType, SerializeDTO, TypeConfig, UnboxArray } from '../typings.js';
|
|
1
|
+
import type { ArrayElement, AutoPath, CleanTypeConfig, ExtractFieldsHint, FromEntityType, ResolveSerializeFields, SerializeDTO, SerializeFieldsKeepPK, TypeConfig, UnboxArray } from '../typings.js';
|
|
2
2
|
import { type PopulatePath } from '../enums.js';
|
|
3
|
-
/** Converts entity instances to plain DTOs via `serialize()`, with fine-grained control over populate, exclude, and serialization groups. */
|
|
3
|
+
/** Converts entity instances to plain DTOs via `serialize()`, with fine-grained control over populate, exclude, fields, and serialization groups. */
|
|
4
4
|
export declare class EntitySerializer {
|
|
5
|
-
/** Serializes an entity to a plain DTO, with fine-grained control over population, exclusion, groups, and custom types. */
|
|
6
|
-
static serialize<T extends object, P extends string = never, E extends string = never>(entity: T, options?: SerializeOptions<T, P, E>): SerializeDTO<T, P, E
|
|
5
|
+
/** Serializes an entity to a plain DTO, with fine-grained control over population, exclusion, fields, groups, and custom types. */
|
|
6
|
+
static serialize<T extends object, P extends string = never, E extends string = never, F extends string = never>(entity: T, options?: SerializeOptions<T, P, E, F>): SerializeDTO<T, P, E, never, ResolveSerializeFields<F>, SerializeFieldsKeepPK<F>>;
|
|
7
7
|
private static propertyName;
|
|
8
8
|
private static processProperty;
|
|
9
9
|
private static processCustomType;
|
|
10
10
|
private static extractChildOptions;
|
|
11
|
+
/**
|
|
12
|
+
* Extracts the nested `fields` whitelist for a child property. A bare parent name (`fields: ['books']`) or a
|
|
13
|
+
* wildcard removes the whitelist on the sub-tree (everything is included), so consumers don't have to repeat
|
|
14
|
+
* every field of the child. Otherwise dot-paths are stripped of the parent prefix and passed down.
|
|
15
|
+
*/
|
|
16
|
+
private static extractChildFields;
|
|
11
17
|
private static processEntity;
|
|
12
18
|
private static processCollection;
|
|
13
19
|
}
|
|
14
|
-
export interface SerializeOptions<T, P extends string = never, E extends string = never> {
|
|
20
|
+
export interface SerializeOptions<T, P extends string = never, E extends string = never, F extends string = never> {
|
|
15
21
|
/** Specify which relation should be serialized as populated and which as a FK. */
|
|
16
22
|
populate?: readonly AutoPath<T, P, `${PopulatePath.ALL}`>[];
|
|
17
23
|
/** Specify which properties should be omitted. */
|
|
18
24
|
exclude?: readonly AutoPath<T, E>[];
|
|
25
|
+
/**
|
|
26
|
+
* Whitelist of properties to serialize, supports dot-paths (e.g. `['name', 'books.title']`). When set, only the
|
|
27
|
+
* listed properties end up in the output, including primary keys. A bare property name keeps its entire sub-tree;
|
|
28
|
+
* a dot-path additionally narrows the nested object to the listed sub-keys. `exclude` takes precedence on conflict.
|
|
29
|
+
*/
|
|
30
|
+
fields?: readonly AutoPath<T, F, `${PopulatePath.ALL}`>[];
|
|
19
31
|
/** Enforce unpopulated references to be returned as objects, e.g. `{ author: { id: 1 } }` instead of `{ author: 1 }`. */
|
|
20
32
|
forceObject?: boolean;
|
|
21
33
|
/** Ignore custom property serializers. */
|
|
@@ -41,4 +53,4 @@ export interface SerializeOptions<T, P extends string = never, E extends string
|
|
|
41
53
|
* const dto2 = wrap(user).serialize({ exclude: ['id', 'email'], forceObject: true });
|
|
42
54
|
* ```
|
|
43
55
|
*/
|
|
44
|
-
export declare function serialize<Entity extends object, Naked extends FromEntityType<Entity> = FromEntityType<Entity>, Populate extends string = never, Exclude extends string = never, Config extends TypeConfig = never>(entity: Entity, options?: Config & SerializeOptions<UnboxArray<Entity>, Populate, Exclude>): Naked extends object[] ? SerializeDTO<ArrayElement<Naked>, Populate, Exclude, CleanTypeConfig<Config>>[] : SerializeDTO<Naked, Populate, Exclude, CleanTypeConfig<Config>, ExtractFieldsHint<Entity>>;
|
|
56
|
+
export declare function serialize<Entity extends object, Naked extends FromEntityType<Entity> = FromEntityType<Entity>, Populate extends string = never, Exclude extends string = never, Fields extends string = never, Config extends TypeConfig = never>(entity: Entity, options?: Config & SerializeOptions<UnboxArray<Entity>, Populate, Exclude, Fields>): Naked extends object[] ? SerializeDTO<ArrayElement<Naked>, Populate, Exclude, CleanTypeConfig<Config>, ResolveSerializeFields<Fields, ExtractFieldsHint<Entity>>, SerializeFieldsKeepPK<Fields>>[] : SerializeDTO<Naked, Populate, Exclude, CleanTypeConfig<Config>, ResolveSerializeFields<Fields, ExtractFieldsHint<Entity>>, SerializeFieldsKeepPK<Fields>>;
|
|
@@ -4,13 +4,19 @@ import { ReferenceKind } from '../enums.js';
|
|
|
4
4
|
import { Reference } from '../entity/Reference.js';
|
|
5
5
|
import { SerializationContext } from './SerializationContext.js';
|
|
6
6
|
import { isRaw } from '../utils/RawQueryFragment.js';
|
|
7
|
+
/** Returns true when any entry in `items` is `propName`, the wildcard `*`, or a dot-path under `propName`. */
|
|
8
|
+
function matchesPath(items, propName) {
|
|
9
|
+
return items.some(item => item === propName || item === '*' || item.startsWith(propName + '.'));
|
|
10
|
+
}
|
|
7
11
|
function isVisible(meta, propName, options) {
|
|
8
12
|
const prop = meta.properties[propName];
|
|
9
13
|
if (options.groups && prop?.groups) {
|
|
10
14
|
return prop.groups.some(g => options.groups.includes(g));
|
|
11
15
|
}
|
|
12
|
-
if (Array.isArray(options.
|
|
13
|
-
|
|
16
|
+
if (Array.isArray(options.fields) && options.fields.length > 0 && !matchesPath(options.fields, propName)) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
if (Array.isArray(options.populate) && matchesPath(options.populate, propName)) {
|
|
14
20
|
return true;
|
|
15
21
|
}
|
|
16
22
|
if (options.exclude?.find(item => item === propName)) {
|
|
@@ -22,7 +28,8 @@ function isVisible(meta, propName, options) {
|
|
|
22
28
|
}
|
|
23
29
|
function isPopulated(propName, options) {
|
|
24
30
|
if (typeof options.populate !== 'boolean' &&
|
|
25
|
-
options.populate
|
|
31
|
+
Array.isArray(options.populate) &&
|
|
32
|
+
matchesPath(options.populate, propName)) {
|
|
26
33
|
return true;
|
|
27
34
|
}
|
|
28
35
|
if (typeof options.populate === 'boolean') {
|
|
@@ -30,9 +37,9 @@ function isPopulated(propName, options) {
|
|
|
30
37
|
}
|
|
31
38
|
return false;
|
|
32
39
|
}
|
|
33
|
-
/** Converts entity instances to plain DTOs via `serialize()`, with fine-grained control over populate, exclude, and serialization groups. */
|
|
40
|
+
/** Converts entity instances to plain DTOs via `serialize()`, with fine-grained control over populate, exclude, fields, and serialization groups. */
|
|
34
41
|
export class EntitySerializer {
|
|
35
|
-
/** Serializes an entity to a plain DTO, with fine-grained control over population, exclusion, groups, and custom types. */
|
|
42
|
+
/** Serializes an entity to a plain DTO, with fine-grained control over population, exclusion, fields, groups, and custom types. */
|
|
36
43
|
static serialize(entity, options = {}) {
|
|
37
44
|
const wrapped = helper(entity);
|
|
38
45
|
const meta = wrapped.__meta;
|
|
@@ -184,8 +191,27 @@ export class EntitySerializer {
|
|
|
184
191
|
? Utils.extractChildElements(options.populate, prop, '*')
|
|
185
192
|
: options.populate,
|
|
186
193
|
exclude: Array.isArray(options.exclude) ? Utils.extractChildElements(options.exclude, prop) : options.exclude,
|
|
194
|
+
fields: Array.isArray(options.fields) ? this.extractChildFields(options.fields, prop) : options.fields,
|
|
187
195
|
};
|
|
188
196
|
}
|
|
197
|
+
/**
|
|
198
|
+
* Extracts the nested `fields` whitelist for a child property. A bare parent name (`fields: ['books']`) or a
|
|
199
|
+
* wildcard removes the whitelist on the sub-tree (everything is included), so consumers don't have to repeat
|
|
200
|
+
* every field of the child. Otherwise dot-paths are stripped of the parent prefix and passed down.
|
|
201
|
+
*/
|
|
202
|
+
static extractChildFields(fields, prop) {
|
|
203
|
+
const out = [];
|
|
204
|
+
const dotPrefix = prop + '.';
|
|
205
|
+
for (const field of fields) {
|
|
206
|
+
if (field === prop || field === '*') {
|
|
207
|
+
return undefined;
|
|
208
|
+
}
|
|
209
|
+
if (field.startsWith(dotPrefix)) {
|
|
210
|
+
out.push(field.substring(dotPrefix.length));
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return out;
|
|
214
|
+
}
|
|
189
215
|
static processEntity(prop, entity, platform, options) {
|
|
190
216
|
const child = Reference.unwrapReference(entity[prop.name]);
|
|
191
217
|
const wrapped = helper(child);
|
package/typings.d.ts
CHANGED
|
@@ -47,7 +47,7 @@ export type AsyncFunction<R = any, T = Dictionary> = (args: T) => Promise<T>;
|
|
|
47
47
|
export type Compute<T> = {
|
|
48
48
|
[K in keyof T]: T[K];
|
|
49
49
|
} & {};
|
|
50
|
-
type InternalKeys = 'EntityRepositoryType' | 'PrimaryKeyProp' | 'OptionalProps' | 'EagerProps' | 'HiddenProps' | '__selectedType' | '__loadedType';
|
|
50
|
+
type InternalKeys = 'EntityRepositoryType' | 'PrimaryKeyProp' | 'OptionalProps' | 'EagerProps' | 'HiddenProps' | 'IndexHints' | '__selectedType' | '__loadedType';
|
|
51
51
|
/** Filters out function, symbol, and internal keys from an entity type. When `B = true`, also excludes scalar keys. */
|
|
52
52
|
export type CleanKeys<T, K extends keyof T, B extends boolean = false> = T[K] & {} extends Function ? never : K extends symbol | InternalKeys ? never : B extends true ? T[K] & {} extends Scalar ? never : K : K;
|
|
53
53
|
/** Extracts keys of `T` whose values are functions. */
|
|
@@ -113,7 +113,7 @@ type LoadedReferenceShape<T = any> = ReferenceShape & {
|
|
|
113
113
|
* Using this instead of `Loadable<any>` in conditional type checks prevents
|
|
114
114
|
* TypeScript from evaluating the full Collection/Reference interfaces.
|
|
115
115
|
*/
|
|
116
|
-
type LoadableShape = CollectionShape | ReferenceShape | readonly any[];
|
|
116
|
+
type LoadableShape = CollectionShape | ReferenceShape | LazyRef.Brand<any> | readonly any[];
|
|
117
117
|
/** Gets all keys from all members of a union type (distributes over the union). */
|
|
118
118
|
export type UnionKeys<T> = T extends any ? keyof T : never;
|
|
119
119
|
/** Gets the type of a property from all union members that have it (distributes over the union). */
|
|
@@ -150,6 +150,44 @@ export declare const EntityName: unique symbol;
|
|
|
150
150
|
export type InferEntityName<T> = T extends {
|
|
151
151
|
[EntityName]?: infer Name;
|
|
152
152
|
} ? (Name extends string ? Name : never) : never;
|
|
153
|
+
/**
|
|
154
|
+
* Symbol used to declare index-to-column mappings on an entity type.
|
|
155
|
+
* For decorator entities, declare as a phantom property:
|
|
156
|
+
* ```typescript
|
|
157
|
+
* [IndexHints]?: { idx_email: 'email'; idx_name_age: 'name' | 'age' };
|
|
158
|
+
* ```
|
|
159
|
+
* For `defineEntity` entities, index hints are inferred automatically from
|
|
160
|
+
* named indexes (property-level `.index('name')` and entity-level `indexes`/`uniques`).
|
|
161
|
+
*/
|
|
162
|
+
export declare const IndexHints: unique symbol;
|
|
163
|
+
/**
|
|
164
|
+
* Extracts the index hints map from an entity type. Returns `never` when no hints are declared.
|
|
165
|
+
* For decorator entities, `[IndexHints]` contains a pre-computed `{ idxName: 'prop' }` map.
|
|
166
|
+
* For `defineEntity` entities, `[IndexHints]` contains `[Properties]` (a tuple wrapping the
|
|
167
|
+
* raw property builders), which is lazily converted to the index map when first accessed.
|
|
168
|
+
*/
|
|
169
|
+
export type ExtractIndexHints<T> = T extends {
|
|
170
|
+
[IndexHints]?: infer H;
|
|
171
|
+
} ? H extends [infer P extends Record<string, any>] ? InferPropertyIndexMap<P> : H : never;
|
|
172
|
+
/**
|
|
173
|
+
* Extracts `{ indexName: propertyKey }` from property builder options.
|
|
174
|
+
* Checks `.index('name')` and `.unique('name')` on each property in a single pass.
|
|
175
|
+
*/
|
|
176
|
+
export type InferPropertyIndexMap<Properties extends Record<string, any>> = {
|
|
177
|
+
[K in keyof Properties as MaybeReturnType<Properties[K]> extends {
|
|
178
|
+
'~options': {
|
|
179
|
+
index: infer N extends string;
|
|
180
|
+
};
|
|
181
|
+
} ? N : MaybeReturnType<Properties[K]> extends {
|
|
182
|
+
'~options': {
|
|
183
|
+
unique: infer N extends string;
|
|
184
|
+
};
|
|
185
|
+
} ? N : never]: K & string;
|
|
186
|
+
};
|
|
187
|
+
/** Union of declared index names on an entity. Falls back to `string` when no `[IndexHints]` are declared. */
|
|
188
|
+
export type IndexName<T> = [ExtractIndexHints<T>] extends [never] ? string : (keyof ExtractIndexHints<T> & string) | (string & {});
|
|
189
|
+
/** Properties covered by the named index on entity T. Falls back to all entity keys when the index is unknown. */
|
|
190
|
+
export type IndexColumns<T, Name extends string> = ExtractIndexHints<T> extends Record<Name, infer Cols> ? Cols & string : EntityKey<T>;
|
|
153
191
|
/**
|
|
154
192
|
* Branded type that marks a property as optional in `em.create()`.
|
|
155
193
|
* Use as a property type wrapper: `createdAt: Opt<Date>` instead of listing in `[OptionalProps]`.
|
|
@@ -328,6 +366,18 @@ export type ObjectQuery<T> = OperatorMap<T> & FilterObject<T>;
|
|
|
328
366
|
* Accepts an object query, a primary key value, entity props with operators, or an array of filters.
|
|
329
367
|
*/
|
|
330
368
|
export type FilterQuery<T> = ObjectQuery<T> | NonNullable<ExpandScalar<Primary<T>>> | NonNullable<EntityProps<T> & OperatorMap<T>> | FilterQuery<T>[];
|
|
369
|
+
/**
|
|
370
|
+
* `FilterQuery` restricted to only properties covered by the specified index(es).
|
|
371
|
+
* Used when `using` option is set in `FindOptions` to enforce type-safe index usage.
|
|
372
|
+
*/
|
|
373
|
+
export type IndexFilterQuery<T, Using extends string> = [Using] extends [never] ? FilterQuery<T> : (OperatorMap<T> & {
|
|
374
|
+
-readonly [K in Extract<EntityKey<T>, IndexColumns<T, Using>>]?: ExpandQuery<ExpandProperty<FilterObjectProp<T, K>>> | ExpandQueryMerged<ExpandProperty<FilterObjectProp<T, K>>> | FilterValue<ExpandProperty<FilterObjectProp<T, K>>> | ElemMatchFilter<FilterObjectProp<T, K>> | null;
|
|
375
|
+
}) | NonNullable<ExpandScalar<Primary<T>>> | IndexFilterQuery<T, Using>[];
|
|
376
|
+
/** Replaces `where` and `using` on an options type with index-aware variants when `Using` is specified. */
|
|
377
|
+
export type WithUsingOptions<Opts, Entity, Using extends string> = Omit<Opts, 'where' | 'using'> & {
|
|
378
|
+
using?: Using | Using[];
|
|
379
|
+
where?: [Using] extends [never] ? FilterQuery<Entity> : IndexFilterQuery<Entity, Using>;
|
|
380
|
+
};
|
|
331
381
|
/** Public interface for the entity wrapper, accessible via `wrap(entity)`. Provides helper methods for entity state management. */
|
|
332
382
|
export interface IWrappedEntity<Entity extends object> {
|
|
333
383
|
isInitialized(): boolean;
|
|
@@ -341,7 +391,7 @@ export interface IWrappedEntity<Entity extends object> {
|
|
|
341
391
|
toObject<Ignored extends EntityKey<Entity>>(ignoreFields: Ignored[]): Omit<EntityDTO<Entity>, Ignored>;
|
|
342
392
|
toJSON(...args: any[]): EntityDTO<Entity>;
|
|
343
393
|
toPOJO(): EntityDTO<Entity>;
|
|
344
|
-
serialize<Naked extends FromEntityType<Entity> = FromEntityType<Entity>, Hint extends string = never, Exclude extends string = never>(options?: SerializeOptions<Naked, Hint, Exclude>): SerializeDTO<Naked, Hint, Exclude
|
|
394
|
+
serialize<Naked extends FromEntityType<Entity> = FromEntityType<Entity>, Hint extends string = never, Exclude extends string = never, Fields extends string = never>(options?: SerializeOptions<Naked, Hint, Exclude, Fields>): SerializeDTO<Naked, Hint, Exclude, never, ResolveSerializeFields<Fields, ExtractFieldsHint<Entity>>, SerializeFieldsKeepPK<Fields>>;
|
|
345
395
|
setSerializationContext<Hint extends string = never, Fields extends string = never, Exclude extends string = never>(options: LoadHint<Entity, Hint, Fields, Exclude>): void;
|
|
346
396
|
assign<Naked extends FromEntityType<Entity> = FromEntityType<Entity>, Convert extends boolean = false, Data extends EntityData<Naked, Convert> | Partial<EntityDTO<Naked>> = EntityData<Naked, Convert> | Partial<EntityDTO<Naked>>>(data: Data & IsSubset<EntityData<Naked, Convert>, Data>, options?: AssignOptions<Convert>): MergeSelected<Entity, Naked, keyof Data & string>;
|
|
347
397
|
getSchema(): string | undefined;
|
|
@@ -417,12 +467,12 @@ type NonArrayObject = object & {
|
|
|
417
467
|
export type EntityDataProp<T, C extends boolean> = T extends Date ? string | Date : T extends Scalar ? T : T extends ScalarReference<infer U> ? EntityDataProp<U, C> : T extends {
|
|
418
468
|
__runtime?: infer Runtime;
|
|
419
469
|
__raw?: infer Raw;
|
|
420
|
-
} ? C extends true ? Raw : Runtime : T extends ReferenceShape<infer U> ? EntityDataNested<U, C> : T extends CollectionShape<infer U> ? U | U[] | EntityDataNested<U & object, C> | EntityDataNested<U & object, C>[] : T extends readonly (infer U)[] ? U extends NonArrayObject ? U | U[] | EntityDataNested<U, C> | EntityDataNested<U, C>[] : U[] | EntityDataNested<U, C>[] : EntityDataNested<T, C>;
|
|
470
|
+
} ? C extends true ? Raw : Runtime : T extends LazyRef.Brand<infer U> ? EntityDataNested<U, C> : T extends ReferenceShape<infer U> ? EntityDataNested<U, C> : T extends CollectionShape<infer U> ? U | U[] | EntityDataNested<U & object, C> | EntityDataNested<U & object, C>[] : T extends readonly (infer U)[] ? U extends NonArrayObject ? U | U[] | EntityDataNested<U, C> | EntityDataNested<U, C>[] : U[] | EntityDataNested<U, C>[] : EntityDataNested<T, C>;
|
|
421
471
|
/** Like `EntityDataProp` but used in `RequiredEntityData` context with required/optional key distinction. */
|
|
422
472
|
export type RequiredEntityDataProp<T, O, C extends boolean> = T extends Date ? string | Date : Exclude<T, null> extends RequiredNullable.Brand ? T | null : T extends Scalar ? T : T extends ScalarReference<infer U> ? RequiredEntityDataProp<U, O, C> : T extends {
|
|
423
473
|
__runtime?: infer Runtime;
|
|
424
474
|
__raw?: infer Raw;
|
|
425
|
-
} ? C extends true ? Raw : Runtime : T extends ReferenceShape<infer U> ? RequiredEntityDataNested<U, O, C> : T extends CollectionShape<infer U> ? U | U[] | RequiredEntityDataNested<U & object, O, C> | RequiredEntityDataNested<U & object, O, C>[] : T extends readonly (infer U)[] ? U extends NonArrayObject ? U | U[] | RequiredEntityDataNested<U, O, C> | RequiredEntityDataNested<U, O, C>[] : U[] | RequiredEntityDataNested<U, O, C>[] : RequiredEntityDataNested<T, O, C>;
|
|
475
|
+
} ? C extends true ? Raw : Runtime : T extends LazyRef.Brand<infer U> ? RequiredEntityDataNested<U, O, C> : T extends ReferenceShape<infer U> ? RequiredEntityDataNested<U, O, C> : T extends CollectionShape<infer U> ? U | U[] | RequiredEntityDataNested<U & object, O, C> | RequiredEntityDataNested<U & object, O, C>[] : T extends readonly (infer U)[] ? U extends NonArrayObject ? U | U[] | RequiredEntityDataNested<U, O, C> | RequiredEntityDataNested<U, O, C>[] : U[] | RequiredEntityDataNested<U, O, C>[] : RequiredEntityDataNested<T, O, C>;
|
|
426
476
|
/** Nested entity data shape for embedded or related entities within `EntityData`. */
|
|
427
477
|
export type EntityDataNested<T, C extends boolean = false> = T extends undefined ? never : T extends any[] ? Readonly<T> : EntityData<T, C> | ExpandEntityProp<T, C>;
|
|
428
478
|
type UnwrapScalarRef<T> = T extends ScalarReference<infer U> ? U : T;
|
|
@@ -471,6 +521,35 @@ type Relation<T> = {
|
|
|
471
521
|
export type Rel<T> = T;
|
|
472
522
|
/** Alias for `ScalarReference` (see {@apilink Ref}). */
|
|
473
523
|
export type ScalarRef<T> = ScalarReference<T>;
|
|
524
|
+
/**
|
|
525
|
+
* Type-level marker for a to-one relation that is **direct at runtime** (no `Reference` wrapper) but
|
|
526
|
+
* **restricted at compile time** until narrowed via `Loaded<>`.
|
|
527
|
+
*
|
|
528
|
+
* Use as the property type on a `@ManyToOne`/`@OneToOne` relation that does **not** have `ref: true`:
|
|
529
|
+
*
|
|
530
|
+
* ```ts
|
|
531
|
+
* @ManyToOne(() => User)
|
|
532
|
+
* author!: LazyRef<User>;
|
|
533
|
+
* ```
|
|
534
|
+
*
|
|
535
|
+
* Semantics:
|
|
536
|
+
* - **Runtime**: identical to a plain direct relation — `article.author` is a `User` instance (stub or hydrated),
|
|
537
|
+
* `article.author instanceof User` is `true`, no `Reference` object is created.
|
|
538
|
+
* - **Type (unloaded view)**: only the primary key is accessible. Accessing other properties is a compile error.
|
|
539
|
+
* - **Type (loaded view)**: once the relation is in the populate hint of a `Loaded<Entity, 'author'>`, it narrows
|
|
540
|
+
* back to the full entity — no `.$` or `.get()` indirection needed.
|
|
541
|
+
*
|
|
542
|
+
* Note: the safety is purely compile-time. JS code or `as any` casts bypass it.
|
|
543
|
+
*/
|
|
544
|
+
export type LazyRef<T extends object> = IsAny<T> extends true ? LazyRef.Brand<T> : {
|
|
545
|
+
[K in PrimaryProperty<T> & keyof T]: T[K];
|
|
546
|
+
} & LazyRef.Brand<T>;
|
|
547
|
+
export declare namespace LazyRef {
|
|
548
|
+
const __lazyRef: unique symbol;
|
|
549
|
+
interface Brand<T> {
|
|
550
|
+
[__lazyRef]?: (arg: T) => T;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
474
553
|
/** Alias for `Reference<T> & { id: number }` (see {@apilink Ref}). */
|
|
475
554
|
export type EntityRef<T extends object> = true extends IsUnknown<PrimaryProperty<T>> ? Reference<T> : IsAny<T> extends true ? Reference<T> : {
|
|
476
555
|
[K in PrimaryProperty<T> & keyof T]: T[K];
|
|
@@ -534,17 +613,32 @@ export type EntityDTOFlat<T, C extends TypeConfig = never> = {
|
|
|
534
613
|
type SerializeTopHints<H extends string> = H extends `${infer Top}.${string}` ? Top : H;
|
|
535
614
|
type SerializeSubHints<K extends string, H extends string> = H extends `${K}.${infer Rest}` ? Rest : never;
|
|
536
615
|
type SerializeSubFields<K extends string, F extends string> = K extends F ? '*' : [F extends `${K & string}.${infer Rest}` ? Rest : never] extends [never] ? '*' : F extends `${K & string}.${infer Rest}` ? Rest : never;
|
|
537
|
-
type SerializeFieldsFilter<T, K extends keyof T, F extends string> = K extends Prefix<T, F> | PrimaryProperty<T> ? K : never;
|
|
616
|
+
type SerializeFieldsFilter<T, K extends keyof T, F extends string, KeepPK extends boolean = true> = K extends Prefix<T, F> | (KeepPK extends true ? PrimaryProperty<T> : never) ? K : never;
|
|
538
617
|
type SerializePropValue<T, K extends keyof T, H extends string, C extends TypeConfig = never> = K & string extends SerializeTopHints<H> ? NonNullable<T[K]> extends CollectionShape<infer U> ? SerializeDTO<U & object, SerializeSubHints<K & string, H>, never, C>[] : SerializeDTO<ExpandProperty<T[K]>, SerializeSubHints<K & string, H>, never, C> | Extract<T[K], null | undefined> : EntityDTOProp<T, T[K], C>;
|
|
539
|
-
type SerializePropValueWithFields<T, K extends keyof T, H extends string, C extends TypeConfig, F extends string> = K & string extends SerializeTopHints<H> ? NonNullable<T[K]> extends CollectionShape<infer U> ? SerializeDTO<U & object, SerializeSubHints<K & string, H>, never, C, SerializeSubFields<K & string, F
|
|
618
|
+
type SerializePropValueWithFields<T, K extends keyof T, H extends string, C extends TypeConfig, F extends string, KeepPK extends boolean = true> = K & string extends SerializeTopHints<H> ? NonNullable<T[K]> extends CollectionShape<infer U> ? SerializeDTO<U & object, SerializeSubHints<K & string, H>, never, C, SerializeSubFields<K & string, F>, KeepPK>[] : SerializeDTO<ExpandProperty<T[K]>, SerializeSubHints<K & string, H>, never, C, SerializeSubFields<K & string, F>, KeepPK> | Extract<T[K], null | undefined> : EntityDTOProp<T, T[K], C>;
|
|
619
|
+
/**
|
|
620
|
+
* Resolves a user-provided `Fields` generic to the value passed to `SerializeDTO`'s `F` parameter:
|
|
621
|
+
* `never` (no `fields` option) falls back to `Default` (typically `'*'` or the entity's `ExtractFieldsHint`).
|
|
622
|
+
*/
|
|
623
|
+
export type ResolveSerializeFields<Fields extends string, Default extends string = '*'> = [Fields] extends [never] ? Default : Fields;
|
|
624
|
+
/**
|
|
625
|
+
* Whether the explicit `serialize()` path should keep primary keys in the output. When the user does not provide
|
|
626
|
+
* a `fields` option (`Fields = never`), behave like `toObject()` and keep PKs; when they do, treat it as a strict
|
|
627
|
+
* whitelist so PKs are dropped unless listed.
|
|
628
|
+
*/
|
|
629
|
+
export type SerializeFieldsKeepPK<Fields extends string> = [Fields] extends [never] ? true : false;
|
|
540
630
|
/**
|
|
541
631
|
* Return type of `serialize()`. Combines Loaded + EntityDTO in a single pass for better performance.
|
|
542
632
|
* Respects populate hints (`H`), exclude hints (`E`), and fields hints (`F`).
|
|
633
|
+
*
|
|
634
|
+
* `KeepPK` controls whether primary keys are auto-included when narrowing by `F`. The `toObject()` path keeps the
|
|
635
|
+
* default `true` (PKs always present); the explicit `serialize()` path passes `false` so the user-provided `fields`
|
|
636
|
+
* option is a strict whitelist that can drop PKs from the output.
|
|
543
637
|
*/
|
|
544
|
-
export type SerializeDTO<T, H extends string = never, E extends string = never, C extends TypeConfig = never, F extends string = '*'> = string extends H ? EntityDTOFlat<T, C> : [F] extends ['*'] ? {
|
|
638
|
+
export type SerializeDTO<T, H extends string = never, E extends string = never, C extends TypeConfig = never, F extends string = '*', KeepPK extends boolean = true> = string extends H ? EntityDTOFlat<T, C> : [F] extends ['*'] ? {
|
|
545
639
|
[K in keyof T as ExcludeHidden<T, K> & CleanKeys<T, K> & (IsNever<E> extends true ? K : Exclude<K, E>)]: SerializePropValue<T, K, H, C> | Extract<T[K], null | undefined>;
|
|
546
640
|
} : {
|
|
547
|
-
[K in keyof T as ExcludeHidden<T, K> & CleanKeys<T, K> & (IsNever<E> extends true ? K : Exclude<K, E>) & SerializeFieldsFilter<T, K, F>]: SerializePropValueWithFields<T, K, H, C, F> | Extract<T[K], null | undefined>;
|
|
641
|
+
[K in keyof T as ExcludeHidden<T, K> & CleanKeys<T, K> & (IsNever<E> extends true ? K : Exclude<K, E>) & SerializeFieldsFilter<T, K, F, KeepPK>]: SerializePropValueWithFields<T, K, H, C, F, KeepPK> | Extract<T[K], null | undefined>;
|
|
548
642
|
};
|
|
549
643
|
type TargetKeys<T> = T extends EntityClass<infer P> ? keyof P : keyof T;
|
|
550
644
|
type PropertyName<T> = IsUnknown<T> extends false ? TargetKeys<T> : string;
|
|
@@ -591,6 +685,8 @@ export type IndexCallback<T> = (columns: Record<PropertyName<T>, string>, table:
|
|
|
591
685
|
export type FormulaCallback<T> = (columns: FormulaColumns<T>, table: FormulaTable) => string | Raw;
|
|
592
686
|
/** Callback for CHECK constraint expressions. Receives column mappings and table info. */
|
|
593
687
|
export type CheckCallback<T> = (columns: Record<PropertyName<T>, string>, table: SchemaTable) => string | Raw;
|
|
688
|
+
/** Callback for trigger body expressions. Receives column mappings and table info. */
|
|
689
|
+
export type TriggerCallback<T> = (columns: Record<PropertyName<T>, string>, table: SchemaTable) => string | Raw;
|
|
594
690
|
/** Callback for generated (computed) column expressions. Receives column mappings and table info. */
|
|
595
691
|
export type GeneratedColumnCallback<T> = (columns: Record<PropertyName<T>, string>, table: SchemaTable) => string | Raw;
|
|
596
692
|
/** Definition of a CHECK constraint on a table or property. */
|
|
@@ -599,6 +695,23 @@ export interface CheckConstraint<T = any> {
|
|
|
599
695
|
property?: string;
|
|
600
696
|
expression: string | Raw | CheckCallback<T>;
|
|
601
697
|
}
|
|
698
|
+
/** Definition of a database trigger on a table. */
|
|
699
|
+
export interface TriggerDef<T = any> {
|
|
700
|
+
/** Trigger name. Auto-generated if omitted. */
|
|
701
|
+
name?: string;
|
|
702
|
+
/** When the trigger fires relative to the event. */
|
|
703
|
+
timing: 'before' | 'after' | 'instead of';
|
|
704
|
+
/** Which DML events activate the trigger. */
|
|
705
|
+
events: ('insert' | 'update' | 'delete' | 'truncate')[];
|
|
706
|
+
/** Whether the trigger fires once per row or per statement. Defaults to `'row'`. */
|
|
707
|
+
forEach?: 'row' | 'statement';
|
|
708
|
+
/** SQL body of the trigger. Can be a string, Raw query, or callback receiving column name mappings. */
|
|
709
|
+
body?: string | Raw | TriggerCallback<T>;
|
|
710
|
+
/** Optional SQL WHEN condition for the trigger. */
|
|
711
|
+
when?: string;
|
|
712
|
+
/** Raw DDL escape hatch — full CREATE TRIGGER statement. Mutually exclusive with `body`. */
|
|
713
|
+
expression?: string;
|
|
714
|
+
}
|
|
602
715
|
/** Branded string that accepts any string value while preserving autocompletion for known literals. */
|
|
603
716
|
export type AnyString = string & {};
|
|
604
717
|
/** Describes a single property (column, relation, or embedded) within an entity's metadata. */
|
|
@@ -818,6 +931,7 @@ export interface EntityMetadata<Entity = any, Class extends EntityCtor<Entity> =
|
|
|
818
931
|
disabled?: boolean;
|
|
819
932
|
}[];
|
|
820
933
|
checks: CheckConstraint<Entity>[];
|
|
934
|
+
triggers: TriggerDef<Entity>[];
|
|
821
935
|
repositoryClass?: string;
|
|
822
936
|
repository: () => EntityClass<EntityRepository<any>>;
|
|
823
937
|
hooks: {
|
|
@@ -1045,6 +1159,11 @@ export interface IMigrator {
|
|
|
1045
1159
|
* Executes down migrations to the given point. Without parameter it will migrate one version down.
|
|
1046
1160
|
*/
|
|
1047
1161
|
down(options?: string | string[] | Omit<MigrateOptions, 'from'>): Promise<MigrationInfo[]>;
|
|
1162
|
+
/**
|
|
1163
|
+
* Combines multiple executed migrations into a single migration file.
|
|
1164
|
+
* Concatenates source code without touching the database schema.
|
|
1165
|
+
*/
|
|
1166
|
+
rollup(migrations?: string[]): Promise<MigrationResult>;
|
|
1048
1167
|
/**
|
|
1049
1168
|
* Registers event handler.
|
|
1050
1169
|
*/
|
|
@@ -1127,13 +1246,32 @@ export type PopulateOptions<T> = {
|
|
|
1127
1246
|
children?: PopulateOptions<T[keyof T]>[];
|
|
1128
1247
|
/** When true, ignores `mapToPk` on the property and returns full entity data instead of just PKs. */
|
|
1129
1248
|
dataOnly?: boolean;
|
|
1249
|
+
/** Limit the number of items loaded per parent entity. Collections will be marked as partial and readonly. */
|
|
1250
|
+
limit?: number;
|
|
1251
|
+
/** Offset for per-parent limiting (used with `limit`). */
|
|
1252
|
+
offset?: number;
|
|
1253
|
+
/** Order by clause for per-parent limiting. Takes precedence over nested `FindOptions.orderBy`. */
|
|
1254
|
+
orderBy?: QueryOrderMap<T[keyof T]>;
|
|
1130
1255
|
};
|
|
1131
1256
|
/** Inline options that can be appended to populate hint strings (e.g., strategy, join type). */
|
|
1132
1257
|
export type PopulateHintOptions = {
|
|
1133
1258
|
strategy?: LoadStrategy.JOINED | LoadStrategy.SELECT_IN | 'joined' | 'select-in';
|
|
1134
1259
|
joinType?: 'inner join' | 'left join';
|
|
1260
|
+
/** Limit the number of items loaded per parent entity. Collections will be marked as partial and readonly. */
|
|
1261
|
+
limit?: number;
|
|
1262
|
+
/** Offset for per-parent limiting (used with `limit`). */
|
|
1263
|
+
offset?: number;
|
|
1264
|
+
/** Order by clause for per-parent limiting. Takes precedence over nested `FindOptions.orderBy`. */
|
|
1265
|
+
orderBy?: QueryOrderMap<any>;
|
|
1135
1266
|
};
|
|
1136
1267
|
type ExtractType<T> = T extends CollectionShape<infer U> ? U : T extends ReferenceShape<infer U> ? U : T extends Ref<infer U> ? U : T extends readonly (infer U)[] ? U : T;
|
|
1268
|
+
/**
|
|
1269
|
+
* Like {@link ExtractType} but also unwraps {@link LazyRef}. Kept separate so {@link ExtractType}'s
|
|
1270
|
+
* hot path (used by `IsOptional`, `EntityData`, `RequiredEntityData`) doesn't pay the cost of the
|
|
1271
|
+
* extra branch — those contexts handle `LazyRef` in their own earlier branches (see
|
|
1272
|
+
* `EntityDataProp` / `RequiredEntityDataProp`) before delegating to `ExtractType`.
|
|
1273
|
+
*/
|
|
1274
|
+
type ExtractTypeWithLazyRef<T> = T extends LazyRef.Brand<infer U> ? U : ExtractType<T>;
|
|
1137
1275
|
type ExtractStringKeys<T> = {
|
|
1138
1276
|
[K in keyof T]-?: CleanKeys<T, K>;
|
|
1139
1277
|
}[keyof T] & {};
|
|
@@ -1141,8 +1279,8 @@ type ExtractStringKeys<T> = {
|
|
|
1141
1279
|
* Extracts string keys from an entity type, handling Collection/Reference wrappers.
|
|
1142
1280
|
* Simplified to just check `T extends object` since ExtractType handles the unwrapping.
|
|
1143
1281
|
*/
|
|
1144
|
-
type StringKeys<T, E extends string = never> = T extends object ? ExtractStringKeys<
|
|
1145
|
-
type GetStringKey<T, K extends StringKeys<T, string>, E extends string> = K extends keyof T ?
|
|
1282
|
+
type StringKeys<T, E extends string = never> = T extends object ? ExtractStringKeys<ExtractTypeWithLazyRef<T>> | E : never;
|
|
1283
|
+
type GetStringKey<T, K extends StringKeys<T, string>, E extends string> = K extends keyof T ? ExtractTypeWithLazyRef<T[K]> : K extends E ? keyof T : never;
|
|
1146
1284
|
type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
|
1147
1285
|
type RelationKeys<T> = T extends object ? {
|
|
1148
1286
|
[K in keyof T]-?: CleanKeys<T, K, true>;
|
|
@@ -1157,8 +1295,8 @@ export type UnboxArray<T> = T extends any[] ? ArrayElement<T> : T;
|
|
|
1157
1295
|
/** Extracts the element type from an array type. */
|
|
1158
1296
|
export type ArrayElement<ArrayType extends unknown[]> = ArrayType extends (infer ElementType)[] ? ElementType : never;
|
|
1159
1297
|
/** Unwraps a property type from its wrapper (Reference, Collection, or array) to the inner entity type. */
|
|
1160
|
-
export type ExpandProperty<T> = T extends ReferenceShape<infer U> ? NonNullable<U> : T extends CollectionShape<infer U> ? NonNullable<U> : T extends (infer U)[] ? NonNullable<U> : NonNullable<T>;
|
|
1161
|
-
type LoadedLoadable<T, E extends object> = T extends CollectionShape ? LoadedCollection<E> : T extends ScalarReference<infer U> ? LoadedScalarReference<U> : T extends ReferenceShape ? T & LoadedReference<E> : T extends Scalar ? T : T extends (infer U)[] ? U extends Scalar ? T : E[] : E;
|
|
1298
|
+
export type ExpandProperty<T> = T extends LazyRef.Brand<infer U> ? NonNullable<U> : T extends ReferenceShape<infer U> ? NonNullable<U> : T extends CollectionShape<infer U> ? NonNullable<U> : T extends (infer U)[] ? NonNullable<U> : NonNullable<T>;
|
|
1299
|
+
type LoadedLoadable<T, E extends object> = T extends CollectionShape ? LoadedCollection<E> : T extends ScalarReference<infer U> ? LoadedScalarReference<U> : T extends LazyRef.Brand<any> ? E : T extends ReferenceShape ? T & LoadedReference<E> : T extends Scalar ? T : T extends (infer U)[] ? U extends Scalar ? T : E[] : E;
|
|
1162
1300
|
type IsTrue<T> = IsNever<T> extends true ? false : T extends boolean ? (T extends true ? true : false) : false;
|
|
1163
1301
|
type StringLiteral<T> = T extends string ? (string extends T ? never : T) : never;
|
|
1164
1302
|
type Prefix<T, K> = K extends `${infer S}.${string}` ? S : K extends '*' ? keyof T : K;
|
|
@@ -1192,7 +1330,7 @@ export type MergeSelected<T, U, F extends string> = IsLoadedType<T> extends true
|
|
|
1192
1330
|
export type MergeLoaded<T, U, P extends string, F extends string, E extends string, R extends boolean = false> = IsLoadedType<T> extends true ? T & Loaded<U, P, F, E> : Loaded<T, P, F, E>;
|
|
1193
1331
|
/** Extracts the nullability modifiers (`null`, `undefined`, or both) from a type `T`. */
|
|
1194
1332
|
export type AddOptional<T> = undefined | null extends T ? null | undefined : null extends T ? null : undefined extends T ? undefined : never;
|
|
1195
|
-
type LoadedProp<T, L extends string = never, F extends string = '*', E extends string = never> = LoadedLoadable<T, Loaded<
|
|
1333
|
+
type LoadedProp<T, L extends string = never, F extends string = '*', E extends string = never> = LoadedLoadable<T, Loaded<ExtractTypeWithLazyRef<T>, L, F, E>>;
|
|
1196
1334
|
/** Extracts the eager-loaded property names declared via `[EagerProps]` as a string union. */
|
|
1197
1335
|
export type AddEager<T> = ExtractEagerProps<T> & string;
|
|
1198
1336
|
/** Combines an explicit populate hint `L` with the entity's eagerly loaded properties. */
|
package/typings.js
CHANGED
|
@@ -4,7 +4,6 @@ import { EntityHelper } from './entity/EntityHelper.js';
|
|
|
4
4
|
import { helper } from './entity/wrap.js';
|
|
5
5
|
import { Utils } from './utils/Utils.js';
|
|
6
6
|
import { EntityComparator } from './utils/EntityComparator.js';
|
|
7
|
-
import { BaseEntity } from './entity/BaseEntity.js';
|
|
8
7
|
/** Symbol used to declare a custom repository type on an entity class (e.g., `[EntityRepositoryType]?: BookRepository`). */
|
|
9
8
|
export const EntityRepositoryType = Symbol('EntityRepositoryType');
|
|
10
9
|
/** Symbol used to declare the primary key property name(s) on an entity (e.g., `[PrimaryKeyProp]?: 'id'`). */
|
|
@@ -22,6 +21,16 @@ export const Config = Symbol('Config');
|
|
|
22
21
|
/** Symbol used to declare the entity name as a string literal type (used by `defineEntity`). */
|
|
23
22
|
// eslint-disable-next-line @typescript-eslint/no-redeclare
|
|
24
23
|
export const EntityName = Symbol('EntityName');
|
|
24
|
+
/**
|
|
25
|
+
* Symbol used to declare index-to-column mappings on an entity type.
|
|
26
|
+
* For decorator entities, declare as a phantom property:
|
|
27
|
+
* ```typescript
|
|
28
|
+
* [IndexHints]?: { idx_email: 'email'; idx_name_age: 'name' | 'age' };
|
|
29
|
+
* ```
|
|
30
|
+
* For `defineEntity` entities, index hints are inferred automatically from
|
|
31
|
+
* named indexes (property-level `.index('name')` and entity-level `indexes`/`uniques`).
|
|
32
|
+
*/
|
|
33
|
+
export const IndexHints = Symbol('IndexHints');
|
|
25
34
|
/**
|
|
26
35
|
* Runtime metadata for an entity, holding its properties, relations, indexes, hooks, and more.
|
|
27
36
|
* Created during metadata discovery and used throughout the ORM lifecycle.
|
|
@@ -39,12 +48,20 @@ export class EntityMetadata {
|
|
|
39
48
|
this.indexes = [];
|
|
40
49
|
this.uniques = [];
|
|
41
50
|
this.checks = [];
|
|
51
|
+
this.triggers = [];
|
|
42
52
|
this.referencingProperties = [];
|
|
43
53
|
this.concurrencyCheckKeys = new Set();
|
|
44
54
|
Object.assign(this, meta);
|
|
45
55
|
const name = meta.className ?? meta.name;
|
|
46
56
|
if (!this.class && name) {
|
|
47
|
-
|
|
57
|
+
let Parent;
|
|
58
|
+
if (typeof this.extends === 'function') {
|
|
59
|
+
Parent = this.extends;
|
|
60
|
+
}
|
|
61
|
+
else if (this.extends != null && typeof this.extends.class === 'function') {
|
|
62
|
+
Parent = this.extends.class;
|
|
63
|
+
}
|
|
64
|
+
const Class = Parent ? { [name]: class extends Parent {
|
|
48
65
|
} }[name] : { [name]: class {
|
|
49
66
|
} }[name];
|
|
50
67
|
this.class = Class;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Constructor, IMigrationGenerator, IMigrationRunner, IMigrator, IMigratorStorage, MaybePromise, Migration, MigrationInfo, MigrationRow, MigratorEvent } from '../typings.js';
|
|
1
|
+
import type { Constructor, IMigrationGenerator, IMigrationRunner, IMigrator, IMigratorStorage, MaybePromise, Migration, MigrationInfo, MigrationResult, MigrationRow, MigratorEvent } from '../typings.js';
|
|
2
2
|
import type { Transaction } from '../connections/Connection.js';
|
|
3
3
|
import type { Configuration, MigrationsOptions } from './Configuration.js';
|
|
4
4
|
import type { EntityManagerType, IDatabaseDriver } from '../drivers/IDatabaseDriver.js';
|
|
@@ -70,6 +70,16 @@ export declare abstract class AbstractMigrator<D extends IDatabaseDriver> implem
|
|
|
70
70
|
* @inheritDoc
|
|
71
71
|
*/
|
|
72
72
|
down(options?: string | string[] | Omit<MigrateOptions, 'from'>): Promise<MigrationInfo[]>;
|
|
73
|
+
/**
|
|
74
|
+
* @inheritDoc
|
|
75
|
+
*/
|
|
76
|
+
rollup(migrations?: string[]): Promise<MigrationResult>;
|
|
77
|
+
/**
|
|
78
|
+
* Extracts the body of a method from migration source code using brace counting.
|
|
79
|
+
* Returns the raw lines between the opening and closing braces, or empty string if not found.
|
|
80
|
+
* @internal
|
|
81
|
+
*/
|
|
82
|
+
private extractMethodBody;
|
|
73
83
|
abstract getStorage(): IMigratorStorage;
|
|
74
84
|
/**
|
|
75
85
|
* @inheritDoc
|