@camstack/system 1.2.7 → 1.2.8

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.
Files changed (48) hide show
  1. package/dist/addon-runner.js +2 -2
  2. package/dist/addon-runner.mjs +2 -2
  3. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  4. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  5. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  6. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  7. package/dist/builtins/alerts/alerts.addon.js +1 -1
  8. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  9. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
  10. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
  11. package/dist/builtins/console-logging/index.js +1 -1
  12. package/dist/builtins/console-logging/index.mjs +1 -1
  13. package/dist/builtins/device-manager/device-manager.addon.js +1 -1
  14. package/dist/builtins/device-manager/device-manager.addon.mjs +1 -1
  15. package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
  16. package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
  17. package/dist/builtins/hub-forwarder/index.js +1 -1
  18. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  19. package/dist/builtins/local-auth/local-auth.addon.js +1 -1
  20. package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
  21. package/dist/builtins/local-network/local-network.addon.js +1 -1
  22. package/dist/builtins/local-network/local-network.addon.mjs +1 -1
  23. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  24. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  25. package/dist/builtins/platform-probe/index.js +1 -1
  26. package/dist/builtins/platform-probe/index.mjs +1 -1
  27. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  28. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  29. package/dist/builtins/snapshot/index.js +1 -1
  30. package/dist/builtins/snapshot/index.mjs +1 -1
  31. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  32. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  33. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +1 -1
  34. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +1 -1
  35. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
  36. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
  37. package/dist/builtins/system-config/system-config.addon.js +1 -1
  38. package/dist/builtins/system-config/system-config.addon.mjs +1 -1
  39. package/dist/builtins/winston-logging/index.js +1 -1
  40. package/dist/builtins/winston-logging/index.mjs +1 -1
  41. package/dist/{dist-DEkwmyIj.js → dist-CdgScQ3H.js} +291 -1
  42. package/dist/{dist-CfcmjXSI.mjs → dist-CxM20CkF.mjs} +291 -1
  43. package/dist/index.js +56 -6
  44. package/dist/index.mjs +56 -6
  45. package/dist/kernel/cap-router-builder.d.ts +18 -1
  46. package/dist/{manifest-python-deps-DIrBiAMS.js → manifest-python-deps-CUHn5wqq.js} +1 -1
  47. package/dist/{manifest-python-deps-QqIGHGMJ.mjs → manifest-python-deps-CcW0WpfS.mjs} +1 -1
  48. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_chunk = require("./chunk-Cek0wNdY.js");
3
- const require_dist = require("./dist-DEkwmyIj.js");
3
+ const require_dist = require("./dist-CdgScQ3H.js");
4
4
  const require_model_download_service = require("./model-download-service-hf0ookyy.js");
5
- const require_manifest_python_deps = require("./manifest-python-deps-DIrBiAMS.js");
5
+ const require_manifest_python_deps = require("./manifest-python-deps-CUHn5wqq.js");
6
6
  const require_resource_monitor = require("./resource-monitor-DNNomR-i.js");
7
7
  const require_builtins_sqlite_storage_filesystem_storage_addon = require("./builtins/sqlite-storage/filesystem-storage.addon.js");
8
8
  const require_builtins_sqlite_storage_sqlite_settings_addon = require("./builtins/sqlite-storage/sqlite-settings.addon.js");
@@ -5378,10 +5378,48 @@ function methodsFor(def) {
5378
5378
  auth: m.auth ?? "protected",
5379
5379
  schema: m,
5380
5380
  isVoid: require_dist.isVoidInput(m.input),
5381
- isObject: require_dist.isObjectInput(m.input)
5381
+ isObject: require_dist.isObjectInput(m.input),
5382
+ callerRequired: m.caller === "required"
5382
5383
  };
5383
5384
  });
5384
5385
  }
5386
+ /**
5387
+ * Extract the authenticated caller identity from the (structurally
5388
+ * unknown) tRPC context. The builder cannot import the server's
5389
+ * `TrpcContext`, so the read is narrowing-based: `ctx.user.id` (string)
5390
+ * + `ctx.user.isAdmin` (boolean) — the stable `AuthenticatedUser` core
5391
+ * every context factory produces. Returns null when no authenticated
5392
+ * user is present (the caller then fails the call — a fabricated
5393
+ * identity is never injected).
5394
+ */
5395
+ function extractCallerIdentity(ctx) {
5396
+ if (ctx === null || typeof ctx !== "object" || !("user" in ctx)) return null;
5397
+ const user = ctx.user;
5398
+ if (user === null || typeof user !== "object") return null;
5399
+ if (!("id" in user) || !("isAdmin" in user)) return null;
5400
+ const id = user.id;
5401
+ const isAdmin = user.isAdmin;
5402
+ if (typeof id !== "string" || id.length === 0 || typeof isAdmin !== "boolean") return null;
5403
+ return {
5404
+ userId: id,
5405
+ isAdmin
5406
+ };
5407
+ }
5408
+ /**
5409
+ * Return a NEW input object carrying the server-derived `caller`. The
5410
+ * spread-then-set ordering guarantees any client-supplied `caller` key
5411
+ * (which survives the `.loose()` wire parse) is overwritten. Raises
5412
+ * UNAUTHORIZED (or `badRequest` on a skewed services object without the
5413
+ * `unauthorized` raiser) when the context has no authenticated user.
5414
+ */
5415
+ function injectCaller(rest, ctx, capName, methodName, services) {
5416
+ const caller = extractCallerIdentity(ctx);
5417
+ if (caller === null) return (services.unauthorized ?? services.badRequest)(`Capability "${capName}.${methodName}" requires an authenticated caller`);
5418
+ return {
5419
+ ...rest,
5420
+ caller
5421
+ };
5422
+ }
5385
5423
  /** Strip a set of selector keys from an input object, returning a NEW object. */
5386
5424
  function stripKeys(input, keys) {
5387
5425
  const src = input ?? {};
@@ -5422,6 +5460,9 @@ function requireLocal(capName, getLocal, services) {
5422
5460
  * Build a single capability's router (the runtime equivalent of one
5423
5461
  * codegen'd `createCapRouter_<Cap>`). Each method becomes a typed
5424
5462
  * procedure with the SAME routing branch the codegen emits.
5463
+ *
5464
+ * Exported for the caller-injection spec (which drives it with synthetic
5465
+ * cap defs) — production callers go through {@link buildCapRouters}.
5425
5466
  */
5426
5467
  function buildOneCapRouter(def, primitives, services) {
5427
5468
  const capName = def.name;
@@ -5430,6 +5471,7 @@ function buildOneCapRouter(def, primitives, services) {
5430
5471
  const nodeIdData = def.nodeIdMode === "data";
5431
5472
  const procedures = {};
5432
5473
  for (const method of methodsFor(def)) {
5474
+ if (method.callerRequired && (method.kind === "subscription" || !method.isObject)) throw new Error(`Cap "${capName}" method "${method.name}": caller: 'required' is only supported on query/mutation methods with an object input schema`);
5433
5475
  const effectiveMountKind = method.schema.systemOnly === true ? systemMountKind : mount.kind;
5434
5476
  const isCollection = effectiveMountKind === "collection";
5435
5477
  const getLocal = (ctx, addonId) => services.getLocalProvider(capName, effectiveMountKind, ctx, addonId);
@@ -5461,17 +5503,25 @@ function buildOneCapRouter(def, primitives, services) {
5461
5503
  if (method.isObject) {
5462
5504
  const schema = nodeIdData ? inputSchema : require_dist.looseSchema(inputSchema);
5463
5505
  procedures[method.name] = base.input(schema)[procKind](({ input, ctx }) => {
5464
- if (nodeIdData) return requireLocal(capName, () => getLocal(ctx), services)[method.name]?.(input);
5506
+ if (nodeIdData) {
5507
+ const provider = requireLocal(capName, () => getLocal(ctx), services);
5508
+ const payload = method.callerRequired ? injectCaller(stripKeys(input, []).rest, ctx, capName, method.name, services) : input;
5509
+ return provider[method.name]?.(payload);
5510
+ }
5465
5511
  if (isCollection) {
5466
5512
  const { rest, picked } = stripKeys(input, ["nodeId", "addonId"]);
5467
5513
  const nodeId = typeof picked.nodeId === "string" ? picked.nodeId : void 0;
5468
5514
  const topLevelAddonId = typeof picked.addonId === "string" ? picked.addonId : void 0;
5469
5515
  const canRecoverNestedAddonId = !require_dist.isArrayOutputSchema(method.schema.output) && !require_dist.objectInputDeclaresAddonId(method.schema.input);
5470
5516
  const addonId = topLevelAddonId ?? (canRecoverNestedAddonId ? require_dist.extractNestedAddonId(rest) : void 0);
5471
- return resolveProviderForCall(capName, nodeId, () => getLocal(ctx, addonId), services)[method.name]?.(rest);
5517
+ const provider = resolveProviderForCall(capName, nodeId, () => getLocal(ctx, addonId), services);
5518
+ const payload = method.callerRequired ? injectCaller(rest, ctx, capName, method.name, services) : rest;
5519
+ return provider[method.name]?.(payload);
5472
5520
  }
5473
5521
  const { rest, picked } = stripKeys(input, ["nodeId"]);
5474
- return resolveProviderForCall(capName, typeof picked.nodeId === "string" ? picked.nodeId : void 0, () => getLocal(ctx), services)[method.name]?.(rest);
5522
+ const provider = resolveProviderForCall(capName, typeof picked.nodeId === "string" ? picked.nodeId : void 0, () => getLocal(ctx), services);
5523
+ const payload = method.callerRequired ? injectCaller(rest, ctx, capName, method.name, services) : rest;
5524
+ return provider[method.name]?.(payload);
5475
5525
  });
5476
5526
  continue;
5477
5527
  }
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
- import { At as EventCategory$1, Dt as resolveCapMount, Et as readinessKey, F as kebabToCamel, I as lifecycleJobSchema, K as procedureAuthKey, M as isCollectionArrayMethod, N as isObjectInput, O as extractNestedAddonId, Ot as scopeKey, P as isVoidInput, Tt as parseJsonUnknown$1, U as objectInputDeclaresAddonId, _t as asString$1, ct as DEVICE_STATUS_METHOD, ft as ReadinessRegistry, gt as asNumber, ht as asJsonObject$1, it as errMsg$1, j as isArrayOutputSchema, o as METHOD_ACCESS_MAP, ot as DATAPLANE_SECRET_HEADER$1, p as addonSettingsCapability, pt as ReadinessTimeoutError, s as RUNTIME_DEFAULTS, st as DEVICE_SETTINGS_CONTRIBUTION_METHODS, t as ALL_CAPABILITY_DEFINITIONS, vt as createEvent, wt as parseJsonObject, xt as expandCapMethods, yt as emitDownForOwnedCaps, z as looseSchema } from "./dist-CfcmjXSI.mjs";
1
+ import { At as EventCategory$1, Dt as resolveCapMount, Et as readinessKey, F as kebabToCamel, I as lifecycleJobSchema, K as procedureAuthKey, M as isCollectionArrayMethod, N as isObjectInput, O as extractNestedAddonId, Ot as scopeKey, P as isVoidInput, Tt as parseJsonUnknown$1, U as objectInputDeclaresAddonId, _t as asString$1, ct as DEVICE_STATUS_METHOD, ft as ReadinessRegistry, gt as asNumber, ht as asJsonObject$1, it as errMsg$1, j as isArrayOutputSchema, o as METHOD_ACCESS_MAP, ot as DATAPLANE_SECRET_HEADER$1, p as addonSettingsCapability, pt as ReadinessTimeoutError, s as RUNTIME_DEFAULTS, st as DEVICE_SETTINGS_CONTRIBUTION_METHODS, t as ALL_CAPABILITY_DEFINITIONS, vt as createEvent, wt as parseJsonObject, xt as expandCapMethods, yt as emitDownForOwnedCaps, z as looseSchema } from "./dist-CxM20CkF.mjs";
2
2
  import { a as downloadModel, c as getModelFilePath, d as contentTypeFor, f as createAuthenticatedFileServer, h as resolveFilePath, i as downloadFile, l as isModelDownloaded, m as parseTokenizedUrl, n as collectModelFiles, o as ensureModel, p as parseRangeHeader, r as deleteModelFromDisk, s as fetchJson, t as ModelDownloadService, u as createFileDataPlaneHandler } from "./model-download-service-Cp9f4dk6.mjs";
3
- import { $ as buildNativeCapProxy, A as createHubCapForwardService, B as AGENT_CAP_FWD_ACTION, C as brokerTransportLink, Ct as resolveAddonClass, D as localProviderLink, E as ipcParentLink, F as createUdsLogger, G as callWithServiceDiscovery, H as CapRouteResolver, I as createUdsLoggerWithControl, J as UdsLocalTransportServer, K as createLocalTransport, L as LocalChildClient, M as createUdsEventBridge, N as createUdsEventBus, O as HUB_CAP_FWD_ACTION, P as udsChildLogToWorkerEntry, Q as encodeFrame, R as LocalChildRegistry, S as brokerCallForCap, St as runNpm, T as ipcChildLink, U as CapRouteError, V as AGENT_CAP_FWD_SERVICE, W as classifyCapRoute, X as localEndpointPath, Y as SocketChannel, Z as FrameDecoder, _ as createKernelHwAccel, _t as CapabilityHandle, a as getWorkerDeviceRegistry, b as __resetCapUsageRegistryForTests, bt as installManifestNativeDeps, c as setHubConnected, ct as NATIVE_PROVIDER_SERVICE_INFIX, d as getBrokerEventBus, dt as capBareAction, et as buildUdsNativeCapProxy, f as getMoleculerEventStats, ft as capServiceName, g as AddonDepsManager, gt as DeviceRegistry, h as subscribePassthrough, ht as serializeTypedArrays, i as createUdsAddonContext, it as mountNativeCapService, j as createParentUnownedCallHandler, k as HUB_CAP_FWD_SERVICE, l as EVENT_TOPIC_PREFIX, lt as capActionName, m as setNodeEventInterest, mt as deserializeTypedArrays, n as adaptBrokerToCluster, o as getOrInitReadinessRegistry, ot as createAddonService, p as registerEventBusService, pt as parseCapAction, q as UdsLocalTransportClient, r as createAddonContext, s as getOrInitReadinessRegistryForClient, st as validateProviderRegistrations, t as installManifestPythonDeps, tt as createBrokerDeviceManagerApi, u as clusterEventTopic, ut as capActionSuffix, v as resolveHwAccel, vt as CapabilityUnavailableError, w as buildLinkChain, wt as createAddonDataPlaneFacility, x as getCapUsageRegistry, xt as resolveNpmInvocation, y as CapUsageRegistry, yt as copyBundledNativeModules, z as UDS_NO_ROUTE_PREFIX } from "./manifest-python-deps-QqIGHGMJ.mjs";
3
+ import { $ as buildNativeCapProxy, A as createHubCapForwardService, B as AGENT_CAP_FWD_ACTION, C as brokerTransportLink, Ct as resolveAddonClass, D as localProviderLink, E as ipcParentLink, F as createUdsLogger, G as callWithServiceDiscovery, H as CapRouteResolver, I as createUdsLoggerWithControl, J as UdsLocalTransportServer, K as createLocalTransport, L as LocalChildClient, M as createUdsEventBridge, N as createUdsEventBus, O as HUB_CAP_FWD_ACTION, P as udsChildLogToWorkerEntry, Q as encodeFrame, R as LocalChildRegistry, S as brokerCallForCap, St as runNpm, T as ipcChildLink, U as CapRouteError, V as AGENT_CAP_FWD_SERVICE, W as classifyCapRoute, X as localEndpointPath, Y as SocketChannel, Z as FrameDecoder, _ as createKernelHwAccel, _t as CapabilityHandle, a as getWorkerDeviceRegistry, b as __resetCapUsageRegistryForTests, bt as installManifestNativeDeps, c as setHubConnected, ct as NATIVE_PROVIDER_SERVICE_INFIX, d as getBrokerEventBus, dt as capBareAction, et as buildUdsNativeCapProxy, f as getMoleculerEventStats, ft as capServiceName, g as AddonDepsManager, gt as DeviceRegistry, h as subscribePassthrough, ht as serializeTypedArrays, i as createUdsAddonContext, it as mountNativeCapService, j as createParentUnownedCallHandler, k as HUB_CAP_FWD_SERVICE, l as EVENT_TOPIC_PREFIX, lt as capActionName, m as setNodeEventInterest, mt as deserializeTypedArrays, n as adaptBrokerToCluster, o as getOrInitReadinessRegistry, ot as createAddonService, p as registerEventBusService, pt as parseCapAction, q as UdsLocalTransportClient, r as createAddonContext, s as getOrInitReadinessRegistryForClient, st as validateProviderRegistrations, t as installManifestPythonDeps, tt as createBrokerDeviceManagerApi, u as clusterEventTopic, ut as capActionSuffix, v as resolveHwAccel, vt as CapabilityUnavailableError, w as buildLinkChain, wt as createAddonDataPlaneFacility, x as getCapUsageRegistry, xt as resolveNpmInvocation, y as CapUsageRegistry, yt as copyBundledNativeModules, z as UDS_NO_ROUTE_PREFIX } from "./manifest-python-deps-CcW0WpfS.mjs";
4
4
  import { n as getSinglePidStats, t as getPidStats } from "./resource-monitor-Le3l0qS2.mjs";
5
5
  import { FilesystemStorageAddon, t as FilesystemStorageProvider } from "./builtins/sqlite-storage/filesystem-storage.addon.mjs";
6
6
  import { SqliteSettingsAddon, t as SqliteSettingsBackend } from "./builtins/sqlite-storage/sqlite-settings.addon.mjs";
@@ -5370,10 +5370,48 @@ function methodsFor(def) {
5370
5370
  auth: m.auth ?? "protected",
5371
5371
  schema: m,
5372
5372
  isVoid: isVoidInput(m.input),
5373
- isObject: isObjectInput(m.input)
5373
+ isObject: isObjectInput(m.input),
5374
+ callerRequired: m.caller === "required"
5374
5375
  };
5375
5376
  });
5376
5377
  }
5378
+ /**
5379
+ * Extract the authenticated caller identity from the (structurally
5380
+ * unknown) tRPC context. The builder cannot import the server's
5381
+ * `TrpcContext`, so the read is narrowing-based: `ctx.user.id` (string)
5382
+ * + `ctx.user.isAdmin` (boolean) — the stable `AuthenticatedUser` core
5383
+ * every context factory produces. Returns null when no authenticated
5384
+ * user is present (the caller then fails the call — a fabricated
5385
+ * identity is never injected).
5386
+ */
5387
+ function extractCallerIdentity(ctx) {
5388
+ if (ctx === null || typeof ctx !== "object" || !("user" in ctx)) return null;
5389
+ const user = ctx.user;
5390
+ if (user === null || typeof user !== "object") return null;
5391
+ if (!("id" in user) || !("isAdmin" in user)) return null;
5392
+ const id = user.id;
5393
+ const isAdmin = user.isAdmin;
5394
+ if (typeof id !== "string" || id.length === 0 || typeof isAdmin !== "boolean") return null;
5395
+ return {
5396
+ userId: id,
5397
+ isAdmin
5398
+ };
5399
+ }
5400
+ /**
5401
+ * Return a NEW input object carrying the server-derived `caller`. The
5402
+ * spread-then-set ordering guarantees any client-supplied `caller` key
5403
+ * (which survives the `.loose()` wire parse) is overwritten. Raises
5404
+ * UNAUTHORIZED (or `badRequest` on a skewed services object without the
5405
+ * `unauthorized` raiser) when the context has no authenticated user.
5406
+ */
5407
+ function injectCaller(rest, ctx, capName, methodName, services) {
5408
+ const caller = extractCallerIdentity(ctx);
5409
+ if (caller === null) return (services.unauthorized ?? services.badRequest)(`Capability "${capName}.${methodName}" requires an authenticated caller`);
5410
+ return {
5411
+ ...rest,
5412
+ caller
5413
+ };
5414
+ }
5377
5415
  /** Strip a set of selector keys from an input object, returning a NEW object. */
5378
5416
  function stripKeys(input, keys) {
5379
5417
  const src = input ?? {};
@@ -5414,6 +5452,9 @@ function requireLocal(capName, getLocal, services) {
5414
5452
  * Build a single capability's router (the runtime equivalent of one
5415
5453
  * codegen'd `createCapRouter_<Cap>`). Each method becomes a typed
5416
5454
  * procedure with the SAME routing branch the codegen emits.
5455
+ *
5456
+ * Exported for the caller-injection spec (which drives it with synthetic
5457
+ * cap defs) — production callers go through {@link buildCapRouters}.
5417
5458
  */
5418
5459
  function buildOneCapRouter(def, primitives, services) {
5419
5460
  const capName = def.name;
@@ -5422,6 +5463,7 @@ function buildOneCapRouter(def, primitives, services) {
5422
5463
  const nodeIdData = def.nodeIdMode === "data";
5423
5464
  const procedures = {};
5424
5465
  for (const method of methodsFor(def)) {
5466
+ if (method.callerRequired && (method.kind === "subscription" || !method.isObject)) throw new Error(`Cap "${capName}" method "${method.name}": caller: 'required' is only supported on query/mutation methods with an object input schema`);
5425
5467
  const effectiveMountKind = method.schema.systemOnly === true ? systemMountKind : mount.kind;
5426
5468
  const isCollection = effectiveMountKind === "collection";
5427
5469
  const getLocal = (ctx, addonId) => services.getLocalProvider(capName, effectiveMountKind, ctx, addonId);
@@ -5453,17 +5495,25 @@ function buildOneCapRouter(def, primitives, services) {
5453
5495
  if (method.isObject) {
5454
5496
  const schema = nodeIdData ? inputSchema : looseSchema(inputSchema);
5455
5497
  procedures[method.name] = base.input(schema)[procKind](({ input, ctx }) => {
5456
- if (nodeIdData) return requireLocal(capName, () => getLocal(ctx), services)[method.name]?.(input);
5498
+ if (nodeIdData) {
5499
+ const provider = requireLocal(capName, () => getLocal(ctx), services);
5500
+ const payload = method.callerRequired ? injectCaller(stripKeys(input, []).rest, ctx, capName, method.name, services) : input;
5501
+ return provider[method.name]?.(payload);
5502
+ }
5457
5503
  if (isCollection) {
5458
5504
  const { rest, picked } = stripKeys(input, ["nodeId", "addonId"]);
5459
5505
  const nodeId = typeof picked.nodeId === "string" ? picked.nodeId : void 0;
5460
5506
  const topLevelAddonId = typeof picked.addonId === "string" ? picked.addonId : void 0;
5461
5507
  const canRecoverNestedAddonId = !isArrayOutputSchema(method.schema.output) && !objectInputDeclaresAddonId(method.schema.input);
5462
5508
  const addonId = topLevelAddonId ?? (canRecoverNestedAddonId ? extractNestedAddonId(rest) : void 0);
5463
- return resolveProviderForCall(capName, nodeId, () => getLocal(ctx, addonId), services)[method.name]?.(rest);
5509
+ const provider = resolveProviderForCall(capName, nodeId, () => getLocal(ctx, addonId), services);
5510
+ const payload = method.callerRequired ? injectCaller(rest, ctx, capName, method.name, services) : rest;
5511
+ return provider[method.name]?.(payload);
5464
5512
  }
5465
5513
  const { rest, picked } = stripKeys(input, ["nodeId"]);
5466
- return resolveProviderForCall(capName, typeof picked.nodeId === "string" ? picked.nodeId : void 0, () => getLocal(ctx), services)[method.name]?.(rest);
5514
+ const provider = resolveProviderForCall(capName, typeof picked.nodeId === "string" ? picked.nodeId : void 0, () => getLocal(ctx), services);
5515
+ const payload = method.callerRequired ? injectCaller(rest, ctx, capName, method.name, services) : rest;
5516
+ return provider[method.name]?.(payload);
5467
5517
  });
5468
5518
  continue;
5469
5519
  }
@@ -1,4 +1,4 @@
1
- import { CapabilityMountKind } from '@camstack/types';
1
+ import { CapabilityDefinition, CapabilityMountKind } from '@camstack/types';
2
2
  /**
3
3
  * A tRPC-procedure-like builder. Mirrors the chainable surface the
4
4
  * codegen emits (`procedure.input(...).output(...).query(...)`), kept
@@ -64,7 +64,24 @@ export interface CapRouterServices {
64
64
  readonly noNodeRouting: (capName: string) => never;
65
65
  /** Raise the canonical "bad request: missing field" error. */
66
66
  readonly badRequest: (message: string) => never;
67
+ /**
68
+ * Raise the canonical UNAUTHORIZED error — used by `caller: 'required'`
69
+ * methods when the context carries no authenticated user. OPTIONAL for
70
+ * framework-live-update version skew (an older server may hand a
71
+ * services object without it to a newer builder); the builder falls
72
+ * back to `badRequest` in that case so the call still fails closed.
73
+ */
74
+ readonly unauthorized?: (message: string) => never;
67
75
  }
76
+ /**
77
+ * Build a single capability's router (the runtime equivalent of one
78
+ * codegen'd `createCapRouter_<Cap>`). Each method becomes a typed
79
+ * procedure with the SAME routing branch the codegen emits.
80
+ *
81
+ * Exported for the caller-injection spec (which drives it with synthetic
82
+ * cap defs) — production callers go through {@link buildCapRouters}.
83
+ */
84
+ export declare function buildOneCapRouter(def: CapabilityDefinition, primitives: CapRouterPrimitives, services: CapRouterServices): unknown;
68
85
  /**
69
86
  * Build the runtime cap-router map: `{ <camelCapName>: <router> }` for
70
87
  * every capability the builder owns. Caps with `mount.kind` `custom` /
@@ -1,5 +1,5 @@
1
1
  const require_chunk = require("./chunk-Cek0wNdY.js");
2
- const require_dist = require("./dist-DEkwmyIj.js");
2
+ const require_dist = require("./dist-CdgScQ3H.js");
3
3
  let _camstack_types_node = require("@camstack/types/node");
4
4
  let node_http = require("node:http");
5
5
  let node_fs = require("node:fs");
@@ -1,4 +1,4 @@
1
- import { q as readNodePin } from "./dist-CfcmjXSI.mjs";
1
+ import { q as readNodePin } from "./dist-CxM20CkF.mjs";
2
2
  import { ensureBinary, ensureFfmpeg, ensurePython, installPythonPackages, installPythonRequirements } from "@camstack/types/node";
3
3
  import { createServer } from "node:http";
4
4
  import * as fs from "node:fs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/system",
3
- "version": "1.2.7",
3
+ "version": "1.2.8",
4
4
  "description": "Core addon for CamStack — builtins, pipeline, process management, auth, logging, events",
5
5
  "keywords": [
6
6
  "camstack",