@clairejs/server 3.28.13 → 3.28.14
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 +4 -0
- package/dist/http/repository/ModelRepository.js +80 -47
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -572,8 +572,13 @@ export class ModelRepository extends AbstractRepository {
|
|
|
572
572
|
//-- check if there is any multi-local fields in projection
|
|
573
573
|
const multiLocaleFields = this.modelMetadata.fields.filter((f) => f.isMultiLocale && (!queries?.projection || queries.projection.includes(f.name)));
|
|
574
574
|
const localeOfFields = this.modelMetadata.fields.filter((f) => multiLocaleFields.find((locale) => locale.name === f.multiLocaleColumn));
|
|
575
|
+
const expandFields = this.modelMetadata.fields.filter((f) => f.expand && (!queries?.projection || queries.projection.includes(f.name)));
|
|
575
576
|
const finalProjection = queries?.projection && [
|
|
576
|
-
...queries.projection.filter((fieldName) => !this.modelMetadata.fields.find((f) => f.name === fieldName && !!f.hasMany)),
|
|
577
|
+
...queries.projection.filter((fieldName) => !this.modelMetadata.fields.find((f) => f.name === fieldName && (!!f.hasMany || !!f.expand))),
|
|
578
|
+
//-- include FK columns for expand fields so we can resolve them
|
|
579
|
+
...expandFields
|
|
580
|
+
.map((f) => f.expand.column)
|
|
581
|
+
.filter((col) => !queries.projection.includes(col)),
|
|
577
582
|
...localeOfFields.map((f) => f.name),
|
|
578
583
|
];
|
|
579
584
|
const result = await this.db.use(this.model, tx).getMany(conditions.length ? { _and: conditions } : {}, {
|
|
@@ -590,65 +595,93 @@ export class ModelRepository extends AbstractRepository {
|
|
|
590
595
|
.flatMap((ids) => ids)
|
|
591
596
|
.filter((id) => id);
|
|
592
597
|
const systemLocale = getSystemLocale();
|
|
593
|
-
|
|
594
|
-
|
|
598
|
+
//-- fetch translations, has many, and expand fields in parallel
|
|
599
|
+
const hasManyFields = this.modelMetadata.fields.filter((f) => f.hasMany && (!queries?.projection || queries.projection.includes(f.name)));
|
|
600
|
+
const translationsPromise = !allLocaleEntries.length
|
|
601
|
+
? Promise.resolve([])
|
|
595
602
|
: !queries?.locale
|
|
596
603
|
? //-- if locale is not specified then get translation for all locales
|
|
597
|
-
|
|
604
|
+
this.db.use(LocaleTranslation, tx).getRecords({
|
|
598
605
|
_in: { entryId: allLocaleEntries },
|
|
599
606
|
}, { projection: ["entryId", "localeCode", "translation"] })
|
|
600
607
|
: //-- if locale is specified then get only the translation of that locale
|
|
601
608
|
queries.locale.toLowerCase() !== systemLocale
|
|
602
|
-
?
|
|
609
|
+
? this.db.use(LocaleTranslation, tx).getRecords({
|
|
603
610
|
_in: { entryId: allLocaleEntries },
|
|
604
611
|
_eq: { localeCode: queries.locale },
|
|
605
612
|
}, { projection: ["entryId", "localeCode", "translation"] })
|
|
606
613
|
: //-- locale is system locale, no need to fetch translation
|
|
607
|
-
[];
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
614
|
+
Promise.resolve([]);
|
|
615
|
+
await Promise.all([
|
|
616
|
+
//-- translations
|
|
617
|
+
translationsPromise.then((translations) => {
|
|
618
|
+
for (const record of result.records) {
|
|
619
|
+
for (const field of localeOfFields) {
|
|
620
|
+
//-- map back translation
|
|
621
|
+
if (!queries?.locale) {
|
|
622
|
+
//-- map as object
|
|
623
|
+
const fieldTranslations = translations
|
|
624
|
+
.filter((t) => t.entryId === record[field.name])
|
|
625
|
+
.map((t) => [t.localeCode, t.translation]);
|
|
626
|
+
if (systemLocale) {
|
|
627
|
+
fieldTranslations.push([systemLocale, record[field.multiLocaleColumn]]);
|
|
628
|
+
}
|
|
629
|
+
record[field.name] = Object.fromEntries(fieldTranslations);
|
|
630
|
+
}
|
|
631
|
+
else {
|
|
632
|
+
//-- replace value
|
|
633
|
+
const translation = translations.find((t) => t.localeCode === queries.locale && t.entryId === record[field.name]);
|
|
634
|
+
if (translation) {
|
|
635
|
+
record[field.multiLocaleColumn] = translation.translation;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
618
638
|
}
|
|
619
|
-
record[field.name] = Object.fromEntries(fieldTranslations);
|
|
620
639
|
}
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
}
|
|
640
|
+
}),
|
|
641
|
+
//-- has many
|
|
642
|
+
...hasManyFields.map(async (field) => {
|
|
643
|
+
const model = getModelById(field.hasMany.relationDto.id);
|
|
644
|
+
if (!model) {
|
|
645
|
+
throw Errors.NOT_FOUND(`Model not found by id: ${field.hasMany.relationDto.id}`);
|
|
627
646
|
}
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
const
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
647
|
+
const service = new ModelRepository(model, this.db);
|
|
648
|
+
const innerRecords = !recordIds.length
|
|
649
|
+
? { records: [] }
|
|
650
|
+
: await service.getMany({
|
|
651
|
+
queries: { fields: { [field.hasMany.column]: recordIds }, limit: field.hasMany.single ? 1 : 0 },
|
|
652
|
+
tx,
|
|
653
|
+
});
|
|
654
|
+
//-- filter corresponding inner records for each master record
|
|
655
|
+
for (const record of result.records) {
|
|
656
|
+
const finalRecords = innerRecords.records.filter((r) => r[field.hasMany.column] === record.id);
|
|
657
|
+
record[field.name] = (field.hasMany.single ? finalRecords[0] : finalRecords);
|
|
658
|
+
}
|
|
659
|
+
}),
|
|
660
|
+
//-- expand
|
|
661
|
+
...expandFields.map(async (field) => {
|
|
662
|
+
const model = getModelById(field.expand.relationDto.id);
|
|
663
|
+
if (!model) {
|
|
664
|
+
throw Errors.NOT_FOUND(`Model not found by id: ${field.expand.relationDto.id}`);
|
|
665
|
+
}
|
|
666
|
+
//-- collect unique FK values from current records
|
|
667
|
+
const fkValues = result.records
|
|
668
|
+
.map((r) => r[field.expand.column])
|
|
669
|
+
.filter((v) => v !== undefined && v !== null)
|
|
670
|
+
.reduce(uniqueReducer, []);
|
|
671
|
+
const service = new ModelRepository(model, this.db);
|
|
672
|
+
const expandedRecords = !fkValues.length
|
|
673
|
+
? { records: [] }
|
|
674
|
+
: await service.getMany({
|
|
675
|
+
queries: { fields: { id: fkValues } },
|
|
676
|
+
tx,
|
|
677
|
+
});
|
|
678
|
+
//-- assign expanded record to each master record
|
|
679
|
+
for (const record of result.records) {
|
|
680
|
+
const fkValue = record[field.expand.column];
|
|
681
|
+
record[field.name] = expandedRecords.records.find((r) => r.id === fkValue);
|
|
682
|
+
}
|
|
683
|
+
}),
|
|
684
|
+
]);
|
|
652
685
|
await this.beforeReturning(result.records);
|
|
653
686
|
return {
|
|
654
687
|
total: result.total,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clairejs/server",
|
|
3
|
-
"version": "3.28.
|
|
3
|
+
"version": "3.28.14",
|
|
4
4
|
"description": "Claire server NodeJs framework written in Typescript.",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
37
|
"@clairejs/client": "^3.5.1",
|
|
38
|
-
"@clairejs/core": "^3.9.
|
|
39
|
-
"@clairejs/orm": "^3.
|
|
38
|
+
"@clairejs/core": "^3.9.5",
|
|
39
|
+
"@clairejs/orm": "^3.19.11"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/cookie-parser": "^1.4.3",
|