metal-orm 1.0.102 → 1.0.104
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/dist/index.cjs +103 -81
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -8
- package/dist/index.d.ts +6 -8
- package/dist/index.js +103 -81
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/scripts/generate-entities/cli.mjs +1 -1
- package/scripts/generate-entities/generate.mjs +21 -12
- package/scripts/generate-entities/render.mjs +5 -4
- package/scripts/naming-strategy.mjs +19 -3
- package/src/orm/entity-relations.ts +209 -207
- package/src/orm/entity.ts +160 -151
- package/src/orm/relations/belongs-to.ts +130 -126
- package/src/orm/relations/has-many.ts +190 -186
- package/src/orm/relations/has-one.ts +162 -158
- package/src/orm/relations/many-to-many.ts +228 -224
package/dist/index.d.cts
CHANGED
|
@@ -6463,6 +6463,7 @@ type Rows$2 = Record<string, unknown>[];
|
|
|
6463
6463
|
* @template TChild - The type of child entities in the collection
|
|
6464
6464
|
*/
|
|
6465
6465
|
declare class DefaultHasManyCollection<TChild> implements HasManyCollection<TChild> {
|
|
6466
|
+
#private;
|
|
6466
6467
|
private readonly ctx;
|
|
6467
6468
|
private readonly meta;
|
|
6468
6469
|
private readonly root;
|
|
@@ -6472,10 +6473,6 @@ declare class DefaultHasManyCollection<TChild> implements HasManyCollection<TChi
|
|
|
6472
6473
|
private readonly loader;
|
|
6473
6474
|
private readonly createEntity;
|
|
6474
6475
|
private readonly localKey;
|
|
6475
|
-
private loaded;
|
|
6476
|
-
private items;
|
|
6477
|
-
private readonly added;
|
|
6478
|
-
private readonly removed;
|
|
6479
6476
|
/**
|
|
6480
6477
|
* Creates a new DefaultHasManyCollection instance.
|
|
6481
6478
|
* @param ctx - The entity context
|
|
@@ -6527,6 +6524,7 @@ declare class DefaultHasManyCollection<TChild> implements HasManyCollection<TChi
|
|
|
6527
6524
|
* Clears all entities from the collection.
|
|
6528
6525
|
*/
|
|
6529
6526
|
clear(): void;
|
|
6527
|
+
isLoaded(): boolean;
|
|
6530
6528
|
private get relationKey();
|
|
6531
6529
|
private hydrateFromCache;
|
|
6532
6530
|
/**
|
|
@@ -6544,6 +6542,7 @@ type Rows$1 = Record<string, unknown>;
|
|
|
6544
6542
|
* @template TParent The type of the parent entity.
|
|
6545
6543
|
*/
|
|
6546
6544
|
declare class DefaultBelongsToReference<TParent extends object> implements BelongsToReferenceApi<TParent> {
|
|
6545
|
+
#private;
|
|
6547
6546
|
private readonly ctx;
|
|
6548
6547
|
private readonly meta;
|
|
6549
6548
|
private readonly root;
|
|
@@ -6553,8 +6552,6 @@ declare class DefaultBelongsToReference<TParent extends object> implements Belon
|
|
|
6553
6552
|
private readonly loader;
|
|
6554
6553
|
private readonly createEntity;
|
|
6555
6554
|
private readonly targetKey;
|
|
6556
|
-
private loaded;
|
|
6557
|
-
private current;
|
|
6558
6555
|
/**
|
|
6559
6556
|
* @param ctx The entity context for tracking changes.
|
|
6560
6557
|
* @param meta Metadata for the child entity.
|
|
@@ -6570,6 +6567,7 @@ declare class DefaultBelongsToReference<TParent extends object> implements Belon
|
|
|
6570
6567
|
load(): Promise<TParent | null>;
|
|
6571
6568
|
get(): TParent | null;
|
|
6572
6569
|
set(data: Partial<TParent> | TParent | null): TParent | null;
|
|
6570
|
+
isLoaded(): boolean;
|
|
6573
6571
|
private get relationKey();
|
|
6574
6572
|
private populateFromHydrationCache;
|
|
6575
6573
|
toJSON(): TParent | null;
|
|
@@ -6584,6 +6582,7 @@ type Rows = Record<string, unknown>[];
|
|
|
6584
6582
|
* @template TTarget The type of the target entities in the collection.
|
|
6585
6583
|
*/
|
|
6586
6584
|
declare class DefaultManyToManyCollection<TTarget, TPivot extends object | undefined = undefined> implements ManyToManyCollection<TTarget, TPivot> {
|
|
6585
|
+
#private;
|
|
6587
6586
|
private readonly ctx;
|
|
6588
6587
|
private readonly meta;
|
|
6589
6588
|
private readonly root;
|
|
@@ -6593,8 +6592,6 @@ declare class DefaultManyToManyCollection<TTarget, TPivot extends object | undef
|
|
|
6593
6592
|
private readonly loader;
|
|
6594
6593
|
private readonly createEntity;
|
|
6595
6594
|
private readonly localKey;
|
|
6596
|
-
private loaded;
|
|
6597
|
-
private items;
|
|
6598
6595
|
/**
|
|
6599
6596
|
* @param ctx The entity context for tracking changes.
|
|
6600
6597
|
* @param meta Metadata for the root entity.
|
|
@@ -6643,6 +6640,7 @@ declare class DefaultManyToManyCollection<TTarget, TPivot extends object | undef
|
|
|
6643
6640
|
* @param ids Array of primary key values to sync with.
|
|
6644
6641
|
*/
|
|
6645
6642
|
syncByIds(ids: (number | string)[]): Promise<void>;
|
|
6643
|
+
isLoaded(): boolean;
|
|
6646
6644
|
private ensureEntity;
|
|
6647
6645
|
private extractId;
|
|
6648
6646
|
private get relationKey();
|
package/dist/index.d.ts
CHANGED
|
@@ -6463,6 +6463,7 @@ type Rows$2 = Record<string, unknown>[];
|
|
|
6463
6463
|
* @template TChild - The type of child entities in the collection
|
|
6464
6464
|
*/
|
|
6465
6465
|
declare class DefaultHasManyCollection<TChild> implements HasManyCollection<TChild> {
|
|
6466
|
+
#private;
|
|
6466
6467
|
private readonly ctx;
|
|
6467
6468
|
private readonly meta;
|
|
6468
6469
|
private readonly root;
|
|
@@ -6472,10 +6473,6 @@ declare class DefaultHasManyCollection<TChild> implements HasManyCollection<TChi
|
|
|
6472
6473
|
private readonly loader;
|
|
6473
6474
|
private readonly createEntity;
|
|
6474
6475
|
private readonly localKey;
|
|
6475
|
-
private loaded;
|
|
6476
|
-
private items;
|
|
6477
|
-
private readonly added;
|
|
6478
|
-
private readonly removed;
|
|
6479
6476
|
/**
|
|
6480
6477
|
* Creates a new DefaultHasManyCollection instance.
|
|
6481
6478
|
* @param ctx - The entity context
|
|
@@ -6527,6 +6524,7 @@ declare class DefaultHasManyCollection<TChild> implements HasManyCollection<TChi
|
|
|
6527
6524
|
* Clears all entities from the collection.
|
|
6528
6525
|
*/
|
|
6529
6526
|
clear(): void;
|
|
6527
|
+
isLoaded(): boolean;
|
|
6530
6528
|
private get relationKey();
|
|
6531
6529
|
private hydrateFromCache;
|
|
6532
6530
|
/**
|
|
@@ -6544,6 +6542,7 @@ type Rows$1 = Record<string, unknown>;
|
|
|
6544
6542
|
* @template TParent The type of the parent entity.
|
|
6545
6543
|
*/
|
|
6546
6544
|
declare class DefaultBelongsToReference<TParent extends object> implements BelongsToReferenceApi<TParent> {
|
|
6545
|
+
#private;
|
|
6547
6546
|
private readonly ctx;
|
|
6548
6547
|
private readonly meta;
|
|
6549
6548
|
private readonly root;
|
|
@@ -6553,8 +6552,6 @@ declare class DefaultBelongsToReference<TParent extends object> implements Belon
|
|
|
6553
6552
|
private readonly loader;
|
|
6554
6553
|
private readonly createEntity;
|
|
6555
6554
|
private readonly targetKey;
|
|
6556
|
-
private loaded;
|
|
6557
|
-
private current;
|
|
6558
6555
|
/**
|
|
6559
6556
|
* @param ctx The entity context for tracking changes.
|
|
6560
6557
|
* @param meta Metadata for the child entity.
|
|
@@ -6570,6 +6567,7 @@ declare class DefaultBelongsToReference<TParent extends object> implements Belon
|
|
|
6570
6567
|
load(): Promise<TParent | null>;
|
|
6571
6568
|
get(): TParent | null;
|
|
6572
6569
|
set(data: Partial<TParent> | TParent | null): TParent | null;
|
|
6570
|
+
isLoaded(): boolean;
|
|
6573
6571
|
private get relationKey();
|
|
6574
6572
|
private populateFromHydrationCache;
|
|
6575
6573
|
toJSON(): TParent | null;
|
|
@@ -6584,6 +6582,7 @@ type Rows = Record<string, unknown>[];
|
|
|
6584
6582
|
* @template TTarget The type of the target entities in the collection.
|
|
6585
6583
|
*/
|
|
6586
6584
|
declare class DefaultManyToManyCollection<TTarget, TPivot extends object | undefined = undefined> implements ManyToManyCollection<TTarget, TPivot> {
|
|
6585
|
+
#private;
|
|
6587
6586
|
private readonly ctx;
|
|
6588
6587
|
private readonly meta;
|
|
6589
6588
|
private readonly root;
|
|
@@ -6593,8 +6592,6 @@ declare class DefaultManyToManyCollection<TTarget, TPivot extends object | undef
|
|
|
6593
6592
|
private readonly loader;
|
|
6594
6593
|
private readonly createEntity;
|
|
6595
6594
|
private readonly localKey;
|
|
6596
|
-
private loaded;
|
|
6597
|
-
private items;
|
|
6598
6595
|
/**
|
|
6599
6596
|
* @param ctx The entity context for tracking changes.
|
|
6600
6597
|
* @param meta Metadata for the root entity.
|
|
@@ -6643,6 +6640,7 @@ declare class DefaultManyToManyCollection<TTarget, TPivot extends object | undef
|
|
|
6643
6640
|
* @param ids Array of primary key values to sync with.
|
|
6644
6641
|
*/
|
|
6645
6642
|
syncByIds(ids: (number | string)[]): Promise<void>;
|
|
6643
|
+
isLoaded(): boolean;
|
|
6646
6644
|
private ensureEntity;
|
|
6647
6645
|
private extractId;
|
|
6648
6646
|
private get relationKey();
|
package/dist/index.js
CHANGED
|
@@ -4933,41 +4933,41 @@ var DefaultHasManyCollection = class {
|
|
|
4933
4933
|
hideInternal(this, ["ctx", "meta", "root", "relationName", "relation", "rootTable", "loader", "createEntity", "localKey"]);
|
|
4934
4934
|
this.hydrateFromCache();
|
|
4935
4935
|
}
|
|
4936
|
-
loaded = false;
|
|
4937
|
-
items = [];
|
|
4938
|
-
added = /* @__PURE__ */ new Set();
|
|
4939
|
-
removed = /* @__PURE__ */ new Set();
|
|
4936
|
+
#loaded = false;
|
|
4937
|
+
#items = [];
|
|
4938
|
+
#added = /* @__PURE__ */ new Set();
|
|
4939
|
+
#removed = /* @__PURE__ */ new Set();
|
|
4940
4940
|
/**
|
|
4941
4941
|
* Loads the related entities if not already loaded.
|
|
4942
4942
|
* @returns Promise resolving to the array of child entities
|
|
4943
4943
|
*/
|
|
4944
4944
|
async load() {
|
|
4945
|
-
if (this
|
|
4945
|
+
if (this.#loaded) return this.#items;
|
|
4946
4946
|
const map = await this.loader();
|
|
4947
4947
|
const key = toKey3(this.root[this.localKey]);
|
|
4948
4948
|
const rows = map.get(key) ?? [];
|
|
4949
|
-
this
|
|
4950
|
-
this
|
|
4951
|
-
return this
|
|
4949
|
+
this.#items = rows.map((row) => this.createEntity(row));
|
|
4950
|
+
this.#loaded = true;
|
|
4951
|
+
return this.#items;
|
|
4952
4952
|
}
|
|
4953
4953
|
/**
|
|
4954
4954
|
* Gets the current items in the collection.
|
|
4955
4955
|
* @returns Array of child entities
|
|
4956
4956
|
*/
|
|
4957
4957
|
getItems() {
|
|
4958
|
-
return this
|
|
4958
|
+
return this.#items;
|
|
4959
4959
|
}
|
|
4960
4960
|
/**
|
|
4961
4961
|
* Array-compatible length for testing frameworks.
|
|
4962
4962
|
*/
|
|
4963
4963
|
get length() {
|
|
4964
|
-
return this
|
|
4964
|
+
return this.#items.length;
|
|
4965
4965
|
}
|
|
4966
4966
|
/**
|
|
4967
4967
|
* Enables iteration over the collection like an array.
|
|
4968
4968
|
*/
|
|
4969
4969
|
[Symbol.iterator]() {
|
|
4970
|
-
return this
|
|
4970
|
+
return this.#items[Symbol.iterator]();
|
|
4971
4971
|
}
|
|
4972
4972
|
/**
|
|
4973
4973
|
* Adds a new child entity to the collection.
|
|
@@ -4981,8 +4981,8 @@ var DefaultHasManyCollection = class {
|
|
|
4981
4981
|
[this.relation.foreignKey]: keyValue
|
|
4982
4982
|
};
|
|
4983
4983
|
const entity = this.createEntity(childRow);
|
|
4984
|
-
this
|
|
4985
|
-
this
|
|
4984
|
+
this.#added.add(entity);
|
|
4985
|
+
this.#items.push(entity);
|
|
4986
4986
|
this.ctx.registerRelationChange(
|
|
4987
4987
|
this.root,
|
|
4988
4988
|
this.relationKey,
|
|
@@ -5001,7 +5001,7 @@ var DefaultHasManyCollection = class {
|
|
|
5001
5001
|
const keyValue = this.root[this.localKey];
|
|
5002
5002
|
entity[this.relation.foreignKey] = keyValue;
|
|
5003
5003
|
this.ctx.markDirty(entity);
|
|
5004
|
-
this
|
|
5004
|
+
this.#items.push(entity);
|
|
5005
5005
|
this.ctx.registerRelationChange(
|
|
5006
5006
|
this.root,
|
|
5007
5007
|
this.relationKey,
|
|
@@ -5016,8 +5016,8 @@ var DefaultHasManyCollection = class {
|
|
|
5016
5016
|
* @param entity - The entity to remove
|
|
5017
5017
|
*/
|
|
5018
5018
|
remove(entity) {
|
|
5019
|
-
this
|
|
5020
|
-
this
|
|
5019
|
+
this.#items = this.#items.filter((item) => item !== entity);
|
|
5020
|
+
this.#removed.add(entity);
|
|
5021
5021
|
this.ctx.registerRelationChange(
|
|
5022
5022
|
this.root,
|
|
5023
5023
|
this.relationKey,
|
|
@@ -5031,10 +5031,13 @@ var DefaultHasManyCollection = class {
|
|
|
5031
5031
|
* Clears all entities from the collection.
|
|
5032
5032
|
*/
|
|
5033
5033
|
clear() {
|
|
5034
|
-
for (const entity of [...this
|
|
5034
|
+
for (const entity of [...this.#items]) {
|
|
5035
5035
|
this.remove(entity);
|
|
5036
5036
|
}
|
|
5037
5037
|
}
|
|
5038
|
+
isLoaded() {
|
|
5039
|
+
return this.#loaded;
|
|
5040
|
+
}
|
|
5038
5041
|
get relationKey() {
|
|
5039
5042
|
return `${this.rootTable.name}.${this.relationName}`;
|
|
5040
5043
|
}
|
|
@@ -5043,15 +5046,15 @@ var DefaultHasManyCollection = class {
|
|
|
5043
5046
|
if (keyValue === void 0 || keyValue === null) return;
|
|
5044
5047
|
const rows = getHydrationRows(this.meta, this.relationName, keyValue);
|
|
5045
5048
|
if (!rows?.length) return;
|
|
5046
|
-
this
|
|
5047
|
-
this
|
|
5049
|
+
this.#items = rows.map((row) => this.createEntity(row));
|
|
5050
|
+
this.#loaded = true;
|
|
5048
5051
|
}
|
|
5049
5052
|
/**
|
|
5050
5053
|
* Returns the items for JSON serialization.
|
|
5051
5054
|
* @returns Array of child entities
|
|
5052
5055
|
*/
|
|
5053
5056
|
toJSON() {
|
|
5054
|
-
return this
|
|
5057
|
+
return this.#items;
|
|
5055
5058
|
}
|
|
5056
5059
|
};
|
|
5057
5060
|
|
|
@@ -5102,42 +5105,42 @@ var DefaultHasOneReference = class {
|
|
|
5102
5105
|
]);
|
|
5103
5106
|
this.populateFromHydrationCache();
|
|
5104
5107
|
}
|
|
5105
|
-
loaded = false;
|
|
5106
|
-
current = null;
|
|
5108
|
+
#loaded = false;
|
|
5109
|
+
#current = null;
|
|
5107
5110
|
async load() {
|
|
5108
|
-
if (this
|
|
5111
|
+
if (this.#loaded) return this.#current;
|
|
5109
5112
|
const map = await this.loader();
|
|
5110
5113
|
const keyValue = this.root[this.localKey];
|
|
5111
5114
|
if (keyValue === void 0 || keyValue === null) {
|
|
5112
|
-
this
|
|
5113
|
-
return this
|
|
5115
|
+
this.#loaded = true;
|
|
5116
|
+
return this.#current;
|
|
5114
5117
|
}
|
|
5115
5118
|
const row = map.get(toKey4(keyValue));
|
|
5116
|
-
this
|
|
5117
|
-
this
|
|
5118
|
-
return this
|
|
5119
|
+
this.#current = row ? this.createEntity(row) : null;
|
|
5120
|
+
this.#loaded = true;
|
|
5121
|
+
return this.#current;
|
|
5119
5122
|
}
|
|
5120
5123
|
get() {
|
|
5121
|
-
return this
|
|
5124
|
+
return this.#current;
|
|
5122
5125
|
}
|
|
5123
5126
|
set(data) {
|
|
5124
5127
|
if (data === null) {
|
|
5125
5128
|
return this.detachCurrent();
|
|
5126
5129
|
}
|
|
5127
5130
|
const entity = hasEntityMeta(data) ? data : this.createEntity(data);
|
|
5128
|
-
if (this
|
|
5131
|
+
if (this.#current && this.#current !== entity) {
|
|
5129
5132
|
this.ctx.registerRelationChange(
|
|
5130
5133
|
this.root,
|
|
5131
5134
|
this.relationKey,
|
|
5132
5135
|
this.rootTable,
|
|
5133
5136
|
this.relationName,
|
|
5134
5137
|
this.relation,
|
|
5135
|
-
{ kind: "remove", entity: this
|
|
5138
|
+
{ kind: "remove", entity: this.#current }
|
|
5136
5139
|
);
|
|
5137
5140
|
}
|
|
5138
5141
|
this.assignForeignKey(entity);
|
|
5139
|
-
this
|
|
5140
|
-
this
|
|
5142
|
+
this.#current = entity;
|
|
5143
|
+
this.#loaded = true;
|
|
5141
5144
|
this.ctx.registerRelationChange(
|
|
5142
5145
|
this.root,
|
|
5143
5146
|
this.relationKey,
|
|
@@ -5148,14 +5151,17 @@ var DefaultHasOneReference = class {
|
|
|
5148
5151
|
);
|
|
5149
5152
|
return entity;
|
|
5150
5153
|
}
|
|
5154
|
+
isLoaded() {
|
|
5155
|
+
return this.#loaded;
|
|
5156
|
+
}
|
|
5151
5157
|
toJSON() {
|
|
5152
|
-
return this
|
|
5158
|
+
return this.#current;
|
|
5153
5159
|
}
|
|
5154
5160
|
detachCurrent() {
|
|
5155
|
-
const previous = this
|
|
5161
|
+
const previous = this.#current;
|
|
5156
5162
|
if (!previous) return null;
|
|
5157
|
-
this
|
|
5158
|
-
this
|
|
5163
|
+
this.#current = null;
|
|
5164
|
+
this.#loaded = true;
|
|
5159
5165
|
this.ctx.registerRelationChange(
|
|
5160
5166
|
this.root,
|
|
5161
5167
|
this.relationKey,
|
|
@@ -5178,8 +5184,8 @@ var DefaultHasOneReference = class {
|
|
|
5178
5184
|
if (keyValue === void 0 || keyValue === null) return;
|
|
5179
5185
|
const row = getHydrationRecord(this.meta, this.relationName, keyValue);
|
|
5180
5186
|
if (!row) return;
|
|
5181
|
-
this
|
|
5182
|
-
this
|
|
5187
|
+
this.#current = this.createEntity(row);
|
|
5188
|
+
this.#loaded = true;
|
|
5183
5189
|
}
|
|
5184
5190
|
};
|
|
5185
5191
|
|
|
@@ -5220,29 +5226,29 @@ var DefaultBelongsToReference = class {
|
|
|
5220
5226
|
hideInternal3(this, ["ctx", "meta", "root", "relationName", "relation", "rootTable", "loader", "createEntity", "targetKey"]);
|
|
5221
5227
|
this.populateFromHydrationCache();
|
|
5222
5228
|
}
|
|
5223
|
-
loaded = false;
|
|
5224
|
-
current = null;
|
|
5229
|
+
#loaded = false;
|
|
5230
|
+
#current = null;
|
|
5225
5231
|
async load() {
|
|
5226
|
-
if (this
|
|
5232
|
+
if (this.#loaded) return this.#current;
|
|
5227
5233
|
const map = await this.loader();
|
|
5228
5234
|
const fkValue = this.root[this.relation.foreignKey];
|
|
5229
5235
|
if (fkValue === null || fkValue === void 0) {
|
|
5230
|
-
this
|
|
5236
|
+
this.#current = null;
|
|
5231
5237
|
} else {
|
|
5232
5238
|
const row = map.get(toKey5(fkValue));
|
|
5233
|
-
this
|
|
5239
|
+
this.#current = row ? this.createEntity(row) : null;
|
|
5234
5240
|
}
|
|
5235
|
-
this
|
|
5236
|
-
return this
|
|
5241
|
+
this.#loaded = true;
|
|
5242
|
+
return this.#current;
|
|
5237
5243
|
}
|
|
5238
5244
|
get() {
|
|
5239
|
-
return this
|
|
5245
|
+
return this.#current;
|
|
5240
5246
|
}
|
|
5241
5247
|
set(data) {
|
|
5242
5248
|
if (data === null) {
|
|
5243
|
-
const previous = this
|
|
5249
|
+
const previous = this.#current;
|
|
5244
5250
|
this.root[this.relation.foreignKey] = null;
|
|
5245
|
-
this
|
|
5251
|
+
this.#current = null;
|
|
5246
5252
|
this.ctx.registerRelationChange(
|
|
5247
5253
|
this.root,
|
|
5248
5254
|
this.relationKey,
|
|
@@ -5258,7 +5264,7 @@ var DefaultBelongsToReference = class {
|
|
|
5258
5264
|
if (pkValue !== void 0) {
|
|
5259
5265
|
this.root[this.relation.foreignKey] = pkValue;
|
|
5260
5266
|
}
|
|
5261
|
-
this
|
|
5267
|
+
this.#current = entity;
|
|
5262
5268
|
this.ctx.registerRelationChange(
|
|
5263
5269
|
this.root,
|
|
5264
5270
|
this.relationKey,
|
|
@@ -5269,6 +5275,9 @@ var DefaultBelongsToReference = class {
|
|
|
5269
5275
|
);
|
|
5270
5276
|
return entity;
|
|
5271
5277
|
}
|
|
5278
|
+
isLoaded() {
|
|
5279
|
+
return this.#loaded;
|
|
5280
|
+
}
|
|
5272
5281
|
get relationKey() {
|
|
5273
5282
|
return `${this.rootTable.name}.${this.relationName}`;
|
|
5274
5283
|
}
|
|
@@ -5277,11 +5286,11 @@ var DefaultBelongsToReference = class {
|
|
|
5277
5286
|
if (fkValue === void 0 || fkValue === null) return;
|
|
5278
5287
|
const row = getHydrationRecord(this.meta, this.relationName, fkValue);
|
|
5279
5288
|
if (!row) return;
|
|
5280
|
-
this
|
|
5281
|
-
this
|
|
5289
|
+
this.#current = this.createEntity(row);
|
|
5290
|
+
this.#loaded = true;
|
|
5282
5291
|
}
|
|
5283
5292
|
toJSON() {
|
|
5284
|
-
return this
|
|
5293
|
+
return this.#current;
|
|
5285
5294
|
}
|
|
5286
5295
|
};
|
|
5287
5296
|
|
|
@@ -5322,45 +5331,45 @@ var DefaultManyToManyCollection = class {
|
|
|
5322
5331
|
hideInternal4(this, ["ctx", "meta", "root", "relationName", "relation", "rootTable", "loader", "createEntity", "localKey"]);
|
|
5323
5332
|
this.hydrateFromCache();
|
|
5324
5333
|
}
|
|
5325
|
-
loaded = false;
|
|
5326
|
-
items = [];
|
|
5334
|
+
#loaded = false;
|
|
5335
|
+
#items = [];
|
|
5327
5336
|
/**
|
|
5328
5337
|
* Loads the collection items if not already loaded.
|
|
5329
5338
|
* @returns A promise that resolves to the array of target entities.
|
|
5330
5339
|
*/
|
|
5331
5340
|
async load() {
|
|
5332
|
-
if (this
|
|
5341
|
+
if (this.#loaded) return this.#items;
|
|
5333
5342
|
const map = await this.loader();
|
|
5334
5343
|
const key = toKey6(this.root[this.localKey]);
|
|
5335
5344
|
const rows = map.get(key) ?? [];
|
|
5336
|
-
this
|
|
5345
|
+
this.#items = rows.map((row) => {
|
|
5337
5346
|
const entity = this.createEntity(row);
|
|
5338
5347
|
if (row._pivot) {
|
|
5339
5348
|
entity._pivot = row._pivot;
|
|
5340
5349
|
}
|
|
5341
5350
|
return entity;
|
|
5342
5351
|
});
|
|
5343
|
-
this
|
|
5344
|
-
return this
|
|
5352
|
+
this.#loaded = true;
|
|
5353
|
+
return this.#items;
|
|
5345
5354
|
}
|
|
5346
5355
|
/**
|
|
5347
5356
|
* Returns the currently loaded items.
|
|
5348
5357
|
* @returns Array of target entities.
|
|
5349
5358
|
*/
|
|
5350
5359
|
getItems() {
|
|
5351
|
-
return this
|
|
5360
|
+
return this.#items;
|
|
5352
5361
|
}
|
|
5353
5362
|
/**
|
|
5354
5363
|
* Array-compatible length for testing frameworks.
|
|
5355
5364
|
*/
|
|
5356
5365
|
get length() {
|
|
5357
|
-
return this
|
|
5366
|
+
return this.#items.length;
|
|
5358
5367
|
}
|
|
5359
5368
|
/**
|
|
5360
5369
|
* Enables iteration over the collection like an array.
|
|
5361
5370
|
*/
|
|
5362
5371
|
[Symbol.iterator]() {
|
|
5363
|
-
return this
|
|
5372
|
+
return this.#items[Symbol.iterator]();
|
|
5364
5373
|
}
|
|
5365
5374
|
/**
|
|
5366
5375
|
* Attaches an entity to the collection.
|
|
@@ -5370,13 +5379,13 @@ var DefaultManyToManyCollection = class {
|
|
|
5370
5379
|
attach(target) {
|
|
5371
5380
|
const entity = this.ensureEntity(target);
|
|
5372
5381
|
const id = this.extractId(entity);
|
|
5373
|
-
if (id != null && this
|
|
5382
|
+
if (id != null && this.#items.some((item) => this.extractId(item) === id)) {
|
|
5374
5383
|
return;
|
|
5375
5384
|
}
|
|
5376
|
-
if (id == null && this
|
|
5385
|
+
if (id == null && this.#items.includes(entity)) {
|
|
5377
5386
|
return;
|
|
5378
5387
|
}
|
|
5379
|
-
this
|
|
5388
|
+
this.#items.push(entity);
|
|
5380
5389
|
this.ctx.registerRelationChange(
|
|
5381
5390
|
this.root,
|
|
5382
5391
|
this.relationKey,
|
|
@@ -5394,9 +5403,9 @@ var DefaultManyToManyCollection = class {
|
|
|
5394
5403
|
detach(target) {
|
|
5395
5404
|
const id = typeof target === "number" || typeof target === "string" ? target : this.extractId(target);
|
|
5396
5405
|
if (id == null) return;
|
|
5397
|
-
const existing = this
|
|
5406
|
+
const existing = this.#items.find((item) => this.extractId(item) === id);
|
|
5398
5407
|
if (!existing) return;
|
|
5399
|
-
this
|
|
5408
|
+
this.#items = this.#items.filter((item) => this.extractId(item) !== id);
|
|
5400
5409
|
this.ctx.registerRelationChange(
|
|
5401
5410
|
this.root,
|
|
5402
5411
|
this.relationKey,
|
|
@@ -5414,19 +5423,22 @@ var DefaultManyToManyCollection = class {
|
|
|
5414
5423
|
async syncByIds(ids) {
|
|
5415
5424
|
await this.load();
|
|
5416
5425
|
const normalized = new Set(ids.map((id) => toKey6(id)));
|
|
5417
|
-
const currentIds = new Set(this
|
|
5426
|
+
const currentIds = new Set(this.#items.map((item) => toKey6(this.extractId(item))));
|
|
5418
5427
|
for (const id of normalized) {
|
|
5419
5428
|
if (!currentIds.has(id)) {
|
|
5420
5429
|
this.attach(id);
|
|
5421
5430
|
}
|
|
5422
5431
|
}
|
|
5423
|
-
for (const item of [...this
|
|
5432
|
+
for (const item of [...this.#items]) {
|
|
5424
5433
|
const itemId = toKey6(this.extractId(item));
|
|
5425
5434
|
if (!normalized.has(itemId)) {
|
|
5426
5435
|
this.detach(item);
|
|
5427
5436
|
}
|
|
5428
5437
|
}
|
|
5429
5438
|
}
|
|
5439
|
+
isLoaded() {
|
|
5440
|
+
return this.#loaded;
|
|
5441
|
+
}
|
|
5430
5442
|
ensureEntity(target) {
|
|
5431
5443
|
if (typeof target === "number" || typeof target === "string") {
|
|
5432
5444
|
const stub = {
|
|
@@ -5454,17 +5466,17 @@ var DefaultManyToManyCollection = class {
|
|
|
5454
5466
|
if (keyValue === void 0 || keyValue === null) return;
|
|
5455
5467
|
const rows = getHydrationRows(this.meta, this.relationName, keyValue);
|
|
5456
5468
|
if (!rows?.length) return;
|
|
5457
|
-
this
|
|
5469
|
+
this.#items = rows.map((row) => {
|
|
5458
5470
|
const entity = this.createEntity(row);
|
|
5459
5471
|
if (row._pivot) {
|
|
5460
5472
|
entity._pivot = row._pivot;
|
|
5461
5473
|
}
|
|
5462
5474
|
return entity;
|
|
5463
5475
|
});
|
|
5464
|
-
this
|
|
5476
|
+
this.#loaded = true;
|
|
5465
5477
|
}
|
|
5466
5478
|
toJSON() {
|
|
5467
|
-
return this
|
|
5479
|
+
return this.#items;
|
|
5468
5480
|
}
|
|
5469
5481
|
};
|
|
5470
5482
|
|
|
@@ -5806,12 +5818,14 @@ var relationLoaderCache = (meta, relationName, factory) => {
|
|
|
5806
5818
|
// src/orm/entity-relations.ts
|
|
5807
5819
|
var proxifyRelationWrapper = (wrapper) => {
|
|
5808
5820
|
return new Proxy(wrapper, {
|
|
5809
|
-
get(target, prop,
|
|
5821
|
+
get(target, prop, _receiver) {
|
|
5810
5822
|
if (typeof prop === "symbol") {
|
|
5811
|
-
|
|
5823
|
+
const value = Reflect.get(target, prop, target);
|
|
5824
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
5812
5825
|
}
|
|
5813
5826
|
if (prop in target) {
|
|
5814
|
-
|
|
5827
|
+
const value = Reflect.get(target, prop, target);
|
|
5828
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
5815
5829
|
}
|
|
5816
5830
|
const getItems = target.getItems;
|
|
5817
5831
|
if (typeof getItems === "function") {
|
|
@@ -5833,12 +5847,12 @@ var proxifyRelationWrapper = (wrapper) => {
|
|
|
5833
5847
|
}
|
|
5834
5848
|
return void 0;
|
|
5835
5849
|
},
|
|
5836
|
-
set(target, prop, value,
|
|
5850
|
+
set(target, prop, value, _receiver) {
|
|
5837
5851
|
if (typeof prop === "symbol") {
|
|
5838
|
-
return Reflect.set(target, prop, value,
|
|
5852
|
+
return Reflect.set(target, prop, value, target);
|
|
5839
5853
|
}
|
|
5840
5854
|
if (prop in target) {
|
|
5841
|
-
return Reflect.set(target, prop, value,
|
|
5855
|
+
return Reflect.set(target, prop, value, target);
|
|
5842
5856
|
}
|
|
5843
5857
|
const getRef = target.get;
|
|
5844
5858
|
if (typeof getRef === "function") {
|
|
@@ -5852,7 +5866,7 @@ var proxifyRelationWrapper = (wrapper) => {
|
|
|
5852
5866
|
const items = getItems.call(target);
|
|
5853
5867
|
return Reflect.set(items, prop, value);
|
|
5854
5868
|
}
|
|
5855
|
-
return Reflect.set(target, prop, value,
|
|
5869
|
+
return Reflect.set(target, prop, value, target);
|
|
5856
5870
|
}
|
|
5857
5871
|
});
|
|
5858
5872
|
};
|
|
@@ -5954,7 +5968,15 @@ var instantiateWrapper = (meta, relationName, relation, owner, createEntity) =>
|
|
|
5954
5968
|
// src/orm/entity.ts
|
|
5955
5969
|
var isRelationWrapperLoaded = (value) => {
|
|
5956
5970
|
if (!value || typeof value !== "object") return false;
|
|
5957
|
-
|
|
5971
|
+
const wrapper = value;
|
|
5972
|
+
if (typeof wrapper.isLoaded === "function") return wrapper.isLoaded();
|
|
5973
|
+
return false;
|
|
5974
|
+
};
|
|
5975
|
+
var unwrapRelationForJson = (value) => {
|
|
5976
|
+
if (value && typeof value === "object" && typeof value.toJSON === "function") {
|
|
5977
|
+
return value.toJSON();
|
|
5978
|
+
}
|
|
5979
|
+
return value;
|
|
5958
5980
|
};
|
|
5959
5981
|
var createEntityProxy = (ctx, table, row, lazyRelations = [], lazyRelationOptions = /* @__PURE__ */ new Map()) => {
|
|
5960
5982
|
const target = { ...row };
|
|
@@ -5976,7 +5998,7 @@ var createEntityProxy = (ctx, table, row, lazyRelations = [], lazyRelationOption
|
|
|
5976
5998
|
for (const [relationName, wrapper] of meta.relationWrappers) {
|
|
5977
5999
|
if (Object.prototype.hasOwnProperty.call(json, relationName)) continue;
|
|
5978
6000
|
if (isRelationWrapperLoaded(wrapper)) {
|
|
5979
|
-
json[relationName] = wrapper;
|
|
6001
|
+
json[relationName] = unwrapRelationForJson(wrapper);
|
|
5980
6002
|
}
|
|
5981
6003
|
}
|
|
5982
6004
|
return json;
|