@optique/core 0.9.0-dev.206 → 0.9.0-dev.212

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright 2025 Hong Minhee
3
+ Copyright 2025–2026 Hong Minhee
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy of
6
6
  this software and associated documentation files (the "Software"), to deal in
@@ -73,7 +73,8 @@ function analyzeNoMatchContext(parsers) {
73
73
  */
74
74
  var DuplicateOptionError = class extends Error {
75
75
  constructor(optionName$1, sources) {
76
- super(`Duplicate option name "${optionName$1}" found in fields: ${sources.join(", ")}. Each option name must be unique within a parser combinator.`);
76
+ const sourceNames = sources.map((s) => typeof s === "symbol" ? s.description ?? s.toString() : s);
77
+ super(`Duplicate option name "${optionName$1}" found in fields: ${sourceNames.join(", ")}. Each option name must be unique within a parser combinator.`);
77
78
  this.optionName = optionName$1;
78
79
  this.sources = sources;
79
80
  this.name = "DuplicateOptionError";
@@ -541,11 +542,14 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
541
542
  parsers = labelOrParsers;
542
543
  options = maybeParsersOrOptions ?? {};
543
544
  }
544
- const parserPairs = Object.entries(parsers);
545
+ const parserKeys = Reflect.ownKeys(parsers);
546
+ const parserPairs = parserKeys.map((k) => [k, parsers[k]]);
545
547
  parserPairs.sort(([_, parserA], [__, parserB]) => parserB.priority - parserA.priority);
548
+ const initialState = {};
549
+ for (const key of parserKeys) initialState[key] = parsers[key].initialState;
546
550
  if (!options.allowDuplicates) checkDuplicateOptionNames(parserPairs.map(([field, parser]) => [field, parser.usage]));
547
- const noMatchContext = analyzeNoMatchContext(Object.values(parsers));
548
- const combinedMode = Object.values(parsers).some((p) => p.$mode === "async") ? "async" : "sync";
551
+ const noMatchContext = analyzeNoMatchContext(parserKeys.map((k) => parsers[k]));
552
+ const combinedMode = parserKeys.some((k) => parsers[k].$mode === "async") ? "async" : "sync";
549
553
  const isAsync = combinedMode === "async";
550
554
  const getInitialError = (context) => ({
551
555
  consumed: 0,
@@ -677,9 +681,9 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
677
681
  $mode: combinedMode,
678
682
  $valueType: [],
679
683
  $stateType: [],
680
- priority: Math.max(...Object.values(parsers).map((p) => p.priority)),
684
+ priority: Math.max(...parserKeys.map((k) => parsers[k].priority)),
681
685
  usage: parserPairs.flatMap(([_, p]) => p.usage),
682
- initialState: Object.fromEntries(Object.entries(parsers).map(([key, parser]) => [key, parser.initialState])),
686
+ initialState,
683
687
  parse(context) {
684
688
  if (isAsync) return parseAsync(context);
685
689
  return parseSync(context);
@@ -687,10 +691,8 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
687
691
  complete(state) {
688
692
  if (!isAsync) {
689
693
  const result = {};
690
- const stateRecord = state;
691
- for (const field in stateRecord) {
692
- if (!(field in parsers)) continue;
693
- const valueResult = parsers[field].complete(stateRecord[field]);
694
+ for (const field of parserKeys) {
695
+ const valueResult = parsers[field].complete(state[field]);
694
696
  if (valueResult.success) result[field] = valueResult.value;
695
697
  else return {
696
698
  success: false,
@@ -704,10 +706,8 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
704
706
  }
705
707
  return (async () => {
706
708
  const result = {};
707
- const stateRecord = state;
708
- for (const field in stateRecord) {
709
- if (!(field in parsers)) continue;
710
- const valueResult = await parsers[field].complete(stateRecord[field]);
709
+ for (const field of parserKeys) {
710
+ const valueResult = await parsers[field].complete(state[field]);
711
711
  if (valueResult.success) result[field] = valueResult.value;
712
712
  else return {
713
713
  success: false,
@@ -102,8 +102,8 @@ interface OrErrorOptions {
102
102
  */
103
103
  declare class DuplicateOptionError extends Error {
104
104
  readonly optionName: string;
105
- readonly sources: string[];
106
- constructor(optionName: string, sources: string[]);
105
+ readonly sources: readonly (string | symbol)[];
106
+ constructor(optionName: string, sources: readonly (string | symbol)[]);
107
107
  }
108
108
  /**
109
109
  * Creates a parser that combines two mutually exclusive parsers into one.
@@ -102,8 +102,8 @@ interface OrErrorOptions {
102
102
  */
103
103
  declare class DuplicateOptionError extends Error {
104
104
  readonly optionName: string;
105
- readonly sources: string[];
106
- constructor(optionName: string, sources: string[]);
105
+ readonly sources: readonly (string | symbol)[];
106
+ constructor(optionName: string, sources: readonly (string | symbol)[]);
107
107
  }
108
108
  /**
109
109
  * Creates a parser that combines two mutually exclusive parsers into one.
@@ -73,7 +73,8 @@ function analyzeNoMatchContext(parsers) {
73
73
  */
74
74
  var DuplicateOptionError = class extends Error {
75
75
  constructor(optionName$1, sources) {
76
- super(`Duplicate option name "${optionName$1}" found in fields: ${sources.join(", ")}. Each option name must be unique within a parser combinator.`);
76
+ const sourceNames = sources.map((s) => typeof s === "symbol" ? s.description ?? s.toString() : s);
77
+ super(`Duplicate option name "${optionName$1}" found in fields: ${sourceNames.join(", ")}. Each option name must be unique within a parser combinator.`);
77
78
  this.optionName = optionName$1;
78
79
  this.sources = sources;
79
80
  this.name = "DuplicateOptionError";
@@ -541,11 +542,14 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
541
542
  parsers = labelOrParsers;
542
543
  options = maybeParsersOrOptions ?? {};
543
544
  }
544
- const parserPairs = Object.entries(parsers);
545
+ const parserKeys = Reflect.ownKeys(parsers);
546
+ const parserPairs = parserKeys.map((k) => [k, parsers[k]]);
545
547
  parserPairs.sort(([_, parserA], [__, parserB]) => parserB.priority - parserA.priority);
548
+ const initialState = {};
549
+ for (const key of parserKeys) initialState[key] = parsers[key].initialState;
546
550
  if (!options.allowDuplicates) checkDuplicateOptionNames(parserPairs.map(([field, parser]) => [field, parser.usage]));
547
- const noMatchContext = analyzeNoMatchContext(Object.values(parsers));
548
- const combinedMode = Object.values(parsers).some((p) => p.$mode === "async") ? "async" : "sync";
551
+ const noMatchContext = analyzeNoMatchContext(parserKeys.map((k) => parsers[k]));
552
+ const combinedMode = parserKeys.some((k) => parsers[k].$mode === "async") ? "async" : "sync";
549
553
  const isAsync = combinedMode === "async";
550
554
  const getInitialError = (context) => ({
551
555
  consumed: 0,
@@ -677,9 +681,9 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
677
681
  $mode: combinedMode,
678
682
  $valueType: [],
679
683
  $stateType: [],
680
- priority: Math.max(...Object.values(parsers).map((p) => p.priority)),
684
+ priority: Math.max(...parserKeys.map((k) => parsers[k].priority)),
681
685
  usage: parserPairs.flatMap(([_, p]) => p.usage),
682
- initialState: Object.fromEntries(Object.entries(parsers).map(([key, parser]) => [key, parser.initialState])),
686
+ initialState,
683
687
  parse(context) {
684
688
  if (isAsync) return parseAsync(context);
685
689
  return parseSync(context);
@@ -687,10 +691,8 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
687
691
  complete(state) {
688
692
  if (!isAsync) {
689
693
  const result = {};
690
- const stateRecord = state;
691
- for (const field in stateRecord) {
692
- if (!(field in parsers)) continue;
693
- const valueResult = parsers[field].complete(stateRecord[field]);
694
+ for (const field of parserKeys) {
695
+ const valueResult = parsers[field].complete(state[field]);
694
696
  if (valueResult.success) result[field] = valueResult.value;
695
697
  else return {
696
698
  success: false,
@@ -704,10 +706,8 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
704
706
  }
705
707
  return (async () => {
706
708
  const result = {};
707
- const stateRecord = state;
708
- for (const field in stateRecord) {
709
- if (!(field in parsers)) continue;
710
- const valueResult = await parsers[field].complete(stateRecord[field]);
709
+ for (const field of parserKeys) {
710
+ const valueResult = await parsers[field].complete(state[field]);
711
711
  if (valueResult.success) result[field] = valueResult.value;
712
712
  else return {
713
713
  success: false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/core",
3
- "version": "0.9.0-dev.206+78abd1b3",
3
+ "version": "0.9.0-dev.212+a3f282b6",
4
4
  "description": "Type-safe combinatorial command-line interface parser",
5
5
  "keywords": [
6
6
  "CLI",