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.
- package/README.md +130 -2
- package/build/eslint-plugin/README.md +164 -0
- package/build/eslint-plugin/config.mjs +308 -0
- package/build/eslint-plugin/index.mjs +7 -0
- package/build/eslint-plugin/plugin.mjs +46 -0
- package/build/eslint-plugin/rules/blank-line-after-open-brace.mjs +137 -0
- package/build/eslint-plugin/rules/blank-line-after-open-brace.test.mjs +112 -0
- package/build/eslint-plugin/rules/comment-style.mjs +190 -0
- package/build/eslint-plugin/rules/comment-style.test.mjs +190 -0
- package/build/eslint-plugin/rules/enforce-node-protocol.mjs +114 -0
- package/build/eslint-plugin/rules/enforce-node-protocol.test.mjs +116 -0
- package/build/eslint-plugin/rules/paren-comparisons-in-logical.mjs +94 -0
- package/build/eslint-plugin/rules/paren-comparisons-in-logical.test.mjs +107 -0
- package/build/eslint-plugin/rules/split-type-imports.mjs +354 -0
- package/build/eslint-plugin/rules/split-type-imports.test.mjs +268 -0
- package/build/eslint-plugin/test-setup.mjs +21 -0
- package/build/fs-ops.mjs +184 -0
- package/build/tsconfig.json +18 -3
- package/dist/backpressure.d.ts +94 -45
- package/dist/backpressure.js +229 -93
- package/dist/backpressure.js.map +1 -1
- package/dist/cli/index.d.ts +166 -0
- package/dist/cli/index.js +551 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/clock-double.d.ts +93 -0
- package/dist/clock-double.js +141 -0
- package/dist/clock-double.js.map +1 -0
- package/dist/clock.d.ts +39 -0
- package/dist/clock.js +34 -0
- package/dist/clock.js.map +1 -0
- 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/eslint-plugin/config.d.mts +193 -0
- package/dist/eslint-plugin/index.d.mts +2 -0
- package/dist/eslint-plugin/plugin.d.mts +87 -0
- package/dist/eslint-plugin/rules/blank-line-after-open-brace.d.mts +19 -0
- package/dist/eslint-plugin/rules/comment-style.d.mts +15 -0
- package/dist/eslint-plugin/rules/enforce-node-protocol.d.mts +18 -0
- package/dist/eslint-plugin/rules/paren-comparisons-in-logical.d.mts +15 -0
- package/dist/eslint-plugin/rules/split-type-imports.d.mts +16 -0
- package/dist/featureOptions-docs.d.ts +96 -0
- package/dist/featureOptions-docs.js +193 -0
- package/dist/featureOptions-docs.js.map +1 -0
- package/dist/featureOptions.d.ts +674 -0
- package/dist/featureOptions.js +870 -0
- package/dist/featureOptions.js.map +1 -0
- package/dist/ffmpeg/codecs.d.ts +256 -72
- package/dist/ffmpeg/codecs.js +477 -262
- package/dist/ffmpeg/codecs.js.map +1 -1
- package/dist/ffmpeg/dgram-util.d.ts +46 -0
- package/dist/ffmpeg/dgram-util.js +38 -0
- package/dist/ffmpeg/dgram-util.js.map +1 -0
- package/dist/ffmpeg/exec.d.ts +83 -64
- package/dist/ffmpeg/exec.js +77 -86
- package/dist/ffmpeg/exec.js.map +1 -1
- package/dist/ffmpeg/fmp4.d.ts +49 -2
- package/dist/ffmpeg/fmp4.js +47 -11
- package/dist/ffmpeg/fmp4.js.map +1 -1
- package/dist/ffmpeg/hap-enums.d.ts +214 -0
- package/dist/ffmpeg/hap-enums.js +92 -0
- package/dist/ffmpeg/hap-enums.js.map +1 -0
- package/dist/ffmpeg/index.d.ts +16 -9
- package/dist/ffmpeg/index.js +6 -0
- package/dist/ffmpeg/index.js.map +1 -1
- package/dist/ffmpeg/mp4-assembler.d.ts +161 -0
- package/dist/ffmpeg/mp4-assembler.js +424 -0
- package/dist/ffmpeg/mp4-assembler.js.map +1 -0
- package/dist/ffmpeg/mp4-parser.d.ts +94 -0
- package/dist/ffmpeg/mp4-parser.js +130 -0
- package/dist/ffmpeg/mp4-parser.js.map +1 -0
- package/dist/ffmpeg/options.d.ts +62 -149
- package/dist/ffmpeg/options.js +608 -499
- package/dist/ffmpeg/options.js.map +1 -1
- package/dist/ffmpeg/process.d.ts +142 -96
- package/dist/ffmpeg/process.js +406 -278
- package/dist/ffmpeg/process.js.map +1 -1
- package/dist/ffmpeg/record.d.ts +325 -186
- package/dist/ffmpeg/record.js +418 -565
- package/dist/ffmpeg/record.js.map +1 -1
- package/dist/ffmpeg/recording-process-double.d.ts +157 -0
- package/dist/ffmpeg/recording-process-double.js +190 -0
- package/dist/ffmpeg/recording-process-double.js.map +1 -0
- package/dist/ffmpeg/rtp-parser.d.ts +70 -0
- package/dist/ffmpeg/rtp-parser.js +77 -0
- package/dist/ffmpeg/rtp-parser.js.map +1 -0
- package/dist/ffmpeg/rtp.d.ts +198 -141
- package/dist/ffmpeg/rtp.js +474 -251
- package/dist/ffmpeg/rtp.js.map +1 -1
- package/dist/ffmpeg/settings.d.ts +5 -2
- package/dist/ffmpeg/settings.js +20 -5
- package/dist/ffmpeg/settings.js.map +1 -1
- package/dist/ffmpeg/stream.d.ts +57 -107
- package/dist/ffmpeg/stream.js +121 -150
- package/dist/ffmpeg/stream.js.map +1 -1
- package/dist/formatters.d.ts +106 -0
- package/dist/formatters.js +174 -0
- package/dist/formatters.js.map +1 -0
- package/dist/homebridge-enums.d.ts +30 -0
- package/dist/homebridge-enums.js +17 -0
- package/dist/homebridge-enums.js.map +1 -0
- package/dist/index.d.ts +13 -6
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/logclient/auth.d.ts +114 -0
- package/dist/logclient/auth.js +199 -0
- package/dist/logclient/auth.js.map +1 -0
- package/dist/logclient/cli-run.d.ts +76 -0
- package/dist/logclient/cli-run.js +639 -0
- package/dist/logclient/cli-run.js.map +1 -0
- package/dist/logclient/cli.d.ts +3 -0
- package/dist/logclient/cli.js +97 -0
- package/dist/logclient/cli.js.map +1 -0
- package/dist/logclient/client.d.ts +145 -0
- package/dist/logclient/client.js +600 -0
- package/dist/logclient/client.js.map +1 -0
- package/dist/logclient/config.d.ts +173 -0
- package/dist/logclient/config.js +199 -0
- package/dist/logclient/config.js.map +1 -0
- package/dist/logclient/endpoints.d.ts +54 -0
- package/dist/logclient/endpoints.js +73 -0
- package/dist/logclient/endpoints.js.map +1 -0
- package/dist/logclient/filter.d.ts +45 -0
- package/dist/logclient/filter.js +51 -0
- package/dist/logclient/filter.js.map +1 -0
- package/dist/logclient/frame.d.ts +93 -0
- package/dist/logclient/frame.js +203 -0
- package/dist/logclient/frame.js.map +1 -0
- package/dist/logclient/index.d.ts +31 -0
- package/dist/logclient/index.js +12 -0
- package/dist/logclient/index.js.map +1 -0
- package/dist/logclient/parser.d.ts +211 -0
- package/dist/logclient/parser.js +393 -0
- package/dist/logclient/parser.js.map +1 -0
- package/dist/logclient/rest.d.ts +41 -0
- package/dist/logclient/rest.js +111 -0
- package/dist/logclient/rest.js.map +1 -0
- package/dist/logclient/settings.d.ts +15 -0
- package/dist/logclient/settings.js +64 -0
- package/dist/logclient/settings.js.map +1 -0
- package/dist/logclient/socket-double.d.ts +201 -0
- package/dist/logclient/socket-double.js +384 -0
- package/dist/logclient/socket-double.js.map +1 -0
- package/dist/logclient/socket.d.ts +257 -0
- package/dist/logclient/socket.js +620 -0
- package/dist/logclient/socket.js.map +1 -0
- package/dist/logclient/stitch.d.ts +83 -0
- package/dist/logclient/stitch.js +146 -0
- package/dist/logclient/stitch.js.map +1 -0
- package/dist/logclient/time-expression.d.ts +42 -0
- package/dist/logclient/time-expression.js +181 -0
- package/dist/logclient/time-expression.js.map +1 -0
- package/dist/logclient/time-window.d.ts +38 -0
- package/dist/logclient/time-window.js +53 -0
- package/dist/logclient/time-window.js.map +1 -0
- package/dist/logclient/types.d.ts +107 -0
- package/dist/logclient/types.js +6 -0
- package/dist/logclient/types.js.map +1 -0
- package/dist/mqttClient.d.ts +287 -0
- package/dist/mqttClient.js +433 -0
- package/dist/mqttClient.js.map +1 -0
- package/dist/service.d.ts +64 -15
- package/dist/service.js +93 -66
- package/dist/service.js.map +1 -1
- package/dist/ui/featureOptions.js +870 -0
- package/dist/ui/featureOptions.js.map +1 -0
- package/dist/ui/formatters.js +174 -0
- package/dist/ui/formatters.js.map +1 -0
- package/dist/ui/pluginConfigSession.mjs +141 -0
- package/dist/ui/webUi-featureOptions/categoryState.mjs +135 -0
- package/dist/ui/webUi-featureOptions/effects/keyboard.mjs +61 -0
- package/dist/ui/webUi-featureOptions/effects/persist.mjs +226 -0
- package/dist/ui/webUi-featureOptions/effects/theme.mjs +398 -0
- package/dist/ui/webUi-featureOptions/effects/tokens.mjs +152 -0
- package/dist/ui/webUi-featureOptions/rendering.mjs +431 -0
- package/dist/ui/webUi-featureOptions/selectors.mjs +360 -0
- package/dist/ui/webUi-featureOptions/state.mjs +319 -0
- package/dist/ui/webUi-featureOptions/store.mjs +181 -0
- package/dist/ui/webUi-featureOptions/utils.mjs +213 -0
- package/dist/ui/webUi-featureOptions/views/connectionError.mjs +152 -0
- package/dist/ui/webUi-featureOptions/views/deviceInfo.mjs +80 -0
- package/dist/ui/webUi-featureOptions/views/header.mjs +77 -0
- package/dist/ui/webUi-featureOptions/views/nav.mjs +341 -0
- package/dist/ui/webUi-featureOptions/views/options.mjs +521 -0
- package/dist/ui/webUi-featureOptions/views/search.mjs +395 -0
- package/dist/ui/webUi-featureOptions.mjs +702 -0
- package/dist/ui/webUi.mjs +225 -88
- package/dist/util.d.ts +679 -45
- package/dist/util.js +830 -77
- package/dist/util.js.map +1 -1
- package/package.json +33 -15
- package/build/eslint-rules.mjs +0 -511
- package/dist/featureoptions.d.ts +0 -264
- package/dist/featureoptions.js +0 -480
- package/dist/featureoptions.js.map +0 -1
- package/dist/mqttclient.d.ts +0 -178
- package/dist/mqttclient.js +0 -310
- package/dist/mqttclient.js.map +0 -1
- package/dist/ui/featureoptions.js +0 -480
- package/dist/ui/featureoptions.js.map +0 -1
- package/dist/ui/webUi-featureoptions.mjs +0 -3765
|
@@ -1,480 +0,0 @@
|
|
|
1
|
-
/* Copyright(C) 2017-2026, HJD (https://github.com/hjdhjd). All rights reserved.
|
|
2
|
-
*
|
|
3
|
-
* featureoptions.ts: Hierarchical feature option capabilities for use in plugins and applications.
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* FeatureOptions provides a hierarchical feature option system for plugins and applications.
|
|
7
|
-
*
|
|
8
|
-
* Supports global, controller, and device-level configuration, value-centric feature options, grouping, and category management.
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
*
|
|
12
|
-
* ```ts
|
|
13
|
-
* // Define categories and options.
|
|
14
|
-
* const categories = [
|
|
15
|
-
*
|
|
16
|
-
* { name: "motion", description: "Motion Options" },
|
|
17
|
-
* { name: "audio", description: "Audio Options" }
|
|
18
|
-
* ];
|
|
19
|
-
*
|
|
20
|
-
* const options = {
|
|
21
|
-
*
|
|
22
|
-
* motion: [
|
|
23
|
-
* { name: "detect", default: true, description: "Enable motion detection." }
|
|
24
|
-
* ],
|
|
25
|
-
*
|
|
26
|
-
* audio: [
|
|
27
|
-
* { name: "volume", default: false, defaultValue: 50, description: "Audio volume." }
|
|
28
|
-
* ]
|
|
29
|
-
* };
|
|
30
|
-
*
|
|
31
|
-
* // Instantiate FeatureOptions.
|
|
32
|
-
* const featureOpts = new FeatureOptions(categories, options, ["Enable.motion.detect"]);
|
|
33
|
-
*
|
|
34
|
-
* // Check if a feature is enabled.
|
|
35
|
-
* const motionEnabled = featureOpts.test("motion.detect");
|
|
36
|
-
*
|
|
37
|
-
* // Get a value-centric feature option.
|
|
38
|
-
* const volume = featureOpts.value("audio.volume");
|
|
39
|
-
* ```
|
|
40
|
-
*
|
|
41
|
-
* @see FeatureOptionEntry
|
|
42
|
-
* @see FeatureCategoryEntry
|
|
43
|
-
* @see OptionScope
|
|
44
|
-
*/
|
|
45
|
-
export class FeatureOptions {
|
|
46
|
-
/**
|
|
47
|
-
* Default return value for unknown options (defaults to false).
|
|
48
|
-
*/
|
|
49
|
-
defaultReturnValue;
|
|
50
|
-
_categories;
|
|
51
|
-
_configuredOptions;
|
|
52
|
-
_groups;
|
|
53
|
-
_options;
|
|
54
|
-
configLookup;
|
|
55
|
-
defaults;
|
|
56
|
-
valueOptions;
|
|
57
|
-
/**
|
|
58
|
-
* Create a new FeatureOptions instance.
|
|
59
|
-
*
|
|
60
|
-
* @param categories - Array of feature option categories.
|
|
61
|
-
* @param options - Dictionary mapping category names to arrays of feature options.
|
|
62
|
-
* @param configuredOptions - Optional. Array of currently configured option strings.
|
|
63
|
-
*
|
|
64
|
-
* @example
|
|
65
|
-
*
|
|
66
|
-
* ```ts
|
|
67
|
-
* const featureOpts = new FeatureOptions(categories, options, ["Enable.motion.detect"]);
|
|
68
|
-
* ```
|
|
69
|
-
*/
|
|
70
|
-
constructor(categories, options, configuredOptions = []) {
|
|
71
|
-
// Initialize our defaults.
|
|
72
|
-
this._categories = [];
|
|
73
|
-
this._configuredOptions = [];
|
|
74
|
-
this._groups = {};
|
|
75
|
-
this._options = {};
|
|
76
|
-
this.configLookup = new Map();
|
|
77
|
-
this.defaultReturnValue = false;
|
|
78
|
-
this.defaults = {};
|
|
79
|
-
this.valueOptions = {};
|
|
80
|
-
this.categories = categories;
|
|
81
|
-
this.configuredOptions = configuredOptions;
|
|
82
|
-
this.options = options;
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Return a Bootstrap-specific color reference depending on the scope of a given feature option.
|
|
86
|
-
*
|
|
87
|
-
* @param option - Feature option to check.
|
|
88
|
-
* @param device - Optional device scope identifier.
|
|
89
|
-
* @param controller - Optional controller scope identifier.
|
|
90
|
-
*
|
|
91
|
-
* @returns Returns a Bootstrap color utility class associated with each scope level. `text-info` denotes an entry that's been modified at that scope level, while
|
|
92
|
-
* `text-success` and `text-warning` denote options that were defined at higher levels in the scope hierarchy - controller and global, respectively.
|
|
93
|
-
*/
|
|
94
|
-
color(option, device, controller) {
|
|
95
|
-
switch (this.scope(option, device, controller)) {
|
|
96
|
-
case "device":
|
|
97
|
-
return "text-info";
|
|
98
|
-
case "controller":
|
|
99
|
-
return "text-success";
|
|
100
|
-
case "global":
|
|
101
|
-
return device ? "text-warning" : "text-info";
|
|
102
|
-
default:
|
|
103
|
-
return "";
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Return the default value for an option.
|
|
108
|
-
*
|
|
109
|
-
* @param option - Feature option to check.
|
|
110
|
-
*
|
|
111
|
-
* @returns Returns true or false, depending on the option default.
|
|
112
|
-
*/
|
|
113
|
-
defaultValue(option) {
|
|
114
|
-
// If it's unknown to us, return the default return value.
|
|
115
|
-
return this.defaults[option.toLowerCase()] ?? this.defaultReturnValue;
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Return whether the option explicitly exists in the list of configured options.
|
|
119
|
-
*
|
|
120
|
-
* @param option - Feature option to check.
|
|
121
|
-
* @param id - Optional device or controller scope identifier to check.
|
|
122
|
-
*
|
|
123
|
-
* @returns Returns true if the option has been explicitly configured, false otherwise.
|
|
124
|
-
*/
|
|
125
|
-
exists(option, id) {
|
|
126
|
-
return this.configLookup.has(option.toLowerCase() + (id ? "." + id.toLowerCase() : ""));
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Return a fully formed feature option string.
|
|
130
|
-
*
|
|
131
|
-
* @param category - Feature option category entry or category name string.
|
|
132
|
-
* @param option - Feature option entry of option name string.
|
|
133
|
-
*
|
|
134
|
-
* @returns Returns a fully formed feature option in the form of `category.option`.
|
|
135
|
-
*/
|
|
136
|
-
expandOption(category, option) {
|
|
137
|
-
const categoryName = (typeof category === "string") ? category : category.name;
|
|
138
|
-
const optionName = (typeof option === "string") ? option : option.name;
|
|
139
|
-
if (!categoryName.length) {
|
|
140
|
-
return "";
|
|
141
|
-
}
|
|
142
|
-
return (!optionName.length) ? categoryName : categoryName + "." + optionName;
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Parse a floating point feature option value.
|
|
146
|
-
*
|
|
147
|
-
* @param option - Feature option to check.
|
|
148
|
-
* @param device - Optional device scope identifier.
|
|
149
|
-
* @param controller - Optional controller scope identifier.
|
|
150
|
-
*
|
|
151
|
-
* @returns Returns the value of a value-centric option as a floating point number, `undefined` if it doesn't exist or couldn't be parsed, and `null` if disabled.
|
|
152
|
-
*/
|
|
153
|
-
getFloat(option, device, controller) {
|
|
154
|
-
// Parse the number and return the value.
|
|
155
|
-
return this.parseOptionNumeric(this.value(option, device, controller), parseFloat);
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* Parse an integer feature option value.
|
|
159
|
-
*
|
|
160
|
-
* @param option - Feature option to check.
|
|
161
|
-
* @param device - Optional device scope identifier.
|
|
162
|
-
* @param controller - Optional controller scope identifier.
|
|
163
|
-
*
|
|
164
|
-
* @returns Returns the value of a value-centric option as an integer, `undefined` if it doesn't exist or couldn't be parsed, and `null` if disabled.
|
|
165
|
-
*/
|
|
166
|
-
getInteger(option, device, controller) {
|
|
167
|
-
// Parse the number and return the value.
|
|
168
|
-
return this.parseOptionNumeric(this.value(option, device, controller), parseInt);
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* Return whether an option has been set in either the device or controller scope context.
|
|
172
|
-
*
|
|
173
|
-
* @param option - Feature option to check.
|
|
174
|
-
*
|
|
175
|
-
* @returns Returns true if the option is set at the device or controller level and false otherwise.
|
|
176
|
-
*/
|
|
177
|
-
isScopeDevice(option, device) {
|
|
178
|
-
return this.exists(option, device);
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Return whether an option has been set in the global scope context.
|
|
182
|
-
*
|
|
183
|
-
* @param option - Feature option to check.
|
|
184
|
-
*
|
|
185
|
-
* @returns Returns true if the option is set globally and false otherwise.
|
|
186
|
-
*/
|
|
187
|
-
isScopeGlobal(option) {
|
|
188
|
-
return this.exists(option);
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* Return whether an option is value-centric or not.
|
|
192
|
-
*
|
|
193
|
-
* @param option - Feature option entry or string to check.
|
|
194
|
-
*
|
|
195
|
-
* @returns Returns true if it is a value-centric option and false otherwise.
|
|
196
|
-
*/
|
|
197
|
-
isValue(option) {
|
|
198
|
-
if (!option) {
|
|
199
|
-
return false;
|
|
200
|
-
}
|
|
201
|
-
return option.toLowerCase() in this.valueOptions;
|
|
202
|
-
}
|
|
203
|
-
/**
|
|
204
|
-
* Return the scope hierarchy location of an option.
|
|
205
|
-
*
|
|
206
|
-
* @param option - Feature option to check.
|
|
207
|
-
* @param device - Optional device scope identifier.
|
|
208
|
-
* @param controller - Optional controller scope identifier.
|
|
209
|
-
*
|
|
210
|
-
* @returns Returns an object containing the location in the scope hierarchy of an `option` as well as the current value associated with the option.
|
|
211
|
-
*/
|
|
212
|
-
scope(option, device, controller) {
|
|
213
|
-
return this.optionInfo(option, device, controller).scope;
|
|
214
|
-
}
|
|
215
|
-
/**
|
|
216
|
-
* Return the current state of a feature option, traversing the scope hierarchy.
|
|
217
|
-
*
|
|
218
|
-
* @param option - Feature option to check.
|
|
219
|
-
* @param device - Optional device scope identifier.
|
|
220
|
-
* @param controller - Optional controller scope identifier.
|
|
221
|
-
*
|
|
222
|
-
* @returns Returns true if the option is enabled, and false otherwise.
|
|
223
|
-
*/
|
|
224
|
-
test(option, device, controller) {
|
|
225
|
-
return this.optionInfo(option, device, controller).value;
|
|
226
|
-
}
|
|
227
|
-
/**
|
|
228
|
-
* Return the value associated with a value-centric feature option, traversing the scope hierarchy.
|
|
229
|
-
*
|
|
230
|
-
* @param option - Feature option to check.
|
|
231
|
-
* @param device - Optional device scope identifier.
|
|
232
|
-
* @param controller - Optional controller scope identifier.
|
|
233
|
-
*
|
|
234
|
-
* @returns Returns the current value associated with `option` if the feature option is enabled, `null` if disabled (or not a value-centric feature option), or
|
|
235
|
-
* `undefined` if it's not specified.
|
|
236
|
-
*/
|
|
237
|
-
value(option, device, controller) {
|
|
238
|
-
// If this isn't a value-centric feature option, we're done.
|
|
239
|
-
if (!this.isValue(option)) {
|
|
240
|
-
return null;
|
|
241
|
-
}
|
|
242
|
-
// Resolve the option through the scope hierarchy in a single traversal. This gives us the scope, enabled state, and raw value in one pass.
|
|
243
|
-
const resolved = this.resolveScope(option, device, controller);
|
|
244
|
-
// If the option has been explicitly disabled at any scope, or wasn't configured and its default is disabled, there's no value.
|
|
245
|
-
if (!resolved.enabled) {
|
|
246
|
-
return null;
|
|
247
|
-
}
|
|
248
|
-
// If we found an explicit value in the index, return it.
|
|
249
|
-
if (resolved.optionValue) {
|
|
250
|
-
return resolved.optionValue;
|
|
251
|
-
}
|
|
252
|
-
// The option is enabled but has no explicit value. If it wasn't configured at any scope (scope is "none"), fall back to the registered default value.
|
|
253
|
-
if (resolved.scope === "none") {
|
|
254
|
-
return this.valueOptions[option.toLowerCase()]?.toString() ?? null;
|
|
255
|
-
}
|
|
256
|
-
// The option is enabled at an explicit scope but no value was provided...return undefined to indicate "enabled, no value."
|
|
257
|
-
return undefined;
|
|
258
|
-
}
|
|
259
|
-
/**
|
|
260
|
-
* Return the list of available feature option categories.
|
|
261
|
-
*
|
|
262
|
-
* @returns Returns the current list of available feature option categories.
|
|
263
|
-
*/
|
|
264
|
-
get categories() {
|
|
265
|
-
return this._categories;
|
|
266
|
-
}
|
|
267
|
-
/**
|
|
268
|
-
* Set the list of available feature option categories.
|
|
269
|
-
*
|
|
270
|
-
* @param category - Array of available categories.
|
|
271
|
-
*/
|
|
272
|
-
set categories(category) {
|
|
273
|
-
this._categories = category;
|
|
274
|
-
// Regenerate defaults and the lookup index.
|
|
275
|
-
this.generateDefaults();
|
|
276
|
-
}
|
|
277
|
-
/**
|
|
278
|
-
* Return the list of currently configured feature options.
|
|
279
|
-
*
|
|
280
|
-
* @returns Returns the currently configured list of feature options.
|
|
281
|
-
*/
|
|
282
|
-
get configuredOptions() {
|
|
283
|
-
return this._configuredOptions;
|
|
284
|
-
}
|
|
285
|
-
/**
|
|
286
|
-
* Set the list of currently configured feature options.
|
|
287
|
-
*
|
|
288
|
-
* @param options - Array of configured feature options.
|
|
289
|
-
*/
|
|
290
|
-
set configuredOptions(options) {
|
|
291
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
292
|
-
this._configuredOptions = options ?? [];
|
|
293
|
-
// Regenerate defaults and the lookup index.
|
|
294
|
-
this.generateDefaults();
|
|
295
|
-
}
|
|
296
|
-
/**
|
|
297
|
-
* Return the list of available feature option groups.
|
|
298
|
-
*
|
|
299
|
-
* @returns Returns the current list of available feature option groups.
|
|
300
|
-
*/
|
|
301
|
-
get groups() {
|
|
302
|
-
return this._groups;
|
|
303
|
-
}
|
|
304
|
-
/**
|
|
305
|
-
* Return the list of available feature options.
|
|
306
|
-
*
|
|
307
|
-
* @returns Returns the current list of available feature options.
|
|
308
|
-
*/
|
|
309
|
-
get options() {
|
|
310
|
-
return this._options;
|
|
311
|
-
}
|
|
312
|
-
/**
|
|
313
|
-
* Set the list of available feature options.
|
|
314
|
-
*
|
|
315
|
-
* @param options - Array of available feature options.
|
|
316
|
-
*/
|
|
317
|
-
set options(options) {
|
|
318
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
319
|
-
this._options = options ?? {};
|
|
320
|
-
// Regenerate defaults and the lookup index.
|
|
321
|
-
this.generateDefaults();
|
|
322
|
-
}
|
|
323
|
-
// Rebuild the defaults, groups, value options, and lookup index from the current categories, options, and configured options. All three property setters call this so
|
|
324
|
-
// that state is always consistent regardless of which setter is called or in what order.
|
|
325
|
-
generateDefaults() {
|
|
326
|
-
this.defaults = {};
|
|
327
|
-
this._groups = {};
|
|
328
|
-
this.valueOptions = {};
|
|
329
|
-
for (const category of this.categories) {
|
|
330
|
-
// If the category doesn't exist, let's skip it.
|
|
331
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
332
|
-
if (!this.options[category.name]) {
|
|
333
|
-
continue;
|
|
334
|
-
}
|
|
335
|
-
// Now enumerate all the feature options for a given device and add then to the full list.
|
|
336
|
-
for (const option of this.options[category.name]) {
|
|
337
|
-
// Expand the entry.
|
|
338
|
-
const entry = this.expandOption(category, option);
|
|
339
|
-
// Index the default value.
|
|
340
|
-
this.defaults[entry.toLowerCase()] = option.default;
|
|
341
|
-
// Track value-centric options.
|
|
342
|
-
if ("defaultValue" in option) {
|
|
343
|
-
this.valueOptions[entry.toLowerCase()] = option.defaultValue;
|
|
344
|
-
}
|
|
345
|
-
// Cross reference the feature option group it belongs to, if any.
|
|
346
|
-
if (option.group !== undefined) {
|
|
347
|
-
const expandedGroup = category.name + (option.group.length ? ("." + option.group) : "");
|
|
348
|
-
// Initialize the group entry if needed and add the entry.
|
|
349
|
-
(this._groups[expandedGroup] ??= []).push(entry);
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
// Rebuild the lookup index now that we know which options are value-centric.
|
|
354
|
-
this.buildConfigIndex();
|
|
355
|
-
}
|
|
356
|
-
// Resolves a feature option through the scope hierarchy in a single traversal. Returns the scope where the option was found, whether it's enabled, and the raw string
|
|
357
|
-
// value for value-centric options. This is the core resolution method that both test()/scope() and value() build on, eliminating the need for separate traversals.
|
|
358
|
-
//
|
|
359
|
-
// There are a couple of ways to enable and disable options. The rules of the road are:
|
|
360
|
-
//
|
|
361
|
-
// 1. Explicitly disabling or enabling an option on the controller propagates to all the devices that are managed by that controller.
|
|
362
|
-
//
|
|
363
|
-
// 2. Explicitly disabling or enabling an option on a device always overrides the above. This means that it's possible to disable an option for a controller, and all
|
|
364
|
-
// the devices that are managed by it, and then override that behavior on a single device that it's managing.
|
|
365
|
-
resolveScope(option, device, controller) {
|
|
366
|
-
const normalizedOption = option.toLowerCase();
|
|
367
|
-
let entry;
|
|
368
|
-
// Check to see if we have a device-level option first.
|
|
369
|
-
if (device) {
|
|
370
|
-
entry = this.configLookup.get(normalizedOption + "." + device.toLowerCase());
|
|
371
|
-
if (entry) {
|
|
372
|
-
return { enabled: entry.enabled, optionValue: entry.value, scope: "device" };
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
// Now check to see if we have a controller-level option.
|
|
376
|
-
if (controller) {
|
|
377
|
-
entry = this.configLookup.get(normalizedOption + "." + controller.toLowerCase());
|
|
378
|
-
if (entry) {
|
|
379
|
-
return { enabled: entry.enabled, optionValue: entry.value, scope: "controller" };
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
// Finally, we check for a global-level value.
|
|
383
|
-
entry = this.configLookup.get(normalizedOption);
|
|
384
|
-
if (entry) {
|
|
385
|
-
return { enabled: entry.enabled, optionValue: entry.value, scope: "global" };
|
|
386
|
-
}
|
|
387
|
-
// The option hasn't been set at any scope, return our default value.
|
|
388
|
-
return { enabled: this.defaultValue(option), scope: "none" };
|
|
389
|
-
}
|
|
390
|
-
// Thin wrapper over resolveScope() that returns the OptionInfoEntry shape expected by test() and scope().
|
|
391
|
-
optionInfo(option, device, controller) {
|
|
392
|
-
const resolved = this.resolveScope(option, device, controller);
|
|
393
|
-
return { scope: resolved.scope, value: resolved.enabled };
|
|
394
|
-
}
|
|
395
|
-
// Utility function to parse and return a numeric configuration parameter.
|
|
396
|
-
parseOptionNumeric(option, convert) {
|
|
397
|
-
// If the option is disabled or we don't have it configured -- we're done.
|
|
398
|
-
if (!option) {
|
|
399
|
-
return (option === null) ? null : undefined;
|
|
400
|
-
}
|
|
401
|
-
// Convert it to a number, if needed.
|
|
402
|
-
const convertedValue = convert(option);
|
|
403
|
-
// Let's validate to make sure it's really a number.
|
|
404
|
-
if (isNaN(convertedValue)) {
|
|
405
|
-
return undefined;
|
|
406
|
-
}
|
|
407
|
-
// Return the value.
|
|
408
|
-
return convertedValue;
|
|
409
|
-
}
|
|
410
|
-
// Build a lookup index from the configured option strings. Each entry is keyed by its normalized lookup path (option name, or option name + scope id) and stores
|
|
411
|
-
// whether the option is enabled along with the extracted value for value-centric options. The index is built once when configured options or option definitions change,
|
|
412
|
-
// and all subsequent lookups are O(1).
|
|
413
|
-
buildConfigIndex() {
|
|
414
|
-
this.configLookup = new Map();
|
|
415
|
-
// Collect known value option names, sorted longest first for greedy prefix matching. This ensures that when option names overlap (e.g., a category "audio" and an
|
|
416
|
-
// option "audio.volume"), the more specific name matches first.
|
|
417
|
-
const valueOptionNames = Object.keys(this.valueOptions).sort((a, b) => b.length - a.length);
|
|
418
|
-
for (const rawEntry of this._configuredOptions) {
|
|
419
|
-
// Parse the action prefix (Enable or Disable).
|
|
420
|
-
const dotIndex = rawEntry.indexOf(".");
|
|
421
|
-
if (dotIndex === -1) {
|
|
422
|
-
continue;
|
|
423
|
-
}
|
|
424
|
-
const action = rawEntry.slice(0, dotIndex).toLowerCase();
|
|
425
|
-
if ((action !== "enable") && (action !== "disable")) {
|
|
426
|
-
continue;
|
|
427
|
-
}
|
|
428
|
-
const enabled = action === "enable";
|
|
429
|
-
const tailOriginal = rawEntry.slice(dotIndex + 1);
|
|
430
|
-
const tail = tailOriginal.toLowerCase();
|
|
431
|
-
// Register the exact tail as a lookup key. First-write-wins...if the same option appears multiple times, the earliest entry in the array takes precedence.
|
|
432
|
-
if (!this.configLookup.has(tail)) {
|
|
433
|
-
this.configLookup.set(tail, { enabled });
|
|
434
|
-
}
|
|
435
|
-
// For Enable entries on value-centric options, extract the trailing value segment and register under the base key (option or option.id) so that value lookups
|
|
436
|
-
// resolve in O(1) instead of requiring regex matching and array scanning.
|
|
437
|
-
if (!enabled) {
|
|
438
|
-
continue;
|
|
439
|
-
}
|
|
440
|
-
for (const optName of valueOptionNames) {
|
|
441
|
-
if (!tail.startsWith(optName)) {
|
|
442
|
-
continue;
|
|
443
|
-
}
|
|
444
|
-
const remainder = tail.slice(optName.length);
|
|
445
|
-
// Exact match on the option name with no trailing segments...there's no value to extract.
|
|
446
|
-
if (!remainder.length) {
|
|
447
|
-
break;
|
|
448
|
-
}
|
|
449
|
-
// The next character must be a dot separator. If not, this option name is merely a prefix of a longer unrelated token.
|
|
450
|
-
if (!remainder.startsWith(".")) {
|
|
451
|
-
continue;
|
|
452
|
-
}
|
|
453
|
-
const extra = remainder.slice(1);
|
|
454
|
-
const extraOriginal = tailOriginal.slice(optName.length + 1);
|
|
455
|
-
const separatorIndex = extra.indexOf(".");
|
|
456
|
-
if (separatorIndex === -1) {
|
|
457
|
-
// Single trailing segment after the option name. At global scope this is the value; at scoped scope it's the id. Register under the option name as the
|
|
458
|
-
// base key so that global value lookups find it.
|
|
459
|
-
if (!this.configLookup.has(optName)) {
|
|
460
|
-
this.configLookup.set(optName, { enabled: true, value: extraOriginal });
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
else {
|
|
464
|
-
// Two trailing segments: the first is the scope id and the second is the value.
|
|
465
|
-
const idLower = extra.slice(0, separatorIndex);
|
|
466
|
-
const valueOriginal = extraOriginal.slice(separatorIndex + 1);
|
|
467
|
-
// Only register if the value portion is a single segment (no additional dots).
|
|
468
|
-
if (!valueOriginal.includes(".")) {
|
|
469
|
-
const baseKey = optName + "." + idLower;
|
|
470
|
-
if (!this.configLookup.has(baseKey)) {
|
|
471
|
-
this.configLookup.set(baseKey, { enabled: true, value: valueOriginal });
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
break;
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
//# sourceMappingURL=featureoptions.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"featureoptions.js","sourceRoot":"","sources":["../src/featureoptions.ts"],"names":[],"mappings":"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"}
|