@objectstack/runtime 5.1.0 → 5.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 CHANGED
@@ -175,6 +175,10 @@ var init_driver_plugin = __esm({
175
175
  });
176
176
 
177
177
  // src/seed-loader.ts
178
+ var seed_loader_exports = {};
179
+ __export(seed_loader_exports, {
180
+ SeedLoaderService: () => SeedLoaderService
181
+ });
178
182
  var import_data, import_formula, DEFAULT_EXTERNAL_ID_FIELD, _SeedLoaderService, SeedLoaderService;
179
183
  var init_seed_loader = __esm({
180
184
  "src/seed-loader.ts"() {
@@ -910,7 +914,7 @@ var init_quickjs_runner = __esm({
910
914
  evalRes.value.dispose();
911
915
  let pumps = 0;
912
916
  while (pumps < 1e3) {
913
- await new Promise((resolve) => setImmediate(resolve));
917
+ await new Promise((resolve2) => setImmediate(resolve2));
914
918
  const pending = runtime.executePendingJobs();
915
919
  if (pending.error) {
916
920
  const err = vm.dump(pending.error);
@@ -9194,7 +9198,7 @@ var require_utils = __commonJS({
9194
9198
  }
9195
9199
  }
9196
9200
  function get(url, options = {}) {
9197
- return new Promise((resolve, reject) => {
9201
+ return new Promise((resolve2, reject) => {
9198
9202
  let timeoutId;
9199
9203
  const request = http.get(url, options, (response) => {
9200
9204
  response.setEncoding("utf8");
@@ -9202,7 +9206,7 @@ var require_utils = __commonJS({
9202
9206
  response.on("data", (chunk) => body += chunk);
9203
9207
  response.on("end", () => {
9204
9208
  (0, timers_1.clearTimeout)(timeoutId);
9205
- resolve({ status: response.statusCode, body });
9209
+ resolve2({ status: response.statusCode, body });
9206
9210
  });
9207
9211
  }).on("error", (error2) => {
9208
9212
  (0, timers_1.clearTimeout)(timeoutId);
@@ -9221,13 +9225,13 @@ var require_utils = __commonJS({
9221
9225
  return host && match.test(host.toLowerCase()) ? true : false;
9222
9226
  }
9223
9227
  function promiseWithResolvers() {
9224
- let resolve;
9228
+ let resolve2;
9225
9229
  let reject;
9226
9230
  const promise = new Promise(function withResolversExecutor(promiseResolve, promiseReject) {
9227
- resolve = promiseResolve;
9231
+ resolve2 = promiseResolve;
9228
9232
  reject = promiseReject;
9229
9233
  });
9230
- return { promise, resolve, reject };
9234
+ return { promise, resolve: resolve2, reject };
9231
9235
  }
9232
9236
  function squashError(_error) {
9233
9237
  return;
@@ -9238,8 +9242,8 @@ var require_utils = __commonJS({
9238
9242
  exports2.randomBytes = randomBytes;
9239
9243
  async function once(ee, name, options) {
9240
9244
  options?.signal?.throwIfAborted();
9241
- const { promise, resolve, reject } = promiseWithResolvers();
9242
- const onEvent = (data) => resolve(data);
9245
+ const { promise, resolve: resolve2, reject } = promiseWithResolvers();
9246
+ const onEvent = (data) => resolve2(data);
9243
9247
  const onError = (error2) => reject(error2);
9244
9248
  const abortListener = addAbortListener(options?.signal, function() {
9245
9249
  reject(this.reason);
@@ -11840,13 +11844,13 @@ var require_mongo_logger = __commonJS({
11840
11844
  function createStdioLogger(stream) {
11841
11845
  return {
11842
11846
  write: (log) => {
11843
- return new Promise((resolve, reject) => {
11847
+ return new Promise((resolve2, reject) => {
11844
11848
  const logLine = (0, util_1.inspect)(log, { compact: true, breakLength: Infinity });
11845
11849
  stream.write(`${logLine}
11846
11850
  `, "utf-8", (error2) => {
11847
11851
  if (error2)
11848
11852
  return reject(error2);
11849
- resolve(true);
11853
+ resolve2(true);
11850
11854
  });
11851
11855
  });
11852
11856
  }
@@ -22621,20 +22625,20 @@ var require_compression = __commonJS({
22621
22625
  ]);
22622
22626
  var ZSTD_COMPRESSION_LEVEL = 3;
22623
22627
  var zlibInflate = (buf) => {
22624
- return new Promise((resolve, reject) => {
22628
+ return new Promise((resolve2, reject) => {
22625
22629
  zlib.inflate(buf, (error2, result) => {
22626
22630
  if (error2)
22627
22631
  return reject(error2);
22628
- resolve(result);
22632
+ resolve2(result);
22629
22633
  });
22630
22634
  });
22631
22635
  };
22632
22636
  var zlibDeflate = (buf, options) => {
22633
- return new Promise((resolve, reject) => {
22637
+ return new Promise((resolve2, reject) => {
22634
22638
  zlib.deflate(buf, options, (error2, result) => {
22635
22639
  if (error2)
22636
22640
  return reject(error2);
22637
- resolve(result);
22641
+ resolve2(result);
22638
22642
  });
22639
22643
  });
22640
22644
  };
@@ -23355,7 +23359,7 @@ var require_state_machine = __commonJS({
23355
23359
  socket = tls.connect(socketOptions, () => {
23356
23360
  socket.write(message);
23357
23361
  });
23358
- const { promise: willResolveKmsRequest, reject: rejectOnTlsSocketError, resolve } = (0, utils_1.promiseWithResolvers)();
23362
+ const { promise: willResolveKmsRequest, reject: rejectOnTlsSocketError, resolve: resolve2 } = (0, utils_1.promiseWithResolvers)();
23359
23363
  abortListener = (0, utils_1.addAbortListener)(options?.signal, function() {
23360
23364
  destroySockets();
23361
23365
  rejectOnTlsSocketError(this.reason);
@@ -23367,7 +23371,7 @@ var require_state_machine = __commonJS({
23367
23371
  request.addResponse(buffer.read(bytesNeeded));
23368
23372
  }
23369
23373
  if (request.bytesNeeded <= 0) {
23370
- resolve();
23374
+ resolve2();
23371
23375
  }
23372
23376
  });
23373
23377
  await (options?.timeoutContext?.csotEnabled() ? Promise.all([
@@ -24948,8 +24952,8 @@ var require_on_data = __commonJS({
24948
24952
  }
24949
24953
  if (finished)
24950
24954
  return closeHandler();
24951
- const { promise, resolve, reject } = (0, utils_1.promiseWithResolvers)();
24952
- unconsumedPromises.push({ resolve, reject });
24955
+ const { promise, resolve: resolve2, reject } = (0, utils_1.promiseWithResolvers)();
24956
+ unconsumedPromises.push({ resolve: resolve2, reject });
24953
24957
  return promise;
24954
24958
  },
24955
24959
  return() {
@@ -26116,13 +26120,13 @@ var require_connect = __commonJS({
26116
26120
  socket.setNoDelay(noDelay);
26117
26121
  socket.setTimeout(connectTimeoutMS);
26118
26122
  let cancellationHandler = null;
26119
- const { promise: connectedSocket, resolve, reject } = (0, utils_1.promiseWithResolvers)();
26123
+ const { promise: connectedSocket, resolve: resolve2, reject } = (0, utils_1.promiseWithResolvers)();
26120
26124
  if (existingSocket) {
26121
- resolve(socket);
26125
+ resolve2(socket);
26122
26126
  } else {
26123
26127
  const start = performance.now();
26124
26128
  const connectEvent = useTLS ? "secureConnect" : "connect";
26125
- socket.once(connectEvent, () => resolve(socket)).once("error", (cause) => reject(new error_1.MongoNetworkError(error_1.MongoError.buildErrorMessage(cause), { cause }))).once("timeout", () => {
26129
+ socket.once(connectEvent, () => resolve2(socket)).once("error", (cause) => reject(new error_1.MongoNetworkError(error_1.MongoError.buildErrorMessage(cause), { cause }))).once("timeout", () => {
26126
26130
  reject(new error_1.MongoNetworkTimeoutError(`Socket '${connectEvent}' timed out after ${performance.now() - start | 0}ms (connectTimeoutMS: ${connectTimeoutMS})`));
26127
26131
  }).once("close", () => reject(new error_1.MongoNetworkError(`Socket closed after ${performance.now() - start | 0} during connection establishment`)));
26128
26132
  if (options.cancellationToken != null) {
@@ -26646,10 +26650,10 @@ var require_connection_pool = __commonJS({
26646
26650
  async checkOut(options) {
26647
26651
  const checkoutTime = (0, utils_1.processTimeMS)();
26648
26652
  this.emitAndLog(_ConnectionPool.CONNECTION_CHECK_OUT_STARTED, new connection_pool_events_1.ConnectionCheckOutStartedEvent(this));
26649
- const { promise, resolve, reject } = (0, utils_1.promiseWithResolvers)();
26653
+ const { promise, resolve: resolve2, reject } = (0, utils_1.promiseWithResolvers)();
26650
26654
  const timeout = options.timeoutContext.connectionCheckoutTimeout;
26651
26655
  const waitQueueMember = {
26652
- resolve,
26656
+ resolve: resolve2,
26653
26657
  reject,
26654
26658
  cancelled: false,
26655
26659
  checkoutTime
@@ -27884,13 +27888,13 @@ var require_connection_string = __commonJS({
27884
27888
  var LB_REPLICA_SET_ERROR = "loadBalanced option not supported with a replicaSet option";
27885
27889
  var LB_DIRECT_CONNECTION_ERROR = "loadBalanced option not supported when directConnection is provided";
27886
27890
  function retryDNSTimeoutFor(rrtype) {
27887
- const resolve = rrtype === "SRV" ? (address) => dns.promises.resolve(address, "SRV") : (address) => dns.promises.resolve(address, "TXT");
27891
+ const resolve2 = rrtype === "SRV" ? (address) => dns.promises.resolve(address, "SRV") : (address) => dns.promises.resolve(address, "TXT");
27888
27892
  return async function dnsReqRetryTimeout(lookupAddress) {
27889
27893
  try {
27890
- return await resolve(lookupAddress);
27894
+ return await resolve2(lookupAddress);
27891
27895
  } catch (firstDNSError) {
27892
27896
  if (firstDNSError.code === dns.TIMEOUT) {
27893
- return await resolve(lookupAddress);
27897
+ return await resolve2(lookupAddress);
27894
27898
  } else {
27895
27899
  throw firstDNSError;
27896
27900
  }
@@ -31529,13 +31533,13 @@ var require_topology = __commonJS({
31529
31533
  }
31530
31534
  return transaction.server;
31531
31535
  }
31532
- const { promise: serverPromise, resolve, reject } = (0, utils_1.promiseWithResolvers)();
31536
+ const { promise: serverPromise, resolve: resolve2, reject } = (0, utils_1.promiseWithResolvers)();
31533
31537
  const waitQueueMember = {
31534
31538
  serverSelector,
31535
31539
  topologyDescription: this.description,
31536
31540
  mongoLogger: this.client.mongoLogger,
31537
31541
  transaction,
31538
- resolve,
31542
+ resolve: resolve2,
31539
31543
  reject,
31540
31544
  cancelled: false,
31541
31545
  startTime: (0, utils_1.processTimeMS)(),
@@ -35157,6 +35161,7 @@ __export(index_exports, {
35157
35161
  ArtifactEnvironmentRegistry: () => ArtifactEnvironmentRegistry,
35158
35162
  ArtifactKernelFactory: () => ArtifactKernelFactory,
35159
35163
  AuthProxyPlugin: () => AuthProxyPlugin,
35164
+ DEFAULT_CLOUD_URL: () => DEFAULT_CLOUD_URL,
35160
35165
  DEFAULT_RATE_LIMITS: () => DEFAULT_RATE_LIMITS,
35161
35166
  DriverPlugin: () => DriverPlugin,
35162
35167
  FileArtifactApiClient: () => FileArtifactApiClient,
@@ -35165,10 +35170,15 @@ __export(index_exports, {
35165
35170
  InMemoryErrorReporter: () => import_observability2.InMemoryErrorReporter,
35166
35171
  InMemoryMetricsRegistry: () => import_observability.InMemoryMetricsRegistry,
35167
35172
  KernelManager: () => KernelManager,
35173
+ MarketplaceInstallLocalPlugin: () => MarketplaceInstallLocalPlugin,
35174
+ MarketplaceProxyPlugin: () => MarketplaceProxyPlugin,
35168
35175
  MiddlewareManager: () => MiddlewareManager,
35169
35176
  NoopErrorReporter: () => import_observability2.NoopErrorReporter,
35170
35177
  NoopMetricsRegistry: () => import_observability.NoopMetricsRegistry,
35178
+ OBSERVABILITY_ERRORS_SERVICE: () => import_observability3.OBSERVABILITY_ERRORS_SERVICE,
35179
+ OBSERVABILITY_METRICS_SERVICE: () => import_observability3.OBSERVABILITY_METRICS_SERVICE,
35171
35180
  ObjectKernel: () => import_core4.ObjectKernel,
35181
+ ObservabilityServicePlugin: () => ObservabilityServicePlugin,
35172
35182
  PLATFORM_SSO_PROVIDER_ID: () => PLATFORM_SSO_PROVIDER_ID,
35173
35183
  QuickJSScriptRunner: () => QuickJSScriptRunner,
35174
35184
  RUNTIME_METRICS: () => import_observability.RUNTIME_METRICS,
@@ -35205,7 +35215,10 @@ __export(index_exports, {
35205
35215
  mergeRuntimeModule: () => mergeRuntimeModule,
35206
35216
  parseTraceparent: () => parseTraceparent,
35207
35217
  readArtifactSource: () => readArtifactSource,
35218
+ resolveCloudUrl: () => resolveCloudUrl,
35208
35219
  resolveDefaultArtifactPath: () => resolveDefaultArtifactPath,
35220
+ resolveErrorReporter: () => resolveErrorReporter,
35221
+ resolveMetrics: () => resolveMetrics,
35209
35222
  resolveRequestId: () => resolveRequestId,
35210
35223
  seedPlatformSsoClient: () => seedPlatformSsoClient
35211
35224
  });
@@ -35214,12 +35227,25 @@ var import_core4 = require("@objectstack/core");
35214
35227
 
35215
35228
  // src/runtime.ts
35216
35229
  var import_core = require("@objectstack/core");
35230
+ var import_service_cluster = require("@objectstack/service-cluster");
35217
35231
  var Runtime = class {
35218
35232
  constructor(config = {}) {
35219
35233
  this.kernel = new import_core.ObjectKernel(config.kernel);
35220
35234
  if (config.server) {
35221
35235
  this.kernel.registerService("http.server", config.server);
35222
35236
  }
35237
+ if (config.cluster !== false) {
35238
+ const opts = this.normalizeClusterOptions(config.cluster);
35239
+ this.kernel.use(new import_service_cluster.ClusterServicePlugin(opts));
35240
+ this.kernel.use(new import_service_cluster.MetadataClusterBridgePlugin());
35241
+ }
35242
+ }
35243
+ normalizeClusterOptions(raw) {
35244
+ if (!raw) return {};
35245
+ if (typeof raw === "object" && ("cluster" in raw || "config" in raw) && !("driver" in raw)) {
35246
+ return raw;
35247
+ }
35248
+ return { config: raw };
35223
35249
  }
35224
35250
  /**
35225
35251
  * Register a plugin
@@ -35521,6 +35547,23 @@ async function resolveExecutionContext(opts) {
35521
35547
  }
35522
35548
  }
35523
35549
  }
35550
+ if (tenantId) {
35551
+ const orgMembers = await tryFind(
35552
+ ql,
35553
+ "sys_member",
35554
+ { organization_id: tenantId },
35555
+ 1e3
35556
+ );
35557
+ const orgUserIds = Array.from(
35558
+ new Set(
35559
+ orgMembers.map((m) => m.user_id ?? m.userId).filter((v) => typeof v === "string" && v.length > 0)
35560
+ )
35561
+ );
35562
+ if (!orgUserIds.includes(userId)) orgUserIds.push(userId);
35563
+ ctx.org_user_ids = orgUserIds;
35564
+ } else {
35565
+ ctx.org_user_ids = [userId];
35566
+ }
35524
35567
  const upsRows = await tryFind(
35525
35568
  ql,
35526
35569
  "sys_user_permission_set",
@@ -38788,6 +38831,44 @@ function safeReport(reporter, err, ctx) {
38788
38831
  }
38789
38832
  }
38790
38833
 
38834
+ // src/observability/observability-service-plugin.ts
38835
+ var import_observability3 = require("@objectstack/observability");
38836
+ var ObservabilityServicePlugin = class {
38837
+ constructor(options = {}) {
38838
+ this.name = "com.objectstack.observability.service";
38839
+ this.version = "1.0.0";
38840
+ this.type = "standard";
38841
+ this.options = options;
38842
+ }
38843
+ async init(ctx) {
38844
+ const metrics = this.options.metrics ?? new import_observability.NoopMetricsRegistry();
38845
+ const errors2 = this.options.errors ?? new import_observability2.NoopErrorReporter();
38846
+ ctx.registerService(import_observability3.OBSERVABILITY_METRICS_SERVICE, metrics);
38847
+ ctx.registerService(import_observability3.OBSERVABILITY_ERRORS_SERVICE, errors2);
38848
+ ctx.logger.info(
38849
+ `ObservabilityServicePlugin: registered metrics=${metrics.constructor?.name ?? "unknown"} errors=${errors2.constructor?.name ?? "unknown"}`
38850
+ );
38851
+ }
38852
+ };
38853
+ function resolveMetrics(ctx, override) {
38854
+ if (override) return override;
38855
+ try {
38856
+ const m = ctx.getService(import_observability3.OBSERVABILITY_METRICS_SERVICE);
38857
+ if (m) return m;
38858
+ } catch {
38859
+ }
38860
+ return new import_observability.NoopMetricsRegistry();
38861
+ }
38862
+ function resolveErrorReporter(ctx, override) {
38863
+ if (override) return override;
38864
+ try {
38865
+ const e = ctx.getService(import_observability3.OBSERVABILITY_ERRORS_SERVICE);
38866
+ if (e) return e;
38867
+ } catch {
38868
+ }
38869
+ return new import_observability2.NoopErrorReporter();
38870
+ }
38871
+
38791
38872
  // src/dispatcher-plugin.ts
38792
38873
  function mountRouteOnServer(route, server, routePath, securityHeaders) {
38793
38874
  const handler = async (req, res) => {
@@ -40511,7 +40592,39 @@ var ArtifactKernelFactory = class {
40511
40592
  // intentionally do NOT pass crossSubDomainCookies here
40512
40593
  // so cookies stay isolated per project subdomain.
40513
40594
  trustedOrigins: trustedOriginsList.length ? trustedOriginsList : void 0,
40514
- ...oidcProviders ? { oidcProviders } : {}
40595
+ ...oidcProviders ? { oidcProviders } : {},
40596
+ // Auto-provision a personal organization for every new
40597
+ // user. SecurityPlugin's ObjectQL middleware does this
40598
+ // for direct `ql.insert` calls, but better-auth's
40599
+ // adapter writes through `dataEngine` directly,
40600
+ // bypassing that middleware — so JIT-created SSO users
40601
+ // would otherwise land on the empty "create
40602
+ // organization" screen on first login.
40603
+ databaseHooks: {
40604
+ user: {
40605
+ create: {
40606
+ after: async (user) => {
40607
+ try {
40608
+ const ql = kernel.getService("objectql");
40609
+ if (!ql) return;
40610
+ const [{ ensureUserHasOrganization, cloneTenantSeedData }] = await Promise.all([
40611
+ import("@objectstack/plugin-security")
40612
+ ]);
40613
+ await ensureUserHasOrganization(ql, user, {
40614
+ logger: this.logger,
40615
+ cloneSeedData: cloneTenantSeedData
40616
+ });
40617
+ } catch (e) {
40618
+ this.logger.warn?.("[ArtifactKernelFactory] auto-org provisioning hook failed", {
40619
+ projectId,
40620
+ userId: user?.id,
40621
+ error: e?.message
40622
+ });
40623
+ }
40624
+ }
40625
+ }
40626
+ }
40627
+ }
40515
40628
  }));
40516
40629
  if (oidcProviders) {
40517
40630
  this.logger.info?.("[ArtifactKernelFactory] platform SSO wired", {
@@ -40904,6 +41017,114 @@ var AuthProxyPlugin = class {
40904
41017
  }
40905
41018
  };
40906
41019
 
41020
+ // src/cloud/cloud-url.ts
41021
+ var DEFAULT_CLOUD_URL = "https://cloud.objectos.app";
41022
+ function resolveCloudUrl(explicit) {
41023
+ const raw = (explicit ?? process.env.OS_CLOUD_URL ?? "").trim();
41024
+ const lower = raw.toLowerCase();
41025
+ if (lower === "off" || lower === "none" || lower === "local" || lower === "disabled") {
41026
+ return "";
41027
+ }
41028
+ const picked = raw || DEFAULT_CLOUD_URL;
41029
+ return picked.replace(/\/+$/, "");
41030
+ }
41031
+
41032
+ // src/cloud/marketplace-proxy-plugin.ts
41033
+ var MARKETPLACE_PREFIX = "/api/v1/marketplace";
41034
+ var MarketplaceProxyPlugin = class _MarketplaceProxyPlugin {
41035
+ constructor(config = {}) {
41036
+ this.name = "com.objectstack.runtime.marketplace-proxy";
41037
+ this.version = "1.0.0";
41038
+ this.init = async (_ctx) => {
41039
+ };
41040
+ this.start = async (ctx) => {
41041
+ ctx.hook("kernel:ready", async () => {
41042
+ let httpServer;
41043
+ try {
41044
+ httpServer = ctx.getService("http-server");
41045
+ } catch {
41046
+ ctx.logger?.warn?.("[MarketplaceProxyPlugin] http-server not available \u2014 marketplace routes not mounted");
41047
+ return;
41048
+ }
41049
+ if (!httpServer || typeof httpServer.getRawApp !== "function") {
41050
+ ctx.logger?.warn?.("[MarketplaceProxyPlugin] http-server missing getRawApp() \u2014 marketplace routes not mounted");
41051
+ return;
41052
+ }
41053
+ const rawApp = httpServer.getRawApp();
41054
+ const cloudUrl = this.cloudUrl;
41055
+ const handler = async (c, next) => {
41056
+ if (!cloudUrl) {
41057
+ return c.json({
41058
+ success: false,
41059
+ error: {
41060
+ code: "marketplace_unavailable",
41061
+ message: "No control-plane URL configured for this runtime (OS_CLOUD_URL)."
41062
+ }
41063
+ }, 503);
41064
+ }
41065
+ try {
41066
+ const incomingUrl = new URL(c.req.url);
41067
+ if (incomingUrl.pathname.startsWith(`${MARKETPLACE_PREFIX}/install-local`)) {
41068
+ return next();
41069
+ }
41070
+ const target = `${cloudUrl}${incomingUrl.pathname}${incomingUrl.search}`;
41071
+ const method = String(c.req.method ?? "GET").toUpperCase();
41072
+ if (method !== "GET" && method !== "HEAD") {
41073
+ return c.json({
41074
+ success: false,
41075
+ error: {
41076
+ code: "marketplace_method_not_allowed",
41077
+ message: `Marketplace proxy only forwards GET/HEAD; install via cloud.`
41078
+ }
41079
+ }, 405);
41080
+ }
41081
+ const resp = await fetch(target, {
41082
+ method,
41083
+ headers: {
41084
+ // Strip the inbound Host header — fetch will set
41085
+ // it to the cloud host. Forward only the
41086
+ // identifying headers cloud might log.
41087
+ "Accept": c.req.header("accept") ?? "application/json",
41088
+ "User-Agent": `objectos-marketplace-proxy/${_MarketplaceProxyPlugin.prototype.version ?? "1.0.0"}`
41089
+ }
41090
+ });
41091
+ const headers = new Headers();
41092
+ const passthroughHeaders = ["content-type", "cache-control", "etag", "last-modified"];
41093
+ for (const h of passthroughHeaders) {
41094
+ const v = resp.headers.get(h);
41095
+ if (v) headers.set(h, v);
41096
+ }
41097
+ const body = await resp.arrayBuffer();
41098
+ return new Response(body, { status: resp.status, headers });
41099
+ } catch (err) {
41100
+ const errObj = err instanceof Error ? err : new Error(err?.message ?? String(err));
41101
+ ctx.logger?.error?.("[MarketplaceProxyPlugin] proxy failed", errObj);
41102
+ return c.json({
41103
+ success: false,
41104
+ error: {
41105
+ code: "marketplace_proxy_failed",
41106
+ message: err?.message ?? String(err)
41107
+ }
41108
+ }, 502);
41109
+ }
41110
+ };
41111
+ if (typeof rawApp.all === "function") {
41112
+ rawApp.all(`${MARKETPLACE_PREFIX}/*`, handler);
41113
+ } else {
41114
+ for (const m of ["get", "head"]) {
41115
+ try {
41116
+ rawApp[m]?.(`${MARKETPLACE_PREFIX}/*`, handler);
41117
+ } catch {
41118
+ }
41119
+ }
41120
+ }
41121
+ ctx.logger?.info?.(`[MarketplaceProxyPlugin] mounted at ${MARKETPLACE_PREFIX}/* \u2192 ${cloudUrl || "(unconfigured)"}`);
41122
+ });
41123
+ };
41124
+ this.cloudUrl = resolveCloudUrl(config.controlPlaneUrl);
41125
+ }
41126
+ };
41127
+
40907
41128
  // src/cloud/file-artifact-api-client.ts
40908
41129
  var import_promises2 = require("fs/promises");
40909
41130
  var import_node_path5 = require("path");
@@ -41130,7 +41351,7 @@ async function createObjectOSStack(config) {
41130
41351
  };
41131
41352
  const enginePlugins = await createHostEnginePlugins();
41132
41353
  return {
41133
- plugins: [...enginePlugins, new ObjectOSProjectPlugin(merged), new AuthProxyPlugin()],
41354
+ plugins: [...enginePlugins, new ObjectOSProjectPlugin(merged), new AuthProxyPlugin(), new MarketplaceProxyPlugin({ controlPlaneUrl: merged.controlPlaneUrl === "file" ? void 0 : merged.controlPlaneUrl })],
41134
41355
  api: {
41135
41356
  enableProjectScoping: true,
41136
41357
  projectResolution: "auto",
@@ -41144,6 +41365,462 @@ async function createObjectOSStack(config) {
41144
41365
  };
41145
41366
  }
41146
41367
 
41368
+ // src/cloud/marketplace-install-local-plugin.ts
41369
+ var import_node_fs3 = require("fs");
41370
+ var import_node_path6 = require("path");
41371
+ var ROUTE_BASE = "/api/v1/marketplace/install-local";
41372
+ var DEFAULT_DIR = ".objectstack/installed-packages";
41373
+ function safeFilename(manifestId) {
41374
+ return manifestId.replace(/[^a-zA-Z0-9._-]/g, "_") + ".json";
41375
+ }
41376
+ var MarketplaceInstallLocalPlugin = class {
41377
+ constructor(config = {}) {
41378
+ this.name = "com.objectstack.runtime.marketplace-install-local";
41379
+ this.version = "1.0.0";
41380
+ this.init = async (_ctx) => {
41381
+ };
41382
+ this.start = async (ctx) => {
41383
+ ctx.hook("kernel:ready", async () => {
41384
+ await this.rehydrate(ctx);
41385
+ let httpServer;
41386
+ try {
41387
+ httpServer = ctx.getService("http-server");
41388
+ } catch {
41389
+ ctx.logger?.warn?.("[MarketplaceInstallLocal] http-server not available \u2014 install endpoints not mounted");
41390
+ return;
41391
+ }
41392
+ if (!httpServer || typeof httpServer.getRawApp !== "function") {
41393
+ ctx.logger?.warn?.("[MarketplaceInstallLocal] http-server missing getRawApp() \u2014 install endpoints not mounted");
41394
+ return;
41395
+ }
41396
+ const rawApp = httpServer.getRawApp();
41397
+ const postHandler = async (c) => this.handleInstall(c, ctx);
41398
+ const getHandler = async (c) => this.handleList(c);
41399
+ const deleteHandler = async (c) => this.handleUninstall(c, ctx);
41400
+ if (typeof rawApp.post === "function") rawApp.post(ROUTE_BASE, postHandler);
41401
+ if (typeof rawApp.get === "function") rawApp.get(ROUTE_BASE, getHandler);
41402
+ if (typeof rawApp.delete === "function") rawApp.delete(`${ROUTE_BASE}/:manifestId`, deleteHandler);
41403
+ ctx.logger?.info?.(`[MarketplaceInstallLocal] mounted at ${ROUTE_BASE} (storage: ${this.storageDir})`);
41404
+ });
41405
+ };
41406
+ /**
41407
+ * Re-register every cached manifest with the kernel's manifest service.
41408
+ * Safe to call on a kernel that already has the same manifest_id (the
41409
+ * underlying ObjectQL registry overwrites by id, but we still warn so
41410
+ * a developer can spot the dev-time clash between their config.ts and
41411
+ * a marketplace package).
41412
+ */
41413
+ this.rehydrate = async (ctx) => {
41414
+ const entries = this.readAll();
41415
+ if (entries.length === 0) return;
41416
+ let manifestService = null;
41417
+ try {
41418
+ manifestService = ctx.getService("manifest");
41419
+ } catch {
41420
+ ctx.logger?.warn?.("[MarketplaceInstallLocal] no `manifest` service \u2014 rehydrate skipped");
41421
+ return;
41422
+ }
41423
+ for (const entry of entries) {
41424
+ try {
41425
+ manifestService.register(entry.manifest);
41426
+ try {
41427
+ const ql = ctx.getService("objectql");
41428
+ if (ql && typeof ql.syncSchemas === "function") await ql.syncSchemas();
41429
+ } catch {
41430
+ }
41431
+ await this.applySideEffects(ctx, entry.manifest, { seedNow: false });
41432
+ ctx.logger?.info?.(`[MarketplaceInstallLocal] rehydrated ${entry.manifestId}@${entry.version}`);
41433
+ } catch (err) {
41434
+ ctx.logger?.error?.(`[MarketplaceInstallLocal] rehydrate failed for ${entry.manifestId}`, err instanceof Error ? err : new Error(String(err)));
41435
+ }
41436
+ }
41437
+ };
41438
+ this.handleInstall = async (c, ctx) => {
41439
+ if (!this.cloudUrl) {
41440
+ return c.json({ success: false, error: { code: "marketplace_unavailable", message: "OS_CLOUD_URL not configured." } }, 503);
41441
+ }
41442
+ const userId = await this.requireAuthenticatedUser(c, ctx);
41443
+ if (!userId) {
41444
+ return c.json({ success: false, error: { code: "unauthorized", message: "Authentication required to install packages." } }, 401);
41445
+ }
41446
+ let body = {};
41447
+ try {
41448
+ body = await c.req.json();
41449
+ } catch {
41450
+ }
41451
+ const packageId = String(body?.packageId ?? "").trim();
41452
+ const versionId = String(body?.versionId ?? "latest").trim() || "latest";
41453
+ if (!packageId) {
41454
+ return c.json({ success: false, error: { code: "bad_request", message: "packageId is required." } }, 400);
41455
+ }
41456
+ let payload;
41457
+ try {
41458
+ const url = `${this.cloudUrl}/api/v1/marketplace/packages/${encodeURIComponent(packageId)}/versions/${encodeURIComponent(versionId)}/manifest`;
41459
+ const resp = await fetch(url, { headers: { "Accept": "application/json" } });
41460
+ if (!resp.ok) {
41461
+ const text = await resp.text().catch(() => "");
41462
+ return c.json({
41463
+ success: false,
41464
+ error: { code: "cloud_fetch_failed", message: `Cloud returned ${resp.status}: ${text.slice(0, 200)}` }
41465
+ }, resp.status === 404 ? 404 : 502);
41466
+ }
41467
+ payload = await resp.json();
41468
+ } catch (err) {
41469
+ return c.json({
41470
+ success: false,
41471
+ error: { code: "cloud_fetch_failed", message: err?.message ?? String(err) }
41472
+ }, 502);
41473
+ }
41474
+ const data = payload?.data ?? payload;
41475
+ const manifest = data?.manifest;
41476
+ const resolvedVersionId = String(data?.version_id ?? versionId);
41477
+ const version = String(data?.version ?? "unknown");
41478
+ const manifestId = String(manifest?.id ?? manifest?.name ?? "");
41479
+ if (!manifest || !manifestId) {
41480
+ return c.json({ success: false, error: { code: "invalid_manifest", message: "Cloud returned an invalid manifest payload." } }, 502);
41481
+ }
41482
+ const conflict = this.findConflict(ctx, manifestId);
41483
+ if (conflict === "user-code") {
41484
+ return c.json({
41485
+ success: false,
41486
+ error: {
41487
+ code: "manifest_conflict",
41488
+ message: `manifest_id "${manifestId}" is already defined by this runtime's local code. Refusing to overwrite. Uninstall the local definition first.`
41489
+ }
41490
+ }, 409);
41491
+ }
41492
+ const entry = {
41493
+ packageId,
41494
+ versionId: resolvedVersionId,
41495
+ manifestId,
41496
+ version,
41497
+ manifest,
41498
+ installedAt: (/* @__PURE__ */ new Date()).toISOString(),
41499
+ installedBy: userId
41500
+ };
41501
+ try {
41502
+ (0, import_node_fs3.mkdirSync)(this.storageDir, { recursive: true });
41503
+ (0, import_node_fs3.writeFileSync)((0, import_node_path6.join)(this.storageDir, safeFilename(manifestId)), JSON.stringify(entry, null, 2), "utf8");
41504
+ } catch (err) {
41505
+ return c.json({
41506
+ success: false,
41507
+ error: { code: "storage_failed", message: `Failed to persist manifest: ${err?.message ?? err}` }
41508
+ }, 500);
41509
+ }
41510
+ try {
41511
+ const manifestService = ctx.getService("manifest");
41512
+ manifestService.register(manifest);
41513
+ } catch (err) {
41514
+ ctx.logger?.warn?.(`[MarketplaceInstallLocal] hot-register failed for ${manifestId} (will load on next restart): ${err?.message ?? err}`);
41515
+ }
41516
+ try {
41517
+ const ql = ctx.getService("objectql");
41518
+ if (ql && typeof ql.syncSchemas === "function") {
41519
+ await ql.syncSchemas();
41520
+ ctx.logger?.info?.(`[MarketplaceInstallLocal] syncSchemas() ran after registering ${manifestId}`);
41521
+ }
41522
+ } catch (err) {
41523
+ ctx.logger?.warn?.(`[MarketplaceInstallLocal] syncSchemas failed for ${manifestId}: ${err?.message ?? err}`);
41524
+ }
41525
+ const seededSummary = await this.applySideEffects(ctx, manifest, { seedNow: true, c });
41526
+ return c.json({
41527
+ success: true,
41528
+ data: {
41529
+ manifestId,
41530
+ version,
41531
+ versionId: resolvedVersionId,
41532
+ installedAt: entry.installedAt,
41533
+ hotLoaded: true,
41534
+ upgradedFrom: conflict === "marketplace" ? "previous-marketplace-version" : null,
41535
+ translationsLoaded: seededSummary.translationsLoaded,
41536
+ seeded: seededSummary.seeded,
41537
+ note: "App is now available in this runtime. Refresh the console to see it in the app switcher."
41538
+ }
41539
+ }, 200);
41540
+ };
41541
+ this.handleList = async (c) => {
41542
+ const entries = this.readAll();
41543
+ return c.json({
41544
+ success: true,
41545
+ data: {
41546
+ items: entries.map((e) => ({
41547
+ packageId: e.packageId,
41548
+ versionId: e.versionId,
41549
+ manifestId: e.manifestId,
41550
+ version: e.version,
41551
+ installedAt: e.installedAt,
41552
+ installedBy: e.installedBy
41553
+ })),
41554
+ total: entries.length,
41555
+ storageDir: this.storageDir
41556
+ }
41557
+ }, 200);
41558
+ };
41559
+ this.handleUninstall = async (c, ctx) => {
41560
+ const userId = await this.requireAuthenticatedUser(c, ctx);
41561
+ if (!userId) {
41562
+ return c.json({ success: false, error: { code: "unauthorized", message: "Authentication required." } }, 401);
41563
+ }
41564
+ const manifestId = String(c.req.param?.("manifestId") ?? c.req.params?.manifestId ?? "").trim();
41565
+ if (!manifestId) {
41566
+ return c.json({ success: false, error: { code: "bad_request", message: "manifestId path param required." } }, 400);
41567
+ }
41568
+ const file = (0, import_node_path6.join)(this.storageDir, safeFilename(manifestId));
41569
+ if (!(0, import_node_fs3.existsSync)(file)) {
41570
+ return c.json({ success: false, error: { code: "not_found", message: `No marketplace install for ${manifestId}.` } }, 404);
41571
+ }
41572
+ try {
41573
+ (0, import_node_fs3.unlinkSync)(file);
41574
+ } catch (err) {
41575
+ return c.json({ success: false, error: { code: "storage_failed", message: err?.message ?? String(err) } }, 500);
41576
+ }
41577
+ ctx.logger?.info?.(`[MarketplaceInstallLocal] uninstalled ${manifestId} (cached manifest removed; restart runtime to unload from running kernel)`);
41578
+ return c.json({
41579
+ success: true,
41580
+ data: {
41581
+ manifestId,
41582
+ note: "Cached manifest removed. The app remains loaded in the running kernel until the next restart (the kernel API does not support unregistering apps in-place)."
41583
+ }
41584
+ }, 200);
41585
+ };
41586
+ /**
41587
+ * Detect whether `manifestId` is already known to the kernel and classify
41588
+ * the source so we can refuse vs upgrade gracefully.
41589
+ *
41590
+ * 'none' — fresh install
41591
+ * 'marketplace' — previously installed by this plugin (allow upgrade)
41592
+ * 'user-code' — defined by AppPlugin from objectstack.config.ts
41593
+ * (refuse to avoid silently overwriting authored code)
41594
+ */
41595
+ this.findConflict = (ctx, manifestId) => {
41596
+ if ((0, import_node_fs3.existsSync)((0, import_node_path6.join)(this.storageDir, safeFilename(manifestId)))) {
41597
+ return "marketplace";
41598
+ }
41599
+ try {
41600
+ const ql = ctx.getService("objectql");
41601
+ const packages = ql?.registry?.getAllPackages?.() ?? [];
41602
+ const hit = packages.find(
41603
+ (p) => (p?.manifest?.id ?? p?.id ?? p?.manifest?.name) === manifestId
41604
+ );
41605
+ if (hit) return "user-code";
41606
+ } catch {
41607
+ }
41608
+ return "none";
41609
+ };
41610
+ /**
41611
+ * Pull a userId out of the request's better-auth session, if any.
41612
+ * Returns null when there is no signed-in user. v1 does not check
41613
+ * admin role — UI gating + the auth requirement is sufficient for
41614
+ * dev / single-tenant runtimes. Stricter checks can be layered on
41615
+ * via a middleware in cloud-hosted multi-tenant deployments.
41616
+ */
41617
+ /**
41618
+ * Replicate the start-time side-effects that AppPlugin runs for
41619
+ * statically-declared apps but the `manifest` service does NOT:
41620
+ *
41621
+ * 1. Load `manifest.translations` (array of `Record<locale, data>`)
41622
+ * into the i18n service — auto-creating an in-memory fallback if
41623
+ * none is registered, matching AppPlugin's behaviour.
41624
+ *
41625
+ * 2. Merge `manifest.data` (an array of seed datasets) into the
41626
+ * kernel's `seed-datasets` service so SecurityPlugin's per-org
41627
+ * replay middleware picks them up on every future
41628
+ * sys_organization insert.
41629
+ *
41630
+ * 3. When `seedNow=true`, also run the seed immediately so the user
41631
+ * sees demo data without having to create a new org:
41632
+ * • single-tenant: run SeedLoaderService inline (mirrors
41633
+ * AppPlugin single-tenant branch)
41634
+ * • multi-tenant: invoke `seed-replayer` for the caller's
41635
+ * active org (resolved from the request session)
41636
+ *
41637
+ * Errors are logged but never thrown — install succeeds even if
41638
+ * post-register side-effects partially fail (the manifest itself is
41639
+ * already registered + cached). Returns a small summary for the
41640
+ * response envelope.
41641
+ */
41642
+ this.applySideEffects = async (ctx, manifest, opts) => {
41643
+ const appId = String(manifest?.id ?? "unknown");
41644
+ let translationsLoaded = 0;
41645
+ let seedSummary = { mode: "skipped", reason: "no-datasets" };
41646
+ try {
41647
+ const bundles = [];
41648
+ if (Array.isArray(manifest?.translations)) bundles.push(...manifest.translations);
41649
+ if (Array.isArray(manifest?.i18n)) bundles.push(...manifest.i18n);
41650
+ if (bundles.length > 0) {
41651
+ let i18nService;
41652
+ try {
41653
+ i18nService = ctx.getService("i18n");
41654
+ } catch {
41655
+ }
41656
+ if (!i18nService) {
41657
+ try {
41658
+ const mod = await import("@objectstack/core");
41659
+ const createMemoryI18n = mod.createMemoryI18n;
41660
+ if (typeof createMemoryI18n === "function") {
41661
+ i18nService = createMemoryI18n();
41662
+ ctx.registerService?.("i18n", i18nService);
41663
+ ctx.logger?.info?.(`[MarketplaceInstallLocal] auto-registered in-memory i18n fallback for "${appId}"`);
41664
+ }
41665
+ } catch {
41666
+ }
41667
+ }
41668
+ if (i18nService?.loadTranslations) {
41669
+ for (const bundle of bundles) {
41670
+ for (const [locale, data] of Object.entries(bundle)) {
41671
+ if (data && typeof data === "object") {
41672
+ try {
41673
+ i18nService.loadTranslations(locale, data);
41674
+ translationsLoaded++;
41675
+ } catch (err) {
41676
+ ctx.logger?.warn?.(`[MarketplaceInstallLocal] failed to load ${appId} translations for ${locale}: ${err?.message ?? err}`);
41677
+ }
41678
+ }
41679
+ }
41680
+ }
41681
+ ctx.logger?.info?.(`[MarketplaceInstallLocal] loaded ${translationsLoaded} locale bundle(s) for ${appId}`);
41682
+ }
41683
+ }
41684
+ } catch (err) {
41685
+ ctx.logger?.warn?.(`[MarketplaceInstallLocal] i18n side-effect failed for ${appId}: ${err?.message ?? err}`);
41686
+ }
41687
+ const datasets = Array.isArray(manifest?.data) ? manifest.data.filter((d) => d && d.object && Array.isArray(d.records)) : [];
41688
+ if (datasets.length > 0) {
41689
+ try {
41690
+ const kernel = ctx.kernel;
41691
+ let existing = [];
41692
+ try {
41693
+ const v = kernel?.getService?.("seed-datasets");
41694
+ if (Array.isArray(v)) existing = v;
41695
+ } catch {
41696
+ }
41697
+ const merged = [...existing, ...datasets];
41698
+ if (kernel?.registerService) kernel.registerService("seed-datasets", merged);
41699
+ else ctx.registerService?.("seed-datasets", merged);
41700
+ ctx.logger?.info?.(`[MarketplaceInstallLocal] merged ${datasets.length} seed dataset(s) into kernel (total: ${merged.length})`);
41701
+ } catch (err) {
41702
+ ctx.logger?.warn?.(`[MarketplaceInstallLocal] failed to merge seed-datasets: ${err?.message ?? err}`);
41703
+ }
41704
+ }
41705
+ if (opts.seedNow && datasets.length > 0) {
41706
+ const multiTenant = String(process.env.OS_MULTI_TENANT ?? "true").toLowerCase() !== "false";
41707
+ try {
41708
+ const ql = ctx.getService("objectql");
41709
+ let metadata;
41710
+ try {
41711
+ metadata = ctx.getService("metadata");
41712
+ } catch {
41713
+ }
41714
+ if (!ql || !metadata) {
41715
+ seedSummary = { mode: "skipped", reason: "objectql-or-metadata-missing" };
41716
+ } else {
41717
+ let organizationId;
41718
+ if (multiTenant) {
41719
+ const resolved = await this.resolveActiveOrgId(opts.c, ctx);
41720
+ if (resolved) organizationId = resolved;
41721
+ else {
41722
+ seedSummary = { mode: "skipped", reason: "multi-tenant-no-active-org" };
41723
+ ctx.logger?.warn?.("[MarketplaceInstallLocal] multi-tenant: no active org on request \u2014 data not seeded");
41724
+ }
41725
+ }
41726
+ if (!multiTenant || organizationId) {
41727
+ const [{ SeedLoaderService: SeedLoaderService2 }, { SeedLoaderRequestSchema }] = await Promise.all([
41728
+ Promise.resolve().then(() => (init_seed_loader(), seed_loader_exports)),
41729
+ import("@objectstack/spec/data")
41730
+ ]);
41731
+ const seedLoader = new SeedLoaderService2(ql, metadata, ctx.logger);
41732
+ const request = SeedLoaderRequestSchema.parse({
41733
+ datasets,
41734
+ config: {
41735
+ defaultMode: "upsert",
41736
+ multiPass: true,
41737
+ ...organizationId ? { organizationId } : {}
41738
+ }
41739
+ });
41740
+ const result = await seedLoader.load(request);
41741
+ seedSummary = {
41742
+ mode: "inline",
41743
+ inserted: result.summary.totalInserted,
41744
+ updated: result.summary.totalUpdated,
41745
+ errors: result.errors.length
41746
+ };
41747
+ ctx.logger?.info?.(`[MarketplaceInstallLocal] inline seed for ${appId}${organizationId ? ` (org=${organizationId})` : ""}: inserted=${seedSummary.inserted} updated=${seedSummary.updated} errors=${seedSummary.errors}`);
41748
+ }
41749
+ }
41750
+ } catch (err) {
41751
+ seedSummary = { mode: "skipped", reason: `seed-error: ${err?.message ?? err}` };
41752
+ ctx.logger?.warn?.(`[MarketplaceInstallLocal] seed run failed for ${appId}: ${err?.message ?? err}`);
41753
+ }
41754
+ }
41755
+ return { translationsLoaded, seeded: seedSummary };
41756
+ };
41757
+ /**
41758
+ * Best-effort active-org resolution. Reads the better-auth session
41759
+ * (same path as requireAuthenticatedUser) and returns
41760
+ * `session.activeOrganizationId`, falling back to the user's first
41761
+ * org membership.
41762
+ */
41763
+ this.resolveActiveOrgId = async (c, ctx) => {
41764
+ if (!c?.req?.raw?.headers) return null;
41765
+ try {
41766
+ const authService = ctx.getService("auth");
41767
+ let api = authService?.api;
41768
+ if (!api && typeof authService?.getApi === "function") api = await authService.getApi();
41769
+ if (!api?.getSession) return null;
41770
+ const session = await api.getSession({ headers: c.req.raw.headers });
41771
+ const direct = session?.session?.activeOrganizationId ?? session?.activeOrganizationId ?? null;
41772
+ if (direct) return String(direct);
41773
+ const userId = session?.user?.id;
41774
+ if (!userId) return null;
41775
+ try {
41776
+ const ql = ctx.getService("objectql");
41777
+ if (ql?.find) {
41778
+ const rows = await ql.find("sys_organization_member", { where: { user_id: userId }, limit: 1, context: { isSystem: true } });
41779
+ const row = Array.isArray(rows) ? rows[0] : rows?.items?.[0] ?? null;
41780
+ return row?.organization_id ? String(row.organization_id) : null;
41781
+ }
41782
+ } catch {
41783
+ }
41784
+ } catch {
41785
+ }
41786
+ return null;
41787
+ };
41788
+ this.requireAuthenticatedUser = async (c, ctx) => {
41789
+ try {
41790
+ const authService = ctx.getService("auth");
41791
+ let api = authService?.api;
41792
+ if (!api && typeof authService?.getApi === "function") {
41793
+ api = await authService.getApi();
41794
+ }
41795
+ if (api?.getSession && c?.req?.raw?.headers) {
41796
+ const session = await api.getSession({ headers: c.req.raw.headers });
41797
+ const userId = session?.user?.id ?? null;
41798
+ if (userId) return String(userId);
41799
+ }
41800
+ } catch {
41801
+ }
41802
+ const xUserId = c?.req?.header?.("x-user-id");
41803
+ if (xUserId) return String(xUserId);
41804
+ return null;
41805
+ };
41806
+ this.readAll = () => {
41807
+ if (!(0, import_node_fs3.existsSync)(this.storageDir)) return [];
41808
+ const out = [];
41809
+ for (const name of (0, import_node_fs3.readdirSync)(this.storageDir)) {
41810
+ if (!name.endsWith(".json")) continue;
41811
+ try {
41812
+ const raw = (0, import_node_fs3.readFileSync)((0, import_node_path6.join)(this.storageDir, name), "utf8");
41813
+ out.push(JSON.parse(raw));
41814
+ } catch {
41815
+ }
41816
+ }
41817
+ return out;
41818
+ };
41819
+ this.cloudUrl = resolveCloudUrl(config.controlPlaneUrl);
41820
+ this.storageDir = config.storageDir ? (0, import_node_path6.resolve)(config.storageDir) : (0, import_node_path6.resolve)(process.cwd(), DEFAULT_DIR);
41821
+ }
41822
+ };
41823
+
41147
41824
  // src/index.ts
41148
41825
  init_platform_sso();
41149
41826
 
@@ -41179,6 +41856,7 @@ __reExport(index_exports, require("@objectstack/core"), module.exports);
41179
41856
  ArtifactEnvironmentRegistry,
41180
41857
  ArtifactKernelFactory,
41181
41858
  AuthProxyPlugin,
41859
+ DEFAULT_CLOUD_URL,
41182
41860
  DEFAULT_RATE_LIMITS,
41183
41861
  DriverPlugin,
41184
41862
  FileArtifactApiClient,
@@ -41187,10 +41865,15 @@ __reExport(index_exports, require("@objectstack/core"), module.exports);
41187
41865
  InMemoryErrorReporter,
41188
41866
  InMemoryMetricsRegistry,
41189
41867
  KernelManager,
41868
+ MarketplaceInstallLocalPlugin,
41869
+ MarketplaceProxyPlugin,
41190
41870
  MiddlewareManager,
41191
41871
  NoopErrorReporter,
41192
41872
  NoopMetricsRegistry,
41873
+ OBSERVABILITY_ERRORS_SERVICE,
41874
+ OBSERVABILITY_METRICS_SERVICE,
41193
41875
  ObjectKernel,
41876
+ ObservabilityServicePlugin,
41194
41877
  PLATFORM_SSO_PROVIDER_ID,
41195
41878
  QuickJSScriptRunner,
41196
41879
  RUNTIME_METRICS,
@@ -41227,7 +41910,10 @@ __reExport(index_exports, require("@objectstack/core"), module.exports);
41227
41910
  mergeRuntimeModule,
41228
41911
  parseTraceparent,
41229
41912
  readArtifactSource,
41913
+ resolveCloudUrl,
41230
41914
  resolveDefaultArtifactPath,
41915
+ resolveErrorReporter,
41916
+ resolveMetrics,
41231
41917
  resolveRequestId,
41232
41918
  seedPlatformSsoClient,
41233
41919
  ...require("@objectstack/core")