orchid-orm 1.3.4 → 1.3.5
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/CHANGELOG.md +6 -0
- package/dist/index.esm.js +21 -0
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/relations/hasMany.test.ts +91 -0
- package/src/relations/hasOne.test.ts +91 -0
- package/src/relations/relations.ts +39 -0
|
@@ -1340,6 +1340,97 @@ describe('hasOne through', () => {
|
|
|
1340
1340
|
expect(Object.keys(db.tag.relations)).toEqual(['postTag', 'post']);
|
|
1341
1341
|
});
|
|
1342
1342
|
|
|
1343
|
+
it('should throw if through relation is not defined', () => {
|
|
1344
|
+
class Post extends Model {
|
|
1345
|
+
table = 'post';
|
|
1346
|
+
columns = this.setColumns((t) => ({
|
|
1347
|
+
id: t.serial().primaryKey(),
|
|
1348
|
+
}));
|
|
1349
|
+
|
|
1350
|
+
relations = {
|
|
1351
|
+
tag: this.hasOne(() => Tag, {
|
|
1352
|
+
through: 'postTag',
|
|
1353
|
+
source: 'tag',
|
|
1354
|
+
}),
|
|
1355
|
+
};
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
class Tag extends Model {
|
|
1359
|
+
table = 'tag';
|
|
1360
|
+
columns = this.setColumns((t) => ({
|
|
1361
|
+
id: t.serial().primaryKey(),
|
|
1362
|
+
}));
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1365
|
+
expect(() => {
|
|
1366
|
+
orchidORM(
|
|
1367
|
+
{
|
|
1368
|
+
...pgConfig,
|
|
1369
|
+
log: false,
|
|
1370
|
+
},
|
|
1371
|
+
{
|
|
1372
|
+
post: Post,
|
|
1373
|
+
tag: Tag,
|
|
1374
|
+
},
|
|
1375
|
+
);
|
|
1376
|
+
}).toThrow(
|
|
1377
|
+
'Cannot define a `tag` relation on `post`: cannot find `postTag` relation required by the `through` option',
|
|
1378
|
+
);
|
|
1379
|
+
});
|
|
1380
|
+
|
|
1381
|
+
it('should throw if source relation is not defined', () => {
|
|
1382
|
+
class Post extends Model {
|
|
1383
|
+
table = 'post';
|
|
1384
|
+
columns = this.setColumns((t) => ({
|
|
1385
|
+
id: t.serial().primaryKey(),
|
|
1386
|
+
}));
|
|
1387
|
+
|
|
1388
|
+
relations = {
|
|
1389
|
+
postTag: this.hasOne(() => PostTag, {
|
|
1390
|
+
primaryKey: 'id',
|
|
1391
|
+
foreignKey: 'postId',
|
|
1392
|
+
}),
|
|
1393
|
+
|
|
1394
|
+
tag: this.hasOne(() => Tag, {
|
|
1395
|
+
through: 'postTag',
|
|
1396
|
+
source: 'tag',
|
|
1397
|
+
}),
|
|
1398
|
+
};
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
class Tag extends Model {
|
|
1402
|
+
table = 'tag';
|
|
1403
|
+
columns = this.setColumns((t) => ({
|
|
1404
|
+
id: t.serial().primaryKey(),
|
|
1405
|
+
}));
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
class PostTag extends Model {
|
|
1409
|
+
table = 'postTag';
|
|
1410
|
+
columns = this.setColumns((t) => ({
|
|
1411
|
+
postId: t.integer().foreignKey(() => Post, 'id'),
|
|
1412
|
+
tagId: t.integer().foreignKey(() => Tag, 'id'),
|
|
1413
|
+
...t.primaryKey(['postId', 'tagId']),
|
|
1414
|
+
}));
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1417
|
+
expect(() => {
|
|
1418
|
+
orchidORM(
|
|
1419
|
+
{
|
|
1420
|
+
...pgConfig,
|
|
1421
|
+
log: false,
|
|
1422
|
+
},
|
|
1423
|
+
{
|
|
1424
|
+
post: Post,
|
|
1425
|
+
tag: Tag,
|
|
1426
|
+
postTag: PostTag,
|
|
1427
|
+
},
|
|
1428
|
+
);
|
|
1429
|
+
}).toThrow(
|
|
1430
|
+
'Cannot define a `tag` relation on `post`: cannot find `tag` relation in `postTag` required by the `source` option',
|
|
1431
|
+
);
|
|
1432
|
+
});
|
|
1433
|
+
|
|
1343
1434
|
it('should have method to query related data', async () => {
|
|
1344
1435
|
const profileQuery = db.profile.take();
|
|
1345
1436
|
|
|
@@ -200,6 +200,45 @@ export const applyRelations = (
|
|
|
200
200
|
applyRelation(qb, data, delayedRelations);
|
|
201
201
|
}
|
|
202
202
|
}
|
|
203
|
+
|
|
204
|
+
if (delayedRelations.size) {
|
|
205
|
+
const { value } = delayedRelations.values().next() as {
|
|
206
|
+
value: Record<string, ApplyRelationData[]>;
|
|
207
|
+
};
|
|
208
|
+
for (const key in value) {
|
|
209
|
+
for (const item of value[key]) {
|
|
210
|
+
const { relation } = item;
|
|
211
|
+
|
|
212
|
+
if (item.dbModel.relations[item.relationName as never]) continue;
|
|
213
|
+
|
|
214
|
+
const as = item.dbModel.definedAs;
|
|
215
|
+
let message = `Cannot define a \`${item.relationName}\` relation on \`${as}\``;
|
|
216
|
+
const model = result[as];
|
|
217
|
+
|
|
218
|
+
const { through, source } = relation.options as {
|
|
219
|
+
through: string;
|
|
220
|
+
source: string;
|
|
221
|
+
};
|
|
222
|
+
const throughRel = model.relations[
|
|
223
|
+
through as never
|
|
224
|
+
] as unknown as BaseRelation;
|
|
225
|
+
|
|
226
|
+
if (through && !throughRel) {
|
|
227
|
+
message += `: cannot find \`${through}\` relation required by the \`through\` option`;
|
|
228
|
+
} else if (
|
|
229
|
+
source &&
|
|
230
|
+
throughRel &&
|
|
231
|
+
!throughRel.model.relations[source as never]
|
|
232
|
+
) {
|
|
233
|
+
message += `: cannot find \`${source}\` relation in \`${
|
|
234
|
+
(throughRel.model as DbModel<ModelClass>).definedAs
|
|
235
|
+
}\` required by the \`source\` option`;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
throw new Error(message);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
203
242
|
};
|
|
204
243
|
|
|
205
244
|
const delayRelation = (
|