roll-parser 3.0.0-beta.0 → 3.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 (159) hide show
  1. package/CHANGELOG.md +107 -9
  2. package/MIGRATION.md +147 -0
  3. package/README.md +960 -154
  4. package/dist/cli/args.d.ts +1 -0
  5. package/dist/cli/args.d.ts.map +1 -1
  6. package/dist/cli/args.js +81 -0
  7. package/dist/cli/args.js.map +1 -0
  8. package/dist/cli/format.d.ts +15 -3
  9. package/dist/cli/format.d.ts.map +1 -1
  10. package/dist/cli/format.js +17 -0
  11. package/dist/cli/format.js.map +1 -0
  12. package/dist/cli/index.d.ts +3 -0
  13. package/dist/cli/index.d.ts.map +1 -1
  14. package/dist/cli/index.js +14 -0
  15. package/dist/cli/index.js.map +1 -0
  16. package/dist/cli/main.d.ts +36 -0
  17. package/dist/cli/main.d.ts.map +1 -0
  18. package/dist/cli/main.js +83 -0
  19. package/dist/cli/main.js.map +1 -0
  20. package/dist/errors.d.ts +332 -17
  21. package/dist/errors.d.ts.map +1 -1
  22. package/dist/errors.js +141 -0
  23. package/dist/errors.js.map +1 -0
  24. package/dist/evaluator/die.d.ts +26 -0
  25. package/dist/evaluator/die.d.ts.map +1 -0
  26. package/dist/evaluator/die.js +19 -0
  27. package/dist/evaluator/die.js.map +1 -0
  28. package/dist/evaluator/env.d.ts +58 -0
  29. package/dist/evaluator/env.d.ts.map +1 -0
  30. package/dist/evaluator/env.js +11 -0
  31. package/dist/evaluator/env.js.map +1 -0
  32. package/dist/evaluator/evaluator.d.ts +41 -75
  33. package/dist/evaluator/evaluator.d.ts.map +1 -1
  34. package/dist/evaluator/evaluator.js +906 -0
  35. package/dist/evaluator/evaluator.js.map +1 -0
  36. package/dist/evaluator/modifiers/compare.js +15 -0
  37. package/dist/evaluator/modifiers/compare.js.map +1 -0
  38. package/dist/evaluator/modifiers/crit-threshold.d.ts +0 -1
  39. package/dist/evaluator/modifiers/crit-threshold.d.ts.map +1 -1
  40. package/dist/evaluator/modifiers/crit-threshold.js +23 -0
  41. package/dist/evaluator/modifiers/crit-threshold.js.map +1 -0
  42. package/dist/evaluator/modifiers/die-bound.d.ts +26 -0
  43. package/dist/evaluator/modifiers/die-bound.d.ts.map +1 -0
  44. package/dist/evaluator/modifiers/die-bound.js +14 -0
  45. package/dist/evaluator/modifiers/die-bound.js.map +1 -0
  46. package/dist/evaluator/modifiers/explode.d.ts +13 -5
  47. package/dist/evaluator/modifiers/explode.d.ts.map +1 -1
  48. package/dist/evaluator/modifiers/explode.js +103 -0
  49. package/dist/evaluator/modifiers/explode.js.map +1 -0
  50. package/dist/evaluator/modifiers/flags.d.ts +37 -0
  51. package/dist/evaluator/modifiers/flags.d.ts.map +1 -0
  52. package/dist/evaluator/modifiers/flags.js +18 -0
  53. package/dist/evaluator/modifiers/flags.js.map +1 -0
  54. package/dist/evaluator/modifiers/keep-drop.d.ts +12 -28
  55. package/dist/evaluator/modifiers/keep-drop.d.ts.map +1 -1
  56. package/dist/evaluator/modifiers/keep-drop.js +82 -0
  57. package/dist/evaluator/modifiers/keep-drop.js.map +1 -0
  58. package/dist/evaluator/modifiers/reroll.d.ts +12 -4
  59. package/dist/evaluator/modifiers/reroll.d.ts.map +1 -1
  60. package/dist/evaluator/modifiers/reroll.js +62 -0
  61. package/dist/evaluator/modifiers/reroll.js.map +1 -0
  62. package/dist/evaluator/modifiers/sort.d.ts +4 -0
  63. package/dist/evaluator/modifiers/sort.d.ts.map +1 -1
  64. package/dist/evaluator/modifiers/sort.js +13 -0
  65. package/dist/evaluator/modifiers/sort.js.map +1 -0
  66. package/dist/evaluator/modifiers/success-count.d.ts +2 -6
  67. package/dist/evaluator/modifiers/success-count.d.ts.map +1 -1
  68. package/dist/evaluator/modifiers/success-count.js +24 -0
  69. package/dist/evaluator/modifiers/success-count.js.map +1 -0
  70. package/dist/index.d.ts +33 -11
  71. package/dist/index.d.ts.map +1 -1
  72. package/dist/index.js +12 -2560
  73. package/dist/index.js.map +1 -26
  74. package/dist/lexer/lexer.d.ts +50 -5
  75. package/dist/lexer/lexer.d.ts.map +1 -1
  76. package/dist/lexer/lexer.js +260 -0
  77. package/dist/lexer/lexer.js.map +1 -0
  78. package/dist/lexer/tokens.d.ts +31 -6
  79. package/dist/lexer/tokens.d.ts.map +1 -1
  80. package/dist/lexer/tokens.js +42 -0
  81. package/dist/lexer/tokens.js.map +1 -0
  82. package/dist/parser/ast.d.ts +314 -160
  83. package/dist/parser/ast.d.ts.map +1 -1
  84. package/dist/parser/ast.js +52 -0
  85. package/dist/parser/ast.js.map +1 -0
  86. package/dist/parser/guards.d.ts +106 -0
  87. package/dist/parser/guards.d.ts.map +1 -0
  88. package/dist/parser/guards.js +121 -0
  89. package/dist/parser/guards.js.map +1 -0
  90. package/dist/parser/parser.d.ts +118 -14
  91. package/dist/parser/parser.d.ts.map +1 -1
  92. package/dist/parser/parser.js +751 -0
  93. package/dist/parser/parser.js.map +1 -0
  94. package/dist/rng/mock.d.ts +73 -12
  95. package/dist/rng/mock.d.ts.map +1 -1
  96. package/dist/rng/mock.js +30 -0
  97. package/dist/rng/mock.js.map +1 -0
  98. package/dist/rng/seeded.d.ts +141 -9
  99. package/dist/rng/seeded.d.ts.map +1 -1
  100. package/dist/rng/seeded.js +138 -0
  101. package/dist/rng/seeded.js.map +1 -0
  102. package/dist/rng/types.d.ts +57 -0
  103. package/dist/rng/types.d.ts.map +1 -1
  104. package/dist/rng/types.js +2 -0
  105. package/dist/rng/types.js.map +1 -0
  106. package/dist/roll.d.ts +58 -28
  107. package/dist/roll.d.ts.map +1 -1
  108. package/dist/roll.js +8 -0
  109. package/dist/roll.js.map +1 -0
  110. package/dist/testing.d.ts +5 -4
  111. package/dist/testing.d.ts.map +1 -1
  112. package/dist/testing.js +2 -41
  113. package/dist/testing.js.map +1 -11
  114. package/dist/types.d.ts +306 -44
  115. package/dist/types.d.ts.map +1 -1
  116. package/dist/types.js +8 -0
  117. package/dist/types.js.map +1 -0
  118. package/dist/version.d.ts +2 -0
  119. package/dist/version.d.ts.map +1 -0
  120. package/dist/version.js +2 -0
  121. package/dist/version.js.map +1 -0
  122. package/package.json +83 -34
  123. package/src/cli/args.ts +66 -10
  124. package/src/cli/format.ts +22 -3
  125. package/src/cli/index.ts +27 -84
  126. package/src/cli/main.ts +129 -0
  127. package/src/errors.ts +480 -27
  128. package/src/evaluator/die.ts +50 -0
  129. package/src/evaluator/env.ts +73 -0
  130. package/src/evaluator/evaluator.ts +653 -421
  131. package/src/evaluator/modifiers/crit-threshold.ts +3 -6
  132. package/src/evaluator/modifiers/die-bound.ts +39 -0
  133. package/src/evaluator/modifiers/explode.ts +60 -58
  134. package/src/evaluator/modifiers/flags.ts +61 -0
  135. package/src/evaluator/modifiers/keep-drop.ts +124 -126
  136. package/src/evaluator/modifiers/reroll.ts +28 -49
  137. package/src/evaluator/modifiers/sort.ts +14 -1
  138. package/src/evaluator/modifiers/success-count.ts +5 -8
  139. package/src/index.ts +56 -35
  140. package/src/lexer/lexer.ts +107 -34
  141. package/src/lexer/tokens.ts +31 -6
  142. package/src/parser/ast.ts +323 -341
  143. package/src/parser/guards.ts +248 -0
  144. package/src/parser/parser.ts +419 -242
  145. package/src/rng/mock.ts +74 -13
  146. package/src/rng/seeded.ts +299 -64
  147. package/src/rng/types.ts +57 -0
  148. package/src/roll.ts +64 -47
  149. package/src/testing.ts +5 -9
  150. package/src/types.ts +310 -43
  151. package/src/version.ts +2 -0
  152. package/dist/cli.js +0 -2608
  153. package/dist/cli.js.map +0 -28
  154. package/dist/evaluator/index.d.ts +0 -8
  155. package/dist/evaluator/index.d.ts.map +0 -1
  156. package/dist/rng/index.d.ts +0 -8
  157. package/dist/rng/index.d.ts.map +0 -1
  158. package/src/evaluator/index.ts +0 -14
  159. package/src/rng/index.ts +0 -8
@@ -11,6 +11,7 @@
11
11
  export type CliArgs = {
12
12
  notation: string | undefined;
13
13
  verbose: boolean;
14
+ json: boolean;
14
15
  seed: string | undefined;
15
16
  showHelp: boolean;
16
17
  showVersion: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzF;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,eAAe,CA0CzD"}
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AA0CzF;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,eAAe,CAyDzD"}
@@ -0,0 +1,81 @@
1
+ const TERMINATOR = '--';
2
+ const BASE_ARGS = {
3
+ notation: undefined,
4
+ verbose: false,
5
+ json: false,
6
+ seed: undefined,
7
+ showHelp: false,
8
+ showVersion: false,
9
+ };
10
+ function findInformationalFlag(argv) {
11
+ let flag;
12
+ for (const arg of argv) {
13
+ if (arg === TERMINATOR)
14
+ break;
15
+ if (arg === '--help' || arg === '-h')
16
+ return 'help';
17
+ if (arg === '--version')
18
+ flag = 'version';
19
+ }
20
+ return flag;
21
+ }
22
+ function isNegativeNotation(arg) {
23
+ return arg.length > 1 && /^[\ddD({@]/.test(arg.slice(1));
24
+ }
25
+ export function parseArgs(argv) {
26
+ const informational = findInformationalFlag(argv);
27
+ if (informational != null) {
28
+ return {
29
+ ok: true,
30
+ args: {
31
+ ...BASE_ARGS,
32
+ showHelp: informational === 'help',
33
+ showVersion: informational === 'version',
34
+ },
35
+ };
36
+ }
37
+ let verbose = false;
38
+ let json = false;
39
+ let seed;
40
+ const positional = [];
41
+ for (let i = 0; i < argv.length; i++) {
42
+ const arg = argv[i];
43
+ if (arg === TERMINATOR) {
44
+ positional.push(...argv.slice(i + 1));
45
+ break;
46
+ }
47
+ else if (arg === '--verbose' || arg === '-v') {
48
+ verbose = true;
49
+ }
50
+ else if (arg === '--json') {
51
+ json = true;
52
+ }
53
+ else if (arg === '--seed') {
54
+ const next = argv[i + 1];
55
+ if (next == null || next === '') {
56
+ return { ok: false, error: 'Missing value for --seed' };
57
+ }
58
+ seed = next;
59
+ i++;
60
+ }
61
+ else if (arg.startsWith('--seed=')) {
62
+ const value = arg.slice('--seed='.length);
63
+ if (value === '') {
64
+ return { ok: false, error: 'Missing value for --seed' };
65
+ }
66
+ seed = value;
67
+ }
68
+ else if (arg.startsWith('--')) {
69
+ return { ok: false, error: `Unknown option: ${arg}` };
70
+ }
71
+ else if (arg.startsWith('-') && !isNegativeNotation(arg)) {
72
+ return { ok: false, error: `Unknown option: ${arg}` };
73
+ }
74
+ else {
75
+ positional.push(arg);
76
+ }
77
+ }
78
+ const notation = positional.length > 0 ? positional.join(' ') : undefined;
79
+ return { ok: true, args: { ...BASE_ARGS, notation, verbose, json, seed } };
80
+ }
81
+ //# sourceMappingURL=args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"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"}
@@ -6,15 +6,27 @@
6
6
  * @module cli/format
7
7
  */
8
8
  import type { RollResult } from '../types.js';
9
+ /**
10
+ * Output mode selectors for {@link formatResult}.
11
+ */
12
+ export type FormatOptions = {
13
+ /** Emit the whole result as compact JSON. Takes precedence over `verbose`. */
14
+ json?: boolean;
15
+ /** Show the detailed roll breakdown instead of the bare total. */
16
+ verbose?: boolean;
17
+ };
9
18
  /**
10
19
  * Formats a roll result for terminal display.
11
20
  *
12
21
  * In normal mode, returns just the total. In verbose mode, returns the
13
- * rendered breakdown with terminal-safe formatting for dropped dice.
22
+ * rendered breakdown with terminal-safe formatting for dropped dice. In JSON
23
+ * mode, returns the complete `RollResult` — including the structured `parts`
24
+ * tree — as a single-line `JSON.stringify` payload, where `degree` appears as
25
+ * its numeric `DegreeOfSuccess` value.
14
26
  *
15
27
  * @param result - The roll result to format
16
- * @param verbose - Whether to show the detailed breakdown
28
+ * @param options - Output mode; JSON wins when combined with verbose
17
29
  * @returns Formatted string for terminal output
18
30
  */
19
- export declare function formatResult(result: RollResult, verbose: boolean): string;
31
+ export declare function formatResult(result: RollResult, options?: FormatOptions): string;
20
32
  //# sourceMappingURL=format.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/cli/format.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAMzE"}
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/cli/format.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,8EAA8E;IAC9E,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,kEAAkE;IAClE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAYpF"}
@@ -0,0 +1,17 @@
1
+ export function formatResult(result, options = {}) {
2
+ const { json = false, verbose = false } = options;
3
+ if (json) {
4
+ return JSON.stringify(result);
5
+ }
6
+ if (!verbose) {
7
+ return String(result.total);
8
+ }
9
+ return formatRendered(result.rendered);
10
+ }
11
+ function formatRendered(rendered) {
12
+ return rendered
13
+ .replace(/\*\*(-?\d+)\*\*/g, '[$1]')
14
+ .replace(/__(-?\d+)__/g, '{$1}')
15
+ .replace(/~~([^~]+)~~/g, '($1)');
16
+ }
17
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/cli/format.ts"],"names":[],"mappings":"AAiCA,MAAM,UAAU,YAAY,CAAC,MAAkB,EAAE,OAAO,GAAkB,EAAE;IAC1E,MAAM,EAAE,IAAI,GAAG,KAAK,EAAE,OAAO,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IAElD,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAChC,CAAC;IAED,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AACzC,CAAC;AAiBD,SAAS,cAAc,CAAC,QAAgB;IACtC,OAAO,QAAQ;SACZ,OAAO,CAAC,kBAAkB,EAAE,MAAM,CAAC;SACnC,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC;SAC/B,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;AACrC,CAAC"}
@@ -2,6 +2,9 @@
2
2
  /**
3
3
  * CLI entry point for roll-parser.
4
4
  *
5
+ * Owns the process-level wiring only; the command itself lives in
6
+ * `./main.js` so it stays testable without spawning a subprocess.
7
+ *
5
8
  * @module cli/index
6
9
  */
7
10
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AAEA;;;;GAIG"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG"}
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ import { main } from './main.js';
3
+ const exitCode = main({
4
+ argv: process.argv.slice(2),
5
+ stdout: (text) => {
6
+ process.stdout.write(text);
7
+ },
8
+ stderr: (text) => {
9
+ process.stderr.write(text);
10
+ },
11
+ });
12
+ if (exitCode !== 0)
13
+ process.exitCode = exitCode;
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AAWA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAWjC,MAAM,QAAQ,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3B,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;QACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IACD,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;QACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;CACF,CAAC,CAAC;AAIH,IAAI,QAAQ,KAAK,CAAC;IAAE,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * CLI command implementation for roll-parser.
3
+ *
4
+ * Split out of `index.ts` so `main` and `writeErrorContext` can run
5
+ * in-process under the test runner — the shebang entry point stays a thin
6
+ * wrapper that owns `process.argv`, the real streams, and `process.exitCode`.
7
+ *
8
+ * @module cli/main
9
+ */
10
+ /** Sink for one stream's worth of CLI output. */
11
+ export type WriteFn = (text: string) => void;
12
+ /** Everything `main` needs from the host process. */
13
+ export type CliEnv = {
14
+ /** Arguments after the interpreter and script path (`process.argv.slice(2)`). */
15
+ argv: string[];
16
+ stdout: WriteFn;
17
+ stderr: WriteFn;
18
+ };
19
+ /**
20
+ * Prints the notation with a caret under the error position. `getErrorSpan`
21
+ * normalizes the lexer/parser `position` and the evaluator `start`/`end`
22
+ * shapes, so no duck-typing is needed here. Skipped for multi-line notations
23
+ * and out-of-range positions to keep the caret honest.
24
+ */
25
+ export declare function writeErrorContext(notation: string, error: unknown, write: WriteFn): void;
26
+ /**
27
+ * Runs one CLI invocation and returns the process exit code: `0` on success,
28
+ * `1` for a roll-parser error, `2` for a usage error. Anything that is not a
29
+ * `RollParserError` propagates so the runtime reports it with a stack.
30
+ *
31
+ * `--json` swaps the success payload only — diagnostics stay plain text on
32
+ * stderr and the exit codes are identical, so scripts can branch on the code
33
+ * before parsing stdout.
34
+ */
35
+ export declare function main(env: CliEnv): number;
36
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAsCH,iDAAiD;AACjD,MAAM,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;AAE7C,qDAAqD;AACrD,MAAM,MAAM,MAAM,GAAG;IACnB,iFAAiF;IACjF,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAWxF;AAED;;;;;;;;GAQG;AACH,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CA2CxC"}
@@ -0,0 +1,83 @@
1
+ import { getErrorSpan, isRollParserError } from '../errors.js';
2
+ import { VERSION } from '../index.js';
3
+ import { roll } from '../roll.js';
4
+ import { parseArgs } from './args.js';
5
+ import { formatResult } from './format.js';
6
+ const HELP_TEXT = `roll-parser v${VERSION}
7
+
8
+ Usage: roll-parser [options] [--] <notation>
9
+
10
+ Options:
11
+ -h, --help Show this help message
12
+ --version Show version number
13
+ -v, --verbose Show detailed roll breakdown
14
+ --json Print the whole result as compact JSON (wins over --verbose)
15
+ --seed <value> Use seed for reproducible rolls
16
+ -- Treat every following argument as notation
17
+
18
+ JSON output:
19
+ Emits the complete result, including the structured "parts" tree. The
20
+ "degree" field (DegreeOfSuccess) serializes as a number: 0 critical failure,
21
+ 1 failure, 2 success, 3 critical success. Errors stay plain text on stderr.
22
+
23
+ Exit codes:
24
+ 0 Success
25
+ 1 Roll or parse error
26
+ 2 Usage error
27
+
28
+ Examples:
29
+ roll-parser 2d6+3
30
+ roll-parser 4d6kh3 --verbose
31
+ roll-parser 4d6dl1 --seed "character-str"
32
+ roll-parser "1d20+7 vs 25" --json
33
+ roll-parser -- -1d6+3
34
+ `;
35
+ export function writeErrorContext(notation, error, write) {
36
+ const span = getErrorSpan(error);
37
+ if (span == null)
38
+ return;
39
+ if (notation.includes('\n') || span.start > notation.length)
40
+ return;
41
+ const column = [...notation.slice(0, span.start)].length;
42
+ write(` ${notation}\n`);
43
+ write(` ${' '.repeat(column)}^\n`);
44
+ }
45
+ export function main(env) {
46
+ const { argv, stdout, stderr } = env;
47
+ const parsed = parseArgs(argv);
48
+ if (!parsed.ok) {
49
+ stderr(`Error: ${parsed.error}\n`);
50
+ stderr('Run "roll-parser --help" for usage.\n');
51
+ return 2;
52
+ }
53
+ const { args } = parsed;
54
+ if (args.showHelp) {
55
+ stdout(HELP_TEXT);
56
+ return 0;
57
+ }
58
+ if (args.showVersion) {
59
+ stdout(`${VERSION}\n`);
60
+ return 0;
61
+ }
62
+ if (args.notation == null) {
63
+ stderr('Error: No dice notation provided.\n');
64
+ stderr('Run "roll-parser --help" for usage.\n');
65
+ return 2;
66
+ }
67
+ try {
68
+ const options = args.seed != null ? { seed: args.seed } : {};
69
+ const result = roll(args.notation, options);
70
+ const output = formatResult(result, { json: args.json, verbose: args.verbose });
71
+ stdout(`${output}\n`);
72
+ }
73
+ catch (error) {
74
+ if (isRollParserError(error)) {
75
+ stderr(`Error: ${error.message}\n`);
76
+ writeErrorContext(args.notation, error, stderr);
77
+ return 1;
78
+ }
79
+ throw error;
80
+ }
81
+ return 0;
82
+ }
83
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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"}