@camstack/server 1.2.594 → 1.2.596
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 +225 -219
- package/dist/api/trpc/generated-cap-routers.js +5167 -4852
- 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 +7 -7
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.singletonPreferenceKey = singletonPreferenceKey;
|
|
4
|
+
exports.singletonSwitchRefusal = singletonSwitchRefusal;
|
|
5
|
+
exports.writeSingletonPreference = writeSingletonPreference;
|
|
6
|
+
exports.writeCollectionToggle = writeCollectionToggle;
|
|
7
|
+
exports.writeCollectionEnabledSet = writeCollectionEnabledSet;
|
|
1
8
|
/**
|
|
2
9
|
* The ONE write order for an operator's capability preference: PERSIST, then
|
|
3
10
|
* switch the live registry (D675 amendment, 2026-09-29).
|
|
@@ -21,10 +28,10 @@
|
|
|
21
28
|
* `setCollectionEnabledProviders`) and the `addons` cap's
|
|
22
29
|
* `setCapabilityProviderEnabled`.
|
|
23
30
|
*/
|
|
24
|
-
|
|
25
|
-
|
|
31
|
+
const server_1 = require("@trpc/server");
|
|
32
|
+
const collection_preference_1 = require("./collection-preference");
|
|
26
33
|
/** ConfigService key holding a singleton preference (global or per-node). */
|
|
27
|
-
|
|
34
|
+
function singletonPreferenceKey(capability, nodeId) {
|
|
28
35
|
return nodeId === undefined
|
|
29
36
|
? `capabilities.singleton.${capability}`
|
|
30
37
|
: `capabilities.singletonNode.${capability}.${nodeId}`;
|
|
@@ -60,7 +67,7 @@ function findCapability(registry, capability) {
|
|
|
60
67
|
* Reads the registry's own projection (`providers`, `perNode`), the same sets
|
|
61
68
|
* `setActiveSingleton` checks.
|
|
62
69
|
*/
|
|
63
|
-
|
|
70
|
+
function singletonSwitchRefusal(registry, write) {
|
|
64
71
|
const cap = findCapability(registry, write.capability);
|
|
65
72
|
if (cap === null) {
|
|
66
73
|
return { code: 'NOT_FOUND', message: `Unknown capability: ${write.capability}` };
|
|
@@ -87,10 +94,10 @@ export function singletonSwitchRefusal(registry, write) {
|
|
|
87
94
|
return null;
|
|
88
95
|
}
|
|
89
96
|
function refuse(refusal) {
|
|
90
|
-
throw new TRPCError({ code: refusal.code, message: refusal.message });
|
|
97
|
+
throw new server_1.TRPCError({ code: refusal.code, message: refusal.message });
|
|
91
98
|
}
|
|
92
99
|
/** Persist a singleton preference, then switch the registry. */
|
|
93
|
-
|
|
100
|
+
async function writeSingletonPreference(store, registry, write) {
|
|
94
101
|
await serialised(write.capability, async () => {
|
|
95
102
|
const refusal = singletonSwitchRefusal(registry, write);
|
|
96
103
|
if (refusal !== null)
|
|
@@ -120,7 +127,7 @@ function applyDisabledSet(registry, capability, current, next) {
|
|
|
120
127
|
}
|
|
121
128
|
}
|
|
122
129
|
/** Persist one collection provider's enable/disable, then apply it live. */
|
|
123
|
-
|
|
130
|
+
async function writeCollectionToggle(store, registry, toggle) {
|
|
124
131
|
await serialised(toggle.capability, async () => {
|
|
125
132
|
const cap = requireCollection(registry, toggle.capability);
|
|
126
133
|
if (!cap.providers.includes(toggle.addonId)) {
|
|
@@ -135,7 +142,7 @@ export async function writeCollectionToggle(store, registry, toggle) {
|
|
|
135
142
|
next.delete(toggle.addonId);
|
|
136
143
|
else
|
|
137
144
|
next.add(toggle.addonId);
|
|
138
|
-
await persistCollectionDisabled(store, toggle.capability, [...next]);
|
|
145
|
+
await (0, collection_preference_1.persistCollectionDisabled)(store, toggle.capability, [...next]);
|
|
139
146
|
applyDisabledSet(registry, toggle.capability, current, next);
|
|
140
147
|
});
|
|
141
148
|
}
|
|
@@ -144,7 +151,7 @@ export async function writeCollectionToggle(store, registry, toggle) {
|
|
|
144
151
|
* Registered providers outside `enabledAddonIds` are disabled; a disabled id
|
|
145
152
|
* whose provider is not registered right now keeps its disabled mark.
|
|
146
153
|
*/
|
|
147
|
-
|
|
154
|
+
async function writeCollectionEnabledSet(store, registry, capability, enabledAddonIds) {
|
|
148
155
|
await serialised(capability, async () => {
|
|
149
156
|
const cap = requireCollection(registry, capability);
|
|
150
157
|
const wanted = new Set(enabledAddonIds);
|
|
@@ -156,7 +163,7 @@ export async function writeCollectionEnabledSet(store, registry, capability, ena
|
|
|
156
163
|
else
|
|
157
164
|
next.add(providerId);
|
|
158
165
|
}
|
|
159
|
-
await persistCollectionDisabled(store, capability, [...next]);
|
|
166
|
+
await (0, collection_preference_1.persistCollectionDisabled)(store, capability, [...next]);
|
|
160
167
|
applyDisabledSet(registry, capability, current, next);
|
|
161
168
|
});
|
|
162
169
|
}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createCertificatesRouter = createCertificatesRouter;
|
|
1
4
|
/**
|
|
2
5
|
* Certificates inventory and management - fixed core API for Identity ->
|
|
3
6
|
* Certificates (D855, D856).
|
|
@@ -19,100 +22,100 @@
|
|
|
19
22
|
* the node, which must be paired again. Neither forgets a node:
|
|
20
23
|
* that stays `clusterNodes.forgetNode`.
|
|
21
24
|
*/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
const node_crypto_1 = require("node:crypto");
|
|
26
|
+
const system_1 = require("@camstack/system");
|
|
27
|
+
const server_1 = require("@trpc/server");
|
|
28
|
+
const zod_1 = require("zod");
|
|
29
|
+
const trpc_middleware_js_1 = require("../trpc/trpc.middleware.js");
|
|
27
30
|
const HUB_NODE_ID = 'hub';
|
|
28
31
|
const EXPIRING_SOON_MS = 7 * 86_400_000;
|
|
29
|
-
const TlsStatusRowSchema = z.object({
|
|
30
|
-
mode: z.enum(['generated', 'uploaded', 'disabled']),
|
|
31
|
-
leafFingerprintSha256: z.string().nullable(),
|
|
32
|
-
caFingerprintSha256: z.string().nullable(),
|
|
33
|
-
validTo: z.string().nullable(),
|
|
34
|
-
sans: z.array(z.string()),
|
|
35
|
-
reissueError: z.string().nullable(),
|
|
36
|
-
restartRequired: z.boolean(),
|
|
32
|
+
const TlsStatusRowSchema = zod_1.z.object({
|
|
33
|
+
mode: zod_1.z.enum(['generated', 'uploaded', 'disabled']),
|
|
34
|
+
leafFingerprintSha256: zod_1.z.string().nullable(),
|
|
35
|
+
caFingerprintSha256: zod_1.z.string().nullable(),
|
|
36
|
+
validTo: zod_1.z.string().nullable(),
|
|
37
|
+
sans: zod_1.z.array(zod_1.z.string()),
|
|
38
|
+
reissueError: zod_1.z.string().nullable(),
|
|
39
|
+
restartRequired: zod_1.z.boolean(),
|
|
37
40
|
});
|
|
38
|
-
const NodeHttpsSchema = z.object({
|
|
39
|
-
nodeId: z.string(),
|
|
40
|
-
isHub: z.boolean(),
|
|
41
|
-
online: z.boolean(),
|
|
42
|
-
https: z.discriminatedUnion('kind', [
|
|
43
|
-
z.object({ kind: z.literal('served'), status: TlsStatusRowSchema }),
|
|
44
|
-
z.object({ kind: z.literal('not-served'), reason: z.string() }),
|
|
41
|
+
const NodeHttpsSchema = zod_1.z.object({
|
|
42
|
+
nodeId: zod_1.z.string(),
|
|
43
|
+
isHub: zod_1.z.boolean(),
|
|
44
|
+
online: zod_1.z.boolean(),
|
|
45
|
+
https: zod_1.z.discriminatedUnion('kind', [
|
|
46
|
+
zod_1.z.object({ kind: zod_1.z.literal('served'), status: TlsStatusRowSchema }),
|
|
47
|
+
zod_1.z.object({ kind: zod_1.z.literal('not-served'), reason: zod_1.z.string() }),
|
|
45
48
|
/** The hub could not read it right now: say so, never present it as "none". */
|
|
46
|
-
z.object({ kind: z.literal('unreadable'), reason: z.string() }),
|
|
49
|
+
zod_1.z.object({ kind: zod_1.z.literal('unreadable'), reason: zod_1.z.string() }),
|
|
47
50
|
]),
|
|
48
51
|
});
|
|
49
|
-
const MeshLeafRowSchema = z.object({
|
|
50
|
-
serial: z.string(),
|
|
51
|
-
fingerprintSha256: z.string(),
|
|
52
|
-
notBefore: z.number(),
|
|
53
|
-
notAfter: z.number(),
|
|
54
|
-
issuedAt: z.number(),
|
|
52
|
+
const MeshLeafRowSchema = zod_1.z.object({
|
|
53
|
+
serial: zod_1.z.string(),
|
|
54
|
+
fingerprintSha256: zod_1.z.string(),
|
|
55
|
+
notBefore: zod_1.z.number(),
|
|
56
|
+
notAfter: zod_1.z.number(),
|
|
57
|
+
issuedAt: zod_1.z.number(),
|
|
55
58
|
/** `enroll` | `pairing` | `renewal` | `boot` were issued by the hub; `observed` was read off a live connection. */
|
|
56
|
-
issuedVia: z.enum(['enroll', 'pairing', 'renewal', 'boot', 'observed']),
|
|
57
|
-
status: z.enum(['valid', 'expiring', 'expired', 'revoked']),
|
|
58
|
-
revokedAt: z.number().nullable(),
|
|
59
|
-
revokedReason: z.string().nullable(),
|
|
59
|
+
issuedVia: zod_1.z.enum(['enroll', 'pairing', 'renewal', 'boot', 'observed']),
|
|
60
|
+
status: zod_1.z.enum(['valid', 'expiring', 'expired', 'revoked']),
|
|
61
|
+
revokedAt: zod_1.z.number().nullable(),
|
|
62
|
+
revokedReason: zod_1.z.string().nullable(),
|
|
60
63
|
});
|
|
61
|
-
const MeshNodeSchema = z.object({
|
|
62
|
-
nodeId: z.string(),
|
|
63
|
-
online: z.boolean(),
|
|
64
|
+
const MeshNodeSchema = zod_1.z.object({
|
|
65
|
+
nodeId: zod_1.z.string(),
|
|
66
|
+
online: zod_1.z.boolean(),
|
|
64
67
|
/** The leaf the node holds now: the newest non-revoked one. `null` when none is known. */
|
|
65
68
|
current: MeshLeafRowSchema.nullable(),
|
|
66
69
|
/** The node is connected and presents exactly `current`. `null` when it is offline. */
|
|
67
|
-
presentingCurrent: z.boolean().nullable(),
|
|
70
|
+
presentingCurrent: zod_1.z.boolean().nullable(),
|
|
68
71
|
/** Older and revoked leaves, newest first. */
|
|
69
|
-
history: z.array(MeshLeafRowSchema),
|
|
72
|
+
history: zod_1.z.array(MeshLeafRowSchema),
|
|
70
73
|
});
|
|
71
|
-
const MeshInventorySchema = z.object({
|
|
72
|
-
ca: z.discriminatedUnion('state', [
|
|
73
|
-
z.object({
|
|
74
|
-
state: z.literal('ready'),
|
|
75
|
-
subject: z.string(),
|
|
76
|
-
fingerprintSha256: z.string(),
|
|
77
|
-
validTo: z.string(),
|
|
74
|
+
const MeshInventorySchema = zod_1.z.object({
|
|
75
|
+
ca: zod_1.z.discriminatedUnion('state', [
|
|
76
|
+
zod_1.z.object({
|
|
77
|
+
state: zod_1.z.literal('ready'),
|
|
78
|
+
subject: zod_1.z.string(),
|
|
79
|
+
fingerprintSha256: zod_1.z.string(),
|
|
80
|
+
validTo: zod_1.z.string(),
|
|
78
81
|
}),
|
|
79
|
-
z.object({ state: z.literal('unavailable'), reason: z.string() }),
|
|
82
|
+
zod_1.z.object({ state: zod_1.z.literal('unavailable'), reason: zod_1.z.string() }),
|
|
80
83
|
]),
|
|
81
84
|
/** Serials the hub refuses at the mesh handshake. Persisted with the registry and replayed at boot. */
|
|
82
|
-
revokedSerials: z.array(z.string()),
|
|
85
|
+
revokedSerials: zod_1.z.array(zod_1.z.string()),
|
|
83
86
|
/** `false` while the registry is not up (no settings store): the node list is then incomplete. */
|
|
84
|
-
registryAvailable: z.boolean(),
|
|
87
|
+
registryAvailable: zod_1.z.boolean(),
|
|
85
88
|
/** The hub's mesh TLS listener: `closed` means every agent is refused (e.g. revocations not loaded). */
|
|
86
|
-
listener: z.discriminatedUnion('state', [
|
|
87
|
-
z.object({ state: z.literal('open') }),
|
|
88
|
-
z.object({ state: z.literal('closed'), reason: z.string(), since: z.number() }),
|
|
89
|
-
z.object({ state: z.literal('not-started') }),
|
|
89
|
+
listener: zod_1.z.discriminatedUnion('state', [
|
|
90
|
+
zod_1.z.object({ state: zod_1.z.literal('open') }),
|
|
91
|
+
zod_1.z.object({ state: zod_1.z.literal('closed'), reason: zod_1.z.string(), since: zod_1.z.number() }),
|
|
92
|
+
zod_1.z.object({ state: zod_1.z.literal('not-started') }),
|
|
90
93
|
]),
|
|
91
|
-
nodes: z.array(MeshNodeSchema),
|
|
94
|
+
nodes: zod_1.z.array(MeshNodeSchema),
|
|
92
95
|
});
|
|
93
|
-
const MeshRenewResultSchema = z.discriminatedUnion('ok', [
|
|
94
|
-
z.object({
|
|
95
|
-
ok: z.literal(true),
|
|
96
|
-
nodeId: z.string(),
|
|
97
|
-
oldSerial: z.string().nullable(),
|
|
98
|
-
newSerial: z.string(),
|
|
99
|
-
newNotAfter: z.number(),
|
|
96
|
+
const MeshRenewResultSchema = zod_1.z.discriminatedUnion('ok', [
|
|
97
|
+
zod_1.z.object({
|
|
98
|
+
ok: zod_1.z.literal(true),
|
|
99
|
+
nodeId: zod_1.z.string(),
|
|
100
|
+
oldSerial: zod_1.z.string().nullable(),
|
|
101
|
+
newSerial: zod_1.z.string(),
|
|
102
|
+
newNotAfter: zod_1.z.number(),
|
|
100
103
|
}),
|
|
101
|
-
z.object({
|
|
102
|
-
ok: z.literal(false),
|
|
103
|
-
nodeId: z.string(),
|
|
104
|
-
stage: z.enum(['prepare', 'issue', 'install', 'reconnect', 'confirm']),
|
|
105
|
-
reason: z.string(),
|
|
104
|
+
zod_1.z.object({
|
|
105
|
+
ok: zod_1.z.literal(false),
|
|
106
|
+
nodeId: zod_1.z.string(),
|
|
107
|
+
stage: zod_1.z.enum(['prepare', 'issue', 'install', 'reconnect', 'confirm']),
|
|
108
|
+
reason: zod_1.z.string(),
|
|
106
109
|
/** The node is on its previous leaf (or never left it): nothing was broken. */
|
|
107
|
-
keptPreviousLeaf: z.boolean(),
|
|
110
|
+
keptPreviousLeaf: zod_1.z.boolean(),
|
|
108
111
|
}),
|
|
109
112
|
]);
|
|
110
|
-
const MeshRevokeResultSchema = z.object({
|
|
111
|
-
nodeId: z.string(),
|
|
112
|
-
revokedSerials: z.array(z.string()),
|
|
113
|
-
disconnected: z.number().int(),
|
|
113
|
+
const MeshRevokeResultSchema = zod_1.z.object({
|
|
114
|
+
nodeId: zod_1.z.string(),
|
|
115
|
+
revokedSerials: zod_1.z.array(zod_1.z.string()),
|
|
116
|
+
disconnected: zod_1.z.number().int(),
|
|
114
117
|
/** What the operator does next. Revoking does not forget the node. */
|
|
115
|
-
next: z.string(),
|
|
118
|
+
next: zod_1.z.string(),
|
|
116
119
|
});
|
|
117
120
|
function leafStatus(record, at) {
|
|
118
121
|
if (record.revokedAt !== null)
|
|
@@ -121,11 +124,11 @@ function leafStatus(record, at) {
|
|
|
121
124
|
return 'expired';
|
|
122
125
|
return record.notAfter - at < EXPIRING_SOON_MS ? 'expiring' : 'valid';
|
|
123
126
|
}
|
|
124
|
-
|
|
127
|
+
function createCertificatesRouter(deps) {
|
|
125
128
|
const localNetwork = () => {
|
|
126
129
|
const provider = deps.registry?.getSingleton('local-network');
|
|
127
130
|
if (!provider) {
|
|
128
|
-
throw new TRPCError({
|
|
131
|
+
throw new server_1.TRPCError({
|
|
129
132
|
code: 'PRECONDITION_FAILED',
|
|
130
133
|
message: 'The local-network capability is not available yet',
|
|
131
134
|
});
|
|
@@ -133,22 +136,22 @@ export function createCertificatesRouter(deps) {
|
|
|
133
136
|
return provider;
|
|
134
137
|
};
|
|
135
138
|
const peers = deps.peers ?? {
|
|
136
|
-
peerLeaf: (nodeId) => getProcessPeerLeaf(nodeId),
|
|
137
|
-
dropPeer: (nodeId) => dropProcessPeer(nodeId),
|
|
139
|
+
peerLeaf: (nodeId) => (0, system_1.getProcessPeerLeaf)(nodeId),
|
|
140
|
+
dropPeer: (nodeId) => (0, system_1.dropProcessPeer)(nodeId),
|
|
138
141
|
};
|
|
139
|
-
const meshRegistry = deps.meshRegistry ?? getProcessMeshCertificateRegistry;
|
|
140
|
-
const crl = deps.crl ?? processMeshCrl;
|
|
142
|
+
const meshRegistry = deps.meshRegistry ?? system_1.getProcessMeshCertificateRegistry;
|
|
143
|
+
const crl = deps.crl ?? system_1.processMeshCrl;
|
|
141
144
|
const meshCa = deps.meshCa ??
|
|
142
145
|
(() => {
|
|
143
|
-
const state = getProcessMeshCaState();
|
|
146
|
+
const state = (0, system_1.getProcessMeshCaState)();
|
|
144
147
|
return state.state === 'ready' ? state.ca : null;
|
|
145
148
|
});
|
|
146
|
-
const issueHttps = deps.issueHttps ?? issueAgentHttpsLeaf;
|
|
149
|
+
const issueHttps = deps.issueHttps ?? system_1.issueAgentHttpsLeaf;
|
|
147
150
|
const listenerState = deps.listenerState ??
|
|
148
|
-
(() => getProcessMeshTlsListenerState() ?? { state: 'not-started' });
|
|
149
|
-
const httpsNames = deps.httpsNames ?? getProcessAgentHttpsNames;
|
|
151
|
+
(() => (0, system_1.getProcessMeshTlsListenerState)() ?? { state: 'not-started' });
|
|
152
|
+
const httpsNames = deps.httpsNames ?? system_1.getProcessAgentHttpsNames;
|
|
150
153
|
const registrations = deps.registrations ?? {
|
|
151
|
-
subscribe: (listener) => onProcessNodeRegistered(listener),
|
|
154
|
+
subscribe: (listener) => (0, system_1.onProcessNodeRegistered)(listener),
|
|
152
155
|
};
|
|
153
156
|
/** One certificate operation per node at a time: a second one is refused, not interleaved. */
|
|
154
157
|
const busy = new Set();
|
|
@@ -158,7 +161,7 @@ export function createCertificatesRouter(deps) {
|
|
|
158
161
|
tags: { nodeId: key },
|
|
159
162
|
meta: { what },
|
|
160
163
|
});
|
|
161
|
-
throw new TRPCError({
|
|
164
|
+
throw new server_1.TRPCError({
|
|
162
165
|
code: 'CONFLICT',
|
|
163
166
|
message: `Another certificate operation is already running on ${key}. Wait for it to finish.`,
|
|
164
167
|
});
|
|
@@ -173,14 +176,14 @@ export function createCertificatesRouter(deps) {
|
|
|
173
176
|
};
|
|
174
177
|
const requireAgent = (nodeId) => {
|
|
175
178
|
if (nodeId === HUB_NODE_ID) {
|
|
176
|
-
throw new TRPCError({
|
|
179
|
+
throw new server_1.TRPCError({
|
|
177
180
|
code: 'PRECONDITION_FAILED',
|
|
178
181
|
message: 'The hub is not an agent: its HTTPS leaf is renewed with renewHttpsOnNode on "hub", and its mesh leaf is re-issued at every boot.',
|
|
179
182
|
});
|
|
180
183
|
}
|
|
181
184
|
const client = deps.nodeClient(nodeId);
|
|
182
185
|
if (client === null) {
|
|
183
|
-
throw new TRPCError({
|
|
186
|
+
throw new server_1.TRPCError({
|
|
184
187
|
code: 'PRECONDITION_FAILED',
|
|
185
188
|
message: `Node ${nodeId} is not reachable, or runs an agent too old to manage its certificates (update it).`,
|
|
186
189
|
});
|
|
@@ -213,11 +216,11 @@ export function createCertificatesRouter(deps) {
|
|
|
213
216
|
reissueError: null,
|
|
214
217
|
restartRequired: false,
|
|
215
218
|
});
|
|
216
|
-
return trpcRouter({
|
|
219
|
+
return (0, trpc_middleware_js_1.trpcRouter)({
|
|
217
220
|
/** HTTPS certificate state per node. The hub serves its own; an agent serves a hub-issued leaf. */
|
|
218
|
-
listHttpsCertificates: adminProcedure
|
|
219
|
-
.input(z.void())
|
|
220
|
-
.output(z.array(NodeHttpsSchema))
|
|
221
|
+
listHttpsCertificates: trpc_middleware_js_1.adminProcedure
|
|
222
|
+
.input(zod_1.z.void())
|
|
223
|
+
.output(zod_1.z.array(NodeHttpsSchema))
|
|
221
224
|
.query(async () => {
|
|
222
225
|
const nodes = deps.agentRegistry.listNodeLiveness();
|
|
223
226
|
const entries = nodes.some((n) => n.id === HUB_NODE_ID)
|
|
@@ -307,8 +310,8 @@ export function createCertificatesRouter(deps) {
|
|
|
307
310
|
* local CA for the names the agent reports (private addresses and local-only host
|
|
308
311
|
* names), and the agent hot-swaps it - no restart, no private key on the mesh.
|
|
309
312
|
*/
|
|
310
|
-
renewHttpsOnNode: adminProcedure
|
|
311
|
-
.input(z.object({ nodeId: z.string().min(1), reason: z.string().max(200).optional() }))
|
|
313
|
+
renewHttpsOnNode: trpc_middleware_js_1.adminProcedure
|
|
314
|
+
.input(zod_1.z.object({ nodeId: zod_1.z.string().min(1), reason: zod_1.z.string().max(200).optional() }))
|
|
312
315
|
.output(TlsStatusRowSchema)
|
|
313
316
|
.mutation(async ({ input }) => {
|
|
314
317
|
if (input.nodeId === HUB_NODE_ID) {
|
|
@@ -350,7 +353,7 @@ export function createCertificatesRouter(deps) {
|
|
|
350
353
|
// the authenticated install call, so the node re-pins instead of refusing for ever.
|
|
351
354
|
const caRotation = prepared.pinnedCaFingerprintSha256 !== null &&
|
|
352
355
|
prepared.pinnedCaFingerprintSha256 !==
|
|
353
|
-
new X509Certificate(issued.caCertPem).fingerprint256;
|
|
356
|
+
new node_crypto_1.X509Certificate(issued.caCertPem).fingerprint256;
|
|
354
357
|
deps.log.info('Agent HTTPS leaf issued', {
|
|
355
358
|
tags,
|
|
356
359
|
meta: { accepted: issued.accepted, rejected: issued.rejected },
|
|
@@ -369,7 +372,7 @@ export function createCertificatesRouter(deps) {
|
|
|
369
372
|
catch (error) {
|
|
370
373
|
const message = error instanceof Error ? error.message : String(error);
|
|
371
374
|
deps.log.error('Agent HTTPS renewal failed', { tags, meta: { error: message } });
|
|
372
|
-
throw new TRPCError({
|
|
375
|
+
throw new server_1.TRPCError({
|
|
373
376
|
code: 'INTERNAL_SERVER_ERROR',
|
|
374
377
|
message: `HTTPS renewal on ${input.nodeId} failed: ${message}. The node keeps serving what it had.`,
|
|
375
378
|
});
|
|
@@ -377,17 +380,17 @@ export function createCertificatesRouter(deps) {
|
|
|
377
380
|
});
|
|
378
381
|
}),
|
|
379
382
|
/** The mesh CA, the revocation list, and every node's recorded leaves. */
|
|
380
|
-
getMeshCertificates: adminProcedure
|
|
381
|
-
.input(z.void())
|
|
383
|
+
getMeshCertificates: trpc_middleware_js_1.adminProcedure
|
|
384
|
+
.input(zod_1.z.void())
|
|
382
385
|
.output(MeshInventorySchema)
|
|
383
386
|
.query(async () => {
|
|
384
|
-
const state = getProcessMeshCaState();
|
|
387
|
+
const state = (0, system_1.getProcessMeshCaState)();
|
|
385
388
|
const ca = state.state === 'ready'
|
|
386
389
|
? {
|
|
387
390
|
state: 'ready',
|
|
388
|
-
subject: new X509Certificate(state.ca.certPem).subject,
|
|
389
|
-
fingerprintSha256: caFingerprint(state.ca.certPem),
|
|
390
|
-
validTo: new X509Certificate(state.ca.certPem).validTo,
|
|
391
|
+
subject: new node_crypto_1.X509Certificate(state.ca.certPem).subject,
|
|
392
|
+
fingerprintSha256: (0, system_1.caFingerprint)(state.ca.certPem),
|
|
393
|
+
validTo: new node_crypto_1.X509Certificate(state.ca.certPem).validTo,
|
|
391
394
|
}
|
|
392
395
|
: { state: 'unavailable', reason: state.reason };
|
|
393
396
|
const registry = meshRegistry();
|
|
@@ -437,20 +440,20 @@ export function createCertificatesRouter(deps) {
|
|
|
437
440
|
* after the hub SEES it connected with the new leaf is the old serial revoked. A failed
|
|
438
441
|
* swap keeps the old leaf valid and says why.
|
|
439
442
|
*/
|
|
440
|
-
renewMeshOnNode: adminProcedure
|
|
441
|
-
.input(z.object({ nodeId: z.string().min(1) }))
|
|
443
|
+
renewMeshOnNode: trpc_middleware_js_1.adminProcedure
|
|
444
|
+
.input(zod_1.z.object({ nodeId: zod_1.z.string().min(1) }))
|
|
442
445
|
.output(MeshRenewResultSchema)
|
|
443
446
|
.mutation(async ({ input }) => {
|
|
444
447
|
const client = requireAgent(input.nodeId);
|
|
445
448
|
const ca = meshCa();
|
|
446
449
|
const registry = meshRegistry();
|
|
447
450
|
if (ca === null || registry === null) {
|
|
448
|
-
throw new TRPCError({
|
|
451
|
+
throw new server_1.TRPCError({
|
|
449
452
|
code: 'PRECONDITION_FAILED',
|
|
450
453
|
message: 'The mesh CA or the certificate registry is not available yet.',
|
|
451
454
|
});
|
|
452
455
|
}
|
|
453
|
-
const result = await exclusive(input.nodeId, 'mesh', () => renewMeshCertificate({
|
|
456
|
+
const result = await exclusive(input.nodeId, 'mesh', () => (0, system_1.renewMeshCertificate)({
|
|
454
457
|
nodeId: input.nodeId,
|
|
455
458
|
client,
|
|
456
459
|
ca,
|
|
@@ -473,24 +476,24 @@ export function createCertificatesRouter(deps) {
|
|
|
473
476
|
* connect: it must be paired again. It is NOT forgotten - that stays
|
|
474
477
|
* `clusterNodes.forgetNode`.
|
|
475
478
|
*/
|
|
476
|
-
revokeMeshOnNode: adminProcedure
|
|
477
|
-
.input(z.object({ nodeId: z.string().min(1) }))
|
|
479
|
+
revokeMeshOnNode: trpc_middleware_js_1.adminProcedure
|
|
480
|
+
.input(zod_1.z.object({ nodeId: zod_1.z.string().min(1) }))
|
|
478
481
|
.output(MeshRevokeResultSchema)
|
|
479
482
|
.mutation(async ({ input }) => {
|
|
480
483
|
if (input.nodeId === HUB_NODE_ID) {
|
|
481
|
-
throw new TRPCError({
|
|
484
|
+
throw new server_1.TRPCError({
|
|
482
485
|
code: 'PRECONDITION_FAILED',
|
|
483
486
|
message: "The hub's own mesh leaf is re-issued at every boot; there is nothing to revoke.",
|
|
484
487
|
});
|
|
485
488
|
}
|
|
486
489
|
const registry = meshRegistry();
|
|
487
490
|
if (registry === null) {
|
|
488
|
-
throw new TRPCError({
|
|
491
|
+
throw new server_1.TRPCError({
|
|
489
492
|
code: 'PRECONDITION_FAILED',
|
|
490
493
|
message: 'The certificate registry is not available yet.',
|
|
491
494
|
});
|
|
492
495
|
}
|
|
493
|
-
const result = await revokeMeshCertificate({
|
|
496
|
+
const result = await (0, system_1.revokeMeshCertificate)({
|
|
494
497
|
nodeId: input.nodeId,
|
|
495
498
|
registry,
|
|
496
499
|
crl: crl(),
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createClusterNodesRouter = createClusterNodesRouter;
|
|
1
4
|
/**
|
|
2
5
|
* Cluster-nodes router — fixed core API (not a capability).
|
|
3
6
|
*
|
|
@@ -10,9 +13,9 @@
|
|
|
10
13
|
* `computeTopology` and is intentionally NOT exposed here — the admin UI reads
|
|
11
14
|
* offline rows off the pushed `cluster.topology-snapshot`, never by polling.
|
|
12
15
|
*/
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const ForgetNodeInputSchema = z.object({ nodeId: z.string().min(1) });
|
|
16
|
+
const zod_1 = require("zod");
|
|
17
|
+
const trpc_middleware_js_1 = require("../trpc/trpc.middleware.js");
|
|
18
|
+
const ForgetNodeInputSchema = zod_1.z.object({ nodeId: zod_1.z.string().min(1) });
|
|
16
19
|
/**
|
|
17
20
|
* What forgetting a node ACTUALLY removed.
|
|
18
21
|
*
|
|
@@ -23,21 +26,21 @@ const ForgetNodeInputSchema = z.object({ nodeId: z.string().min(1) });
|
|
|
23
26
|
* sources of its topology row was being purged. An action that changed nothing
|
|
24
27
|
* must not answer `success`.
|
|
25
28
|
*/
|
|
26
|
-
const ForgetNodeResultSchema = z.object({
|
|
29
|
+
const ForgetNodeResultSchema = zod_1.z.object({
|
|
27
30
|
/** At least one source of the node's topology row was purged. */
|
|
28
|
-
forgotten: z.boolean(),
|
|
31
|
+
forgotten: zod_1.z.boolean(),
|
|
29
32
|
/** The durable history row existed and is gone. */
|
|
30
|
-
historyRemoved: z.boolean(),
|
|
33
|
+
historyRemoved: zod_1.z.boolean(),
|
|
31
34
|
/** The Moleculer node-catalog entry existed and is gone. */
|
|
32
|
-
registryRemoved: z.boolean(),
|
|
35
|
+
registryRemoved: zod_1.z.boolean(),
|
|
33
36
|
/** Read back AFTER the attempt: the node is still in the cluster registry. */
|
|
34
|
-
stillListed: z.boolean(),
|
|
37
|
+
stillListed: zod_1.z.boolean(),
|
|
35
38
|
/** One operator-grade sentence naming what happened. */
|
|
36
|
-
message: z.string(),
|
|
39
|
+
message: zod_1.z.string(),
|
|
37
40
|
});
|
|
38
|
-
const RepairNodeAddonsInputSchema = z.object({ nodeId: z.string().min(1) });
|
|
39
|
-
|
|
40
|
-
return trpcRouter({
|
|
41
|
+
const RepairNodeAddonsInputSchema = zod_1.z.object({ nodeId: zod_1.z.string().min(1) });
|
|
42
|
+
function createClusterNodesRouter(agentRegistry) {
|
|
43
|
+
return (0, trpc_middleware_js_1.trpcRouter)({
|
|
41
44
|
/**
|
|
42
45
|
* The explicit half of the addon back-fill's trigger set.
|
|
43
46
|
*
|
|
@@ -52,9 +55,9 @@ export function createClusterNodesRouter(agentRegistry) {
|
|
|
52
55
|
* roster the node itself declared, with the same circuit breaker. Nothing
|
|
53
56
|
* can be repaired by hand that the node could not have converged to.
|
|
54
57
|
*/
|
|
55
|
-
repairNodeAddons: adminProcedure
|
|
58
|
+
repairNodeAddons: trpc_middleware_js_1.adminProcedure
|
|
56
59
|
.input(RepairNodeAddonsInputSchema)
|
|
57
|
-
.output(z.object({ success: z.boolean() }))
|
|
60
|
+
.output(zod_1.z.object({ success: zod_1.z.boolean() }))
|
|
58
61
|
.mutation(async ({ input }) => {
|
|
59
62
|
await agentRegistry.repairNodeAddons(input.nodeId);
|
|
60
63
|
return { success: true };
|
|
@@ -62,7 +65,7 @@ export function createClusterNodesRouter(agentRegistry) {
|
|
|
62
65
|
// Purge one node's persisted offline history. Pairs with
|
|
63
66
|
// `pipelineOrchestrator.removeAgentSettings` on the frontend to fully
|
|
64
67
|
// forget an offline node (history row + per-node pipeline assignments).
|
|
65
|
-
forgetNode: adminProcedure
|
|
68
|
+
forgetNode: trpc_middleware_js_1.adminProcedure
|
|
66
69
|
.input(ForgetNodeInputSchema)
|
|
67
70
|
.output(ForgetNodeResultSchema)
|
|
68
71
|
// The service's own result IS the answer — this procedure adds nothing
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.collectionPreferenceKey = collectionPreferenceKey;
|
|
4
|
+
exports.persistCollectionDisabled = persistCollectionDisabled;
|
|
1
5
|
/** ConfigService key holding the persisted disabled-set for a collection cap. */
|
|
2
|
-
|
|
6
|
+
function collectionPreferenceKey(capability) {
|
|
3
7
|
return `capabilities.collection.${capability}`;
|
|
4
8
|
}
|
|
5
9
|
/**
|
|
6
10
|
* Persist the disabled-addonId set for a collection capability: the set the
|
|
7
11
|
* registry WILL hold once the write has landed and is applied.
|
|
8
12
|
*/
|
|
9
|
-
|
|
13
|
+
async function persistCollectionDisabled(configService, capability, disabled) {
|
|
10
14
|
await configService.set(collectionPreferenceKey(capability), JSON.stringify({ disabled: [...disabled] }));
|
|
11
15
|
}
|