homebridge-plugin-utils 1.35.0 → 2.0.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 (198) 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 +95 -0
  23. package/dist/cli/index.js +355 -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/eslint-plugin/config.d.mts +193 -0
  32. package/dist/eslint-plugin/index.d.mts +2 -0
  33. package/dist/eslint-plugin/plugin.d.mts +87 -0
  34. package/dist/eslint-plugin/rules/blank-line-after-open-brace.d.mts +19 -0
  35. package/dist/eslint-plugin/rules/comment-style.d.mts +15 -0
  36. package/dist/eslint-plugin/rules/enforce-node-protocol.d.mts +18 -0
  37. package/dist/eslint-plugin/rules/paren-comparisons-in-logical.d.mts +15 -0
  38. package/dist/eslint-plugin/rules/split-type-imports.d.mts +16 -0
  39. package/dist/featureOptions-docs.d.ts +96 -0
  40. package/dist/featureOptions-docs.js +193 -0
  41. package/dist/featureOptions-docs.js.map +1 -0
  42. package/dist/featureOptions.d.ts +674 -0
  43. package/dist/featureOptions.js +870 -0
  44. package/dist/featureOptions.js.map +1 -0
  45. package/dist/ffmpeg/codecs.d.ts +256 -72
  46. package/dist/ffmpeg/codecs.js +477 -262
  47. package/dist/ffmpeg/codecs.js.map +1 -1
  48. package/dist/ffmpeg/dgram-util.d.ts +46 -0
  49. package/dist/ffmpeg/dgram-util.js +38 -0
  50. package/dist/ffmpeg/dgram-util.js.map +1 -0
  51. package/dist/ffmpeg/exec.d.ts +83 -64
  52. package/dist/ffmpeg/exec.js +77 -86
  53. package/dist/ffmpeg/exec.js.map +1 -1
  54. package/dist/ffmpeg/fmp4.d.ts +49 -2
  55. package/dist/ffmpeg/fmp4.js +47 -11
  56. package/dist/ffmpeg/fmp4.js.map +1 -1
  57. package/dist/ffmpeg/hap-enums.d.ts +214 -0
  58. package/dist/ffmpeg/hap-enums.js +92 -0
  59. package/dist/ffmpeg/hap-enums.js.map +1 -0
  60. package/dist/ffmpeg/index.d.ts +16 -9
  61. package/dist/ffmpeg/index.js +6 -0
  62. package/dist/ffmpeg/index.js.map +1 -1
  63. package/dist/ffmpeg/mp4-assembler.d.ts +120 -0
  64. package/dist/ffmpeg/mp4-assembler.js +387 -0
  65. package/dist/ffmpeg/mp4-assembler.js.map +1 -0
  66. package/dist/ffmpeg/mp4-parser.d.ts +94 -0
  67. package/dist/ffmpeg/mp4-parser.js +130 -0
  68. package/dist/ffmpeg/mp4-parser.js.map +1 -0
  69. package/dist/ffmpeg/options.d.ts +62 -149
  70. package/dist/ffmpeg/options.js +608 -499
  71. package/dist/ffmpeg/options.js.map +1 -1
  72. package/dist/ffmpeg/process.d.ts +142 -96
  73. package/dist/ffmpeg/process.js +406 -278
  74. package/dist/ffmpeg/process.js.map +1 -1
  75. package/dist/ffmpeg/record.d.ts +302 -188
  76. package/dist/ffmpeg/record.js +408 -567
  77. package/dist/ffmpeg/record.js.map +1 -1
  78. package/dist/ffmpeg/recording-process-double.d.ts +144 -0
  79. package/dist/ffmpeg/recording-process-double.js +168 -0
  80. package/dist/ffmpeg/recording-process-double.js.map +1 -0
  81. package/dist/ffmpeg/rtp-parser.d.ts +70 -0
  82. package/dist/ffmpeg/rtp-parser.js +77 -0
  83. package/dist/ffmpeg/rtp-parser.js.map +1 -0
  84. package/dist/ffmpeg/rtp.d.ts +198 -141
  85. package/dist/ffmpeg/rtp.js +473 -251
  86. package/dist/ffmpeg/rtp.js.map +1 -1
  87. package/dist/ffmpeg/settings.d.ts +5 -2
  88. package/dist/ffmpeg/settings.js +20 -5
  89. package/dist/ffmpeg/settings.js.map +1 -1
  90. package/dist/ffmpeg/stream.d.ts +57 -107
  91. package/dist/ffmpeg/stream.js +121 -150
  92. package/dist/ffmpeg/stream.js.map +1 -1
  93. package/dist/formatters.d.ts +106 -0
  94. package/dist/formatters.js +174 -0
  95. package/dist/formatters.js.map +1 -0
  96. package/dist/homebridge-enums.d.ts +30 -0
  97. package/dist/homebridge-enums.js +17 -0
  98. package/dist/homebridge-enums.js.map +1 -0
  99. package/dist/index.d.ts +12 -6
  100. package/dist/index.js +7 -2
  101. package/dist/index.js.map +1 -1
  102. package/dist/logclient/auth.d.ts +114 -0
  103. package/dist/logclient/auth.js +199 -0
  104. package/dist/logclient/auth.js.map +1 -0
  105. package/dist/logclient/cli-run.d.ts +76 -0
  106. package/dist/logclient/cli-run.js +639 -0
  107. package/dist/logclient/cli-run.js.map +1 -0
  108. package/dist/logclient/cli.d.ts +3 -0
  109. package/dist/logclient/cli.js +97 -0
  110. package/dist/logclient/cli.js.map +1 -0
  111. package/dist/logclient/client.d.ts +145 -0
  112. package/dist/logclient/client.js +600 -0
  113. package/dist/logclient/client.js.map +1 -0
  114. package/dist/logclient/config.d.ts +173 -0
  115. package/dist/logclient/config.js +199 -0
  116. package/dist/logclient/config.js.map +1 -0
  117. package/dist/logclient/endpoints.d.ts +54 -0
  118. package/dist/logclient/endpoints.js +73 -0
  119. package/dist/logclient/endpoints.js.map +1 -0
  120. package/dist/logclient/filter.d.ts +45 -0
  121. package/dist/logclient/filter.js +51 -0
  122. package/dist/logclient/filter.js.map +1 -0
  123. package/dist/logclient/frame.d.ts +93 -0
  124. package/dist/logclient/frame.js +203 -0
  125. package/dist/logclient/frame.js.map +1 -0
  126. package/dist/logclient/index.d.ts +31 -0
  127. package/dist/logclient/index.js +12 -0
  128. package/dist/logclient/index.js.map +1 -0
  129. package/dist/logclient/parser.d.ts +211 -0
  130. package/dist/logclient/parser.js +393 -0
  131. package/dist/logclient/parser.js.map +1 -0
  132. package/dist/logclient/rest.d.ts +41 -0
  133. package/dist/logclient/rest.js +111 -0
  134. package/dist/logclient/rest.js.map +1 -0
  135. package/dist/logclient/settings.d.ts +15 -0
  136. package/dist/logclient/settings.js +64 -0
  137. package/dist/logclient/settings.js.map +1 -0
  138. package/dist/logclient/socket-double.d.ts +201 -0
  139. package/dist/logclient/socket-double.js +384 -0
  140. package/dist/logclient/socket-double.js.map +1 -0
  141. package/dist/logclient/socket.d.ts +257 -0
  142. package/dist/logclient/socket.js +620 -0
  143. package/dist/logclient/socket.js.map +1 -0
  144. package/dist/logclient/stitch.d.ts +83 -0
  145. package/dist/logclient/stitch.js +146 -0
  146. package/dist/logclient/stitch.js.map +1 -0
  147. package/dist/logclient/time-expression.d.ts +42 -0
  148. package/dist/logclient/time-expression.js +181 -0
  149. package/dist/logclient/time-expression.js.map +1 -0
  150. package/dist/logclient/time-window.d.ts +38 -0
  151. package/dist/logclient/time-window.js +53 -0
  152. package/dist/logclient/time-window.js.map +1 -0
  153. package/dist/logclient/types.d.ts +107 -0
  154. package/dist/logclient/types.js +6 -0
  155. package/dist/logclient/types.js.map +1 -0
  156. package/dist/mqttClient.d.ts +287 -0
  157. package/dist/mqttClient.js +433 -0
  158. package/dist/mqttClient.js.map +1 -0
  159. package/dist/service.d.ts +64 -15
  160. package/dist/service.js +93 -66
  161. package/dist/service.js.map +1 -1
  162. package/dist/ui/featureOptions.js +870 -0
  163. package/dist/ui/featureOptions.js.map +1 -0
  164. package/dist/ui/formatters.js +174 -0
  165. package/dist/ui/formatters.js.map +1 -0
  166. package/dist/ui/pluginConfigSession.mjs +141 -0
  167. package/dist/ui/webUi-featureOptions/categoryState.mjs +135 -0
  168. package/dist/ui/webUi-featureOptions/effects/keyboard.mjs +61 -0
  169. package/dist/ui/webUi-featureOptions/effects/persist.mjs +226 -0
  170. package/dist/ui/webUi-featureOptions/effects/theme.mjs +398 -0
  171. package/dist/ui/webUi-featureOptions/effects/tokens.mjs +152 -0
  172. package/dist/ui/webUi-featureOptions/rendering.mjs +431 -0
  173. package/dist/ui/webUi-featureOptions/selectors.mjs +360 -0
  174. package/dist/ui/webUi-featureOptions/state.mjs +319 -0
  175. package/dist/ui/webUi-featureOptions/store.mjs +181 -0
  176. package/dist/ui/webUi-featureOptions/utils.mjs +200 -0
  177. package/dist/ui/webUi-featureOptions/views/connectionError.mjs +152 -0
  178. package/dist/ui/webUi-featureOptions/views/deviceInfo.mjs +80 -0
  179. package/dist/ui/webUi-featureOptions/views/header.mjs +77 -0
  180. package/dist/ui/webUi-featureOptions/views/nav.mjs +327 -0
  181. package/dist/ui/webUi-featureOptions/views/options.mjs +521 -0
  182. package/dist/ui/webUi-featureOptions/views/search.mjs +395 -0
  183. package/dist/ui/webUi-featureOptions.mjs +677 -0
  184. package/dist/ui/webUi.mjs +192 -87
  185. package/dist/util.d.ts +602 -45
  186. package/dist/util.js +783 -78
  187. package/dist/util.js.map +1 -1
  188. package/package.json +33 -15
  189. package/build/eslint-rules.mjs +0 -511
  190. package/dist/featureoptions.d.ts +0 -264
  191. package/dist/featureoptions.js +0 -480
  192. package/dist/featureoptions.js.map +0 -1
  193. package/dist/mqttclient.d.ts +0 -178
  194. package/dist/mqttclient.js +0 -310
  195. package/dist/mqttclient.js.map +0 -1
  196. package/dist/ui/featureoptions.js +0 -480
  197. package/dist/ui/featureoptions.js.map +0 -1
  198. package/dist/ui/webUi-featureoptions.mjs +0 -3765
@@ -0,0 +1,39 @@
1
+ /**
2
+ * The injectable wall-clock contract: the platform time primitives time-dependent code reads. A consumer holds a `Clock` rather than calling `Date.now()` /
3
+ * `node:timers/promises` `setTimeout` directly, so a test can substitute a controllable double (`TestClock`) and drive time deterministically while production behavior
4
+ * stays unchanged through {@link systemClock}.
5
+ *
6
+ * @see systemClock
7
+ *
8
+ * @category Utilities
9
+ */
10
+ export interface Clock {
11
+ /**
12
+ * Resolve after `ms` milliseconds, or reject if `init.signal` aborts first. The production {@link systemClock} implements this as `node:timers/promises` `setTimeout`,
13
+ * so an abort rejects with that primitive's `AbortError` (`name` `"AbortError"`, `code` `"ABORT_ERR"`) rather than the signal's reason.
14
+ *
15
+ * @param ms - The delay, in milliseconds.
16
+ * @param init - Optional init options. `signal` cancels the delay - resolving the wait early with a rejection - when it aborts.
17
+ *
18
+ * @returns A promise that resolves after the delay, or rejects with an `AbortError` if the signal aborts first.
19
+ */
20
+ delay(ms: number, init?: {
21
+ signal?: AbortSignal;
22
+ }): Promise<void>;
23
+ /**
24
+ * Return the current time as epoch milliseconds. The production {@link systemClock} implements this as `Date.now()`.
25
+ *
26
+ * @returns The current time in epoch milliseconds.
27
+ */
28
+ now(): number;
29
+ }
30
+ /**
31
+ * The behavior-neutral production {@link Clock}: `now()` IS `Date.now()` and `delay()` IS `node:timers/promises` `setTimeout`. A consumer that routes its time reads
32
+ * through this clock instead of calling those primitives directly cannot observe any behavior change - it is the same two calls, one indirection removed at test time.
33
+ *
34
+ * @see Clock
35
+ *
36
+ * @category Utilities
37
+ */
38
+ export declare const systemClock: Clock;
39
+ //# sourceMappingURL=clock.d.ts.map
package/dist/clock.js ADDED
@@ -0,0 +1,34 @@
1
+ /* Copyright(C) 2017-2026, HJD (https://github.com/hjdhjd). All rights reserved.
2
+ *
3
+ * clock.ts: An injectable wall-clock seam - the current time and an abortable delay - so time-dependent code can be driven deterministically under test.
4
+ */
5
+ /**
6
+ * An injectable wall-clock time seam.
7
+ *
8
+ * Time-dependent code reads the platform time primitives it needs: the current epoch time (`Date.now()`) and a delay that can be cancelled (`node:timers/promises`
9
+ * `setTimeout`). Calling those directly bakes real wall-clock time into the code, so a test cannot exercise a pacing or timeout path without multi-second real waits, and
10
+ * `node:test`'s mock timers do not patch the `node:timers/promises` primitives. Holding a {@link Clock} instead - the abstraction over those primitives - inverts the
11
+ * dependency: production wires {@link systemClock}, whose `now()` IS `Date.now()` and whose `delay()` IS `node:timers/promises` `setTimeout`, so routing through the seam
12
+ * is behavior-neutral; a test wires a `TestClock` (see `clock-double.ts`) that advances virtual time explicitly, so the consumer's time-dependent path runs
13
+ * deterministically and instantly.
14
+ *
15
+ * This module imports `node:timers/promises` and is therefore Node-only (not browser-safe), like `util.ts`. A browser-targeted consumer cannot resolve that import.
16
+ *
17
+ * @module
18
+ */
19
+ import { setTimeout as delay } from "node:timers/promises";
20
+ /**
21
+ * The behavior-neutral production {@link Clock}: `now()` IS `Date.now()` and `delay()` IS `node:timers/promises` `setTimeout`. A consumer that routes its time reads
22
+ * through this clock instead of calling those primitives directly cannot observe any behavior change - it is the same two calls, one indirection removed at test time.
23
+ *
24
+ * @see Clock
25
+ *
26
+ * @category Utilities
27
+ */
28
+ export const systemClock = {
29
+ // `setTimeout(ms, value, options)` from `node:timers/promises`: pass `undefined` for the resolution value and forward `init` as the options so the caller's signal
30
+ // cancels the wait. `setTimeout(ms, undefined, opts)` resolves to `Promise<undefined>`, which is assignable to the `Promise<void>` the contract declares.
31
+ delay: (ms, init) => delay(ms, undefined, init),
32
+ now: () => Date.now()
33
+ };
34
+ //# sourceMappingURL=clock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clock.js","sourceRoot":"","sources":["../src/clock.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,UAAU,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAgC3D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,WAAW,GAAU;IAEhC,mKAAmK;IACnK,0JAA0J;IAC1J,KAAK,EAAE,CAAC,EAAU,EAAE,IAA+B,EAAiB,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC;IACjG,GAAG,EAAE,GAAW,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;CAC9B,CAAC"}
@@ -0,0 +1,193 @@
1
+ export default config;
2
+ /**
3
+ * Build a ready-to-use ESLint flat config array. Consumers call this function and export default the result.
4
+ *
5
+ * Every option is optional and defaults to an empty array, mirrored by the destructuring defaults in the signature below. The JSDoc marks them optional with the
6
+ * bracket form so the emitted declaration types each property as optional, matching how consumers actually call this - passing only the subset they need.
7
+ *
8
+ * @param {object} [options] - Configuration options.
9
+ * @param {string[]} [options.ts] - Glob patterns for TypeScript files (strict + stylistic type-checked rules).
10
+ * @param {string[]} [options.js] - Glob patterns for JavaScript files (disable-type-checked rules).
11
+ * @param {string[]} [options.ui] - Glob patterns for browser UI files (adds browser globals).
12
+ * @param {string[]} [options.allowDefaultProject] - Globs passed to parserOptions.projectService.allowDefaultProject.
13
+ * @param {string[]} [options.ignores] - Global ignore patterns (in addition to the hardcoded "dist" ignore on the common block).
14
+ * @param {object[]} [options.extraConfigs] - Additional flat config objects appended to the output.
15
+ * @returns {object[]} A flat config array suitable for `export default` in eslint.config.mjs. Block ordering is significant - do not reorder.
16
+ */
17
+ export function config({ allowDefaultProject, extraConfigs, ignores, js, ts: tsFiles, ui }?: {
18
+ ts?: string[] | undefined;
19
+ js?: string[] | undefined;
20
+ ui?: string[] | undefined;
21
+ allowDefaultProject?: string[] | undefined;
22
+ ignores?: string[] | undefined;
23
+ extraConfigs?: any[] | undefined;
24
+ }): object[];
25
+ /**
26
+ * Rule preset applied to every linted file regardless of language. Disables the base ESLint rules that are redundant once TypeScript's own compiler
27
+ * and syntax already catch the same errors, mirroring the `typescript-eslint` compatibility overlay it spreads in; the enabled ESLint-recommended
28
+ * baseline itself comes from the separate `eslintJs.configs.recommended` block pushed in {@link config}. Layers on top of that the full `@hjdhjd/*`
29
+ * rule set, the `@stylistic/*` whitespace and formatting rules, and the project's opinionated `sort-imports` / `sort-keys` / `quotes` / `eqeqeq` /
30
+ * `curly` constraints.
31
+ *
32
+ * Spread into the `rules:` slot of the all-files block of a flat config.
33
+ */
34
+ export const commonRules: {
35
+ "@hjdhjd/blank-line-after-open-brace": string;
36
+ "@hjdhjd/comment-style": string;
37
+ "@hjdhjd/enforce-node-protocol": string;
38
+ "@hjdhjd/paren-comparisons-in-logical": string;
39
+ "@hjdhjd/split-type-imports": string;
40
+ "@stylistic/array-bracket-spacing": (string | {
41
+ arraysInArrays: boolean;
42
+ objectsInArrays: boolean;
43
+ singleValue: boolean;
44
+ })[];
45
+ "@stylistic/block-spacing": string;
46
+ "@stylistic/brace-style": (string | {
47
+ allowSingleLine: boolean;
48
+ })[];
49
+ "@stylistic/comma-dangle": string;
50
+ "@stylistic/eol-last": string[];
51
+ "@stylistic/generator-star-spacing": string;
52
+ "@stylistic/implicit-arrow-linebreak": string;
53
+ "@stylistic/indent": (string | number | {
54
+ SwitchCase: number;
55
+ })[];
56
+ "@stylistic/keyword-spacing": (string | {
57
+ overrides: {
58
+ for: {
59
+ after: boolean;
60
+ };
61
+ if: {
62
+ after: boolean;
63
+ };
64
+ switch: {
65
+ after: boolean;
66
+ };
67
+ while: {
68
+ after: boolean;
69
+ };
70
+ };
71
+ })[];
72
+ "@stylistic/linebreak-style": string[];
73
+ "@stylistic/lines-between-class-members": (string | {
74
+ exceptAfterSingleLine: boolean;
75
+ })[];
76
+ "@stylistic/max-len": (string | number)[];
77
+ "@stylistic/no-tabs": string;
78
+ "@stylistic/no-trailing-spaces": string;
79
+ "@stylistic/operator-linebreak": (string | {
80
+ overrides: {
81
+ ":": string;
82
+ "?": string;
83
+ };
84
+ })[];
85
+ "@stylistic/padding-line-between-statements": (string | {
86
+ blankLine: string;
87
+ next: string[];
88
+ prev: string;
89
+ } | {
90
+ blankLine: string;
91
+ next: string;
92
+ prev: string[];
93
+ } | {
94
+ blankLine: string;
95
+ next: string[];
96
+ prev: string[];
97
+ } | {
98
+ blankLine: string;
99
+ next: string;
100
+ prev: string;
101
+ })[];
102
+ "@stylistic/semi": string[];
103
+ "@stylistic/space-before-function-paren": (string | {
104
+ anonymous: string;
105
+ asyncArrow: string;
106
+ catch: string;
107
+ named: string;
108
+ })[];
109
+ "@stylistic/space-in-parens": string;
110
+ "@stylistic/space-infix-ops": string;
111
+ "@stylistic/space-unary-ops": string;
112
+ "@typescript-eslint/dot-notation": (string | {
113
+ allowIndexSignaturePropertyAccess: boolean;
114
+ })[];
115
+ "@typescript-eslint/no-this-alias": string;
116
+ camelcase: string;
117
+ curly: string[];
118
+ "dot-notation": string;
119
+ eqeqeq: string;
120
+ "logical-assignment-operators": (string | {
121
+ enforceForIfStatements: boolean;
122
+ })[];
123
+ "no-await-in-loop": string;
124
+ "no-console": string;
125
+ "no-restricted-syntax": string[];
126
+ "prefer-arrow-callback": string;
127
+ "prefer-const": string;
128
+ quotes: (string | {
129
+ allowTemplateLiterals: boolean;
130
+ avoidEscape: boolean;
131
+ })[];
132
+ "sort-imports": string;
133
+ "sort-keys": string;
134
+ "sort-vars": string;
135
+ };
136
+ /**
137
+ * Browser-environment globals typically present in Homebridge webUI files - `window`, `document`, `fetch`, the Homebridge configuration API entry
138
+ * point, and a few timer functions. Each is declared as `"readonly"` so `no-undef` accepts references without permitting reassignment.
139
+ *
140
+ * Pass into the `languageOptions.globals` slot of a flat config block scoped to UI files.
141
+ */
142
+ export const globalsUi: {
143
+ [k: string]: string;
144
+ };
145
+ /**
146
+ * Rule preset for JavaScript source files. Starts from `typescript-eslint`'s `disableTypeChecked` set (so type-aware rules don't fire on plain JS), then
147
+ * re-enables `no-unused-vars` with the underscore-prefix ignore pattern. The `require-await` rule is left disabled here for the same reason the TypeScript
148
+ * preset omits its pair - see the omission paragraph in the {@link tsRules} JSDoc.
149
+ *
150
+ * Spread into the `rules:` slot of a flat config block scoped to `.js` / `.mjs` files.
151
+ */
152
+ export const jsRules: {
153
+ "@typescript-eslint/no-floating-promises": string;
154
+ "no-unused-vars": (string | {
155
+ argsIgnorePattern: string;
156
+ caughtErrors: string;
157
+ caughtErrorsIgnorePattern: string;
158
+ varsIgnorePattern: string;
159
+ })[];
160
+ };
161
+ /**
162
+ * The ESLint plugin namespace map used by the composed configuration: `@hjdhjd` (this package's rules), `@stylistic` (the official stylistic-rules
163
+ * plugin), and `@typescript-eslint`. Drop this object into the `plugins` slot of a flat config block to register every plugin namespace this preset
164
+ * composes at once.
165
+ *
166
+ * The type annotation is deliberately loose since consumers that read the named `plugins` export do their own narrowing before touching rule entries.
167
+ * It's annotated explicitly so the emitted type stays portable - the raw inference picks up typescript-eslint's exported `CompatiblePlugin` shape,
168
+ * and the `tsconfig.eslint-plugin.json` declaration-only build (TS2742) refuses to serialize it into the `.d.ts` without citing a deep module path.
169
+ *
170
+ * @type {Record<string, { meta?: { name: string; version?: string }; rules?: Record<string, unknown> }>}
171
+ */
172
+ export const plugins: Record<string, {
173
+ meta?: {
174
+ name: string;
175
+ version?: string;
176
+ };
177
+ rules?: Record<string, unknown>;
178
+ }>;
179
+ /**
180
+ * Rule preset for TypeScript source files. Builds on `typescript-eslint`'s strict and stylistic type-checked configs, then layers project-specific
181
+ * overrides: type-aware lint rules (`await-thenable`, `no-floating-promises`, `prefer-nullish-coalescing`, etc.) at warn level, explicit return-type and
182
+ * module-boundary requirements, and `@stylistic/member-delimiter-style`. Disables the JavaScript-recommended versions of rules that have TypeScript-aware
183
+ * equivalents to avoid double-flagging.
184
+ *
185
+ * Deliberately omits `@typescript-eslint/promise-function-async` and forces `@typescript-eslint/require-await` (and the base `require-await`) off. The pair
186
+ * encodes a tight coupling between Promise return types and the `async` keyword that predates the Disposable protocol: `[Symbol.asyncDispose]()` must be declared
187
+ * `async ...(): Promise<void>` to satisfy `await using` even when the body is synchronous, and identity-preserving Promise pass-throughs (e.g., `markHandled` in
188
+ * `src/util.ts`) cannot be marked `async` without wrapping the return in a fresh chain and breaking reference equality. Encoding the stance at the preset level
189
+ * rather than scattering per-site `eslint-disable` directives is the SSOT.
190
+ *
191
+ * Spread into the `rules:` slot of a flat config block scoped to `.ts` files.
192
+ */
193
+ export const tsRules: any;
@@ -0,0 +1,2 @@
1
+ export { default as plugin } from "./plugin.mjs";
2
+ export { commonRules, config, globalsUi, jsRules, plugins, tsRules, default } from "./config.mjs";
@@ -0,0 +1,87 @@
1
+ export default plugin;
2
+ declare namespace plugin {
3
+ namespace meta {
4
+ let name: string;
5
+ let version: string;
6
+ }
7
+ let rules: {
8
+ "blank-line-after-open-brace": {
9
+ create(context: any): {
10
+ BlockStatement(node: any): void;
11
+ ClassBody(node: any): void;
12
+ ObjectExpression(node: any): void;
13
+ TSInterfaceBody(node: any): void;
14
+ TSTypeAliasDeclaration(node: any): void;
15
+ };
16
+ meta: {
17
+ docs: {
18
+ description: string;
19
+ recommended: boolean;
20
+ };
21
+ fixable: string;
22
+ schema: never[];
23
+ type: string;
24
+ };
25
+ };
26
+ "comment-style": {
27
+ create(context: any): {
28
+ Program(): void;
29
+ };
30
+ meta: {
31
+ docs: {
32
+ description: string;
33
+ recommended: boolean;
34
+ };
35
+ fixable: string;
36
+ schema: never[];
37
+ type: string;
38
+ };
39
+ };
40
+ "enforce-node-protocol": {
41
+ create(context: any): {
42
+ ExportAllDeclaration(node: any): void;
43
+ ExportNamedDeclaration(node: any): void;
44
+ ImportDeclaration(node: any): void;
45
+ ImportExpression(node: any): void;
46
+ };
47
+ meta: {
48
+ docs: {
49
+ description: string;
50
+ recommended: boolean;
51
+ };
52
+ fixable: string;
53
+ schema: never[];
54
+ type: string;
55
+ };
56
+ };
57
+ "paren-comparisons-in-logical": {
58
+ create(context: any): {
59
+ LogicalExpression(node: any): void;
60
+ };
61
+ meta: {
62
+ docs: {
63
+ description: string;
64
+ recommended: boolean;
65
+ };
66
+ fixable: string;
67
+ schema: never[];
68
+ type: string;
69
+ };
70
+ };
71
+ "split-type-imports": {
72
+ create(context: any): {
73
+ ExportNamedDeclaration(node: any): void;
74
+ ImportDeclaration(node: any): void;
75
+ };
76
+ meta: {
77
+ docs: {
78
+ description: string;
79
+ recommended: boolean;
80
+ };
81
+ fixable: string;
82
+ schema: never[];
83
+ type: string;
84
+ };
85
+ };
86
+ };
87
+ }
@@ -0,0 +1,19 @@
1
+ export default ruleBlankAfterOpenBrace;
2
+ declare namespace ruleBlankAfterOpenBrace {
3
+ function create(context: any): {
4
+ BlockStatement(node: any): void;
5
+ ClassBody(node: any): void;
6
+ ObjectExpression(node: any): void;
7
+ TSInterfaceBody(node: any): void;
8
+ TSTypeAliasDeclaration(node: any): void;
9
+ };
10
+ namespace meta {
11
+ namespace docs {
12
+ let description: string;
13
+ let recommended: boolean;
14
+ }
15
+ let fixable: string;
16
+ let schema: never[];
17
+ let type: string;
18
+ }
19
+ }
@@ -0,0 +1,15 @@
1
+ export default ruleCommentStyle;
2
+ declare namespace ruleCommentStyle {
3
+ function create(context: any): {
4
+ Program(): void;
5
+ };
6
+ namespace meta {
7
+ namespace docs {
8
+ let description: string;
9
+ let recommended: boolean;
10
+ }
11
+ let fixable: string;
12
+ let schema: never[];
13
+ let type: string;
14
+ }
15
+ }
@@ -0,0 +1,18 @@
1
+ export default ruleEnforceNodeProtocol;
2
+ declare namespace ruleEnforceNodeProtocol {
3
+ function create(context: any): {
4
+ ExportAllDeclaration(node: any): void;
5
+ ExportNamedDeclaration(node: any): void;
6
+ ImportDeclaration(node: any): void;
7
+ ImportExpression(node: any): void;
8
+ };
9
+ namespace meta {
10
+ namespace docs {
11
+ let description: string;
12
+ let recommended: boolean;
13
+ }
14
+ let fixable: string;
15
+ let schema: never[];
16
+ let type: string;
17
+ }
18
+ }
@@ -0,0 +1,15 @@
1
+ export default ruleParenComparisonsInLogical;
2
+ declare namespace ruleParenComparisonsInLogical {
3
+ function create(context: any): {
4
+ LogicalExpression(node: any): void;
5
+ };
6
+ namespace meta {
7
+ namespace docs {
8
+ let description: string;
9
+ let recommended: boolean;
10
+ }
11
+ let fixable: string;
12
+ let schema: never[];
13
+ let type: string;
14
+ }
15
+ }
@@ -0,0 +1,16 @@
1
+ export default ruleSplitTypeImports;
2
+ declare namespace ruleSplitTypeImports {
3
+ function create(context: any): {
4
+ ExportNamedDeclaration(node: any): void;
5
+ ImportDeclaration(node: any): void;
6
+ };
7
+ namespace meta {
8
+ namespace docs {
9
+ let description: string;
10
+ let recommended: boolean;
11
+ }
12
+ let fixable: string;
13
+ let schema: never[];
14
+ let type: string;
15
+ }
16
+ }
@@ -0,0 +1,96 @@
1
+ /**
2
+ * A shared documentation renderer for the {@link featureOptions!FeatureOptions | FeatureOptions} catalog.
3
+ *
4
+ * Every plugin in the family used to ship a near-duplicate `*-gendocs.ts` script that walked its feature-options catalog and printed a markdown category index plus
5
+ * per-category option tables, then pasted the result into its `docs/FeatureOptions.md` by hand. ~95% of each script was identical, and each hand-rolled the dotted-key
6
+ * construction and the value-vs-toggle discrimination that this library already owns as single-source-of-truth helpers. This module collapses all of that into one
7
+ * elegant renderer so the documentation becomes a pure projection of the live catalog.
8
+ *
9
+ * The module exports two pure string functions:
10
+ *
11
+ * - {@link renderFeatureOptionsReference} - the projection itself. It derives every key via {@link expandOption}, decides value-ness via {@link isValueOption}, and
12
+ * builds the catalog index once via {@link buildCatalogIndex}; it never re-derives any of those. Plugin-private scope prose is supplied through two optional render
13
+ * hooks that mirror the webUI's field-blind `validOption` / `validOptionCategory` predicate seam, lifted from *filter* (boolean) to *describe* (string). No
14
+ * plugin-specific field name appears anywhere in this file.
15
+ *
16
+ * - {@link spliceMarkedRegion} - the in-place splice that replaces the region between {@link FEATURE_OPTIONS_DOC_BEGIN} / {@link FEATURE_OPTIONS_DOC_END} in an
17
+ * existing doc with freshly rendered content, leaving each plugin's hand-written header and intro untouched.
18
+ *
19
+ * Both functions are pure and isomorphic: no `node:` imports, no `fs`, no `process`. The only I/O - reading the doc and writing it back - is two lines of
20
+ * `node:fs/promises` in each plugin's build-script shim, which is inherently a tooling concern. This module is therefore browser-safe and trivially testable, but it
21
+ * is a tooling concern and is deliberately NOT mirrored into `dist/ui/` by the build pipeline.
22
+ *
23
+ * @module
24
+ */
25
+ import type { FeatureCategoryEntry, FeatureOptionEntry } from "./featureOptions.ts";
26
+ /**
27
+ * The opening marker of the auto-generated region in a plugin's `docs/FeatureOptions.md`. {@link spliceMarkedRegion} replaces everything strictly between this marker
28
+ * and {@link FEATURE_OPTIONS_DOC_END}, preserving both markers and the hand-written prose around them. The text doubles as an in-document warning to maintainers not to
29
+ * edit the region by hand.
30
+ *
31
+ * @category Feature Options
32
+ */
33
+ export declare const FEATURE_OPTIONS_DOC_BEGIN = "<!-- FEATURE OPTIONS:BEGIN - Auto-generated by homebridge-plugin-utils. Do not edit this region by hand. -->";
34
+ /**
35
+ * The closing marker of the auto-generated region. See {@link FEATURE_OPTIONS_DOC_BEGIN}.
36
+ *
37
+ * @category Feature Options
38
+ */
39
+ export declare const FEATURE_OPTIONS_DOC_END = "<!-- FEATURE OPTIONS:END -->";
40
+ /**
41
+ * Render a feature-options catalog into the markdown reference fragment a plugin embeds in its `docs/FeatureOptions.md`. The output is a category index (one bullet per
42
+ * category, deep-linking to its detail section), an optional one-line legend explaining the `.<value>` notation, and then one detail section per category, each carrying
43
+ * an optional device-scope line and a flat table of option rows. The legend is emitted only when the catalog has at least one value option, since a toggle-only catalog
44
+ * never renders the `.<value>` placeholder the legend describes.
45
+ *
46
+ * The renderer owns all base-shaped scaffolding - the index, headings, per-row deep-link anchors, the key cell with its value/toggle placeholder, the default cell, the
47
+ * description cell, and the column math - purely from the base {@link FeatureOptionEntry} / {@link FeatureCategoryEntry} fields. The two optional hooks own *only* the
48
+ * plugin-private scope prose: `describeCategoryScope` contributes the device-scope sentence under a category heading, and `describeOptionScope` contributes a suffix
49
+ * appended to an option's description cell. A hook returning `undefined` omits its contribution cleanly - never an "undefined" literal, never a stray blank line.
50
+ *
51
+ * The catalog index is built once via {@link buildCatalogIndex}; value-ness is decided via {@link isValueOption}; the canonical dotted key is derived via
52
+ * {@link expandOption}. None of those is re-derived here - the renderer is a projection of the same single source of truth the rest of the module owns.
53
+ *
54
+ * @typeParam TOptionMeta - The concrete type of an option entry's opaque `meta` annotation, reconstituted at this boundary so `describeOptionScope` sees it typed.
55
+ * @typeParam TCategoryMeta - The concrete type of a category entry's opaque `meta` annotation, reconstituted so `describeCategoryScope` sees it typed.
56
+ * @param input
57
+ * @param input.categories - The catalog's category list, in the order the index and detail sections should follow.
58
+ * @param input.describeCategoryScope - Optional. Returns the device-scope sentence emitted under a category's heading, or `undefined` to omit it. The hook owns the full
59
+ * sentence including any leading or trailing text.
60
+ * @param input.describeOptionScope - Optional. Returns a suffix appended to an option's description cell, or `undefined` to omit it. The hook owns its full text
61
+ * including any leading separator.
62
+ * @param input.options - The catalog's options map keyed by category name.
63
+ *
64
+ * @returns The rendered markdown fragment.
65
+ */
66
+ export declare function renderFeatureOptionsReference<TOptionMeta = unknown, TCategoryMeta = unknown>(input: {
67
+ categories: readonly FeatureCategoryEntry<TCategoryMeta>[];
68
+ describeCategoryScope?: (category: FeatureCategoryEntry<TCategoryMeta>) => string | undefined;
69
+ describeOptionScope?: (option: FeatureOptionEntry<TOptionMeta>, category: FeatureCategoryEntry<TCategoryMeta>) => string | undefined;
70
+ options: Readonly<Record<string, readonly FeatureOptionEntry<TOptionMeta>[]>>;
71
+ }): string;
72
+ /**
73
+ * Replace the region strictly between {@link FEATURE_OPTIONS_DOC_BEGIN} and {@link FEATURE_OPTIONS_DOC_END} in `source` with `content`, leaving both markers and all
74
+ * surrounding prose untouched. This is the pure half of the in-place splice each plugin's build-script shim performs; the shim supplies the trivial `readFile` /
75
+ * `writeFile` around it.
76
+ *
77
+ * The replacement inserts a newline before and after `content`, so a marker pair on its own lines stays on its own lines and the rendered fragment is cleanly framed.
78
+ * The operation is idempotent: splicing the same `content` into an already-spliced document reproduces it byte-for-byte. Each marker may be overridden through the
79
+ * options object for documents that use a different convention, though the defaults match what every plugin in the family embeds.
80
+ *
81
+ * @param source - The full document text.
82
+ * @param content - The fragment to insert between the markers, typically the output of {@link renderFeatureOptionsReference}.
83
+ * @param markers
84
+ * @param markers.beginMarker - The opening marker to search for. Defaults to {@link FEATURE_OPTIONS_DOC_BEGIN}.
85
+ * @param markers.endMarker - The closing marker to search for. Defaults to {@link FEATURE_OPTIONS_DOC_END}.
86
+ *
87
+ * @returns `source` with the marked region's contents replaced by `content`.
88
+ *
89
+ * @throws `Error` naming the offending marker when either marker is absent, when the closing marker precedes the opening marker, or when the document is ambiguous - a
90
+ * second begin marker after the first, or a second end marker - since the marked region would not be uniquely identified.
91
+ */
92
+ export declare function spliceMarkedRegion(source: string, content: string, { beginMarker, endMarker }?: {
93
+ beginMarker?: string;
94
+ endMarker?: string;
95
+ }): string;
96
+ //# sourceMappingURL=featureOptions-docs.d.ts.map