@serfab/cadre-host 1.13.0 → 1.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +347 -423
- package/dist/bin/host.d.ts +6 -3
- package/dist/bin/host.js +332 -524
- package/dist/bin/host.js.map +1 -1
- package/dist/bin/join-output.d.ts +56 -0
- package/dist/bin/join-output.js +92 -0
- package/dist/bin/join-output.js.map +1 -0
- package/dist/bin/nat-output.d.ts +54 -0
- package/dist/bin/nat-output.js +138 -0
- package/dist/bin/nat-output.js.map +1 -0
- package/dist/bin/ui-access.d.ts +22 -0
- package/dist/bin/ui-access.js +44 -0
- package/dist/bin/ui-access.js.map +1 -0
- package/dist/hosted/claim-details.d.ts +66 -0
- package/dist/hosted/claim-details.js +60 -0
- package/dist/hosted/claim-details.js.map +1 -0
- package/dist/hosted/hosted-node-service.d.ts +325 -0
- package/dist/hosted/hosted-node-service.js +678 -0
- package/dist/hosted/hosted-node-service.js.map +1 -0
- package/dist/hosted/hosted-node-store.d.ts +40 -0
- package/dist/hosted/hosted-node-store.js +126 -0
- package/dist/hosted/hosted-node-store.js.map +1 -0
- package/dist/{donation/donation-supervisor.d.ts → hosted/hosted-node-supervisor.d.ts} +70 -53
- package/dist/hosted/hosted-node-supervisor.js +396 -0
- package/dist/hosted/hosted-node-supervisor.js.map +1 -0
- package/dist/hosted/hosted-node-watcher.d.ts +95 -0
- package/dist/hosted/hosted-node-watcher.js +260 -0
- package/dist/hosted/hosted-node-watcher.js.map +1 -0
- package/dist/hosted/index.d.ts +16 -0
- package/dist/hosted/index.js +13 -0
- package/dist/hosted/index.js.map +1 -0
- package/dist/hosted/node-status.d.ts +51 -0
- package/dist/hosted/node-status.js +77 -0
- package/dist/hosted/node-status.js.map +1 -0
- package/dist/hosted/types.d.ts +141 -0
- package/dist/hosted/types.js +22 -0
- package/dist/hosted/types.js.map +1 -0
- package/dist/index.d.ts +12 -24
- package/dist/index.js +9 -19
- package/dist/index.js.map +1 -1
- package/dist/installer/config.d.ts +27 -34
- package/dist/installer/config.js +46 -15
- package/dist/installer/config.js.map +1 -1
- package/dist/installer/index.d.ts +9 -19
- package/dist/installer/index.js +21 -85
- package/dist/installer/index.js.map +1 -1
- package/dist/installer/paths.d.ts +0 -2
- package/dist/installer/paths.js +0 -4
- package/dist/installer/paths.js.map +1 -1
- package/dist/installer/wizard.d.ts +12 -9
- package/dist/installer/wizard.js +15 -14
- package/dist/installer/wizard.js.map +1 -1
- package/dist/nat/address-resolver.d.ts +18 -17
- package/dist/nat/address-resolver.js +79 -25
- package/dist/nat/address-resolver.js.map +1 -1
- package/dist/nat/address-watch.d.ts +37 -0
- package/dist/nat/address-watch.js +84 -0
- package/dist/nat/address-watch.js.map +1 -0
- package/dist/nat/ddns/duckdns.d.ts +2 -1
- package/dist/nat/ddns/duckdns.js +5 -1
- package/dist/nat/ddns/duckdns.js.map +1 -1
- package/dist/nat/ddns/index.d.ts +6 -0
- package/dist/nat/ddns/index.js.map +1 -1
- package/dist/nat/index.d.ts +13 -9
- package/dist/nat/index.js +7 -5
- package/dist/nat/index.js.map +1 -1
- package/dist/nat/nat-service.d.ts +220 -77
- package/dist/nat/nat-service.js +653 -239
- package/dist/nat/nat-service.js.map +1 -1
- package/dist/nat/nat-store.d.ts +12 -5
- package/dist/nat/nat-store.js +124 -29
- package/dist/nat/nat-store.js.map +1 -1
- package/dist/nat/network-mode.d.ts +19 -0
- package/dist/nat/network-mode.js +32 -0
- package/dist/nat/network-mode.js.map +1 -0
- package/dist/nat/port-mapper.d.ts +83 -79
- package/dist/nat/port-mapper.js +148 -189
- package/dist/nat/port-mapper.js.map +1 -1
- package/dist/nat/reachability.d.ts +32 -15
- package/dist/nat/reachability.js +110 -22
- package/dist/nat/reachability.js.map +1 -1
- package/dist/nat/types.d.ts +98 -27
- package/dist/nat/types.js +8 -5
- package/dist/nat/types.js.map +1 -1
- package/dist/orchestrator/host-process-orchestrator.d.ts +32 -74
- package/dist/orchestrator/host-process-orchestrator.js +84 -233
- package/dist/orchestrator/host-process-orchestrator.js.map +1 -1
- package/dist/{installer/identity.d.ts → orchestrator/identity-file.d.ts} +5 -5
- package/dist/{installer/identity.js → orchestrator/identity-file.js} +6 -6
- package/dist/orchestrator/identity-file.js.map +1 -0
- package/dist/orchestrator/index.d.ts +2 -3
- package/dist/orchestrator/index.js +1 -1
- package/dist/orchestrator/index.js.map +1 -1
- package/dist/orchestrator/node-identity.d.ts +6 -6
- package/dist/orchestrator/node-identity.js +7 -7
- package/dist/orchestrator/node-identity.js.map +1 -1
- package/dist/orchestrator/port-allocator.d.ts +5 -6
- package/dist/orchestrator/port-allocator.js +9 -11
- package/dist/orchestrator/port-allocator.js.map +1 -1
- package/dist/orchestrator/state-store.d.ts +3 -5
- package/dist/orchestrator/state-store.js +2 -10
- package/dist/orchestrator/state-store.js.map +1 -1
- package/dist/orchestrator/types.d.ts +33 -22
- package/dist/orchestrator/types.js.map +1 -1
- package/dist/package-version.d.ts +1 -0
- package/dist/package-version.js +4 -0
- package/dist/package-version.js.map +1 -0
- package/dist/server/error-handler.d.ts +5 -25
- package/dist/server/error-handler.js +11 -74
- package/dist/server/error-handler.js.map +1 -1
- package/dist/server/events/types.d.ts +7 -11
- package/dist/server/events/types.js +2 -1
- package/dist/server/events/types.js.map +1 -1
- package/dist/server/index.d.ts +11 -37
- package/dist/server/index.js +30 -48
- package/dist/server/index.js.map +1 -1
- package/dist/server/routes/hosted-nodes.d.ts +28 -0
- package/dist/server/routes/hosted-nodes.js +68 -0
- package/dist/server/routes/hosted-nodes.js.map +1 -0
- package/dist/server/routes/nat.d.ts +4 -1
- package/dist/server/routes/nat.js +13 -2
- package/dist/server/routes/nat.js.map +1 -1
- package/dist/server/routes/nodes.d.ts +6 -20
- package/dist/server/routes/nodes.js +7 -86
- package/dist/server/routes/nodes.js.map +1 -1
- package/dist/server/routes/settings.d.ts +3 -7
- package/dist/server/routes/settings.js +18 -8
- package/dist/server/routes/settings.js.map +1 -1
- package/dist/server/routes/status.d.ts +2 -25
- package/dist/server/routes/status.js +3 -43
- package/dist/server/routes/status.js.map +1 -1
- package/dist/server/server.js +8 -8
- package/dist/server/settings-store.d.ts +2 -2
- package/dist/server/settings-store.js +2 -2
- package/dist/server/static.js +1 -2
- package/dist/server/static.js.map +1 -1
- package/dist/ui/assets/index-BHd8CWZA.css +1 -0
- package/dist/ui/assets/index-Ccr2GjPT.js +23 -0
- package/dist/ui/assets/index-Ccr2GjPT.js.map +1 -0
- package/dist/ui/index.html +2 -2
- package/dist/update/index.d.ts +2 -2
- package/dist/update/index.js +2 -2
- package/dist/update/store.d.ts +1 -1
- package/dist/update/store.js +1 -1
- package/dist/update/types.d.ts +1 -1
- package/dist/update/types.js +1 -1
- package/package.json +5 -7
- package/src/__tests__/cli-nat.smoke.test.ts +219 -212
- package/src/__tests__/cli.smoke.test.ts +2 -2
- package/src/__tests__/global-setup.ts +2 -3
- package/src/__tests__/orchestrator-claim-secret.test.ts +111 -0
- package/src/__tests__/orchestrator-env-scrub.test.ts +160 -163
- package/src/__tests__/orchestrator-handle-contract.ts +134 -134
- package/src/__tests__/orchestrator-node-identity.test.ts +177 -203
- package/src/__tests__/orchestrator-ports.test.ts +124 -143
- package/src/__tests__/orchestrator-push.test.ts +138 -146
- package/src/__tests__/orchestrator.test.ts +1017 -1063
- package/src/__tests__/ui-access.test.ts +30 -0
- package/src/bin/host.ts +397 -572
- package/src/bin/join-output.ts +120 -0
- package/src/bin/nat-output.ts +188 -0
- package/src/bin/ui-access.ts +50 -0
- package/src/{donation → hosted}/__tests__/fake-orchestrator.test.ts +172 -173
- package/src/{donation → hosted}/__tests__/fake-orchestrator.ts +43 -23
- package/src/hosted/__tests__/hosted-node-service.test.ts +708 -0
- package/src/hosted/__tests__/hosted-node-supervisor.test.ts +475 -0
- package/src/hosted/__tests__/test-invitation.ts +33 -0
- package/src/hosted/claim-details.ts +103 -0
- package/src/hosted/hosted-node-service.ts +814 -0
- package/src/hosted/hosted-node-store.ts +144 -0
- package/src/hosted/hosted-node-supervisor.ts +439 -0
- package/src/hosted/hosted-node-watcher.ts +288 -0
- package/src/hosted/index.ts +53 -0
- package/src/hosted/node-status.ts +97 -0
- package/src/hosted/types.ts +160 -0
- package/src/index.ts +72 -91
- package/src/installer/__tests__/config.test.ts +15 -40
- package/src/installer/__tests__/installer.smoke.test.ts +184 -263
- package/src/installer/__tests__/wizard.test.ts +25 -13
- package/src/installer/config.ts +201 -175
- package/src/installer/index.ts +252 -327
- package/src/installer/paths.ts +104 -109
- package/src/installer/wizard.ts +24 -26
- package/src/nat/__tests__/address-resolver.test.ts +107 -82
- package/src/nat/__tests__/nat-service.test.ts +608 -515
- package/src/nat/__tests__/nat-store.test.ts +49 -12
- package/src/nat/__tests__/network-mode.test.ts +38 -0
- package/src/nat/__tests__/port-mapper.test.ts +30 -191
- package/src/nat/__tests__/reachability.test.ts +96 -13
- package/src/nat/address-resolver.ts +94 -52
- package/src/nat/address-watch.ts +92 -0
- package/src/nat/ddns/duckdns.ts +5 -1
- package/src/nat/ddns/index.ts +6 -0
- package/src/nat/index.ts +33 -13
- package/src/nat/nat-service.ts +942 -501
- package/src/nat/nat-store.ts +126 -31
- package/src/nat/network-mode.ts +36 -0
- package/src/nat/port-mapper.ts +241 -329
- package/src/nat/reachability.ts +155 -34
- package/src/nat/types.ts +110 -37
- package/src/{installer/__tests__/identity.test.ts → orchestrator/__tests__/identity-file.test.ts} +34 -34
- package/src/orchestrator/__tests__/node-identity.test.ts +62 -62
- package/src/orchestrator/host-process-orchestrator.ts +1089 -1260
- package/src/{installer/identity.ts → orchestrator/identity-file.ts} +56 -56
- package/src/orchestrator/index.ts +9 -10
- package/src/orchestrator/node-identity.ts +41 -41
- package/src/orchestrator/port-allocator.ts +71 -73
- package/src/orchestrator/state-store.ts +76 -90
- package/src/orchestrator/types.ts +34 -23
- package/src/package-version.ts +4 -0
- package/src/server/__tests__/bus.test.ts +38 -38
- package/src/server/__tests__/error-handler.test.ts +81 -118
- package/src/server/__tests__/fakes.ts +15 -18
- package/src/server/__tests__/hosted-nodes-route.test.ts +161 -0
- package/src/server/__tests__/nodes-route.test.ts +114 -283
- package/src/server/__tests__/publishers.test.ts +193 -180
- package/src/server/__tests__/server.smoke.test.ts +134 -223
- package/src/server/__tests__/settings-route.test.ts +210 -195
- package/src/server/__tests__/sse-route.test.ts +119 -119
- package/src/server/__tests__/status-route.test.ts +82 -121
- package/src/server/error-handler.ts +112 -178
- package/src/server/events/types.ts +20 -24
- package/src/server/index.ts +223 -267
- package/src/server/routes/hosted-nodes.ts +83 -0
- package/src/server/routes/nat.ts +75 -63
- package/src/server/routes/nodes.ts +96 -188
- package/src/server/routes/settings.ts +20 -15
- package/src/server/routes/status.ts +5 -67
- package/src/server/server.ts +8 -8
- package/src/server/settings-store.ts +2 -2
- package/src/server/static.ts +1 -2
- package/src/update/index.ts +2 -2
- package/src/update/store.ts +1 -1
- package/src/update/types.ts +1 -1
- package/dist/auth/duration.d.ts +0 -1
- package/dist/auth/duration.js +0 -32
- package/dist/auth/duration.js.map +0 -1
- package/dist/auth/index.d.ts +0 -11
- package/dist/auth/index.js +0 -9
- package/dist/auth/index.js.map +0 -1
- package/dist/auth/self-label.d.ts +0 -36
- package/dist/auth/self-label.js +0 -57
- package/dist/auth/self-label.js.map +0 -1
- package/dist/auth/trust-circle-store.d.ts +0 -26
- package/dist/auth/trust-circle-store.js +0 -129
- package/dist/auth/trust-circle-store.js.map +0 -1
- package/dist/auth/trust-circle.d.ts +0 -156
- package/dist/auth/trust-circle.js +0 -307
- package/dist/auth/trust-circle.js.map +0 -1
- package/dist/auth/types.d.ts +0 -84
- package/dist/auth/types.js +0 -24
- package/dist/auth/types.js.map +0 -1
- package/dist/donation/donation-service.d.ts +0 -389
- package/dist/donation/donation-service.js +0 -828
- package/dist/donation/donation-service.js.map +0 -1
- package/dist/donation/donation-store.d.ts +0 -51
- package/dist/donation/donation-store.js +0 -152
- package/dist/donation/donation-store.js.map +0 -1
- package/dist/donation/donation-supervisor.js +0 -364
- package/dist/donation/donation-supervisor.js.map +0 -1
- package/dist/donation/grant-service.d.ts +0 -80
- package/dist/donation/grant-service.js +0 -210
- package/dist/donation/grant-service.js.map +0 -1
- package/dist/donation/grant-store.d.ts +0 -38
- package/dist/donation/grant-store.js +0 -135
- package/dist/donation/grant-store.js.map +0 -1
- package/dist/donation/index.d.ts +0 -20
- package/dist/donation/index.js +0 -17
- package/dist/donation/index.js.map +0 -1
- package/dist/donation/types.d.ts +0 -224
- package/dist/donation/types.js +0 -40
- package/dist/donation/types.js.map +0 -1
- package/dist/installer/identity.js.map +0 -1
- package/dist/owner/index.d.ts +0 -11
- package/dist/owner/index.js +0 -11
- package/dist/owner/index.js.map +0 -1
- package/dist/owner/owner-node-client.d.ts +0 -110
- package/dist/owner/owner-node-client.js +0 -184
- package/dist/owner/owner-node-client.js.map +0 -1
- package/dist/server/routes/bootstrap-node-validation.d.ts +0 -115
- package/dist/server/routes/bootstrap-node-validation.js +0 -197
- package/dist/server/routes/bootstrap-node-validation.js.map +0 -1
- package/dist/server/routes/grants-admin.d.ts +0 -29
- package/dist/server/routes/grants-admin.js +0 -58
- package/dist/server/routes/grants-admin.js.map +0 -1
- package/dist/server/routes/grants.d.ts +0 -28
- package/dist/server/routes/grants.js +0 -165
- package/dist/server/routes/grants.js.map +0 -1
- package/dist/server/routes/provision-request-validation.d.ts +0 -45
- package/dist/server/routes/provision-request-validation.js +0 -97
- package/dist/server/routes/provision-request-validation.js.map +0 -1
- package/dist/server/routes/strands.d.ts +0 -20
- package/dist/server/routes/strands.js +0 -38
- package/dist/server/routes/strands.js.map +0 -1
- package/dist/server/routes/trust-circle.d.ts +0 -17
- package/dist/server/routes/trust-circle.js +0 -35
- package/dist/server/routes/trust-circle.js.map +0 -1
- package/dist/strands/index.d.ts +0 -7
- package/dist/strands/index.js +0 -6
- package/dist/strands/index.js.map +0 -1
- package/dist/strands/strand-service.d.ts +0 -50
- package/dist/strands/strand-service.js +0 -103
- package/dist/strands/strand-service.js.map +0 -1
- package/dist/strands/types.d.ts +0 -93
- package/dist/strands/types.js +0 -23
- package/dist/strands/types.js.map +0 -1
- package/dist/ui/assets/index-C6nELNfC.js +0 -23
- package/dist/ui/assets/index-C6nELNfC.js.map +0 -1
- package/dist/ui/assets/index-TtIYSeZO.css +0 -1
- package/src/__tests__/cli-invite.smoke.test.ts +0 -192
- package/src/__tests__/host-owner.smoke.test.ts +0 -123
- package/src/__tests__/orchestrator-owner.test.ts +0 -234
- package/src/__tests__/orchestrator-pin-keys.test.ts +0 -152
- package/src/auth/__tests__/duration.test.ts +0 -28
- package/src/auth/__tests__/self-label.test.ts +0 -85
- package/src/auth/__tests__/trust-circle-integration.test.ts +0 -152
- package/src/auth/__tests__/trust-circle-store.test.ts +0 -115
- package/src/auth/__tests__/trust-circle.test.ts +0 -445
- package/src/auth/duration.ts +0 -33
- package/src/auth/index.ts +0 -21
- package/src/auth/self-label.ts +0 -74
- package/src/auth/trust-circle-store.ts +0 -155
- package/src/auth/trust-circle.ts +0 -395
- package/src/auth/types.ts +0 -99
- package/src/donation/__tests__/donation-service.test.ts +0 -1193
- package/src/donation/__tests__/donation-supervisor.test.ts +0 -548
- package/src/donation/__tests__/grant-service.test.ts +0 -213
- package/src/donation/__tests__/grant-store.test.ts +0 -113
- package/src/donation/donation-service.ts +0 -1033
- package/src/donation/donation-store.ts +0 -176
- package/src/donation/donation-supervisor.ts +0 -411
- package/src/donation/grant-service.ts +0 -252
- package/src/donation/grant-store.ts +0 -152
- package/src/donation/index.ts +0 -65
- package/src/donation/types.ts +0 -260
- package/src/owner/__tests__/owner-node-client.test.ts +0 -194
- package/src/owner/index.ts +0 -12
- package/src/owner/owner-node-client.ts +0 -259
- package/src/server/__tests__/bootstrap-node-validation.test.ts +0 -138
- package/src/server/__tests__/grants-admin-route.test.ts +0 -171
- package/src/server/__tests__/grants-route.test.ts +0 -394
- package/src/server/__tests__/strands-route.test.ts +0 -234
- package/src/server/routes/bootstrap-node-validation.ts +0 -206
- package/src/server/routes/grants-admin.ts +0 -74
- package/src/server/routes/grants.ts +0 -193
- package/src/server/routes/provision-request-validation.ts +0 -105
- package/src/server/routes/strands.ts +0 -54
- package/src/server/routes/trust-circle.ts +0 -49
- package/src/strands/__tests__/strand-service.test.ts +0 -165
- package/src/strands/index.ts +0 -14
- package/src/strands/strand-service.ts +0 -135
- package/src/strands/types.ts +0 -102
package/dist/ui/index.html
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<meta name="color-scheme" content="light dark" />
|
|
7
7
|
<title>cadre-host</title>
|
|
8
|
-
<script type="module" crossorigin src="./assets/index-
|
|
9
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
8
|
+
<script type="module" crossorigin src="./assets/index-Ccr2GjPT.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="./assets/index-BHd8CWZA.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<div id="app"></div>
|
package/dist/update/index.d.ts
CHANGED
|
@@ -98,8 +98,8 @@ export declare class UpdateService {
|
|
|
98
98
|
stop(): void;
|
|
99
99
|
}
|
|
100
100
|
/**
|
|
101
|
-
* Typed handler facade —
|
|
102
|
-
*
|
|
101
|
+
* Typed handler facade — same shape as `createNatHandlers`. The local-UI
|
|
102
|
+
* server consumes these.
|
|
103
103
|
*/
|
|
104
104
|
export declare function createUpdateHandlers(service: UpdateService): UpdateHandlers;
|
|
105
105
|
export type { UpdateState, UpdateApplyResult, UpdateSettings, UpdateManifest, SignedManifest } from './types.js';
|
package/dist/update/index.js
CHANGED
|
@@ -231,8 +231,8 @@ export class UpdateService {
|
|
|
231
231
|
}
|
|
232
232
|
}
|
|
233
233
|
/**
|
|
234
|
-
* Typed handler facade —
|
|
235
|
-
*
|
|
234
|
+
* Typed handler facade — same shape as `createNatHandlers`. The local-UI
|
|
235
|
+
* server consumes these.
|
|
236
236
|
*/
|
|
237
237
|
export function createUpdateHandlers(service) {
|
|
238
238
|
return {
|
package/dist/update/store.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Atomic JSON store for `<dataDir>/update-state.json`.
|
|
3
3
|
*
|
|
4
|
-
* Mirrors `
|
|
4
|
+
* Mirrors `NatStore`: load on demand, write to
|
|
5
5
|
* `<path>.tmp` then rename. Single-writer assumption — only one cadre-host
|
|
6
6
|
* process owns a given dataDir.
|
|
7
7
|
*/
|
package/dist/update/store.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Atomic JSON store for `<dataDir>/update-state.json`.
|
|
3
3
|
*
|
|
4
|
-
* Mirrors `
|
|
4
|
+
* Mirrors `NatStore`: load on demand, write to
|
|
5
5
|
* `<path>.tmp` then rename. Single-writer assumption — only one cadre-host
|
|
6
6
|
* process owns a given dataDir.
|
|
7
7
|
*/
|
package/dist/update/types.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* - apply.ts — invoke `npm install -g` + rollback on failure.
|
|
9
9
|
* - index.ts — composes the above (UpdateService).
|
|
10
10
|
*
|
|
11
|
-
* Mirrors the typed-handler pattern used by
|
|
11
|
+
* Mirrors the typed-handler pattern used by NAT (handlers
|
|
12
12
|
* throw `UpdateError` whose `.code` the local-UI maps to HTTP status).
|
|
13
13
|
*/
|
|
14
14
|
/** Inner manifest object — signed by the release key. */
|
package/dist/update/types.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* - apply.ts — invoke `npm install -g` + rollback on failure.
|
|
9
9
|
* - index.ts — composes the above (UpdateService).
|
|
10
10
|
*
|
|
11
|
-
* Mirrors the typed-handler pattern used by
|
|
11
|
+
* Mirrors the typed-handler pattern used by NAT (handlers
|
|
12
12
|
* throw `UpdateError` whose `.code` the local-UI maps to HTTP status).
|
|
13
13
|
*/
|
|
14
14
|
/** Thrown by UpdateService.apply() and related entry points. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@serfab/cadre-host",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.15.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Self-hosted cadre node manager for basement-PC deployments",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -29,8 +29,7 @@
|
|
|
29
29
|
"cadre",
|
|
30
30
|
"host",
|
|
31
31
|
"self-hosted",
|
|
32
|
-
"p2p"
|
|
33
|
-
"trust-circle"
|
|
32
|
+
"p2p"
|
|
34
33
|
],
|
|
35
34
|
"scripts": {
|
|
36
35
|
"clean": "rimraf dist",
|
|
@@ -64,10 +63,9 @@
|
|
|
64
63
|
"@libp2p/crypto": "^5.1.23",
|
|
65
64
|
"@libp2p/interface": "^3.3.0",
|
|
66
65
|
"@libp2p/peer-id": "^6.0.15",
|
|
67
|
-
"@
|
|
68
|
-
"@serfab/cadre-
|
|
69
|
-
"@serfab/cadre-
|
|
70
|
-
"@serfab/cadre-provider": "^1.13.0",
|
|
66
|
+
"@serfab/cadre-cli": "^1.15.0",
|
|
67
|
+
"@serfab/cadre-core": "^1.15.0",
|
|
68
|
+
"@serfab/cadre-provider": "^1.15.0",
|
|
71
69
|
"commander": "^14.0.2",
|
|
72
70
|
"debug": "^4.4.3",
|
|
73
71
|
"fastify": "^5.7.1",
|
|
@@ -1,212 +1,219 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CLI smoke test for the `nat` subcommand. Spawns a stub HTTP server playing
|
|
3
|
-
* the role of cadre-host's management API and asserts the CLI:
|
|
4
|
-
* - GETs /nat/status
|
|
5
|
-
* - POSTs /nat/test
|
|
6
|
-
* - PUTs /nat/ddns with the expected body
|
|
7
|
-
* - PUTs /nat/settings
|
|
8
|
-
* - Exits non-zero when the host is not reachable
|
|
9
|
-
*
|
|
10
|
-
* Relies on `yarn build` having produced dist/bin/host.js.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import { spawn } from 'node:child_process';
|
|
14
|
-
import { createServer, type IncomingMessage, type Server, type ServerResponse } from 'node:http';
|
|
15
|
-
import { existsSync } from 'node:fs';
|
|
16
|
-
import { fileURLToPath } from 'node:url';
|
|
17
|
-
import { dirname, resolve } from 'node:path';
|
|
18
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
19
|
-
|
|
20
|
-
const here = dirname(fileURLToPath(import.meta.url));
|
|
21
|
-
const binPath = resolve(here, '../../dist/bin/host.js');
|
|
22
|
-
|
|
23
|
-
// These smoke tests cold-start the built CLI as a child process (Node boot +,
|
|
24
|
-
// for some, an HTTP server). That comfortably exceeds vitest's 5s default under
|
|
25
|
-
// heavy parallel load, so give the subprocess generous headroom.
|
|
26
|
-
vi.setConfig({ testTimeout: 30000 });
|
|
27
|
-
|
|
28
|
-
interface StubServer {
|
|
29
|
-
server: Server;
|
|
30
|
-
port: number;
|
|
31
|
-
requests: Array<{ method: string; url: string; body: string }>;
|
|
32
|
-
setResponse(handler: (req: IncomingMessage, res: ServerResponse) => void): void;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const DEFAULT_STATUS = {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
let
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
expect(
|
|
123
|
-
|
|
124
|
-
expect(
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const result = await runCli(['nat', 'status', '--port', String(port)]);
|
|
131
|
-
expect(result.code).toBe(
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
expect(
|
|
141
|
-
expect(
|
|
142
|
-
});
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
describe('cadre-host nat
|
|
146
|
-
it('
|
|
147
|
-
const result = await runCli([
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
expect(
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
'
|
|
175
|
-
'--
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
expect(result.
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
1
|
+
/**
|
|
2
|
+
* CLI smoke test for the `nat` subcommand. Spawns a stub HTTP server playing
|
|
3
|
+
* the role of cadre-host's management API and asserts the CLI:
|
|
4
|
+
* - GETs /nat/status
|
|
5
|
+
* - POSTs /nat/test
|
|
6
|
+
* - PUTs /nat/ddns with the expected body
|
|
7
|
+
* - PUTs /nat/settings
|
|
8
|
+
* - Exits non-zero when the host is not reachable
|
|
9
|
+
*
|
|
10
|
+
* Relies on `yarn build` having produced dist/bin/host.js.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { spawn } from 'node:child_process';
|
|
14
|
+
import { createServer, type IncomingMessage, type Server, type ServerResponse } from 'node:http';
|
|
15
|
+
import { existsSync } from 'node:fs';
|
|
16
|
+
import { fileURLToPath } from 'node:url';
|
|
17
|
+
import { dirname, resolve } from 'node:path';
|
|
18
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
19
|
+
|
|
20
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
21
|
+
const binPath = resolve(here, '../../dist/bin/host.js');
|
|
22
|
+
|
|
23
|
+
// These smoke tests cold-start the built CLI as a child process (Node boot +,
|
|
24
|
+
// for some, an HTTP server). That comfortably exceeds vitest's 5s default under
|
|
25
|
+
// heavy parallel load, so give the subprocess generous headroom.
|
|
26
|
+
vi.setConfig({ testTimeout: 30000 });
|
|
27
|
+
|
|
28
|
+
interface StubServer {
|
|
29
|
+
server: Server;
|
|
30
|
+
port: number;
|
|
31
|
+
requests: Array<{ method: string; url: string; body: string }>;
|
|
32
|
+
setResponse(handler: (req: IncomingMessage, res: ServerResponse) => void): void;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const DEFAULT_STATUS = {
|
|
36
|
+
upnpEnabled: true,
|
|
37
|
+
gateway: { found: true, lanAddress: '192.168.1.20', routerExternalIp: '203.0.113.5', lastError: null },
|
|
38
|
+
externalIp: '203.0.113.5',
|
|
39
|
+
externalIpDetectedAt: new Date().toISOString(),
|
|
40
|
+
cgnatDetected: false,
|
|
41
|
+
directReachability: 'reachable',
|
|
42
|
+
lastTestedAt: null,
|
|
43
|
+
nodes: [
|
|
44
|
+
{
|
|
45
|
+
nodeId: 'owner',
|
|
46
|
+
running: true,
|
|
47
|
+
verdict: 'mapped',
|
|
48
|
+
reason: null,
|
|
49
|
+
tcp: { internalPort: 4001, externalPort: 4001, source: 'upnp', leaseExpiresAt: null, error: null },
|
|
50
|
+
ws: { internalPort: 10001, externalPort: 10001, source: 'upnp', leaseExpiresAt: null, error: null },
|
|
51
|
+
publicAddrs: ['/ip4/203.0.113.5/tcp/4001', '/ip4/203.0.113.5/tcp/10001/ws'],
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
ddns: {
|
|
55
|
+
providerId: 'duckdns',
|
|
56
|
+
hostname: 'foo.duckdns.org',
|
|
57
|
+
externallyManaged: false,
|
|
58
|
+
lastUpdateAt: null,
|
|
59
|
+
lastUpdateOk: null,
|
|
60
|
+
lastError: null,
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
async function startStub(): Promise<StubServer> {
|
|
65
|
+
const requests: StubServer['requests'] = [];
|
|
66
|
+
let handler: (req: IncomingMessage, res: ServerResponse) => void = (_req, res) => {
|
|
67
|
+
res.statusCode = 200;
|
|
68
|
+
res.setHeader('content-type', 'application/json');
|
|
69
|
+
res.end(JSON.stringify(DEFAULT_STATUS));
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const server = createServer((req, res) => {
|
|
73
|
+
const chunks: Buffer[] = [];
|
|
74
|
+
req.on('data', (chunk: Buffer) => chunks.push(chunk));
|
|
75
|
+
req.on('end', () => {
|
|
76
|
+
requests.push({ method: req.method ?? '', url: req.url ?? '', body: Buffer.concat(chunks).toString('utf8') });
|
|
77
|
+
handler(req, res);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
await new Promise<void>((resolveStart) => server.listen(0, '127.0.0.1', () => resolveStart()));
|
|
82
|
+
const addr = server.address();
|
|
83
|
+
const port = typeof addr === 'object' && addr ? addr.port : 0;
|
|
84
|
+
return {
|
|
85
|
+
server,
|
|
86
|
+
port,
|
|
87
|
+
requests,
|
|
88
|
+
setResponse: (h) => { handler = h; },
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function runCli(args: string[]): Promise<{ code: number; stdout: string; stderr: string }> {
|
|
93
|
+
return new Promise((resolveRun) => {
|
|
94
|
+
const child = spawn(process.execPath, [binPath, ...args], { stdio: ['ignore', 'pipe', 'pipe'] });
|
|
95
|
+
let stdout = '';
|
|
96
|
+
let stderr = '';
|
|
97
|
+
child.stdout.on('data', (chunk: Buffer) => { stdout += chunk.toString('utf8'); });
|
|
98
|
+
child.stderr.on('data', (chunk: Buffer) => { stderr += chunk.toString('utf8'); });
|
|
99
|
+
child.on('close', (code) => resolveRun({ code: code ?? -1, stdout, stderr }));
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
let stub: StubServer;
|
|
104
|
+
|
|
105
|
+
beforeEach(async () => {
|
|
106
|
+
if (!existsSync(binPath)) {
|
|
107
|
+
throw new Error(`cadre-host bin not built at ${binPath}; run \`yarn build\` first`);
|
|
108
|
+
}
|
|
109
|
+
stub = await startStub();
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
afterEach(async () => {
|
|
113
|
+
await new Promise<void>((resolveClose) => stub.server.close(() => resolveClose()));
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
describe('cadre-host nat status', () => {
|
|
117
|
+
it('GETs /nat/status and renders the snapshot', async () => {
|
|
118
|
+
const result = await runCli(['nat', 'status', '--port', String(stub.port)]);
|
|
119
|
+
expect(result.code).toBe(0);
|
|
120
|
+
expect(stub.requests).toHaveLength(1);
|
|
121
|
+
expect(stub.requests[0]!.method).toBe('GET');
|
|
122
|
+
expect(stub.requests[0]!.url).toBe('/nat/status');
|
|
123
|
+
expect(result.stdout).toContain('reachable');
|
|
124
|
+
expect(result.stdout).toContain('203.0.113.5');
|
|
125
|
+
expect(result.stdout).toContain('owner: mapped');
|
|
126
|
+
expect(result.stdout).toContain('foo.duckdns.org');
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('--json prints raw JSON', async () => {
|
|
130
|
+
const result = await runCli(['nat', 'status', '--port', String(stub.port), '--json']);
|
|
131
|
+
expect(result.code).toBe(0);
|
|
132
|
+
const parsed = JSON.parse(result.stdout);
|
|
133
|
+
expect(parsed.directReachability).toBe('reachable');
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('exits 2 when cadre-host is unreachable', async () => {
|
|
137
|
+
const port = stub.port;
|
|
138
|
+
await new Promise<void>((resolveClose) => stub.server.close(() => resolveClose()));
|
|
139
|
+
const result = await runCli(['nat', 'status', '--port', String(port)]);
|
|
140
|
+
expect(result.code).toBe(2);
|
|
141
|
+
expect(result.stderr).toMatch(/cadre-host start|Failed to reach/);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
describe('cadre-host nat test', () => {
|
|
146
|
+
it('POSTs /nat/test', async () => {
|
|
147
|
+
const result = await runCli(['nat', 'test', '--port', String(stub.port)]);
|
|
148
|
+
expect(result.code).toBe(0);
|
|
149
|
+
expect(stub.requests[0]!.method).toBe('POST');
|
|
150
|
+
expect(stub.requests[0]!.url).toBe('/nat/test');
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
describe('cadre-host nat ddns set', () => {
|
|
155
|
+
it('PUTs /nat/ddns with provider + hostname + token', async () => {
|
|
156
|
+
const result = await runCli([
|
|
157
|
+
'nat', 'ddns', 'set', 'duckdns',
|
|
158
|
+
'--hostname', 'foo.duckdns.org',
|
|
159
|
+
'--token', 'TOK',
|
|
160
|
+
'--port', String(stub.port),
|
|
161
|
+
]);
|
|
162
|
+
expect(result.code).toBe(0);
|
|
163
|
+
expect(stub.requests[0]!.method).toBe('PUT');
|
|
164
|
+
expect(stub.requests[0]!.url).toBe('/nat/ddns');
|
|
165
|
+
const body = JSON.parse(stub.requests[0]!.body);
|
|
166
|
+
expect(body.providerId).toBe('duckdns');
|
|
167
|
+
expect(body.hostname).toBe('foo.duckdns.org');
|
|
168
|
+
expect(body.config).toEqual({ token: 'TOK' });
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it('exits 1 when --hostname is missing', async () => {
|
|
172
|
+
const result = await runCli([
|
|
173
|
+
'nat', 'ddns', 'set', 'duckdns',
|
|
174
|
+
'--token', 'TOK',
|
|
175
|
+
'--port', String(stub.port),
|
|
176
|
+
]);
|
|
177
|
+
expect(result.code).toBe(1);
|
|
178
|
+
expect(result.stderr).toMatch(/--hostname/);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it('exits 1 when --token is missing on a non-TTY stdin', async () => {
|
|
182
|
+
const result = await runCli([
|
|
183
|
+
'nat', 'ddns', 'set', 'duckdns',
|
|
184
|
+
'--hostname', 'foo.duckdns.org',
|
|
185
|
+
'--port', String(stub.port),
|
|
186
|
+
]);
|
|
187
|
+
expect(result.code).toBe(1);
|
|
188
|
+
expect(result.stderr).toMatch(/--token/);
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
describe('cadre-host nat ddns external', () => {
|
|
193
|
+
it('PUTs /nat/settings with externallyManaged=true', async () => {
|
|
194
|
+
const result = await runCli([
|
|
195
|
+
'nat', 'ddns', 'external',
|
|
196
|
+
'--hostname', 'mydomain.example.com',
|
|
197
|
+
'--port', String(stub.port),
|
|
198
|
+
]);
|
|
199
|
+
expect(result.code).toBe(0);
|
|
200
|
+
expect(stub.requests[0]!.method).toBe('PUT');
|
|
201
|
+
expect(stub.requests[0]!.url).toBe('/nat/settings');
|
|
202
|
+
const body = JSON.parse(stub.requests[0]!.body);
|
|
203
|
+
expect(body.ddns.hostname).toBe('mydomain.example.com');
|
|
204
|
+
expect(body.ddns.externallyManaged).toBe(true);
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
describe('cadre-host nat settings', () => {
|
|
209
|
+
it('PUTs /nat/settings with --no-upnp', async () => {
|
|
210
|
+
const result = await runCli([
|
|
211
|
+
'nat', 'settings',
|
|
212
|
+
'--no-upnp',
|
|
213
|
+
'--port', String(stub.port),
|
|
214
|
+
]);
|
|
215
|
+
expect(result.code).toBe(0);
|
|
216
|
+
expect(stub.requests[0]!.url).toBe('/nat/settings');
|
|
217
|
+
expect(JSON.parse(stub.requests[0]!.body)).toEqual({ upnpEnabled: false });
|
|
218
|
+
});
|
|
219
|
+
});
|
|
@@ -28,7 +28,7 @@ describe('cadre-host CLI smoke test', () => {
|
|
|
28
28
|
});
|
|
29
29
|
|
|
30
30
|
expect(stdout.length).toBeGreaterThan(0);
|
|
31
|
-
for (const cmd of ['install', 'start', 'status', '
|
|
31
|
+
for (const cmd of ['install', 'start', 'status', 'uninstall']) {
|
|
32
32
|
expect(stdout).toContain(cmd);
|
|
33
33
|
}
|
|
34
34
|
});
|
|
@@ -42,7 +42,7 @@ describe('cadre-host CLI smoke test', () => {
|
|
|
42
42
|
encoding: 'utf8',
|
|
43
43
|
});
|
|
44
44
|
// The built CLI reads package.json at runtime, so this holds even against a
|
|
45
|
-
// stale dist — it catches
|
|
45
|
+
// stale dist — it catches dist/package-version.js resolving the wrong path.
|
|
46
46
|
const pkg = JSON.parse(
|
|
47
47
|
readFileSync(resolve(here, '../../package.json'), 'utf8'),
|
|
48
48
|
) as { version: string };
|
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
* Vitest global setup — runs once before the whole cadre-host suite.
|
|
3
3
|
*
|
|
4
4
|
* `src/update/manifest.ts` and `src/push/index.ts` import real symbols from
|
|
5
|
-
* `@serfab/cadre-core` (`canonicalJson`, `validatePushCredentials`)
|
|
6
|
-
*
|
|
7
|
-
* it too. `@serfab/cadre-core`'s compiled entry point in turn imports
|
|
5
|
+
* `@serfab/cadre-core` (`canonicalJson`, `validatePushCredentials`).
|
|
6
|
+
* `@serfab/cadre-core`'s compiled entry point in turn imports
|
|
8
7
|
* `@serfab/quereus-plugin-sereus`, which imports the `@optimystic/*` and
|
|
9
8
|
* `@quereus/quereus` packages linked in from their sibling checkouts.
|
|
10
9
|
* `host-process-orchestrator.ts` also resolves `@serfab/cadre-cli`'s bin path at
|