@optique/core 0.10.7 → 1.0.0-dev.1109

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 (56) hide show
  1. package/README.md +4 -6
  2. package/dist/annotations.cjs +209 -1
  3. package/dist/annotations.d.cts +78 -1
  4. package/dist/annotations.d.ts +78 -1
  5. package/dist/annotations.js +201 -1
  6. package/dist/completion.cjs +186 -50
  7. package/dist/completion.js +186 -50
  8. package/dist/constructs.cjs +310 -78
  9. package/dist/constructs.d.cts +525 -644
  10. package/dist/constructs.d.ts +525 -644
  11. package/dist/constructs.js +311 -79
  12. package/dist/context.cjs +43 -3
  13. package/dist/context.d.cts +113 -5
  14. package/dist/context.d.ts +113 -5
  15. package/dist/context.js +41 -3
  16. package/dist/dependency.cjs +172 -66
  17. package/dist/dependency.d.cts +22 -2
  18. package/dist/dependency.d.ts +22 -2
  19. package/dist/dependency.js +172 -66
  20. package/dist/doc.cjs +46 -1
  21. package/dist/doc.d.cts +24 -0
  22. package/dist/doc.d.ts +24 -0
  23. package/dist/doc.js +46 -1
  24. package/dist/facade.cjs +702 -322
  25. package/dist/facade.d.cts +124 -190
  26. package/dist/facade.d.ts +124 -190
  27. package/dist/facade.js +703 -323
  28. package/dist/index.cjs +5 -0
  29. package/dist/index.d.cts +5 -5
  30. package/dist/index.d.ts +5 -5
  31. package/dist/index.js +3 -3
  32. package/dist/message.cjs +7 -4
  33. package/dist/message.js +7 -4
  34. package/dist/mode-dispatch.cjs +23 -1
  35. package/dist/mode-dispatch.d.cts +55 -0
  36. package/dist/mode-dispatch.d.ts +55 -0
  37. package/dist/mode-dispatch.js +21 -1
  38. package/dist/modifiers.cjs +210 -55
  39. package/dist/modifiers.js +211 -56
  40. package/dist/parser.cjs +80 -47
  41. package/dist/parser.d.cts +18 -3
  42. package/dist/parser.d.ts +18 -3
  43. package/dist/parser.js +82 -50
  44. package/dist/primitives.cjs +102 -37
  45. package/dist/primitives.d.cts +81 -24
  46. package/dist/primitives.d.ts +81 -24
  47. package/dist/primitives.js +103 -39
  48. package/dist/usage.cjs +88 -6
  49. package/dist/usage.d.cts +51 -13
  50. package/dist/usage.d.ts +51 -13
  51. package/dist/usage.js +85 -7
  52. package/dist/valueparser.cjs +371 -99
  53. package/dist/valueparser.d.cts +56 -7
  54. package/dist/valueparser.d.ts +56 -7
  55. package/dist/valueparser.js +371 -99
  56. package/package.json +10 -1
package/dist/context.cjs CHANGED
@@ -1,21 +1,61 @@
1
1
 
2
2
  //#region src/context.ts
3
3
  /**
4
+ * Brand symbol for placeholder values.
5
+ *
6
+ * Placeholder values are sentinel objects that represent values to be
7
+ * resolved later (e.g., deferred interactive prompts). During two-phase
8
+ * parsing, placeholder values are stripped from parsed results before they
9
+ * are passed to phase-2 context annotation collection, and `map()`
10
+ * transformations skip them.
11
+ *
12
+ * Packages that produce placeholder values should set this symbol as a
13
+ * property on their sentinel objects:
14
+ *
15
+ * ~~~~ typescript
16
+ * import { placeholder } from "@optique/core/context";
17
+ *
18
+ * class MyPlaceholder {
19
+ * readonly [placeholder] = true;
20
+ * }
21
+ * ~~~~
22
+ *
23
+ * @since 1.0.0
24
+ */
25
+ const placeholder = Symbol.for("@optique/core/placeholder");
26
+ /**
27
+ * Tests whether a value is a placeholder.
28
+ *
29
+ * Returns `true` if the value is a non-null object carrying the
30
+ * {@link placeholder} property.
31
+ *
32
+ * @param value The value to test.
33
+ * @returns `true` if the value is a placeholder.
34
+ * @since 1.0.0
35
+ */
36
+ function isPlaceholderValue(value) {
37
+ return value != null && typeof value === "object" && placeholder in value;
38
+ }
39
+ /**
4
40
  * Checks whether a context is static (returns annotations without needing
5
41
  * parsed results).
6
42
  *
7
- * A context is considered static if `getAnnotations()` called without
8
- * arguments returns a non-empty annotations object synchronously.
43
+ * A context is considered static if it declares `mode: "static"` or if
44
+ * `getAnnotations()` called without arguments returns a non-empty
45
+ * annotations object synchronously.
9
46
  *
10
47
  * @param context The source context to check.
11
48
  * @returns `true` if the context is static, `false` otherwise.
12
49
  * @since 0.10.0
13
50
  */
14
51
  function isStaticContext(context) {
52
+ if (context.mode !== void 0) return context.mode === "static";
15
53
  const result = context.getAnnotations();
16
54
  if (result instanceof Promise) return false;
17
55
  return Object.getOwnPropertySymbols(result).length > 0;
18
56
  }
19
57
 
20
58
  //#endregion
21
- exports.isStaticContext = isStaticContext;
59
+ exports.isPlaceholderValue = isPlaceholderValue;
60
+ exports.isStaticContext = isStaticContext;
61
+ exports.placeholder = placeholder;
@@ -2,6 +2,17 @@ import { Annotations } from "./annotations.cjs";
2
2
 
3
3
  //#region src/context.d.ts
4
4
 
5
+ /**
6
+ * Declares whether a {@link SourceContext} provides its annotations
7
+ * immediately (`"static"`) or only after a prior parse pass (`"dynamic"`).
8
+ *
9
+ * Used as the type of the optional `mode` field on {@link SourceContext}.
10
+ * When set, {@link isStaticContext} reads this value directly instead of
11
+ * calling `getAnnotations()`, preventing any side effects.
12
+ *
13
+ * @since 1.0.0
14
+ */
15
+ type SourceContextMode = "static" | "dynamic";
5
16
  /**
6
17
  * Brand symbol for ParserValuePlaceholder type.
7
18
  * @internal
@@ -46,6 +57,10 @@ type ParserValuePlaceholder = {
46
57
  * - *Dynamic*: Data depends on parsing results (e.g., config files whose path
47
58
  * is determined by a CLI option)
48
59
  *
60
+ * Contexts may optionally implement `Disposable` or `AsyncDisposable` for
61
+ * cleanup. When present, `runWith()` and `runWithSync()` call the dispose
62
+ * method in a `finally` block after parsing completes.
63
+ *
49
64
  * @template TRequiredOptions Additional options that `runWith()` must provide
50
65
  * when this context is used. Use `void` (the default) for contexts that
51
66
  * don't require extra options. Use {@link ParserValuePlaceholder} in option
@@ -88,7 +103,20 @@ interface SourceContext<TRequiredOptions = void> {
88
103
  * Type-level marker for the required options. Not used at runtime.
89
104
  * @internal
90
105
  */
91
- readonly _requiredOptions?: TRequiredOptions;
106
+ readonly $requiredOptions?: TRequiredOptions;
107
+ /**
108
+ * Optional declaration of whether this context is static or dynamic.
109
+ *
110
+ * When present, {@link isStaticContext} reads this field directly instead
111
+ * of calling {@link getAnnotations}, avoiding any side effects that
112
+ * `getAnnotations` might have (such as mutating a global registry).
113
+ *
114
+ * If omitted, {@link isStaticContext} falls back to calling
115
+ * `getAnnotations()` with no arguments to determine static-ness.
116
+ *
117
+ * @since 1.0.0
118
+ */
119
+ readonly mode?: SourceContextMode;
92
120
  /**
93
121
  * Get annotations to inject into parsing.
94
122
  *
@@ -103,17 +131,97 @@ interface SourceContext<TRequiredOptions = void> {
103
131
  * @param parsed Optional parsed result from a previous parse pass.
104
132
  * Static contexts can ignore this parameter.
105
133
  * Dynamic contexts use this to extract necessary data.
134
+ * @param options Optional context-required options provided by the caller
135
+ * of `runWith()`. These are the options declared via the
136
+ * `TRequiredOptions` type parameter.
106
137
  * @returns Annotations to merge into the parsing session. Can be a Promise
107
138
  * for async operations (e.g., loading config files).
108
139
  */
109
- getAnnotations(parsed?: unknown): Promise<Annotations> | Annotations;
140
+ getAnnotations(parsed?: unknown, options?: unknown): Promise<Annotations> | Annotations;
141
+ /**
142
+ * Optional hook to provide additional internal annotations during
143
+ * annotation collection. Called after {@link getAnnotations} with the
144
+ * same parsed value and the annotations returned by `getAnnotations()`.
145
+ *
146
+ * Returns additional annotations to merge, or `undefined` to add nothing.
147
+ * This enables contexts to inject phase-specific markers without
148
+ * exposing them through the primary `getAnnotations()` API.
149
+ *
150
+ * @param parsed The parsed result from a previous parse pass, or
151
+ * `undefined` during the first pass.
152
+ * @param annotations The annotations returned by `getAnnotations()`.
153
+ * @returns Additional annotations to merge, or `undefined`.
154
+ * @since 1.0.0
155
+ */
156
+ getInternalAnnotations?(parsed: unknown, annotations: Annotations): Annotations | undefined;
157
+ /**
158
+ * Optional hook to transform the parsed value before it is passed to
159
+ * {@link getAnnotations} during phase-2 annotation collection.
160
+ *
161
+ * This allows contexts to distinguish between "parsed value was
162
+ * `undefined`" and "no parse happened yet" by wrapping `undefined`
163
+ * values with a context-private marker.
164
+ *
165
+ * @param parsed The parsed value to finalize.
166
+ * @returns The finalized parsed value.
167
+ * @since 1.0.0
168
+ */
169
+ finalizeParsed?(parsed: unknown): unknown;
170
+ /**
171
+ * Optional synchronous cleanup method. Called by `runWith()` and
172
+ * `runWithSync()` in a `finally` block after parsing completes.
173
+ */
174
+ [Symbol.dispose]?(): void;
175
+ /**
176
+ * Optional asynchronous cleanup method. Called by `runWith()` in a
177
+ * `finally` block after parsing completes. Takes precedence over
178
+ * `[Symbol.dispose]` in async runners. `runWithSync()` also calls this
179
+ * method when `[Symbol.dispose]` is absent, but throws if it returns a
180
+ * Promise.
181
+ */
182
+ [Symbol.asyncDispose]?(): void | PromiseLike<void>;
110
183
  }
184
+ /**
185
+ * Brand symbol for placeholder values.
186
+ *
187
+ * Placeholder values are sentinel objects that represent values to be
188
+ * resolved later (e.g., deferred interactive prompts). During two-phase
189
+ * parsing, placeholder values are stripped from parsed results before they
190
+ * are passed to phase-2 context annotation collection, and `map()`
191
+ * transformations skip them.
192
+ *
193
+ * Packages that produce placeholder values should set this symbol as a
194
+ * property on their sentinel objects:
195
+ *
196
+ * ~~~~ typescript
197
+ * import { placeholder } from "@optique/core/context";
198
+ *
199
+ * class MyPlaceholder {
200
+ * readonly [placeholder] = true;
201
+ * }
202
+ * ~~~~
203
+ *
204
+ * @since 1.0.0
205
+ */
206
+ declare const placeholder: unique symbol;
207
+ /**
208
+ * Tests whether a value is a placeholder.
209
+ *
210
+ * Returns `true` if the value is a non-null object carrying the
211
+ * {@link placeholder} property.
212
+ *
213
+ * @param value The value to test.
214
+ * @returns `true` if the value is a placeholder.
215
+ * @since 1.0.0
216
+ */
217
+ declare function isPlaceholderValue(value: unknown): boolean;
111
218
  /**
112
219
  * Checks whether a context is static (returns annotations without needing
113
220
  * parsed results).
114
221
  *
115
- * A context is considered static if `getAnnotations()` called without
116
- * arguments returns a non-empty annotations object synchronously.
222
+ * A context is considered static if it declares `mode: "static"` or if
223
+ * `getAnnotations()` called without arguments returns a non-empty
224
+ * annotations object synchronously.
117
225
  *
118
226
  * @param context The source context to check.
119
227
  * @returns `true` if the context is static, `false` otherwise.
@@ -121,4 +229,4 @@ interface SourceContext<TRequiredOptions = void> {
121
229
  */
122
230
  declare function isStaticContext(context: SourceContext<unknown>): boolean;
123
231
  //#endregion
124
- export { type Annotations, ParserValuePlaceholder, SourceContext, isStaticContext };
232
+ export { type Annotations, ParserValuePlaceholder, SourceContext, SourceContextMode, isPlaceholderValue, isStaticContext, placeholder };
package/dist/context.d.ts CHANGED
@@ -2,6 +2,17 @@ import { Annotations } from "./annotations.js";
2
2
 
3
3
  //#region src/context.d.ts
4
4
 
5
+ /**
6
+ * Declares whether a {@link SourceContext} provides its annotations
7
+ * immediately (`"static"`) or only after a prior parse pass (`"dynamic"`).
8
+ *
9
+ * Used as the type of the optional `mode` field on {@link SourceContext}.
10
+ * When set, {@link isStaticContext} reads this value directly instead of
11
+ * calling `getAnnotations()`, preventing any side effects.
12
+ *
13
+ * @since 1.0.0
14
+ */
15
+ type SourceContextMode = "static" | "dynamic";
5
16
  /**
6
17
  * Brand symbol for ParserValuePlaceholder type.
7
18
  * @internal
@@ -46,6 +57,10 @@ type ParserValuePlaceholder = {
46
57
  * - *Dynamic*: Data depends on parsing results (e.g., config files whose path
47
58
  * is determined by a CLI option)
48
59
  *
60
+ * Contexts may optionally implement `Disposable` or `AsyncDisposable` for
61
+ * cleanup. When present, `runWith()` and `runWithSync()` call the dispose
62
+ * method in a `finally` block after parsing completes.
63
+ *
49
64
  * @template TRequiredOptions Additional options that `runWith()` must provide
50
65
  * when this context is used. Use `void` (the default) for contexts that
51
66
  * don't require extra options. Use {@link ParserValuePlaceholder} in option
@@ -88,7 +103,20 @@ interface SourceContext<TRequiredOptions = void> {
88
103
  * Type-level marker for the required options. Not used at runtime.
89
104
  * @internal
90
105
  */
91
- readonly _requiredOptions?: TRequiredOptions;
106
+ readonly $requiredOptions?: TRequiredOptions;
107
+ /**
108
+ * Optional declaration of whether this context is static or dynamic.
109
+ *
110
+ * When present, {@link isStaticContext} reads this field directly instead
111
+ * of calling {@link getAnnotations}, avoiding any side effects that
112
+ * `getAnnotations` might have (such as mutating a global registry).
113
+ *
114
+ * If omitted, {@link isStaticContext} falls back to calling
115
+ * `getAnnotations()` with no arguments to determine static-ness.
116
+ *
117
+ * @since 1.0.0
118
+ */
119
+ readonly mode?: SourceContextMode;
92
120
  /**
93
121
  * Get annotations to inject into parsing.
94
122
  *
@@ -103,17 +131,97 @@ interface SourceContext<TRequiredOptions = void> {
103
131
  * @param parsed Optional parsed result from a previous parse pass.
104
132
  * Static contexts can ignore this parameter.
105
133
  * Dynamic contexts use this to extract necessary data.
134
+ * @param options Optional context-required options provided by the caller
135
+ * of `runWith()`. These are the options declared via the
136
+ * `TRequiredOptions` type parameter.
106
137
  * @returns Annotations to merge into the parsing session. Can be a Promise
107
138
  * for async operations (e.g., loading config files).
108
139
  */
109
- getAnnotations(parsed?: unknown): Promise<Annotations> | Annotations;
140
+ getAnnotations(parsed?: unknown, options?: unknown): Promise<Annotations> | Annotations;
141
+ /**
142
+ * Optional hook to provide additional internal annotations during
143
+ * annotation collection. Called after {@link getAnnotations} with the
144
+ * same parsed value and the annotations returned by `getAnnotations()`.
145
+ *
146
+ * Returns additional annotations to merge, or `undefined` to add nothing.
147
+ * This enables contexts to inject phase-specific markers without
148
+ * exposing them through the primary `getAnnotations()` API.
149
+ *
150
+ * @param parsed The parsed result from a previous parse pass, or
151
+ * `undefined` during the first pass.
152
+ * @param annotations The annotations returned by `getAnnotations()`.
153
+ * @returns Additional annotations to merge, or `undefined`.
154
+ * @since 1.0.0
155
+ */
156
+ getInternalAnnotations?(parsed: unknown, annotations: Annotations): Annotations | undefined;
157
+ /**
158
+ * Optional hook to transform the parsed value before it is passed to
159
+ * {@link getAnnotations} during phase-2 annotation collection.
160
+ *
161
+ * This allows contexts to distinguish between "parsed value was
162
+ * `undefined`" and "no parse happened yet" by wrapping `undefined`
163
+ * values with a context-private marker.
164
+ *
165
+ * @param parsed The parsed value to finalize.
166
+ * @returns The finalized parsed value.
167
+ * @since 1.0.0
168
+ */
169
+ finalizeParsed?(parsed: unknown): unknown;
170
+ /**
171
+ * Optional synchronous cleanup method. Called by `runWith()` and
172
+ * `runWithSync()` in a `finally` block after parsing completes.
173
+ */
174
+ [Symbol.dispose]?(): void;
175
+ /**
176
+ * Optional asynchronous cleanup method. Called by `runWith()` in a
177
+ * `finally` block after parsing completes. Takes precedence over
178
+ * `[Symbol.dispose]` in async runners. `runWithSync()` also calls this
179
+ * method when `[Symbol.dispose]` is absent, but throws if it returns a
180
+ * Promise.
181
+ */
182
+ [Symbol.asyncDispose]?(): void | PromiseLike<void>;
110
183
  }
184
+ /**
185
+ * Brand symbol for placeholder values.
186
+ *
187
+ * Placeholder values are sentinel objects that represent values to be
188
+ * resolved later (e.g., deferred interactive prompts). During two-phase
189
+ * parsing, placeholder values are stripped from parsed results before they
190
+ * are passed to phase-2 context annotation collection, and `map()`
191
+ * transformations skip them.
192
+ *
193
+ * Packages that produce placeholder values should set this symbol as a
194
+ * property on their sentinel objects:
195
+ *
196
+ * ~~~~ typescript
197
+ * import { placeholder } from "@optique/core/context";
198
+ *
199
+ * class MyPlaceholder {
200
+ * readonly [placeholder] = true;
201
+ * }
202
+ * ~~~~
203
+ *
204
+ * @since 1.0.0
205
+ */
206
+ declare const placeholder: unique symbol;
207
+ /**
208
+ * Tests whether a value is a placeholder.
209
+ *
210
+ * Returns `true` if the value is a non-null object carrying the
211
+ * {@link placeholder} property.
212
+ *
213
+ * @param value The value to test.
214
+ * @returns `true` if the value is a placeholder.
215
+ * @since 1.0.0
216
+ */
217
+ declare function isPlaceholderValue(value: unknown): boolean;
111
218
  /**
112
219
  * Checks whether a context is static (returns annotations without needing
113
220
  * parsed results).
114
221
  *
115
- * A context is considered static if `getAnnotations()` called without
116
- * arguments returns a non-empty annotations object synchronously.
222
+ * A context is considered static if it declares `mode: "static"` or if
223
+ * `getAnnotations()` called without arguments returns a non-empty
224
+ * annotations object synchronously.
117
225
  *
118
226
  * @param context The source context to check.
119
227
  * @returns `true` if the context is static, `false` otherwise.
@@ -121,4 +229,4 @@ interface SourceContext<TRequiredOptions = void> {
121
229
  */
122
230
  declare function isStaticContext(context: SourceContext<unknown>): boolean;
123
231
  //#endregion
124
- export { type Annotations, ParserValuePlaceholder, SourceContext, isStaticContext };
232
+ export { type Annotations, ParserValuePlaceholder, SourceContext, SourceContextMode, isPlaceholderValue, isStaticContext, placeholder };
package/dist/context.js CHANGED
@@ -1,20 +1,58 @@
1
1
  //#region src/context.ts
2
2
  /**
3
+ * Brand symbol for placeholder values.
4
+ *
5
+ * Placeholder values are sentinel objects that represent values to be
6
+ * resolved later (e.g., deferred interactive prompts). During two-phase
7
+ * parsing, placeholder values are stripped from parsed results before they
8
+ * are passed to phase-2 context annotation collection, and `map()`
9
+ * transformations skip them.
10
+ *
11
+ * Packages that produce placeholder values should set this symbol as a
12
+ * property on their sentinel objects:
13
+ *
14
+ * ~~~~ typescript
15
+ * import { placeholder } from "@optique/core/context";
16
+ *
17
+ * class MyPlaceholder {
18
+ * readonly [placeholder] = true;
19
+ * }
20
+ * ~~~~
21
+ *
22
+ * @since 1.0.0
23
+ */
24
+ const placeholder = Symbol.for("@optique/core/placeholder");
25
+ /**
26
+ * Tests whether a value is a placeholder.
27
+ *
28
+ * Returns `true` if the value is a non-null object carrying the
29
+ * {@link placeholder} property.
30
+ *
31
+ * @param value The value to test.
32
+ * @returns `true` if the value is a placeholder.
33
+ * @since 1.0.0
34
+ */
35
+ function isPlaceholderValue(value) {
36
+ return value != null && typeof value === "object" && placeholder in value;
37
+ }
38
+ /**
3
39
  * Checks whether a context is static (returns annotations without needing
4
40
  * parsed results).
5
41
  *
6
- * A context is considered static if `getAnnotations()` called without
7
- * arguments returns a non-empty annotations object synchronously.
42
+ * A context is considered static if it declares `mode: "static"` or if
43
+ * `getAnnotations()` called without arguments returns a non-empty
44
+ * annotations object synchronously.
8
45
  *
9
46
  * @param context The source context to check.
10
47
  * @returns `true` if the context is static, `false` otherwise.
11
48
  * @since 0.10.0
12
49
  */
13
50
  function isStaticContext(context) {
51
+ if (context.mode !== void 0) return context.mode === "static";
14
52
  const result = context.getAnnotations();
15
53
  if (result instanceof Promise) return false;
16
54
  return Object.getOwnPropertySymbols(result).length > 0;
17
55
  }
18
56
 
19
57
  //#endregion
20
- export { isStaticContext };
58
+ export { isPlaceholderValue, isStaticContext, placeholder };