@camstack/system 1.2.69 → 1.2.71
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-runner.js +6 -6
- package/dist/addon-runner.mjs +3 -3
- package/dist/addon-utils.js +11 -11
- package/dist/addon-utils.mjs +1 -1
- package/dist/auth/auth-manager.d.ts +13 -29
- package/dist/auth/scope-matcher.d.ts +6 -5
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +3 -3
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +2 -2
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +3 -3
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +2 -2
- package/dist/builtins/alerts/alerts.addon.js +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +8 -8
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +6 -6
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.js +3 -3
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
- package/dist/builtins/device-manager/device-manager.addon.js +2 -2
- package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
- package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
- package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/index.d.ts +0 -1
- package/dist/builtins/local-auth/index.js +0 -1
- package/dist/builtins/local-auth/index.mjs +2 -2
- package/dist/builtins/local-auth/local-auth.addon.js +4878 -4883
- package/dist/builtins/local-auth/local-auth.addon.mjs +4879 -4883
- package/dist/builtins/local-auth/oauth-grants.d.ts +15 -0
- package/dist/builtins/local-network/local-network.addon.js +1 -1
- package/dist/builtins/local-network/local-network.addon.mjs +1 -1
- package/dist/builtins/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.mjs +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.js +5 -5
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +4 -4
- package/dist/builtins/platform-probe/index.js +4 -4
- package/dist/builtins/platform-probe/index.mjs +3 -3
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +2 -2
- package/dist/builtins/snapshot/index.mjs +2 -2
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +4 -4
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +3 -3
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +1 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +3 -3
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +2 -2
- package/dist/builtins/system-config/system-config.addon.js +1 -1
- package/dist/builtins/system-config/system-config.addon.mjs +1 -1
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{dist-C-QzFJ8v.mjs → dist-Daxx9CB0.mjs} +139 -5
- package/dist/{dist-D7wC-S4p.js → dist-I0WgqQQ-.js} +150 -10
- package/dist/{model-download-service-CTBHzORJ.mjs → file-data-plane-CuE_hBli.mjs} +848 -848
- package/dist/index.d.ts +73 -81
- package/dist/index.js +1302 -1278
- package/dist/index.mjs +1283 -1259
- package/dist/kernel/capability-registry.d.ts +26 -0
- package/dist/kernel/config-schema.d.ts +1 -1
- package/dist/kernel/transport/parent-unowned-call.d.ts +27 -0
- package/dist/{manifest-python-deps-Dz1ryHIN.mjs → manifest-python-deps-BdWxKNvu.mjs} +49 -47
- package/dist/{manifest-python-deps-BE6l8Y4W.js → manifest-python-deps-BqIpg0C7.js} +49 -47
- package/package.json +1 -4
- package/dist/builtins/local-auth/homeassistant-integration.d.ts +0 -7
- package/dist/{model-download-service-Caj1kaSi.js → file-data-plane-DUHPHa-Y.js} +847 -847
- package/dist/{resource-monitor-BkP504Vq.mjs → resource-monitor-BWmQ5i-o.mjs} +1 -1
- package/dist/{resource-monitor-DNNomR-i.js → resource-monitor-CdnzxBLP.js} +1 -1
|
@@ -30,6 +30,19 @@ export declare class CapabilityRegistry {
|
|
|
30
30
|
private _ready;
|
|
31
31
|
/** Boot-time dependency graph: capability → dependsOn names (from CapabilityDeclaration) */
|
|
32
32
|
private readonly capabilityDeps;
|
|
33
|
+
/**
|
|
34
|
+
* capability → addon ids whose MANIFEST declares it.
|
|
35
|
+
*
|
|
36
|
+
* Populated by {@link declareFromManifest}, which runs at addon-LOAD time —
|
|
37
|
+
* before a forked addon's runner has spawned, let alone registered anything.
|
|
38
|
+
* So this map answers a question `providers` cannot: **which addons still owe
|
|
39
|
+
* this capability a provider**, i.e. is an absence final or merely early.
|
|
40
|
+
*
|
|
41
|
+
* It is not a second registry and nothing waits on it: it stores an argument
|
|
42
|
+
* `declareFromManifest` was already being handed and dropping, and it is read
|
|
43
|
+
* synchronously at the moment a caller needs the answer ([D3](../../../../docs/decisions/adr-0003.md)).
|
|
44
|
+
*/
|
|
45
|
+
private readonly manifestDeclarers;
|
|
33
46
|
/** Per-device singleton overrides: deviceId → (capability → addonId) */
|
|
34
47
|
private readonly deviceOverrides;
|
|
35
48
|
/** capName → (nodeId → bare addonId) per-node singleton overrides. */
|
|
@@ -147,6 +160,19 @@ export declare class CapabilityRegistry {
|
|
|
147
160
|
* re-register the same pair must unregister first.
|
|
148
161
|
*/
|
|
149
162
|
hasProvider(capabilityName: string, addonId: string): boolean;
|
|
163
|
+
/**
|
|
164
|
+
* Addon ids whose manifest declares `capabilityName`, whether or not they
|
|
165
|
+
* have registered a provider yet.
|
|
166
|
+
*
|
|
167
|
+
* Pair it with {@link hasProvider} to separate "this capability's collection
|
|
168
|
+
* is still filling up" from "this is everything there will ever be" — the
|
|
169
|
+
* difference between a 503 a client should retry and a 400 it should not.
|
|
170
|
+
* Every entry is an addon INSTALLED on this node; an addon that is installed
|
|
171
|
+
* but disabled therefore stays listed, which is the honest answer (the
|
|
172
|
+
* capability is owed by something that is not going to supply it, and naming
|
|
173
|
+
* it is the diagnosis).
|
|
174
|
+
*/
|
|
175
|
+
getManifestDeclarers(capabilityName: string): readonly string[];
|
|
150
176
|
/** Unregister a provider. For singleton: clears active. For collection: removes from list. */
|
|
151
177
|
unregisterProvider(capabilityName: string, addonId: string): void;
|
|
152
178
|
/** Enable a previously disabled collection provider. */
|
|
@@ -5,8 +5,8 @@ export declare const DEFAULT_DATA_PATH = "camstack-data";
|
|
|
5
5
|
* All other settings live in SQL (system_settings table). */
|
|
6
6
|
export declare const bootstrapSchema: z.ZodObject<{
|
|
7
7
|
mode: z.ZodDefault<z.ZodEnum<{
|
|
8
|
-
hub: "hub";
|
|
9
8
|
agent: "agent";
|
|
9
|
+
hub: "hub";
|
|
10
10
|
}>>;
|
|
11
11
|
server: z.ZodDefault<z.ZodObject<{
|
|
12
12
|
port: z.ZodDefault<z.ZodNumber>;
|
|
@@ -132,6 +132,33 @@ export interface ParentUnownedCallDeps {
|
|
|
132
132
|
* so the two answers cannot drift).
|
|
133
133
|
*/
|
|
134
134
|
readonly callCollectionAggregate?: (capName: string, method: string, args: unknown) => Promise<readonly unknown[] | null>;
|
|
135
|
+
/**
|
|
136
|
+
* Optional `{ addonId }` PIN for a collection cap's SCALAR method — the twin
|
|
137
|
+
* of {@link callCollectionAggregate}, for the same reason.
|
|
138
|
+
*
|
|
139
|
+
* On a system-scoped collection cap `addonId` is not provider data: the
|
|
140
|
+
* codegen injects it as the `{nodeId?, addonId?}` selector on every method,
|
|
141
|
+
* and the hub's tRPC cap-router routes by it. This handler lifted only
|
|
142
|
+
* `nodeId` and `deviceId` out of a child's args, so a forked addon's pin was
|
|
143
|
+
* DISCARDED IN SILENCE and the call was answered by whichever provider
|
|
144
|
+
* registered first. `broker.getBrokerConfig({id:'ha_001', addonId:'provider-
|
|
145
|
+
* homeassistant'})` therefore returned Homematic's `null` — indistinguishable
|
|
146
|
+
* from "no such broker" — and the Home Assistant export could never open a
|
|
147
|
+
* link. Every write-up that "proved the pin works" had measured the hub's
|
|
148
|
+
* tRPC surface, never this path (2026-08-09).
|
|
149
|
+
*
|
|
150
|
+
* Returns a `{ value }` box so a legitimate `null` result is distinguishable
|
|
151
|
+
* from "not a pinned collection call, route normally", and THROWS when the
|
|
152
|
+
* pin names a non-provider — a pin that silently degrades to another
|
|
153
|
+
* provider's answer is worse than no pin. Array methods are never pinned
|
|
154
|
+
* here: their contract is the union above.
|
|
155
|
+
*
|
|
156
|
+
* The kernel layer has no cap registry, so the wiring side injects this and
|
|
157
|
+
* it shares the tRPC path's provider resolution — the two must not drift.
|
|
158
|
+
*/
|
|
159
|
+
readonly callPinnedCollection?: (capName: string, method: string, args: unknown) => Promise<{
|
|
160
|
+
readonly value: unknown;
|
|
161
|
+
} | null>;
|
|
135
162
|
/**
|
|
136
163
|
* Optional predicate — returns `true` when `capName` is a HUB-CORE `$`-service
|
|
137
164
|
* cap (`system`, `addons`, `nodes`, `capabilities`, `stream-probe`, …): served
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { ensureBinary, ensureFfmpeg, ensurePython, installPythonPackages, installPythonRequirements } from "@camstack/types/node";
|
|
2
1
|
import * as crypto$1 from "node:crypto";
|
|
3
2
|
import { randomBytes, randomUUID } from "node:crypto";
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
3
|
+
import { ensureBinary, ensureFfmpeg, ensurePython, installPythonPackages, installPythonRequirements } from "@camstack/types/node";
|
|
4
|
+
import { unlink } from "node:fs/promises";
|
|
6
5
|
import * as path$1 from "node:path";
|
|
7
6
|
import { isAbsolute, join } from "node:path";
|
|
8
|
-
import { promisify } from "node:util";
|
|
9
|
-
import { DATAPLANE_SECRET_HEADER, DeviceType, DisposerChain, EventCategory, ReadinessRegistry, asJsonObject, asString, createDeviceProxy, deviceOpsCapability, emitReadiness, errMsg, expandCapMethods, readNodePin, scopeKey, sleep, withCapInputDefaults } from "@camstack/types/addon";
|
|
10
7
|
import { execFile } from "node:child_process";
|
|
8
|
+
import { promisify } from "node:util";
|
|
11
9
|
import * as os from "node:os";
|
|
12
10
|
import { tmpdir } from "node:os";
|
|
13
|
-
import
|
|
11
|
+
import * as fs from "node:fs";
|
|
12
|
+
import { createServer } from "node:http";
|
|
13
|
+
import { DATAPLANE_SECRET_HEADER, DeviceType, DisposerChain, EventCategory, ReadinessRegistry, asJsonObject, asString, createDeviceProxy, deviceOpsCapability, emitReadiness, errMsg, expandCapMethods, readNodePin, scopeKey, sleep, withCapInputDefaults } from "@camstack/types/addon";
|
|
14
14
|
import { TRPCClientError, createTRPCClient } from "@trpc/client";
|
|
15
15
|
import { connect, createServer as createServer$1 } from "node:net";
|
|
16
16
|
//#region src/kernel/moleculer/addon-data-plane-facility.ts
|
|
@@ -129,46 +129,6 @@ function createAddonDataPlaneFacility(args) {
|
|
|
129
129
|
};
|
|
130
130
|
}
|
|
131
131
|
//#endregion
|
|
132
|
-
//#region src/kernel/addon-class-resolver.ts
|
|
133
|
-
function isRecord(value) {
|
|
134
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Resolve the addon class from a dynamically imported module.
|
|
138
|
-
*
|
|
139
|
-
* Two compilation patterns to handle:
|
|
140
|
-
* 1. ESM with explicit `export default class …` — `mod.default` is the class.
|
|
141
|
-
* 2. CJS via tsup that emits only named exports (no `module.exports = …`)
|
|
142
|
-
* — `mod.default` is undefined; we must pick the right named export.
|
|
143
|
-
*
|
|
144
|
-
* The CJS path is the trap: an addon bundle can also re-export device
|
|
145
|
-
* classes (e.g. `ReolinkCamera` extends `BaseDevice`) and helper
|
|
146
|
-
* functions. Picking `Object.keys(mod)[0]` is bundler-order-dependent —
|
|
147
|
-
* the first named export today is `ReolinkCamera`, whose `new` requires
|
|
148
|
-
* a `DeviceContext` and crashes on `new MyClass()`.
|
|
149
|
-
*
|
|
150
|
-
* The contract is: the addon class extends `BaseAddon`, which has an
|
|
151
|
-
* `initialize` method on its prototype. Device classes (`BaseDevice`)
|
|
152
|
-
* do not. We probe for that method to disambiguate.
|
|
153
|
-
*/
|
|
154
|
-
function isAddonConstructor(fn) {
|
|
155
|
-
if (typeof fn !== "function") return false;
|
|
156
|
-
const proto = fn.prototype;
|
|
157
|
-
if (!isRecord(proto)) return false;
|
|
158
|
-
return typeof proto["initialize"] === "function";
|
|
159
|
-
}
|
|
160
|
-
function resolveAddonClass(mod) {
|
|
161
|
-
let candidate = mod["default"];
|
|
162
|
-
if (isRecord(candidate) && "default" in candidate) candidate = candidate["default"];
|
|
163
|
-
if (isAddonConstructor(candidate)) return candidate;
|
|
164
|
-
if (isRecord(candidate)) {
|
|
165
|
-
const fn = Object.values(candidate).find(isAddonConstructor);
|
|
166
|
-
if (fn) return fn;
|
|
167
|
-
}
|
|
168
|
-
const namedAddon = Object.values(mod).find(isAddonConstructor);
|
|
169
|
-
if (namedAddon) return namedAddon;
|
|
170
|
-
}
|
|
171
|
-
//#endregion
|
|
172
132
|
//#region src/kernel/deps/npm-command.ts
|
|
173
133
|
/**
|
|
174
134
|
* npm invocation resolver — makes "is npm available?" a solved problem for
|
|
@@ -298,6 +258,46 @@ async function resolveUncached(options) {
|
|
|
298
258
|
}
|
|
299
259
|
}
|
|
300
260
|
//#endregion
|
|
261
|
+
//#region src/kernel/addon-class-resolver.ts
|
|
262
|
+
function isRecord(value) {
|
|
263
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Resolve the addon class from a dynamically imported module.
|
|
267
|
+
*
|
|
268
|
+
* Two compilation patterns to handle:
|
|
269
|
+
* 1. ESM with explicit `export default class …` — `mod.default` is the class.
|
|
270
|
+
* 2. CJS via tsup that emits only named exports (no `module.exports = …`)
|
|
271
|
+
* — `mod.default` is undefined; we must pick the right named export.
|
|
272
|
+
*
|
|
273
|
+
* The CJS path is the trap: an addon bundle can also re-export device
|
|
274
|
+
* classes (e.g. `ReolinkCamera` extends `BaseDevice`) and helper
|
|
275
|
+
* functions. Picking `Object.keys(mod)[0]` is bundler-order-dependent —
|
|
276
|
+
* the first named export today is `ReolinkCamera`, whose `new` requires
|
|
277
|
+
* a `DeviceContext` and crashes on `new MyClass()`.
|
|
278
|
+
*
|
|
279
|
+
* The contract is: the addon class extends `BaseAddon`, which has an
|
|
280
|
+
* `initialize` method on its prototype. Device classes (`BaseDevice`)
|
|
281
|
+
* do not. We probe for that method to disambiguate.
|
|
282
|
+
*/
|
|
283
|
+
function isAddonConstructor(fn) {
|
|
284
|
+
if (typeof fn !== "function") return false;
|
|
285
|
+
const proto = fn.prototype;
|
|
286
|
+
if (!isRecord(proto)) return false;
|
|
287
|
+
return typeof proto["initialize"] === "function";
|
|
288
|
+
}
|
|
289
|
+
function resolveAddonClass(mod) {
|
|
290
|
+
let candidate = mod["default"];
|
|
291
|
+
if (isRecord(candidate) && "default" in candidate) candidate = candidate["default"];
|
|
292
|
+
if (isAddonConstructor(candidate)) return candidate;
|
|
293
|
+
if (isRecord(candidate)) {
|
|
294
|
+
const fn = Object.values(candidate).find(isAddonConstructor);
|
|
295
|
+
if (fn) return fn;
|
|
296
|
+
}
|
|
297
|
+
const namedAddon = Object.values(mod).find(isAddonConstructor);
|
|
298
|
+
if (namedAddon) return namedAddon;
|
|
299
|
+
}
|
|
300
|
+
//#endregion
|
|
301
301
|
//#region src/kernel/deps/manifest-native-deps.ts
|
|
302
302
|
var execFileAsync = promisify(execFile);
|
|
303
303
|
/**
|
|
@@ -5421,6 +5421,8 @@ function createParentUnownedCallHandler(deps) {
|
|
|
5421
5421
|
if (empty != null) return empty;
|
|
5422
5422
|
const aggregate = await deps.callCollectionAggregate?.(input.capName, input.method, input.args);
|
|
5423
5423
|
if (aggregate != null) return aggregate;
|
|
5424
|
+
const pinned = await deps.callPinnedCollection?.(input.capName, input.method, input.args);
|
|
5425
|
+
if (pinned !== null && pinned !== void 0) return pinned.value;
|
|
5424
5426
|
}
|
|
5425
5427
|
const resolver = deps.getResolver();
|
|
5426
5428
|
if (resolver !== null) try {
|
|
@@ -7614,4 +7616,4 @@ async function installManifestPythonDeps(declaration, addonDir, deps, logger) {
|
|
|
7614
7616
|
await deps.installPythonRequirements(reqAbs);
|
|
7615
7617
|
}
|
|
7616
7618
|
//#endregion
|
|
7617
|
-
export { buildNativeCapProxy as $, createHubCapForwardService as A, AGENT_CAP_FWD_ACTION as B, brokerTransportLink as C,
|
|
7619
|
+
export { buildNativeCapProxy as $, createHubCapForwardService as A, AGENT_CAP_FWD_ACTION as B, brokerTransportLink as C, runNpm as Ct, localProviderLink as D, ipcParentLink as E, createUdsLogger as F, callWithServiceDiscovery as G, CapRouteResolver as H, createUdsLoggerWithControl as I, UdsLocalTransportServer as J, createLocalTransport as K, LocalChildClient as L, createUdsEventBridge as M, createUdsEventBus as N, HUB_CAP_FWD_ACTION as O, udsChildLogToWorkerEntry as P, encodeFrame as Q, LocalChildRegistry as R, brokerCallForCap as S, resolveNpmInvocation as St, ipcChildLink as T, CapRouteError as U, AGENT_CAP_FWD_SERVICE as V, classifyCapRoute as W, localEndpointPath as X, SocketChannel as Y, FrameDecoder as Z, createKernelHwAccel as _, CapabilityHandle as _t, getWorkerDeviceRegistry as a, setWorkerNativeCapsChangeListener as at, __resetCapUsageRegistryForTests as b, installManifestNativeDeps as bt, setHubConnected as c, NATIVE_PROVIDER_SERVICE_INFIX as ct, getBrokerEventBus as d, capBareAction as dt, buildUdsNativeCapProxy as et, getMoleculerEventStats as f, capServiceName as ft, AddonDepsManager as g, DeviceRegistry as gt, subscribePassthrough as h, serializeTypedArrays as ht, createUdsAddonContext as i, mountNativeCapService as it, createParentUnownedCallHandler as j, HUB_CAP_FWD_SERVICE as k, EVENT_TOPIC_PREFIX as l, capActionName as lt, setNodeEventInterest as m, deserializeTypedArrays as mt, adaptBrokerToCluster as n, getWorkerNativeCapProvider as nt, getOrInitReadinessRegistry as o, createAddonService as ot, registerEventBusService as p, parseCapAction as pt, UdsLocalTransportClient as q, createAddonContext as r, getWorkerNativeCapSnapshot as rt, getOrInitReadinessRegistryForClient as s, validateProviderRegistrations as st, installManifestPythonDeps as t, createBrokerDeviceManagerApi as tt, clusterEventTopic as u, capActionSuffix as ut, resolveHwAccel as v, CapabilityUnavailableError as vt, buildLinkChain as w, createAddonDataPlaneFacility as wt, getCapUsageRegistry as x, resolveAddonClass as xt, CapUsageRegistry as y, copyBundledNativeModules as yt, UDS_NO_ROUTE_PREFIX as z };
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
const require_chunk = require("./chunk-Cek0wNdY.js");
|
|
2
|
-
let _camstack_types_node = require("@camstack/types/node");
|
|
3
2
|
let node_crypto = require("node:crypto");
|
|
4
3
|
node_crypto = require_chunk.__toESM(node_crypto);
|
|
5
|
-
let
|
|
6
|
-
let
|
|
7
|
-
node_fs = require_chunk.__toESM(node_fs);
|
|
4
|
+
let _camstack_types_node = require("@camstack/types/node");
|
|
5
|
+
let node_fs_promises = require("node:fs/promises");
|
|
8
6
|
let node_path = require("node:path");
|
|
9
7
|
node_path = require_chunk.__toESM(node_path);
|
|
10
|
-
let node_util = require("node:util");
|
|
11
|
-
let _camstack_types_addon = require("@camstack/types/addon");
|
|
12
8
|
let node_child_process = require("node:child_process");
|
|
9
|
+
let node_util = require("node:util");
|
|
13
10
|
let node_os = require("node:os");
|
|
14
11
|
node_os = require_chunk.__toESM(node_os);
|
|
15
|
-
let
|
|
12
|
+
let node_fs = require("node:fs");
|
|
13
|
+
node_fs = require_chunk.__toESM(node_fs);
|
|
14
|
+
let node_http = require("node:http");
|
|
15
|
+
let _camstack_types_addon = require("@camstack/types/addon");
|
|
16
16
|
let _trpc_client = require("@trpc/client");
|
|
17
17
|
let node_net = require("node:net");
|
|
18
18
|
//#region src/kernel/moleculer/addon-data-plane-facility.ts
|
|
@@ -131,46 +131,6 @@ function createAddonDataPlaneFacility(args) {
|
|
|
131
131
|
};
|
|
132
132
|
}
|
|
133
133
|
//#endregion
|
|
134
|
-
//#region src/kernel/addon-class-resolver.ts
|
|
135
|
-
function isRecord(value) {
|
|
136
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Resolve the addon class from a dynamically imported module.
|
|
140
|
-
*
|
|
141
|
-
* Two compilation patterns to handle:
|
|
142
|
-
* 1. ESM with explicit `export default class …` — `mod.default` is the class.
|
|
143
|
-
* 2. CJS via tsup that emits only named exports (no `module.exports = …`)
|
|
144
|
-
* — `mod.default` is undefined; we must pick the right named export.
|
|
145
|
-
*
|
|
146
|
-
* The CJS path is the trap: an addon bundle can also re-export device
|
|
147
|
-
* classes (e.g. `ReolinkCamera` extends `BaseDevice`) and helper
|
|
148
|
-
* functions. Picking `Object.keys(mod)[0]` is bundler-order-dependent —
|
|
149
|
-
* the first named export today is `ReolinkCamera`, whose `new` requires
|
|
150
|
-
* a `DeviceContext` and crashes on `new MyClass()`.
|
|
151
|
-
*
|
|
152
|
-
* The contract is: the addon class extends `BaseAddon`, which has an
|
|
153
|
-
* `initialize` method on its prototype. Device classes (`BaseDevice`)
|
|
154
|
-
* do not. We probe for that method to disambiguate.
|
|
155
|
-
*/
|
|
156
|
-
function isAddonConstructor(fn) {
|
|
157
|
-
if (typeof fn !== "function") return false;
|
|
158
|
-
const proto = fn.prototype;
|
|
159
|
-
if (!isRecord(proto)) return false;
|
|
160
|
-
return typeof proto["initialize"] === "function";
|
|
161
|
-
}
|
|
162
|
-
function resolveAddonClass(mod) {
|
|
163
|
-
let candidate = mod["default"];
|
|
164
|
-
if (isRecord(candidate) && "default" in candidate) candidate = candidate["default"];
|
|
165
|
-
if (isAddonConstructor(candidate)) return candidate;
|
|
166
|
-
if (isRecord(candidate)) {
|
|
167
|
-
const fn = Object.values(candidate).find(isAddonConstructor);
|
|
168
|
-
if (fn) return fn;
|
|
169
|
-
}
|
|
170
|
-
const namedAddon = Object.values(mod).find(isAddonConstructor);
|
|
171
|
-
if (namedAddon) return namedAddon;
|
|
172
|
-
}
|
|
173
|
-
//#endregion
|
|
174
134
|
//#region src/kernel/deps/npm-command.ts
|
|
175
135
|
/**
|
|
176
136
|
* npm invocation resolver — makes "is npm available?" a solved problem for
|
|
@@ -300,6 +260,46 @@ async function resolveUncached(options) {
|
|
|
300
260
|
}
|
|
301
261
|
}
|
|
302
262
|
//#endregion
|
|
263
|
+
//#region src/kernel/addon-class-resolver.ts
|
|
264
|
+
function isRecord(value) {
|
|
265
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Resolve the addon class from a dynamically imported module.
|
|
269
|
+
*
|
|
270
|
+
* Two compilation patterns to handle:
|
|
271
|
+
* 1. ESM with explicit `export default class …` — `mod.default` is the class.
|
|
272
|
+
* 2. CJS via tsup that emits only named exports (no `module.exports = …`)
|
|
273
|
+
* — `mod.default` is undefined; we must pick the right named export.
|
|
274
|
+
*
|
|
275
|
+
* The CJS path is the trap: an addon bundle can also re-export device
|
|
276
|
+
* classes (e.g. `ReolinkCamera` extends `BaseDevice`) and helper
|
|
277
|
+
* functions. Picking `Object.keys(mod)[0]` is bundler-order-dependent —
|
|
278
|
+
* the first named export today is `ReolinkCamera`, whose `new` requires
|
|
279
|
+
* a `DeviceContext` and crashes on `new MyClass()`.
|
|
280
|
+
*
|
|
281
|
+
* The contract is: the addon class extends `BaseAddon`, which has an
|
|
282
|
+
* `initialize` method on its prototype. Device classes (`BaseDevice`)
|
|
283
|
+
* do not. We probe for that method to disambiguate.
|
|
284
|
+
*/
|
|
285
|
+
function isAddonConstructor(fn) {
|
|
286
|
+
if (typeof fn !== "function") return false;
|
|
287
|
+
const proto = fn.prototype;
|
|
288
|
+
if (!isRecord(proto)) return false;
|
|
289
|
+
return typeof proto["initialize"] === "function";
|
|
290
|
+
}
|
|
291
|
+
function resolveAddonClass(mod) {
|
|
292
|
+
let candidate = mod["default"];
|
|
293
|
+
if (isRecord(candidate) && "default" in candidate) candidate = candidate["default"];
|
|
294
|
+
if (isAddonConstructor(candidate)) return candidate;
|
|
295
|
+
if (isRecord(candidate)) {
|
|
296
|
+
const fn = Object.values(candidate).find(isAddonConstructor);
|
|
297
|
+
if (fn) return fn;
|
|
298
|
+
}
|
|
299
|
+
const namedAddon = Object.values(mod).find(isAddonConstructor);
|
|
300
|
+
if (namedAddon) return namedAddon;
|
|
301
|
+
}
|
|
302
|
+
//#endregion
|
|
303
303
|
//#region src/kernel/deps/manifest-native-deps.ts
|
|
304
304
|
var execFileAsync = (0, node_util.promisify)(node_child_process.execFile);
|
|
305
305
|
/**
|
|
@@ -5423,6 +5423,8 @@ function createParentUnownedCallHandler(deps) {
|
|
|
5423
5423
|
if (empty != null) return empty;
|
|
5424
5424
|
const aggregate = await deps.callCollectionAggregate?.(input.capName, input.method, input.args);
|
|
5425
5425
|
if (aggregate != null) return aggregate;
|
|
5426
|
+
const pinned = await deps.callPinnedCollection?.(input.capName, input.method, input.args);
|
|
5427
|
+
if (pinned !== null && pinned !== void 0) return pinned.value;
|
|
5426
5428
|
}
|
|
5427
5429
|
const resolver = deps.getResolver();
|
|
5428
5430
|
if (resolver !== null) try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/system",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.71",
|
|
4
4
|
"description": "Core addon for CamStack — builtins, pipeline, process management, auth, logging, events",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|
|
@@ -267,9 +267,6 @@
|
|
|
267
267
|
},
|
|
268
268
|
{
|
|
269
269
|
"name": "user-management"
|
|
270
|
-
},
|
|
271
|
-
{
|
|
272
|
-
"name": "oauth-integration"
|
|
273
270
|
}
|
|
274
271
|
]
|
|
275
272
|
},
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { OauthIntegrationDescriptor } from '@camstack/types';
|
|
2
|
-
/**
|
|
3
|
-
* Scopes granted to a linked Home Assistant, derived from the tRPC paths the
|
|
4
|
-
* component actually calls. `category:system [create]` was rejected: it would
|
|
5
|
-
* hand `addons.installPackage` to a home-automation bridge.
|
|
6
|
-
*/
|
|
7
|
-
export declare const HOME_ASSISTANT_OAUTH_INTEGRATION: OauthIntegrationDescriptor;
|