homebridge-plugin-utils 2.0.0 → 2.1.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/dist/backpressure.d.ts +1 -1
- package/dist/backpressure.js +4 -4
- package/dist/backpressure.js.map +1 -1
- package/dist/cli/index.d.ts +73 -2
- package/dist/cli/index.js +221 -25
- package/dist/cli/index.js.map +1 -1
- package/dist/clock-double.js +2 -2
- package/dist/clock-double.js.map +1 -1
- package/dist/disposable-stack.d.ts +59 -0
- package/dist/disposable-stack.js +155 -0
- package/dist/disposable-stack.js.map +1 -0
- package/dist/docChrome.d.ts +260 -0
- package/dist/docChrome.js +361 -0
- package/dist/docChrome.js.map +1 -0
- package/dist/featureOptions-docs.d.ts +2 -2
- package/dist/featureOptions-docs.js +1 -1
- package/dist/featureOptions.d.ts +5 -5
- package/dist/featureOptions.js +6 -6
- package/dist/ffmpeg/exec.d.ts +2 -2
- package/dist/ffmpeg/exec.js +2 -2
- package/dist/ffmpeg/mp4-assembler.d.ts +45 -4
- package/dist/ffmpeg/mp4-assembler.js +45 -8
- package/dist/ffmpeg/mp4-assembler.js.map +1 -1
- package/dist/ffmpeg/mp4-parser.d.ts +1 -1
- package/dist/ffmpeg/mp4-parser.js +1 -1
- package/dist/ffmpeg/options.js +3 -3
- package/dist/ffmpeg/options.js.map +1 -1
- package/dist/ffmpeg/process.d.ts +1 -1
- package/dist/ffmpeg/process.js +4 -4
- package/dist/ffmpeg/process.js.map +1 -1
- package/dist/ffmpeg/record.d.ts +26 -1
- package/dist/ffmpeg/record.js +12 -0
- package/dist/ffmpeg/record.js.map +1 -1
- package/dist/ffmpeg/recording-process-double.d.ts +13 -0
- package/dist/ffmpeg/recording-process-double.js +22 -0
- package/dist/ffmpeg/recording-process-double.js.map +1 -1
- package/dist/ffmpeg/rtp-parser.d.ts +1 -1
- package/dist/ffmpeg/rtp-parser.js +1 -1
- package/dist/ffmpeg/rtp.d.ts +4 -4
- package/dist/ffmpeg/rtp.js +7 -6
- package/dist/ffmpeg/rtp.js.map +1 -1
- package/dist/ffmpeg/stream.js +1 -1
- package/dist/ffmpeg/stream.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/logclient/auth.d.ts +3 -3
- package/dist/logclient/auth.js +2 -2
- package/dist/logclient/auth.js.map +1 -1
- package/dist/logclient/cli-run.js +2 -2
- package/dist/logclient/cli-run.js.map +1 -1
- package/dist/logclient/cli.js +2 -2
- package/dist/logclient/client.js +2 -2
- package/dist/logclient/client.js.map +1 -1
- package/dist/logclient/rest.js +1 -1
- package/dist/logclient/socket-double.d.ts +1 -1
- package/dist/logclient/socket-double.js +1 -1
- package/dist/logclient/socket.js +5 -5
- package/dist/logclient/socket.js.map +1 -1
- package/dist/logclient/time-window.d.ts +1 -1
- package/dist/mqttClient.d.ts +1 -1
- package/dist/mqttClient.js +3 -3
- package/dist/mqttClient.js.map +1 -1
- package/dist/ui/featureOptions.js +6 -6
- package/dist/ui/pluginConfigSession.mjs +1 -1
- package/dist/ui/webUi-featureOptions/effects/persist.mjs +2 -2
- package/dist/ui/webUi-featureOptions/effects/theme.mjs +1 -1
- package/dist/ui/webUi-featureOptions/effects/tokens.mjs +1 -1
- package/dist/ui/webUi-featureOptions/rendering.mjs +2 -2
- package/dist/ui/webUi-featureOptions/selectors.mjs +3 -3
- package/dist/ui/webUi-featureOptions/state.mjs +6 -6
- package/dist/ui/webUi-featureOptions/store.mjs +1 -1
- package/dist/ui/webUi-featureOptions/utils.mjs +14 -1
- package/dist/ui/webUi-featureOptions/views/connectionError.mjs +1 -1
- package/dist/ui/webUi-featureOptions/views/nav.mjs +42 -28
- package/dist/ui/webUi-featureOptions/views/options.mjs +2 -2
- package/dist/ui/webUi-featureOptions/views/search.mjs +2 -2
- package/dist/ui/webUi-featureOptions.mjs +57 -32
- package/dist/ui/webUi.mjs +43 -11
- package/dist/util.d.ts +89 -12
- package/dist/util.js +62 -14
- package/dist/util.js.map +1 -1
- package/package.json +9 -9
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A container that aggregates disposable resources and disposes them, in reverse (last-in-first-out) order, when the stack itself is disposed.
|
|
3
|
+
*
|
|
4
|
+
* The class satisfies the platform `DisposableStack` interface by construction - the `implements` clause below binds it to `globalThis.DisposableStack`, so the
|
|
5
|
+
* compiler enforces that the name's promise (the platform contract) is kept at the definition site.
|
|
6
|
+
*
|
|
7
|
+
* @category Utilities
|
|
8
|
+
*/
|
|
9
|
+
export declare class DisposableStack implements InstanceType<typeof globalThis.DisposableStack> {
|
|
10
|
+
#private;
|
|
11
|
+
readonly [Symbol.toStringTag] = "DisposableStack";
|
|
12
|
+
/**
|
|
13
|
+
* Whether this stack has been disposed.
|
|
14
|
+
*/
|
|
15
|
+
get disposed(): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Register a {@link Disposable} whose `[Symbol.dispose]()` runs when this stack is disposed, returning the value unchanged.
|
|
18
|
+
*
|
|
19
|
+
* `null` and `undefined` pass through without being registered. The dispose method is captured at registration time and invoked with the value as its receiver, so
|
|
20
|
+
* a later mutation of `value[Symbol.dispose]` cannot change what runs.
|
|
21
|
+
*
|
|
22
|
+
* @param value - The resource to register, or `null`/`undefined` to skip registration.
|
|
23
|
+
* @returns The provided `value`.
|
|
24
|
+
*/
|
|
25
|
+
use<T extends Disposable | null | undefined>(value: T): T;
|
|
26
|
+
/**
|
|
27
|
+
* Register a value together with an explicit disposal callback, returning the value unchanged. The callback is invoked with the value as its first argument when
|
|
28
|
+
* this stack is disposed.
|
|
29
|
+
*
|
|
30
|
+
* @param value - The value to associate with the callback.
|
|
31
|
+
* @param onDispose - The disposal callback, invoked with `value`.
|
|
32
|
+
* @returns The provided `value`.
|
|
33
|
+
*/
|
|
34
|
+
adopt<T>(value: T, onDispose: (value: T) => void): T;
|
|
35
|
+
/**
|
|
36
|
+
* Register a callback to run when this stack is disposed.
|
|
37
|
+
*
|
|
38
|
+
* @param onDispose - The callback to run on disposal.
|
|
39
|
+
*/
|
|
40
|
+
defer(onDispose: () => void): void;
|
|
41
|
+
/**
|
|
42
|
+
* Move every pending disposer out of this stack into a fresh {@link DisposableStack}, preserving registration order, and mark this stack disposed without running
|
|
43
|
+
* anything. This is the "commit" primitive: after a successful acquire sequence, moving the disposers away disarms this stack's scope-bound cleanup while handing
|
|
44
|
+
* responsibility for those resources to the returned stack.
|
|
45
|
+
*
|
|
46
|
+
* @returns A new stack owning the transferred disposers.
|
|
47
|
+
*/
|
|
48
|
+
move(): DisposableStack;
|
|
49
|
+
/**
|
|
50
|
+
* Dispose every registered resource in reverse (last-in-first-out) order. A second call is a no-op. Every disposer runs even when an earlier one throws: a single
|
|
51
|
+
* failure is rethrown after the sweep completes, and multiple failures chain through `SuppressedError` (the newest failure wrapping the accumulated one).
|
|
52
|
+
*/
|
|
53
|
+
dispose(): void;
|
|
54
|
+
/**
|
|
55
|
+
* Dispose this stack. Enables `using` semantics by delegating to {@link dispose}.
|
|
56
|
+
*/
|
|
57
|
+
[Symbol.dispose](): void;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=disposable-stack.d.ts.map
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/* Copyright(C) 2017-2026, HJD (https://github.com/hjdhjd). All rights reserved.
|
|
2
|
+
*
|
|
3
|
+
* disposable-stack.ts: An in-package stand-in for the platform `DisposableStack` global that the library's own port allocator relies on.
|
|
4
|
+
*/
|
|
5
|
+
// Build a `SuppressedError` that links a newer disposal failure to the error it supersedes, matching the spec's multi-failure aggregation shape. We read the platform
|
|
6
|
+
// `SuppressedError` global fresh on every call rather than caching a reference, because that constructor is itself part of the Node 24 explicit-resource-management
|
|
7
|
+
// surface and can be absent on the engines floor this module exists to serve. When it is missing we synthesize a structurally-identical stand-in - an `Error` whose
|
|
8
|
+
// name is "SuppressedError" carrying `error` and `suppressed` - so multi-failure aggregation is observably identical whether or not the global is present. The typed
|
|
9
|
+
// optional read tells the truth the platform lib cannot: on this engines floor the global may not exist.
|
|
10
|
+
function createSuppressedError(error, suppressed) {
|
|
11
|
+
const suppressedErrorConstructor = globalThis.SuppressedError;
|
|
12
|
+
if (suppressedErrorConstructor !== undefined) {
|
|
13
|
+
return new suppressedErrorConstructor(error, suppressed);
|
|
14
|
+
}
|
|
15
|
+
const synthesized = new Error();
|
|
16
|
+
synthesized.error = error;
|
|
17
|
+
synthesized.name = "SuppressedError";
|
|
18
|
+
synthesized.suppressed = suppressed;
|
|
19
|
+
return synthesized;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* A container that aggregates disposable resources and disposes them, in reverse (last-in-first-out) order, when the stack itself is disposed.
|
|
23
|
+
*
|
|
24
|
+
* The class satisfies the platform `DisposableStack` interface by construction - the `implements` clause below binds it to `globalThis.DisposableStack`, so the
|
|
25
|
+
* compiler enforces that the name's promise (the platform contract) is kept at the definition site.
|
|
26
|
+
*
|
|
27
|
+
* @category Utilities
|
|
28
|
+
*/
|
|
29
|
+
export class DisposableStack {
|
|
30
|
+
// The pending disposers in registration order. A `null` array is the disposed state: pairing "disposed" with "no pending disposers" in a single field makes the
|
|
31
|
+
// disposed-with-pending-work state unrepresentable, so every member checks this one field to decide whether it may still register or run work.
|
|
32
|
+
#disposers = [];
|
|
33
|
+
// The platform tag reported by `Object.prototype.toString`, matching the native class.
|
|
34
|
+
[Symbol.toStringTag] = "DisposableStack";
|
|
35
|
+
/**
|
|
36
|
+
* Whether this stack has been disposed.
|
|
37
|
+
*/
|
|
38
|
+
get disposed() {
|
|
39
|
+
return this.#disposers === null;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Register a {@link Disposable} whose `[Symbol.dispose]()` runs when this stack is disposed, returning the value unchanged.
|
|
43
|
+
*
|
|
44
|
+
* `null` and `undefined` pass through without being registered. The dispose method is captured at registration time and invoked with the value as its receiver, so
|
|
45
|
+
* a later mutation of `value[Symbol.dispose]` cannot change what runs.
|
|
46
|
+
*
|
|
47
|
+
* @param value - The resource to register, or `null`/`undefined` to skip registration.
|
|
48
|
+
* @returns The provided `value`.
|
|
49
|
+
*/
|
|
50
|
+
use(value) {
|
|
51
|
+
if (this.#disposers === null) {
|
|
52
|
+
throw new ReferenceError("Cannot use a resource on a disposed DisposableStack.");
|
|
53
|
+
}
|
|
54
|
+
// Skip registration for null and undefined, returning them unchanged. We test undefined with `typeof` so the generic parameter narrows cleanly to a Disposable for
|
|
55
|
+
// the member access below.
|
|
56
|
+
if ((value === null) || (typeof value === "undefined")) {
|
|
57
|
+
return value;
|
|
58
|
+
}
|
|
59
|
+
// Capture the dispose method now, at registration time, matching the spec's registration-time capture... a later mutation of `value[Symbol.dispose]` must not change
|
|
60
|
+
// what runs. We read it through `unknown` because use() is a trust boundary: a value can satisfy the Disposable type nominally yet present a non-callable member at
|
|
61
|
+
// runtime, which the spec requires we reject with a TypeError.
|
|
62
|
+
const disposeMethod = value[Symbol.dispose];
|
|
63
|
+
if (typeof disposeMethod !== "function") {
|
|
64
|
+
throw new TypeError("The value passed to DisposableStack.use() is not disposable.");
|
|
65
|
+
}
|
|
66
|
+
const boundDispose = disposeMethod;
|
|
67
|
+
this.#disposers.push(() => {
|
|
68
|
+
boundDispose.call(value);
|
|
69
|
+
});
|
|
70
|
+
return value;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Register a value together with an explicit disposal callback, returning the value unchanged. The callback is invoked with the value as its first argument when
|
|
74
|
+
* this stack is disposed.
|
|
75
|
+
*
|
|
76
|
+
* @param value - The value to associate with the callback.
|
|
77
|
+
* @param onDispose - The disposal callback, invoked with `value`.
|
|
78
|
+
* @returns The provided `value`.
|
|
79
|
+
*/
|
|
80
|
+
adopt(value, onDispose) {
|
|
81
|
+
if (this.#disposers === null) {
|
|
82
|
+
throw new ReferenceError("Cannot adopt a resource on a disposed DisposableStack.");
|
|
83
|
+
}
|
|
84
|
+
if (typeof onDispose !== "function") {
|
|
85
|
+
throw new TypeError("The onDispose callback passed to DisposableStack.adopt() is not a function.");
|
|
86
|
+
}
|
|
87
|
+
this.#disposers.push(() => onDispose(value));
|
|
88
|
+
return value;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Register a callback to run when this stack is disposed.
|
|
92
|
+
*
|
|
93
|
+
* @param onDispose - The callback to run on disposal.
|
|
94
|
+
*/
|
|
95
|
+
defer(onDispose) {
|
|
96
|
+
if (this.#disposers === null) {
|
|
97
|
+
throw new ReferenceError("Cannot defer a callback on a disposed DisposableStack.");
|
|
98
|
+
}
|
|
99
|
+
if (typeof onDispose !== "function") {
|
|
100
|
+
throw new TypeError("The onDispose callback passed to DisposableStack.defer() is not a function.");
|
|
101
|
+
}
|
|
102
|
+
this.#disposers.push(onDispose);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Move every pending disposer out of this stack into a fresh {@link DisposableStack}, preserving registration order, and mark this stack disposed without running
|
|
106
|
+
* anything. This is the "commit" primitive: after a successful acquire sequence, moving the disposers away disarms this stack's scope-bound cleanup while handing
|
|
107
|
+
* responsibility for those resources to the returned stack.
|
|
108
|
+
*
|
|
109
|
+
* @returns A new stack owning the transferred disposers.
|
|
110
|
+
*/
|
|
111
|
+
move() {
|
|
112
|
+
if (this.#disposers === null) {
|
|
113
|
+
throw new ReferenceError("Cannot move a disposed DisposableStack.");
|
|
114
|
+
}
|
|
115
|
+
const moved = new DisposableStack();
|
|
116
|
+
// Transfer the array by reference so order is preserved, then mark this stack disposed without running any disposer.
|
|
117
|
+
moved.#disposers = this.#disposers;
|
|
118
|
+
this.#disposers = null;
|
|
119
|
+
return moved;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Dispose every registered resource in reverse (last-in-first-out) order. A second call is a no-op. Every disposer runs even when an earlier one throws: a single
|
|
123
|
+
* failure is rethrown after the sweep completes, and multiple failures chain through `SuppressedError` (the newest failure wrapping the accumulated one).
|
|
124
|
+
*/
|
|
125
|
+
dispose() {
|
|
126
|
+
if (this.#disposers === null) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
// Detach the array and mark disposed before running anything, so a disposer that re-enters this stack observes the disposed state and cannot double-run work.
|
|
130
|
+
const disposers = this.#disposers;
|
|
131
|
+
this.#disposers = null;
|
|
132
|
+
let hasError = false;
|
|
133
|
+
let heldError;
|
|
134
|
+
// Reverse the detached array in place - we hold the only reference to it, so mutating it is safe - and run the disposers last-in-first-out.
|
|
135
|
+
for (const disposer of disposers.reverse()) {
|
|
136
|
+
try {
|
|
137
|
+
disposer();
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
heldError = hasError ? createSuppressedError(error, heldError) : error;
|
|
141
|
+
hasError = true;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (hasError) {
|
|
145
|
+
throw heldError;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Dispose this stack. Enables `using` semantics by delegating to {@link dispose}.
|
|
150
|
+
*/
|
|
151
|
+
[Symbol.dispose]() {
|
|
152
|
+
this.dispose();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=disposable-stack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"disposable-stack.js","sourceRoot":"","sources":["../src/disposable-stack.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A shared documentation-chrome renderer for the family's plugins.
|
|
3
|
+
*
|
|
4
|
+
* Every plugin hand-maintains the same "chrome" in many places: a multi-line badge/logo masthead byte-copied to the top of the README and every content doc, and an
|
|
5
|
+
* ordered documentation index (each doc's title plus a one-line blurb) duplicated between the README's documentation section and the webUI's Support tab. Those copies
|
|
6
|
+
* drift - a badge label here, a blurb there, an href form that differs per surface. This module collapses all of it into one per-plugin {@link DocChromeManifest} that a
|
|
7
|
+
* plugin authors once (as a typed module or a static JSON file), so each surface becomes a pure projection of a single source of truth.
|
|
8
|
+
*
|
|
9
|
+
* The module exports pure string renderers - {@link renderMasthead}, {@link renderDocIndex}, {@link renderDevBadges}, {@link renderProjects} - and the marker constants
|
|
10
|
+
* each surface embeds, plus the {@link parseDocChromeManifest} / {@link parseProjectEntries} validators. Like `featureOptions-docs.ts`, every function here is pure and
|
|
11
|
+
* isomorphic: no `node:` imports, no `fs`, no `fetch`. Reading the target files, resolving a remote project list, and writing the spliced result back are the CLI's
|
|
12
|
+
* concern; this module only ever renders already-resolved data. That keeps it browser-safe and trivially testable, though it is a tooling concern and is deliberately
|
|
13
|
+
* NOT mirrored into `dist/ui/`.
|
|
14
|
+
*
|
|
15
|
+
* @module
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Repository coordinates used to derive the GitHub blob URLs that navigation entries link to. The blob base is `https://github.com/{owner}/{name}/blob/{branch}`.
|
|
19
|
+
*
|
|
20
|
+
* @category Doc Chrome
|
|
21
|
+
*/
|
|
22
|
+
export interface RepoCoordinates {
|
|
23
|
+
readonly branch: string;
|
|
24
|
+
readonly name: string;
|
|
25
|
+
readonly owner: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* A single shields-style badge: its alt text, its image URL, and the URL it links to. Stored as a full image URL rather than assembled from parts so the manifest stays
|
|
29
|
+
* provider-agnostic - any badge service works, not just shields.io.
|
|
30
|
+
*
|
|
31
|
+
* @category Doc Chrome
|
|
32
|
+
*/
|
|
33
|
+
export interface Badge {
|
|
34
|
+
readonly alt: string;
|
|
35
|
+
readonly image: string;
|
|
36
|
+
readonly link: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The masthead: the centered logo, the H1 title, the ordered badge row, and the H2 tagline. Rendered identically into the README and every content doc. Text fields are
|
|
40
|
+
* author-owned markup (the tagline may contain markdown links) and pass through verbatim.
|
|
41
|
+
*
|
|
42
|
+
* @category Doc Chrome
|
|
43
|
+
*/
|
|
44
|
+
export interface Masthead {
|
|
45
|
+
readonly badges: readonly Badge[];
|
|
46
|
+
readonly logo: {
|
|
47
|
+
readonly alt: string;
|
|
48
|
+
readonly href: string;
|
|
49
|
+
readonly src: string;
|
|
50
|
+
};
|
|
51
|
+
readonly tagline: string;
|
|
52
|
+
readonly title: string;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* One documentation-index entry. A discriminated union on `kind`: a `"doc"` entry points at a file under the plugin's `docs/` tree (and may opt out of the masthead via
|
|
56
|
+
* `masthead: false`, as the changelog does), while a `"readme-anchor"` entry points at a section anchor within the README itself. The renderer derives the correct href
|
|
57
|
+
* per surface from this one canonical shape, so the same entry can render as an in-README anchor on the README and as an absolute blob URL everywhere else.
|
|
58
|
+
*
|
|
59
|
+
* @category Doc Chrome
|
|
60
|
+
*/
|
|
61
|
+
export type DocEntry = {
|
|
62
|
+
readonly anchor: string;
|
|
63
|
+
readonly blurb: string;
|
|
64
|
+
readonly kind: "readme-anchor";
|
|
65
|
+
readonly title: string;
|
|
66
|
+
} | {
|
|
67
|
+
readonly blurb: string;
|
|
68
|
+
readonly file: string;
|
|
69
|
+
readonly kind: "doc";
|
|
70
|
+
readonly masthead?: boolean;
|
|
71
|
+
readonly title: string;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* A named, ordered group of documentation entries (for example "Getting Started" or "Additional Topics"). Sections render in array order, and entries within a section
|
|
75
|
+
* render in array order.
|
|
76
|
+
*
|
|
77
|
+
* @category Doc Chrome
|
|
78
|
+
*/
|
|
79
|
+
export interface NavSection {
|
|
80
|
+
readonly entries: readonly DocEntry[];
|
|
81
|
+
readonly title: string;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* One "other projects" entry for the webUI's project list. The rendered link text is `{title}: {blurb}`.
|
|
85
|
+
*
|
|
86
|
+
* @category Doc Chrome
|
|
87
|
+
*/
|
|
88
|
+
export interface ProjectEntry {
|
|
89
|
+
readonly blurb: string;
|
|
90
|
+
readonly href: string;
|
|
91
|
+
readonly title: string;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* A manifest fragment whose data may be supplied inline (an array), read from a local file relative to the plugin root (`{ file }`), or fetched from a URL at stamp time
|
|
95
|
+
* (`{ url }`). The CLI resolves these; the renderers only ever see the resolved inline array. The URL form is what lets a family-wide list (the project list) live in one
|
|
96
|
+
* external file that every plugin's next build pulls from, without baking that list into this generic library.
|
|
97
|
+
*
|
|
98
|
+
* @category Doc Chrome
|
|
99
|
+
*/
|
|
100
|
+
export type ExternalSource<T> = readonly T[] | {
|
|
101
|
+
readonly file: string;
|
|
102
|
+
} | {
|
|
103
|
+
readonly url: string;
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* The per-plugin documentation-chrome manifest - the single source of truth for a plugin's masthead, documentation index, dashboard badges, and project list. Authored
|
|
107
|
+
* once per plugin (a typed TS module or a static JSON file) and consumed by the `prepare-chrome` CLI subcommand.
|
|
108
|
+
*
|
|
109
|
+
* @category Doc Chrome
|
|
110
|
+
*/
|
|
111
|
+
export interface DocChromeManifest {
|
|
112
|
+
readonly devBadges?: readonly Badge[];
|
|
113
|
+
readonly masthead: Masthead;
|
|
114
|
+
readonly nav: readonly NavSection[];
|
|
115
|
+
readonly projects?: ExternalSource<ProjectEntry>;
|
|
116
|
+
readonly repo: RepoCoordinates;
|
|
117
|
+
readonly surfaces?: {
|
|
118
|
+
readonly readme?: string;
|
|
119
|
+
readonly webui?: string;
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* The surface a documentation index is rendered for. `"readme"` and `"doc-footer"` both render markdown; `"webui"` renders HTML. The surface also selects href
|
|
124
|
+
* derivation: `"readme"` uses in-README section anchors for `readme-anchor` entries, while `"doc-footer"` and `"webui"` use absolute blob URLs (an anchor entry viewed
|
|
125
|
+
* from anywhere other than the README itself must resolve to the README's absolute URL). Only `"doc-footer"` omits the current document from its own list.
|
|
126
|
+
*
|
|
127
|
+
* @category Doc Chrome
|
|
128
|
+
*/
|
|
129
|
+
export type NavSurface = "doc-footer" | "readme" | "webui";
|
|
130
|
+
/**
|
|
131
|
+
* The opening marker of the auto-generated masthead region. See {@link renderMasthead}. The text doubles as an in-document warning not to edit the region by hand.
|
|
132
|
+
*
|
|
133
|
+
* @category Doc Chrome
|
|
134
|
+
*/
|
|
135
|
+
export declare const MASTHEAD_BEGIN = "<!-- MASTHEAD:BEGIN - Auto-generated by homebridge-plugin-utils. Do not edit this region by hand. -->";
|
|
136
|
+
/**
|
|
137
|
+
* The closing marker of the auto-generated masthead region. See {@link MASTHEAD_BEGIN}.
|
|
138
|
+
*
|
|
139
|
+
* @category Doc Chrome
|
|
140
|
+
*/
|
|
141
|
+
export declare const MASTHEAD_END = "<!-- MASTHEAD:END -->";
|
|
142
|
+
/**
|
|
143
|
+
* The opening marker of the auto-generated documentation-index region, used in the README's documentation section, each content doc's footer, and the webUI's Support
|
|
144
|
+
* tab. See {@link renderDocIndex}.
|
|
145
|
+
*
|
|
146
|
+
* @category Doc Chrome
|
|
147
|
+
*/
|
|
148
|
+
export declare const DOCUMENTATION_BEGIN = "<!-- DOCUMENTATION:BEGIN - Auto-generated by homebridge-plugin-utils. Do not edit this region by hand. -->";
|
|
149
|
+
/**
|
|
150
|
+
* The closing marker of the auto-generated documentation-index region. See {@link DOCUMENTATION_BEGIN}.
|
|
151
|
+
*
|
|
152
|
+
* @category Doc Chrome
|
|
153
|
+
*/
|
|
154
|
+
export declare const DOCUMENTATION_END = "<!-- DOCUMENTATION:END -->";
|
|
155
|
+
/**
|
|
156
|
+
* The opening marker of the auto-generated development-dashboard badge region (README only). See {@link renderDevBadges}.
|
|
157
|
+
*
|
|
158
|
+
* @category Doc Chrome
|
|
159
|
+
*/
|
|
160
|
+
export declare const DEV_BADGES_BEGIN = "<!-- DEV BADGES:BEGIN - Auto-generated by homebridge-plugin-utils. Do not edit this region by hand. -->";
|
|
161
|
+
/**
|
|
162
|
+
* The closing marker of the auto-generated development-dashboard badge region. See {@link DEV_BADGES_BEGIN}.
|
|
163
|
+
*
|
|
164
|
+
* @category Doc Chrome
|
|
165
|
+
*/
|
|
166
|
+
export declare const DEV_BADGES_END = "<!-- DEV BADGES:END -->";
|
|
167
|
+
/**
|
|
168
|
+
* The opening marker of the auto-generated project-list region (webUI only). See {@link renderProjects}.
|
|
169
|
+
*
|
|
170
|
+
* @category Doc Chrome
|
|
171
|
+
*/
|
|
172
|
+
export declare const PROJECTS_BEGIN = "<!-- PROJECTS:BEGIN - Auto-generated by homebridge-plugin-utils. Do not edit this region by hand. -->";
|
|
173
|
+
/**
|
|
174
|
+
* The closing marker of the auto-generated project-list region. See {@link PROJECTS_BEGIN}.
|
|
175
|
+
*
|
|
176
|
+
* @category Doc Chrome
|
|
177
|
+
*/
|
|
178
|
+
export declare const PROJECTS_END = "<!-- PROJECTS:END -->";
|
|
179
|
+
/**
|
|
180
|
+
* Render the masthead - the centered logo, the H1 title, the ordered badge row, and the H2 tagline - as the markdown/HTML block a plugin embeds at the top of its README
|
|
181
|
+
* and every content doc. The block is identical across those surfaces, so a single manifest drives all of them and the hand-copied mastheads collapse to one.
|
|
182
|
+
*
|
|
183
|
+
* @param manifest - The documentation-chrome manifest.
|
|
184
|
+
*
|
|
185
|
+
* @returns The rendered masthead block.
|
|
186
|
+
*
|
|
187
|
+
* @category Doc Chrome
|
|
188
|
+
*/
|
|
189
|
+
export declare function renderMasthead(manifest: DocChromeManifest): string;
|
|
190
|
+
/**
|
|
191
|
+
* Render the development-dashboard badges - the README-only badge row (license, build status, dependencies, and the like) that sits apart from the masthead. Returns an
|
|
192
|
+
* empty string when the manifest declares no dashboard badges.
|
|
193
|
+
*
|
|
194
|
+
* @param manifest - The documentation-chrome manifest.
|
|
195
|
+
*
|
|
196
|
+
* @returns The rendered badge rows, one badge per line.
|
|
197
|
+
*
|
|
198
|
+
* @category Doc Chrome
|
|
199
|
+
*/
|
|
200
|
+
export declare function renderDevBadges(manifest: DocChromeManifest): string;
|
|
201
|
+
/**
|
|
202
|
+
* Render the documentation index for a surface. On the markdown surfaces (`"readme"`, `"doc-footer"`) the output is one bullet per section with a nested bullet per
|
|
203
|
+
* entry; on `"webui"` it is one `<h5>` heading and `<ul>` per section. Href derivation follows the surface: in-README anchors on `"readme"`, absolute blob URLs
|
|
204
|
+
* elsewhere. A `"doc-footer"` render omits the current document (via `currentFile`) and drops any section left empty by that omission, so a doc's own footer never links
|
|
205
|
+
* back to itself.
|
|
206
|
+
*
|
|
207
|
+
* @param input
|
|
208
|
+
* @param input.currentFile - The doc file being rendered into, relative to the plugin root. Only consulted for the `"doc-footer"` surface, to omit the self-link.
|
|
209
|
+
* @param input.manifest - The documentation-chrome manifest.
|
|
210
|
+
* @param input.surface - The surface to render for.
|
|
211
|
+
*
|
|
212
|
+
* @returns The rendered documentation index.
|
|
213
|
+
*
|
|
214
|
+
* @category Doc Chrome
|
|
215
|
+
*/
|
|
216
|
+
export declare function renderDocIndex({ currentFile, manifest, surface }: {
|
|
217
|
+
currentFile?: string;
|
|
218
|
+
manifest: DocChromeManifest;
|
|
219
|
+
surface: NavSurface;
|
|
220
|
+
}): string;
|
|
221
|
+
/**
|
|
222
|
+
* Render the webUI project list - the "other projects" links - as an HTML `<ul>`. The CLI resolves the manifest's project source (inline, local file, or remote URL) to
|
|
223
|
+
* this array before calling; the renderer never performs I/O. Entries are rendered in alphabetical order by title, so the list reads predictably no matter what order the
|
|
224
|
+
* source - often a shared, remotely-fetched file every plugin points at - happens to hold. Each entry's link text is `{title}: {blurb}`.
|
|
225
|
+
*
|
|
226
|
+
* @param projects - The resolved project entries. Their order is not significant; the renderer sorts them by title.
|
|
227
|
+
*
|
|
228
|
+
* @returns The rendered project list.
|
|
229
|
+
*
|
|
230
|
+
* @category Doc Chrome
|
|
231
|
+
*/
|
|
232
|
+
export declare function renderProjects(projects: readonly ProjectEntry[]): string;
|
|
233
|
+
/**
|
|
234
|
+
* Validate a loaded value and return it typed as a well-formed {@link DocChromeManifest}, failing fast with a framed diagnostic that names the manifest source and the
|
|
235
|
+
* offending field rather than surfacing an opaque error deep inside a renderer or a bare `resolve()` type error in the CLI. Validates every field the renderer or the
|
|
236
|
+
* CLI consumes - `masthead`, `nav`, `repo`, and the optional `devBadges` and `surfaces`. The project source is validated separately at resolution time, since it may be
|
|
237
|
+
* a remote reference rather than inline data.
|
|
238
|
+
*
|
|
239
|
+
* @param value - The loaded manifest value, untrusted until validated.
|
|
240
|
+
* @param source - The manifest's path or module specifier, for diagnostics.
|
|
241
|
+
*
|
|
242
|
+
* @returns The same value, now typed as a validated {@link DocChromeManifest}.
|
|
243
|
+
*
|
|
244
|
+
* @category Doc Chrome
|
|
245
|
+
*/
|
|
246
|
+
export declare function parseDocChromeManifest(value: unknown, source: string): DocChromeManifest;
|
|
247
|
+
/**
|
|
248
|
+
* Validate a resolved project source and return it typed as an array of {@link ProjectEntry}. The CLI calls this after resolving the manifest's project source - which
|
|
249
|
+
* may be inline data, a local file, or a remote URL - so a malformed external list fails fast with a framed diagnostic naming the source rather than rendering broken
|
|
250
|
+
* markup.
|
|
251
|
+
*
|
|
252
|
+
* @param value - The resolved project value, untrusted until validated.
|
|
253
|
+
* @param source - The project source (a path or URL) for diagnostics.
|
|
254
|
+
*
|
|
255
|
+
* @returns The same value, now typed as a validated array of {@link ProjectEntry}.
|
|
256
|
+
*
|
|
257
|
+
* @category Doc Chrome
|
|
258
|
+
*/
|
|
259
|
+
export declare function parseProjectEntries(value: unknown, source: string): readonly ProjectEntry[];
|
|
260
|
+
//# sourceMappingURL=docChrome.d.ts.map
|