@optique/core 1.0.0-dev.908 → 1.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 (109) hide show
  1. package/dist/annotation-state.cjs +425 -0
  2. package/dist/annotation-state.d.cts +24 -0
  3. package/dist/annotation-state.d.ts +24 -0
  4. package/dist/annotation-state.js +414 -0
  5. package/dist/annotations.cjs +2 -248
  6. package/dist/annotations.d.cts +2 -137
  7. package/dist/annotations.d.ts +2 -137
  8. package/dist/annotations.js +2 -238
  9. package/dist/completion.cjs +611 -100
  10. package/dist/completion.d.cts +1 -1
  11. package/dist/completion.d.ts +1 -1
  12. package/dist/completion.js +611 -100
  13. package/dist/constructs.cjs +3338 -827
  14. package/dist/constructs.d.cts +48 -7
  15. package/dist/constructs.d.ts +48 -7
  16. package/dist/constructs.js +3338 -827
  17. package/dist/context.cjs +0 -23
  18. package/dist/context.d.cts +119 -53
  19. package/dist/context.d.ts +119 -53
  20. package/dist/context.js +0 -22
  21. package/dist/dependency-metadata.cjs +139 -0
  22. package/dist/dependency-metadata.d.cts +112 -0
  23. package/dist/dependency-metadata.d.ts +112 -0
  24. package/dist/dependency-metadata.js +138 -0
  25. package/dist/dependency-runtime.cjs +698 -0
  26. package/dist/dependency-runtime.d.cts +149 -0
  27. package/dist/dependency-runtime.d.ts +149 -0
  28. package/dist/dependency-runtime.js +687 -0
  29. package/dist/dependency.cjs +7 -928
  30. package/dist/dependency.d.cts +2 -794
  31. package/dist/dependency.d.ts +2 -794
  32. package/dist/dependency.js +2 -899
  33. package/dist/displaywidth.cjs +44 -0
  34. package/dist/displaywidth.js +43 -0
  35. package/dist/doc.cjs +285 -23
  36. package/dist/doc.d.cts +57 -2
  37. package/dist/doc.d.ts +57 -2
  38. package/dist/doc.js +283 -25
  39. package/dist/execution-context.cjs +56 -0
  40. package/dist/execution-context.js +53 -0
  41. package/dist/extension.cjs +87 -0
  42. package/dist/extension.d.cts +97 -0
  43. package/dist/extension.d.ts +97 -0
  44. package/dist/extension.js +76 -0
  45. package/dist/facade.cjs +718 -523
  46. package/dist/facade.d.cts +87 -18
  47. package/dist/facade.d.ts +87 -18
  48. package/dist/facade.js +718 -523
  49. package/dist/index.cjs +14 -29
  50. package/dist/index.d.cts +10 -10
  51. package/dist/index.d.ts +10 -10
  52. package/dist/index.js +7 -7
  53. package/dist/input-trace.cjs +56 -0
  54. package/dist/input-trace.d.cts +77 -0
  55. package/dist/input-trace.d.ts +77 -0
  56. package/dist/input-trace.js +55 -0
  57. package/dist/internal/annotations.cjs +316 -0
  58. package/dist/internal/annotations.d.cts +140 -0
  59. package/dist/internal/annotations.d.ts +140 -0
  60. package/dist/internal/annotations.js +306 -0
  61. package/dist/internal/dependency.cjs +984 -0
  62. package/dist/internal/dependency.d.cts +539 -0
  63. package/dist/internal/dependency.d.ts +539 -0
  64. package/dist/internal/dependency.js +964 -0
  65. package/dist/{mode-dispatch.cjs → internal/mode-dispatch.cjs} +1 -3
  66. package/dist/{mode-dispatch.d.cts → internal/mode-dispatch.d.cts} +3 -7
  67. package/dist/{mode-dispatch.d.ts → internal/mode-dispatch.d.ts} +3 -7
  68. package/dist/{mode-dispatch.js → internal/mode-dispatch.js} +1 -3
  69. package/dist/internal/parser.cjs +728 -0
  70. package/dist/internal/parser.d.cts +947 -0
  71. package/dist/internal/parser.d.ts +947 -0
  72. package/dist/internal/parser.js +711 -0
  73. package/dist/message.cjs +84 -26
  74. package/dist/message.d.cts +49 -9
  75. package/dist/message.d.ts +49 -9
  76. package/dist/message.js +84 -27
  77. package/dist/modifiers.cjs +1023 -240
  78. package/dist/modifiers.d.cts +42 -1
  79. package/dist/modifiers.d.ts +42 -1
  80. package/dist/modifiers.js +1023 -240
  81. package/dist/parser.cjs +11 -463
  82. package/dist/parser.d.cts +3 -537
  83. package/dist/parser.d.ts +3 -537
  84. package/dist/parser.js +2 -433
  85. package/dist/phase2-seed.cjs +59 -0
  86. package/dist/phase2-seed.js +56 -0
  87. package/dist/primitives.cjs +557 -208
  88. package/dist/primitives.d.cts +10 -14
  89. package/dist/primitives.d.ts +10 -14
  90. package/dist/primitives.js +557 -208
  91. package/dist/program.cjs +5 -1
  92. package/dist/program.d.cts +5 -3
  93. package/dist/program.d.ts +5 -3
  94. package/dist/program.js +6 -1
  95. package/dist/suggestion.cjs +22 -8
  96. package/dist/suggestion.js +22 -8
  97. package/dist/usage-internals.cjs +3 -2
  98. package/dist/usage-internals.js +4 -2
  99. package/dist/usage.cjs +195 -40
  100. package/dist/usage.d.cts +92 -11
  101. package/dist/usage.d.ts +92 -11
  102. package/dist/usage.js +194 -41
  103. package/dist/validate.cjs +170 -0
  104. package/dist/validate.js +164 -0
  105. package/dist/valueparser.cjs +1278 -191
  106. package/dist/valueparser.d.cts +330 -20
  107. package/dist/valueparser.d.ts +330 -20
  108. package/dist/valueparser.js +1277 -192
  109. package/package.json +9 -9
package/dist/message.js CHANGED
@@ -1,5 +1,45 @@
1
+ import { getDisplayWidth } from "./displaywidth.js";
2
+
1
3
  //#region src/message.ts
2
4
  /**
5
+ * Creates a deep clone of a {@link MessageTerm}. Most variants contain only
6
+ * primitive fields and are cloned via object spread. The `url` variant
7
+ * receives a new `URL` object (since `structuredClone` cannot handle `URL`
8
+ * on Node.js), and array-valued fields (`optionNames`, `values`) are
9
+ * shallow-copied.
10
+ *
11
+ * @param term The message term to clone.
12
+ * @returns A structurally equal but referentially distinct copy.
13
+ * @since 1.0.0
14
+ */
15
+ function cloneMessageTerm(term) {
16
+ switch (term.type) {
17
+ case "optionNames": return {
18
+ ...term,
19
+ optionNames: [...term.optionNames]
20
+ };
21
+ case "values": return {
22
+ ...term,
23
+ values: [...term.values]
24
+ };
25
+ case "url": return {
26
+ type: "url",
27
+ url: new URL(term.url.href)
28
+ };
29
+ default: return { ...term };
30
+ }
31
+ }
32
+ /**
33
+ * Creates a deep clone of a {@link Message} array and all of its terms.
34
+ *
35
+ * @param msg The message to clone.
36
+ * @returns A structurally equal but referentially distinct copy.
37
+ * @since 1.0.0
38
+ */
39
+ function cloneMessage(msg) {
40
+ return msg.map(cloneMessageTerm);
41
+ }
42
+ /**
3
43
  * Creates a structured message with template strings and values.
4
44
  *
5
45
  * This function allows creating messages where specific values can be
@@ -28,8 +68,8 @@ function message(message$1, ...values$1) {
28
68
  type: "value",
29
69
  value: value$1
30
70
  });
31
- else if (Array.isArray(value$1)) messageTerms.push(...value$1);
32
- else if (typeof value$1 === "object" && value$1 != null && "type" in value$1) messageTerms.push(value$1);
71
+ else if (Array.isArray(value$1)) messageTerms.push(...cloneMessage(value$1));
72
+ else if (typeof value$1 === "object" && value$1 != null && "type" in value$1) messageTerms.push(cloneMessageTerm(value$1));
33
73
  else throw new TypeError(`Invalid value type in message: ${typeof value$1}.`);
34
74
  }
35
75
  return messageTerms;
@@ -67,7 +107,7 @@ function optionName(name) {
67
107
  function optionNames(names) {
68
108
  return {
69
109
  type: "optionNames",
70
- optionNames: names
110
+ optionNames: [...names]
71
111
  };
72
112
  }
73
113
  /**
@@ -104,11 +144,13 @@ function value(value$1) {
104
144
  * string representations of consecutive values.
105
145
  * For example, `["42", "hello"]`.
106
146
  * @returns A {@link MessageTerm} representing the list of values.
147
+ * @throws {TypeError} If the values array is empty.
107
148
  */
108
149
  function values(values$1) {
150
+ if (values$1.length === 0) throw new TypeError("values must not be empty.");
109
151
  return {
110
152
  type: "values",
111
- values: values$1
153
+ values: [...values$1]
112
154
  };
113
155
  }
114
156
  /**
@@ -164,7 +206,7 @@ function url(url$1) {
164
206
  if (typeof url$1 === "string") {
165
207
  if (!URL.canParse(url$1)) throw new RangeError(`Invalid URL: ${url$1}.`);
166
208
  urlObj = new URL(url$1);
167
- } else urlObj = url$1;
209
+ } else urlObj = new URL(url$1.href);
168
210
  return {
169
211
  type: "url",
170
212
  url: urlObj
@@ -197,29 +239,44 @@ function link(href) {
197
239
  * to be styled independently while respecting the locale's list formatting
198
240
  * conventions.
199
241
  *
242
+ * A fallback must be provided for when the values array is empty. This can
243
+ * be either a simple string (shorthand) or an options object with a
244
+ * `fallback` field. When the values array is empty, the fallback text
245
+ * is returned as a single text term. An empty fallback string produces
246
+ * an empty {@link Message}.
247
+ *
200
248
  * @example
201
249
  * ```typescript
202
250
  * // English conjunction (default): "error", "warn", and "info"
203
- * const msg1 = message`Expected one of ${valueSet(["error", "warn", "info"])}.`;
251
+ * const msg1 = message`Expected one of ${
252
+ * valueSet(["error", "warn", "info"], "")
253
+ * }.`;
204
254
  *
205
255
  * // English disjunction: "error", "warn", or "info"
206
256
  * const msg2 = message`Expected ${
207
- * valueSet(["error", "warn", "info"], { type: "disjunction" })
257
+ * valueSet(["error", "warn", "info"], { fallback: "", type: "disjunction" })
208
258
  * }.`;
209
259
  *
210
- * // Korean disjunction: "error", "warn" 또는 "info"
211
- * const msg3 = message`${
212
- * valueSet(["error", "warn", "info"], { locale: "ko", type: "disjunction" })
213
- * } 중 하나여야 합니다.`;
260
+ * // Fallback for empty list:
261
+ * const msg3 = message`Expected one of ${valueSet([], "(none)")}.`;
262
+ * // "Expected one of (none)."
214
263
  * ```
215
264
  *
216
265
  * @param values The list of values to format.
217
- * @param options Optional formatting options including locale and list type.
266
+ * @param fallbackOrOptions A fallback string for empty lists, or an options
267
+ * object including the fallback and formatting
268
+ * options such as locale and list type.
218
269
  * @returns A {@link Message} with alternating value and text terms.
270
+ * @throws {TypeError} If the fallback parameter is missing or invalid.
219
271
  * @since 0.9.0
220
272
  */
221
- function valueSet(values$1, options) {
222
- if (values$1.length === 0) return [];
273
+ function valueSet(values$1, fallbackOrOptions) {
274
+ if (fallbackOrOptions == null || typeof fallbackOrOptions !== "string" && typeof fallbackOrOptions.fallback !== "string") throw new TypeError("valueSet() requires a fallback string or an options object with a fallback field.");
275
+ const options = typeof fallbackOrOptions === "string" ? { fallback: fallbackOrOptions } : fallbackOrOptions;
276
+ if (values$1.length === 0) return options.fallback === "" ? [] : [{
277
+ type: "text",
278
+ text: options.fallback
279
+ }];
223
280
  const formatter = new Intl.ListFormat(options?.locale, {
224
281
  type: options?.type,
225
282
  style: options?.style
@@ -267,7 +324,7 @@ function formatMessage(msg, options = {}) {
267
324
  if (match == null) break;
268
325
  yield {
269
326
  text: match[0],
270
- width: match[0].length
327
+ width: getDisplayWidth(match[0])
271
328
  };
272
329
  }
273
330
  }
@@ -284,7 +341,7 @@ function formatMessage(msg, options = {}) {
284
341
  if (match == null) break;
285
342
  yield {
286
343
  text: match[0],
287
- width: match[0].length
344
+ width: getDisplayWidth(match[0])
288
345
  };
289
346
  }
290
347
  }
@@ -293,7 +350,7 @@ function formatMessage(msg, options = {}) {
293
350
  const name = useQuotes ? `\`${term.optionName}\`` : term.optionName;
294
351
  yield {
295
352
  text: useColors ? `\x1b[3m${name}${resetSequence}` : name,
296
- width: name.length
353
+ width: getDisplayWidth(name)
297
354
  };
298
355
  } else if (term.type === "optionNames") {
299
356
  const names = term.optionNames.map((name) => useQuotes ? `\`${name}\`` : name);
@@ -305,7 +362,7 @@ function formatMessage(msg, options = {}) {
305
362
  };
306
363
  yield {
307
364
  text: useColors ? `\x1b[3m${name}${resetSequence}` : name,
308
- width: name.length
365
+ width: getDisplayWidth(name)
309
366
  };
310
367
  i++;
311
368
  }
@@ -313,13 +370,13 @@ function formatMessage(msg, options = {}) {
313
370
  const metavar$1 = useQuotes ? `\`${term.metavar}\`` : term.metavar;
314
371
  yield {
315
372
  text: useColors ? `\x1b[1m${metavar$1}${resetSequence}` : metavar$1,
316
- width: metavar$1.length
373
+ width: getDisplayWidth(metavar$1)
317
374
  };
318
375
  } else if (term.type === "value") {
319
376
  const value$1 = useQuotes ? `${JSON.stringify(term.value)}` : term.value;
320
377
  yield {
321
378
  text: useColors ? `\x1b[32m${value$1}${resetSequence}` : value$1,
322
- width: value$1.length
379
+ width: getDisplayWidth(value$1)
323
380
  };
324
381
  } else if (term.type === "values") for (let i = 0; i < term.values.length; i++) {
325
382
  if (i > 0) yield {
@@ -329,20 +386,20 @@ function formatMessage(msg, options = {}) {
329
386
  const value$1 = useQuotes ? JSON.stringify(term.values[i]) : term.values[i];
330
387
  yield {
331
388
  text: useColors ? i <= 0 ? `\x1b[32m${value$1}` : i + 1 >= term.values.length ? `${value$1}${resetSequence}` : value$1 : value$1,
332
- width: value$1.length
389
+ width: getDisplayWidth(value$1)
333
390
  };
334
391
  }
335
392
  else if (term.type === "envVar") {
336
393
  const envVar$1 = useQuotes ? `\`${term.envVar}\`` : term.envVar;
337
394
  yield {
338
395
  text: useColors ? `\x1b[1;4m${envVar$1}${resetSequence}` : envVar$1,
339
- width: envVar$1.length
396
+ width: getDisplayWidth(envVar$1)
340
397
  };
341
398
  } else if (term.type === "commandLine") {
342
399
  const cmd = useQuotes ? `\`${term.commandLine}\`` : term.commandLine;
343
400
  yield {
344
401
  text: useColors ? `\x1b[36m${cmd}${resetSequence}` : cmd,
345
- width: cmd.length
402
+ width: getDisplayWidth(cmd)
346
403
  };
347
404
  } else if (term.type === "lineBreak") {
348
405
  yield {
@@ -357,11 +414,11 @@ function formatMessage(msg, options = {}) {
357
414
  const hyperlink = `\x1b]8;;${urlString}\x1b\\${displayText}\x1b]8;;\x1b\\${resetSuffix}`;
358
415
  yield {
359
416
  text: hyperlink,
360
- width: displayText.length
417
+ width: getDisplayWidth(displayText)
361
418
  };
362
419
  } else yield {
363
420
  text: displayText,
364
- width: displayText.length
421
+ width: getDisplayWidth(displayText)
365
422
  };
366
423
  } else throw new TypeError(`Invalid MessageTerm type: ${term["type"]}.`);
367
424
  }
@@ -374,7 +431,7 @@ function formatMessage(msg, options = {}) {
374
431
  totalWidth = 0;
375
432
  continue;
376
433
  }
377
- if (options.maxWidth != null && totalWidth + width > options.maxWidth) {
434
+ if (options.maxWidth != null && totalWidth > 0 && totalWidth + width > options.maxWidth) {
378
435
  output += "\n";
379
436
  totalWidth = 0;
380
437
  }
@@ -385,4 +442,4 @@ function formatMessage(msg, options = {}) {
385
442
  }
386
443
 
387
444
  //#endregion
388
- export { commandLine, envVar, formatMessage, lineBreak, link, message, metavar, optionName, optionNames, text, url, value, valueSet, values };
445
+ export { cloneMessage, cloneMessageTerm, commandLine, envVar, formatMessage, lineBreak, link, message, metavar, optionName, optionNames, text, url, value, valueSet, values };