@objectstack/runtime 6.8.0 → 6.9.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 +201 -51
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +201 -51
- package/dist/index.js.map +1 -1
- package/package.json +18 -18
package/dist/index.cjs
CHANGED
|
@@ -1468,6 +1468,66 @@ var init_app_plugin = __esm({
|
|
|
1468
1468
|
} catch (err) {
|
|
1469
1469
|
ctx.logger.error("[AppPlugin] Failed to schedule approval-process registration", err, { appId });
|
|
1470
1470
|
}
|
|
1471
|
+
try {
|
|
1472
|
+
const jobs = Array.isArray(this.bundle.jobs) ? this.bundle.jobs : Array.isArray((this.bundle.manifest || {}).jobs) ? this.bundle.manifest.jobs : [];
|
|
1473
|
+
if (jobs.length > 0) {
|
|
1474
|
+
ctx.hook("kernel:ready", async () => {
|
|
1475
|
+
let svc;
|
|
1476
|
+
try {
|
|
1477
|
+
svc = ctx.getService("job");
|
|
1478
|
+
} catch {
|
|
1479
|
+
}
|
|
1480
|
+
if (!svc || typeof svc.schedule !== "function") {
|
|
1481
|
+
ctx.logger.warn("[AppPlugin] job service not registered \u2014 skipping declarative jobs", {
|
|
1482
|
+
appId,
|
|
1483
|
+
jobCount: jobs.length
|
|
1484
|
+
});
|
|
1485
|
+
return;
|
|
1486
|
+
}
|
|
1487
|
+
const fnMap = collectBundleFunctions(this.bundle);
|
|
1488
|
+
let ok = 0;
|
|
1489
|
+
for (const job of jobs) {
|
|
1490
|
+
const jobName = job?.name;
|
|
1491
|
+
if (!jobName) {
|
|
1492
|
+
ctx.logger.warn("[AppPlugin] skipping job without name", { appId, job });
|
|
1493
|
+
continue;
|
|
1494
|
+
}
|
|
1495
|
+
if (job.enabled === false) {
|
|
1496
|
+
ctx.logger.debug("[AppPlugin] job disabled \u2014 skipping", { appId, job: jobName });
|
|
1497
|
+
continue;
|
|
1498
|
+
}
|
|
1499
|
+
const handler = fnMap[job.handler];
|
|
1500
|
+
if (typeof handler !== "function") {
|
|
1501
|
+
ctx.logger.warn("[AppPlugin] job handler not found in bundle.functions \u2014 skipping", {
|
|
1502
|
+
appId,
|
|
1503
|
+
job: jobName,
|
|
1504
|
+
handler: job.handler
|
|
1505
|
+
});
|
|
1506
|
+
continue;
|
|
1507
|
+
}
|
|
1508
|
+
try {
|
|
1509
|
+
await svc.schedule(
|
|
1510
|
+
jobName,
|
|
1511
|
+
job.schedule,
|
|
1512
|
+
async (jobCtx) => {
|
|
1513
|
+
await handler({ ...jobCtx, jobId: jobName, bundle: this.bundle });
|
|
1514
|
+
}
|
|
1515
|
+
);
|
|
1516
|
+
ok++;
|
|
1517
|
+
} catch (err) {
|
|
1518
|
+
ctx.logger.warn("[AppPlugin] Failed to schedule job", {
|
|
1519
|
+
appId,
|
|
1520
|
+
job: jobName,
|
|
1521
|
+
error: err?.message ?? String(err)
|
|
1522
|
+
});
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
ctx.logger.info("[AppPlugin] Scheduled background jobs", { appId, count: ok });
|
|
1526
|
+
});
|
|
1527
|
+
}
|
|
1528
|
+
} catch (err) {
|
|
1529
|
+
ctx.logger.error("[AppPlugin] Failed to schedule background-job registration", err, { appId });
|
|
1530
|
+
}
|
|
1471
1531
|
this.emitCatalogEvent(ctx, "app:registered", sys);
|
|
1472
1532
|
await this.loadTranslations(ctx, appId);
|
|
1473
1533
|
const seedDatasets = [];
|
|
@@ -1540,7 +1600,7 @@ var init_app_plugin = __esm({
|
|
|
1540
1600
|
} catch (e) {
|
|
1541
1601
|
ctx.logger.warn("[Seeder] Failed to register seed-datasets/seed-replayer service", { error: e?.message });
|
|
1542
1602
|
}
|
|
1543
|
-
const multiTenant = String(process.env.OS_MULTI_TENANT ?? "
|
|
1603
|
+
const multiTenant = String(process.env.OS_MULTI_TENANT ?? "false").toLowerCase() !== "false";
|
|
1544
1604
|
if (multiTenant) {
|
|
1545
1605
|
ctx.logger.info("[Seeder] multi-tenant mode \u2014 skipping inline seed; per-org replay will run on sys_organization insert");
|
|
1546
1606
|
} else {
|
|
@@ -1595,10 +1655,22 @@ var init_app_plugin = __esm({
|
|
|
1595
1655
|
};
|
|
1596
1656
|
this.bundle = bundle;
|
|
1597
1657
|
this.projectContext = projectContext;
|
|
1598
|
-
const sys = bundle
|
|
1599
|
-
const appId = sys
|
|
1658
|
+
const sys = bundle?.manifest || bundle;
|
|
1659
|
+
const appId = sys?.id || sys?.name;
|
|
1660
|
+
if (!appId) {
|
|
1661
|
+
const bundleKeys = bundle && typeof bundle === "object" ? Object.keys(bundle).slice(0, 20).join(",") : typeof bundle;
|
|
1662
|
+
const sysKeys = sys && typeof sys === "object" ? Object.keys(sys).slice(0, 20).join(",") : typeof sys;
|
|
1663
|
+
const ctxHint = projectContext ? ` projectContext=${JSON.stringify({
|
|
1664
|
+
environmentId: projectContext.environmentId,
|
|
1665
|
+
packageId: projectContext.packageId,
|
|
1666
|
+
source: projectContext.source
|
|
1667
|
+
})}` : "";
|
|
1668
|
+
throw new Error(
|
|
1669
|
+
`[AppPlugin] bundle is missing manifest.id and manifest.name \u2014 cannot register as a plugin. bundleKeys=[${bundleKeys}] sysKeys=[${sysKeys}]${ctxHint}`
|
|
1670
|
+
);
|
|
1671
|
+
}
|
|
1600
1672
|
this.name = `plugin.app.${appId}`;
|
|
1601
|
-
this.version = sys
|
|
1673
|
+
this.version = sys?.version;
|
|
1602
1674
|
}
|
|
1603
1675
|
/**
|
|
1604
1676
|
* Emit a kernel hook so the control-plane `AppCatalogService` can
|
|
@@ -2213,7 +2285,19 @@ var StandaloneStackConfigSchema = import_zod.z.object({
|
|
|
2213
2285
|
databaseAuthToken: import_zod.z.string().optional(),
|
|
2214
2286
|
databaseDriver: import_zod.z.enum(["sqlite", "sqlite-wasm", "turso", "memory", "postgres", "mongodb"]).optional(),
|
|
2215
2287
|
environmentId: import_zod.z.string().optional(),
|
|
2216
|
-
artifactPath: import_zod.z.string().optional()
|
|
2288
|
+
artifactPath: import_zod.z.string().optional(),
|
|
2289
|
+
/**
|
|
2290
|
+
* Project root directory. When set (typically by the CLI after locating
|
|
2291
|
+
* `objectstack.config.ts`), the default sqlite database is placed under
|
|
2292
|
+
* `<projectRoot>/.objectstack/data/standalone.db` instead of the global
|
|
2293
|
+
* `~/.objectstack/data/standalone.db`. This keeps per-project data
|
|
2294
|
+
* scoped to the project folder so different examples / apps don't
|
|
2295
|
+
* share a single database by accident.
|
|
2296
|
+
*
|
|
2297
|
+
* Explicit `databaseUrl` / `OS_DATABASE_URL` / `OS_HOME` still take
|
|
2298
|
+
* precedence over this default.
|
|
2299
|
+
*/
|
|
2300
|
+
projectRoot: import_zod.z.string().optional()
|
|
2217
2301
|
});
|
|
2218
2302
|
function detectDriverFromUrl(dbUrl) {
|
|
2219
2303
|
if (/^memory:\/\//i.test(dbUrl)) return "memory";
|
|
@@ -2238,7 +2322,7 @@ async function createStandaloneStack(config) {
|
|
|
2238
2322
|
const environmentId = cfg.environmentId ?? process.env.OS_ENVIRONMENT_ID ?? "proj_local";
|
|
2239
2323
|
const artifactPathInput = cfg.artifactPath ?? process.env.OS_ARTIFACT_PATH ?? (0, import_node_path2.resolve)(cwd, "dist/objectstack.json");
|
|
2240
2324
|
const artifactPath = isHttpUrl(artifactPathInput) ? artifactPathInput : artifactPathInput.startsWith("/") ? artifactPathInput : (0, import_node_path2.resolve)(cwd, artifactPathInput);
|
|
2241
|
-
const dbUrl = cfg.databaseUrl ?? process.env.OS_DATABASE_URL?.trim() ?? process.env.TURSO_DATABASE_URL?.trim() ?? `file:${(0, import_node_path2.resolve)(resolveObjectStackHome(), "data/standalone.db")}
|
|
2325
|
+
const dbUrl = cfg.databaseUrl ?? process.env.OS_DATABASE_URL?.trim() ?? process.env.TURSO_DATABASE_URL?.trim() ?? (process.env.OS_HOME?.trim() ? `file:${(0, import_node_path2.resolve)(resolveObjectStackHome(), "data/standalone.db")}` : cfg.projectRoot ? `file:${(0, import_node_path2.resolve)(cfg.projectRoot, ".objectstack/data/standalone.db")}` : `file:${(0, import_node_path2.resolve)(resolveObjectStackHome(), "data/standalone.db")}`);
|
|
2242
2326
|
const dbAuthToken = cfg.databaseAuthToken ?? process.env.OS_DATABASE_AUTH_TOKEN?.trim() ?? process.env.TURSO_AUTH_TOKEN?.trim();
|
|
2243
2327
|
const explicitDriver = cfg.databaseDriver ?? process.env.OS_DATABASE_DRIVER?.trim();
|
|
2244
2328
|
const dbDriver = explicitDriver ?? detectDriverFromUrl(dbUrl);
|
|
@@ -2456,6 +2540,13 @@ function toHeaders(input) {
|
|
|
2456
2540
|
}
|
|
2457
2541
|
return h;
|
|
2458
2542
|
}
|
|
2543
|
+
function safeJsonParse2(s, fallback) {
|
|
2544
|
+
try {
|
|
2545
|
+
return JSON.parse(s);
|
|
2546
|
+
} catch {
|
|
2547
|
+
return fallback;
|
|
2548
|
+
}
|
|
2549
|
+
}
|
|
2459
2550
|
async function tryFind(ql, object, where, limit = 100) {
|
|
2460
2551
|
if (!ql || typeof ql.find !== "function") return [];
|
|
2461
2552
|
try {
|
|
@@ -2471,6 +2562,7 @@ async function resolveExecutionContext(opts) {
|
|
|
2471
2562
|
const ctx = {
|
|
2472
2563
|
roles: [],
|
|
2473
2564
|
permissions: [],
|
|
2565
|
+
systemPermissions: [],
|
|
2474
2566
|
isSystem: false
|
|
2475
2567
|
};
|
|
2476
2568
|
let userId;
|
|
@@ -2508,8 +2600,12 @@ async function resolveExecutionContext(opts) {
|
|
|
2508
2600
|
if (!userId) {
|
|
2509
2601
|
try {
|
|
2510
2602
|
const authService = await opts.getService("auth");
|
|
2603
|
+
let api = authService?.api;
|
|
2604
|
+
if (!api && typeof authService?.getApi === "function") {
|
|
2605
|
+
api = await authService.getApi();
|
|
2606
|
+
}
|
|
2511
2607
|
const headersInstance = toHeaders(headers);
|
|
2512
|
-
const sessionData = await
|
|
2608
|
+
const sessionData = await api?.getSession?.({ headers: headersInstance });
|
|
2513
2609
|
userId = sessionData?.user?.id ?? sessionData?.session?.userId;
|
|
2514
2610
|
tenantId = tenantId ?? sessionData?.session?.activeOrganizationId;
|
|
2515
2611
|
ctx.accessToken = sessionData?.session?.token ?? ctx.accessToken;
|
|
@@ -2579,10 +2675,38 @@ async function resolveExecutionContext(opts) {
|
|
|
2579
2675
|
{ id: { $in: Array.from(psIds) } },
|
|
2580
2676
|
500
|
|
2581
2677
|
);
|
|
2678
|
+
const tabRank = {
|
|
2679
|
+
hidden: 0,
|
|
2680
|
+
default_off: 1,
|
|
2681
|
+
default_on: 2,
|
|
2682
|
+
visible: 3
|
|
2683
|
+
};
|
|
2684
|
+
const mergedTabs = {};
|
|
2582
2685
|
for (const ps of psRows) {
|
|
2583
2686
|
if (ps.name && !ctx.permissions.includes(ps.name)) {
|
|
2584
2687
|
ctx.permissions.push(ps.name);
|
|
2585
2688
|
}
|
|
2689
|
+
const sysPerms = typeof ps.system_permissions === "string" ? safeJsonParse2(ps.system_permissions, []) : ps.system_permissions ?? ps.systemPermissions;
|
|
2690
|
+
if (Array.isArray(sysPerms)) {
|
|
2691
|
+
for (const p of sysPerms) {
|
|
2692
|
+
if (typeof p === "string" && !ctx.systemPermissions.includes(p)) {
|
|
2693
|
+
ctx.systemPermissions.push(p);
|
|
2694
|
+
}
|
|
2695
|
+
}
|
|
2696
|
+
}
|
|
2697
|
+
const tabs = typeof ps.tab_permissions === "string" ? safeJsonParse2(ps.tab_permissions, {}) : ps.tab_permissions ?? ps.tabPermissions;
|
|
2698
|
+
if (tabs && typeof tabs === "object") {
|
|
2699
|
+
for (const [app, val] of Object.entries(tabs)) {
|
|
2700
|
+
if (typeof val !== "string" || !(val in tabRank)) continue;
|
|
2701
|
+
const cur = mergedTabs[app];
|
|
2702
|
+
if (!cur || tabRank[val] > tabRank[cur]) {
|
|
2703
|
+
mergedTabs[app] = val;
|
|
2704
|
+
}
|
|
2705
|
+
}
|
|
2706
|
+
}
|
|
2707
|
+
}
|
|
2708
|
+
if (Object.keys(mergedTabs).length > 0) {
|
|
2709
|
+
ctx.tabPermissions = mergedTabs;
|
|
2586
2710
|
}
|
|
2587
2711
|
}
|
|
2588
2712
|
return ctx;
|
|
@@ -5326,7 +5450,7 @@ var _HttpDispatcher = class _HttpDispatcher {
|
|
|
5326
5450
|
* Handle AI service routes (/ai/chat, /ai/models, /ai/conversations, etc.)
|
|
5327
5451
|
* Resolves the AI service and its built-in route handlers, then dispatches.
|
|
5328
5452
|
*/
|
|
5329
|
-
async handleAI(subPath, method, body, query,
|
|
5453
|
+
async handleAI(subPath, method, body, query, context) {
|
|
5330
5454
|
let aiService;
|
|
5331
5455
|
try {
|
|
5332
5456
|
aiService = await this.resolveService("ai");
|
|
@@ -5370,7 +5494,23 @@ var _HttpDispatcher = class _HttpDispatcher {
|
|
|
5370
5494
|
if (route.method !== method) continue;
|
|
5371
5495
|
const params = matchRoute(route.path, fullPath);
|
|
5372
5496
|
if (params === null) continue;
|
|
5373
|
-
const
|
|
5497
|
+
const ec = context.executionContext;
|
|
5498
|
+
const user = ec?.userId ? {
|
|
5499
|
+
userId: ec.userId,
|
|
5500
|
+
id: ec.userId,
|
|
5501
|
+
displayName: ec.userDisplayName ?? ec.userName ?? ec.userId,
|
|
5502
|
+
email: ec.userEmail,
|
|
5503
|
+
roles: Array.isArray(ec.roles) ? ec.roles : [],
|
|
5504
|
+
permissions: Array.isArray(ec.permissions) ? ec.permissions : [],
|
|
5505
|
+
organizationId: ec.tenantId
|
|
5506
|
+
} : void 0;
|
|
5507
|
+
const result = await route.handler({
|
|
5508
|
+
body,
|
|
5509
|
+
params,
|
|
5510
|
+
query,
|
|
5511
|
+
headers: context.request?.headers,
|
|
5512
|
+
user
|
|
5513
|
+
});
|
|
5374
5514
|
if (result.stream && result.events) {
|
|
5375
5515
|
return {
|
|
5376
5516
|
handled: true,
|
|
@@ -5865,13 +6005,22 @@ function resolveErrorReporter(ctx, override) {
|
|
|
5865
6005
|
}
|
|
5866
6006
|
|
|
5867
6007
|
// src/dispatcher-plugin.ts
|
|
5868
|
-
function mountRouteOnServer(route, server, routePath, securityHeaders) {
|
|
6008
|
+
function mountRouteOnServer(route, server, routePath, securityHeaders, resolveUser) {
|
|
5869
6009
|
const handler = async (req, res) => {
|
|
5870
6010
|
try {
|
|
6011
|
+
let user;
|
|
6012
|
+
if (resolveUser) {
|
|
6013
|
+
try {
|
|
6014
|
+
user = await resolveUser(req.headers ?? {});
|
|
6015
|
+
} catch {
|
|
6016
|
+
}
|
|
6017
|
+
}
|
|
5871
6018
|
const result = await route.handler({
|
|
5872
6019
|
body: req.body,
|
|
5873
6020
|
params: req.params,
|
|
5874
|
-
query: req.query
|
|
6021
|
+
query: req.query,
|
|
6022
|
+
headers: req.headers,
|
|
6023
|
+
user
|
|
5875
6024
|
});
|
|
5876
6025
|
if (result.stream && result.events) {
|
|
5877
6026
|
res.status(result.status);
|
|
@@ -6608,6 +6757,32 @@ function createDispatcherPlugin(config = {}) {
|
|
|
6608
6757
|
}
|
|
6609
6758
|
}
|
|
6610
6759
|
ctx.logger.info("Dispatcher bridge routes registered", { prefix, enableProjectScoping, projectResolution });
|
|
6760
|
+
const resolveRequestUser = async (headers) => {
|
|
6761
|
+
try {
|
|
6762
|
+
const authService = ctx.getService("auth");
|
|
6763
|
+
if (!authService) return void 0;
|
|
6764
|
+
let api = authService.api;
|
|
6765
|
+
if (!api && typeof authService.getApi === "function") {
|
|
6766
|
+
api = await authService.getApi();
|
|
6767
|
+
}
|
|
6768
|
+
if (!api?.getSession) return void 0;
|
|
6769
|
+
const headersInstance = headers instanceof Headers ? headers : new Headers(headers);
|
|
6770
|
+
const sessionData = await api.getSession({ headers: headersInstance });
|
|
6771
|
+
const userId = sessionData?.user?.id ?? sessionData?.session?.userId;
|
|
6772
|
+
if (!userId) return void 0;
|
|
6773
|
+
return {
|
|
6774
|
+
userId,
|
|
6775
|
+
id: userId,
|
|
6776
|
+
displayName: sessionData?.user?.name ?? sessionData?.user?.email ?? userId,
|
|
6777
|
+
email: sessionData?.user?.email,
|
|
6778
|
+
roles: [],
|
|
6779
|
+
permissions: [],
|
|
6780
|
+
organizationId: sessionData?.session?.activeOrganizationId
|
|
6781
|
+
};
|
|
6782
|
+
} catch {
|
|
6783
|
+
return void 0;
|
|
6784
|
+
}
|
|
6785
|
+
};
|
|
6611
6786
|
const toScopedPath = (routePath) => {
|
|
6612
6787
|
if (routePath.startsWith(prefix)) {
|
|
6613
6788
|
const tail = routePath.slice(prefix.length);
|
|
@@ -6620,11 +6795,11 @@ function createDispatcherPlugin(config = {}) {
|
|
|
6620
6795
|
const routePath = route.path.startsWith("/api/v1") ? route.path : `${prefix}${route.path}`;
|
|
6621
6796
|
let count = 0;
|
|
6622
6797
|
if (enableProjectScoping && projectResolution === "required") {
|
|
6623
|
-
if (mountRouteOnServer(route, server, toScopedPath(routePath), securityHeaders)) count++;
|
|
6798
|
+
if (mountRouteOnServer(route, server, toScopedPath(routePath), securityHeaders, resolveRequestUser)) count++;
|
|
6624
6799
|
} else {
|
|
6625
|
-
if (mountRouteOnServer(route, server, routePath, securityHeaders)) count++;
|
|
6800
|
+
if (mountRouteOnServer(route, server, routePath, securityHeaders, resolveRequestUser)) count++;
|
|
6626
6801
|
if (enableProjectScoping) {
|
|
6627
|
-
if (mountRouteOnServer(route, server, toScopedPath(routePath), securityHeaders)) count++;
|
|
6802
|
+
if (mountRouteOnServer(route, server, toScopedPath(routePath), securityHeaders, resolveRequestUser)) count++;
|
|
6628
6803
|
}
|
|
6629
6804
|
}
|
|
6630
6805
|
return count;
|
|
@@ -7686,39 +7861,7 @@ var ArtifactKernelFactory = class {
|
|
|
7686
7861
|
// intentionally do NOT pass crossSubDomainCookies here
|
|
7687
7862
|
// so cookies stay isolated per project subdomain.
|
|
7688
7863
|
trustedOrigins: trustedOriginsList.length ? trustedOriginsList : void 0,
|
|
7689
|
-
...oidcProviders ? { oidcProviders } : {}
|
|
7690
|
-
// Auto-provision a personal organization for every new
|
|
7691
|
-
// user. SecurityPlugin's ObjectQL middleware does this
|
|
7692
|
-
// for direct `ql.insert` calls, but better-auth's
|
|
7693
|
-
// adapter writes through `dataEngine` directly,
|
|
7694
|
-
// bypassing that middleware — so JIT-created SSO users
|
|
7695
|
-
// would otherwise land on the empty "create
|
|
7696
|
-
// organization" screen on first login.
|
|
7697
|
-
databaseHooks: {
|
|
7698
|
-
user: {
|
|
7699
|
-
create: {
|
|
7700
|
-
after: async (user) => {
|
|
7701
|
-
try {
|
|
7702
|
-
const ql = kernel.getService("objectql");
|
|
7703
|
-
if (!ql) return;
|
|
7704
|
-
const [{ ensureUserHasOrganization, cloneTenantSeedData }] = await Promise.all([
|
|
7705
|
-
import("@objectstack/plugin-security")
|
|
7706
|
-
]);
|
|
7707
|
-
await ensureUserHasOrganization(ql, user, {
|
|
7708
|
-
logger: this.logger,
|
|
7709
|
-
cloneSeedData: cloneTenantSeedData
|
|
7710
|
-
});
|
|
7711
|
-
} catch (e) {
|
|
7712
|
-
this.logger.warn?.("[ArtifactKernelFactory] auto-org provisioning hook failed", {
|
|
7713
|
-
environmentId,
|
|
7714
|
-
userId: user?.id,
|
|
7715
|
-
error: e?.message
|
|
7716
|
-
});
|
|
7717
|
-
}
|
|
7718
|
-
}
|
|
7719
|
-
}
|
|
7720
|
-
}
|
|
7721
|
-
}
|
|
7864
|
+
...oidcProviders ? { oidcProviders } : {}
|
|
7722
7865
|
}));
|
|
7723
7866
|
if (oidcProviders) {
|
|
7724
7867
|
this.logger.info?.("[ArtifactKernelFactory] platform SSO wired", {
|
|
@@ -7737,7 +7880,7 @@ var ArtifactKernelFactory = class {
|
|
|
7737
7880
|
}
|
|
7738
7881
|
try {
|
|
7739
7882
|
const { SecurityPlugin } = await import("@objectstack/plugin-security");
|
|
7740
|
-
const multiTenant = String(process.env.OS_MULTI_TENANT ?? "
|
|
7883
|
+
const multiTenant = String(process.env.OS_MULTI_TENANT ?? "false").toLowerCase() !== "false";
|
|
7741
7884
|
await kernel.use(new SecurityPlugin({ multiTenant }));
|
|
7742
7885
|
} catch (err) {
|
|
7743
7886
|
this.logger.warn?.("[ArtifactKernelFactory] SecurityPlugin not registered", {
|
|
@@ -7746,8 +7889,15 @@ var ArtifactKernelFactory = class {
|
|
|
7746
7889
|
});
|
|
7747
7890
|
}
|
|
7748
7891
|
const projectName = project.hostname ?? environmentId;
|
|
7749
|
-
const
|
|
7750
|
-
const
|
|
7892
|
+
const artifactAny = artifact;
|
|
7893
|
+
const topLevelManifest = artifactAny?.manifest && typeof artifactAny.manifest === "object" ? artifactAny.manifest : null;
|
|
7894
|
+
const topLevelFunctions = Array.isArray(artifactAny?.functions) ? artifactAny.functions : [];
|
|
7895
|
+
const bundle = {
|
|
7896
|
+
...artifact.metadata ?? {},
|
|
7897
|
+
...topLevelManifest ? { manifest: topLevelManifest } : {},
|
|
7898
|
+
functions: topLevelFunctions
|
|
7899
|
+
};
|
|
7900
|
+
const sys = bundle.manifest ?? bundle;
|
|
7751
7901
|
const packageId = sys?.packageId ?? sys?.package_id ?? bundle?.packageId;
|
|
7752
7902
|
const i18nCfg = bundle?.i18n ?? sys?.i18n ?? {};
|
|
7753
7903
|
const trArr = Array.isArray(bundle?.translations) ? bundle.translations : Array.isArray(sys?.translations) ? sys.translations : [];
|
|
@@ -9015,7 +9165,7 @@ var MarketplaceInstallLocalPlugin = class {
|
|
|
9015
9165
|
}
|
|
9016
9166
|
}
|
|
9017
9167
|
if (opts.seedNow && datasets.length > 0) {
|
|
9018
|
-
const multiTenant = String(process.env.OS_MULTI_TENANT ?? "
|
|
9168
|
+
const multiTenant = String(process.env.OS_MULTI_TENANT ?? "false").toLowerCase() !== "false";
|
|
9019
9169
|
try {
|
|
9020
9170
|
const ql = ctx.getService("objectql");
|
|
9021
9171
|
let metadata;
|