@optique/config 1.0.0-dev.428 → 1.0.0-dev.431

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.
@@ -1,237 +0,0 @@
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
- const contextId = Symbol.for(`@optique/config:${Math.random()}`);
64
- return {
65
- id: contextId,
66
- schema: options.schema,
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: options.default !== void 0 ? [{
111
- type: "optional",
112
- terms: parser.usage
113
- }] : parser.usage,
114
- initialState: parser.initialState,
115
- parse: (context) => {
116
- const annotations = getAnnotations(context.state);
117
- const result = parser.parse(context);
118
- if (!(result instanceof Promise)) {
119
- if (result.success) {
120
- const newState$1 = {
121
- hasCliValue: true,
122
- cliState: result.next.state,
123
- ...annotations && { [annotationKey]: annotations }
124
- };
125
- return {
126
- success: true,
127
- next: {
128
- ...result.next,
129
- state: newState$1
130
- },
131
- consumed: result.consumed
132
- };
133
- }
134
- const newState = {
135
- hasCliValue: false,
136
- ...annotations && { [annotationKey]: annotations }
137
- };
138
- return {
139
- success: true,
140
- next: {
141
- ...context,
142
- state: newState
143
- },
144
- consumed: []
145
- };
146
- }
147
- return result.then((res) => {
148
- if (res.success) {
149
- const newState$1 = {
150
- hasCliValue: true,
151
- cliState: res.next.state,
152
- ...annotations && { [annotationKey]: annotations }
153
- };
154
- return {
155
- success: true,
156
- next: {
157
- ...res.next,
158
- state: newState$1
159
- },
160
- consumed: res.consumed
161
- };
162
- }
163
- const newState = {
164
- hasCliValue: false,
165
- ...annotations && { [annotationKey]: annotations }
166
- };
167
- return {
168
- success: true,
169
- next: {
170
- ...context,
171
- state: newState
172
- },
173
- consumed: []
174
- };
175
- });
176
- },
177
- complete: (state) => {
178
- const bindState = state;
179
- if (bindState?.hasCliValue && bindState.cliState !== void 0) {
180
- const innerResult = parser.complete(bindState.cliState);
181
- if (innerResult instanceof Promise) return innerResult.then((res) => {
182
- if (res.success) return {
183
- success: true,
184
- value: res.value
185
- };
186
- return res;
187
- });
188
- if (innerResult.success) return {
189
- success: true,
190
- value: innerResult.value
191
- };
192
- return innerResult;
193
- }
194
- return getConfigOrDefault(state, options);
195
- },
196
- suggest: parser.suggest,
197
- getDocFragments(state, upperDefaultValue) {
198
- const defaultValue = upperDefaultValue ?? options.default;
199
- return parser.getDocFragments(state, defaultValue);
200
- }
201
- };
202
- }
203
- /**
204
- * Helper function to get value from config or default.
205
- * Checks both annotations (for top-level parsers) and the active config
206
- * registry (for parsers nested inside object() when used with runWithConfig).
207
- */
208
- function getConfigOrDefault(state, options) {
209
- const annotations = getAnnotations(state);
210
- let configData = annotations?.[configKey];
211
- if (configData === void 0 || configData === null) {
212
- const contextId = options.context.id;
213
- configData = getActiveConfig(contextId);
214
- }
215
- let configValue;
216
- if (configData !== void 0 && configData !== null) if (typeof options.key === "function") try {
217
- configValue = options.key(configData);
218
- } catch {
219
- configValue = void 0;
220
- }
221
- else configValue = configData[options.key];
222
- if (configValue !== void 0) return {
223
- success: true,
224
- value: configValue
225
- };
226
- if (options.default !== void 0) return {
227
- success: true,
228
- value: options.default
229
- };
230
- return {
231
- success: false,
232
- error: message`Missing required configuration value.`
233
- };
234
- }
235
-
236
- //#endregion
237
- export { bindConfig, clearActiveConfig, configKey, createConfigContext, getActiveConfig, setActiveConfig };