@camstack/server 1.2.594 → 1.2.595
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/addon-root-inventory.js +50 -11
- package/dist/agent/addon-scan.js +44 -6
- package/dist/agent/agent-addon-runtime.js +8 -3
- package/dist/agent/agent-addon-updates.js +52 -12
- package/dist/agent/agent-cap-dispatch-service.js +5 -3
- package/dist/agent/agent-config.js +42 -7
- package/dist/agent/agent-deploy-swap.js +41 -5
- package/dist/agent/agent-group-runner.js +47 -8
- package/dist/agent/agent-http-auth.js +22 -10
- package/dist/agent/agent-http.js +113 -64
- package/dist/agent/agent-hub-addon-update.js +16 -10
- package/dist/agent/agent-hub-registration.js +7 -4
- package/dist/agent/agent-infra-capabilities.js +9 -5
- package/dist/agent/agent-json-file.js +42 -5
- package/dist/agent/agent-mesh-gate.js +8 -5
- package/dist/agent/agent-node-certificates.js +28 -25
- package/dist/agent/agent-pairing-local.js +47 -10
- package/dist/agent/agent-pairing-routes.js +20 -16
- package/dist/agent/agent-pairing-store.js +58 -18
- package/dist/agent/agent-reconnect.js +4 -1
- package/dist/agent/agent-service.js +71 -35
- package/dist/agent/agent-sniffing-listener.js +48 -11
- package/dist/agent/agent-undeploy.js +41 -5
- package/dist/agent/agent-update-routes.js +19 -14
- package/dist/agent/agent-update-service.js +80 -38
- package/dist/agent/apply-model-distribution.js +4 -1
- package/dist/agent/apply-stage-dev-uploads.js +9 -6
- package/dist/agent/derive-hub-url.js +8 -3
- package/dist/agent/fetch-bundle-from-hub.js +9 -6
- package/dist/agent/hubs-found.js +43 -6
- package/dist/agent/infra-boot-guard.js +4 -1
- package/dist/agent/infra-boot-plan.js +6 -2
- package/dist/agent/main.js +183 -148
- package/dist/agent/register-agent-cap-dispatch.js +6 -3
- package/dist/agent/serial-queue.js +7 -2
- package/dist/agent-status-page.js +4 -1
- package/dist/api/addon-upload.js +61 -22
- package/dist/api/agent-addon-delivery.js +11 -6
- package/dist/api/auth-whoami.js +4 -1
- package/dist/api/backup-download-pump.js +9 -5
- package/dist/api/backup-download.js +10 -7
- package/dist/api/core/addon-settings.router.js +19 -16
- package/dist/api/core/agent-pairing.router.js +79 -76
- package/dist/api/core/agents.router.js +24 -21
- package/dist/api/core/auth-admin-tokens.procedures.js +52 -48
- package/dist/api/core/auth-device-cert.procedures.js +67 -62
- package/dist/api/core/auth-limits.js +25 -16
- package/dist/api/core/auth-reauth.procedures.js +37 -32
- package/dist/api/core/auth-revoke-credentials.procedures.js +26 -22
- package/dist/api/core/auth-sessions.procedures.js +56 -52
- package/dist/api/core/auth.router.js +304 -300
- package/dist/api/core/cap-providers.js +121 -74
- package/dist/api/core/capabilities.router.js +37 -34
- package/dist/api/core/capability-preference-writes.js +17 -10
- package/dist/api/core/certificates.router.js +109 -106
- package/dist/api/core/cluster-nodes.router.js +18 -15
- package/dist/api/core/collection-preference.js +6 -2
- package/dist/api/core/event-bus-proxy.router.js +37 -34
- package/dist/api/core/failure-contributions.js +8 -4
- package/dist/api/core/hwaccel.router.js +20 -17
- package/dist/api/core/integration-secrets.js +12 -8
- package/dist/api/core/lifecycle-job-runner.js +49 -13
- package/dist/api/core/live-events.router.js +32 -29
- package/dist/api/core/load-contributions.js +8 -4
- package/dist/api/core/logging-settings.js +43 -30
- package/dist/api/core/logs.router.js +43 -40
- package/dist/api/core/notifications.router.js +18 -15
- package/dist/api/core/public-event-filter.js +8 -4
- package/dist/api/core/repl.router.js +21 -18
- package/dist/api/core/request-census-settings.js +16 -11
- package/dist/api/core/server-management.provider.js +4 -1
- package/dist/api/core/server-name.js +17 -9
- package/dist/api/core/site-location.js +24 -16
- package/dist/api/core/stream-probe.router.js +24 -21
- package/dist/api/core/system-events.router.js +26 -23
- package/dist/api/cors/cors-policy.js +29 -20
- package/dist/api/cors/register-cors-policy.js +14 -9
- package/dist/api/deploy-stage-registry.js +10 -6
- package/dist/api/dev-uploads-bundle.js +50 -12
- package/dist/api/health/adaptive-probe.routes.js +13 -9
- package/dist/api/health/health.routes.js +13 -8
- package/dist/api/hub-cluster-url.js +9 -3
- package/dist/api/model-distributor.js +50 -12
- package/dist/api/oauth2/consent-page.js +13 -10
- package/dist/api/oauth2/oauth2-routes.js +25 -17
- package/dist/api/oauth2/private-host.js +4 -1
- package/dist/api/server-upload-propagate.js +51 -15
- package/dist/api/server-upload.js +50 -13
- package/dist/api/sse-no-compression.js +4 -1
- package/dist/api/static/frame-policy.js +9 -4
- package/dist/api/static/precompressed-asset.js +57 -15
- package/dist/api/static/spa-mount.js +47 -8
- package/dist/api/static/spa-static.js +12 -5
- package/dist/api/tarball-manifest.js +44 -7
- package/dist/api/trpc/cap-mount-helpers.js +12 -7
- package/dist/api/trpc/cap-route-error-formatter.js +13 -10
- package/dist/api/trpc/cap-router-runtime.js +51 -40
- package/dist/api/trpc/client-ip.js +20 -9
- package/dist/api/trpc/core-cap-bridge.js +42 -32
- package/dist/api/trpc/device-collection-dispatch.js +27 -23
- package/dist/api/trpc/device-config-secret-redaction.js +40 -24
- package/dist/api/trpc/generated-cap-mounts.js +222 -218
- package/dist/api/trpc/generated-cap-routers.js +4856 -4676
- package/dist/api/trpc/http-request-census-hook.js +11 -8
- package/dist/api/trpc/http-request-census.js +41 -34
- package/dist/api/trpc/http-request-census.singleton.js +8 -4
- package/dist/api/trpc/localized-schema-paths.js +4 -1
- package/dist/api/trpc/principal-visibility.js +22 -14
- package/dist/api/trpc/remote-addon-update-grant.js +4 -1
- package/dist/api/trpc/scope-access.js +15 -10
- package/dist/api/trpc/server-provided-caps.js +7 -3
- package/dist/api/trpc/share-view-access.js +14 -6
- package/dist/api/trpc/trpc-error-device-tags.js +6 -3
- package/dist/api/trpc/trpc-error-principal.js +6 -2
- package/dist/api/trpc/trpc.context.js +25 -20
- package/dist/api/trpc/trpc.middleware.js +46 -38
- package/dist/api/trpc/trpc.router.js +99 -58
- package/dist/api/trpc/user-error.js +8 -5
- package/dist/api/trpc/ws-request-census.js +24 -17
- package/dist/api/trpc/ws-slow-consumer-guard.js +16 -11
- package/dist/api/upload-auth.js +9 -5
- package/dist/auth/addon-route-jwt-gate.js +7 -4
- package/dist/auth/addon-route-share-gate.js +12 -7
- package/dist/auth/app-confirm-page.js +22 -17
- package/dist/auth/app-confirm-routes.js +31 -26
- package/dist/auth/app-confirmations.js +44 -7
- package/dist/auth/app-page-shell.js +30 -17
- package/dist/auth/app-page-strings.js +17 -11
- package/dist/auth/app-passkey-page.js +21 -16
- package/dist/auth/app-passkey-routes.js +41 -37
- package/dist/auth/app-refused-route.js +18 -13
- package/dist/auth/auth-network-policy.js +15 -11
- package/dist/auth/auth-provider-gate.js +9 -4
- package/dist/auth/auth-rate-limit.js +7 -3
- package/dist/auth/client-address.js +9 -6
- package/dist/auth/device-enroll-proofs.js +43 -6
- package/dist/auth/external-link-intents.js +7 -3
- package/dist/auth/hub-sessions.js +12 -6
- package/dist/auth/native-link-completions.js +11 -7
- package/dist/auth/native-return.js +13 -9
- package/dist/auth/passkey-provider.js +32 -26
- package/dist/auth/second-factors.js +10 -6
- package/dist/auth/session-connections.js +12 -6
- package/dist/auth/session-cookie.js +23 -12
- package/dist/auth/session-lifetimes.js +12 -8
- package/dist/auth/session-mint.js +11 -4
- package/dist/auth/sso-finish-app.js +16 -13
- package/dist/auth/sso-finish-deps.js +27 -21
- package/dist/auth/sso-finish.js +38 -28
- package/dist/auth/sso-routes.js +25 -22
- package/dist/auth/used-bridge-ids.js +5 -1
- package/dist/boot/boot-config.js +55 -16
- package/dist/boot/init-sequence.js +4 -1
- package/dist/boot/integration-id-backfill.js +8 -3
- package/dist/boot/platform-keychain-key.js +42 -5
- package/dist/boot/post-boot.service.js +18 -14
- package/dist/boot/reconcile-lifecycle-jobs.js +6 -3
- package/dist/boot/retired-public-url-env.js +8 -4
- package/dist/bootstrap-packages.js +4 -1
- package/dist/closure-node-modules.js +38 -2
- package/dist/core/addon/addon-call-gateway.js +5 -1
- package/dist/core/addon/addon-package.service.js +123 -83
- package/dist/core/addon/addon-process-view.js +6 -2
- package/dist/core/addon/addon-realign-plan.js +4 -1
- package/dist/core/addon/addon-registry.service.js +187 -146
- package/dist/core/addon/addon-row-manifest.js +4 -1
- package/dist/core/addon/addon-search.service.js +7 -3
- package/dist/core/addon/addon-settings-provider.js +3 -1
- package/dist/core/addon/addon-uninstall.js +11 -4
- package/dist/core/addon/addon.tokens.js +5 -2
- package/dist/core/addon/device-meta-mirror.js +13 -8
- package/dist/core/addon/forked-custom-actions.js +11 -6
- package/dist/core/addon/integration-visibility.js +6 -3
- package/dist/core/addon/materialize-route-path.js +4 -1
- package/dist/core/addon/package-dir-utils.js +45 -8
- package/dist/core/addon/prune-misplaced-addons.js +43 -5
- package/dist/core/addon/runner-convergence.js +4 -1
- package/dist/core/addon/runner-serialization.js +4 -1
- package/dist/core/addon/runner-spawn-fanout.js +8 -3
- package/dist/core/addon/settings-door-wiring.js +8 -5
- package/dist/core/addon/single-flight-refresh.js +4 -1
- package/dist/core/addon-bridge/addon-bridge.service.js +44 -7
- package/dist/core/addon-pages/addon-pages.service.js +40 -3
- package/dist/core/addon-widgets/addon-widgets.service.js +42 -4
- package/dist/core/agent/agent-addon-backfill.js +17 -9
- package/dist/core/agent/agent-delivery-ledger.js +7 -3
- package/dist/core/agent/agent-liveness-event.js +6 -2
- package/dist/core/agent/agent-pairing-http.js +45 -41
- package/dist/core/agent/agent-registry.service.js +89 -50
- package/dist/core/agent/cluster-node-history-mirror.js +7 -3
- package/dist/core/agent/cluster-node-history-store.js +35 -31
- package/dist/core/agent/hub-agent-pairing.js +5 -1
- package/dist/core/agent/node-certificates-client.js +6 -3
- package/dist/core/agent/node-directory.js +4 -1
- package/dist/core/app-links/well-known-app-links.js +6 -2
- package/dist/core/auth/auth.service.js +8 -3
- package/dist/core/auth/handoff-code.service.js +49 -11
- package/dist/core/auth/record-kinds.js +19 -16
- package/dist/core/auth/share-token.service.js +79 -42
- package/dist/core/capability/capability.service.js +5 -1
- package/dist/core/config/config.schema.js +6 -1
- package/dist/core/config/config.service.js +6 -2
- package/dist/core/events/event-bus.service.js +7 -3
- package/dist/core/feature/feature.service.js +6 -2
- package/dist/core/lifecycle/lifecycle-runner.singleton.js +10 -5
- package/dist/core/lifecycle/lifecycle-state-machine.js +5 -1
- package/dist/core/logging/log-ring-buffer.js +5 -1
- package/dist/core/logging/logging.service.js +9 -5
- package/dist/core/logging/scoped-logger.js +5 -1
- package/dist/core/moleculer/agent-readiness-pull.js +4 -1
- package/dist/core/moleculer/agent-registration-request.js +7 -3
- package/dist/core/moleculer/cap-call-fn.js +7 -4
- package/dist/core/moleculer/cap-route-authority.js +8 -3
- package/dist/core/moleculer/hub-mesh-guard.js +9 -5
- package/dist/core/moleculer/moleculer.service.js +86 -79
- package/dist/core/network/network-quality.service.js +6 -2
- package/dist/core/notification/notification-wrapper.service.js +7 -3
- package/dist/core/notification/toast-wrapper.service.js +7 -3
- package/dist/core/provider/provider.tokens.js +4 -1
- package/dist/core/repl/repl-engine.service.js +8 -4
- package/dist/core/runner-health/runner-boot-check.js +15 -7
- package/dist/core/runner-health/update-preflight.js +14 -9
- package/dist/core/server-update/server-update.service.js +49 -12
- package/dist/core/server-update/system-apply-closure-patches.js +42 -6
- package/dist/core/server-update/system-ensure-prebuilds.js +6 -3
- package/dist/core/server-update/system-exec-npm.js +5 -2
- package/dist/core/storage/fs-storage-backend.js +5 -1
- package/dist/core/storage/storage-location-manager.js +5 -1
- package/dist/core/storage/storage.service.js +6 -2
- package/dist/core/streaming/ffmpeg-stream-info.js +8 -3
- package/dist/core/streaming/stream-probe.service.js +16 -12
- package/dist/core/streaming/ttl-cache.js +5 -1
- package/dist/core/topology/topology-emitter.service.js +23 -19
- package/dist/core/update-availability-emitter.js +7 -3
- package/dist/core/update-availability-store.js +45 -8
- package/dist/core/updates/agent-installed-packages.js +9 -5
- package/dist/core/updates/restart-marker.js +8 -3
- package/dist/core/updates/update-check-scheduler.js +18 -13
- package/dist/core/updates/wrapper-update-checker.js +7 -3
- package/dist/first-boot-addon-plan.js +6 -2
- package/dist/framework-nodepath.js +38 -2
- package/dist/i18n/request-lang.js +11 -7
- package/dist/launcher.js +65 -30
- package/dist/lifecycle-journal-path.js +38 -2
- package/dist/main.js +324 -286
- package/dist/manual-boot.js +156 -117
- package/dist/node-role.js +4 -1
- package/dist/package-inventory.js +48 -7
- package/dist/pending-restore.js +43 -7
- package/dist/single-copy-cleanup-runner.js +45 -9
- package/dist/single-copy-cleanup.js +15 -7
- package/dist/sqlite-restore.js +48 -9
- package/dist/starter.js +39 -4
- package/dist/ui-serving/lazy-ui-serving.js +39 -3
- package/package.json +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Small helpers for wiring capability routers to the `CapabilityRegistry`
|
|
3
4
|
* in `trpc.router.ts`. These functions don't generate code — they just
|
|
@@ -15,16 +16,20 @@
|
|
|
15
16
|
* provider responsible for a given `streamId`) are NOT covered here —
|
|
16
17
|
* they have app-specific routing logic that belongs in the mount.
|
|
17
18
|
*/
|
|
18
|
-
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.requireSingleton = requireSingleton;
|
|
21
|
+
exports.requireDeviceScoped = requireDeviceScoped;
|
|
22
|
+
exports.concatCollection = concatCollection;
|
|
23
|
+
const server_1 = require("@trpc/server");
|
|
19
24
|
/**
|
|
20
25
|
* Fetch the currently active singleton provider for a capability.
|
|
21
26
|
* Returns null if no provider is registered; the downstream codegen'd
|
|
22
27
|
* router surfaces this as `PRECONDITION_FAILED` to the caller.
|
|
23
28
|
*/
|
|
24
|
-
|
|
29
|
+
function requireSingleton(registry, capName) {
|
|
25
30
|
return registry?.getSingleton(capName) ?? null;
|
|
26
31
|
}
|
|
27
|
-
|
|
32
|
+
function requireDeviceScoped(registry, capName) {
|
|
28
33
|
if (!registry)
|
|
29
34
|
return null;
|
|
30
35
|
// The Proxy is the singleton stand-in. Each property access returns
|
|
@@ -38,7 +43,7 @@ export function requireDeviceScoped(registry, capName) {
|
|
|
38
43
|
return async (input) => {
|
|
39
44
|
const deviceId = input?.deviceId;
|
|
40
45
|
if (typeof deviceId !== 'number') {
|
|
41
|
-
throw new TRPCError({
|
|
46
|
+
throw new server_1.TRPCError({
|
|
42
47
|
code: 'BAD_REQUEST',
|
|
43
48
|
message: `${String(capName)}.${prop}: input must carry numeric "deviceId"`,
|
|
44
49
|
});
|
|
@@ -61,14 +66,14 @@ export function requireDeviceScoped(registry, capName) {
|
|
|
61
66
|
// cap with no provider at all still answered. Wiring was deleted on
|
|
62
67
|
// 2026-08-08 — a composed device's caps are native to it, so there
|
|
63
68
|
// is nothing to conjure and the honest answer is the error.
|
|
64
|
-
throw new TRPCError({
|
|
69
|
+
throw new server_1.TRPCError({
|
|
65
70
|
code: 'PRECONDITION_FAILED',
|
|
66
71
|
message: `Capability "${String(capName)}" not registered for device ${deviceId}`,
|
|
67
72
|
});
|
|
68
73
|
}
|
|
69
74
|
const fn = provider[prop];
|
|
70
75
|
if (typeof fn !== 'function') {
|
|
71
|
-
throw new TRPCError({
|
|
76
|
+
throw new server_1.TRPCError({
|
|
72
77
|
code: 'NOT_IMPLEMENTED',
|
|
73
78
|
message: `Capability "${String(capName)}" provider for device ${deviceId} does not implement "${prop}"`,
|
|
74
79
|
});
|
|
@@ -88,7 +93,7 @@ export function requireDeviceScoped(registry, capName) {
|
|
|
88
93
|
* and concatenates their array results. Useful for contribution-style
|
|
89
94
|
* caps where each provider adds to a shared pool.
|
|
90
95
|
*/
|
|
91
|
-
|
|
96
|
+
function concatCollection(providers, method) {
|
|
92
97
|
const wrapper = async (...args) => {
|
|
93
98
|
const results = await Promise.all(providers.map(async (p) => {
|
|
94
99
|
const member = Reflect.get(p, method);
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatTrpcError = formatTrpcError;
|
|
1
4
|
/**
|
|
2
5
|
* tRPC error formatter that serializes CapRouteError diagnostic fields
|
|
3
6
|
* across the server→client boundary.
|
|
@@ -13,8 +16,8 @@
|
|
|
13
16
|
*
|
|
14
17
|
* The formatter is EXPORTED for unit testing (no side-effects, pure function).
|
|
15
18
|
*/
|
|
16
|
-
|
|
17
|
-
|
|
19
|
+
const system_1 = require("@camstack/system");
|
|
20
|
+
const types_1 = require("@camstack/types");
|
|
18
21
|
// ---------------------------------------------------------------------------
|
|
19
22
|
// Type guards
|
|
20
23
|
// ---------------------------------------------------------------------------
|
|
@@ -54,7 +57,7 @@ function extractCapRouteError(err) {
|
|
|
54
57
|
for (let depth = 0; depth < 8; depth++) {
|
|
55
58
|
if (current === null || current === undefined)
|
|
56
59
|
return null;
|
|
57
|
-
if (current instanceof CapRouteError) {
|
|
60
|
+
if (current instanceof system_1.CapRouteError) {
|
|
58
61
|
return current;
|
|
59
62
|
}
|
|
60
63
|
// Duck-type fallback: err.name + err.reason field present
|
|
@@ -81,7 +84,7 @@ function extractCapRouteError(err) {
|
|
|
81
84
|
const rawCapName = Reflect.get(current, 'capName');
|
|
82
85
|
const capName = typeof rawCapName === 'string' ? rawCapName : '(unknown)';
|
|
83
86
|
// Build a minimal object with the same shape — enough for the formatter.
|
|
84
|
-
const synthetic = Object.assign(new CapRouteError(capName, undefined, {
|
|
87
|
+
const synthetic = Object.assign(new system_1.CapRouteError(capName, undefined, {
|
|
85
88
|
reason,
|
|
86
89
|
rejected,
|
|
87
90
|
...(typeof nodeId === 'string' ? { nodeId } : {}),
|
|
@@ -107,7 +110,7 @@ function extractCapRouteError(err) {
|
|
|
107
110
|
* when the thrown error (or any error in its `.cause` chain) is a CapRouteError.
|
|
108
111
|
* Returns the shape unchanged for all other errors.
|
|
109
112
|
*/
|
|
110
|
-
|
|
113
|
+
function formatTrpcError(opts) {
|
|
111
114
|
return withErrorI18n(opts, withCapRouteData(opts));
|
|
112
115
|
}
|
|
113
116
|
/**
|
|
@@ -117,16 +120,16 @@ export function formatTrpcError(opts) {
|
|
|
117
120
|
* unknown code and English all pass through with the original message.
|
|
118
121
|
*/
|
|
119
122
|
function withErrorI18n(opts, shape) {
|
|
120
|
-
const coded = readErrorI18n(opts.error);
|
|
123
|
+
const coded = (0, types_1.readErrorI18n)(opts.error);
|
|
121
124
|
if (coded === null)
|
|
122
125
|
return shape;
|
|
123
|
-
const lang = opts.ctx?.lang ?? DEFAULT_CATALOG_LANG;
|
|
124
|
-
const text = lang === DEFAULT_CATALOG_LANG
|
|
126
|
+
const lang = opts.ctx?.lang ?? types_1.DEFAULT_CATALOG_LANG;
|
|
127
|
+
const text = lang === types_1.DEFAULT_CATALOG_LANG
|
|
125
128
|
? undefined
|
|
126
|
-
: getCatalogRegistry().lookup(lang, SERVER_NAMESPACE, coded.code);
|
|
129
|
+
: (0, system_1.getCatalogRegistry)().lookup(lang, system_1.SERVER_NAMESPACE, coded.code);
|
|
127
130
|
return {
|
|
128
131
|
...shape,
|
|
129
|
-
...(text !== undefined ? { message: interpolate(text, coded.params) } : {}),
|
|
132
|
+
...(text !== undefined ? { message: (0, types_1.interpolate)(text, coded.params) } : {}),
|
|
130
133
|
data: { ...shape.data, i18n: coded },
|
|
131
134
|
};
|
|
132
135
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Server-side glue for the runtime cap-router builder (BIG PLAN 2).
|
|
3
4
|
*
|
|
@@ -18,33 +19,43 @@
|
|
|
18
19
|
* supplies `server-provided` provider factories (incl. webrtc-session) via the
|
|
19
20
|
* `serverProviders` map — no hand-written cap-router override remains.
|
|
20
21
|
*/
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.COLLECTION_ARRAY_METHODS = void 0;
|
|
24
|
+
exports.aggregateCollectionCall = aggregateCollectionCall;
|
|
25
|
+
exports.devicePinOf = devicePinOf;
|
|
26
|
+
exports.pinnedDeviceCollectionCall = pinnedDeviceCollectionCall;
|
|
27
|
+
exports.addonPinOf = addonPinOf;
|
|
28
|
+
exports.pinnedCollectionCall = pinnedCollectionCall;
|
|
29
|
+
exports.createCapRouterPrimitives = createCapRouterPrimitives;
|
|
30
|
+
exports.createCapRouterServices = createCapRouterServices;
|
|
31
|
+
exports.buildRuntimeCapRouters = buildRuntimeCapRouters;
|
|
32
|
+
const system_1 = require("@camstack/system");
|
|
33
|
+
const types_1 = require("@camstack/types");
|
|
34
|
+
const server_1 = require("@trpc/server");
|
|
35
|
+
const cap_mount_helpers_js_1 = require("./cap-mount-helpers.js");
|
|
36
|
+
const device_collection_dispatch_js_1 = require("./device-collection-dispatch.js");
|
|
37
|
+
const trpc_middleware_js_1 = require("./trpc.middleware.js");
|
|
27
38
|
/**
|
|
28
39
|
* Pre-computed set of capName → array-output method names for collection
|
|
29
40
|
* caps, derived once from the cap defs at module init. Mirrors
|
|
30
41
|
* `generate-cap-mounts.ts` `isArrayOutputSchema` so the runtime collection
|
|
31
42
|
* resolver fans the SAME methods the codegen used to.
|
|
32
43
|
*/
|
|
33
|
-
|
|
44
|
+
exports.COLLECTION_ARRAY_METHODS = computeArrayMethods();
|
|
34
45
|
function computeArrayMethods() {
|
|
35
46
|
const out = new Map();
|
|
36
|
-
for (const def of ALL_CAPABILITY_DEFINITIONS) {
|
|
47
|
+
for (const def of system_1.ALL_CAPABILITY_DEFINITIONS) {
|
|
37
48
|
// The effective MOUNT, never `mode`: a device-scoped wrapper collection
|
|
38
49
|
// (`videoclips`, D554) fans over ONE DEVICE's sources through the
|
|
39
50
|
// per-device dispatcher, and must never be fanned globally here.
|
|
40
|
-
if (resolveCapMount(def).kind !== 'collection')
|
|
51
|
+
if ((0, types_1.resolveCapMount)(def).kind !== 'collection')
|
|
41
52
|
continue;
|
|
42
53
|
const names = [];
|
|
43
54
|
for (const [name, schema] of Object.entries(def.methods)) {
|
|
44
55
|
const m = schema;
|
|
45
56
|
if (m.kind === 'subscription')
|
|
46
57
|
continue;
|
|
47
|
-
if (isArrayOutputSchema(m.output))
|
|
58
|
+
if ((0, system_1.isArrayOutputSchema)(m.output))
|
|
48
59
|
names.push(name);
|
|
49
60
|
}
|
|
50
61
|
if (names.length > 0)
|
|
@@ -66,7 +77,7 @@ function computeArrayMethods() {
|
|
|
66
77
|
*/
|
|
67
78
|
function isGlobalCollection(reg, capName) {
|
|
68
79
|
const def = reg.getDefinition(capName);
|
|
69
|
-
return def !== undefined && resolveCapMount(def).kind === 'collection';
|
|
80
|
+
return def !== undefined && (0, types_1.resolveCapMount)(def).kind === 'collection';
|
|
70
81
|
}
|
|
71
82
|
/**
|
|
72
83
|
* Resolve a collection cap's provider exactly as the codegen-emitted
|
|
@@ -92,7 +103,7 @@ function resolveCollectionProvider(reg, capName, addonId) {
|
|
|
92
103
|
const first = providers[0];
|
|
93
104
|
if (first === undefined)
|
|
94
105
|
return null;
|
|
95
|
-
const arrayMethods = COLLECTION_ARRAY_METHODS.get(capName);
|
|
106
|
+
const arrayMethods = exports.COLLECTION_ARRAY_METHODS.get(capName);
|
|
96
107
|
if (!arrayMethods || arrayMethods.length === 0)
|
|
97
108
|
return first;
|
|
98
109
|
const aggregate = { ...first };
|
|
@@ -117,12 +128,12 @@ function resolveCollectionProvider(reg, capName, addonId) {
|
|
|
117
128
|
* `null` on zero providers too: that is the empty-collection fast-path's job
|
|
118
129
|
* (it answers `[]` without routing), not this one's.
|
|
119
130
|
*/
|
|
120
|
-
|
|
131
|
+
async function aggregateCollectionCall(reg, capName, method, args) {
|
|
121
132
|
if (!reg)
|
|
122
133
|
return null;
|
|
123
134
|
if (!isGlobalCollection(reg, capName))
|
|
124
135
|
return null;
|
|
125
|
-
if (!COLLECTION_ARRAY_METHODS.get(capName)?.includes(method))
|
|
136
|
+
if (!exports.COLLECTION_ARRAY_METHODS.get(capName)?.includes(method))
|
|
126
137
|
return null;
|
|
127
138
|
if (reg.getCollectionEntries(capName).length === 0)
|
|
128
139
|
return null;
|
|
@@ -146,7 +157,7 @@ function isDeviceCollection(reg, capName) {
|
|
|
146
157
|
const def = reg.getDefinition(capName);
|
|
147
158
|
if (def === undefined)
|
|
148
159
|
return false;
|
|
149
|
-
return def.mode === 'collection' && resolveCapMount(def).kind === 'device-scoped';
|
|
160
|
+
return def.mode === 'collection' && (0, types_1.resolveCapMount)(def).kind === 'device-scoped';
|
|
150
161
|
}
|
|
151
162
|
/**
|
|
152
163
|
* The `{ provider }` a DEVICE-collection call pins to, or `null`.
|
|
@@ -173,7 +184,7 @@ function isDeviceCollection(reg, capName) {
|
|
|
173
184
|
* is required on `listClips` too (D554), and the narrowing happens inside
|
|
174
185
|
* `requireDeviceCollection`, which then decides fan-out vs scalar itself.
|
|
175
186
|
*/
|
|
176
|
-
|
|
187
|
+
function devicePinOf(reg, capName, args) {
|
|
177
188
|
if (!reg)
|
|
178
189
|
return null;
|
|
179
190
|
if (!isDeviceCollection(reg, capName))
|
|
@@ -183,7 +194,7 @@ export function devicePinOf(reg, capName, args) {
|
|
|
183
194
|
const rec = args;
|
|
184
195
|
if (typeof rec['deviceId'] !== 'number')
|
|
185
196
|
return null;
|
|
186
|
-
const pin = rec[PROVIDER_PIN_FIELD];
|
|
197
|
+
const pin = rec[types_1.PROVIDER_PIN_FIELD];
|
|
187
198
|
return typeof pin === 'string' && pin.length > 0 ? pin : null;
|
|
188
199
|
}
|
|
189
200
|
/**
|
|
@@ -199,10 +210,10 @@ export function devicePinOf(reg, capName, args) {
|
|
|
199
210
|
* legitimately answer `null`, which a bare return could not tell from "not
|
|
200
211
|
* handled".
|
|
201
212
|
*/
|
|
202
|
-
|
|
213
|
+
async function pinnedDeviceCollectionCall(reg, capName, method, args) {
|
|
203
214
|
if (devicePinOf(reg, capName, args) === null)
|
|
204
215
|
return null;
|
|
205
|
-
const dispatcher = requireDeviceCollection(reg, capName);
|
|
216
|
+
const dispatcher = (0, device_collection_dispatch_js_1.requireDeviceCollection)(reg, capName);
|
|
206
217
|
if (dispatcher === null)
|
|
207
218
|
return null;
|
|
208
219
|
const fn = dispatcher[method];
|
|
@@ -228,12 +239,12 @@ export async function pinnedDeviceCollectionCall(reg, capName, method, args) {
|
|
|
228
239
|
* (there `addonId` is provider DATA: `addons.getLogs({addonId})` names the addon
|
|
229
240
|
* whose logs you want, it does not name a provider).
|
|
230
241
|
*/
|
|
231
|
-
|
|
242
|
+
function addonPinOf(reg, capName, method, args) {
|
|
232
243
|
if (!reg)
|
|
233
244
|
return null;
|
|
234
245
|
if (!isGlobalCollection(reg, capName))
|
|
235
246
|
return null;
|
|
236
|
-
if (COLLECTION_ARRAY_METHODS.get(capName)?.includes(method) === true)
|
|
247
|
+
if (exports.COLLECTION_ARRAY_METHODS.get(capName)?.includes(method) === true)
|
|
237
248
|
return null;
|
|
238
249
|
if (args === null || typeof args !== 'object' || Array.isArray(args))
|
|
239
250
|
return null;
|
|
@@ -279,7 +290,7 @@ export function addonPinOf(reg, capName, method, args) {
|
|
|
279
290
|
* Returns a `{ value }` box, never the bare result: `getBrokerConfig` answers
|
|
280
291
|
* `null` legitimately, so a bare `null` could not be told from "not handled".
|
|
281
292
|
*/
|
|
282
|
-
|
|
293
|
+
async function pinnedCollectionCall(reg, capName, method, args) {
|
|
283
294
|
const addonId = addonPinOf(reg, capName, method, args);
|
|
284
295
|
if (addonId === null)
|
|
285
296
|
return null;
|
|
@@ -316,11 +327,11 @@ function concatArrayMethod(providers, method) {
|
|
|
316
327
|
};
|
|
317
328
|
}
|
|
318
329
|
/** Build the `primitives` half of `buildCapRouters(primitives, services)`. */
|
|
319
|
-
|
|
330
|
+
function createCapRouterPrimitives() {
|
|
320
331
|
const procedures = {
|
|
321
|
-
public: publicProcedure,
|
|
322
|
-
protected: protectedProcedure,
|
|
323
|
-
admin: adminProcedure,
|
|
332
|
+
public: trpc_middleware_js_1.publicProcedure,
|
|
333
|
+
protected: trpc_middleware_js_1.protectedProcedure,
|
|
334
|
+
admin: trpc_middleware_js_1.adminProcedure,
|
|
324
335
|
};
|
|
325
336
|
return {
|
|
326
337
|
// Documented type boundary: the builder hands a record of REAL tRPC
|
|
@@ -329,13 +340,13 @@ export function createCapRouterPrimitives() {
|
|
|
329
340
|
// `CreateRouterOptions`; the runtime values satisfy it. Narrow at this
|
|
330
341
|
// single seam so the rest of the builder stays free of `@trpc/server`
|
|
331
342
|
// internal types — mirrors the existing `remoteCapProxy` cast pattern.
|
|
332
|
-
router: (procs) => trpcRouter(procs),
|
|
343
|
+
router: (procs) => (0, trpc_middleware_js_1.trpcRouter)(procs),
|
|
333
344
|
procedures,
|
|
334
|
-
iterableSubscription,
|
|
345
|
+
iterableSubscription: trpc_middleware_js_1.iterableSubscription,
|
|
335
346
|
};
|
|
336
347
|
}
|
|
337
348
|
/** Build the `services` half of `buildCapRouters(primitives, services)`. */
|
|
338
|
-
|
|
349
|
+
function createCapRouterServices(deps) {
|
|
339
350
|
const reg = deps.capabilityRegistry;
|
|
340
351
|
const remoteProxy = (capName, nodeId) => deps.moleculer.createCapabilityProxy(capName, nodeId);
|
|
341
352
|
const getLocalProvider = (capName, mountKind, ctx, addonId) => {
|
|
@@ -364,9 +375,9 @@ export function createCapRouterServices(deps) {
|
|
|
364
375
|
// collection twin fans the array methods over the device's sources and
|
|
365
376
|
// routes the scalar ones by the source inside the id.
|
|
366
377
|
if (reg?.getMode(capName) === 'collection') {
|
|
367
|
-
return requireDeviceCollection(reg, capName, deps.logger);
|
|
378
|
+
return (0, device_collection_dispatch_js_1.requireDeviceCollection)(reg, capName, deps.logger);
|
|
368
379
|
}
|
|
369
|
-
return requireDeviceScoped(reg, capName);
|
|
380
|
+
return (0, cap_mount_helpers_js_1.requireDeviceScoped)(reg, capName);
|
|
370
381
|
}
|
|
371
382
|
case 'collection':
|
|
372
383
|
return resolveCollectionProvider(reg, capName, addonId);
|
|
@@ -401,7 +412,7 @@ export function createCapRouterServices(deps) {
|
|
|
401
412
|
tags: { addonId },
|
|
402
413
|
meta: { capability: capName, validAddonIds: [...known] },
|
|
403
414
|
});
|
|
404
|
-
throw new TRPCError({
|
|
415
|
+
throw new server_1.TRPCError({
|
|
405
416
|
code: 'BAD_REQUEST',
|
|
406
417
|
message: `Capability "${capName}" has no provider with addonId "${addonId}". ` +
|
|
407
418
|
`Valid addonId(s): ${known.join(', ')}. ` +
|
|
@@ -414,30 +425,30 @@ export function createCapRouterServices(deps) {
|
|
|
414
425
|
rejectUnresolvedAddonPin,
|
|
415
426
|
noProvider: (capName, nodeId) => {
|
|
416
427
|
if (nodeId !== undefined && nodeId !== 'hub') {
|
|
417
|
-
throw new TRPCError({
|
|
428
|
+
throw new server_1.TRPCError({
|
|
418
429
|
code: 'PRECONDITION_FAILED',
|
|
419
430
|
message: `Capability "${capName}" not available on node "${nodeId}"`,
|
|
420
431
|
});
|
|
421
432
|
}
|
|
422
|
-
throw new TRPCError({
|
|
433
|
+
throw new server_1.TRPCError({
|
|
423
434
|
code: 'PRECONDITION_FAILED',
|
|
424
435
|
message: `Capability "${capName}" provider not available`,
|
|
425
436
|
});
|
|
426
437
|
},
|
|
427
438
|
noNodeRouting: (capName) => {
|
|
428
|
-
throw new TRPCError({
|
|
439
|
+
throw new server_1.TRPCError({
|
|
429
440
|
code: 'BAD_REQUEST',
|
|
430
441
|
message: `Node routing not available for "${capName}"`,
|
|
431
442
|
});
|
|
432
443
|
},
|
|
433
444
|
badRequest: (message) => {
|
|
434
|
-
throw new TRPCError({ code: 'BAD_REQUEST', message });
|
|
445
|
+
throw new server_1.TRPCError({ code: 'BAD_REQUEST', message });
|
|
435
446
|
},
|
|
436
447
|
// D-1 caller-identity injection: a `caller: 'required'` method whose
|
|
437
448
|
// context carries no authenticated user fails closed — the builder
|
|
438
449
|
// never fabricates an identity.
|
|
439
450
|
unauthorized: (message) => {
|
|
440
|
-
throw new TRPCError({ code: 'UNAUTHORIZED', message });
|
|
451
|
+
throw new server_1.TRPCError({ code: 'UNAUTHORIZED', message });
|
|
441
452
|
},
|
|
442
453
|
// Task 7.5d: a resolved provider that does not implement `method` must
|
|
443
454
|
// fail, not answer `undefined` (200). NOT_IMPLEMENTED mirrors what
|
|
@@ -445,7 +456,7 @@ export function createCapRouterServices(deps) {
|
|
|
445
456
|
// child plane — the hub previously answered silently where the child
|
|
446
457
|
// already throws.
|
|
447
458
|
methodNotFound: (capName, method) => {
|
|
448
|
-
throw new TRPCError({
|
|
459
|
+
throw new server_1.TRPCError({
|
|
449
460
|
code: 'NOT_IMPLEMENTED',
|
|
450
461
|
message: `Capability "${capName}" has no method "${method}"`,
|
|
451
462
|
});
|
|
@@ -459,6 +470,6 @@ export function createCapRouterServices(deps) {
|
|
|
459
470
|
* boundary so the AppRouter TYPE stays codegen-derived while the VALUE is
|
|
460
471
|
* built at runtime from `ALL_CAPABILITY_DEFINITIONS`.
|
|
461
472
|
*/
|
|
462
|
-
|
|
463
|
-
return buildCapRouters(createCapRouterPrimitives(), createCapRouterServices(deps));
|
|
473
|
+
function buildRuntimeCapRouters(deps) {
|
|
474
|
+
return (0, system_1.buildCapRouters)(createCapRouterPrimitives(), createCapRouterServices(deps));
|
|
464
475
|
}
|
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractClientIp = extractClientIp;
|
|
4
|
+
exports.extractCfConnectingIp = extractCfConnectingIp;
|
|
5
|
+
exports.extractPeerIp = extractPeerIp;
|
|
6
|
+
exports.extractUserAgent = extractUserAgent;
|
|
7
|
+
exports.ipClass = ipClass;
|
|
8
|
+
exports.classifyClient = classifyClient;
|
|
9
|
+
exports.classifyClientRequest = classifyClientRequest;
|
|
10
|
+
exports.deriveRelayOnly = deriveRelayOnly;
|
|
11
|
+
exports.isRemoteClientIp = isRemoteClientIp;
|
|
1
12
|
/**
|
|
2
13
|
* Best-effort extraction of the originating client IP from a tRPC
|
|
3
14
|
* request. Order of preference:
|
|
@@ -11,7 +22,7 @@
|
|
|
11
22
|
* calls that carry no HTTP request) — the caller treats `null` as "not
|
|
12
23
|
* remote" so the LAN/direct path stays the safe default.
|
|
13
24
|
*/
|
|
14
|
-
|
|
25
|
+
function extractClientIp(req) {
|
|
15
26
|
if (!req)
|
|
16
27
|
return null;
|
|
17
28
|
// 1. X-Forwarded-For — comma-separated list, client is the FIRST entry.
|
|
@@ -47,7 +58,7 @@ export function extractClientIp(req) {
|
|
|
47
58
|
* direct internet client that forges the header still classifies by its own
|
|
48
59
|
* (remote) peer address. Returns `null` when absent.
|
|
49
60
|
*/
|
|
50
|
-
|
|
61
|
+
function extractCfConnectingIp(req) {
|
|
51
62
|
if (!req)
|
|
52
63
|
return null;
|
|
53
64
|
const raw = req.headers['cf-connecting-ip'];
|
|
@@ -63,7 +74,7 @@ export function extractCfConnectingIp(req) {
|
|
|
63
74
|
* loopback/LAN peer (the local `cloudflared` connector). Returns `null` when
|
|
64
75
|
* no socket is present (mesh-originated calls).
|
|
65
76
|
*/
|
|
66
|
-
|
|
77
|
+
function extractPeerIp(req) {
|
|
67
78
|
if (!req)
|
|
68
79
|
return null;
|
|
69
80
|
const remote = req.socket?.remoteAddress;
|
|
@@ -80,7 +91,7 @@ export function extractPeerIp(req) {
|
|
|
80
91
|
* subscriber's broker attribution with the viewer's UA — the SERVER reads
|
|
81
92
|
* it from the request context; any client-supplied value is ignored.
|
|
82
93
|
*/
|
|
83
|
-
|
|
94
|
+
function extractUserAgent(req) {
|
|
84
95
|
if (!req)
|
|
85
96
|
return null;
|
|
86
97
|
const ua = req.headers['user-agent'];
|
|
@@ -107,7 +118,7 @@ function normalizeIp(ip) {
|
|
|
107
118
|
* Classify a single already-normalised IP literal. Null / unparseable →
|
|
108
119
|
* `'lan'` (the safe default that keeps the low-latency direct path).
|
|
109
120
|
*/
|
|
110
|
-
|
|
121
|
+
function ipClass(ip) {
|
|
111
122
|
if (!ip)
|
|
112
123
|
return 'lan';
|
|
113
124
|
if (ip.includes(':')) {
|
|
@@ -138,7 +149,7 @@ export function ipClass(ip) {
|
|
|
138
149
|
* header is ignored (a direct internet client could forge it) and we classify
|
|
139
150
|
* by the proxy-resolved `clientIp`.
|
|
140
151
|
*/
|
|
141
|
-
|
|
152
|
+
function classifyClient(args) {
|
|
142
153
|
if (args.peerIsLocal && args.cfConnectingIp)
|
|
143
154
|
return ipClass(args.cfConnectingIp);
|
|
144
155
|
return ipClass(args.clientIp);
|
|
@@ -149,7 +160,7 @@ export function classifyClient(args) {
|
|
|
149
160
|
* than forcing a policy. Composes `extractClientIp` (proxy-aware), the
|
|
150
161
|
* `CF-Connecting-IP` header, and the immediate socket peer (CF trust gate).
|
|
151
162
|
*/
|
|
152
|
-
|
|
163
|
+
function classifyClientRequest(req) {
|
|
153
164
|
if (!req)
|
|
154
165
|
return null;
|
|
155
166
|
const clientIp = extractClientIp(req);
|
|
@@ -167,7 +178,7 @@ export function classifyClientRequest(req) {
|
|
|
167
178
|
* direct overlay host pair; forcing TURN would be worse).
|
|
168
179
|
* - `lan` → false (low-latency direct host/srflx path).
|
|
169
180
|
*/
|
|
170
|
-
|
|
181
|
+
function deriveRelayOnly(clientClass) {
|
|
171
182
|
return clientClass === 'remote';
|
|
172
183
|
}
|
|
173
184
|
/**
|
|
@@ -177,7 +188,7 @@ export function deriveRelayOnly(clientClass) {
|
|
|
177
188
|
* (`'vpn'`) is NOT remote (kept on the direct overlay path). Unparseable /
|
|
178
189
|
* null → false (safe LAN default).
|
|
179
190
|
*/
|
|
180
|
-
|
|
191
|
+
function isRemoteClientIp(ip) {
|
|
181
192
|
return ipClass(ip) === 'remote';
|
|
182
193
|
}
|
|
183
194
|
function isIpv4(ip) {
|