@camstack/system 1.0.2
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/addon-api-factory.d.ts +35 -0
- package/dist/addon-routes/addon-route-registry.d.ts +37 -0
- package/dist/addon-runner.js +599 -0
- package/dist/addon-runner.mjs +597 -0
- package/dist/auth/api-key-manager.d.ts +26 -0
- package/dist/auth/auth-manager.d.ts +109 -0
- package/dist/auth/parse-record.d.ts +18 -0
- package/dist/auth/scope-matcher.d.ts +7 -0
- package/dist/auth/scoped-token-manager.d.ts +40 -0
- package/dist/auth/totp-manager.d.ts +51 -0
- package/dist/auth/user-manager.d.ts +34 -0
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.d.ts +53 -0
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +259 -0
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +251 -0
- package/dist/builtins/addon-pages-aggregator/dedupe-pages.d.ts +6 -0
- package/dist/builtins/addon-pages-aggregator/index.d.ts +1 -0
- package/dist/builtins/addon-pages-aggregator/index.js +8 -0
- package/dist/builtins/addon-pages-aggregator/index.mjs +2 -0
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.d.ts +47 -0
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +228 -0
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +220 -0
- package/dist/builtins/addon-widgets-aggregator/index.d.ts +1 -0
- package/dist/builtins/addon-widgets-aggregator/index.js +8 -0
- package/dist/builtins/addon-widgets-aggregator/index.mjs +2 -0
- package/dist/builtins/alerts/alerts.addon.d.ts +81 -0
- package/dist/builtins/alerts/alerts.addon.js +601 -0
- package/dist/builtins/alerts/alerts.addon.mjs +595 -0
- package/dist/builtins/alerts/index.d.ts +1 -0
- package/dist/builtins/alerts/index.js +4 -0
- package/dist/builtins/alerts/index.mjs +2 -0
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.d.ts +147 -0
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +2229 -0
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +2220 -0
- package/dist/builtins/backup-orchestrator/cron-helpers.d.ts +23 -0
- package/dist/builtins/backup-orchestrator/destination-policy.d.ts +72 -0
- package/dist/builtins/backup-orchestrator/download-helpers.d.ts +12 -0
- package/dist/builtins/backup-orchestrator/index.d.ts +2 -0
- package/dist/builtins/backup-orchestrator/index.js +8 -0
- package/dist/builtins/backup-orchestrator/index.mjs +2 -0
- package/dist/builtins/backup-orchestrator/manifest-store.d.ts +77 -0
- package/dist/builtins/console-logging/console-destination.d.ts +13 -0
- package/dist/builtins/console-logging/console-logging.addon.d.ts +25 -0
- package/dist/builtins/console-logging/index.d.ts +3 -0
- package/dist/builtins/console-logging/index.js +104 -0
- package/dist/builtins/console-logging/index.mjs +95 -0
- package/dist/builtins/device-manager/device-config-contribution.d.ts +32 -0
- package/dist/builtins/device-manager/device-event-propagator.d.ts +26 -0
- package/dist/builtins/device-manager/device-link-overlay.d.ts +23 -0
- package/dist/builtins/device-manager/device-link-resolver.d.ts +15 -0
- package/dist/builtins/device-manager/device-manager.addon.d.ts +452 -0
- package/dist/builtins/device-manager/device-manager.addon.js +3299 -0
- package/dist/builtins/device-manager/device-manager.addon.mjs +3292 -0
- package/dist/builtins/device-manager/index.d.ts +2 -0
- package/dist/builtins/device-manager/index.js +8 -0
- package/dist/builtins/device-manager/index.mjs +2 -0
- package/dist/builtins/hub-forwarder/hub-forwarder-destination.d.ts +44 -0
- package/dist/builtins/hub-forwarder/hub-forwarder.addon.d.ts +15 -0
- package/dist/builtins/hub-forwarder/index.d.ts +3 -0
- package/dist/builtins/hub-forwarder/index.js +154 -0
- package/dist/builtins/hub-forwarder/index.mjs +145 -0
- package/dist/builtins/local-auth/auth-schema.d.ts +26 -0
- package/dist/builtins/local-auth/index.d.ts +1 -0
- package/dist/builtins/local-auth/index.js +4 -0
- package/dist/builtins/local-auth/index.mjs +2 -0
- package/dist/builtins/local-auth/local-auth.addon.d.ts +18 -0
- package/dist/builtins/local-auth/local-auth.addon.js +8094 -0
- package/dist/builtins/local-auth/local-auth.addon.mjs +8063 -0
- package/dist/builtins/local-auth/oauth-grants.d.ts +45 -0
- package/dist/builtins/local-auth/oauth-session-manager.d.ts +50 -0
- package/dist/builtins/local-network/index.d.ts +2 -0
- package/dist/builtins/local-network/index.js +10 -0
- package/dist/builtins/local-network/index.mjs +2 -0
- package/dist/builtins/local-network/local-network.addon.d.ts +150 -0
- package/dist/builtins/local-network/local-network.addon.js +489 -0
- package/dist/builtins/local-network/local-network.addon.mjs +477 -0
- package/dist/builtins/native-metrics/index.d.ts +2 -0
- package/dist/builtins/native-metrics/native-metrics-provider.d.ts +48 -0
- package/dist/builtins/native-metrics/native-metrics.addon.d.ts +73 -0
- package/dist/builtins/native-metrics/native-metrics.addon.js +922 -0
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +914 -0
- package/dist/builtins/platform-probe/hardware-decode-accel-probe.d.ts +37 -0
- package/dist/builtins/platform-probe/hardware-encoder-probe.d.ts +13 -0
- package/dist/builtins/platform-probe/index.d.ts +22 -0
- package/dist/builtins/platform-probe/index.js +834 -0
- package/dist/builtins/platform-probe/index.mjs +822 -0
- package/dist/builtins/platform-probe/inference-config-resolver.d.ts +29 -0
- package/dist/builtins/platform-probe/intel-accelerators.d.ts +11 -0
- package/dist/builtins/platform-probe/platform-scorer.d.ts +30 -0
- package/dist/builtins/platform-probe/runtime-packages.d.ts +6 -0
- package/dist/builtins/remote-access-orchestrator/enabled-providers-reconcile.d.ts +96 -0
- package/dist/builtins/remote-access-orchestrator/index.d.ts +1 -0
- package/dist/builtins/remote-access-orchestrator/index.js +8 -0
- package/dist/builtins/remote-access-orchestrator/index.mjs +2 -0
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.d.ts +40 -0
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +214 -0
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +208 -0
- package/dist/builtins/shared/settle-sources.d.ts +22 -0
- package/dist/builtins/snapshot/index.d.ts +2 -0
- package/dist/builtins/snapshot/index.js +494 -0
- package/dist/builtins/snapshot/index.mjs +488 -0
- package/dist/builtins/snapshot/snapshot.addon.d.ts +120 -0
- package/dist/builtins/sqlite-storage/config-store.d.ts +8 -0
- package/dist/builtins/sqlite-storage/device-store.d.ts +23 -0
- package/dist/builtins/sqlite-storage/filesystem-browse-provider.d.ts +25 -0
- package/dist/builtins/sqlite-storage/filesystem-storage-provider.d.ts +83 -0
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.d.ts +32 -0
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +396 -0
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +388 -0
- package/dist/builtins/sqlite-storage/index.d.ts +8 -0
- package/dist/builtins/sqlite-storage/index.js +62 -0
- package/dist/builtins/sqlite-storage/index.mjs +49 -0
- package/dist/builtins/sqlite-storage/integration-registry.d.ts +27 -0
- package/dist/builtins/sqlite-storage/path-guard.d.ts +4 -0
- package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts +102 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.d.ts +14 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +644 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +636 -0
- package/dist/builtins/storage-orchestrator/index.d.ts +6 -0
- package/dist/builtins/storage-orchestrator/index.js +10 -0
- package/dist/builtins/storage-orchestrator/index.mjs +2 -0
- package/dist/builtins/storage-orchestrator/location-store.d.ts +49 -0
- package/dist/builtins/storage-orchestrator/provider-discovery.d.ts +10 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +103 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1138 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1128 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.service.d.ts +236 -0
- package/dist/builtins/storage-orchestrator/storage-pressure-manager.d.ts +38 -0
- package/dist/builtins/system-backup/system-backup.service.d.ts +137 -0
- package/dist/builtins/system-config/index.d.ts +1 -0
- package/dist/builtins/system-config/index.js +8 -0
- package/dist/builtins/system-config/index.mjs +2 -0
- package/dist/builtins/system-config/system-config.addon.d.ts +10 -0
- package/dist/builtins/system-config/system-config.addon.js +232 -0
- package/dist/builtins/system-config/system-config.addon.mjs +226 -0
- package/dist/builtins/winston-logging/index.d.ts +3 -0
- package/dist/builtins/winston-logging/index.js +156 -0
- package/dist/builtins/winston-logging/index.mjs +144 -0
- package/dist/builtins/winston-logging/winston-destination.d.ts +21 -0
- package/dist/builtins/winston-logging/winston-logging.addon.d.ts +19 -0
- package/dist/chunk-CNf5ZN-e.mjs +37 -0
- package/dist/chunk-Cek0wNdY.js +64 -0
- package/dist/download/model-download-service.d.ts +41 -0
- package/dist/download/model-downloader.d.ts +31 -0
- package/dist/events/event-bus.d.ts +10 -0
- package/dist/events/system-event-bus.d.ts +14 -0
- package/dist/feature/feature-manager.d.ts +11 -0
- package/dist/formatter-B7qW8bPJ.mjs +162 -0
- package/dist/formatter-DqAKDlvN.js +167 -0
- package/dist/http/authenticated-file-server.d.ts +53 -0
- package/dist/http/data-plane-registry.d.ts +23 -0
- package/dist/http/file-data-plane.d.ts +10 -0
- package/dist/http/reverse-proxy.d.ts +15 -0
- package/dist/index.d.ts +82 -0
- package/dist/index.js +93485 -0
- package/dist/index.mjs +93179 -0
- package/dist/intel-accelerators-Gg0P5mnl.js +20 -0
- package/dist/intel-accelerators-hGgpZ0pX.mjs +19 -0
- package/dist/kernel/addon-class-resolver.d.ts +4 -0
- package/dist/kernel/addon-engine-manager.d.ts +22 -0
- package/dist/kernel/addon-health-monitor.d.ts +154 -0
- package/dist/kernel/addon-installer.d.ts +208 -0
- package/dist/kernel/addon-loader.d.ts +106 -0
- package/dist/kernel/addon-manifest.d.ts +77 -0
- package/dist/kernel/capability-handle.d.ts +46 -0
- package/dist/kernel/capability-registry.d.ts +412 -0
- package/dist/kernel/config-manager.d.ts +212 -0
- package/dist/kernel/config-schema.d.ts +93 -0
- package/dist/kernel/custom-action-registry.d.ts +23 -0
- package/dist/kernel/deps/addon-deps-manager.d.ts +19 -0
- package/dist/kernel/deps/manifest-native-deps.d.ts +25 -0
- package/dist/kernel/deps/manifest-python-deps.d.ts +20 -0
- package/dist/kernel/device-registry.d.ts +29 -0
- package/dist/kernel/fs-utils.d.ts +41 -0
- package/dist/kernel/hwaccel/hwaccel-resolver.d.ts +19 -0
- package/dist/kernel/hwaccel/hwaccel-service.d.ts +4 -0
- package/dist/kernel/index.d.ts +74 -0
- package/dist/kernel/infra-capabilities.d.ts +13 -0
- package/dist/kernel/moleculer/addon-context-factory.d.ts +91 -0
- package/dist/kernel/moleculer/addon-data-plane-facility.d.ts +19 -0
- package/dist/kernel/moleculer/addon-runner.d.ts +1 -0
- package/dist/kernel/moleculer/addon-service-factory.d.ts +50 -0
- package/dist/kernel/moleculer/broker-factory.d.ts +50 -0
- package/dist/kernel/moleculer/cap-usage-registry.d.ts +46 -0
- package/dist/kernel/moleculer/capabilities-access.d.ts +21 -0
- package/dist/kernel/moleculer/child-addon-call-dispatch.d.ts +46 -0
- package/dist/kernel/moleculer/child-cap-dispatch.d.ts +20 -0
- package/dist/kernel/moleculer/cluster-secret.d.ts +15 -0
- package/dist/kernel/moleculer/core-cap-service.d.ts +50 -0
- package/dist/kernel/moleculer/crash-supervisor.d.ts +50 -0
- package/dist/kernel/moleculer/device-cap-proxy.d.ts +79 -0
- package/dist/kernel/moleculer/event-bus-core.d.ts +53 -0
- package/dist/kernel/moleculer/event-bus.d.ts +53 -0
- package/dist/kernel/moleculer/hub-log-forwarder.d.ts +36 -0
- package/dist/kernel/moleculer/hub-service.d.ts +35 -0
- package/dist/kernel/moleculer/node-registry.d.ts +126 -0
- package/dist/kernel/moleculer/process-context.d.ts +4 -0
- package/dist/kernel/moleculer/process-service.d.ts +72 -0
- package/dist/kernel/moleculer/provider-registry.d.ts +28 -0
- package/dist/kernel/moleculer/readiness-context.d.ts +62 -0
- package/dist/kernel/moleculer/readiness-service.d.ts +7 -0
- package/dist/kernel/moleculer/register-node-client.d.ts +35 -0
- package/dist/kernel/moleculer/remote-logger.d.ts +43 -0
- package/dist/kernel/moleculer/resilient-cap-call.d.ts +28 -0
- package/dist/kernel/moleculer/stream-probe-service.d.ts +9 -0
- package/dist/kernel/moleculer/trpc-links.d.ts +189 -0
- package/dist/kernel/moleculer/typed-array-serde.d.ts +25 -0
- package/dist/kernel/moleculer/worker-device-restore.d.ts +10 -0
- package/dist/kernel/provider-kind-drift.d.ts +12 -0
- package/dist/kernel/restart-coordinator.d.ts +90 -0
- package/dist/kernel/storage-location-registry.d.ts +40 -0
- package/dist/kernel/transport/cap-action-name.d.ts +100 -0
- package/dist/kernel/transport/cap-route-resolver.d.ts +148 -0
- package/dist/kernel/transport/cap-route.d.ts +148 -0
- package/dist/kernel/transport/child-cap-protocol.d.ts +136 -0
- package/dist/kernel/transport/create-local-transport.d.ts +7 -0
- package/dist/kernel/transport/frame-codec.d.ts +7 -0
- package/dist/kernel/transport/index.d.ts +27 -0
- package/dist/kernel/transport/local-child-client.d.ts +136 -0
- package/dist/kernel/transport/local-child-registry.d.ts +179 -0
- package/dist/kernel/transport/local-endpoint-path.d.ts +6 -0
- package/dist/kernel/transport/local-transport.d.ts +46 -0
- package/dist/kernel/transport/parent-unowned-call.d.ts +75 -0
- package/dist/kernel/transport/socket-channel.d.ts +27 -0
- package/dist/kernel/transport/uds-event-bridge.d.ts +36 -0
- package/dist/kernel/transport/uds-event-bus.d.ts +22 -0
- package/dist/kernel/transport/uds-local-transport.d.ts +18 -0
- package/dist/kernel/transport/uds-log-ingest.d.ts +28 -0
- package/dist/kernel/transport/uds-logger.d.ts +44 -0
- package/dist/kernel/utils/ring-buffer.d.ts +15 -0
- package/dist/kernel/workspace-detect.d.ts +9 -0
- package/dist/lifecycle/lifecycle-state-machine.d.ts +28 -0
- package/dist/logging/formatter.d.ts +30 -0
- package/dist/logging/log-manager.d.ts +54 -0
- package/dist/logging/log-ring-buffer.d.ts +47 -0
- package/dist/logging/partitioned-log-buffer.d.ts +35 -0
- package/dist/logging/scoped-logger.d.ts +17 -0
- package/dist/main-DNnMW7Z2.js +9983 -0
- package/dist/main-rtjOwPBR.mjs +9976 -0
- package/dist/manifest-python-deps-D1DbAQEv.js +6724 -0
- package/dist/manifest-python-deps-DZsKTbs1.mjs +6315 -0
- package/dist/network/network-quality.d.ts +11 -0
- package/dist/notification/notification-service.d.ts +37 -0
- package/dist/notification/toast-service.d.ts +22 -0
- package/dist/pipeline/engine-manager-resolver.d.ts +15 -0
- package/dist/pipeline/pipeline-runner.d.ts +8 -0
- package/dist/pipeline/pipeline-validator.d.ts +13 -0
- package/dist/process/resource-monitor.d.ts +11 -0
- package/dist/python/python-env-manager.d.ts +12 -0
- package/dist/repl/interfaces.d.ts +31 -0
- package/dist/repl/repl-engine.d.ts +8 -0
- package/dist/resource-monitor-ClDGFyf6.mjs +57 -0
- package/dist/resource-monitor-IIEanuJt.js +74 -0
- package/dist/settle-sources-Bhsy57y-.js +38 -0
- package/dist/settle-sources-CDtNC8ub.mjs +33 -0
- package/dist/storage/fs-storage-backend.d.ts +40 -0
- package/dist/storage/storage-location-manager.d.ts +23 -0
- package/dist/storage/storage-manager.d.ts +83 -0
- package/dist/tar-BgAEMRBR.js +5434 -0
- package/dist/tar-ByMOPNM0.mjs +5429 -0
- package/dist/tls/cert-manager.d.ts +26 -0
- package/dist/tls/index.d.ts +1 -0
- package/package.json +343 -0
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
3
|
+
let _camstack_types = require("@camstack/types");
|
|
4
|
+
let node_os = require("node:os");
|
|
5
|
+
node_os = require_chunk.__toESM(node_os);
|
|
6
|
+
//#region src/builtins/local-network/local-network.addon.ts
|
|
7
|
+
/**
|
|
8
|
+
* local-network — hub-only system cap implementation.
|
|
9
|
+
*
|
|
10
|
+
* Wraps `os.networkInterfaces()` with:
|
|
11
|
+
* - Coarse kind classification (lan/wifi/docker/vpn/loopback/other)
|
|
12
|
+
* - Auto-select heuristic for the outbound interface
|
|
13
|
+
* - Periodic poll (30s) + diff to emit `LocalNetworkChanged` events
|
|
14
|
+
* so subscribers can react to DHCP renewals, VPN connect, etc.
|
|
15
|
+
* - `getConnectionEndpoints()` — ranked URL list for SDK clients
|
|
16
|
+
*
|
|
17
|
+
* Does NOT poll the cloudflare-tunnel state directly; the public
|
|
18
|
+
* tunnel hostname (if any) is provided by `network-access` consumers
|
|
19
|
+
* via `NetworkTunnelStarted/Stopped` events on the bus, so the cap
|
|
20
|
+
* stays free of cross-addon dependencies.
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Forked `mesh-network` provider addon ids `local-network` pull-reconciles
|
|
24
|
+
* against. `mesh-network` is a COLLECTION cap, so a hub builtin's local
|
|
25
|
+
* registry can't enumerate forked providers — we resolve each by addonId
|
|
26
|
+
* via `getProviderByAddon`. New mesh providers (Headscale, ZeroTier) add
|
|
27
|
+
* their id here.
|
|
28
|
+
*/
|
|
29
|
+
var MESH_PROVIDER_ADDON_IDS = ["tailscale-client"];
|
|
30
|
+
var POLL_INTERVAL_MS = 3e4;
|
|
31
|
+
var LocalNetworkAddon = class extends _camstack_types.BaseAddon {
|
|
32
|
+
pollTimer = null;
|
|
33
|
+
lastSnapshotKey = "";
|
|
34
|
+
/** Optional public hostname tracked from `NetworkTunnelStarted`/
|
|
35
|
+
* `Stopped` events on the bus. */
|
|
36
|
+
publicHostname = "";
|
|
37
|
+
/**
|
|
38
|
+
* Mesh-reachable endpoint (Tailscale MagicDNS / 100.x), learned from
|
|
39
|
+
* the `MeshNetworkChanged` event-tail and refreshed by a pull-reconcile
|
|
40
|
+
* before each `getConnectionEndpoints` build (events are lossy — D8).
|
|
41
|
+
* `null` when no mesh provider is joined.
|
|
42
|
+
*/
|
|
43
|
+
meshEndpoint = null;
|
|
44
|
+
constructor() {
|
|
45
|
+
super({
|
|
46
|
+
allowedAddresses: [],
|
|
47
|
+
bootSeeded: false
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
async onInitialize() {
|
|
51
|
+
if (!this.config.bootSeeded) {
|
|
52
|
+
const seed = autoSeedAllowlist(this.enumerate());
|
|
53
|
+
await this.updateGlobalSettings({
|
|
54
|
+
allowedAddresses: seed,
|
|
55
|
+
bootSeeded: true
|
|
56
|
+
});
|
|
57
|
+
this.ctx.logger.info("local-network: first-boot auto-seed", { meta: { addresses: seed } });
|
|
58
|
+
}
|
|
59
|
+
const provider = {
|
|
60
|
+
list: async () => ({
|
|
61
|
+
interfaces: this.enumerate(),
|
|
62
|
+
probedAt: Date.now()
|
|
63
|
+
}),
|
|
64
|
+
getPreferred: async () => pickPreferred(applyAllowlist(this.enumerate(), this.config.allowedAddresses)),
|
|
65
|
+
getConnectionEndpoints: async (input) => {
|
|
66
|
+
const includeLoopback = input.includeLoopback ?? true;
|
|
67
|
+
const ipv4Only = input.ipv4Only ?? false;
|
|
68
|
+
const scheme = input.scheme ?? "http";
|
|
69
|
+
const allow = this.config.allowedAddresses;
|
|
70
|
+
const interfaces = applyAllowlist(this.enumerate(), allow);
|
|
71
|
+
await this.reconcileMeshEndpoint();
|
|
72
|
+
return { endpoints: buildEndpoints(interfaces, input.port, includeLoopback, ipv4Only, this.publicHostname, scheme, this.meshEndpoint) };
|
|
73
|
+
},
|
|
74
|
+
getAllowedAddresses: async () => ({ addresses: this.config.allowedAddresses }),
|
|
75
|
+
resetAllowlistToBestMatch: async () => {
|
|
76
|
+
const seed = autoSeedAllowlist(this.enumerate());
|
|
77
|
+
await this.updateGlobalSettings({
|
|
78
|
+
allowedAddresses: seed,
|
|
79
|
+
bootSeeded: true
|
|
80
|
+
});
|
|
81
|
+
this.ctx.logger.info("local-network: allowlist reset to auto-seed", { meta: { count: seed.length } });
|
|
82
|
+
return { addresses: seed };
|
|
83
|
+
},
|
|
84
|
+
setAllowedAddresses: async ({ addresses }) => {
|
|
85
|
+
const known = new Set(this.enumerate().map((i) => i.address));
|
|
86
|
+
const cleaned = [...new Set(addresses)].filter((a) => known.has(a));
|
|
87
|
+
await this.updateGlobalSettings({ allowedAddresses: cleaned });
|
|
88
|
+
this.ctx.logger.info("local-network: allowlist updated", { meta: {
|
|
89
|
+
count: cleaned.length,
|
|
90
|
+
dropped: addresses.length - cleaned.length
|
|
91
|
+
} });
|
|
92
|
+
return { success: true };
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
this.lastSnapshotKey = snapshotKey(this.enumerate());
|
|
96
|
+
this.pollTimer = setInterval(() => this.detectChanges(), POLL_INTERVAL_MS);
|
|
97
|
+
this.pollTimer.unref?.();
|
|
98
|
+
this.ctx.eventBus?.subscribe({ category: _camstack_types.EventCategory.NetworkTunnelStarted }, (event) => {
|
|
99
|
+
const data = event.data ?? {};
|
|
100
|
+
if (typeof data.url === "string") try {
|
|
101
|
+
const hostname = new URL(data.url).hostname;
|
|
102
|
+
if (hostname && !hostname.endsWith(".placeholder") && !hostname.startsWith("pending.")) this.setPublicHostname(hostname);
|
|
103
|
+
} catch {}
|
|
104
|
+
});
|
|
105
|
+
this.ctx.eventBus?.subscribe({ category: _camstack_types.EventCategory.NetworkTunnelStopped }, () => this.setPublicHostname(""));
|
|
106
|
+
this.ctx.eventBus?.subscribe({ category: _camstack_types.EventCategory.MeshNetworkChanged }, (event) => {
|
|
107
|
+
const data = event.data ?? {};
|
|
108
|
+
const host = typeof data.host === "string" ? data.host : "";
|
|
109
|
+
const port = typeof data.port === "number" ? data.port : 0;
|
|
110
|
+
this.setMeshEndpoint(host && port > 0 ? {
|
|
111
|
+
host,
|
|
112
|
+
port
|
|
113
|
+
} : null);
|
|
114
|
+
});
|
|
115
|
+
this.ctx.logger.info("local-network initialized", { meta: { interfaceCount: this.enumerate().length } });
|
|
116
|
+
return [{
|
|
117
|
+
capability: _camstack_types.localNetworkCapability,
|
|
118
|
+
provider
|
|
119
|
+
}];
|
|
120
|
+
}
|
|
121
|
+
async onShutdown() {
|
|
122
|
+
if (this.pollTimer) {
|
|
123
|
+
clearInterval(this.pollTimer);
|
|
124
|
+
this.pollTimer = null;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Other hub addons (e.g. cloudflare-tunnel) signal the active public
|
|
129
|
+
* FQDN by emitting `NetworkTunnelStarted` on the bus — handled in
|
|
130
|
+
* `onInitialize`. This setter exists for tests + future direct
|
|
131
|
+
* callers; cleared by passing an empty string.
|
|
132
|
+
*/
|
|
133
|
+
setPublicHostname(hostname) {
|
|
134
|
+
if (this.publicHostname === hostname) return;
|
|
135
|
+
this.publicHostname = hostname;
|
|
136
|
+
this.ctx.logger.info("local-network: public hostname updated", { meta: { hostname: hostname || "(cleared)" } });
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Replace the cached mesh endpoint. Set from the `MeshNetworkChanged`
|
|
140
|
+
* event-tail + the pull-reconcile; exposed for tests + future direct
|
|
141
|
+
* callers. Pass `null` to clear (mesh left / no provider joined).
|
|
142
|
+
*/
|
|
143
|
+
setMeshEndpoint(endpoint) {
|
|
144
|
+
const prev = this.meshEndpoint;
|
|
145
|
+
if (prev?.host === endpoint?.host && prev?.port === endpoint?.port) return;
|
|
146
|
+
this.meshEndpoint = endpoint;
|
|
147
|
+
this.ctx.logger.info("local-network: mesh endpoint updated", { meta: {
|
|
148
|
+
host: endpoint?.host || "(cleared)",
|
|
149
|
+
port: endpoint?.port ?? 0
|
|
150
|
+
} });
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Refresh the cached mesh endpoint from the authoritative forked
|
|
154
|
+
* `mesh-network` provider(s). `mesh-network` is a COLLECTION cap on a
|
|
155
|
+
* forked addon, so the hub builtin can't see it via `ctx.api` /
|
|
156
|
+
* `getCollectionEntries` — we resolve each provider by addonId through
|
|
157
|
+
* the hub-side `capabilityRegistry.getProviderByAddon` resolver (the
|
|
158
|
+
* same mechanism `device-manager` uses for cross-process exporter
|
|
159
|
+
* contributions). Best-effort: a provider that's absent / errors /
|
|
160
|
+
* not joined simply contributes nothing.
|
|
161
|
+
*/
|
|
162
|
+
async reconcileMeshEndpoint() {
|
|
163
|
+
const registry = this.ctx.kernel.capabilityRegistry;
|
|
164
|
+
if (!registry) return;
|
|
165
|
+
for (const addonId of MESH_PROVIDER_ADDON_IDS) {
|
|
166
|
+
const provider = registry.getProviderByAddon("mesh-network", addonId);
|
|
167
|
+
if (!provider) continue;
|
|
168
|
+
try {
|
|
169
|
+
const status = await provider.getStatus();
|
|
170
|
+
if (!status.joined) {
|
|
171
|
+
this.setMeshEndpoint(null);
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
const host = status.magicDnsHostname || status.meshIp;
|
|
175
|
+
const port = (status.endpoints.find((e) => e.id === "magicdns") ?? status.endpoints.find((e) => e.id === "mesh-ipv4"))?.port ?? 0;
|
|
176
|
+
this.setMeshEndpoint(host && port > 0 ? {
|
|
177
|
+
host,
|
|
178
|
+
port
|
|
179
|
+
} : null);
|
|
180
|
+
return;
|
|
181
|
+
} catch (err) {
|
|
182
|
+
this.ctx.logger.debug("local-network: mesh reconcile skipped", { meta: {
|
|
183
|
+
addonId,
|
|
184
|
+
error: err instanceof Error ? err.message : String(err)
|
|
185
|
+
} });
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
enumerate() {
|
|
190
|
+
return enumerateOsInterfaces(node_os.networkInterfaces());
|
|
191
|
+
}
|
|
192
|
+
detectChanges() {
|
|
193
|
+
const interfaces = this.enumerate();
|
|
194
|
+
const key = snapshotKey(interfaces);
|
|
195
|
+
if (key === this.lastSnapshotKey) return;
|
|
196
|
+
this.ctx.logger.info("local-network: interface set changed", { meta: {
|
|
197
|
+
count: interfaces.length,
|
|
198
|
+
key
|
|
199
|
+
} });
|
|
200
|
+
this.lastSnapshotKey = key;
|
|
201
|
+
this.ctx.eventBus?.emit({
|
|
202
|
+
id: `local-network-changed-${Date.now()}`,
|
|
203
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
204
|
+
source: {
|
|
205
|
+
type: "core",
|
|
206
|
+
id: "local-network"
|
|
207
|
+
},
|
|
208
|
+
category: _camstack_types.EventCategory.LocalNetworkChanged,
|
|
209
|
+
data: { count: interfaces.length }
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
function enumerateOsInterfaces(ifaces) {
|
|
214
|
+
const raw = [];
|
|
215
|
+
for (const [name, addrs] of Object.entries(ifaces)) {
|
|
216
|
+
if (!addrs) continue;
|
|
217
|
+
for (const a of addrs) {
|
|
218
|
+
if (a.family !== "IPv4" && a.family !== "IPv6") continue;
|
|
219
|
+
raw.push({
|
|
220
|
+
name,
|
|
221
|
+
family: a.family,
|
|
222
|
+
address: a.address,
|
|
223
|
+
cidr: a.cidr ?? "",
|
|
224
|
+
netmask: a.netmask,
|
|
225
|
+
internal: a.internal,
|
|
226
|
+
mac: a.mac
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
const classified = raw.map((r) => {
|
|
231
|
+
const kind = classifyKind(r.name, r.address, r.internal);
|
|
232
|
+
const reachableKind = kind === "lan" || kind === "wifi";
|
|
233
|
+
const plausible = !r.internal && reachableKind && isPlausibleAutoSeed(r.address, r.family);
|
|
234
|
+
const plausibleReason = plausible ? "" : explainNonPlausible({
|
|
235
|
+
kind,
|
|
236
|
+
family: r.family,
|
|
237
|
+
address: r.address,
|
|
238
|
+
internal: r.internal
|
|
239
|
+
});
|
|
240
|
+
return {
|
|
241
|
+
name: r.name,
|
|
242
|
+
family: r.family,
|
|
243
|
+
address: r.address,
|
|
244
|
+
cidr: r.cidr,
|
|
245
|
+
netmask: r.netmask,
|
|
246
|
+
internal: r.internal,
|
|
247
|
+
mac: r.mac,
|
|
248
|
+
kind,
|
|
249
|
+
preferred: false,
|
|
250
|
+
plausible,
|
|
251
|
+
plausibleReason
|
|
252
|
+
};
|
|
253
|
+
});
|
|
254
|
+
const preferred = pickPreferred(classified);
|
|
255
|
+
return classified.map((iface) => ({
|
|
256
|
+
...iface,
|
|
257
|
+
preferred: preferred !== null && iface.name === preferred.name && iface.address === preferred.address
|
|
258
|
+
}));
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Filter the interface list by the operator's allowlist. Empty
|
|
262
|
+
* allowlist = no-op (every interface passes); otherwise only entries
|
|
263
|
+
* whose `address` matches an allowlist entry remain. Loopback always
|
|
264
|
+
* survives so the SDK keeps `127.0.0.1` as the last-resort fallback.
|
|
265
|
+
*/
|
|
266
|
+
function applyAllowlist(interfaces, allowed) {
|
|
267
|
+
if (allowed.length === 0) return interfaces;
|
|
268
|
+
const set = new Set(allowed);
|
|
269
|
+
return interfaces.filter((i) => i.kind === "loopback" || set.has(i.address));
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Rank interfaces and pick the auto-selected outbound one. See the
|
|
273
|
+
* cap's `getPreferred` doc for the heuristic.
|
|
274
|
+
*/
|
|
275
|
+
function pickPreferred(interfaces) {
|
|
276
|
+
const candidates = interfaces.filter((i) => !i.internal && i.family === "IPv4" && !i.address.startsWith("169.254.") && i.kind !== "loopback");
|
|
277
|
+
if (candidates.length === 0) return null;
|
|
278
|
+
const kindRank = {
|
|
279
|
+
lan: 1,
|
|
280
|
+
wifi: 2,
|
|
281
|
+
vpn: 3,
|
|
282
|
+
docker: 4,
|
|
283
|
+
other: 5,
|
|
284
|
+
loopback: 99
|
|
285
|
+
};
|
|
286
|
+
return [...candidates].toSorted((a, b) => {
|
|
287
|
+
const ra = kindRank[a.kind];
|
|
288
|
+
const rb = kindRank[b.kind];
|
|
289
|
+
if (ra !== rb) return ra - rb;
|
|
290
|
+
return prefixLen(b.netmask) - prefixLen(a.netmask);
|
|
291
|
+
})[0] ?? null;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Build the ordered candidate URL list. Priority schema:
|
|
295
|
+
* 0 — preferred LAN IPv4
|
|
296
|
+
* 10+ — other LAN IPv4
|
|
297
|
+
* 100 — public tunnel hostname (always HTTPS)
|
|
298
|
+
* 150 — mesh endpoint (Tailscale MagicDNS / 100.x, always HTTPS)
|
|
299
|
+
* 200+ — LAN IPv6
|
|
300
|
+
* 1000 — loopback (last resort)
|
|
301
|
+
*
|
|
302
|
+
* The mesh endpoint ranks just below a true public funnel (a Funnel is
|
|
303
|
+
* reachable by ANY client; the mesh needs the peer on the same tailnet)
|
|
304
|
+
* but above the IPv6 / loopback fallbacks — giving remote, mesh-joined
|
|
305
|
+
* clients a working candidate when no public tunnel is up.
|
|
306
|
+
*
|
|
307
|
+
* `scheme` controls LAN + loopback URLs. Browsers running over HTTPS
|
|
308
|
+
* block `http://` candidates as mixed content, so callers loaded over
|
|
309
|
+
* HTTPS should pass `scheme: 'https'` even when probing a LAN IP — the
|
|
310
|
+
* hub's cert manager already issues a SAN-multi cert covering local
|
|
311
|
+
* interfaces. The public tunnel + mesh endpoint always emit `https://`
|
|
312
|
+
* (the tunnel edge / the hub itself terminates TLS).
|
|
313
|
+
*/
|
|
314
|
+
function buildEndpoints(interfaces, port, includeLoopback, ipv4Only, publicHostname, scheme = "http", meshEndpoint = null) {
|
|
315
|
+
const out = [];
|
|
316
|
+
let priority = 0;
|
|
317
|
+
const preferred = pickPreferred(interfaces);
|
|
318
|
+
const emit = (iface, kind, label, baseUrl, pri) => {
|
|
319
|
+
out.push({
|
|
320
|
+
label,
|
|
321
|
+
baseUrl,
|
|
322
|
+
kind,
|
|
323
|
+
interfaceKind: iface.kind,
|
|
324
|
+
plausible: iface.plausible,
|
|
325
|
+
plausibleReason: iface.plausibleReason,
|
|
326
|
+
priority: pri
|
|
327
|
+
});
|
|
328
|
+
};
|
|
329
|
+
if (preferred) emit(preferred, "lan-ipv4", `${formatKind(preferred.kind)} — ${preferred.name}`, `${scheme}://${preferred.address}:${port}`, priority++);
|
|
330
|
+
for (const iface of interfaces) {
|
|
331
|
+
if (iface.internal || iface.family !== "IPv4") continue;
|
|
332
|
+
if (iface.kind === "loopback") continue;
|
|
333
|
+
if (preferred && iface.name === preferred.name && iface.address === preferred.address) continue;
|
|
334
|
+
if (iface.address.startsWith("169.254.")) continue;
|
|
335
|
+
emit(iface, "lan-ipv4", `${formatKind(iface.kind)} — ${iface.name}`, `${scheme}://${iface.address}:${port}`, 10 + priority++);
|
|
336
|
+
}
|
|
337
|
+
if (publicHostname) out.push({
|
|
338
|
+
label: "Public tunnel",
|
|
339
|
+
baseUrl: `https://${publicHostname}`,
|
|
340
|
+
kind: "public",
|
|
341
|
+
interfaceKind: "public",
|
|
342
|
+
plausible: true,
|
|
343
|
+
plausibleReason: "",
|
|
344
|
+
priority: 100
|
|
345
|
+
});
|
|
346
|
+
if (meshEndpoint && meshEndpoint.host) out.push({
|
|
347
|
+
label: "Mesh (Tailscale)",
|
|
348
|
+
baseUrl: `https://${meshEndpoint.host}:${meshEndpoint.port}`,
|
|
349
|
+
kind: "public",
|
|
350
|
+
interfaceKind: "vpn",
|
|
351
|
+
plausible: true,
|
|
352
|
+
plausibleReason: "",
|
|
353
|
+
priority: 150
|
|
354
|
+
});
|
|
355
|
+
if (!ipv4Only) {
|
|
356
|
+
let v6prio = 200;
|
|
357
|
+
for (const iface of interfaces) {
|
|
358
|
+
if (iface.internal || iface.family !== "IPv6") continue;
|
|
359
|
+
if (iface.kind === "loopback") continue;
|
|
360
|
+
if (iface.address.startsWith("fe80:")) continue;
|
|
361
|
+
emit(iface, "lan-ipv6", `${formatKind(iface.kind)} — ${iface.name} (IPv6)`, `${scheme}://[${iface.address}]:${port}`, v6prio++);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
if (includeLoopback) out.push({
|
|
365
|
+
label: "Loopback",
|
|
366
|
+
baseUrl: `${scheme}://127.0.0.1:${port}`,
|
|
367
|
+
kind: "loopback",
|
|
368
|
+
interfaceKind: "loopback",
|
|
369
|
+
plausible: false,
|
|
370
|
+
plausibleReason: "Loopback — last-resort fallback when no other endpoint responds.",
|
|
371
|
+
priority: 1e3
|
|
372
|
+
});
|
|
373
|
+
return out.toSorted((a, b) => a.priority - b.priority);
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* First-boot heuristic: which addresses should the allowlist start
|
|
377
|
+
* with? Includes LAN + Wi-Fi IPv4 addresses + plausible IPv6:
|
|
378
|
+
*
|
|
379
|
+
* - **IPv4**: skip link-local (`169.254.*`), keep the rest.
|
|
380
|
+
* - **IPv6**: skip link-local (`fe80::*`), unspecified, and
|
|
381
|
+
* multicast. Keep ULAs (`fc00::/7` → `fc??:` / `fd??:`) and Global
|
|
382
|
+
* Unicast addresses (`2000::/3` → `2???`/`3???`). Privacy-extension
|
|
383
|
+
* temporary addresses get included by default; the operator can
|
|
384
|
+
* prune them from the Network Addresses tab if the rotating IPs
|
|
385
|
+
* become a nuisance.
|
|
386
|
+
*
|
|
387
|
+
* Skips docker/vpn/loopback/other entirely — those stay opt-in.
|
|
388
|
+
*/
|
|
389
|
+
function autoSeedAllowlist(interfaces) {
|
|
390
|
+
return [...new Set(interfaces.filter((i) => !i.internal && (i.kind === "lan" || i.kind === "wifi") && isPlausibleAutoSeed(i.address, i.family)).map((i) => i.address))];
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Per-interface tooltip text surfaced on the "Unlikely usable" badge.
|
|
394
|
+
* Server-side so the UI doesn't re-derive the rationale (single source
|
|
395
|
+
* of truth). Returns `''` for plausible entries; the addon overlays
|
|
396
|
+
* this on the `LocalInterface.plausibleReason` field.
|
|
397
|
+
*/
|
|
398
|
+
function explainNonPlausible(input) {
|
|
399
|
+
if (input.internal) return "Internal interface (loopback) — not reachable from clients.";
|
|
400
|
+
if (input.kind === "docker") return "Docker bridge — only reachable from inside the container network.";
|
|
401
|
+
if (input.kind === "vpn") return "VPN tunnel — only reachable while the VPN is connected.";
|
|
402
|
+
if (input.kind === "other") return "Unrecognised interface kind — verify reachability before pinning.";
|
|
403
|
+
if (input.family === "IPv6") {
|
|
404
|
+
const a = input.address.toLowerCase();
|
|
405
|
+
if (a.startsWith("fe80:")) return "IPv6 link-local — only reachable on the same link, not routed.";
|
|
406
|
+
if (a.startsWith("ff")) return "IPv6 multicast — not a unicast address.";
|
|
407
|
+
if (a === "::" || a === "::1") return "IPv6 loopback / unspecified — not a public address.";
|
|
408
|
+
return "IPv6 address outside the ULA / GUA ranges — verify before pinning.";
|
|
409
|
+
}
|
|
410
|
+
if (input.address.startsWith("169.254.")) return "IPv4 link-local (RFC 3927) — only valid when DHCP fails.";
|
|
411
|
+
return "Address looks unusual for client traffic — verify before pinning.";
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Per-address gate used by `autoSeedAllowlist`. Exposed for tests so
|
|
415
|
+
* we can pin every classification rule without standing up the addon.
|
|
416
|
+
*/
|
|
417
|
+
function isPlausibleAutoSeed(address, family) {
|
|
418
|
+
if (family === "IPv4") {
|
|
419
|
+
if (address.startsWith("169.254.")) return false;
|
|
420
|
+
return true;
|
|
421
|
+
}
|
|
422
|
+
const a = address.toLowerCase();
|
|
423
|
+
if (a === "::" || a === "::1") return false;
|
|
424
|
+
if (a.startsWith("fe80:")) return false;
|
|
425
|
+
if (a.startsWith("ff")) return false;
|
|
426
|
+
if (/^f[cd][0-9a-f]{0,2}:/.test(a)) return true;
|
|
427
|
+
if (/^[23][0-9a-f]{0,3}:/.test(a)) return true;
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
function classifyKind(name, address, internal) {
|
|
431
|
+
if (internal || name === "lo" || name.startsWith("lo")) return "loopback";
|
|
432
|
+
const n = name.toLowerCase();
|
|
433
|
+
if (n.startsWith("docker") || n.startsWith("br-") || n.startsWith("veth")) return "docker";
|
|
434
|
+
if (n.startsWith("tun") || n.startsWith("utun") || n.startsWith("wg") || n.startsWith("tap")) return "vpn";
|
|
435
|
+
if (n.startsWith("wlan") || n.startsWith("wlp") || n.startsWith("wlx")) return "wifi";
|
|
436
|
+
if (n.startsWith("eth") || /^en\d+$/.test(n)) {
|
|
437
|
+
if (process.platform === "darwin" && /^en[1-9]\d*$/.test(n)) return "wifi";
|
|
438
|
+
return "lan";
|
|
439
|
+
}
|
|
440
|
+
if (address === "127.0.0.1" || address === "::1") return "loopback";
|
|
441
|
+
return "other";
|
|
442
|
+
}
|
|
443
|
+
/** Convert an IPv4/IPv6 netmask string to its prefix length (CIDR). */
|
|
444
|
+
function prefixLen(netmask) {
|
|
445
|
+
if (!netmask) return 0;
|
|
446
|
+
if (netmask.includes(":")) {
|
|
447
|
+
let bits = 0;
|
|
448
|
+
for (const group of netmask.split(":")) {
|
|
449
|
+
if (!group) continue;
|
|
450
|
+
const n = parseInt(group, 16);
|
|
451
|
+
if (!Number.isFinite(n)) break;
|
|
452
|
+
for (let mask = 32768; mask; mask >>= 1) if (n & mask) bits++;
|
|
453
|
+
else return bits;
|
|
454
|
+
}
|
|
455
|
+
return bits;
|
|
456
|
+
}
|
|
457
|
+
let bits = 0;
|
|
458
|
+
for (const part of netmask.split(".")) {
|
|
459
|
+
const n = parseInt(part, 10);
|
|
460
|
+
if (!Number.isFinite(n)) break;
|
|
461
|
+
for (let mask = 128; mask; mask >>= 1) if (n & mask) bits++;
|
|
462
|
+
else return bits;
|
|
463
|
+
}
|
|
464
|
+
return bits;
|
|
465
|
+
}
|
|
466
|
+
function snapshotKey(interfaces) {
|
|
467
|
+
return [...interfaces].map((i) => `${i.name}|${i.family}|${i.address}|${i.netmask}`).toSorted().join("\n");
|
|
468
|
+
}
|
|
469
|
+
function formatKind(kind) {
|
|
470
|
+
switch (kind) {
|
|
471
|
+
case "lan": return "LAN";
|
|
472
|
+
case "wifi": return "Wi-Fi";
|
|
473
|
+
case "vpn": return "VPN";
|
|
474
|
+
case "docker": return "Docker";
|
|
475
|
+
case "loopback": return "Loopback";
|
|
476
|
+
case "other": return "Other";
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
//#endregion
|
|
480
|
+
exports.LocalNetworkAddon = LocalNetworkAddon;
|
|
481
|
+
exports.applyAllowlist = applyAllowlist;
|
|
482
|
+
exports.autoSeedAllowlist = autoSeedAllowlist;
|
|
483
|
+
exports.buildEndpoints = buildEndpoints;
|
|
484
|
+
exports.classifyKind = classifyKind;
|
|
485
|
+
exports.enumerateOsInterfaces = enumerateOsInterfaces;
|
|
486
|
+
exports.explainNonPlausible = explainNonPlausible;
|
|
487
|
+
exports.isPlausibleAutoSeed = isPlausibleAutoSeed;
|
|
488
|
+
exports.pickPreferred = pickPreferred;
|
|
489
|
+
exports.prefixLen = prefixLen;
|