@optique/config 0.10.0-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/run.d.ts ADDED
@@ -0,0 +1,79 @@
1
+ import { ConfigContext } from "./index-DiDpcijz.js";
2
+ import { Parser } from "@optique/core/parser";
3
+
4
+ //#region src/run.d.ts
5
+
6
+ /**
7
+ * Options for runWithConfig.
8
+ *
9
+ * @template TValue The parser value type, inferred from the parser.
10
+ * @since 0.10.0
11
+ */
12
+ interface RunWithConfigOptions<TValue> {
13
+ /**
14
+ * Function to extract the config file path from parsed CLI arguments.
15
+ * This function receives the result of the first parse pass and should
16
+ * return the config file path or undefined if no config file is specified.
17
+ *
18
+ * The `parsed` parameter is typed based on the parser's result type,
19
+ * providing full type safety without manual type assertions.
20
+ */
21
+ readonly getConfigPath: (parsed: TValue) => string | undefined;
22
+ /**
23
+ * Command-line arguments to parse.
24
+ * If not provided, defaults to an empty array.
25
+ */
26
+ readonly args?: readonly string[];
27
+ }
28
+ /**
29
+ * Runs a parser with configuration file support using two-pass parsing.
30
+ *
31
+ * This function performs the following steps:
32
+ * 1. First pass: Parse arguments to extract the config file path
33
+ * 2. Load and validate: Read the config file and validate using Standard Schema
34
+ * 3. Second pass: Parse arguments again with config data as annotations
35
+ *
36
+ * The priority order for values is: CLI > config file > default.
37
+ *
38
+ * @template M The parser mode (sync or async).
39
+ * @template TValue The parser value type.
40
+ * @template TState The parser state type.
41
+ * @template T The config data type.
42
+ * @param parser The parser to execute.
43
+ * @param context The config context with schema and optional custom parser.
44
+ * @param options Run options including getConfigPath and args.
45
+ * @returns Promise that resolves to the parsed result.
46
+ * @throws Error if config file validation fails.
47
+ * @since 0.10.0
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * import { z } from "zod";
52
+ * import { runWithConfig } from "@optique/config/run";
53
+ * import { createConfigContext, bindConfig } from "@optique/config";
54
+ *
55
+ * const schema = z.object({
56
+ * host: z.string(),
57
+ * port: z.number(),
58
+ * });
59
+ *
60
+ * const context = createConfigContext({ schema });
61
+ *
62
+ * const parser = object({
63
+ * config: option("--config", string()),
64
+ * host: bindConfig(option("--host", string()), {
65
+ * context,
66
+ * key: "host",
67
+ * default: "localhost",
68
+ * }),
69
+ * });
70
+ *
71
+ * const result = await runWithConfig(parser, context, {
72
+ * getConfigPath: (parsed) => parsed.config,
73
+ * args: process.argv.slice(2),
74
+ * });
75
+ * ```
76
+ */
77
+ declare function runWithConfig<M extends "sync" | "async", TValue, TState, T>(parser: Parser<M, TValue, TState>, context: ConfigContext<T>, options: RunWithConfigOptions<TValue>): Promise<TValue>;
78
+ //#endregion
79
+ export { RunWithConfigOptions, runWithConfig };
package/dist/run.js ADDED
@@ -0,0 +1,114 @@
1
+ import { clearActiveConfig, configKey, setActiveConfig } from "./src-iXO5MxwN.js";
2
+ import { readFile } from "node:fs/promises";
3
+ import { parse } from "@optique/core/parser";
4
+
5
+ //#region src/run.ts
6
+ /**
7
+ * Runs a parser with configuration file support using two-pass parsing.
8
+ *
9
+ * This function performs the following steps:
10
+ * 1. First pass: Parse arguments to extract the config file path
11
+ * 2. Load and validate: Read the config file and validate using Standard Schema
12
+ * 3. Second pass: Parse arguments again with config data as annotations
13
+ *
14
+ * The priority order for values is: CLI > config file > default.
15
+ *
16
+ * @template M The parser mode (sync or async).
17
+ * @template TValue The parser value type.
18
+ * @template TState The parser state type.
19
+ * @template T The config data type.
20
+ * @param parser The parser to execute.
21
+ * @param context The config context with schema and optional custom parser.
22
+ * @param options Run options including getConfigPath and args.
23
+ * @returns Promise that resolves to the parsed result.
24
+ * @throws Error if config file validation fails.
25
+ * @since 0.10.0
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * import { z } from "zod";
30
+ * import { runWithConfig } from "@optique/config/run";
31
+ * import { createConfigContext, bindConfig } from "@optique/config";
32
+ *
33
+ * const schema = z.object({
34
+ * host: z.string(),
35
+ * port: z.number(),
36
+ * });
37
+ *
38
+ * const context = createConfigContext({ schema });
39
+ *
40
+ * const parser = object({
41
+ * config: option("--config", string()),
42
+ * host: bindConfig(option("--host", string()), {
43
+ * context,
44
+ * key: "host",
45
+ * default: "localhost",
46
+ * }),
47
+ * });
48
+ *
49
+ * const result = await runWithConfig(parser, context, {
50
+ * getConfigPath: (parsed) => parsed.config,
51
+ * args: process.argv.slice(2),
52
+ * });
53
+ * ```
54
+ */
55
+ async function runWithConfig(parser, context, options) {
56
+ const args = options.args ?? [];
57
+ const firstPass = parse(parser, args);
58
+ let firstPassResult;
59
+ if (firstPass instanceof Promise) firstPassResult = await firstPass;
60
+ else firstPassResult = firstPass;
61
+ if (!firstPassResult.success) {
62
+ const errorParts = firstPassResult.error.map((part) => {
63
+ if (part.type === "text") return part.text;
64
+ if (part.type === "optionName") return part.optionName;
65
+ if (part.type === "optionNames") return part.optionNames.join(", ");
66
+ if (part.type === "metavar") return part.metavar;
67
+ if (part.type === "value") return part.value;
68
+ if (part.type === "values") return part.values.join(", ");
69
+ if (part.type === "envVar") return part.envVar;
70
+ if (part.type === "commandLine") return part.commandLine;
71
+ if (part.type === "url") return part.url;
72
+ return "";
73
+ });
74
+ throw new Error(`Parsing failed: ${errorParts.join("")}`);
75
+ }
76
+ const configPath = options.getConfigPath(firstPassResult.value);
77
+ let configData;
78
+ if (configPath) try {
79
+ const contents = await readFile(configPath);
80
+ let rawData;
81
+ if (context.parser) rawData = context.parser(contents);
82
+ else {
83
+ const text = new TextDecoder().decode(contents);
84
+ rawData = JSON.parse(text);
85
+ }
86
+ const validation = context.schema["~standard"].validate(rawData);
87
+ let validationResult;
88
+ if (validation instanceof Promise) validationResult = await validation;
89
+ else validationResult = validation;
90
+ if (validationResult.issues) {
91
+ const firstIssue = validationResult.issues[0];
92
+ throw new Error(`Config validation failed: ${firstIssue?.message ?? "Unknown error"}`);
93
+ }
94
+ configData = validationResult.value;
95
+ } catch (error) {
96
+ if (error instanceof Error && error.message.includes("validation")) throw error;
97
+ configData = void 0;
98
+ }
99
+ const annotations = configData ? { [configKey]: configData } : {};
100
+ if (configData) setActiveConfig(context.id, configData);
101
+ try {
102
+ const secondPass = parse(parser, args, { annotations });
103
+ let secondPassResult;
104
+ if (secondPass instanceof Promise) secondPassResult = await secondPass;
105
+ else secondPassResult = secondPass;
106
+ if (!secondPassResult.success) throw new Error(`Parsing failed: ${String(secondPassResult.error)}`);
107
+ return secondPassResult.value;
108
+ } finally {
109
+ clearActiveConfig(context.id);
110
+ }
111
+ }
112
+
113
+ //#endregion
114
+ export { runWithConfig };
@@ -0,0 +1,295 @@
1
+ //#region rolldown:runtime
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+
23
+ //#endregion
24
+ const __optique_core_annotations = __toESM(require("@optique/core/annotations"));
25
+ const __optique_core_message = __toESM(require("@optique/core/message"));
26
+
27
+ //#region src/index.ts
28
+ /**
29
+ * Unique symbol for config data in annotations.
30
+ * @since 0.10.0
31
+ */
32
+ const configKey = Symbol.for("@optique/config");
33
+ /**
34
+ * Internal registry for active config data during runWithConfig execution.
35
+ * This is a workaround for the limitation that object() doesn't propagate
36
+ * annotations to child field parsers.
37
+ * @internal
38
+ */
39
+ const activeConfigRegistry = /* @__PURE__ */ new Map();
40
+ /**
41
+ * Sets active config data for a context.
42
+ * @internal
43
+ */
44
+ function setActiveConfig(contextId, data) {
45
+ activeConfigRegistry.set(contextId, data);
46
+ }
47
+ /**
48
+ * Gets active config data for a context.
49
+ * @internal
50
+ */
51
+ function getActiveConfig(contextId) {
52
+ return activeConfigRegistry.get(contextId);
53
+ }
54
+ /**
55
+ * Clears active config data for a context.
56
+ * @internal
57
+ */
58
+ function clearActiveConfig(contextId) {
59
+ activeConfigRegistry.delete(contextId);
60
+ }
61
+ /**
62
+ * Creates a config context for use with Optique parsers.
63
+ *
64
+ * The config context implements the SourceContext interface and can be used
65
+ * with runWith() or runWithConfig() to provide configuration file support.
66
+ *
67
+ * @template T The output type of the config schema.
68
+ * @param options Configuration options including schema and optional parser.
69
+ * @returns A config context that can be used with bindConfig() and runWithConfig().
70
+ * @since 0.10.0
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * import { z } from "zod";
75
+ * import { createConfigContext } from "@optique/config";
76
+ *
77
+ * const schema = z.object({
78
+ * host: z.string(),
79
+ * port: z.number(),
80
+ * });
81
+ *
82
+ * const configContext = createConfigContext({ schema });
83
+ * ```
84
+ */
85
+ function createConfigContext(options) {
86
+ return {
87
+ id: configKey,
88
+ schema: options.schema,
89
+ parser: options.parser,
90
+ getAnnotations(parsed) {
91
+ if (!parsed) return {};
92
+ return {};
93
+ }
94
+ };
95
+ }
96
+ /**
97
+ * Binds a parser to configuration values with fallback priority.
98
+ *
99
+ * The binding implements the following priority order:
100
+ * 1. CLI argument (if provided)
101
+ * 2. Config file value (if available)
102
+ * 3. Default value (if specified)
103
+ * 4. Error (if none of the above)
104
+ *
105
+ * @template M The parser mode (sync or async).
106
+ * @template TValue The parser value type.
107
+ * @template TState The parser state type.
108
+ * @template T The config data type.
109
+ * @param parser The parser to bind to config values.
110
+ * @param options Binding options including context, key, and default.
111
+ * @returns A new parser with config fallback behavior.
112
+ * @since 0.10.0
113
+ *
114
+ * @example
115
+ * ```typescript
116
+ * import { bindConfig } from "@optique/config";
117
+ * import { option } from "@optique/core/primitives";
118
+ * import { string } from "@optique/core/valueparser";
119
+ *
120
+ * const hostParser = bindConfig(option("--host", string()), {
121
+ * context: configContext,
122
+ * key: "host",
123
+ * default: "localhost",
124
+ * });
125
+ * ```
126
+ */
127
+ function bindConfig(parser, options) {
128
+ return {
129
+ $mode: parser.$mode,
130
+ $valueType: parser.$valueType,
131
+ $stateType: parser.$stateType,
132
+ priority: parser.priority,
133
+ usage: parser.usage,
134
+ initialState: parser.initialState,
135
+ parse: (context) => {
136
+ const annotations = (0, __optique_core_annotations.getAnnotations)(context.state);
137
+ const result = parser.parse(context);
138
+ if (!(result instanceof Promise)) {
139
+ if (result.success) {
140
+ const newState$1 = {
141
+ hasCliValue: true,
142
+ cliState: result.next.state,
143
+ ...annotations && { [__optique_core_annotations.annotationKey]: annotations }
144
+ };
145
+ return {
146
+ success: true,
147
+ next: {
148
+ ...result.next,
149
+ state: newState$1
150
+ },
151
+ consumed: result.consumed
152
+ };
153
+ }
154
+ const newState = {
155
+ hasCliValue: false,
156
+ ...annotations && { [__optique_core_annotations.annotationKey]: annotations }
157
+ };
158
+ return {
159
+ success: true,
160
+ next: {
161
+ ...context,
162
+ state: newState
163
+ },
164
+ consumed: []
165
+ };
166
+ }
167
+ return result.then((res) => {
168
+ if (res.success) {
169
+ const newState$1 = {
170
+ hasCliValue: true,
171
+ cliState: res.next.state,
172
+ ...annotations && { [__optique_core_annotations.annotationKey]: annotations }
173
+ };
174
+ return {
175
+ success: true,
176
+ next: {
177
+ ...res.next,
178
+ state: newState$1
179
+ },
180
+ consumed: res.consumed
181
+ };
182
+ }
183
+ const newState = {
184
+ hasCliValue: false,
185
+ ...annotations && { [__optique_core_annotations.annotationKey]: annotations }
186
+ };
187
+ return {
188
+ success: true,
189
+ next: {
190
+ ...context,
191
+ state: newState
192
+ },
193
+ consumed: []
194
+ };
195
+ });
196
+ },
197
+ complete: (state) => {
198
+ const bindState = state;
199
+ if (bindState.hasCliValue && bindState.cliState !== void 0) {
200
+ const innerResult = parser.complete(bindState.cliState);
201
+ if (innerResult instanceof Promise) return innerResult.then((res) => {
202
+ if (res.success) return {
203
+ success: true,
204
+ value: res.value
205
+ };
206
+ return getConfigOrDefault(state, options);
207
+ });
208
+ if (innerResult.success) return {
209
+ success: true,
210
+ value: innerResult.value
211
+ };
212
+ return getConfigOrDefault(state, options);
213
+ }
214
+ return getConfigOrDefault(state, options);
215
+ },
216
+ suggest: parser.suggest,
217
+ getDocFragments: parser.getDocFragments
218
+ };
219
+ }
220
+ /**
221
+ * Helper function to get value from config or default.
222
+ * Checks both annotations (for top-level parsers) and the active config
223
+ * registry (for parsers nested inside object() when used with runWithConfig).
224
+ */
225
+ function getConfigOrDefault(state, options) {
226
+ const annotations = (0, __optique_core_annotations.getAnnotations)(state);
227
+ let configData = annotations?.[configKey];
228
+ if (configData === void 0 || configData === null) {
229
+ const contextId = options.context.id;
230
+ configData = getActiveConfig(contextId);
231
+ }
232
+ let configValue;
233
+ if (configData !== void 0 && configData !== null) if (typeof options.key === "function") try {
234
+ configValue = options.key(configData);
235
+ } catch {
236
+ configValue = void 0;
237
+ }
238
+ else configValue = configData[options.key];
239
+ if (configValue !== void 0) return {
240
+ success: true,
241
+ value: configValue
242
+ };
243
+ if (options.default !== void 0) return {
244
+ success: true,
245
+ value: options.default
246
+ };
247
+ return {
248
+ success: false,
249
+ error: __optique_core_message.message`Missing required configuration value.`
250
+ };
251
+ }
252
+
253
+ //#endregion
254
+ Object.defineProperty(exports, '__toESM', {
255
+ enumerable: true,
256
+ get: function () {
257
+ return __toESM;
258
+ }
259
+ });
260
+ Object.defineProperty(exports, 'bindConfig', {
261
+ enumerable: true,
262
+ get: function () {
263
+ return bindConfig;
264
+ }
265
+ });
266
+ Object.defineProperty(exports, 'clearActiveConfig', {
267
+ enumerable: true,
268
+ get: function () {
269
+ return clearActiveConfig;
270
+ }
271
+ });
272
+ Object.defineProperty(exports, 'configKey', {
273
+ enumerable: true,
274
+ get: function () {
275
+ return configKey;
276
+ }
277
+ });
278
+ Object.defineProperty(exports, 'createConfigContext', {
279
+ enumerable: true,
280
+ get: function () {
281
+ return createConfigContext;
282
+ }
283
+ });
284
+ Object.defineProperty(exports, 'getActiveConfig', {
285
+ enumerable: true,
286
+ get: function () {
287
+ return getActiveConfig;
288
+ }
289
+ });
290
+ Object.defineProperty(exports, 'setActiveConfig', {
291
+ enumerable: true,
292
+ get: function () {
293
+ return setActiveConfig;
294
+ }
295
+ });
@@ -0,0 +1,231 @@
1
+ import { annotationKey, getAnnotations } from "@optique/core/annotations";
2
+ import { message } from "@optique/core/message";
3
+
4
+ //#region src/index.ts
5
+ /**
6
+ * Unique symbol for config data in annotations.
7
+ * @since 0.10.0
8
+ */
9
+ const configKey = Symbol.for("@optique/config");
10
+ /**
11
+ * Internal registry for active config data during runWithConfig execution.
12
+ * This is a workaround for the limitation that object() doesn't propagate
13
+ * annotations to child field parsers.
14
+ * @internal
15
+ */
16
+ const activeConfigRegistry = /* @__PURE__ */ new Map();
17
+ /**
18
+ * Sets active config data for a context.
19
+ * @internal
20
+ */
21
+ function setActiveConfig(contextId, data) {
22
+ activeConfigRegistry.set(contextId, data);
23
+ }
24
+ /**
25
+ * Gets active config data for a context.
26
+ * @internal
27
+ */
28
+ function getActiveConfig(contextId) {
29
+ return activeConfigRegistry.get(contextId);
30
+ }
31
+ /**
32
+ * Clears active config data for a context.
33
+ * @internal
34
+ */
35
+ function clearActiveConfig(contextId) {
36
+ activeConfigRegistry.delete(contextId);
37
+ }
38
+ /**
39
+ * Creates a config context for use with Optique parsers.
40
+ *
41
+ * The config context implements the SourceContext interface and can be used
42
+ * with runWith() or runWithConfig() to provide configuration file support.
43
+ *
44
+ * @template T The output type of the config schema.
45
+ * @param options Configuration options including schema and optional parser.
46
+ * @returns A config context that can be used with bindConfig() and runWithConfig().
47
+ * @since 0.10.0
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * import { z } from "zod";
52
+ * import { createConfigContext } from "@optique/config";
53
+ *
54
+ * const schema = z.object({
55
+ * host: z.string(),
56
+ * port: z.number(),
57
+ * });
58
+ *
59
+ * const configContext = createConfigContext({ schema });
60
+ * ```
61
+ */
62
+ function createConfigContext(options) {
63
+ return {
64
+ id: configKey,
65
+ schema: options.schema,
66
+ parser: options.parser,
67
+ getAnnotations(parsed) {
68
+ if (!parsed) return {};
69
+ return {};
70
+ }
71
+ };
72
+ }
73
+ /**
74
+ * Binds a parser to configuration values with fallback priority.
75
+ *
76
+ * The binding implements the following priority order:
77
+ * 1. CLI argument (if provided)
78
+ * 2. Config file value (if available)
79
+ * 3. Default value (if specified)
80
+ * 4. Error (if none of the above)
81
+ *
82
+ * @template M The parser mode (sync or async).
83
+ * @template TValue The parser value type.
84
+ * @template TState The parser state type.
85
+ * @template T The config data type.
86
+ * @param parser The parser to bind to config values.
87
+ * @param options Binding options including context, key, and default.
88
+ * @returns A new parser with config fallback behavior.
89
+ * @since 0.10.0
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * import { bindConfig } from "@optique/config";
94
+ * import { option } from "@optique/core/primitives";
95
+ * import { string } from "@optique/core/valueparser";
96
+ *
97
+ * const hostParser = bindConfig(option("--host", string()), {
98
+ * context: configContext,
99
+ * key: "host",
100
+ * default: "localhost",
101
+ * });
102
+ * ```
103
+ */
104
+ function bindConfig(parser, options) {
105
+ return {
106
+ $mode: parser.$mode,
107
+ $valueType: parser.$valueType,
108
+ $stateType: parser.$stateType,
109
+ priority: parser.priority,
110
+ usage: parser.usage,
111
+ initialState: parser.initialState,
112
+ parse: (context) => {
113
+ const annotations = getAnnotations(context.state);
114
+ const result = parser.parse(context);
115
+ if (!(result instanceof Promise)) {
116
+ if (result.success) {
117
+ const newState$1 = {
118
+ hasCliValue: true,
119
+ cliState: result.next.state,
120
+ ...annotations && { [annotationKey]: annotations }
121
+ };
122
+ return {
123
+ success: true,
124
+ next: {
125
+ ...result.next,
126
+ state: newState$1
127
+ },
128
+ consumed: result.consumed
129
+ };
130
+ }
131
+ const newState = {
132
+ hasCliValue: false,
133
+ ...annotations && { [annotationKey]: annotations }
134
+ };
135
+ return {
136
+ success: true,
137
+ next: {
138
+ ...context,
139
+ state: newState
140
+ },
141
+ consumed: []
142
+ };
143
+ }
144
+ return result.then((res) => {
145
+ if (res.success) {
146
+ const newState$1 = {
147
+ hasCliValue: true,
148
+ cliState: res.next.state,
149
+ ...annotations && { [annotationKey]: annotations }
150
+ };
151
+ return {
152
+ success: true,
153
+ next: {
154
+ ...res.next,
155
+ state: newState$1
156
+ },
157
+ consumed: res.consumed
158
+ };
159
+ }
160
+ const newState = {
161
+ hasCliValue: false,
162
+ ...annotations && { [annotationKey]: annotations }
163
+ };
164
+ return {
165
+ success: true,
166
+ next: {
167
+ ...context,
168
+ state: newState
169
+ },
170
+ consumed: []
171
+ };
172
+ });
173
+ },
174
+ complete: (state) => {
175
+ const bindState = state;
176
+ if (bindState.hasCliValue && bindState.cliState !== void 0) {
177
+ const innerResult = parser.complete(bindState.cliState);
178
+ if (innerResult instanceof Promise) return innerResult.then((res) => {
179
+ if (res.success) return {
180
+ success: true,
181
+ value: res.value
182
+ };
183
+ return getConfigOrDefault(state, options);
184
+ });
185
+ if (innerResult.success) return {
186
+ success: true,
187
+ value: innerResult.value
188
+ };
189
+ return getConfigOrDefault(state, options);
190
+ }
191
+ return getConfigOrDefault(state, options);
192
+ },
193
+ suggest: parser.suggest,
194
+ getDocFragments: parser.getDocFragments
195
+ };
196
+ }
197
+ /**
198
+ * Helper function to get value from config or default.
199
+ * Checks both annotations (for top-level parsers) and the active config
200
+ * registry (for parsers nested inside object() when used with runWithConfig).
201
+ */
202
+ function getConfigOrDefault(state, options) {
203
+ const annotations = getAnnotations(state);
204
+ let configData = annotations?.[configKey];
205
+ if (configData === void 0 || configData === null) {
206
+ const contextId = options.context.id;
207
+ configData = getActiveConfig(contextId);
208
+ }
209
+ let configValue;
210
+ if (configData !== void 0 && configData !== null) if (typeof options.key === "function") try {
211
+ configValue = options.key(configData);
212
+ } catch {
213
+ configValue = void 0;
214
+ }
215
+ else configValue = configData[options.key];
216
+ if (configValue !== void 0) return {
217
+ success: true,
218
+ value: configValue
219
+ };
220
+ if (options.default !== void 0) return {
221
+ success: true,
222
+ value: options.default
223
+ };
224
+ return {
225
+ success: false,
226
+ error: message`Missing required configuration value.`
227
+ };
228
+ }
229
+
230
+ //#endregion
231
+ export { bindConfig, clearActiveConfig, configKey, createConfigContext, getActiveConfig, setActiveConfig };