@platonic-dice/core 2.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 (51) hide show
  1. package/README.md +57 -0
  2. package/dist/entities/DieType.d.ts +35 -0
  3. package/dist/entities/DieType.d.ts.map +1 -0
  4. package/dist/entities/DieType.js +43 -0
  5. package/dist/entities/Outcome.d.ts +26 -0
  6. package/dist/entities/Outcome.d.ts.map +1 -0
  7. package/dist/entities/Outcome.js +37 -0
  8. package/dist/entities/RollModifier.d.ts +115 -0
  9. package/dist/entities/RollModifier.d.ts.map +1 -0
  10. package/dist/entities/RollModifier.js +147 -0
  11. package/dist/entities/RollType.d.ts +24 -0
  12. package/dist/entities/RollType.d.ts.map +1 -0
  13. package/dist/entities/RollType.js +35 -0
  14. package/dist/entities/TestConditions.d.ts +97 -0
  15. package/dist/entities/TestConditions.d.ts.map +1 -0
  16. package/dist/entities/TestConditions.js +324 -0
  17. package/dist/entities/TestType.d.ts +28 -0
  18. package/dist/entities/TestType.d.ts.map +1 -0
  19. package/dist/entities/TestType.js +39 -0
  20. package/dist/entities/index.d.ts +16 -0
  21. package/dist/entities/index.d.ts.map +1 -0
  22. package/dist/entities/index.js +46 -0
  23. package/dist/index.d.ts +5 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +42 -0
  26. package/dist/roll.d.ts +66 -0
  27. package/dist/roll.d.ts.map +1 -0
  28. package/dist/roll.js +135 -0
  29. package/dist/rollDice.d.ts +48 -0
  30. package/dist/rollDice.d.ts.map +1 -0
  31. package/dist/rollDice.js +92 -0
  32. package/dist/rollDiceMod.d.ts +54 -0
  33. package/dist/rollDiceMod.d.ts.map +1 -0
  34. package/dist/rollDiceMod.js +137 -0
  35. package/dist/rollMod.d.ts +52 -0
  36. package/dist/rollMod.d.ts.map +1 -0
  37. package/dist/rollMod.js +114 -0
  38. package/dist/rollTest.d.ts +40 -0
  39. package/dist/rollTest.d.ts.map +1 -0
  40. package/dist/rollTest.js +100 -0
  41. package/dist/utils/determineOutcome.d.ts +45 -0
  42. package/dist/utils/determineOutcome.d.ts.map +1 -0
  43. package/dist/utils/determineOutcome.js +115 -0
  44. package/dist/utils/generateResult.d.ts +30 -0
  45. package/dist/utils/generateResult.d.ts.map +1 -0
  46. package/dist/utils/generateResult.js +51 -0
  47. package/dist/utils/index.d.ts +5 -0
  48. package/dist/utils/index.d.ts.map +1 -0
  49. package/dist/utils/index.js +26 -0
  50. package/dist-types.d.ts +48 -0
  51. package/package.json +46 -0
package/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # @platonic-dice/core
2
+
3
+ Core JavaScript/TypeScript library providing dice-roll logic, modifiers, and test evaluation for tabletop RPGs.
4
+
5
+ This package contains the pure logic used by higher-level packages (for example `@platonic-dice/dice`). It exports rolling helpers, entities (die types, roll types, outcomes), and utility functions.
6
+
7
+ ## Installation
8
+
9
+ Install from npm:
10
+
11
+ ```bash
12
+ npm install @platonic-dice/core
13
+ ```
14
+
15
+ ## Quick usage
16
+
17
+ CommonJS:
18
+
19
+ ```js
20
+ const { roll, rollDice, DieType, RollType } = require('@platonic-dice/core');
21
+
22
+ console.log( roll(DieType.D20) );
23
+ console.log( rollDice(DieType.D6, { count: 3 }) );
24
+ ```
25
+
26
+ ESM / TypeScript:
27
+
28
+ ```ts
29
+ import { roll, DieType } from '@platonic-dice/core';
30
+ console.log( roll(DieType.D20) );
31
+ ```
32
+
33
+ ## Build & Test
34
+
35
+ This package's sources live under `src/`. To run tests or build from the monorepo root:
36
+
37
+ ```bash
38
+ # from repo root
39
+ npm run build
40
+ npm test
41
+ ```
42
+
43
+ Or run package-local scripts:
44
+
45
+ ```bash
46
+ cd packages/core
47
+ # run unit tests
48
+ npm test
49
+ ```
50
+
51
+ ## Contributing
52
+
53
+ See the repository root `README.md` for contribution guidelines. Keep changes backwards-compatible where possible and include tests.
54
+
55
+ ## License
56
+
57
+ MIT — see the repository `LICENSE` file.
@@ -0,0 +1,35 @@
1
+ export type DieTypeKey = keyof typeof DieType;
2
+ export type DieTypeValue = (typeof DieType)[keyof typeof DieType];
3
+ /**
4
+ * *
5
+ */
6
+ export type DieType = string;
7
+ /**
8
+ * @module @platonic-dice/core/src/entities/DieType
9
+ * @description
10
+ * Enum for die types used in rolling functions.
11
+ *
12
+ * @readonly
13
+ * @enum {string}
14
+ *
15
+ * @example
16
+ * import { DieType } from "@platonic-dice/core/src/entities";
17
+ * const result = roll(DieType.D20);
18
+ */
19
+ export const DieType: Readonly<{
20
+ D4: "d4";
21
+ D6: "d6";
22
+ D8: "d8";
23
+ D10: "d10";
24
+ D12: "d12";
25
+ D20: "d20";
26
+ }>;
27
+ /**
28
+ * Checks whether a given value is a valid `DieType`.
29
+ *
30
+ * @function isValidDieType
31
+ * @param {DieTypeValue | null | undefined} dieType
32
+ * @returns {boolean}
33
+ */
34
+ export function isValidDieType(dieType: DieTypeValue | null | undefined): boolean;
35
+ //# sourceMappingURL=DieType.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DieType.d.ts","sourceRoot":"","sources":["../../src/entities/DieType.js"],"names":[],"mappings":"yBAmCa,MAAM,OAAO,OAAO;2BACpB,CAAA,OAAO,OAAO,EAAC,MAAM,OAAO,OAAO,CAAC;;;;sBA7BvC,MAAM;AANhB;;;;;;;;;;;GAWG;AACH;;;;;;;GAOG;AAEH;;;;;;GAMG;AACH,wCAHW,YAAY,GAAG,IAAI,GAAG,SAAS,GAC7B,OAAO,CAKnB"}
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ /**
3
+ * @module @platonic-dice/core/src/entities/DieType
4
+ * @description
5
+ * Enum for die types used in rolling functions.
6
+ *
7
+ * @readonly
8
+ * @enum {string}
9
+ *
10
+ * @example
11
+ * import { DieType } from "@platonic-dice/core/src/entities";
12
+ * const result = roll(DieType.D20);
13
+ */
14
+ const DieType = Object.freeze({
15
+ D4: "d4",
16
+ D6: "d6",
17
+ D8: "d8",
18
+ D10: "d10",
19
+ D12: "d12",
20
+ D20: "d20",
21
+ });
22
+
23
+ /**
24
+ * Checks whether a given value is a valid `DieType`.
25
+ *
26
+ * @function isValidDieType
27
+ * @param {DieTypeValue | null | undefined} dieType
28
+ * @returns {boolean}
29
+ */
30
+ function isValidDieType(dieType) {
31
+ if (!dieType) return false;
32
+ return Object.values(DieType).includes(dieType);
33
+ }
34
+
35
+ /**
36
+ * @typedef {keyof typeof DieType} DieTypeKey
37
+ * @typedef {typeof DieType[keyof typeof DieType]} DieTypeValue
38
+ */
39
+
40
+ module.exports = {
41
+ DieType,
42
+ isValidDieType,
43
+ };
@@ -0,0 +1,26 @@
1
+ export type OutcomeKey = keyof typeof Outcome;
2
+ export type OutcomeValue = (typeof Outcome)[keyof typeof Outcome];
3
+ export type Outcome = string;
4
+ /**
5
+ * @module @platonic-dice/core/src/entities/Outcome
6
+ * @description
7
+ * Enum for possible roll outcomes.
8
+ *
9
+ * @readonly
10
+ * @enum {string}
11
+ */
12
+ export const Outcome: Readonly<{
13
+ Success: "success";
14
+ Failure: "failure";
15
+ CriticalSuccess: "critical_success";
16
+ CriticalFailure: "critical_failure";
17
+ }>;
18
+ /**
19
+ * Checks whether a given value is a valid `Outcome`.
20
+ *
21
+ * @function isValidOutcome
22
+ * @param {OutcomeValue | null | undefined} outcome
23
+ * @returns {boolean}
24
+ */
25
+ export function isValidOutcome(outcome: OutcomeValue | null | undefined): boolean;
26
+ //# sourceMappingURL=Outcome.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Outcome.d.ts","sourceRoot":"","sources":["../../src/entities/Outcome.js"],"names":[],"mappings":"yBA6Ba,MAAM,OAAO,OAAO;2BACpB,CAAA,OAAO,OAAO,EAAC,MAAM,OAAO,OAAO,CAAC;sBAvBvC,MAAM;AANhB;;;;;;;GAOG;AACH;;;;;GAKG;AAEH;;;;;;GAMG;AACH,wCAHW,YAAY,GAAG,IAAI,GAAG,SAAS,GAC7B,OAAO,CAKnB"}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ /**
3
+ * @module @platonic-dice/core/src/entities/Outcome
4
+ * @description
5
+ * Enum for possible roll outcomes.
6
+ *
7
+ * @readonly
8
+ * @enum {string}
9
+ */
10
+ const Outcome = Object.freeze({
11
+ Success: "success",
12
+ Failure: "failure",
13
+ CriticalSuccess: "critical_success",
14
+ CriticalFailure: "critical_failure",
15
+ });
16
+
17
+ /**
18
+ * Checks whether a given value is a valid `Outcome`.
19
+ *
20
+ * @function isValidOutcome
21
+ * @param {OutcomeValue | null | undefined} outcome
22
+ * @returns {boolean}
23
+ */
24
+ function isValidOutcome(outcome) {
25
+ if (!outcome) return false;
26
+ return Object.values(Outcome).includes(outcome);
27
+ }
28
+
29
+ /**
30
+ * @typedef {keyof typeof Outcome} OutcomeKey
31
+ * @typedef {typeof Outcome[keyof typeof Outcome]} OutcomeValue
32
+ */
33
+
34
+ module.exports = {
35
+ Outcome,
36
+ isValidOutcome,
37
+ };
@@ -0,0 +1,115 @@
1
+ export type RollModifierFunction = (n: number) => number;
2
+ export type DiceModifier = {
3
+ /**
4
+ * Function or {@link RollModifier} applied to each individual die.
5
+ */
6
+ each?: RollModifierFunction | RollModifier | null | undefined;
7
+ /**
8
+ * Function or {@link RollModifier} applied to the total (sum) of all dice.
9
+ */
10
+ net?: RollModifierFunction | RollModifier | null | undefined;
11
+ };
12
+ export type RollModifierInstance = InstanceType<typeof RollModifier>;
13
+ /**
14
+ * @module @platonic-dice/core/src/entities/RollModifier
15
+ * @description
16
+ * Represents a numeric modifier applied to dice rolls.
17
+ *
18
+ * A `RollModifier` wraps a pure function `(n: number) => number`
19
+ * that takes a base roll and returns a modified value.
20
+ *
21
+ * @example
22
+ * const bonus = new RollModifier(n => n + 2);
23
+ * const result = bonus.apply(10); // 12
24
+ */
25
+ /**
26
+ * @typedef {(n: number) => number} RollModifierFunction
27
+ * @description
28
+ * A function that takes a single numeric input (the base roll or the total sum)
29
+ * and returns a numeric result. Implementations SHOULD:
30
+ * - declare exactly one parameter (helps static checks: `fn.length === 1`)
31
+ * - accept a number and return a number (ideally integer for dice use-cases)
32
+ *
33
+ * Examples:
34
+ * - Per-die modifier: `(n) => n + 1`
35
+ * - Net modifier: `(sum) => Math.floor(sum * 1.5)`
36
+ *
37
+ * Notes:
38
+ * - The runtime `isValidRollModifier` performs a light validation:
39
+ * checks the function arity and performs a test call `fn(1)` to ensure
40
+ * a numeric, integer-like result is returned. Keep modifiers pure.
41
+ */
42
+ /**
43
+ * @typedef {Object} DiceModifier
44
+ * @property {RollModifierFunction | RollModifier | null | undefined} [each]
45
+ * Function or {@link RollModifier} applied to each individual die.
46
+ * @property {RollModifierFunction | RollModifier | null | undefined} [net]
47
+ * Function or {@link RollModifier} applied to the total (sum) of all dice.
48
+ *
49
+ * @description
50
+ * Represents the composite modifier structure used by {@link rollDiceMod}.
51
+ * Each field is optional and defaults to the identity modifier if omitted.
52
+ *
53
+ * @example
54
+ * const modifier = {
55
+ * each: (n) => n + 1,
56
+ * net: (sum) => sum + 2,
57
+ * };
58
+ *
59
+ * const mod2 = {
60
+ * each: new RollModifier((n) => n * 2),
61
+ * };
62
+ */
63
+ /**
64
+ * Represents a numeric modifier applied to dice rolls.
65
+ */
66
+ export class RollModifier {
67
+ /**
68
+ * @param {RollModifierFunction} fn - Modifier function.
69
+ * @throws {TypeError} If the function is not a valid roll modifier.
70
+ */
71
+ constructor(fn: RollModifierFunction);
72
+ /** @type {RollModifierFunction} */
73
+ fn: RollModifierFunction;
74
+ /**
75
+ * Applies this modifier to a roll result.
76
+ * @param {number} baseValue - The base roll result.
77
+ * @returns {number} - The modified roll result.
78
+ */
79
+ apply(baseValue: number): number;
80
+ /**
81
+ * Validates that this modifier still conforms to spec.
82
+ * (Useful if modifiers are loaded dynamically or serialized.)
83
+ * @throws {TypeError} If the modifier is invalid.
84
+ */
85
+ validate(): void;
86
+ }
87
+ /**
88
+ * Checks whether a given function is a valid roll modifier.
89
+ *
90
+ * @function isValidRollModifier
91
+ * @param {Function | null} m
92
+ * @returns {boolean}
93
+ */
94
+ export function isValidRollModifier(m: Function | null): boolean;
95
+ /**
96
+ * This function ensures all modifiers conform to the correct structure:
97
+ * - A {@link RollModifier} instance → returned as-is.
98
+ * - A function `(n: number) => number` → wrapped in a new {@link RollModifier}.
99
+ * - `null` or `undefined` → treated as an identity modifier.
100
+ *
101
+ * @function normaliseRollModifier
102
+ * @param {RollModifier | ((n: number) => number) | null | undefined} m
103
+ * The input modifier to normalise.
104
+ * @returns {RollModifier}
105
+ * A valid {@link RollModifier} instance.
106
+ * @throws {TypeError}
107
+ * If the input is invalid (not a RollModifier, function, or null/undefined).
108
+ *
109
+ * @example
110
+ * const rm1 = normaliseRollModifier(); // → identity modifier
111
+ * const rm2 = normaliseRollModifier(x => x + 1); // → RollModifier wrapping function
112
+ * const rm3 = normaliseRollModifier(new RollModifier(x => x * 2)); // → same instance
113
+ */
114
+ export function normaliseRollModifier(m: RollModifier | ((n: number) => number) | null | undefined): RollModifier;
115
+ //# sourceMappingURL=RollModifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RollModifier.d.ts","sourceRoot":"","sources":["../../src/entities/RollModifier.js"],"names":[],"mappings":"mCAca,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM;;;;;WAmBpB,oBAAoB,GAAG,YAAY,GAAG,IAAI,GAAG,SAAS;;;;UAEtD,oBAAoB,GAAG,YAAY,GAAG,IAAI,GAAG,SAAS;;mCAwGvD,YAAY,CAAC,OAAO,YAAY,CAAC;AA3I9C;;;;;;;;;;;GAWG;AAEH;;;;;;;;;;;;;;;;GAgBG;AAEH;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH;;GAEG;AACH;IACE;;;OAGG;IACH,gBAHW,oBAAoB,EAY9B;IAFC,mCAAmC;IACnC,IADW,oBAAoB,CACnB;IAGd;;;;OAIG;IACH,iBAHW,MAAM,GACJ,MAAM,CAIlB;IAED;;;;OAIG;IACH,iBAIC;CACF;AAED;;;;;;GAMG;AACH,uCAHW,WAAW,IAAI,GACb,OAAO,CAWnB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,yCAZW,YAAY,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC,GAAG,IAAI,GAAG,SAAS,GAEvD,YAAY,CAgBxB"}
@@ -0,0 +1,147 @@
1
+ /**
2
+ * @module @platonic-dice/core/src/entities/RollModifier
3
+ * @description
4
+ * Represents a numeric modifier applied to dice rolls.
5
+ *
6
+ * A `RollModifier` wraps a pure function `(n: number) => number`
7
+ * that takes a base roll and returns a modified value.
8
+ *
9
+ * @example
10
+ * const bonus = new RollModifier(n => n + 2);
11
+ * const result = bonus.apply(10); // 12
12
+ */
13
+
14
+ /**
15
+ * @typedef {(n: number) => number} RollModifierFunction
16
+ * @description
17
+ * A function that takes a single numeric input (the base roll or the total sum)
18
+ * and returns a numeric result. Implementations SHOULD:
19
+ * - declare exactly one parameter (helps static checks: `fn.length === 1`)
20
+ * - accept a number and return a number (ideally integer for dice use-cases)
21
+ *
22
+ * Examples:
23
+ * - Per-die modifier: `(n) => n + 1`
24
+ * - Net modifier: `(sum) => Math.floor(sum * 1.5)`
25
+ *
26
+ * Notes:
27
+ * - The runtime `isValidRollModifier` performs a light validation:
28
+ * checks the function arity and performs a test call `fn(1)` to ensure
29
+ * a numeric, integer-like result is returned. Keep modifiers pure.
30
+ */
31
+
32
+ /**
33
+ * @typedef {Object} DiceModifier
34
+ * @property {RollModifierFunction | RollModifier | null | undefined} [each]
35
+ * Function or {@link RollModifier} applied to each individual die.
36
+ * @property {RollModifierFunction | RollModifier | null | undefined} [net]
37
+ * Function or {@link RollModifier} applied to the total (sum) of all dice.
38
+ *
39
+ * @description
40
+ * Represents the composite modifier structure used by {@link rollDiceMod}.
41
+ * Each field is optional and defaults to the identity modifier if omitted.
42
+ *
43
+ * @example
44
+ * const modifier = {
45
+ * each: (n) => n + 1,
46
+ * net: (sum) => sum + 2,
47
+ * };
48
+ *
49
+ * const mod2 = {
50
+ * each: new RollModifier((n) => n * 2),
51
+ * };
52
+ */
53
+
54
+ /**
55
+ * Represents a numeric modifier applied to dice rolls.
56
+ */
57
+ class RollModifier {
58
+ /**
59
+ * @param {RollModifierFunction} fn - Modifier function.
60
+ * @throws {TypeError} If the function is not a valid roll modifier.
61
+ */
62
+ constructor(fn) {
63
+ if (!isValidRollModifier(fn)) {
64
+ throw new TypeError(
65
+ "Invalid roll modifier: must be a function accepting one numeric argument and returning a number."
66
+ );
67
+ }
68
+
69
+ /** @type {RollModifierFunction} */
70
+ this.fn = fn;
71
+ }
72
+
73
+ /**
74
+ * Applies this modifier to a roll result.
75
+ * @param {number} baseValue - The base roll result.
76
+ * @returns {number} - The modified roll result.
77
+ */
78
+ apply(baseValue) {
79
+ return this.fn(baseValue);
80
+ }
81
+
82
+ /**
83
+ * Validates that this modifier still conforms to spec.
84
+ * (Useful if modifiers are loaded dynamically or serialized.)
85
+ * @throws {TypeError} If the modifier is invalid.
86
+ */
87
+ validate() {
88
+ if (!isValidRollModifier(this.fn)) {
89
+ throw new TypeError("Invalid roll modifier function shape.");
90
+ }
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Checks whether a given function is a valid roll modifier.
96
+ *
97
+ * @function isValidRollModifier
98
+ * @param {Function | null} m
99
+ * @returns {boolean}
100
+ */
101
+ function isValidRollModifier(m) {
102
+ if (!m || typeof m !== "function") return false;
103
+
104
+ /** ---Validate modifier shape --- */
105
+ if (m.length !== 1) return false; // Must declare exactly 1 parameter
106
+
107
+ // Quick runtime check: apply to a number and verify return is an integer.
108
+ const testValue = m(1);
109
+ return typeof testValue === "number" && Number.isInteger(testValue);
110
+ }
111
+
112
+ /**
113
+ * This function ensures all modifiers conform to the correct structure:
114
+ * - A {@link RollModifier} instance → returned as-is.
115
+ * - A function `(n: number) => number` → wrapped in a new {@link RollModifier}.
116
+ * - `null` or `undefined` → treated as an identity modifier.
117
+ *
118
+ * @function normaliseRollModifier
119
+ * @param {RollModifier | ((n: number) => number) | null | undefined} m
120
+ * The input modifier to normalise.
121
+ * @returns {RollModifier}
122
+ * A valid {@link RollModifier} instance.
123
+ * @throws {TypeError}
124
+ * If the input is invalid (not a RollModifier, function, or null/undefined).
125
+ *
126
+ * @example
127
+ * const rm1 = normaliseRollModifier(); // → identity modifier
128
+ * const rm2 = normaliseRollModifier(x => x + 1); // → RollModifier wrapping function
129
+ * const rm3 = normaliseRollModifier(new RollModifier(x => x * 2)); // → same instance
130
+ */
131
+ function normaliseRollModifier(m) {
132
+ if (!m) return new RollModifier((n) => n); // identity modifier
133
+ if (m instanceof RollModifier) return m;
134
+ if (typeof m === "function" && isValidRollModifier(m))
135
+ return new RollModifier(m);
136
+ throw new TypeError("Invalid RollModifier");
137
+ }
138
+
139
+ /**
140
+ * @typedef {InstanceType<typeof RollModifier>} RollModifierInstance
141
+ */
142
+
143
+ module.exports = {
144
+ RollModifier,
145
+ isValidRollModifier,
146
+ normaliseRollModifier,
147
+ };
@@ -0,0 +1,24 @@
1
+ export type RollTypeKey = keyof typeof RollType;
2
+ export type RollTypeValue = (typeof RollType)[keyof typeof RollType];
3
+ export type RollType = string;
4
+ /**
5
+ * @module @platonic-dice/core/src/entities/RollType
6
+ * @description
7
+ * Enum for roll modes (normal, advantage, disadvantage).
8
+ *
9
+ * @readonly
10
+ * @enum {string}
11
+ */
12
+ export const RollType: Readonly<{
13
+ Advantage: "advantage";
14
+ Disadvantage: "disadvantage";
15
+ }>;
16
+ /**
17
+ * Checks whether a given value is a valid `RollType`.
18
+ *
19
+ * @function isValidRollType
20
+ * @param {RollTypeValue | null | undefined} rollType
21
+ * @returns {boolean}
22
+ */
23
+ export function isValidRollType(rollType: RollTypeValue | null | undefined): boolean;
24
+ //# sourceMappingURL=RollType.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RollType.d.ts","sourceRoot":"","sources":["../../src/entities/RollType.js"],"names":[],"mappings":"0BA2Ba,MAAM,OAAO,QAAQ;4BACrB,CAAA,OAAO,QAAQ,EAAC,MAAM,OAAO,QAAQ,CAAC;uBArBzC,MAAM;AANhB;;;;;;;GAOG;AACH;;;GAGG;AAEH;;;;;;GAMG;AACH,0CAHW,aAAa,GAAG,IAAI,GAAG,SAAS,GAC9B,OAAO,CAKnB"}
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ /**
3
+ * @module @platonic-dice/core/src/entities/RollType
4
+ * @description
5
+ * Enum for roll modes (normal, advantage, disadvantage).
6
+ *
7
+ * @readonly
8
+ * @enum {string}
9
+ */
10
+ const RollType = Object.freeze({
11
+ Advantage: "advantage",
12
+ Disadvantage: "disadvantage",
13
+ });
14
+
15
+ /**
16
+ * Checks whether a given value is a valid `RollType`.
17
+ *
18
+ * @function isValidRollType
19
+ * @param {RollTypeValue | null | undefined} rollType
20
+ * @returns {boolean}
21
+ */
22
+ function isValidRollType(rollType) {
23
+ if (!rollType) return false;
24
+ return Object.values(RollType).includes(rollType);
25
+ }
26
+
27
+ /**
28
+ * @typedef {keyof typeof RollType} RollTypeKey
29
+ * @typedef {typeof RollType[keyof typeof RollType]} RollTypeValue
30
+ */
31
+
32
+ module.exports = {
33
+ RollType,
34
+ isValidRollType,
35
+ };
@@ -0,0 +1,97 @@
1
+ export type BaseTestCondition = {
2
+ dieType: DieTypeValue;
3
+ };
4
+ export type TargetConditions = BaseTestCondition & {
5
+ target: number;
6
+ };
7
+ export type WithinConditions = BaseTestCondition & {
8
+ min: number;
9
+ max: number;
10
+ };
11
+ export type SpecificListConditions = BaseTestCondition & {
12
+ values: number[];
13
+ };
14
+ export type SkillConditions = BaseTestCondition & {
15
+ target: number;
16
+ critical_success?: number;
17
+ critical_failure?: number;
18
+ };
19
+ export type TestTypeValue = import("./TestType").TestTypeValue;
20
+ export type DieTypeValue = import("./DieType").DieTypeValue;
21
+ /**
22
+ * Represents any valid dice roll test condition.
23
+ *
24
+ * This is a union type of all the internal test condition shapes:
25
+ * - `TargetConditions` – single target value
26
+ * - `SkillConditions` – target with optional critical thresholds
27
+ * - `WithinConditions` – min/max range
28
+ * - `SpecificListConditions` – array of specific allowed values
29
+ */
30
+ export type Conditions = TargetConditions | SkillConditions | WithinConditions | SpecificListConditions;
31
+ export type TestConditionsInstance = InstanceType<typeof TestConditions>;
32
+ /**
33
+ * @typedef {import("./TestType").TestTypeValue} TestTypeValue
34
+ * @typedef {import("./DieType").DieTypeValue} DieTypeValue
35
+ */
36
+ /**
37
+ * Represents a set of conditions for a dice roll test.
38
+ */
39
+ export class TestConditions {
40
+ /**
41
+ * @param {TestTypeValue} testType - The test type.
42
+ * @param {Conditions} conditions - The test conditions object.
43
+ * @param {DieTypeValue} dieType - The die type to validate numeric ranges.
44
+ * @throws {TypeError|RangeError} If the test type or conditions are invalid.
45
+ */
46
+ constructor(testType: TestTypeValue, conditions: Conditions, dieType: DieTypeValue);
47
+ /** @type {TestTypeValue} */
48
+ testType: TestTypeValue;
49
+ /** @type {Conditions} */
50
+ conditions: Conditions;
51
+ /** @type {DieTypeValue} */
52
+ dieType: DieTypeValue;
53
+ /**
54
+ * Validates that the test conditions still conforms to spec.
55
+ * (Useful if they are loaded dynamically or serialized.)
56
+ * @throws {TypeError} If the test conditions are invalid.
57
+ */
58
+ validate(): void;
59
+ }
60
+ /**
61
+ * Master validation function for all test conditions.
62
+ *
63
+ * @function areValidTestConditions
64
+ * @param {Conditions} c
65
+ * @param {TestTypeValue} testType
66
+ * @returns {boolean}
67
+ */
68
+ export function areValidTestConditions(c: Conditions, testType: TestTypeValue): boolean;
69
+ /**
70
+ * Normalises any input into a {@link TestConditions} instance.
71
+ * Supports both pre-existing instances and plain objects.
72
+ * Automatically validates all conditions for the specified die type.
73
+ *
74
+ * @function normaliseTestConditions
75
+ * @param {TestConditions | { testType: TestTypeValue, [key: string]: any }} tc
76
+ * A {@link TestConditions} instance or plain object with `testType` and other fields.
77
+ * @param {DieTypeValue} dieType
78
+ * The die type (e.g., `'d6'`, `'d20'`) used for validation.
79
+ * @returns {TestConditions}
80
+ * A validated {@link TestConditions} instance.
81
+ * @throws {TypeError}
82
+ * If the input is neither a TestConditions instance nor a plain object.
83
+ *
84
+ * @example
85
+ * // Passing a plain object
86
+ * const conditions = normaliseTestConditions({ testType: 'atLeast', target: 4 }, 'd6');
87
+ *
88
+ * @example
89
+ * // Passing an existing TestConditions instance
90
+ * const existing = new TestConditions('exact', { target: 3 }, 'd6');
91
+ * const conditions2 = normaliseTestConditions(existing, 'd6');
92
+ */
93
+ export function normaliseTestConditions(tc: TestConditions | {
94
+ testType: TestTypeValue;
95
+ [key: string]: any;
96
+ }, dieType: DieTypeValue): TestConditions;
97
+ //# sourceMappingURL=TestConditions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TestConditions.d.ts","sourceRoot":"","sources":["../../src/entities/TestConditions.js"],"names":[],"mappings":";aAiMc,YAAY;;+BAKb,iBAAiB,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE;+BAEtC,iBAAiB,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE;qCAEhD,iBAAiB,GAAG;IAAE,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE;8BAExC,iBAAiB,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAE;4BA5L5F,OAAO,YAAY,EAAE,aAAa;2BAClC,OAAO,WAAW,EAAE,YAAY;;;;;;;;;;yBA4JhC,gBAAgB,GAAG,eAAe,GAAG,gBAAgB,GAAG,sBAAsB;qCAI9E,YAAY,CAAC,OAAO,cAAc,CAAC;AAlKhD;;;GAGG;AAEH;;GAEG;AACH;IACE;;;;;OAKG;IACH,sBALW,aAAa,cACb,UAAU,WACV,YAAY,EAgDtB;IANC,4BAA4B;IAC5B,UADW,aAAa,CACA;IACxB,yBAAyB;IACzB,YADW,UAAU,CACO;IAC5B,2BAA2B;IAC3B,SADW,YAAY,CACD;IAGxB;;;;OAIG;IACH,iBASC;CACF;AAED;;;;;;;GAOG;AACH,0CAJW,UAAU,YACV,aAAa,GACX,OAAO,CAwBnB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,4CAlBW,cAAc,GAAG;IAAE,QAAQ,EAAE,aAAa,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,WAEhE,YAAY,GAEV,cAAc,CA0B1B"}