metal-orm 1.1.10 → 1.1.16
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/README.md +758 -769
- package/dist/index.cjs +106 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +106 -43
- package/dist/index.js.map +1 -1
- package/package.json +100 -96
- package/scripts/generate-entities/render.mjs +21 -12
- package/scripts/generate-entities/schema.mjs +209 -195
- package/scripts/generate-entities/tree-detection.mjs +159 -153
- package/scripts/inflection/pt-br.mjs +468 -468
- package/scripts/run-eslint.mjs +33 -34
- package/scripts/show-sql-seed.sql +102 -0
- package/scripts/show-sql.mjs +321 -325
- package/src/bulk/bulk-delete-executor.ts +3 -5
- package/src/bulk/bulk-insert-executor.ts +7 -7
- package/src/bulk/bulk-update-executor.ts +2 -2
- package/src/bulk/bulk-upsert-executor.ts +5 -7
- package/src/codegen/naming-strategy.ts +54 -54
- package/src/codegen/typescript.ts +482 -482
- package/src/core/ast/adapters.ts +1 -1
- package/src/core/ast/builders.ts +123 -123
- package/src/core/ast/expression-builders.ts +745 -745
- package/src/core/ast/expression-nodes.ts +304 -304
- package/src/core/ast/expression-visitor.ts +212 -212
- package/src/core/ast/expression.ts +20 -20
- package/src/core/ast/helpers.ts +14 -14
- package/src/core/ast/join.ts +18 -18
- package/src/core/ast/query.ts +200 -200
- package/src/core/ddl/dialects/base-schema-dialect.ts +1 -1
- package/src/core/ddl/dialects/mssql-schema-dialect.ts +1 -1
- package/src/core/ddl/dialects/mysql-schema-dialect.ts +1 -1
- package/src/core/ddl/dialects/postgres-schema-dialect.ts +1 -1
- package/src/core/ddl/dialects/render-reference.test.ts +70 -70
- package/src/core/ddl/dialects/sqlite-schema-dialect.ts +1 -1
- package/src/core/ddl/introspect/catalogs/index.ts +5 -5
- package/src/core/ddl/introspect/catalogs/postgres.ts +146 -146
- package/src/core/ddl/introspect/context.ts +15 -15
- package/src/core/ddl/introspect/functions/postgres.ts +35 -35
- package/src/core/ddl/introspect/mysql.ts +113 -36
- package/src/core/ddl/introspect/registry.ts +40 -40
- package/src/core/ddl/introspect/run-select.ts +35 -35
- package/src/core/ddl/introspect/utils.ts +56 -56
- package/src/core/ddl/naming-strategy.ts +16 -16
- package/src/core/ddl/schema-dialect.ts +56 -56
- package/src/core/ddl/schema-diff.ts +234 -234
- package/src/core/ddl/schema-generator.ts +1 -1
- package/src/core/ddl/schema-introspect.ts +25 -25
- package/src/core/ddl/sql-writing.ts +171 -171
- package/src/core/dialect/abstract.ts +541 -541
- package/src/core/dialect/base/cte-compiler.ts +33 -33
- package/src/core/dialect/base/function-table-formatter.ts +103 -103
- package/src/core/dialect/base/groupby-compiler.ts +21 -21
- package/src/core/dialect/base/join-compiler.ts +25 -25
- package/src/core/dialect/base/orderby-compiler.ts +35 -35
- package/src/core/dialect/base/pagination-strategy.ts +32 -32
- package/src/core/dialect/base/returning-strategy.ts +57 -57
- package/src/core/dialect/base/sql-dialect.ts +294 -294
- package/src/core/dialect/dialect-factory.ts +91 -91
- package/src/core/dialect/mssql/functions.ts +120 -120
- package/src/core/dialect/mssql/index.ts +317 -317
- package/src/core/dialect/mysql/functions.ts +103 -103
- package/src/core/dialect/mysql/index.ts +105 -105
- package/src/core/dialect/postgres/functions.ts +108 -108
- package/src/core/dialect/postgres/index.ts +91 -91
- package/src/core/dialect/sqlite/functions.ts +129 -129
- package/src/core/dialect/sqlite/index.ts +67 -67
- package/src/core/driver/database-driver.ts +19 -19
- package/src/core/driver/mssql-driver.ts +23 -23
- package/src/core/driver/mysql-driver.ts +23 -23
- package/src/core/driver/postgres-driver.ts +23 -23
- package/src/core/driver/sqlite-driver.ts +23 -23
- package/src/core/execution/db-executor.ts +92 -92
- package/src/core/execution/executors/better-sqlite3-executor.ts +94 -94
- package/src/core/execution/executors/mssql-executor.ts +184 -184
- package/src/core/execution/executors/mysql-executor.ts +88 -88
- package/src/core/execution/executors/postgres-executor.ts +26 -26
- package/src/core/execution/executors/sqlite-executor.ts +42 -42
- package/src/core/execution/pooling/pool-types.ts +30 -30
- package/src/core/execution/pooling/pool.ts +275 -275
- package/src/core/functions/array.ts +35 -35
- package/src/core/functions/control-flow.ts +79 -79
- package/src/core/functions/datetime.ts +237 -237
- package/src/core/functions/json.ts +70 -70
- package/src/core/functions/numeric.ts +297 -297
- package/src/core/functions/text.ts +334 -334
- package/src/core/functions/types.ts +33 -33
- package/src/core/hydration/types.ts +51 -51
- package/src/core/sql/sql-operator-config.ts +39 -39
- package/src/core/sql/sql.ts +152 -152
- package/src/decorators/column-decorator.ts +87 -87
- package/src/decorators/decorator-metadata.ts +143 -143
- package/src/decorators/entity.ts +93 -93
- package/src/decorators/index.ts +39 -39
- package/src/decorators/relations.ts +231 -231
- package/src/decorators/transformers/built-in/string-transformers.ts +231 -231
- package/src/decorators/transformers/transformer-decorators.ts +134 -134
- package/src/decorators/transformers/transformer-executor.ts +171 -171
- package/src/decorators/transformers/transformer-metadata.ts +73 -73
- package/src/decorators/validators/built-in/br-cep-validator.ts +55 -55
- package/src/decorators/validators/built-in/br-cnpj-validator.ts +105 -105
- package/src/decorators/validators/built-in/br-cpf-validator.ts +103 -103
- package/src/decorators/validators/country-validator-registry.ts +64 -64
- package/src/decorators/validators/country-validators-decorators.ts +203 -203
- package/src/decorators/validators/country-validators.ts +105 -105
- package/src/decorators/validators/validator-metadata.ts +59 -59
- package/src/dto/dto-types.ts +226 -226
- package/src/dto/filter-types.ts +141 -141
- package/src/dto/index.ts +95 -95
- package/src/dto/openapi/generators/base.ts +29 -29
- package/src/dto/openapi/generators/column.ts +37 -37
- package/src/dto/openapi/generators/dto.ts +91 -91
- package/src/dto/openapi/generators/filter.ts +75 -75
- package/src/dto/openapi/generators/nested-dto.ts +618 -618
- package/src/dto/openapi/generators/pagination.ts +111 -111
- package/src/dto/openapi/generators/relation-filter.ts +228 -228
- package/src/dto/openapi/index.ts +12 -12
- package/src/dto/openapi/types.ts +101 -101
- package/src/dto/openapi/utilities.ts +95 -95
- package/src/dto/pagination-utils.ts +150 -150
- package/src/dto/transform.ts +197 -197
- package/src/index.ts +86 -86
- package/src/orm/als.ts +58 -58
- package/src/orm/domain-event-bus.ts +119 -119
- package/src/orm/entity-context.ts +86 -86
- package/src/orm/entity-materializer.ts +159 -159
- package/src/orm/entity-meta.ts +97 -97
- package/src/orm/entity-registry.ts +39 -39
- package/src/orm/entity-relation-cache.ts +39 -39
- package/src/orm/execute.ts +194 -194
- package/src/orm/execution-context.ts +18 -18
- package/src/orm/hydration-context.ts +26 -26
- package/src/orm/hydration.ts +112 -112
- package/src/orm/identity-map.ts +61 -61
- package/src/orm/interceptor-pipeline.ts +16 -16
- package/src/orm/lazy-batch/belongs-to-many.ts +119 -119
- package/src/orm/lazy-batch/belongs-to.ts +108 -108
- package/src/orm/lazy-batch/has-many.ts +69 -69
- package/src/orm/lazy-batch/has-one.ts +68 -68
- package/src/orm/lazy-batch/shared.ts +125 -125
- package/src/orm/orm-session.ts +620 -620
- package/src/orm/orm.ts +34 -34
- package/src/orm/pooled-executor-factory.ts +121 -121
- package/src/orm/query-logger.ts +40 -40
- package/src/orm/relation-change-processor.ts +420 -420
- package/src/orm/relations/belongs-to.ts +143 -143
- package/src/orm/relations/has-many.ts +204 -204
- package/src/orm/relations/has-one.ts +174 -174
- package/src/orm/relations/many-to-many.ts +288 -288
- package/src/orm/relations/morph-many.ts +156 -156
- package/src/orm/relations/morph-one.ts +151 -151
- package/src/orm/relations/morph-to.ts +162 -162
- package/src/orm/runtime-types.ts +92 -92
- package/src/orm/save-graph.ts +561 -561
- package/src/orm/transaction-runner.ts +24 -24
- package/src/orm/unit-of-work.ts +426 -426
- package/src/query/index.ts +69 -69
- package/src/query/target.ts +46 -46
- package/src/query-builder/column-selector.ts +81 -81
- package/src/query-builder/delete.ts +141 -141
- package/src/query-builder/insert-query-state.ts +149 -149
- package/src/query-builder/insert.ts +117 -117
- package/src/query-builder/query-ast-service.ts +287 -287
- package/src/query-builder/query-resolution.ts +78 -78
- package/src/query-builder/raw-column-parser.ts +38 -38
- package/src/query-builder/relation-filter-utils.ts +153 -153
- package/src/query-builder/relation-join-planner.ts +10 -10
- package/src/query-builder/relation-manager.ts +87 -87
- package/src/query-builder/relation-projection-helper.ts +102 -102
- package/src/query-builder/relation-types.ts +9 -9
- package/src/query-builder/relation-utils.ts +15 -15
- package/src/query-builder/select/cte-facet.ts +40 -40
- package/src/query-builder/select/from-facet.ts +80 -80
- package/src/query-builder/select/join-facet.ts +62 -62
- package/src/query-builder/select/predicate-facet.ts +104 -104
- package/src/query-builder/select/projection-facet.ts +70 -70
- package/src/query-builder/select/relation-facet.ts +81 -81
- package/src/query-builder/select/setop-facet.ts +36 -36
- package/src/query-builder/select-helpers.ts +1 -1
- package/src/query-builder/select-query-builder-deps.ts +130 -130
- package/src/query-builder/select-query-state.ts +207 -207
- package/src/query-builder/update.ts +151 -151
- package/src/schema/column-types.ts +322 -322
- package/src/schema/table-guards.ts +37 -37
- package/src/schema/table.ts +281 -281
- package/src/tree/index.ts +13 -13
- package/src/tree/nested-set-strategy.ts +545 -545
- package/src/tree/tree-decorator.ts +397 -397
- package/src/tree/tree-manager.ts +754 -754
- package/src/tree/tree-query.ts +427 -427
- package/src/tree/tree-types.ts +299 -299
|
@@ -1,143 +1,143 @@
|
|
|
1
|
-
import { BelongsToReferenceApi } from '../../schema/types.js';
|
|
2
|
-
import { EntityContext } from '../entity-context.js';
|
|
3
|
-
import { RelationKey } from '../runtime-types.js';
|
|
4
|
-
import { BelongsToRelation } from '../../schema/relation.js';
|
|
5
|
-
import { TableDef } from '../../schema/table.js';
|
|
6
|
-
import { EntityMeta, getHydrationRecord, hasEntityMeta } from '../entity-meta.js';
|
|
7
|
-
|
|
8
|
-
type Rows = Record<string, unknown>;
|
|
9
|
-
|
|
10
|
-
const toKey = (value: unknown): string => (value === null || value === undefined ? '' : String(value));
|
|
11
|
-
|
|
12
|
-
const hideInternal = (obj: object, keys: string[]): void => {
|
|
13
|
-
for (const key of keys) {
|
|
14
|
-
Object.defineProperty(obj, key, {
|
|
15
|
-
value: obj[key],
|
|
16
|
-
writable: false,
|
|
17
|
-
configurable: false,
|
|
18
|
-
enumerable: false
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const hideWritable = (obj: object, keys: string[]): void => {
|
|
24
|
-
for (const key of keys) {
|
|
25
|
-
const value = obj[key as keyof typeof obj];
|
|
26
|
-
Object.defineProperty(obj, key, {
|
|
27
|
-
value,
|
|
28
|
-
writable: true,
|
|
29
|
-
configurable: true,
|
|
30
|
-
enumerable: false
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Default implementation of a belongs-to reference.
|
|
37
|
-
* Manages a reference to a parent entity from a child entity through a foreign key.
|
|
38
|
-
*
|
|
39
|
-
* @template TParent The type of the parent entity.
|
|
40
|
-
*/
|
|
41
|
-
export class DefaultBelongsToReference<TParent extends object> implements BelongsToReferenceApi<TParent> {
|
|
42
|
-
private loaded = false;
|
|
43
|
-
private current: TParent | null = null;
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* @param ctx The entity context for tracking changes.
|
|
47
|
-
* @param meta Metadata for the child entity.
|
|
48
|
-
* @param root The child entity instance (carrying the foreign key).
|
|
49
|
-
* @param relationName The name of the relation.
|
|
50
|
-
* @param relation Relation definition.
|
|
51
|
-
* @param rootTable Table definition of the child entity.
|
|
52
|
-
* @param loader Function to load the parent entity.
|
|
53
|
-
* @param createEntity Function to create entity instances from rows.
|
|
54
|
-
* @param targetKey The primary key of the target (parent) table.
|
|
55
|
-
*/
|
|
56
|
-
constructor(
|
|
57
|
-
private readonly ctx: EntityContext,
|
|
58
|
-
private readonly meta: EntityMeta<TableDef>,
|
|
59
|
-
private readonly root: unknown,
|
|
60
|
-
private readonly relationName: string,
|
|
61
|
-
private readonly relation: BelongsToRelation,
|
|
62
|
-
private readonly rootTable: TableDef,
|
|
63
|
-
private readonly loader: () => Promise<Map<string, Rows>>,
|
|
64
|
-
private readonly createEntity: (row: Record<string, unknown>) => TParent,
|
|
65
|
-
private readonly targetKey: string
|
|
66
|
-
) {
|
|
67
|
-
hideInternal(this, ['ctx', 'meta', 'root', 'relationName', 'relation', 'rootTable', 'loader', 'createEntity', 'targetKey']);
|
|
68
|
-
hideWritable(this, ['loaded', 'current']);
|
|
69
|
-
this.populateFromHydrationCache();
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
async load(): Promise<TParent | null> {
|
|
73
|
-
if (this.loaded) return this.current;
|
|
74
|
-
const map = await this.loader();
|
|
75
|
-
const fkValue = (this.root as Record<string, unknown>)[this.relation.foreignKey];
|
|
76
|
-
if (fkValue === null || fkValue === undefined) {
|
|
77
|
-
this.current = null;
|
|
78
|
-
} else {
|
|
79
|
-
const row = map.get(toKey(fkValue));
|
|
80
|
-
this.current = row ? this.createEntity(row) : null;
|
|
81
|
-
}
|
|
82
|
-
this.loaded = true;
|
|
83
|
-
return this.current;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
get(): TParent | null {
|
|
87
|
-
return this.current;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
set(data: Partial<TParent> | TParent | null): TParent | null {
|
|
91
|
-
if (data === null) {
|
|
92
|
-
const previous = this.current;
|
|
93
|
-
(this.root as Record<string, unknown>)[this.relation.foreignKey] = null;
|
|
94
|
-
this.current = null;
|
|
95
|
-
this.ctx.registerRelationChange(
|
|
96
|
-
this.root,
|
|
97
|
-
this.relationKey,
|
|
98
|
-
this.rootTable,
|
|
99
|
-
this.relationName,
|
|
100
|
-
this.relation,
|
|
101
|
-
{ kind: 'remove', entity: previous }
|
|
102
|
-
);
|
|
103
|
-
return null;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const entity = hasEntityMeta(data) ? (data as TParent) : this.createEntity(data as Record<string, unknown>);
|
|
107
|
-
const pkValue = (entity as Record<string, unknown>)[this.targetKey];
|
|
108
|
-
if (pkValue !== undefined) {
|
|
109
|
-
(this.root as Record<string, unknown>)[this.relation.foreignKey] = pkValue;
|
|
110
|
-
}
|
|
111
|
-
this.current = entity;
|
|
112
|
-
this.ctx.registerRelationChange(
|
|
113
|
-
this.root,
|
|
114
|
-
this.relationKey,
|
|
115
|
-
this.rootTable,
|
|
116
|
-
this.relationName,
|
|
117
|
-
this.relation,
|
|
118
|
-
{ kind: 'attach', entity }
|
|
119
|
-
);
|
|
120
|
-
return entity;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
private get relationKey(): RelationKey {
|
|
124
|
-
return `${this.rootTable.name}.${this.relationName}`;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
private populateFromHydrationCache(): void {
|
|
128
|
-
const fkValue = (this.root as Record<string, unknown>)[this.relation.foreignKey];
|
|
129
|
-
if (fkValue === undefined || fkValue === null) return;
|
|
130
|
-
const row = getHydrationRecord(this.meta, this.relationName, fkValue);
|
|
131
|
-
if (!row) return;
|
|
132
|
-
this.current = this.createEntity(row);
|
|
133
|
-
this.loaded = true;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
toJSON(): unknown {
|
|
137
|
-
if (!this.current) return null;
|
|
138
|
-
const entityWithToJSON = this.current as { toJSON?: () => unknown };
|
|
139
|
-
return typeof entityWithToJSON.toJSON === 'function'
|
|
140
|
-
? entityWithToJSON.toJSON()
|
|
141
|
-
: this.current;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
1
|
+
import { BelongsToReferenceApi } from '../../schema/types.js';
|
|
2
|
+
import { EntityContext } from '../entity-context.js';
|
|
3
|
+
import { RelationKey } from '../runtime-types.js';
|
|
4
|
+
import { BelongsToRelation } from '../../schema/relation.js';
|
|
5
|
+
import { TableDef } from '../../schema/table.js';
|
|
6
|
+
import { EntityMeta, getHydrationRecord, hasEntityMeta } from '../entity-meta.js';
|
|
7
|
+
|
|
8
|
+
type Rows = Record<string, unknown>;
|
|
9
|
+
|
|
10
|
+
const toKey = (value: unknown): string => (value === null || value === undefined ? '' : String(value));
|
|
11
|
+
|
|
12
|
+
const hideInternal = (obj: object, keys: string[]): void => {
|
|
13
|
+
for (const key of keys) {
|
|
14
|
+
Object.defineProperty(obj, key, {
|
|
15
|
+
value: obj[key],
|
|
16
|
+
writable: false,
|
|
17
|
+
configurable: false,
|
|
18
|
+
enumerable: false
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const hideWritable = (obj: object, keys: string[]): void => {
|
|
24
|
+
for (const key of keys) {
|
|
25
|
+
const value = obj[key as keyof typeof obj];
|
|
26
|
+
Object.defineProperty(obj, key, {
|
|
27
|
+
value,
|
|
28
|
+
writable: true,
|
|
29
|
+
configurable: true,
|
|
30
|
+
enumerable: false
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Default implementation of a belongs-to reference.
|
|
37
|
+
* Manages a reference to a parent entity from a child entity through a foreign key.
|
|
38
|
+
*
|
|
39
|
+
* @template TParent The type of the parent entity.
|
|
40
|
+
*/
|
|
41
|
+
export class DefaultBelongsToReference<TParent extends object> implements BelongsToReferenceApi<TParent> {
|
|
42
|
+
private loaded = false;
|
|
43
|
+
private current: TParent | null = null;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @param ctx The entity context for tracking changes.
|
|
47
|
+
* @param meta Metadata for the child entity.
|
|
48
|
+
* @param root The child entity instance (carrying the foreign key).
|
|
49
|
+
* @param relationName The name of the relation.
|
|
50
|
+
* @param relation Relation definition.
|
|
51
|
+
* @param rootTable Table definition of the child entity.
|
|
52
|
+
* @param loader Function to load the parent entity.
|
|
53
|
+
* @param createEntity Function to create entity instances from rows.
|
|
54
|
+
* @param targetKey The primary key of the target (parent) table.
|
|
55
|
+
*/
|
|
56
|
+
constructor(
|
|
57
|
+
private readonly ctx: EntityContext,
|
|
58
|
+
private readonly meta: EntityMeta<TableDef>,
|
|
59
|
+
private readonly root: unknown,
|
|
60
|
+
private readonly relationName: string,
|
|
61
|
+
private readonly relation: BelongsToRelation,
|
|
62
|
+
private readonly rootTable: TableDef,
|
|
63
|
+
private readonly loader: () => Promise<Map<string, Rows>>,
|
|
64
|
+
private readonly createEntity: (row: Record<string, unknown>) => TParent,
|
|
65
|
+
private readonly targetKey: string
|
|
66
|
+
) {
|
|
67
|
+
hideInternal(this, ['ctx', 'meta', 'root', 'relationName', 'relation', 'rootTable', 'loader', 'createEntity', 'targetKey']);
|
|
68
|
+
hideWritable(this, ['loaded', 'current']);
|
|
69
|
+
this.populateFromHydrationCache();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async load(): Promise<TParent | null> {
|
|
73
|
+
if (this.loaded) return this.current;
|
|
74
|
+
const map = await this.loader();
|
|
75
|
+
const fkValue = (this.root as Record<string, unknown>)[this.relation.foreignKey];
|
|
76
|
+
if (fkValue === null || fkValue === undefined) {
|
|
77
|
+
this.current = null;
|
|
78
|
+
} else {
|
|
79
|
+
const row = map.get(toKey(fkValue));
|
|
80
|
+
this.current = row ? this.createEntity(row) : null;
|
|
81
|
+
}
|
|
82
|
+
this.loaded = true;
|
|
83
|
+
return this.current;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
get(): TParent | null {
|
|
87
|
+
return this.current;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
set(data: Partial<TParent> | TParent | null): TParent | null {
|
|
91
|
+
if (data === null) {
|
|
92
|
+
const previous = this.current;
|
|
93
|
+
(this.root as Record<string, unknown>)[this.relation.foreignKey] = null;
|
|
94
|
+
this.current = null;
|
|
95
|
+
this.ctx.registerRelationChange(
|
|
96
|
+
this.root,
|
|
97
|
+
this.relationKey,
|
|
98
|
+
this.rootTable,
|
|
99
|
+
this.relationName,
|
|
100
|
+
this.relation,
|
|
101
|
+
{ kind: 'remove', entity: previous }
|
|
102
|
+
);
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const entity = hasEntityMeta(data) ? (data as TParent) : this.createEntity(data as Record<string, unknown>);
|
|
107
|
+
const pkValue = (entity as Record<string, unknown>)[this.targetKey];
|
|
108
|
+
if (pkValue !== undefined) {
|
|
109
|
+
(this.root as Record<string, unknown>)[this.relation.foreignKey] = pkValue;
|
|
110
|
+
}
|
|
111
|
+
this.current = entity;
|
|
112
|
+
this.ctx.registerRelationChange(
|
|
113
|
+
this.root,
|
|
114
|
+
this.relationKey,
|
|
115
|
+
this.rootTable,
|
|
116
|
+
this.relationName,
|
|
117
|
+
this.relation,
|
|
118
|
+
{ kind: 'attach', entity }
|
|
119
|
+
);
|
|
120
|
+
return entity;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
private get relationKey(): RelationKey {
|
|
124
|
+
return `${this.rootTable.name}.${this.relationName}`;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
private populateFromHydrationCache(): void {
|
|
128
|
+
const fkValue = (this.root as Record<string, unknown>)[this.relation.foreignKey];
|
|
129
|
+
if (fkValue === undefined || fkValue === null) return;
|
|
130
|
+
const row = getHydrationRecord(this.meta, this.relationName, fkValue);
|
|
131
|
+
if (!row) return;
|
|
132
|
+
this.current = this.createEntity(row);
|
|
133
|
+
this.loaded = true;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
toJSON(): unknown {
|
|
137
|
+
if (!this.current) return null;
|
|
138
|
+
const entityWithToJSON = this.current as { toJSON?: () => unknown };
|
|
139
|
+
return typeof entityWithToJSON.toJSON === 'function'
|
|
140
|
+
? entityWithToJSON.toJSON()
|
|
141
|
+
: this.current;
|
|
142
|
+
}
|
|
143
|
+
}
|