@objectstack/runtime 4.0.3 → 4.0.4
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 +10 -0
- package/dist/index.cjs +139 -188
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -11
- package/dist/index.d.ts +9 -11
- package/dist/index.js +139 -188
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/src/app-plugin.ts +9 -0
- package/src/http-dispatcher.root.test.ts +0 -3
- package/src/http-dispatcher.test.ts +105 -100
- package/src/http-dispatcher.ts +160 -240
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @objectstack/runtime@4.0.
|
|
2
|
+
> @objectstack/runtime@4.0.4 build /home/runner/work/framework/framework/packages/runtime
|
|
3
3
|
> tsup --config ../../tsup.config.ts
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
@@ -10,13 +10,13 @@
|
|
|
10
10
|
[34mCLI[39m Cleaning output folder
|
|
11
11
|
[34mESM[39m Build start
|
|
12
12
|
[34mCJS[39m Build start
|
|
13
|
-
[
|
|
14
|
-
[
|
|
15
|
-
[
|
|
16
|
-
[
|
|
17
|
-
[
|
|
18
|
-
[
|
|
13
|
+
[32mCJS[39m [1mdist/index.cjs [22m[32m97.58 KB[39m
|
|
14
|
+
[32mCJS[39m [1mdist/index.cjs.map [22m[32m206.05 KB[39m
|
|
15
|
+
[32mCJS[39m ⚡️ Build success in 196ms
|
|
16
|
+
[32mESM[39m [1mdist/index.js [22m[32m94.96 KB[39m
|
|
17
|
+
[32mESM[39m [1mdist/index.js.map [22m[32m205.98 KB[39m
|
|
18
|
+
[32mESM[39m ⚡️ Build success in 200ms
|
|
19
19
|
[34mDTS[39m Build start
|
|
20
|
-
[32mDTS[39m ⚡️ Build success in
|
|
21
|
-
[32mDTS[39m [1mdist/index.d.ts [22m[
|
|
22
|
-
[32mDTS[39m [1mdist/index.d.cts [22m[
|
|
20
|
+
[32mDTS[39m ⚡️ Build success in 3990ms
|
|
21
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m25.96 KB[39m
|
|
22
|
+
[32mDTS[39m [1mdist/index.d.cts [22m[32m25.96 KB[39m
|
package/CHANGELOG.md
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -665,6 +665,13 @@ var AppPlugin = class {
|
|
|
665
665
|
return;
|
|
666
666
|
}
|
|
667
667
|
ctx.logger.debug("Retrieved ObjectQL engine service", { appId });
|
|
668
|
+
if (this.bundle.datasourceMapping && Array.isArray(this.bundle.datasourceMapping)) {
|
|
669
|
+
ctx.logger.info("Configuring datasource mapping rules", {
|
|
670
|
+
appId,
|
|
671
|
+
ruleCount: this.bundle.datasourceMapping.length
|
|
672
|
+
});
|
|
673
|
+
ql.setDatasourceMapping(this.bundle.datasourceMapping);
|
|
674
|
+
}
|
|
668
675
|
const runtime = this.bundle.default || this.bundle;
|
|
669
676
|
if (runtime && typeof runtime.onEnable === "function") {
|
|
670
677
|
ctx.logger.info("Executing runtime.onEnable", {
|
|
@@ -840,7 +847,7 @@ function randomUUID() {
|
|
|
840
847
|
});
|
|
841
848
|
}
|
|
842
849
|
var HttpDispatcher = class {
|
|
843
|
-
// Casting to any to access dynamic props like
|
|
850
|
+
// Casting to any to access dynamic props like services, graphql
|
|
844
851
|
constructor(kernel) {
|
|
845
852
|
this.kernel = kernel;
|
|
846
853
|
}
|
|
@@ -874,11 +881,73 @@ var HttpDispatcher = class {
|
|
|
874
881
|
}
|
|
875
882
|
};
|
|
876
883
|
}
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
884
|
+
/**
|
|
885
|
+
* Direct data service dispatch — replaces broker.call('data.*').
|
|
886
|
+
* Tries protocol service first (supports expand/populate), falls back to ObjectQL.
|
|
887
|
+
*/
|
|
888
|
+
async callData(action, params) {
|
|
889
|
+
const protocol = await this.resolveService("protocol");
|
|
890
|
+
const qlService = await this.getObjectQLService();
|
|
891
|
+
const ql = qlService ?? await this.resolveService("objectql");
|
|
892
|
+
if (action === "create") {
|
|
893
|
+
if (ql) {
|
|
894
|
+
const res = await ql.insert(params.object, params.data);
|
|
895
|
+
const record = { ...params.data, ...res };
|
|
896
|
+
return { object: params.object, id: record.id, record };
|
|
897
|
+
}
|
|
898
|
+
throw { statusCode: 503, message: "Data service not available" };
|
|
899
|
+
}
|
|
900
|
+
if (action === "get") {
|
|
901
|
+
if (protocol && typeof protocol.getData === "function") {
|
|
902
|
+
return await protocol.getData({ object: params.object, id: params.id, expand: params.expand, select: params.select });
|
|
903
|
+
}
|
|
904
|
+
if (ql) {
|
|
905
|
+
let all = await ql.find(params.object);
|
|
906
|
+
if (!all) all = [];
|
|
907
|
+
const match = all.find((i) => i.id === params.id);
|
|
908
|
+
return match ? { object: params.object, id: params.id, record: match } : null;
|
|
909
|
+
}
|
|
910
|
+
throw { statusCode: 503, message: "Data service not available" };
|
|
911
|
+
}
|
|
912
|
+
if (action === "update") {
|
|
913
|
+
if (ql && params.id) {
|
|
914
|
+
let all = await ql.find(params.object);
|
|
915
|
+
if (all && all.value) all = all.value;
|
|
916
|
+
if (!all) all = [];
|
|
917
|
+
const existing = all.find((i) => i.id === params.id);
|
|
918
|
+
if (!existing) throw new Error("[ObjectStack] Not Found");
|
|
919
|
+
await ql.update(params.object, params.data, { where: { id: params.id } });
|
|
920
|
+
return { object: params.object, id: params.id, record: { ...existing, ...params.data } };
|
|
921
|
+
}
|
|
922
|
+
throw { statusCode: 503, message: "Data service not available" };
|
|
923
|
+
}
|
|
924
|
+
if (action === "delete") {
|
|
925
|
+
if (ql) {
|
|
926
|
+
await ql.delete(params.object, { where: { id: params.id } });
|
|
927
|
+
return { object: params.object, id: params.id, deleted: true };
|
|
928
|
+
}
|
|
929
|
+
throw { statusCode: 503, message: "Data service not available" };
|
|
930
|
+
}
|
|
931
|
+
if (action === "query" || action === "find") {
|
|
932
|
+
if (protocol && typeof protocol.findData === "function") {
|
|
933
|
+
const query = params.query || (() => {
|
|
934
|
+
const { object, ...rest } = params;
|
|
935
|
+
return rest;
|
|
936
|
+
})();
|
|
937
|
+
return await protocol.findData({ object: params.object, query });
|
|
938
|
+
}
|
|
939
|
+
if (ql) {
|
|
940
|
+
let all = await ql.find(params.object);
|
|
941
|
+
if (!Array.isArray(all) && all && all.value) all = all.value;
|
|
942
|
+
if (!all) all = [];
|
|
943
|
+
return { object: params.object, records: all, total: all.length };
|
|
944
|
+
}
|
|
945
|
+
throw { statusCode: 503, message: "Data service not available" };
|
|
946
|
+
}
|
|
947
|
+
if (action === "batch") {
|
|
948
|
+
return { object: params.object, results: [] };
|
|
949
|
+
}
|
|
950
|
+
throw { statusCode: 400, message: `Unknown data action: ${action}` };
|
|
882
951
|
}
|
|
883
952
|
/**
|
|
884
953
|
* Generates the discovery JSON response for the API root.
|
|
@@ -1042,18 +1111,6 @@ var HttpDispatcher = class {
|
|
|
1042
1111
|
return { handled: true, result: response };
|
|
1043
1112
|
}
|
|
1044
1113
|
const normalizedPath = path.replace(/^\/+/, "");
|
|
1045
|
-
if (normalizedPath === "login" && method.toUpperCase() === "POST") {
|
|
1046
|
-
try {
|
|
1047
|
-
const broker = this.ensureBroker();
|
|
1048
|
-
const data = await broker.call("auth.login", body, { request: context.request });
|
|
1049
|
-
return { handled: true, response: { status: 200, body: data } };
|
|
1050
|
-
} catch (error) {
|
|
1051
|
-
const statusCode = error?.statusCode ?? error?.status;
|
|
1052
|
-
if (statusCode !== 500 || !error?.message?.includes("Broker not available")) {
|
|
1053
|
-
throw error;
|
|
1054
|
-
}
|
|
1055
|
-
}
|
|
1056
|
-
}
|
|
1057
1114
|
return this.mockAuthFallback(normalizedPath, method, body);
|
|
1058
1115
|
}
|
|
1059
1116
|
/**
|
|
@@ -1109,70 +1166,23 @@ var HttpDispatcher = class {
|
|
|
1109
1166
|
* Standard: /metadata/:type/:name
|
|
1110
1167
|
* Fallback for backward compat: /metadata (all objects), /metadata/:objectName (get object)
|
|
1111
1168
|
*/
|
|
1112
|
-
async handleMetadata(path,
|
|
1113
|
-
const broker = this.kernel.broker ?? null;
|
|
1169
|
+
async handleMetadata(path, _context, method, body, query) {
|
|
1114
1170
|
const parts = path.replace(/^\/+/, "").split("/").filter(Boolean);
|
|
1115
1171
|
if (parts[0] === "types") {
|
|
1116
|
-
|
|
1117
|
-
console.log("[HttpDispatcher] Available kernel methods:", {
|
|
1118
|
-
hasGetServiceAsync: typeof this.kernel.getServiceAsync === "function",
|
|
1119
|
-
hasGetService: typeof this.kernel.getService === "function",
|
|
1120
|
-
hasContext: !!this.kernel.context,
|
|
1121
|
-
hasContextGetService: typeof this.kernel.context?.getService === "function"
|
|
1122
|
-
});
|
|
1123
|
-
let metadataService = null;
|
|
1124
|
-
if (typeof this.kernel.getServiceAsync === "function") {
|
|
1125
|
-
try {
|
|
1126
|
-
metadataService = await this.kernel.getServiceAsync("metadata");
|
|
1127
|
-
console.log('[HttpDispatcher] kernel.getServiceAsync("metadata") returned:', !!metadataService);
|
|
1128
|
-
} catch (e) {
|
|
1129
|
-
console.log('[HttpDispatcher] kernel.getServiceAsync("metadata") failed:', e.message);
|
|
1130
|
-
}
|
|
1131
|
-
}
|
|
1132
|
-
if (!metadataService && typeof this.kernel.getService === "function") {
|
|
1133
|
-
try {
|
|
1134
|
-
metadataService = await this.kernel.getService("metadata");
|
|
1135
|
-
console.log('[HttpDispatcher] kernel.getService("metadata") returned:', !!metadataService);
|
|
1136
|
-
} catch (e) {
|
|
1137
|
-
console.log('[HttpDispatcher] kernel.getService("metadata") failed:', e.message);
|
|
1138
|
-
}
|
|
1139
|
-
}
|
|
1140
|
-
if (!metadataService && this.kernel.context?.getService) {
|
|
1141
|
-
try {
|
|
1142
|
-
metadataService = await this.kernel.context.getService("metadata");
|
|
1143
|
-
console.log('[HttpDispatcher] kernel.context.getService("metadata") returned:', !!metadataService);
|
|
1144
|
-
} catch (e) {
|
|
1145
|
-
console.log('[HttpDispatcher] kernel.context.getService("metadata") failed:', e.message);
|
|
1146
|
-
}
|
|
1147
|
-
}
|
|
1148
|
-
console.log("[HttpDispatcher] Final metadataService:", !!metadataService, "has getRegisteredTypes:", typeof metadataService?.getRegisteredTypes);
|
|
1172
|
+
const metadataService = await this.resolveService("metadata");
|
|
1149
1173
|
if (metadataService && typeof metadataService.getRegisteredTypes === "function") {
|
|
1150
1174
|
try {
|
|
1151
1175
|
const types = await metadataService.getRegisteredTypes();
|
|
1152
|
-
console.log("[HttpDispatcher] MetadataService.getRegisteredTypes() returned:", types);
|
|
1153
1176
|
return { handled: true, response: this.success({ types }) };
|
|
1154
1177
|
} catch (e) {
|
|
1155
|
-
console.warn("[HttpDispatcher] MetadataService.getRegisteredTypes() failed:", e.message
|
|
1178
|
+
console.warn("[HttpDispatcher] MetadataService.getRegisteredTypes() failed:", e.message);
|
|
1156
1179
|
}
|
|
1157
|
-
} else {
|
|
1158
|
-
console.log("[HttpDispatcher] MetadataService not available or missing getRegisteredTypes, falling back to protocol service");
|
|
1159
1180
|
}
|
|
1160
1181
|
const protocol = await this.resolveService("protocol");
|
|
1161
1182
|
if (protocol && typeof protocol.getMetaTypes === "function") {
|
|
1162
1183
|
const result = await protocol.getMetaTypes({});
|
|
1163
|
-
console.log("[HttpDispatcher] Protocol service returned types:", result);
|
|
1164
1184
|
return { handled: true, response: this.success(result) };
|
|
1165
1185
|
}
|
|
1166
|
-
if (broker) {
|
|
1167
|
-
try {
|
|
1168
|
-
const data = await broker.call("metadata.types", {}, { request: context.request });
|
|
1169
|
-
console.log("[HttpDispatcher] Broker returned types:", data);
|
|
1170
|
-
return { handled: true, response: this.success(data) };
|
|
1171
|
-
} catch (e) {
|
|
1172
|
-
console.log("[HttpDispatcher] Broker call failed:", e);
|
|
1173
|
-
}
|
|
1174
|
-
}
|
|
1175
|
-
console.warn("[HttpDispatcher] Falling back to hardcoded defaults for metadata types");
|
|
1176
1186
|
return { handled: true, response: this.success({ types: ["object", "app", "plugin"] }) };
|
|
1177
1187
|
}
|
|
1178
1188
|
if (parts.length === 3 && parts[2] === "published" && (!method || method === "GET")) {
|
|
@@ -1183,12 +1193,12 @@ var HttpDispatcher = class {
|
|
|
1183
1193
|
if (data === void 0) return { handled: true, response: this.error("Not found", 404) };
|
|
1184
1194
|
return { handled: true, response: this.success(data) };
|
|
1185
1195
|
}
|
|
1186
|
-
|
|
1196
|
+
const metaSvc = await this.resolveService("metadata");
|
|
1197
|
+
if (metaSvc && typeof metaSvc.getPublished === "function") {
|
|
1187
1198
|
try {
|
|
1188
|
-
const
|
|
1189
|
-
return { handled: true, response: this.success(
|
|
1190
|
-
} catch
|
|
1191
|
-
return { handled: true, response: this.error(e.message, 404) };
|
|
1199
|
+
const fallbackData = await metaSvc.getPublished(type, name);
|
|
1200
|
+
if (fallbackData !== void 0) return { handled: true, response: this.success(fallbackData) };
|
|
1201
|
+
} catch {
|
|
1192
1202
|
}
|
|
1193
1203
|
}
|
|
1194
1204
|
return { handled: true, response: this.error("Not found", 404) };
|
|
@@ -1206,9 +1216,10 @@ var HttpDispatcher = class {
|
|
|
1206
1216
|
return { handled: true, response: this.error(e.message, 400) };
|
|
1207
1217
|
}
|
|
1208
1218
|
}
|
|
1209
|
-
|
|
1219
|
+
const metaSvc = await this.resolveService("metadata");
|
|
1220
|
+
if (metaSvc && typeof metaSvc.saveItem === "function") {
|
|
1210
1221
|
try {
|
|
1211
|
-
const data = await
|
|
1222
|
+
const data = await metaSvc.saveItem(type, name, body);
|
|
1212
1223
|
return { handled: true, response: this.success(data) };
|
|
1213
1224
|
} catch (e) {
|
|
1214
1225
|
return { handled: true, response: this.error(e.message || "Save not supported", 501) };
|
|
@@ -1218,10 +1229,6 @@ var HttpDispatcher = class {
|
|
|
1218
1229
|
}
|
|
1219
1230
|
try {
|
|
1220
1231
|
if (type === "objects" || type === "object") {
|
|
1221
|
-
if (broker) {
|
|
1222
|
-
const data = await broker.call("metadata.getObject", { objectName: name }, { request: context.request });
|
|
1223
|
-
return { handled: true, response: this.success(data) };
|
|
1224
|
-
}
|
|
1225
1232
|
const qlService = await this.getObjectQLService();
|
|
1226
1233
|
if (qlService?.registry) {
|
|
1227
1234
|
const data = qlService.registry.getObject(name);
|
|
@@ -1238,10 +1245,13 @@ var HttpDispatcher = class {
|
|
|
1238
1245
|
} catch (e) {
|
|
1239
1246
|
}
|
|
1240
1247
|
}
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1248
|
+
const metaSvc = await this.resolveService("metadata");
|
|
1249
|
+
if (metaSvc && typeof metaSvc.getItem === "function") {
|
|
1250
|
+
try {
|
|
1251
|
+
const data = await metaSvc.getItem(singularType, name);
|
|
1252
|
+
if (data) return { handled: true, response: this.success(data) };
|
|
1253
|
+
} catch {
|
|
1254
|
+
}
|
|
1245
1255
|
}
|
|
1246
1256
|
return { handled: true, response: this.error("Not found", 404) };
|
|
1247
1257
|
} catch (e) {
|
|
@@ -1264,7 +1274,10 @@ var HttpDispatcher = class {
|
|
|
1264
1274
|
const metadataService = await this.getService(import_system.CoreServiceName.enum.metadata);
|
|
1265
1275
|
if (metadataService && typeof metadataService.list === "function") {
|
|
1266
1276
|
try {
|
|
1267
|
-
|
|
1277
|
+
let items = await metadataService.list(typeOrName);
|
|
1278
|
+
if (packageId && items && items.length > 0) {
|
|
1279
|
+
items = items.filter((item) => item?._packageId === packageId);
|
|
1280
|
+
}
|
|
1268
1281
|
if (items && items.length > 0) {
|
|
1269
1282
|
return { handled: true, response: this.success({ type: typeOrName, items }) };
|
|
1270
1283
|
}
|
|
@@ -1273,25 +1286,6 @@ var HttpDispatcher = class {
|
|
|
1273
1286
|
console.debug(`[HttpDispatcher] MetadataService.list() failed for type:`, sanitizedType, "error:", e.message);
|
|
1274
1287
|
}
|
|
1275
1288
|
}
|
|
1276
|
-
if (broker) {
|
|
1277
|
-
try {
|
|
1278
|
-
if (typeOrName === "objects") {
|
|
1279
|
-
const data2 = await broker.call("metadata.objects", { packageId }, { request: context.request });
|
|
1280
|
-
return { handled: true, response: this.success(data2) };
|
|
1281
|
-
}
|
|
1282
|
-
const data = await broker.call(`metadata.${typeOrName}`, { packageId }, { request: context.request });
|
|
1283
|
-
if (data !== null && data !== void 0) {
|
|
1284
|
-
return { handled: true, response: this.success(data) };
|
|
1285
|
-
}
|
|
1286
|
-
} catch {
|
|
1287
|
-
}
|
|
1288
|
-
try {
|
|
1289
|
-
const data = await broker.call("metadata.getObject", { objectName: typeOrName }, { request: context.request });
|
|
1290
|
-
return { handled: true, response: this.success(data) };
|
|
1291
|
-
} catch (e) {
|
|
1292
|
-
return { handled: true, response: this.error(e.message, 404) };
|
|
1293
|
-
}
|
|
1294
|
-
}
|
|
1295
1289
|
const qlService = await this.getObjectQLService();
|
|
1296
1290
|
if (qlService?.registry) {
|
|
1297
1291
|
if (typeOrName === "objects") {
|
|
@@ -1308,18 +1302,19 @@ var HttpDispatcher = class {
|
|
|
1308
1302
|
return { handled: true, response: this.error("Not found", 404) };
|
|
1309
1303
|
}
|
|
1310
1304
|
if (parts.length === 0) {
|
|
1305
|
+
const metadataService = await this.resolveService("metadata");
|
|
1306
|
+
if (metadataService && typeof metadataService.getRegisteredTypes === "function") {
|
|
1307
|
+
try {
|
|
1308
|
+
const types = await metadataService.getRegisteredTypes();
|
|
1309
|
+
return { handled: true, response: this.success({ types }) };
|
|
1310
|
+
} catch {
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1311
1313
|
const protocol = await this.resolveService("protocol");
|
|
1312
1314
|
if (protocol && typeof protocol.getMetaTypes === "function") {
|
|
1313
1315
|
const result = await protocol.getMetaTypes({});
|
|
1314
1316
|
return { handled: true, response: this.success(result) };
|
|
1315
1317
|
}
|
|
1316
|
-
if (broker) {
|
|
1317
|
-
try {
|
|
1318
|
-
const data = await broker.call("metadata.types", {}, { request: context.request });
|
|
1319
|
-
return { handled: true, response: this.success(data) };
|
|
1320
|
-
} catch {
|
|
1321
|
-
}
|
|
1322
|
-
}
|
|
1323
1318
|
return { handled: true, response: this.success({ types: ["object", "app", "plugin"] }) };
|
|
1324
1319
|
}
|
|
1325
1320
|
return { handled: false };
|
|
@@ -1328,8 +1323,7 @@ var HttpDispatcher = class {
|
|
|
1328
1323
|
* Handles Data requests
|
|
1329
1324
|
* path: sub-path after /data/ (e.g. "contacts", "contacts/123", "contacts/query")
|
|
1330
1325
|
*/
|
|
1331
|
-
async handleData(path, method, body, query,
|
|
1332
|
-
const broker = this.ensureBroker();
|
|
1326
|
+
async handleData(path, method, body, query, _context) {
|
|
1333
1327
|
const parts = path.replace(/^\/+/, "").split("/");
|
|
1334
1328
|
const objectName = parts[0];
|
|
1335
1329
|
if (!objectName) {
|
|
@@ -1339,11 +1333,11 @@ var HttpDispatcher = class {
|
|
|
1339
1333
|
if (parts.length > 1) {
|
|
1340
1334
|
const action = parts[1];
|
|
1341
1335
|
if (action === "query" && m === "POST") {
|
|
1342
|
-
const result = await
|
|
1336
|
+
const result = await this.callData("query", { object: objectName, ...body });
|
|
1343
1337
|
return { handled: true, response: this.success(result) };
|
|
1344
1338
|
}
|
|
1345
1339
|
if (action === "batch" && m === "POST") {
|
|
1346
|
-
const result = await
|
|
1340
|
+
const result = await this.callData("batch", { object: objectName, ...body });
|
|
1347
1341
|
return { handled: true, response: this.success(result) };
|
|
1348
1342
|
}
|
|
1349
1343
|
if (parts.length === 2 && m === "GET") {
|
|
@@ -1352,17 +1346,17 @@ var HttpDispatcher = class {
|
|
|
1352
1346
|
const allowedParams = {};
|
|
1353
1347
|
if (select != null) allowedParams.select = select;
|
|
1354
1348
|
if (expand != null) allowedParams.expand = expand;
|
|
1355
|
-
const result = await
|
|
1349
|
+
const result = await this.callData("get", { object: objectName, id, ...allowedParams });
|
|
1356
1350
|
return { handled: true, response: this.success(result) };
|
|
1357
1351
|
}
|
|
1358
1352
|
if (parts.length === 2 && m === "PATCH") {
|
|
1359
1353
|
const id = parts[1];
|
|
1360
|
-
const result = await
|
|
1354
|
+
const result = await this.callData("update", { object: objectName, id, data: body });
|
|
1361
1355
|
return { handled: true, response: this.success(result) };
|
|
1362
1356
|
}
|
|
1363
1357
|
if (parts.length === 2 && m === "DELETE") {
|
|
1364
1358
|
const id = parts[1];
|
|
1365
|
-
const result = await
|
|
1359
|
+
const result = await this.callData("delete", { object: objectName, id });
|
|
1366
1360
|
return { handled: true, response: this.success(result) };
|
|
1367
1361
|
}
|
|
1368
1362
|
} else {
|
|
@@ -1389,11 +1383,11 @@ var HttpDispatcher = class {
|
|
|
1389
1383
|
normalized.offset = normalized.skip;
|
|
1390
1384
|
delete normalized.skip;
|
|
1391
1385
|
}
|
|
1392
|
-
const result = await
|
|
1386
|
+
const result = await this.callData("query", { object: objectName, query: normalized });
|
|
1393
1387
|
return { handled: true, response: this.success(result) };
|
|
1394
1388
|
}
|
|
1395
1389
|
if (m === "POST") {
|
|
1396
|
-
const result = await
|
|
1390
|
+
const result = await this.callData("create", { object: objectName, data: body });
|
|
1397
1391
|
const res = this.success(result);
|
|
1398
1392
|
res.status = 201;
|
|
1399
1393
|
return { handled: true, response: res };
|
|
@@ -1495,18 +1489,14 @@ var HttpDispatcher = class {
|
|
|
1495
1489
|
* - POST /packages/:id/publish → publish a package (metadata snapshot)
|
|
1496
1490
|
* - POST /packages/:id/revert → revert a package to last published state
|
|
1497
1491
|
*
|
|
1498
|
-
* Uses ObjectQL SchemaRegistry directly (via the 'objectql' service)
|
|
1499
|
-
* with broker fallback for backward compatibility.
|
|
1492
|
+
* Uses ObjectQL SchemaRegistry directly (via the 'objectql' service).
|
|
1500
1493
|
*/
|
|
1501
|
-
async handlePackages(path, method, body, query,
|
|
1494
|
+
async handlePackages(path, method, body, query, _context) {
|
|
1502
1495
|
const m = method.toUpperCase();
|
|
1503
1496
|
const parts = path.replace(/^\/+/, "").split("/").filter(Boolean);
|
|
1504
1497
|
const qlService = await this.getObjectQLService();
|
|
1505
1498
|
const registry = qlService?.registry;
|
|
1506
1499
|
if (!registry) {
|
|
1507
|
-
if (this.kernel.broker) {
|
|
1508
|
-
return this.handlePackagesViaBroker(parts, m, body, query, context);
|
|
1509
|
-
}
|
|
1510
1500
|
return { handled: true, response: this.error("Package service not available", 503) };
|
|
1511
1501
|
}
|
|
1512
1502
|
try {
|
|
@@ -1545,10 +1535,6 @@ var HttpDispatcher = class {
|
|
|
1545
1535
|
const result = await metadataService.publishPackage(id, body || {});
|
|
1546
1536
|
return { handled: true, response: this.success(result) };
|
|
1547
1537
|
}
|
|
1548
|
-
if (this.kernel.broker) {
|
|
1549
|
-
const result = await this.kernel.broker.call("metadata.publishPackage", { packageId: id, ...body }, { request: context.request });
|
|
1550
|
-
return { handled: true, response: this.success(result) };
|
|
1551
|
-
}
|
|
1552
1538
|
return { handled: true, response: this.error("Metadata service not available", 503) };
|
|
1553
1539
|
}
|
|
1554
1540
|
if (parts.length === 2 && parts[1] === "revert" && m === "POST") {
|
|
@@ -1558,10 +1544,6 @@ var HttpDispatcher = class {
|
|
|
1558
1544
|
await metadataService.revertPackage(id);
|
|
1559
1545
|
return { handled: true, response: this.success({ success: true }) };
|
|
1560
1546
|
}
|
|
1561
|
-
if (this.kernel.broker) {
|
|
1562
|
-
await this.kernel.broker.call("metadata.revertPackage", { packageId: id }, { request: context.request });
|
|
1563
|
-
return { handled: true, response: this.success({ success: true }) };
|
|
1564
|
-
}
|
|
1565
1547
|
return { handled: true, response: this.error("Metadata service not available", 503) };
|
|
1566
1548
|
}
|
|
1567
1549
|
if (parts.length === 1 && m === "GET") {
|
|
@@ -1581,47 +1563,6 @@ var HttpDispatcher = class {
|
|
|
1581
1563
|
}
|
|
1582
1564
|
return { handled: false };
|
|
1583
1565
|
}
|
|
1584
|
-
/**
|
|
1585
|
-
* Fallback: handle packages via broker (for backward compatibility)
|
|
1586
|
-
*/
|
|
1587
|
-
async handlePackagesViaBroker(parts, m, body, query, context) {
|
|
1588
|
-
const broker = this.kernel.broker;
|
|
1589
|
-
try {
|
|
1590
|
-
if (parts.length === 0 && m === "GET") {
|
|
1591
|
-
const result = await broker.call("package.list", query || {}, { request: context.request });
|
|
1592
|
-
return { handled: true, response: this.success(result) };
|
|
1593
|
-
}
|
|
1594
|
-
if (parts.length === 0 && m === "POST") {
|
|
1595
|
-
const result = await broker.call("package.install", body, { request: context.request });
|
|
1596
|
-
const res = this.success(result);
|
|
1597
|
-
res.status = 201;
|
|
1598
|
-
return { handled: true, response: res };
|
|
1599
|
-
}
|
|
1600
|
-
if (parts.length === 2 && parts[1] === "enable" && m === "PATCH") {
|
|
1601
|
-
const id = decodeURIComponent(parts[0]);
|
|
1602
|
-
const result = await broker.call("package.enable", { id }, { request: context.request });
|
|
1603
|
-
return { handled: true, response: this.success(result) };
|
|
1604
|
-
}
|
|
1605
|
-
if (parts.length === 2 && parts[1] === "disable" && m === "PATCH") {
|
|
1606
|
-
const id = decodeURIComponent(parts[0]);
|
|
1607
|
-
const result = await broker.call("package.disable", { id }, { request: context.request });
|
|
1608
|
-
return { handled: true, response: this.success(result) };
|
|
1609
|
-
}
|
|
1610
|
-
if (parts.length === 1 && m === "GET") {
|
|
1611
|
-
const id = decodeURIComponent(parts[0]);
|
|
1612
|
-
const result = await broker.call("package.get", { id }, { request: context.request });
|
|
1613
|
-
return { handled: true, response: this.success(result) };
|
|
1614
|
-
}
|
|
1615
|
-
if (parts.length === 1 && m === "DELETE") {
|
|
1616
|
-
const id = decodeURIComponent(parts[0]);
|
|
1617
|
-
const result = await broker.call("package.uninstall", { id }, { request: context.request });
|
|
1618
|
-
return { handled: true, response: this.success(result) };
|
|
1619
|
-
}
|
|
1620
|
-
} catch (e) {
|
|
1621
|
-
return { handled: true, response: this.error(e.message, e.statusCode || 500) };
|
|
1622
|
-
}
|
|
1623
|
-
return { handled: false };
|
|
1624
|
-
}
|
|
1625
1566
|
/**
|
|
1626
1567
|
* Handles Storage requests
|
|
1627
1568
|
* path: sub-path after /storage/
|
|
@@ -1830,9 +1771,6 @@ var HttpDispatcher = class {
|
|
|
1830
1771
|
}
|
|
1831
1772
|
return null;
|
|
1832
1773
|
}
|
|
1833
|
-
capitalize(s) {
|
|
1834
|
-
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
1835
|
-
}
|
|
1836
1774
|
/**
|
|
1837
1775
|
* Handle AI service routes (/ai/chat, /ai/models, /ai/conversations, etc.)
|
|
1838
1776
|
* Resolves the AI service and its built-in route handlers, then dispatches.
|
|
@@ -1969,10 +1907,12 @@ var HttpDispatcher = class {
|
|
|
1969
1907
|
return this.handleAI(cleanPath, method, body, query, context);
|
|
1970
1908
|
}
|
|
1971
1909
|
if (cleanPath === "/openapi.json" && method === "GET") {
|
|
1972
|
-
const broker = this.ensureBroker();
|
|
1973
1910
|
try {
|
|
1974
|
-
const
|
|
1975
|
-
|
|
1911
|
+
const metaSvc = await this.resolveService("metadata");
|
|
1912
|
+
if (metaSvc && typeof metaSvc.generateOpenApi === "function") {
|
|
1913
|
+
const result2 = await metaSvc.generateOpenApi({});
|
|
1914
|
+
return { handled: true, response: this.success(result2) };
|
|
1915
|
+
}
|
|
1976
1916
|
} catch (e) {
|
|
1977
1917
|
}
|
|
1978
1918
|
}
|
|
@@ -1987,37 +1927,48 @@ var HttpDispatcher = class {
|
|
|
1987
1927
|
* Handles Custom API Endpoints defined in metadata
|
|
1988
1928
|
*/
|
|
1989
1929
|
async handleApiEndpoint(path, method, body, query, context) {
|
|
1990
|
-
const broker = this.ensureBroker();
|
|
1991
1930
|
try {
|
|
1992
|
-
const
|
|
1931
|
+
const metaSvc = await this.resolveService("metadata");
|
|
1932
|
+
if (!metaSvc || typeof metaSvc.matchEndpoint !== "function") {
|
|
1933
|
+
return { handled: false };
|
|
1934
|
+
}
|
|
1935
|
+
const endpoint = await metaSvc.matchEndpoint({ path, method });
|
|
1993
1936
|
if (endpoint) {
|
|
1994
1937
|
if (endpoint.type === "flow") {
|
|
1995
|
-
const
|
|
1938
|
+
const automationSvc = await this.resolveService("automation");
|
|
1939
|
+
if (!automationSvc || typeof automationSvc.runFlow !== "function") {
|
|
1940
|
+
return { handled: true, response: this.error("Automation service not available", 503) };
|
|
1941
|
+
}
|
|
1942
|
+
const result = await automationSvc.runFlow({
|
|
1996
1943
|
flowId: endpoint.target,
|
|
1997
1944
|
inputs: { ...query, ...body, _request: context.request }
|
|
1998
1945
|
});
|
|
1999
1946
|
return { handled: true, response: this.success(result) };
|
|
2000
1947
|
}
|
|
2001
1948
|
if (endpoint.type === "script") {
|
|
2002
|
-
const
|
|
1949
|
+
const automationSvc = await this.resolveService("automation");
|
|
1950
|
+
if (!automationSvc || typeof automationSvc.runScript !== "function") {
|
|
1951
|
+
return { handled: true, response: this.error("Automation service not available", 503) };
|
|
1952
|
+
}
|
|
1953
|
+
const result = await automationSvc.runScript({
|
|
2003
1954
|
scriptName: endpoint.target,
|
|
2004
1955
|
context: { ...query, ...body, request: context.request }
|
|
2005
|
-
}
|
|
1956
|
+
});
|
|
2006
1957
|
return { handled: true, response: this.success(result) };
|
|
2007
1958
|
}
|
|
2008
1959
|
if (endpoint.type === "object_operation") {
|
|
2009
1960
|
if (endpoint.objectParams) {
|
|
2010
1961
|
const { object, operation } = endpoint.objectParams;
|
|
2011
1962
|
if (operation === "find") {
|
|
2012
|
-
const result = await
|
|
1963
|
+
const result = await this.callData("query", { object, query });
|
|
2013
1964
|
return { handled: true, response: this.success(result.records, { total: result.total }) };
|
|
2014
1965
|
}
|
|
2015
1966
|
if (operation === "get" && query.id) {
|
|
2016
|
-
const result = await
|
|
1967
|
+
const result = await this.callData("get", { object, id: query.id });
|
|
2017
1968
|
return { handled: true, response: this.success(result) };
|
|
2018
1969
|
}
|
|
2019
1970
|
if (operation === "create") {
|
|
2020
|
-
const result = await
|
|
1971
|
+
const result = await this.callData("create", { object, data: body });
|
|
2021
1972
|
return { handled: true, response: this.success(result) };
|
|
2022
1973
|
}
|
|
2023
1974
|
}
|