homebridge-plugin-utils 1.35.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.
Files changed (204) hide show
  1. package/README.md +130 -2
  2. package/build/eslint-plugin/README.md +164 -0
  3. package/build/eslint-plugin/config.mjs +308 -0
  4. package/build/eslint-plugin/index.mjs +7 -0
  5. package/build/eslint-plugin/plugin.mjs +46 -0
  6. package/build/eslint-plugin/rules/blank-line-after-open-brace.mjs +137 -0
  7. package/build/eslint-plugin/rules/blank-line-after-open-brace.test.mjs +112 -0
  8. package/build/eslint-plugin/rules/comment-style.mjs +190 -0
  9. package/build/eslint-plugin/rules/comment-style.test.mjs +190 -0
  10. package/build/eslint-plugin/rules/enforce-node-protocol.mjs +114 -0
  11. package/build/eslint-plugin/rules/enforce-node-protocol.test.mjs +116 -0
  12. package/build/eslint-plugin/rules/paren-comparisons-in-logical.mjs +94 -0
  13. package/build/eslint-plugin/rules/paren-comparisons-in-logical.test.mjs +107 -0
  14. package/build/eslint-plugin/rules/split-type-imports.mjs +354 -0
  15. package/build/eslint-plugin/rules/split-type-imports.test.mjs +268 -0
  16. package/build/eslint-plugin/test-setup.mjs +21 -0
  17. package/build/fs-ops.mjs +184 -0
  18. package/build/tsconfig.json +18 -3
  19. package/dist/backpressure.d.ts +94 -45
  20. package/dist/backpressure.js +229 -93
  21. package/dist/backpressure.js.map +1 -1
  22. package/dist/cli/index.d.ts +166 -0
  23. package/dist/cli/index.js +551 -0
  24. package/dist/cli/index.js.map +1 -0
  25. package/dist/clock-double.d.ts +93 -0
  26. package/dist/clock-double.js +141 -0
  27. package/dist/clock-double.js.map +1 -0
  28. package/dist/clock.d.ts +39 -0
  29. package/dist/clock.js +34 -0
  30. package/dist/clock.js.map +1 -0
  31. package/dist/disposable-stack.d.ts +59 -0
  32. package/dist/disposable-stack.js +155 -0
  33. package/dist/disposable-stack.js.map +1 -0
  34. package/dist/docChrome.d.ts +260 -0
  35. package/dist/docChrome.js +361 -0
  36. package/dist/docChrome.js.map +1 -0
  37. package/dist/eslint-plugin/config.d.mts +193 -0
  38. package/dist/eslint-plugin/index.d.mts +2 -0
  39. package/dist/eslint-plugin/plugin.d.mts +87 -0
  40. package/dist/eslint-plugin/rules/blank-line-after-open-brace.d.mts +19 -0
  41. package/dist/eslint-plugin/rules/comment-style.d.mts +15 -0
  42. package/dist/eslint-plugin/rules/enforce-node-protocol.d.mts +18 -0
  43. package/dist/eslint-plugin/rules/paren-comparisons-in-logical.d.mts +15 -0
  44. package/dist/eslint-plugin/rules/split-type-imports.d.mts +16 -0
  45. package/dist/featureOptions-docs.d.ts +96 -0
  46. package/dist/featureOptions-docs.js +193 -0
  47. package/dist/featureOptions-docs.js.map +1 -0
  48. package/dist/featureOptions.d.ts +674 -0
  49. package/dist/featureOptions.js +870 -0
  50. package/dist/featureOptions.js.map +1 -0
  51. package/dist/ffmpeg/codecs.d.ts +256 -72
  52. package/dist/ffmpeg/codecs.js +477 -262
  53. package/dist/ffmpeg/codecs.js.map +1 -1
  54. package/dist/ffmpeg/dgram-util.d.ts +46 -0
  55. package/dist/ffmpeg/dgram-util.js +38 -0
  56. package/dist/ffmpeg/dgram-util.js.map +1 -0
  57. package/dist/ffmpeg/exec.d.ts +83 -64
  58. package/dist/ffmpeg/exec.js +77 -86
  59. package/dist/ffmpeg/exec.js.map +1 -1
  60. package/dist/ffmpeg/fmp4.d.ts +49 -2
  61. package/dist/ffmpeg/fmp4.js +47 -11
  62. package/dist/ffmpeg/fmp4.js.map +1 -1
  63. package/dist/ffmpeg/hap-enums.d.ts +214 -0
  64. package/dist/ffmpeg/hap-enums.js +92 -0
  65. package/dist/ffmpeg/hap-enums.js.map +1 -0
  66. package/dist/ffmpeg/index.d.ts +16 -9
  67. package/dist/ffmpeg/index.js +6 -0
  68. package/dist/ffmpeg/index.js.map +1 -1
  69. package/dist/ffmpeg/mp4-assembler.d.ts +161 -0
  70. package/dist/ffmpeg/mp4-assembler.js +424 -0
  71. package/dist/ffmpeg/mp4-assembler.js.map +1 -0
  72. package/dist/ffmpeg/mp4-parser.d.ts +94 -0
  73. package/dist/ffmpeg/mp4-parser.js +130 -0
  74. package/dist/ffmpeg/mp4-parser.js.map +1 -0
  75. package/dist/ffmpeg/options.d.ts +62 -149
  76. package/dist/ffmpeg/options.js +608 -499
  77. package/dist/ffmpeg/options.js.map +1 -1
  78. package/dist/ffmpeg/process.d.ts +142 -96
  79. package/dist/ffmpeg/process.js +406 -278
  80. package/dist/ffmpeg/process.js.map +1 -1
  81. package/dist/ffmpeg/record.d.ts +325 -186
  82. package/dist/ffmpeg/record.js +418 -565
  83. package/dist/ffmpeg/record.js.map +1 -1
  84. package/dist/ffmpeg/recording-process-double.d.ts +157 -0
  85. package/dist/ffmpeg/recording-process-double.js +190 -0
  86. package/dist/ffmpeg/recording-process-double.js.map +1 -0
  87. package/dist/ffmpeg/rtp-parser.d.ts +70 -0
  88. package/dist/ffmpeg/rtp-parser.js +77 -0
  89. package/dist/ffmpeg/rtp-parser.js.map +1 -0
  90. package/dist/ffmpeg/rtp.d.ts +198 -141
  91. package/dist/ffmpeg/rtp.js +474 -251
  92. package/dist/ffmpeg/rtp.js.map +1 -1
  93. package/dist/ffmpeg/settings.d.ts +5 -2
  94. package/dist/ffmpeg/settings.js +20 -5
  95. package/dist/ffmpeg/settings.js.map +1 -1
  96. package/dist/ffmpeg/stream.d.ts +57 -107
  97. package/dist/ffmpeg/stream.js +121 -150
  98. package/dist/ffmpeg/stream.js.map +1 -1
  99. package/dist/formatters.d.ts +106 -0
  100. package/dist/formatters.js +174 -0
  101. package/dist/formatters.js.map +1 -0
  102. package/dist/homebridge-enums.d.ts +30 -0
  103. package/dist/homebridge-enums.js +17 -0
  104. package/dist/homebridge-enums.js.map +1 -0
  105. package/dist/index.d.ts +13 -6
  106. package/dist/index.js +8 -2
  107. package/dist/index.js.map +1 -1
  108. package/dist/logclient/auth.d.ts +114 -0
  109. package/dist/logclient/auth.js +199 -0
  110. package/dist/logclient/auth.js.map +1 -0
  111. package/dist/logclient/cli-run.d.ts +76 -0
  112. package/dist/logclient/cli-run.js +639 -0
  113. package/dist/logclient/cli-run.js.map +1 -0
  114. package/dist/logclient/cli.d.ts +3 -0
  115. package/dist/logclient/cli.js +97 -0
  116. package/dist/logclient/cli.js.map +1 -0
  117. package/dist/logclient/client.d.ts +145 -0
  118. package/dist/logclient/client.js +600 -0
  119. package/dist/logclient/client.js.map +1 -0
  120. package/dist/logclient/config.d.ts +173 -0
  121. package/dist/logclient/config.js +199 -0
  122. package/dist/logclient/config.js.map +1 -0
  123. package/dist/logclient/endpoints.d.ts +54 -0
  124. package/dist/logclient/endpoints.js +73 -0
  125. package/dist/logclient/endpoints.js.map +1 -0
  126. package/dist/logclient/filter.d.ts +45 -0
  127. package/dist/logclient/filter.js +51 -0
  128. package/dist/logclient/filter.js.map +1 -0
  129. package/dist/logclient/frame.d.ts +93 -0
  130. package/dist/logclient/frame.js +203 -0
  131. package/dist/logclient/frame.js.map +1 -0
  132. package/dist/logclient/index.d.ts +31 -0
  133. package/dist/logclient/index.js +12 -0
  134. package/dist/logclient/index.js.map +1 -0
  135. package/dist/logclient/parser.d.ts +211 -0
  136. package/dist/logclient/parser.js +393 -0
  137. package/dist/logclient/parser.js.map +1 -0
  138. package/dist/logclient/rest.d.ts +41 -0
  139. package/dist/logclient/rest.js +111 -0
  140. package/dist/logclient/rest.js.map +1 -0
  141. package/dist/logclient/settings.d.ts +15 -0
  142. package/dist/logclient/settings.js +64 -0
  143. package/dist/logclient/settings.js.map +1 -0
  144. package/dist/logclient/socket-double.d.ts +201 -0
  145. package/dist/logclient/socket-double.js +384 -0
  146. package/dist/logclient/socket-double.js.map +1 -0
  147. package/dist/logclient/socket.d.ts +257 -0
  148. package/dist/logclient/socket.js +620 -0
  149. package/dist/logclient/socket.js.map +1 -0
  150. package/dist/logclient/stitch.d.ts +83 -0
  151. package/dist/logclient/stitch.js +146 -0
  152. package/dist/logclient/stitch.js.map +1 -0
  153. package/dist/logclient/time-expression.d.ts +42 -0
  154. package/dist/logclient/time-expression.js +181 -0
  155. package/dist/logclient/time-expression.js.map +1 -0
  156. package/dist/logclient/time-window.d.ts +38 -0
  157. package/dist/logclient/time-window.js +53 -0
  158. package/dist/logclient/time-window.js.map +1 -0
  159. package/dist/logclient/types.d.ts +107 -0
  160. package/dist/logclient/types.js +6 -0
  161. package/dist/logclient/types.js.map +1 -0
  162. package/dist/mqttClient.d.ts +287 -0
  163. package/dist/mqttClient.js +433 -0
  164. package/dist/mqttClient.js.map +1 -0
  165. package/dist/service.d.ts +64 -15
  166. package/dist/service.js +93 -66
  167. package/dist/service.js.map +1 -1
  168. package/dist/ui/featureOptions.js +870 -0
  169. package/dist/ui/featureOptions.js.map +1 -0
  170. package/dist/ui/formatters.js +174 -0
  171. package/dist/ui/formatters.js.map +1 -0
  172. package/dist/ui/pluginConfigSession.mjs +141 -0
  173. package/dist/ui/webUi-featureOptions/categoryState.mjs +135 -0
  174. package/dist/ui/webUi-featureOptions/effects/keyboard.mjs +61 -0
  175. package/dist/ui/webUi-featureOptions/effects/persist.mjs +226 -0
  176. package/dist/ui/webUi-featureOptions/effects/theme.mjs +398 -0
  177. package/dist/ui/webUi-featureOptions/effects/tokens.mjs +152 -0
  178. package/dist/ui/webUi-featureOptions/rendering.mjs +431 -0
  179. package/dist/ui/webUi-featureOptions/selectors.mjs +360 -0
  180. package/dist/ui/webUi-featureOptions/state.mjs +319 -0
  181. package/dist/ui/webUi-featureOptions/store.mjs +181 -0
  182. package/dist/ui/webUi-featureOptions/utils.mjs +213 -0
  183. package/dist/ui/webUi-featureOptions/views/connectionError.mjs +152 -0
  184. package/dist/ui/webUi-featureOptions/views/deviceInfo.mjs +80 -0
  185. package/dist/ui/webUi-featureOptions/views/header.mjs +77 -0
  186. package/dist/ui/webUi-featureOptions/views/nav.mjs +341 -0
  187. package/dist/ui/webUi-featureOptions/views/options.mjs +521 -0
  188. package/dist/ui/webUi-featureOptions/views/search.mjs +395 -0
  189. package/dist/ui/webUi-featureOptions.mjs +702 -0
  190. package/dist/ui/webUi.mjs +225 -88
  191. package/dist/util.d.ts +679 -45
  192. package/dist/util.js +830 -77
  193. package/dist/util.js.map +1 -1
  194. package/package.json +33 -15
  195. package/build/eslint-rules.mjs +0 -511
  196. package/dist/featureoptions.d.ts +0 -264
  197. package/dist/featureoptions.js +0 -480
  198. package/dist/featureoptions.js.map +0 -1
  199. package/dist/mqttclient.d.ts +0 -178
  200. package/dist/mqttclient.js +0 -310
  201. package/dist/mqttclient.js.map +0 -1
  202. package/dist/ui/featureoptions.js +0 -480
  203. package/dist/ui/featureoptions.js.map +0 -1
  204. package/dist/ui/webUi-featureoptions.mjs +0 -3765
@@ -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
@@ -0,0 +1,361 @@
1
+ /* Copyright(C) 2017-2026, HJD (https://github.com/hjdhjd). All rights reserved.
2
+ *
3
+ * docChrome.ts: Pure, isomorphic renderers that project a per-plugin documentation-chrome manifest into the masthead, navigation index, dashboard badges, and project
4
+ * list that every family plugin repeats by hand across its README, its docs, and its webUI.
5
+ */
6
+ /**
7
+ * 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.
8
+ *
9
+ * @category Doc Chrome
10
+ */
11
+ export const MASTHEAD_BEGIN = "<!-- MASTHEAD:BEGIN - Auto-generated by homebridge-plugin-utils. Do not edit this region by hand. -->";
12
+ /**
13
+ * The closing marker of the auto-generated masthead region. See {@link MASTHEAD_BEGIN}.
14
+ *
15
+ * @category Doc Chrome
16
+ */
17
+ export const MASTHEAD_END = "<!-- MASTHEAD:END -->";
18
+ /**
19
+ * 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
20
+ * tab. See {@link renderDocIndex}.
21
+ *
22
+ * @category Doc Chrome
23
+ */
24
+ export const DOCUMENTATION_BEGIN = "<!-- DOCUMENTATION:BEGIN - Auto-generated by homebridge-plugin-utils. Do not edit this region by hand. -->";
25
+ /**
26
+ * The closing marker of the auto-generated documentation-index region. See {@link DOCUMENTATION_BEGIN}.
27
+ *
28
+ * @category Doc Chrome
29
+ */
30
+ export const DOCUMENTATION_END = "<!-- DOCUMENTATION:END -->";
31
+ /**
32
+ * The opening marker of the auto-generated development-dashboard badge region (README only). See {@link renderDevBadges}.
33
+ *
34
+ * @category Doc Chrome
35
+ */
36
+ export const DEV_BADGES_BEGIN = "<!-- DEV BADGES:BEGIN - Auto-generated by homebridge-plugin-utils. Do not edit this region by hand. -->";
37
+ /**
38
+ * The closing marker of the auto-generated development-dashboard badge region. See {@link DEV_BADGES_BEGIN}.
39
+ *
40
+ * @category Doc Chrome
41
+ */
42
+ export const DEV_BADGES_END = "<!-- DEV BADGES:END -->";
43
+ /**
44
+ * The opening marker of the auto-generated project-list region (webUI only). See {@link renderProjects}.
45
+ *
46
+ * @category Doc Chrome
47
+ */
48
+ export const PROJECTS_BEGIN = "<!-- PROJECTS:BEGIN - Auto-generated by homebridge-plugin-utils. Do not edit this region by hand. -->";
49
+ /**
50
+ * The closing marker of the auto-generated project-list region. See {@link PROJECTS_BEGIN}.
51
+ *
52
+ * @category Doc Chrome
53
+ */
54
+ export const PROJECTS_END = "<!-- PROJECTS:END -->";
55
+ // Escape text destined for an HTML text node. We neutralize "&", "<", and ">" so a blurb containing any of them renders as literal text rather than being parsed as
56
+ // markup. "&" is replaced first so the entities we introduce are not themselves re-escaped. This applies only to the webUI (HTML) surface; the markdown surfaces embed
57
+ // author-owned prose verbatim, matching the hand-authored source the renderer reproduces.
58
+ function escapeHtmlText(text) {
59
+ return text.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
60
+ }
61
+ // Escape a value destined for a double-quoted HTML attribute (an href). It builds on the text-node escaping - the shared single source of truth for the "&"/"<"/">"
62
+ // entities - and adds the double quote that would otherwise terminate the attribute early. The quote substitution runs after the text escaping, so the "&" it introduces
63
+ // is not itself re-escaped.
64
+ function escapeHtmlAttr(value) {
65
+ return escapeHtmlText(value).replaceAll("\"", "&quot;");
66
+ }
67
+ // The absolute GitHub blob base for a repository, the prefix every non-local navigation href is built on.
68
+ function blobBaseUrl(repo) {
69
+ return "https://github.com/" + repo.owner + "/" + repo.name + "/blob/" + repo.branch;
70
+ }
71
+ // Render a single badge as a linked markdown image, the shape both the masthead and the dashboard badges share.
72
+ function renderBadge(badge) {
73
+ return "[![" + badge.alt + "](" + badge.image + ")](" + badge.link + ")";
74
+ }
75
+ // Derive the href for a documentation entry on a given surface. On the README itself a `readme-anchor` entry is an in-page anchor; viewed from anywhere else it must
76
+ // resolve to the README's absolute blob URL. A `doc` entry is always an absolute blob URL to its file, identical on every surface - which is what collapses the
77
+ // per-surface href drift the hand-maintained lists suffer from.
78
+ function docEntryHref(entry, repo, local) {
79
+ if (entry.kind === "readme-anchor") {
80
+ return local ? ("#" + entry.anchor) : (blobBaseUrl(repo) + "/README.md#" + entry.anchor);
81
+ }
82
+ return blobBaseUrl(repo) + "/" + entry.file;
83
+ }
84
+ /**
85
+ * 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
86
+ * 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.
87
+ *
88
+ * @param manifest - The documentation-chrome manifest.
89
+ *
90
+ * @returns The rendered masthead block.
91
+ *
92
+ * @category Doc Chrome
93
+ */
94
+ export function renderMasthead(manifest) {
95
+ const { badges, logo, tagline, title } = manifest.masthead;
96
+ // Assemble the block line by line: the centering wrapper, the linked logo image, the title, one linked badge image per badge, and the tagline. A pushed empty string
97
+ // is a blank line, keeping the vertical rhythm explicit rather than threading "\n\n" through concatenations.
98
+ const lines = [
99
+ "<SPAN ALIGN=\"CENTER\" STYLE=\"text-align:center\">",
100
+ "<DIV ALIGN=\"CENTER\" STYLE=\"text-align:center\">",
101
+ "",
102
+ "[![" + logo.alt + "](" + logo.src + ")](" + logo.href + ")",
103
+ "",
104
+ "# " + title,
105
+ "",
106
+ ...badges.map(renderBadge),
107
+ "",
108
+ "## " + tagline,
109
+ "</DIV>",
110
+ "</SPAN>"
111
+ ];
112
+ return lines.join("\n");
113
+ }
114
+ /**
115
+ * 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
116
+ * empty string when the manifest declares no dashboard badges.
117
+ *
118
+ * @param manifest - The documentation-chrome manifest.
119
+ *
120
+ * @returns The rendered badge rows, one badge per line.
121
+ *
122
+ * @category Doc Chrome
123
+ */
124
+ export function renderDevBadges(manifest) {
125
+ return (manifest.devBadges ?? []).map(renderBadge).join("\n");
126
+ }
127
+ /**
128
+ * 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
129
+ * 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
130
+ * 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
131
+ * back to itself.
132
+ *
133
+ * @param input
134
+ * @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.
135
+ * @param input.manifest - The documentation-chrome manifest.
136
+ * @param input.surface - The surface to render for.
137
+ *
138
+ * @returns The rendered documentation index.
139
+ *
140
+ * @category Doc Chrome
141
+ */
142
+ export function renderDocIndex({ currentFile, manifest, surface }) {
143
+ if (surface === "webui") {
144
+ // The webUI surface renders HTML and never omits a self-link (it is not itself a doc). Each entry links to an absolute blob URL.
145
+ const sections = manifest.nav.map((section) => {
146
+ const items = section.entries.map((entry) => {
147
+ return " <li><a target=\"_blank\" href=\"" + escapeHtmlAttr(docEntryHref(entry, manifest.repo, false)) + "\">" + escapeHtmlText(entry.title) + "</a>: " +
148
+ escapeHtmlText(entry.blurb) + "</li>";
149
+ });
150
+ return "<h5>" + escapeHtmlText(section.title) + "</h5>\n<ul dir=\"auto\">\n" + items.join("\n") + "\n</ul>";
151
+ });
152
+ return sections.join("\n\n");
153
+ }
154
+ // The markdown surfaces. `"readme"` uses in-page anchors for anchor entries; `"doc-footer"` uses absolute URLs and omits the current doc.
155
+ const local = surface === "readme";
156
+ const omitFile = (surface === "doc-footer") ? currentFile : undefined;
157
+ const sections = [];
158
+ for (const section of manifest.nav) {
159
+ const bullets = section.entries
160
+ .filter((entry) => !((entry.kind === "doc") && (entry.file === omitFile)))
161
+ .map((entry) => " * [" + entry.title + "](" + docEntryHref(entry, manifest.repo, local) + "): " + entry.blurb);
162
+ // Drop a section that the self-omission emptied, so a footer never renders a heading with no entries beneath it.
163
+ if (bullets.length === 0) {
164
+ continue;
165
+ }
166
+ sections.push(["* " + section.title, ...bullets].join("\n"));
167
+ }
168
+ return sections.join("\n\n");
169
+ }
170
+ /**
171
+ * 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
172
+ * 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
173
+ * source - often a shared, remotely-fetched file every plugin points at - happens to hold. Each entry's link text is `{title}: {blurb}`.
174
+ *
175
+ * @param projects - The resolved project entries. Their order is not significant; the renderer sorts them by title.
176
+ *
177
+ * @returns The rendered project list.
178
+ *
179
+ * @category Doc Chrome
180
+ */
181
+ export function renderProjects(projects) {
182
+ // Sort a copy by lowercased title so the output is alphabetical and consistent regardless of the source order, without disturbing the caller's array. We compare
183
+ // lowercased titles directly rather than through localeCompare so the ordering is identical on every build machine, independent of the host's locale.
184
+ const ordered = projects.toSorted((left, right) => {
185
+ const leftTitle = left.title.toLowerCase();
186
+ const rightTitle = right.title.toLowerCase();
187
+ if (leftTitle < rightTitle) {
188
+ return -1;
189
+ }
190
+ if (leftTitle > rightTitle) {
191
+ return 1;
192
+ }
193
+ return 0;
194
+ });
195
+ const items = ordered.map((project) => {
196
+ return " <li><a target=\"_blank\" href=\"" + escapeHtmlAttr(project.href) + "\">" + escapeHtmlText(project.title) + ": " +
197
+ escapeHtmlText(project.blurb) + "</a></li>";
198
+ });
199
+ return "<ul dir=\"auto\">\n" + items.join("\n") + "\n</ul>";
200
+ }
201
+ // Throw a uniformly framed validation error naming the manifest source and the offending path, mirroring the diagnostics the catalog validation in the CLI produces.
202
+ function fail(source, detail) {
203
+ throw new Error("Doc-chrome manifest " + source + " " + detail + ".");
204
+ }
205
+ // Assert that a value is a non-empty string at a named path, else fail with a framed diagnostic.
206
+ function assertString(value, path, source) {
207
+ if ((typeof value !== "string") || (value.length === 0)) {
208
+ fail(source, "field `" + path + "` must be a non-empty string");
209
+ }
210
+ }
211
+ // Validate a badge's shape. Shared by the masthead badges and the optional dashboard badges.
212
+ function assertBadge(value, path, source) {
213
+ if ((typeof value !== "object") || (value === null)) {
214
+ fail(source, "field `" + path + "` must be an object");
215
+ }
216
+ const badge = value;
217
+ assertString(badge.alt, path + ".alt", source);
218
+ assertString(badge.image, path + ".image", source);
219
+ assertString(badge.link, path + ".link", source);
220
+ }
221
+ // Validate one documentation entry. The `kind` tag selects which additional field is required.
222
+ function assertDocEntry(value, path, source) {
223
+ if ((typeof value !== "object") || (value === null)) {
224
+ fail(source, "field `" + path + "` must be an object");
225
+ }
226
+ const entry = value;
227
+ assertString(entry.title, path + ".title", source);
228
+ assertString(entry.blurb, path + ".blurb", source);
229
+ switch (entry.kind) {
230
+ case "doc": {
231
+ assertString(entry.file, path + ".file", source);
232
+ if ((entry.masthead !== undefined) && (typeof entry.masthead !== "boolean")) {
233
+ fail(source, "field `" + path + ".masthead` must be a boolean when present");
234
+ }
235
+ return;
236
+ }
237
+ case "readme-anchor": {
238
+ assertString(entry.anchor, path + ".anchor", source);
239
+ return;
240
+ }
241
+ default: {
242
+ fail(source, "field `" + path + ".kind` must be \"doc\" or \"readme-anchor\"");
243
+ }
244
+ }
245
+ }
246
+ /**
247
+ * 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
248
+ * 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
249
+ * CLI consumes - `masthead`, `nav`, `repo`, and the optional `devBadges` and `surfaces`. The project source is validated separately at resolution time, since it may be
250
+ * a remote reference rather than inline data.
251
+ *
252
+ * @param value - The loaded manifest value, untrusted until validated.
253
+ * @param source - The manifest's path or module specifier, for diagnostics.
254
+ *
255
+ * @returns The same value, now typed as a validated {@link DocChromeManifest}.
256
+ *
257
+ * @category Doc Chrome
258
+ */
259
+ export function parseDocChromeManifest(value, source) {
260
+ if ((typeof value !== "object") || (value === null)) {
261
+ fail(source, "must export a manifest object");
262
+ }
263
+ const manifest = value;
264
+ // The masthead and its nested logo and badge row.
265
+ if ((typeof manifest.masthead !== "object") || (manifest.masthead === null)) {
266
+ fail(source, "field `masthead` must be an object");
267
+ }
268
+ const masthead = manifest.masthead;
269
+ assertString(masthead.title, "masthead.title", source);
270
+ assertString(masthead.tagline, "masthead.tagline", source);
271
+ if ((typeof masthead.logo !== "object") || (masthead.logo === null)) {
272
+ fail(source, "field `masthead.logo` must be an object");
273
+ }
274
+ const logo = masthead.logo;
275
+ assertString(logo.alt, "masthead.logo.alt", source);
276
+ assertString(logo.href, "masthead.logo.href", source);
277
+ assertString(logo.src, "masthead.logo.src", source);
278
+ if (!Array.isArray(masthead.badges)) {
279
+ fail(source, "field `masthead.badges` must be an array");
280
+ }
281
+ for (const [index, badge] of masthead.badges.entries()) {
282
+ assertBadge(badge, "masthead.badges[" + String(index) + "]", source);
283
+ }
284
+ // The repository coordinates.
285
+ if ((typeof manifest.repo !== "object") || (manifest.repo === null)) {
286
+ fail(source, "field `repo` must be an object");
287
+ }
288
+ const repo = manifest.repo;
289
+ assertString(repo.branch, "repo.branch", source);
290
+ assertString(repo.name, "repo.name", source);
291
+ assertString(repo.owner, "repo.owner", source);
292
+ // The navigation sections and their entries.
293
+ if (!Array.isArray(manifest.nav)) {
294
+ fail(source, "field `nav` must be an array");
295
+ }
296
+ for (const [sectionIndex, section] of manifest.nav.entries()) {
297
+ if ((typeof section !== "object") || (section === null)) {
298
+ fail(source, "field `nav[" + String(sectionIndex) + "]` must be an object");
299
+ }
300
+ const navSection = section;
301
+ assertString(navSection.title, "nav[" + String(sectionIndex) + "].title", source);
302
+ if (!Array.isArray(navSection.entries)) {
303
+ fail(source, "field `nav[" + String(sectionIndex) + "].entries` must be an array");
304
+ }
305
+ for (const [entryIndex, entry] of navSection.entries.entries()) {
306
+ assertDocEntry(entry, "nav[" + String(sectionIndex) + "].entries[" + String(entryIndex) + "]", source);
307
+ }
308
+ }
309
+ // The optional dashboard badges.
310
+ if (manifest.devBadges !== undefined) {
311
+ if (!Array.isArray(manifest.devBadges)) {
312
+ fail(source, "field `devBadges` must be an array when present");
313
+ }
314
+ for (const [index, badge] of manifest.devBadges.entries()) {
315
+ assertBadge(badge, "devBadges[" + String(index) + "]", source);
316
+ }
317
+ }
318
+ // The optional per-surface path overrides. These are consumed by the CLI's `resolve()` calls, so validating them here keeps the framed-diagnostic guarantee whole for
319
+ // a JSON-authored manifest that could otherwise smuggle a non-string path past the type system.
320
+ if (manifest.surfaces !== undefined) {
321
+ if ((typeof manifest.surfaces !== "object") || (manifest.surfaces === null)) {
322
+ fail(source, "field `surfaces` must be an object when present");
323
+ }
324
+ const surfaces = manifest.surfaces;
325
+ if ((surfaces.readme !== undefined) && ((typeof surfaces.readme !== "string") || (surfaces.readme.length === 0))) {
326
+ fail(source, "field `surfaces.readme` must be a non-empty string when present");
327
+ }
328
+ if ((surfaces.webui !== undefined) && ((typeof surfaces.webui !== "string") || (surfaces.webui.length === 0))) {
329
+ fail(source, "field `surfaces.webui` must be a non-empty string when present");
330
+ }
331
+ }
332
+ return value;
333
+ }
334
+ /**
335
+ * 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
336
+ * 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
337
+ * markup.
338
+ *
339
+ * @param value - The resolved project value, untrusted until validated.
340
+ * @param source - The project source (a path or URL) for diagnostics.
341
+ *
342
+ * @returns The same value, now typed as a validated array of {@link ProjectEntry}.
343
+ *
344
+ * @category Doc Chrome
345
+ */
346
+ export function parseProjectEntries(value, source) {
347
+ if (!Array.isArray(value)) {
348
+ fail(source, "project source must resolve to an array of project entries");
349
+ }
350
+ for (const [index, entry] of value.entries()) {
351
+ if ((typeof entry !== "object") || (entry === null)) {
352
+ fail(source, "project entry [" + String(index) + "] must be an object");
353
+ }
354
+ const project = entry;
355
+ assertString(project.blurb, "project entry [" + String(index) + "].blurb", source);
356
+ assertString(project.href, "project entry [" + String(index) + "].href", source);
357
+ assertString(project.title, "project entry [" + String(index) + "].title", source);
358
+ }
359
+ return value;
360
+ }
361
+ //# sourceMappingURL=docChrome.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docChrome.js","sourceRoot":"","sources":["../src/docChrome.ts"],"names":[],"mappings":"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"}