@objectstack/objectql 3.2.1 → 3.2.3
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/.turbo/turbo-build.log +10 -10
- package/CHANGELOG.md +17 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +37 -38
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +37 -38
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
- package/src/engine.test.ts +46 -46
- package/src/engine.ts +8 -10
- package/src/plugin.integration.test.ts +23 -24
- package/src/plugin.ts +17 -14
- package/src/protocol-data.test.ts +12 -12
- package/src/protocol.ts +17 -17
package/dist/index.mjs
CHANGED
|
@@ -670,7 +670,7 @@ var ObjectStackProtocolImplementation = class {
|
|
|
670
670
|
}
|
|
671
671
|
};
|
|
672
672
|
} else {
|
|
673
|
-
const formFields = fieldKeys.filter((k) => k !== "id" && k !== "created_at" && k !== "
|
|
673
|
+
const formFields = fieldKeys.filter((k) => k !== "id" && k !== "created_at" && k !== "updated_at" && !fields[k].hidden).map((f) => ({
|
|
674
674
|
field: f,
|
|
675
675
|
label: fields[f]?.label,
|
|
676
676
|
required: fields[f]?.required,
|
|
@@ -761,7 +761,7 @@ var ObjectStackProtocolImplementation = class {
|
|
|
761
761
|
}
|
|
762
762
|
async getData(request) {
|
|
763
763
|
const queryOptions = {
|
|
764
|
-
filter: {
|
|
764
|
+
filter: { id: request.id }
|
|
765
765
|
};
|
|
766
766
|
if (request.select) {
|
|
767
767
|
queryOptions.select = typeof request.select === "string" ? request.select.split(",").map((s) => s.trim()).filter(Boolean) : request.select;
|
|
@@ -783,12 +783,12 @@ var ObjectStackProtocolImplementation = class {
|
|
|
783
783
|
const result = await this.engine.insert(request.object, request.data);
|
|
784
784
|
return {
|
|
785
785
|
object: request.object,
|
|
786
|
-
id: result.
|
|
786
|
+
id: result.id,
|
|
787
787
|
record: result
|
|
788
788
|
};
|
|
789
789
|
}
|
|
790
790
|
async updateData(request) {
|
|
791
|
-
const result = await this.engine.update(request.object, request.data, { filter: {
|
|
791
|
+
const result = await this.engine.update(request.object, request.data, { filter: { id: request.id } });
|
|
792
792
|
return {
|
|
793
793
|
object: request.object,
|
|
794
794
|
id: request.id,
|
|
@@ -796,7 +796,7 @@ var ObjectStackProtocolImplementation = class {
|
|
|
796
796
|
};
|
|
797
797
|
}
|
|
798
798
|
async deleteData(request) {
|
|
799
|
-
await this.engine.delete(request.object, { filter: {
|
|
799
|
+
await this.engine.delete(request.object, { filter: { id: request.id } });
|
|
800
800
|
return {
|
|
801
801
|
object: request.object,
|
|
802
802
|
id: request.id,
|
|
@@ -853,13 +853,13 @@ var ObjectStackProtocolImplementation = class {
|
|
|
853
853
|
switch (operation) {
|
|
854
854
|
case "create": {
|
|
855
855
|
const created = await this.engine.insert(object, record.data || record);
|
|
856
|
-
results.push({ id: created.
|
|
856
|
+
results.push({ id: created.id, success: true, record: created });
|
|
857
857
|
succeeded++;
|
|
858
858
|
break;
|
|
859
859
|
}
|
|
860
860
|
case "update": {
|
|
861
861
|
if (!record.id) throw new Error("Record id is required for update");
|
|
862
|
-
const updated = await this.engine.update(object, record.data || {}, { filter: {
|
|
862
|
+
const updated = await this.engine.update(object, record.data || {}, { filter: { id: record.id } });
|
|
863
863
|
results.push({ id: record.id, success: true, record: updated });
|
|
864
864
|
succeeded++;
|
|
865
865
|
break;
|
|
@@ -867,28 +867,28 @@ var ObjectStackProtocolImplementation = class {
|
|
|
867
867
|
case "upsert": {
|
|
868
868
|
if (record.id) {
|
|
869
869
|
try {
|
|
870
|
-
const existing = await this.engine.findOne(object, { filter: {
|
|
870
|
+
const existing = await this.engine.findOne(object, { filter: { id: record.id } });
|
|
871
871
|
if (existing) {
|
|
872
|
-
const updated = await this.engine.update(object, record.data || {}, { filter: {
|
|
872
|
+
const updated = await this.engine.update(object, record.data || {}, { filter: { id: record.id } });
|
|
873
873
|
results.push({ id: record.id, success: true, record: updated });
|
|
874
874
|
} else {
|
|
875
|
-
const created = await this.engine.insert(object, {
|
|
876
|
-
results.push({ id: created.
|
|
875
|
+
const created = await this.engine.insert(object, { id: record.id, ...record.data || {} });
|
|
876
|
+
results.push({ id: created.id, success: true, record: created });
|
|
877
877
|
}
|
|
878
878
|
} catch {
|
|
879
|
-
const created = await this.engine.insert(object, {
|
|
880
|
-
results.push({ id: created.
|
|
879
|
+
const created = await this.engine.insert(object, { id: record.id, ...record.data || {} });
|
|
880
|
+
results.push({ id: created.id, success: true, record: created });
|
|
881
881
|
}
|
|
882
882
|
} else {
|
|
883
883
|
const created = await this.engine.insert(object, record.data || record);
|
|
884
|
-
results.push({ id: created.
|
|
884
|
+
results.push({ id: created.id, success: true, record: created });
|
|
885
885
|
}
|
|
886
886
|
succeeded++;
|
|
887
887
|
break;
|
|
888
888
|
}
|
|
889
889
|
case "delete": {
|
|
890
890
|
if (!record.id) throw new Error("Record id is required for delete");
|
|
891
|
-
await this.engine.delete(object, { filter: {
|
|
891
|
+
await this.engine.delete(object, { filter: { id: record.id } });
|
|
892
892
|
results.push({ id: record.id, success: true });
|
|
893
893
|
succeeded++;
|
|
894
894
|
break;
|
|
@@ -932,7 +932,7 @@ var ObjectStackProtocolImplementation = class {
|
|
|
932
932
|
let failed = 0;
|
|
933
933
|
for (const record of records) {
|
|
934
934
|
try {
|
|
935
|
-
const updated = await this.engine.update(object, record.data, { filter: {
|
|
935
|
+
const updated = await this.engine.update(object, record.data, { filter: { id: record.id } });
|
|
936
936
|
results.push({ id: record.id, success: true, record: updated });
|
|
937
937
|
succeeded++;
|
|
938
938
|
} catch (err) {
|
|
@@ -1096,7 +1096,7 @@ var ObjectStackProtocolImplementation = class {
|
|
|
1096
1096
|
}
|
|
1097
1097
|
async deleteManyData(request) {
|
|
1098
1098
|
return this.engine.delete(request.object, {
|
|
1099
|
-
filter: {
|
|
1099
|
+
filter: { id: { $in: request.ids } },
|
|
1100
1100
|
...request.options
|
|
1101
1101
|
});
|
|
1102
1102
|
}
|
|
@@ -1781,7 +1781,7 @@ var _ObjectQL = class _ObjectQL {
|
|
|
1781
1781
|
try {
|
|
1782
1782
|
const relatedQuery = {
|
|
1783
1783
|
object: referenceObject,
|
|
1784
|
-
where: {
|
|
1784
|
+
where: { id: { $in: uniqueIds } },
|
|
1785
1785
|
...nestedAST.fields ? { fields: nestedAST.fields } : {},
|
|
1786
1786
|
...nestedAST.orderBy ? { orderBy: nestedAST.orderBy } : {}
|
|
1787
1787
|
};
|
|
@@ -1789,7 +1789,7 @@ var _ObjectQL = class _ObjectQL {
|
|
|
1789
1789
|
const relatedRecords = await driver.find(referenceObject, relatedQuery) ?? [];
|
|
1790
1790
|
const recordMap = /* @__PURE__ */ new Map();
|
|
1791
1791
|
for (const rec of relatedRecords) {
|
|
1792
|
-
const id = rec.
|
|
1792
|
+
const id = rec.id;
|
|
1793
1793
|
if (id != null) recordMap.set(String(id), rec);
|
|
1794
1794
|
}
|
|
1795
1795
|
if (nestedAST.expand && Object.keys(nestedAST.expand).length > 0) {
|
|
@@ -1801,7 +1801,7 @@ var _ObjectQL = class _ObjectQL {
|
|
|
1801
1801
|
);
|
|
1802
1802
|
recordMap.clear();
|
|
1803
1803
|
for (const rec of expandedRelated) {
|
|
1804
|
-
const id = rec.
|
|
1804
|
+
const id = rec.id;
|
|
1805
1805
|
if (id != null) recordMap.set(String(id), rec);
|
|
1806
1806
|
}
|
|
1807
1807
|
}
|
|
@@ -1969,10 +1969,9 @@ var _ObjectQL = class _ObjectQL {
|
|
|
1969
1969
|
object = this.resolveObjectName(object);
|
|
1970
1970
|
this.logger.debug("Update operation starting", { object });
|
|
1971
1971
|
const driver = this.getDriver(object);
|
|
1972
|
-
let id = data.id
|
|
1972
|
+
let id = data.id;
|
|
1973
1973
|
if (!id && options?.filter) {
|
|
1974
1974
|
if (typeof options.filter === "string") id = options.filter;
|
|
1975
|
-
else if (options.filter._id) id = options.filter._id;
|
|
1976
1975
|
else if (options.filter.id) id = options.filter.id;
|
|
1977
1976
|
}
|
|
1978
1977
|
const opCtx = {
|
|
@@ -2020,7 +2019,6 @@ var _ObjectQL = class _ObjectQL {
|
|
|
2020
2019
|
let id = void 0;
|
|
2021
2020
|
if (options?.filter) {
|
|
2022
2021
|
if (typeof options.filter === "string") id = options.filter;
|
|
2023
|
-
else if (options.filter._id) id = options.filter._id;
|
|
2024
2022
|
else if (options.filter.id) id = options.filter.id;
|
|
2025
2023
|
}
|
|
2026
2024
|
const opCtx = {
|
|
@@ -2074,7 +2072,7 @@ var _ObjectQL = class _ObjectQL {
|
|
|
2074
2072
|
const ast = this.toQueryAST(object, { filter: query?.filter });
|
|
2075
2073
|
return driver.count(object, ast);
|
|
2076
2074
|
}
|
|
2077
|
-
const res = await this.find(object, { filter: query?.filter, select: ["
|
|
2075
|
+
const res = await this.find(object, { filter: query?.filter, select: ["id"] });
|
|
2078
2076
|
return res.length;
|
|
2079
2077
|
});
|
|
2080
2078
|
return opCtx.result;
|
|
@@ -2308,8 +2306,8 @@ var ObjectRepository = class {
|
|
|
2308
2306
|
}
|
|
2309
2307
|
/** Update a single record by ID */
|
|
2310
2308
|
async updateById(id, data) {
|
|
2311
|
-
return this.engine.update(this.objectName, { ...data,
|
|
2312
|
-
filter: {
|
|
2309
|
+
return this.engine.update(this.objectName, { ...data, id }, {
|
|
2310
|
+
filter: { id },
|
|
2313
2311
|
context: this.context
|
|
2314
2312
|
});
|
|
2315
2313
|
}
|
|
@@ -2322,7 +2320,7 @@ var ObjectRepository = class {
|
|
|
2322
2320
|
/** Delete a single record by ID */
|
|
2323
2321
|
async deleteById(id) {
|
|
2324
2322
|
return this.engine.delete(this.objectName, {
|
|
2325
|
-
filter: {
|
|
2323
|
+
filter: { id },
|
|
2326
2324
|
context: this.context
|
|
2327
2325
|
});
|
|
2328
2326
|
}
|
|
@@ -2570,6 +2568,7 @@ var ObjectQLPlugin = class {
|
|
|
2570
2568
|
}
|
|
2571
2569
|
}
|
|
2572
2570
|
}
|
|
2571
|
+
await this.ql?.init();
|
|
2573
2572
|
this.registerAuditHooks(ctx);
|
|
2574
2573
|
this.registerTenantMiddleware(ctx);
|
|
2575
2574
|
ctx.logger.info("ObjectQL engine started", {
|
|
@@ -2584,7 +2583,7 @@ var ObjectQLPlugin = class {
|
|
|
2584
2583
|
}
|
|
2585
2584
|
}
|
|
2586
2585
|
/**
|
|
2587
|
-
* Register built-in audit hooks for auto-stamping
|
|
2586
|
+
* Register built-in audit hooks for auto-stamping created_by/updated_by
|
|
2588
2587
|
* and fetching previousData for update/delete operations.
|
|
2589
2588
|
*/
|
|
2590
2589
|
registerAuditHooks(ctx) {
|
|
@@ -2594,11 +2593,11 @@ var ObjectQLPlugin = class {
|
|
|
2594
2593
|
const data = hookCtx.input.data;
|
|
2595
2594
|
if (typeof data === "object" && data !== null) {
|
|
2596
2595
|
data.created_by = data.created_by ?? hookCtx.session.userId;
|
|
2597
|
-
data.
|
|
2596
|
+
data.updated_by = hookCtx.session.userId;
|
|
2598
2597
|
data.created_at = data.created_at ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
2599
|
-
data.
|
|
2598
|
+
data.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
2600
2599
|
if (hookCtx.session.tenantId) {
|
|
2601
|
-
data.
|
|
2600
|
+
data.tenant_id = data.tenant_id ?? hookCtx.session.tenantId;
|
|
2602
2601
|
}
|
|
2603
2602
|
}
|
|
2604
2603
|
}
|
|
@@ -2607,8 +2606,8 @@ var ObjectQLPlugin = class {
|
|
|
2607
2606
|
if (hookCtx.session?.userId && hookCtx.input?.data) {
|
|
2608
2607
|
const data = hookCtx.input.data;
|
|
2609
2608
|
if (typeof data === "object" && data !== null) {
|
|
2610
|
-
data.
|
|
2611
|
-
data.
|
|
2609
|
+
data.updated_by = hookCtx.session.userId;
|
|
2610
|
+
data.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
2612
2611
|
}
|
|
2613
2612
|
}
|
|
2614
2613
|
}, { object: "*", priority: 10 });
|
|
@@ -2616,7 +2615,7 @@ var ObjectQLPlugin = class {
|
|
|
2616
2615
|
if (hookCtx.input?.id && !hookCtx.previous) {
|
|
2617
2616
|
try {
|
|
2618
2617
|
const existing = await this.ql.findOne(hookCtx.object, {
|
|
2619
|
-
filter: {
|
|
2618
|
+
filter: { id: hookCtx.input.id }
|
|
2620
2619
|
});
|
|
2621
2620
|
if (existing) {
|
|
2622
2621
|
hookCtx.previous = existing;
|
|
@@ -2629,7 +2628,7 @@ var ObjectQLPlugin = class {
|
|
|
2629
2628
|
if (hookCtx.input?.id && !hookCtx.previous) {
|
|
2630
2629
|
try {
|
|
2631
2630
|
const existing = await this.ql.findOne(hookCtx.object, {
|
|
2632
|
-
filter: {
|
|
2631
|
+
filter: { id: hookCtx.input.id }
|
|
2633
2632
|
});
|
|
2634
2633
|
if (existing) {
|
|
2635
2634
|
hookCtx.previous = existing;
|
|
@@ -2638,10 +2637,10 @@ var ObjectQLPlugin = class {
|
|
|
2638
2637
|
}
|
|
2639
2638
|
}
|
|
2640
2639
|
}, { object: "*", priority: 5 });
|
|
2641
|
-
ctx.logger.debug("Audit hooks registered (
|
|
2640
|
+
ctx.logger.debug("Audit hooks registered (created_by/updated_by, previousData)");
|
|
2642
2641
|
}
|
|
2643
2642
|
/**
|
|
2644
|
-
* Register tenant isolation middleware that auto-injects
|
|
2643
|
+
* Register tenant isolation middleware that auto-injects tenant_id filter
|
|
2645
2644
|
* for multi-tenant operations.
|
|
2646
2645
|
*/
|
|
2647
2646
|
registerTenantMiddleware(ctx) {
|
|
@@ -2652,7 +2651,7 @@ var ObjectQLPlugin = class {
|
|
|
2652
2651
|
}
|
|
2653
2652
|
if (["find", "findOne", "count", "aggregate"].includes(opCtx.operation)) {
|
|
2654
2653
|
if (opCtx.ast) {
|
|
2655
|
-
const tenantFilter = {
|
|
2654
|
+
const tenantFilter = { tenant_id: opCtx.context.tenantId };
|
|
2656
2655
|
if (opCtx.ast.where) {
|
|
2657
2656
|
opCtx.ast.where = { $and: [opCtx.ast.where, tenantFilter] };
|
|
2658
2657
|
} else {
|