@open-mercato/core 0.6.4-develop.4015.1.efaafadf79 → 0.6.4-develop.4095.1.9c790dc021
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/modules/query_index/lib/engine.js +32 -4
- package/dist/modules/query_index/lib/engine.js.map +2 -2
- package/dist/modules/sales/api/shipments/route.js +135 -131
- package/dist/modules/sales/api/shipments/route.js.map +2 -2
- package/package.json +7 -7
- package/src/modules/query_index/lib/engine.ts +37 -7
- package/src/modules/sales/api/shipments/route.ts +157 -150
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
import { resolveSearchConfig } from "@open-mercato/shared/lib/search/config";
|
|
15
15
|
import { tokenizeText } from "@open-mercato/shared/lib/search/tokenize";
|
|
16
16
|
import { runBeforeQueryPipeline, runAfterQueryPipeline } from "@open-mercato/shared/lib/query/query-extension-runner";
|
|
17
|
+
import { resolveEncryptedSortFields, sortRowsInMemory } from "@open-mercato/shared/lib/query/encrypted-sort";
|
|
17
18
|
function buildFilterableCustomFieldJoins(sources) {
|
|
18
19
|
if (!sources || sources.length === 0) return [];
|
|
19
20
|
return sources.flatMap((source, index) => {
|
|
@@ -410,6 +411,26 @@ class HybridQueryEngine {
|
|
|
410
411
|
if (field === "organization_id" && columns.has("id")) return "id";
|
|
411
412
|
return null;
|
|
412
413
|
};
|
|
414
|
+
const fallbackOrgId = opts.organizationId ?? (Array.isArray(opts.organizationIds) && opts.organizationIds.length === 1 ? opts.organizationIds[0] : null);
|
|
415
|
+
const encSvc = this.getEncryptionService();
|
|
416
|
+
const resolvedSorts = [];
|
|
417
|
+
for (const sort of opts.sort || []) {
|
|
418
|
+
const field = String(sort.field);
|
|
419
|
+
if (field.startsWith("cf:")) {
|
|
420
|
+
resolvedSorts.push({ ...sort, field });
|
|
421
|
+
} else {
|
|
422
|
+
const baseField = resolveBaseColumn(field);
|
|
423
|
+
if (baseField) resolvedSorts.push({ ...sort, field: baseField });
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
const encryptedSortFields = await resolveEncryptedSortFields(
|
|
427
|
+
encSvc,
|
|
428
|
+
entity,
|
|
429
|
+
resolvedSorts.filter((sort) => !sort.field.startsWith("cf:")).map((sort) => sort.field),
|
|
430
|
+
opts.tenantId ?? null,
|
|
431
|
+
fallbackOrgId
|
|
432
|
+
);
|
|
433
|
+
const requiresPlaintextSort = encryptedSortFields.size > 0;
|
|
413
434
|
const applyBaseScope = (q) => {
|
|
414
435
|
let next = q;
|
|
415
436
|
if (orgScope && hasOrganizationColumn) {
|
|
@@ -617,6 +638,9 @@ class HybridQueryEngine {
|
|
|
617
638
|
const hasCustomFieldFilters = cfFilters.length > 0;
|
|
618
639
|
const canOptimizeCount = !hasCustomFieldFilters && !hasNonBaseSearchSource;
|
|
619
640
|
const selectFieldSet = new Set(opts.fields && opts.fields.length ? opts.fields.map(String) : Array.from(columns.keys()));
|
|
641
|
+
if (requiresPlaintextSort) {
|
|
642
|
+
for (const field of encryptedSortFields) selectFieldSet.add(field);
|
|
643
|
+
}
|
|
620
644
|
if (opts.includeCustomFields === true) {
|
|
621
645
|
const entityIds = Array.from(new Set(indexSources.map((src) => String(src.entityId))));
|
|
622
646
|
try {
|
|
@@ -647,7 +671,8 @@ class HybridQueryEngine {
|
|
|
647
671
|
};
|
|
648
672
|
const applySort = (q) => {
|
|
649
673
|
let next = q;
|
|
650
|
-
|
|
674
|
+
if (requiresPlaintextSort) return next;
|
|
675
|
+
for (const s of resolvedSorts) {
|
|
651
676
|
const fieldName = String(s.field);
|
|
652
677
|
if (fieldName.startsWith("cf:")) {
|
|
653
678
|
const textExpr = this.buildCfTextExprSql(fieldName, indexSources);
|
|
@@ -722,7 +747,9 @@ class HybridQueryEngine {
|
|
|
722
747
|
let dataBuilder = await applyQueryShape(dataRoot);
|
|
723
748
|
dataBuilder = applySelection(dataBuilder);
|
|
724
749
|
dataBuilder = applySort(dataBuilder);
|
|
725
|
-
|
|
750
|
+
if (!requiresPlaintextSort) {
|
|
751
|
+
dataBuilder = dataBuilder.limit(pageSize).offset((page - 1) * pageSize);
|
|
752
|
+
}
|
|
726
753
|
if (debugEnabled && sqlDebugEnabled) {
|
|
727
754
|
const compiled = dataBuilder.compile();
|
|
728
755
|
this.debug("query:sql:data", { entity, sql: compiled.sql, bindings: compiled.parameters, page, pageSize });
|
|
@@ -736,11 +763,9 @@ class HybridQueryEngine {
|
|
|
736
763
|
);
|
|
737
764
|
if (debugEnabled) this.debug("query:complete", { entity, total, items: Array.isArray(itemsRaw) ? itemsRaw.length : 0 });
|
|
738
765
|
let items = itemsRaw;
|
|
739
|
-
const encSvc = this.getEncryptionService();
|
|
740
766
|
const dekKeyCache = /* @__PURE__ */ new Map();
|
|
741
767
|
if (encSvc?.decryptEntityPayload) {
|
|
742
768
|
const decrypt = encSvc.decryptEntityPayload.bind(encSvc);
|
|
743
|
-
const fallbackOrgId = opts.organizationId ?? (Array.isArray(opts.organizationIds) && opts.organizationIds.length === 1 ? opts.organizationIds[0] : null);
|
|
744
769
|
items = await Promise.all(
|
|
745
770
|
items.map(async (item) => {
|
|
746
771
|
try {
|
|
@@ -777,6 +802,9 @@ class HybridQueryEngine {
|
|
|
777
802
|
})
|
|
778
803
|
);
|
|
779
804
|
}
|
|
805
|
+
if (requiresPlaintextSort) {
|
|
806
|
+
items = sortRowsInMemory(items, resolvedSorts).slice((page - 1) * pageSize, page * pageSize);
|
|
807
|
+
}
|
|
780
808
|
const typedItems = items;
|
|
781
809
|
let result = { items: typedItems, page, pageSize, total };
|
|
782
810
|
if (partialIndexWarning) result.meta = { partialIndexWarning };
|