@objectstack/runtime 12.0.0 → 12.2.0
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/index.cjs +65 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -1
- package/package.json +21 -21
package/dist/index.cjs
CHANGED
|
@@ -901,10 +901,11 @@ function collectBundleFunctions(bundle) {
|
|
|
901
901
|
merge(bundle?.manifest?.functions);
|
|
902
902
|
return out;
|
|
903
903
|
}
|
|
904
|
-
var import_types, AppPlugin;
|
|
904
|
+
var import_core2, import_types, AppPlugin;
|
|
905
905
|
var init_app_plugin = __esm({
|
|
906
906
|
"src/app-plugin.ts"() {
|
|
907
907
|
"use strict";
|
|
908
|
+
import_core2 = require("@objectstack/core");
|
|
908
909
|
import_types = require("@objectstack/types");
|
|
909
910
|
init_seed_loader();
|
|
910
911
|
init_package_state_store();
|
|
@@ -917,6 +918,8 @@ var init_app_plugin = __esm({
|
|
|
917
918
|
this.empty = false;
|
|
918
919
|
this.init = async (ctx) => {
|
|
919
920
|
this.installDefaultHookBodyRunner(ctx);
|
|
921
|
+
this.installDefaultActionBodyRunner(ctx);
|
|
922
|
+
(0, import_core2.wireAuthoredTranslationSync)(ctx);
|
|
920
923
|
if (this.empty) {
|
|
921
924
|
ctx.logger.debug("[AppPlugin] empty env \u2014 no app payload, skipping init", {
|
|
922
925
|
pluginName: this.name
|
|
@@ -1479,6 +1482,43 @@ var init_app_plugin = __esm({
|
|
|
1479
1482
|
}));
|
|
1480
1483
|
ctx.logger.info("[AppPlugin] Installed default hook body runner (runtime-authored hooks can execute)");
|
|
1481
1484
|
}
|
|
1485
|
+
/**
|
|
1486
|
+
* Install the engine's DEFAULT action body runner (`engine.setDefaultActionRunner`).
|
|
1487
|
+
*
|
|
1488
|
+
* The exact action-path parallel of {@link installDefaultHookBodyRunner}
|
|
1489
|
+
* (#2605 item 1): actions authored at runtime (Studio → `action` metadata →
|
|
1490
|
+
* publish) are registered by ObjectQLPlugin's authored-action re-sync,
|
|
1491
|
+
* which lives in `objectql` and therefore has no sandbox of its own. This
|
|
1492
|
+
* boot point hands it the same QuickJS-sandboxed runner that
|
|
1493
|
+
* `defineStack({ actions })` bundles already execute through, so an
|
|
1494
|
+
* authored `body` becomes a real `executeAction` handler instead of a
|
|
1495
|
+
* silent "Action not found".
|
|
1496
|
+
*
|
|
1497
|
+
* `OS_DISABLE_AUTHORED_ACTIONS=1` opts out for deployments that want
|
|
1498
|
+
* runtime-authored (DB-stored, non-code-reviewed) action bodies to stay
|
|
1499
|
+
* inert; code-shipped actions are unaffected (AppPlugin registers those
|
|
1500
|
+
* itself with its own runner).
|
|
1501
|
+
*/
|
|
1502
|
+
installDefaultActionBodyRunner(ctx) {
|
|
1503
|
+
if (process.env.OS_DISABLE_AUTHORED_ACTIONS === "1") {
|
|
1504
|
+
ctx.logger.info("[AppPlugin] OS_DISABLE_AUTHORED_ACTIONS=1 \u2014 runtime-authored action bodies will not execute");
|
|
1505
|
+
return;
|
|
1506
|
+
}
|
|
1507
|
+
let ql;
|
|
1508
|
+
try {
|
|
1509
|
+
ql = ctx.getService("objectql");
|
|
1510
|
+
} catch {
|
|
1511
|
+
return;
|
|
1512
|
+
}
|
|
1513
|
+
if (!ql || typeof ql.setDefaultActionRunner !== "function") return;
|
|
1514
|
+
if (ql._defaultActionRunner) return;
|
|
1515
|
+
ql.setDefaultActionRunner(actionBodyRunnerFactory(new QuickJSScriptRunner(), {
|
|
1516
|
+
ql,
|
|
1517
|
+
logger: ctx.logger,
|
|
1518
|
+
appId: "runtime-authored"
|
|
1519
|
+
}));
|
|
1520
|
+
ctx.logger.info("[AppPlugin] Installed default action body runner (runtime-authored actions can execute)");
|
|
1521
|
+
}
|
|
1482
1522
|
/**
|
|
1483
1523
|
* Emit a kernel hook so the control-plane `AppCatalogService` can
|
|
1484
1524
|
* upsert / delete the corresponding `sys_app` row. Silently no-ops
|
|
@@ -1793,7 +1833,7 @@ __export(index_exports, {
|
|
|
1793
1833
|
NoopMetricsRegistry: () => import_observability.NoopMetricsRegistry,
|
|
1794
1834
|
OBSERVABILITY_ERRORS_SERVICE: () => import_observability3.OBSERVABILITY_ERRORS_SERVICE,
|
|
1795
1835
|
OBSERVABILITY_METRICS_SERVICE: () => import_observability3.OBSERVABILITY_METRICS_SERVICE,
|
|
1796
|
-
ObjectKernel: () =>
|
|
1836
|
+
ObjectKernel: () => import_core6.ObjectKernel,
|
|
1797
1837
|
ObservabilityServicePlugin: () => ObservabilityServicePlugin,
|
|
1798
1838
|
QuickJSScriptRunner: () => QuickJSScriptRunner,
|
|
1799
1839
|
RUNTIME_METRICS: () => import_observability.RUNTIME_METRICS,
|
|
@@ -1835,7 +1875,7 @@ __export(index_exports, {
|
|
|
1835
1875
|
resolveRequestId: () => resolveRequestId
|
|
1836
1876
|
});
|
|
1837
1877
|
module.exports = __toCommonJS(index_exports);
|
|
1838
|
-
var
|
|
1878
|
+
var import_core6 = require("@objectstack/core");
|
|
1839
1879
|
|
|
1840
1880
|
// src/runtime.ts
|
|
1841
1881
|
var import_core = require("@objectstack/core");
|
|
@@ -2107,7 +2147,7 @@ function safeGet(ctx, name) {
|
|
|
2107
2147
|
}
|
|
2108
2148
|
|
|
2109
2149
|
// src/http-dispatcher.ts
|
|
2110
|
-
var
|
|
2150
|
+
var import_core5 = require("@objectstack/core");
|
|
2111
2151
|
var import_system = require("@objectstack/spec/system");
|
|
2112
2152
|
var import_shared2 = require("@objectstack/spec/shared");
|
|
2113
2153
|
init_package_state_store();
|
|
@@ -2142,7 +2182,7 @@ function checkApiExposure(def, action) {
|
|
|
2142
2182
|
}
|
|
2143
2183
|
|
|
2144
2184
|
// src/security/resolve-execution-context.ts
|
|
2145
|
-
var
|
|
2185
|
+
var import_core3 = require("@objectstack/core");
|
|
2146
2186
|
function toHeaders(input) {
|
|
2147
2187
|
if (!input) return new Headers();
|
|
2148
2188
|
if (typeof Headers !== "undefined" && input instanceof Headers) return input;
|
|
@@ -2171,7 +2211,7 @@ async function resolveExecutionContext(opts) {
|
|
|
2171
2211
|
return void 0;
|
|
2172
2212
|
}
|
|
2173
2213
|
};
|
|
2174
|
-
const authz = await (0,
|
|
2214
|
+
const authz = await (0, import_core3.resolveAuthzContext)({ ql, headers, getSession });
|
|
2175
2215
|
const ctx = {
|
|
2176
2216
|
roles: authz.roles,
|
|
2177
2217
|
permissions: authz.permissions,
|
|
@@ -2186,7 +2226,7 @@ async function resolveExecutionContext(opts) {
|
|
|
2186
2226
|
ctx.org_user_ids = authz.org_user_ids;
|
|
2187
2227
|
if (authz.userId) {
|
|
2188
2228
|
const settings = await Promise.resolve(opts.getService("settings")).catch(() => void 0);
|
|
2189
|
-
const localization = await (0,
|
|
2229
|
+
const localization = await (0, import_core3.resolveLocalizationContext)({
|
|
2190
2230
|
ql,
|
|
2191
2231
|
settings,
|
|
2192
2232
|
tenantId: authz.tenantId,
|
|
@@ -2205,7 +2245,7 @@ function isPermissionDeniedError(e) {
|
|
|
2205
2245
|
}
|
|
2206
2246
|
|
|
2207
2247
|
// src/security/api-key.ts
|
|
2208
|
-
var
|
|
2248
|
+
var import_core4 = require("@objectstack/core");
|
|
2209
2249
|
|
|
2210
2250
|
// src/http-dispatcher.ts
|
|
2211
2251
|
function randomUUID() {
|
|
@@ -2897,7 +2937,7 @@ var _HttpDispatcher = class _HttpDispatcher {
|
|
|
2897
2937
|
if (!ql || typeof ql.insert !== "function") {
|
|
2898
2938
|
return { handled: true, response: this.error("Data service not available", 503) };
|
|
2899
2939
|
}
|
|
2900
|
-
const generated = (0,
|
|
2940
|
+
const generated = (0, import_core4.generateApiKey)();
|
|
2901
2941
|
const row = {
|
|
2902
2942
|
name,
|
|
2903
2943
|
key: generated.hash,
|
|
@@ -2990,7 +3030,7 @@ var _HttpDispatcher = class _HttpDispatcher {
|
|
|
2990
3030
|
*/
|
|
2991
3031
|
async enforceAuthGate(context, cleanPath) {
|
|
2992
3032
|
try {
|
|
2993
|
-
if ((0,
|
|
3033
|
+
if ((0, import_core5.isAuthGateAllowlisted)(cleanPath)) return null;
|
|
2994
3034
|
const authService = await this.resolveService("auth", context.environmentId);
|
|
2995
3035
|
if (!authService || typeof authService.isAuthGateActive !== "function" || !authService.isAuthGateActive()) {
|
|
2996
3036
|
return null;
|
|
@@ -3012,7 +3052,7 @@ var _HttpDispatcher = class _HttpDispatcher {
|
|
|
3012
3052
|
return null;
|
|
3013
3053
|
}
|
|
3014
3054
|
const session = await api.getSession({ headers }).catch(() => void 0);
|
|
3015
|
-
const gate = (0,
|
|
3055
|
+
const gate = (0, import_core5.evaluateAuthGate)(session?.user, cleanPath);
|
|
3016
3056
|
if (!gate) return null;
|
|
3017
3057
|
return this.error(gate.message, 403, { code: gate.code });
|
|
3018
3058
|
} catch {
|
|
@@ -3176,7 +3216,7 @@ var _HttpDispatcher = class _HttpDispatcher {
|
|
|
3176
3216
|
return {
|
|
3177
3217
|
name: "ObjectOS",
|
|
3178
3218
|
version: "1.0.0",
|
|
3179
|
-
environment: (0,
|
|
3219
|
+
environment: (0, import_core5.getEnv)("NODE_ENV", "development"),
|
|
3180
3220
|
routes,
|
|
3181
3221
|
endpoints: routes,
|
|
3182
3222
|
// Alias for backward compatibility with some clients
|
|
@@ -3681,7 +3721,7 @@ var _HttpDispatcher = class _HttpDispatcher {
|
|
|
3681
3721
|
let translations = i18nService.getTranslations(locale);
|
|
3682
3722
|
if (Object.keys(translations).length === 0) {
|
|
3683
3723
|
const availableLocales = typeof i18nService.getLocales === "function" ? i18nService.getLocales() : [];
|
|
3684
|
-
const resolved = (0,
|
|
3724
|
+
const resolved = (0, import_core5.resolveLocale)(locale, availableLocales);
|
|
3685
3725
|
if (resolved && resolved !== locale) {
|
|
3686
3726
|
translations = i18nService.getTranslations(resolved);
|
|
3687
3727
|
return { handled: true, response: this.success({ locale: resolved, requestedLocale: locale, translations }) };
|
|
@@ -3694,7 +3734,7 @@ var _HttpDispatcher = class _HttpDispatcher {
|
|
|
3694
3734
|
let locale = parts[2] ? decodeURIComponent(parts[2]) : query?.locale;
|
|
3695
3735
|
if (!locale) return { handled: true, response: this.error("Missing locale parameter", 400) };
|
|
3696
3736
|
const availableLocales = typeof i18nService.getLocales === "function" ? i18nService.getLocales() : [];
|
|
3697
|
-
const resolved = (0,
|
|
3737
|
+
const resolved = (0, import_core5.resolveLocale)(locale, availableLocales);
|
|
3698
3738
|
if (resolved) locale = resolved;
|
|
3699
3739
|
if (typeof i18nService.getFieldLabels === "function") {
|
|
3700
3740
|
const labels2 = i18nService.getFieldLabels(objectName, locale);
|
|
@@ -4370,6 +4410,14 @@ var _HttpDispatcher = class _HttpDispatcher {
|
|
|
4370
4410
|
}
|
|
4371
4411
|
return { handled: true, response: this.success({ connectors: [], total: 0 }) };
|
|
4372
4412
|
}
|
|
4413
|
+
if (parts[0] === "_status" && parts.length === 1 && m === "GET") {
|
|
4414
|
+
const svc = automationService;
|
|
4415
|
+
if (typeof svc.getFlowRuntimeStates === "function") {
|
|
4416
|
+
const flows = svc.getFlowRuntimeStates();
|
|
4417
|
+
return { handled: true, response: this.success({ flows, total: flows.length }) };
|
|
4418
|
+
}
|
|
4419
|
+
return { handled: true, response: this.success({ flows: [], total: 0 }) };
|
|
4420
|
+
}
|
|
4373
4421
|
if (parts.length >= 1) {
|
|
4374
4422
|
const name = parts[0];
|
|
4375
4423
|
if (parts[1] === "trigger" && m === "POST") {
|
|
@@ -4662,6 +4710,9 @@ var _HttpDispatcher = class _HttpDispatcher {
|
|
|
4662
4710
|
} catch {
|
|
4663
4711
|
}
|
|
4664
4712
|
if (!aiService) {
|
|
4713
|
+
if (method === "GET" && subPath === "/ai/agents") {
|
|
4714
|
+
return { handled: true, response: { status: 200, body: { agents: [] } } };
|
|
4715
|
+
}
|
|
4665
4716
|
return {
|
|
4666
4717
|
handled: true,
|
|
4667
4718
|
response: {
|