@dicelette/core 1.8.7 → 1.9.1
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/dist/index.d.mts +24 -8
- package/dist/index.d.ts +24 -8
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +4 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
@@ -39,7 +39,7 @@ interface Resultat {
|
|
39
39
|
/**
|
40
40
|
* The comparison made on the dice
|
41
41
|
*/
|
42
|
-
compare?:
|
42
|
+
compare?: ComparedValue;
|
43
43
|
/**
|
44
44
|
* If any value was added to the dice throw
|
45
45
|
*/
|
@@ -58,6 +58,12 @@ interface Compare {
|
|
58
58
|
* Value of the comparison
|
59
59
|
*/
|
60
60
|
value: number;
|
61
|
+
}
|
62
|
+
/**
|
63
|
+
* Sign format for calculation of modifier
|
64
|
+
*/
|
65
|
+
type Sign = "+" | "-" | "*" | "/" | "%" | "^" | "**";
|
66
|
+
type ComparedValue = Compare & {
|
61
67
|
/**
|
62
68
|
* Original dice if the comparaison is made with a dice throw
|
63
69
|
*/
|
@@ -66,11 +72,7 @@ interface Compare {
|
|
66
72
|
* Output of the dice throw
|
67
73
|
*/
|
68
74
|
rollValue?: string;
|
69
|
-
}
|
70
|
-
/**
|
71
|
-
* Sign format for calculation of modifier
|
72
|
-
*/
|
73
|
-
type Sign = "+" | "-" | "*" | "/" | "%" | "^" | "**";
|
75
|
+
};
|
74
76
|
interface Modifier {
|
75
77
|
/**
|
76
78
|
* Sign of the modifier
|
@@ -106,6 +108,10 @@ string, {
|
|
106
108
|
* Automatically disable the max/min value
|
107
109
|
*/
|
108
110
|
combinaison?: string;
|
111
|
+
/**
|
112
|
+
* Allow to exclude from roll selection in /dbroll!
|
113
|
+
*/
|
114
|
+
exclude?: boolean;
|
109
115
|
}>;
|
110
116
|
/**
|
111
117
|
* @example
|
@@ -194,8 +200,9 @@ declare function escapeRegex(string: string): string;
|
|
194
200
|
* Replace the stat name by their value using stat and after evaluate any formula using `replaceFormulaInDice`
|
195
201
|
* @param originalDice {dice}
|
196
202
|
* @param stats {Record<string,number>}
|
203
|
+
* @param dollarValue
|
197
204
|
*/
|
198
|
-
declare function generateStatsDice(originalDice: string, stats?: Record<string, number
|
205
|
+
declare function generateStatsDice(originalDice: string, stats?: Record<string, number>, dollarValue?: string): string;
|
199
206
|
/**
|
200
207
|
* Replace the {{}} in the dice string and evaluate the interior if any
|
201
208
|
* @param dice {string}
|
@@ -317,30 +324,37 @@ declare const templateSchema: z.ZodObject<{
|
|
317
324
|
max: z.ZodOptional<z.ZodNumber>;
|
318
325
|
min: z.ZodOptional<z.ZodNumber>;
|
319
326
|
combinaison: z.ZodOptional<z.ZodEffects<z.ZodString, string | undefined, string>>;
|
327
|
+
exclude: z.ZodOptional<z.ZodBoolean>;
|
320
328
|
}, "strip", z.ZodTypeAny, {
|
321
329
|
max?: number | undefined;
|
322
330
|
min?: number | undefined;
|
323
331
|
combinaison?: string | undefined;
|
332
|
+
exclude?: boolean | undefined;
|
324
333
|
}, {
|
325
334
|
max?: number | undefined;
|
326
335
|
min?: number | undefined;
|
327
336
|
combinaison?: string | undefined;
|
337
|
+
exclude?: boolean | undefined;
|
328
338
|
}>, {
|
329
339
|
max?: number | undefined;
|
330
340
|
min?: number | undefined;
|
331
341
|
combinaison?: string | undefined;
|
342
|
+
exclude?: boolean | undefined;
|
332
343
|
}, {
|
333
344
|
max?: number | undefined;
|
334
345
|
min?: number | undefined;
|
335
346
|
combinaison?: string | undefined;
|
347
|
+
exclude?: boolean | undefined;
|
336
348
|
}>>>, Record<string, {
|
337
349
|
max?: number | undefined;
|
338
350
|
min?: number | undefined;
|
339
351
|
combinaison?: string | undefined;
|
352
|
+
exclude?: boolean | undefined;
|
340
353
|
}> | undefined, Record<string, {
|
341
354
|
max?: number | undefined;
|
342
355
|
min?: number | undefined;
|
343
356
|
combinaison?: string | undefined;
|
357
|
+
exclude?: boolean | undefined;
|
344
358
|
}> | undefined>;
|
345
359
|
total: z.ZodOptional<z.ZodNumber>;
|
346
360
|
diceType: z.ZodOptional<z.ZodString>;
|
@@ -394,6 +408,7 @@ declare const templateSchema: z.ZodObject<{
|
|
394
408
|
max?: number | undefined;
|
395
409
|
min?: number | undefined;
|
396
410
|
combinaison?: string | undefined;
|
411
|
+
exclude?: boolean | undefined;
|
397
412
|
}> | undefined;
|
398
413
|
diceType?: string | undefined;
|
399
414
|
critical?: {
|
@@ -414,6 +429,7 @@ declare const templateSchema: z.ZodObject<{
|
|
414
429
|
max?: number | undefined;
|
415
430
|
min?: number | undefined;
|
416
431
|
combinaison?: string | undefined;
|
432
|
+
exclude?: boolean | undefined;
|
417
433
|
}> | undefined;
|
418
434
|
diceType?: string | undefined;
|
419
435
|
critical?: {
|
@@ -437,4 +453,4 @@ interface StatisticalSchema extends StatisticalTemplate {
|
|
437
453
|
$schema?: string;
|
438
454
|
}
|
439
455
|
|
440
|
-
export { COMMENT_REGEX, type Compare, type Critical, type CustomCritical, DiceTypeError, EmptyObjectError, FormulaError, MaxGreater, type Modifier, NoStatisticsError, type Resultat, SIGN_REGEX, SIGN_REGEX_SPACE, SYMBOL_DICE, type Sign, type Statistic, type StatisticalSchema, type StatisticalTemplate, TooManyDice, TooManyStats, calculator, cleanedDice, createCriticalCustom, diceRandomParse, diceTypeRandomParse, escapeRegex, evalCombinaison, evalOneCombinaison, evalStatsDice, generateRandomStat, generateStatsDice, replaceFormulaInDice, roll, templateSchema, testDiceRegistered, testStatCombinaison, verifyTemplateValue };
|
456
|
+
export { COMMENT_REGEX, type Compare, type ComparedValue, type Critical, type CustomCritical, DiceTypeError, EmptyObjectError, FormulaError, MaxGreater, type Modifier, NoStatisticsError, type Resultat, SIGN_REGEX, SIGN_REGEX_SPACE, SYMBOL_DICE, type Sign, type Statistic, type StatisticalSchema, type StatisticalTemplate, TooManyDice, TooManyStats, calculator, cleanedDice, createCriticalCustom, diceRandomParse, diceTypeRandomParse, escapeRegex, evalCombinaison, evalOneCombinaison, evalStatsDice, generateRandomStat, generateStatsDice, replaceFormulaInDice, roll, templateSchema, testDiceRegistered, testStatCombinaison, verifyTemplateValue };
|
package/dist/index.d.ts
CHANGED
@@ -39,7 +39,7 @@ interface Resultat {
|
|
39
39
|
/**
|
40
40
|
* The comparison made on the dice
|
41
41
|
*/
|
42
|
-
compare?:
|
42
|
+
compare?: ComparedValue;
|
43
43
|
/**
|
44
44
|
* If any value was added to the dice throw
|
45
45
|
*/
|
@@ -58,6 +58,12 @@ interface Compare {
|
|
58
58
|
* Value of the comparison
|
59
59
|
*/
|
60
60
|
value: number;
|
61
|
+
}
|
62
|
+
/**
|
63
|
+
* Sign format for calculation of modifier
|
64
|
+
*/
|
65
|
+
type Sign = "+" | "-" | "*" | "/" | "%" | "^" | "**";
|
66
|
+
type ComparedValue = Compare & {
|
61
67
|
/**
|
62
68
|
* Original dice if the comparaison is made with a dice throw
|
63
69
|
*/
|
@@ -66,11 +72,7 @@ interface Compare {
|
|
66
72
|
* Output of the dice throw
|
67
73
|
*/
|
68
74
|
rollValue?: string;
|
69
|
-
}
|
70
|
-
/**
|
71
|
-
* Sign format for calculation of modifier
|
72
|
-
*/
|
73
|
-
type Sign = "+" | "-" | "*" | "/" | "%" | "^" | "**";
|
75
|
+
};
|
74
76
|
interface Modifier {
|
75
77
|
/**
|
76
78
|
* Sign of the modifier
|
@@ -106,6 +108,10 @@ string, {
|
|
106
108
|
* Automatically disable the max/min value
|
107
109
|
*/
|
108
110
|
combinaison?: string;
|
111
|
+
/**
|
112
|
+
* Allow to exclude from roll selection in /dbroll!
|
113
|
+
*/
|
114
|
+
exclude?: boolean;
|
109
115
|
}>;
|
110
116
|
/**
|
111
117
|
* @example
|
@@ -194,8 +200,9 @@ declare function escapeRegex(string: string): string;
|
|
194
200
|
* Replace the stat name by their value using stat and after evaluate any formula using `replaceFormulaInDice`
|
195
201
|
* @param originalDice {dice}
|
196
202
|
* @param stats {Record<string,number>}
|
203
|
+
* @param dollarValue
|
197
204
|
*/
|
198
|
-
declare function generateStatsDice(originalDice: string, stats?: Record<string, number
|
205
|
+
declare function generateStatsDice(originalDice: string, stats?: Record<string, number>, dollarValue?: string): string;
|
199
206
|
/**
|
200
207
|
* Replace the {{}} in the dice string and evaluate the interior if any
|
201
208
|
* @param dice {string}
|
@@ -317,30 +324,37 @@ declare const templateSchema: z.ZodObject<{
|
|
317
324
|
max: z.ZodOptional<z.ZodNumber>;
|
318
325
|
min: z.ZodOptional<z.ZodNumber>;
|
319
326
|
combinaison: z.ZodOptional<z.ZodEffects<z.ZodString, string | undefined, string>>;
|
327
|
+
exclude: z.ZodOptional<z.ZodBoolean>;
|
320
328
|
}, "strip", z.ZodTypeAny, {
|
321
329
|
max?: number | undefined;
|
322
330
|
min?: number | undefined;
|
323
331
|
combinaison?: string | undefined;
|
332
|
+
exclude?: boolean | undefined;
|
324
333
|
}, {
|
325
334
|
max?: number | undefined;
|
326
335
|
min?: number | undefined;
|
327
336
|
combinaison?: string | undefined;
|
337
|
+
exclude?: boolean | undefined;
|
328
338
|
}>, {
|
329
339
|
max?: number | undefined;
|
330
340
|
min?: number | undefined;
|
331
341
|
combinaison?: string | undefined;
|
342
|
+
exclude?: boolean | undefined;
|
332
343
|
}, {
|
333
344
|
max?: number | undefined;
|
334
345
|
min?: number | undefined;
|
335
346
|
combinaison?: string | undefined;
|
347
|
+
exclude?: boolean | undefined;
|
336
348
|
}>>>, Record<string, {
|
337
349
|
max?: number | undefined;
|
338
350
|
min?: number | undefined;
|
339
351
|
combinaison?: string | undefined;
|
352
|
+
exclude?: boolean | undefined;
|
340
353
|
}> | undefined, Record<string, {
|
341
354
|
max?: number | undefined;
|
342
355
|
min?: number | undefined;
|
343
356
|
combinaison?: string | undefined;
|
357
|
+
exclude?: boolean | undefined;
|
344
358
|
}> | undefined>;
|
345
359
|
total: z.ZodOptional<z.ZodNumber>;
|
346
360
|
diceType: z.ZodOptional<z.ZodString>;
|
@@ -394,6 +408,7 @@ declare const templateSchema: z.ZodObject<{
|
|
394
408
|
max?: number | undefined;
|
395
409
|
min?: number | undefined;
|
396
410
|
combinaison?: string | undefined;
|
411
|
+
exclude?: boolean | undefined;
|
397
412
|
}> | undefined;
|
398
413
|
diceType?: string | undefined;
|
399
414
|
critical?: {
|
@@ -414,6 +429,7 @@ declare const templateSchema: z.ZodObject<{
|
|
414
429
|
max?: number | undefined;
|
415
430
|
min?: number | undefined;
|
416
431
|
combinaison?: string | undefined;
|
432
|
+
exclude?: boolean | undefined;
|
417
433
|
}> | undefined;
|
418
434
|
diceType?: string | undefined;
|
419
435
|
critical?: {
|
@@ -437,4 +453,4 @@ interface StatisticalSchema extends StatisticalTemplate {
|
|
437
453
|
$schema?: string;
|
438
454
|
}
|
439
455
|
|
440
|
-
export { COMMENT_REGEX, type Compare, type Critical, type CustomCritical, DiceTypeError, EmptyObjectError, FormulaError, MaxGreater, type Modifier, NoStatisticsError, type Resultat, SIGN_REGEX, SIGN_REGEX_SPACE, SYMBOL_DICE, type Sign, type Statistic, type StatisticalSchema, type StatisticalTemplate, TooManyDice, TooManyStats, calculator, cleanedDice, createCriticalCustom, diceRandomParse, diceTypeRandomParse, escapeRegex, evalCombinaison, evalOneCombinaison, evalStatsDice, generateRandomStat, generateStatsDice, replaceFormulaInDice, roll, templateSchema, testDiceRegistered, testStatCombinaison, verifyTemplateValue };
|
456
|
+
export { COMMENT_REGEX, type Compare, type ComparedValue, type Critical, type CustomCritical, DiceTypeError, EmptyObjectError, FormulaError, MaxGreater, type Modifier, NoStatisticsError, type Resultat, SIGN_REGEX, SIGN_REGEX_SPACE, SYMBOL_DICE, type Sign, type Statistic, type StatisticalSchema, type StatisticalTemplate, TooManyDice, TooManyStats, calculator, cleanedDice, createCriticalCustom, diceRandomParse, diceTypeRandomParse, escapeRegex, evalCombinaison, evalOneCombinaison, evalStatsDice, generateRandomStat, generateStatsDice, replaceFormulaInDice, roll, templateSchema, testDiceRegistered, testStatCombinaison, verifyTemplateValue };
|
package/dist/index.js
CHANGED
@@ -391,7 +391,7 @@ var import_uniformize = require("uniformize");
|
|
391
391
|
function escapeRegex(string) {
|
392
392
|
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
393
393
|
}
|
394
|
-
function generateStatsDice(originalDice, stats) {
|
394
|
+
function generateStatsDice(originalDice, stats, dollarValue) {
|
395
395
|
let dice = originalDice.standardize();
|
396
396
|
if (stats && Object.keys(stats).length > 0) {
|
397
397
|
const allStats = Object.keys(stats);
|
@@ -403,6 +403,7 @@ function generateStatsDice(originalDice, stats) {
|
|
403
403
|
}
|
404
404
|
}
|
405
405
|
}
|
406
|
+
if (dollarValue) dice = dice.replaceAll("$", dollarValue);
|
406
407
|
return replaceFormulaInDice(dice);
|
407
408
|
}
|
408
409
|
function replaceFormulaInDice(dice) {
|
@@ -436,7 +437,8 @@ var import_zod = require("zod");
|
|
436
437
|
var statisticValueSchema = import_zod.z.object({
|
437
438
|
max: import_zod.z.number().positive().optional(),
|
438
439
|
min: import_zod.z.number().positive().optional(),
|
439
|
-
combinaison: import_zod.z.string().transform((str) => str.trim() || void 0).optional()
|
440
|
+
combinaison: import_zod.z.string().transform((str) => str.trim() || void 0).optional(),
|
441
|
+
exclude: import_zod.z.boolean().optional()
|
440
442
|
}).superRefine((data, ctx) => {
|
441
443
|
if (data.max !== void 0 && data.min !== void 0 && data.max <= data.min) {
|
442
444
|
ctx.addIssue({
|
@@ -606,7 +608,6 @@ function verifyTemplateValue(template) {
|
|
606
608
|
const customCritical = statistiqueTemplate.customCritical;
|
607
609
|
for (const [, custom] of Object.entries(customCritical)) {
|
608
610
|
const cleanedDice2 = createCriticalCustom(
|
609
|
-
// biome-ignore lint/style/noNonNullAssertion: <explanation>
|
610
611
|
statistiqueTemplate.diceType,
|
611
612
|
custom,
|
612
613
|
statistiqueTemplate
|
package/dist/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/dice.ts","../src/errors.ts","../src/interfaces/constant.ts","../src/utils.ts","../src/verify_template.ts","../src/interfaces/zod.ts"],"sourcesContent":["export * from \"./dice\";\r\nexport * from \"./interfaces\";\r\nexport * from \"./utils\";\r\nexport * from \"./verify_template\";\r\nexport * from \"./errors\";\r\nexport * from \"./interfaces/constant\";\r\nexport * from \"./interfaces/zod\";\r\nexport * from \"./interfaces/toJsonSchema\";\r\n","import { DiceRoller } from \"@dice-roller/rpg-dice-roller\";\r\nimport { evaluate } from \"mathjs\";\r\n\r\nimport {\r\n\ttype Compare,\r\n\ttype CustomCritical,\r\n\ttype Modifier,\r\n\ttype Resultat,\r\n\ttype Sign,\r\n\ttype StatisticalTemplate,\r\n\tdiceTypeRandomParse,\r\n} from \".\";\r\nimport { DiceTypeError } from \"./errors\";\r\nimport {\r\n\tCOMMENT_REGEX,\r\n\tSIGN_REGEX,\r\n\tSIGN_REGEX_SPACE,\r\n\tSYMBOL_DICE,\r\n} from \"./interfaces/constant\";\r\n\r\nfunction getCompare(\r\n\tdice: string,\r\n\tcompareRegex: RegExpMatchArray\r\n): { dice: string; compare: Compare | undefined } {\r\n\tdice = dice.replace(SIGN_REGEX_SPACE, \"\");\r\n\tlet compare: Compare;\r\n\tconst calc = compareRegex[1];\r\n\tconst sign = calc.match(/[+-\\/*^]/)?.[0];\r\n\tconst compareSign = compareRegex[0].match(SIGN_REGEX)?.[0];\r\n\tif (sign) {\r\n\t\tconst toCalc = calc.replace(SIGN_REGEX, \"\").replace(/\\s/g, \"\").replace(/;(.*)/, \"\");\r\n\t\tconst rCompare = rollCompare(toCalc);\r\n\t\tconst total = evaluate(rCompare.value.toString());\r\n\t\tdice = dice.replace(SIGN_REGEX_SPACE, `${compareSign}${total}`);\r\n\t\tcompare = {\r\n\t\t\tsign: compareSign as \"<\" | \">\" | \">=\" | \"<=\" | \"=\" | \"!=\" | \"==\",\r\n\t\t\tvalue: total,\r\n\t\t\toriginalDice: rCompare.dice,\r\n\t\t\trollValue: rCompare.diceResult,\r\n\t\t};\r\n\t} else {\r\n\t\tconst rcompare = rollCompare(calc);\r\n\t\tcompare = {\r\n\t\t\tsign: compareSign as \"<\" | \">\" | \">=\" | \"<=\" | \"=\" | \"!=\" | \"==\",\r\n\t\t\tvalue: rcompare.value,\r\n\t\t\toriginalDice: rcompare.dice,\r\n\t\t\trollValue: rcompare.diceResult,\r\n\t\t};\r\n\t}\r\n\treturn { dice, compare };\r\n}\r\n\r\nfunction rollCompare(value: unknown) {\r\n\tconst isNumber = (value: unknown): boolean =>\r\n\t\ttypeof value === \"number\" ||\r\n\t\t(!Number.isNaN(Number(value)) && typeof value === \"string\");\r\n\tif (isNumber(value)) return { value: Number.parseInt(value as string, 10) };\r\n\tconst rollComp = roll(value as string);\r\n\tif (!rollComp?.total) //not a dice throw\r\n\t\treturn { value: evaluate(value as string), diceResult: value as string };\r\n\treturn {\r\n\t\tdice: value as string,\r\n\t\tvalue: rollComp.total,\r\n\t\tdiceResult: rollComp?.result,\r\n\t};\r\n}\r\n\r\n/**\r\n * Allow to replace the compare part of a dice and use the critical customized one\r\n * @example\r\n * dice = \"1d20=20\";\r\n * custom critical {sign: \">\", value: \"$/2\"}\r\n * Random stats = 6\r\n * result = \"1d20>3\"\r\n */\r\nexport function createCriticalCustom(\r\n\tdice: string,\r\n\tcustomCritical: CustomCritical,\r\n\ttemplate: StatisticalTemplate\r\n) {\r\n\tconst compareRegex = dice.match(SIGN_REGEX_SPACE);\r\n\tlet customDice = dice;\r\n\tconst compareValue = diceTypeRandomParse(customCritical.value, template);\r\n\tif (compareValue.includes(\"$\"))\r\n\t\tthrow new DiceTypeError(compareValue, \"createCriticalCustom\");\r\n\tconst comparaison = `${customCritical.sign}${compareValue}`;\r\n\tif (compareRegex) customDice = customDice.replace(SIGN_REGEX_SPACE, comparaison);\r\n\telse customDice += comparaison;\r\n\treturn diceTypeRandomParse(customDice, template);\r\n}\r\n\r\nfunction getModifier(dice: string) {\r\n\tconst modifier = dice.matchAll(/(\\+|-|%|\\/|\\^|\\*|\\*{2})(\\d+)/gi);\r\n\tlet modificator: Modifier | undefined;\r\n\tfor (const mod of modifier) {\r\n\t\t//calculate the modifier if multiple\r\n\t\tif (modificator) {\r\n\t\t\tconst sign = modificator.sign;\r\n\t\t\tlet value = modificator.value;\r\n\t\t\tif (sign) value = calculator(sign, value, Number.parseInt(mod[2], 10));\r\n\t\t\tmodificator = {\r\n\t\t\t\tsign: mod[1] as Sign,\r\n\t\t\t\tvalue,\r\n\t\t\t};\r\n\t\t} else {\r\n\t\t\tmodificator = {\r\n\t\t\t\tsign: mod[1] as Sign,\r\n\t\t\t\tvalue: Number.parseInt(mod[2], 10),\r\n\t\t\t};\r\n\t\t}\r\n\t}\r\n\treturn modificator;\r\n}\r\n\r\n/**\r\n * Parse the string provided and turn it as a readable dice for dice parser\r\n * @param dice {string}\r\n */\r\nexport function roll(dice: string): Resultat | undefined {\r\n\t//parse dice string\r\n\tif (!dice.includes(\"d\")) return undefined;\r\n\tconst compareRegex = dice.match(SIGN_REGEX_SPACE);\r\n\tlet compare: Compare | undefined;\r\n\tif (dice.includes(\";\") && dice.includes(\"&\")) return sharedRolls(dice);\r\n\tif (compareRegex) {\r\n\t\tconst compareResult = getCompare(dice, compareRegex);\r\n\t\tdice = compareResult.dice;\r\n\t\tcompare = compareResult.compare;\r\n\t}\r\n\tconst modificator = getModifier(dice);\r\n\r\n\tif (dice.match(/\\d+?#(.*)/)) {\r\n\t\tconst diceArray = dice.split(\"#\");\r\n\t\tconst numberOfDice = Number.parseInt(diceArray[0], 10);\r\n\t\tconst diceToRoll = diceArray[1].replace(COMMENT_REGEX, \"\");\r\n\t\tconst commentsMatch = diceArray[1].match(COMMENT_REGEX);\r\n\t\tconst comments = commentsMatch ? commentsMatch[2] : undefined;\r\n\t\tconst roller = new DiceRoller();\r\n\t\t//remove comments if any\r\n\t\tfor (let i = 0; i < numberOfDice; i++) {\r\n\t\t\ttry {\r\n\t\t\t\troller.roll(diceToRoll);\r\n\t\t\t} catch (error) {\r\n\t\t\t\tthrow new DiceTypeError(diceToRoll, \"roll\", error);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn {\r\n\t\t\tdice: diceToRoll,\r\n\t\t\tresult: roller.output,\r\n\t\t\tcomment: comments,\r\n\t\t\tcompare: compare ? compare : undefined,\r\n\t\t\tmodifier: modificator,\r\n\t\t\ttotal: roller.total,\r\n\t\t};\r\n\t}\r\n\tconst roller = new DiceRoller();\r\n\tconst diceWithoutComment = dice.replace(COMMENT_REGEX, \"\").trimEnd();\r\n\ttry {\r\n\t\troller.roll(diceWithoutComment);\r\n\t} catch (error) {\r\n\t\tthrow new DiceTypeError(diceWithoutComment, \"roll\", error);\r\n\t}\r\n\tconst commentMatch = dice.match(COMMENT_REGEX);\r\n\tconst comment = commentMatch ? commentMatch[2] : undefined;\r\n\treturn {\r\n\t\tdice,\r\n\t\tresult: roller.output,\r\n\t\tcomment,\r\n\t\tcompare: compare ? compare : undefined,\r\n\t\tmodifier: modificator,\r\n\t\ttotal: roller.total,\r\n\t};\r\n}\r\n/**\r\n * Evaluate a formula and replace \"^\" by \"**\" if any\r\n * @param {Sign} sign\r\n * @param {number} value\r\n * @param {number} total\r\n * @returns\r\n */\r\nexport function calculator(sign: Sign, value: number, total: number): number {\r\n\tif (sign === \"^\") sign = \"**\";\r\n\treturn evaluate(`${total} ${sign} ${value}`);\r\n}\r\n\r\nfunction inverseSign(\r\n\tsign: \"<\" | \">\" | \">=\" | \"<=\" | \"=\" | \"!=\" | \"==\"\r\n): \"<\" | \">\" | \">=\" | \"<=\" | \"=\" | \"!=\" | \"==\" {\r\n\tswitch (sign) {\r\n\t\tcase \"<\":\r\n\t\t\treturn \">\";\r\n\t\tcase \">\":\r\n\t\t\treturn \"<\";\r\n\t\tcase \"<=\":\r\n\t\t\treturn \">=\";\r\n\t\tcase \">=\":\r\n\t\t\treturn \"<=\";\r\n\t\tcase \"=\":\r\n\t\t\treturn \"!=\";\r\n\t\tcase \"==\":\r\n\t\t\treturn \"!=\";\r\n\t\tcase \"!=\":\r\n\t\t\treturn \"==\";\r\n\t}\r\n}\r\n\r\nfunction replaceInFormula(\r\n\telement: string,\r\n\tdiceResult: Resultat,\r\n\tcompareResult: { dice: string; compare: Compare | undefined },\r\n\tres: boolean\r\n) {\r\n\tconst { formule, diceAll } = replaceText(\r\n\t\telement,\r\n\t\tdiceResult.total ?? 0,\r\n\t\tdiceResult.dice\r\n\t);\r\n\tconst validSign = res ? \"✓\" : \"✕\";\r\n\tconst invertedSign = res\r\n\t\t? compareResult.compare!.sign\r\n\t\t: inverseSign(compareResult.compare!.sign);\r\n\tlet evaluateRoll: unknown;\r\n\ttry {\r\n\t\tevaluateRoll = evaluate(compareResult.dice);\r\n\t\treturn `${validSign} ${diceAll}: ${formule} = ${evaluateRoll}${invertedSign}${compareResult.compare?.value}`;\r\n\t} catch (error) {\r\n\t\tconst evaluateRoll = roll(compareResult.dice) as Resultat | undefined;\r\n\t\tif (evaluateRoll)\r\n\t\t\treturn `${validSign} ${diceAll}: ${evaluateRoll.result.split(\":\").splice(1).join(\":\")}`;\r\n\r\n\t\treturn `${validSign} ${diceAll}: ${formule} = ${evaluateRoll}${invertedSign}${compareResult.compare?.value}`;\r\n\t}\r\n}\r\n\r\nfunction compareSignFormule(\r\n\ttoRoll: string,\r\n\tcompareRegex: RegExpMatchArray,\r\n\telement: string,\r\n\tdiceResult: Resultat\r\n) {\r\n\tlet results = \"\";\r\n\tconst compareResult = getCompare(toRoll, compareRegex);\r\n\tconst toCompare = `${compareResult.dice}${compareResult.compare?.sign}${compareResult.compare?.value}`;\r\n\tlet res: unknown;\r\n\ttry {\r\n\t\tres = evaluate(toCompare);\r\n\t} catch (error) {\r\n\t\tres = roll(toCompare);\r\n\t}\r\n\tif (typeof res === \"boolean\") {\r\n\t\tresults = replaceInFormula(element, diceResult, compareResult, res);\r\n\t} else if (res instanceof Object) {\r\n\t\tconst diceResult = res as Resultat;\r\n\t\tif (diceResult.compare) {\r\n\t\t\tconst toEvaluate = evaluate(\r\n\t\t\t\t`${diceResult.total}${diceResult.compare.sign}${diceResult.compare.value}`\r\n\t\t\t);\r\n\t\t\tconst sign = toEvaluate ? \"✓\" : \"✕\";\r\n\t\t\tconst invertedSign = toEvaluate\r\n\t\t\t\t? diceResult.compare.sign\r\n\t\t\t\t: inverseSign(diceResult.compare.sign);\r\n\t\t\tconst dice = replaceText(element, 0, diceResult.dice).diceAll;\r\n\r\n\t\t\tresults = `${sign} ${dice}: ${diceResult.result.split(\":\").splice(1).join(\":\").trim()}${invertedSign}${diceResult.compare.value}`;\r\n\t\t}\r\n\t}\r\n\treturn { dice: compareResult.dice, results };\r\n}\r\n\r\nfunction replaceText(element: string, total: number, dice: string) {\r\n\treturn {\r\n\t\tformule: element.replace(SYMBOL_DICE, `[${total}]`).trim(),\r\n\t\tdiceAll: element.replace(SYMBOL_DICE, `[${dice.replace(COMMENT_REGEX, \"\")}]`).trim(),\r\n\t};\r\n}\r\n\r\nfunction sharedRolls(dice: string): Resultat | undefined {\r\n\t/* bulk roll are not allowed in shared rolls */\r\n\tif (dice.includes(\"#\"))\r\n\t\tthrow new DiceTypeError(\r\n\t\t\tdice,\r\n\t\t\t\"noBulkRoll\",\r\n\t\t\t\"bulk roll are not allowed in shared rolls\"\r\n\t\t);\r\n\tconst results = [];\r\n\tconst split = dice.split(\";\");\r\n\tconst diceResult = roll(split[0]);\r\n\tif (!diceResult || !diceResult.total) return undefined;\r\n\tresults.push(`${diceResult.result}`);\r\n\r\n\tlet total = diceResult.total;\r\n\tlet comments = diceResult.comment ?? \"\";\r\n\tif (!total) return diceResult;\r\n\tfor (let element of split.slice(1)) {\r\n\t\tif (!element.includes(SYMBOL_DICE)) {\r\n\t\t\tconst result = roll(element);\r\n\t\t\tif (!result) continue;\r\n\t\t\tresults.push(result.result);\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\t//remove comments & keep it\r\n\t\tconst commentMatch = element.match(COMMENT_REGEX);\r\n\t\telement = element.replace(COMMENT_REGEX, \"\");\r\n\t\tconst comment = commentMatch ? commentMatch[2] : undefined;\r\n\t\tif (comment) comments += ` ${comment}`;\r\n\t\tlet toRoll = element.replace(SYMBOL_DICE, `${diceResult.total}`);\r\n\t\tconst compareRegex = toRoll.match(SIGN_REGEX_SPACE);\r\n\t\tif (compareRegex) {\r\n\t\t\tconst compareResult = compareSignFormule(toRoll, compareRegex, element, diceResult);\r\n\t\t\ttoRoll = compareResult.dice;\r\n\t\t\tresults.push(compareResult.results);\r\n\t\t} else {\r\n\t\t\tconst { formule, diceAll } = replaceText(\r\n\t\t\t\telement,\r\n\t\t\t\tdiceResult.total,\r\n\t\t\t\tdiceResult.dice\r\n\t\t\t);\r\n\r\n\t\t\ttry {\r\n\t\t\t\tconst evaluated = evaluate(toRoll);\r\n\t\t\t\tresults.push(`◈ ${diceAll}: ${formule} = ${evaluated}`);\r\n\t\t\t\ttotal += Number.parseInt(evaluated, 10);\r\n\t\t\t} catch (error) {\r\n\t\t\t\tconst evaluated = roll(toRoll);\r\n\t\t\t\tif (evaluated)\r\n\t\t\t\t\tresults.push(`◈ ${diceAll}: ${evaluated.result.split(\":\").slice(1).join(\":\")}`);\r\n\t\t\t\telse results.push(`◈ ${diceAll}: ${formule} = ${evaluated}`);\r\n\t\t\t\ttotal += evaluated?.total ?? 0;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\treturn {\r\n\t\tdice: split[0],\r\n\t\tresult: results.join(\";\"),\r\n\t\tcomment: comments,\r\n\t\tcompare: diceResult.compare,\r\n\t\tmodifier: diceResult.modifier,\r\n\t\ttotal,\r\n\t};\r\n}\r\n","export class DiceTypeError extends Error {\r\n\tpublic readonly dice: string;\r\n\tpublic readonly cause: string | undefined;\r\n\tpublic readonly method: unknown;\r\n\r\n\tconstructor(dice: string, cause?: string, method?: unknown) {\r\n\t\tsuper(dice);\r\n\t\tthis.name = \"Invalid_Dice_Type\";\r\n\t\tthis.dice = dice;\r\n\t\tthis.cause = cause;\r\n\t\tthis.method = method;\r\n\t}\r\n}\r\n\r\nexport class FormulaError extends Error {\r\n\tpublic readonly formula: string;\r\n\tpublic readonly cause: string | undefined;\r\n\tpublic readonly method: unknown;\r\n\r\n\tconstructor(formula: string, cause?: string, method?: unknown) {\r\n\t\tsuper(formula);\r\n\t\tthis.name = \"Invalid_Formula\";\r\n\t\tthis.formula = formula;\r\n\t\tthis.cause = cause;\r\n\t\tthis.method = method;\r\n\t}\r\n}\r\n\r\nexport class MaxGreater extends Error {\r\n\tpublic readonly name: string;\r\n\tpublic readonly value: number;\r\n\tpublic readonly max: number;\r\n\r\n\tconstructor(value: number, max: number) {\r\n\t\tsuper(value.toString());\r\n\t\tthis.name = \"Max_Greater\";\r\n\t\tthis.value = value;\r\n\t\tthis.max = max;\r\n\t}\r\n}\r\n\r\nexport class EmptyObjectError extends Error {\r\n\tpublic readonly name: string;\r\n\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t\tthis.name = \"Empty_Object\";\r\n\t}\r\n}\r\n\r\nexport class TooManyDice extends Error {\r\n\tpublic readonly name: string;\r\n\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t\tthis.name = \"Too_Many_Dice\";\r\n\t}\r\n}\r\n\r\nexport class TooManyStats extends Error {\r\n\tpublic readonly name: string;\r\n\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t\tthis.name = \"Too_Many_Stats\";\r\n\t}\r\n}\r\n\r\nexport class NoStatisticsError extends Error {\r\n\tpublic readonly name: string;\r\n\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t\tthis.name = \"No_Statistics\";\r\n\t}\r\n}\r\n","export const COMMENT_REGEX = /\\s+(#|\\/{2}|\\[|\\/\\*)(.*)/;\r\nexport const SIGN_REGEX = /[><=!]+/;\r\nexport const SIGN_REGEX_SPACE = /[><=!]+(\\S+)/;\r\n\r\nexport const SYMBOL_DICE = \"&\";\r\n","import { evaluate } from \"mathjs\";\r\nimport \"uniformize\";\r\nimport { FormulaError } from \"./errors\";\r\n\r\n/**\r\n * Escape regex string\r\n * @param string {string}\r\n */\r\nexport function escapeRegex(string: string) {\r\n\treturn string.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\r\n}\r\n\r\n/**\r\n * Replace the stat name by their value using stat and after evaluate any formula using `replaceFormulaInDice`\r\n * @param originalDice {dice}\r\n * @param stats {Record<string,number>}\r\n */\r\nexport function generateStatsDice(originalDice: string, stats?: Record<string, number>) {\r\n\tlet dice = originalDice.standardize();\r\n\tif (stats && Object.keys(stats).length > 0) {\r\n\t\t//damage field support adding statistic, like : 1d6 + strength\r\n\t\t//check if the value contains a statistic & calculate if it's okay\r\n\t\t//the dice will be converted before roll\r\n\t\tconst allStats = Object.keys(stats);\r\n\t\tfor (const stat of allStats) {\r\n\t\t\tconst regex = new RegExp(escapeRegex(stat.standardize()), \"gi\");\r\n\t\t\tif (dice.match(regex)) {\r\n\t\t\t\tconst statValue = stats[stat];\r\n\t\t\t\tdice = dice.replace(regex, statValue.toString());\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn replaceFormulaInDice(dice);\r\n}\r\n\r\n/**\r\n * Replace the {{}} in the dice string and evaluate the interior if any\r\n * @param dice {string}\r\n */\r\nexport function replaceFormulaInDice(dice: string) {\r\n\tconst formula = /(?<formula>\\{{2}(.+?)}{2})/gim;\r\n\t// biome-ignore lint/suspicious/noImplicitAnyLet: <explanation>\r\n\tlet match;\r\n\tlet modifiedDice = dice.standardize();\r\n\twhile ((match = formula.exec(dice)) !== null) {\r\n\t\tif (match.groups?.formula) {\r\n\t\t\tconst formulae = match.groups.formula.replaceAll(\"{{\", \"\").replaceAll(\"}}\", \"\");\r\n\t\t\ttry {\r\n\t\t\t\tconst result = evaluate(formulae);\r\n\t\t\t\tmodifiedDice = modifiedDice.replace(match.groups.formula, result.toString());\r\n\t\t\t} catch (error) {\r\n\t\t\t\tthrow new FormulaError(match.groups.formula, \"replaceFormulasInDice\", error);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\treturn cleanedDice(modifiedDice);\r\n}\r\n\r\n/**\r\n * Replace the ++ +- -- by their proper value:\r\n * - `++` = `+`\r\n * - `+-` = `-`\r\n * - `--` = `+`\r\n * @param dice {string}\r\n */\r\nexport function cleanedDice(dice: string) {\r\n\treturn dice.replaceAll(\"+-\", \"-\").replaceAll(\"--\", \"+\").replaceAll(\"++\", \"+\").trimEnd();\r\n}\r\n","/* eslint-disable @typescript-eslint/no-unused-vars */\r\nimport { evaluate } from \"mathjs\";\r\nimport { Random } from \"random-js\";\r\nimport \"uniformize\";\r\n\r\nimport type { StatisticalTemplate } from \".\";\r\nimport { createCriticalCustom, roll } from \"./dice\";\r\nimport {\r\n\tDiceTypeError,\r\n\tEmptyObjectError,\r\n\tFormulaError,\r\n\tNoStatisticsError,\r\n\tTooManyDice,\r\n} from \"./errors\";\r\nimport { templateSchema } from \"./interfaces/zod\";\r\nimport { escapeRegex, replaceFormulaInDice } from \"./utils\";\r\n\r\n/**\r\n * Verify if the provided dice work with random value\r\n * @param testDice {string}\r\n * @param allStats {Record<string,number>}\r\n */\r\nexport function evalStatsDice(testDice: string, allStats?: Record<string, number>) {\r\n\tlet dice = testDice.trimEnd();\r\n\tif (allStats && Object.keys(allStats).length > 0) {\r\n\t\tconst names = Object.keys(allStats);\r\n\t\tfor (const name of names) {\r\n\t\t\tconst regex = new RegExp(escapeRegex(name.standardize()), \"gi\");\r\n\t\t\tif (dice.standardize().match(regex)) {\r\n\t\t\t\tconst statValue = allStats[name];\r\n\t\t\t\tdice = dice.standardize().replace(regex, statValue.toString()).trimEnd();\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\ttry {\r\n\t\tif (!roll(replaceFormulaInDice(dice)))\r\n\t\t\tthrow new DiceTypeError(dice, \"evalStatsDice\", \"no roll result\");\r\n\t\treturn testDice;\r\n\t} catch (error) {\r\n\t\tthrow new DiceTypeError(dice, \"evalStatsDice\", error);\r\n\t}\r\n}\r\n\r\n/**\r\n * Generate a random dice and remove the formula (+ evaluate it)\r\n * Used for diceDamage only\r\n * @param value {string}\r\n * @param template {StatisticalTemplate}\r\n * @returns\r\n */\r\nexport function diceRandomParse(value: string, template: StatisticalTemplate) {\r\n\tif (!template.statistics) return value;\r\n\tvalue = value.standardize();\r\n\tconst statNames = Object.keys(template.statistics);\r\n\tlet newDice = value;\r\n\tfor (const name of statNames) {\r\n\t\tconst regex = new RegExp(escapeRegex(name.standardize()), \"gi\");\r\n\t\tif (value.match(regex)) {\r\n\t\t\tlet max: undefined | number = undefined;\r\n\t\t\tlet min: undefined | number = undefined;\r\n\t\t\tconst foundStat = template.statistics?.[name];\r\n\t\t\tif (foundStat) {\r\n\t\t\t\tmax = foundStat.max;\r\n\t\t\t\tmin = foundStat.min;\r\n\t\t\t}\r\n\t\t\tconst total = template.total || 100;\r\n\t\t\tconst randomStatValue = generateRandomStat(total, max, min);\r\n\t\t\tnewDice = value.replace(regex, randomStatValue.toString());\r\n\t\t}\r\n\t}\r\n\treturn replaceFormulaInDice(newDice);\r\n}\r\n\r\n/**\r\n * Same as damageDice but for DiceType\r\n * @param dice {string}\r\n * @param template {StatisticalTemplate}\r\n */\r\nexport function diceTypeRandomParse(dice: string, template: StatisticalTemplate) {\r\n\tif (!template.statistics) return dice;\r\n\tconst firstStatNotcombinaison = Object.keys(template.statistics).find(\r\n\t\t(stat) => !template.statistics?.[stat].combinaison\r\n\t);\r\n\tif (!firstStatNotcombinaison) return dice;\r\n\tconst stats = template.statistics[firstStatNotcombinaison];\r\n\tconst { min, max } = stats;\r\n\tconst total = template.total || 100;\r\n\tconst randomStatValue = generateRandomStat(total, max, min);\r\n\treturn replaceFormulaInDice(dice.replaceAll(\"$\", randomStatValue.toString()));\r\n}\r\n\r\n/**\r\n * Random the combinaison and evaluate it to check if everything is valid\r\n * @param combinaison {Record<string,string>}\r\n * @param stats {Record<string,number|number>}\r\n */\r\nexport function evalCombinaison(\r\n\tcombinaison: Record<string, string>,\r\n\tstats: Record<string, number | string>\r\n) {\r\n\tconst newStats: Record<string, number> = {};\r\n\tfor (const [stat, combin] of Object.entries(combinaison)) {\r\n\t\t//replace the stats in formula\r\n\t\tlet formula = combin.standardize();\r\n\t\tfor (const [statName, value] of Object.entries(stats)) {\r\n\t\t\tconst regex = new RegExp(statName.standardize(), \"gi\");\r\n\t\t\tformula = formula.replace(regex, value.toString());\r\n\t\t}\r\n\t\ttry {\r\n\t\t\tnewStats[stat] = evaluate(formula);\r\n\t\t} catch (error) {\r\n\t\t\tthrow new FormulaError(stat, \"evalCombinaison\", error);\r\n\t\t}\r\n\t}\r\n\treturn newStats;\r\n}\r\n\r\n/**\r\n * Evaluate one selected combinaison\r\n * @param combinaison {string}\r\n * @param stats {[name: string]: string|number}\r\n */\r\nexport function evalOneCombinaison(\r\n\tcombinaison: string,\r\n\tstats: Record<string, number | string>\r\n) {\r\n\tlet formula = combinaison.standardize();\r\n\tfor (const [statName, value] of Object.entries(stats)) {\r\n\t\tconst regex = new RegExp(statName.standardize(), \"gi\");\r\n\t\tformula = formula.replace(regex, value.toString());\r\n\t}\r\n\ttry {\r\n\t\treturn evaluate(formula);\r\n\t} catch (error) {\r\n\t\tthrow new FormulaError(combinaison, \"evalOneCombinaison\", error);\r\n\t}\r\n}\r\n\r\nfunction convertNumber(number: string | number | undefined) {\r\n\tif (!number) return undefined;\r\n\tconst isNumber = (value: unknown): boolean =>\r\n\t\ttypeof value === \"number\" ||\r\n\t\t(!Number.isNaN(Number(value)) && typeof value === \"string\");\r\n\tif (number.toString().length === 0) return undefined;\r\n\tif (isNumber(number)) return Number.parseInt(number.toString(), 10);\r\n\treturn undefined;\r\n}\r\n\r\n/**\r\n * Parse the provided JSON and verify each field to check if everything could work when rolling\r\n * @param {any} template\r\n * @returns {StatisticalTemplate}\r\n */\r\nexport function verifyTemplateValue(template: unknown): StatisticalTemplate {\r\n\tconst parsedTemplate = templateSchema.parse(template);\r\n\tconst { success, failure } = parsedTemplate.critical ?? {};\r\n\tconst criticicalVal = {\r\n\t\tsuccess: convertNumber(success),\r\n\t\tfailure: convertNumber(failure),\r\n\t};\r\n\tconst statistiqueTemplate: StatisticalTemplate = {\r\n\t\tdiceType: parsedTemplate.diceType,\r\n\t\tstatistics: parsedTemplate.statistics,\r\n\t\tcritical: criticicalVal,\r\n\t\ttotal: parsedTemplate.total,\r\n\t\tcharName: parsedTemplate.charName,\r\n\t\tdamage: parsedTemplate.damage,\r\n\t\tcustomCritical: parsedTemplate.customCritical,\r\n\t};\r\n\tif (statistiqueTemplate.diceType) {\r\n\t\tconst cleanedDice = diceTypeRandomParse(\r\n\t\t\tstatistiqueTemplate.diceType,\r\n\t\t\tstatistiqueTemplate\r\n\t\t);\r\n\t\tconst rolled = roll(cleanedDice);\r\n\t\tif (!rolled) {\r\n\t\t\tthrow new DiceTypeError(cleanedDice, \"verifyTemplateValue\", \"no roll result\");\r\n\t\t}\r\n\t}\r\n\tif (statistiqueTemplate.customCritical) {\r\n\t\tif (!statistiqueTemplate.diceType) {\r\n\t\t\tthrow new DiceTypeError(\"no_dice_type\", \"verifyTemplateValue\", \"no dice type\");\r\n\t\t}\r\n\t\tconst customCritical = statistiqueTemplate.customCritical;\r\n\t\tfor (const [, custom] of Object.entries(customCritical)) {\r\n\t\t\tconst cleanedDice = createCriticalCustom(\r\n\t\t\t\t// biome-ignore lint/style/noNonNullAssertion: <explanation>\r\n\t\t\t\tstatistiqueTemplate.diceType!,\r\n\t\t\t\tcustom,\r\n\t\t\t\tstatistiqueTemplate\r\n\t\t\t);\r\n\t\t\tconst rolled = roll(cleanedDice);\r\n\t\t\tif (!rolled)\r\n\t\t\t\tthrow new DiceTypeError(cleanedDice, \"verifyTemplateValue\", \"no roll result\");\r\n\t\t}\r\n\t}\r\n\ttestDiceRegistered(statistiqueTemplate);\r\n\ttestStatCombinaison(statistiqueTemplate);\r\n\treturn statistiqueTemplate;\r\n}\r\n\r\n/**\r\n * Test each damage roll from the template.damage\r\n * @param {StatisticalTemplate} template\r\n */\r\nexport function testDiceRegistered(template: StatisticalTemplate) {\r\n\tif (!template.damage) return;\r\n\tif (Object.keys(template.damage).length === 0) throw new EmptyObjectError();\r\n\tif (Object.keys(template.damage).length > 25) throw new TooManyDice();\r\n\tfor (const [name, dice] of Object.entries(template.damage)) {\r\n\t\tif (!dice) continue;\r\n\t\tconst randomDiceParsed = diceRandomParse(dice, template);\r\n\t\ttry {\r\n\t\t\tconst rolled = roll(randomDiceParsed);\r\n\t\t\tif (!rolled) throw new DiceTypeError(name, \"no_roll_result\", dice);\r\n\t\t} catch (error) {\r\n\t\t\tconsole.error(error);\r\n\t\t\tthrow new DiceTypeError(name, \"testDiceRegistered\", error);\r\n\t\t}\r\n\t}\r\n}\r\n\r\n/**\r\n * Test all combinaison with generated random value\r\n * @param {StatisticalTemplate} template\r\n */\r\nexport function testStatCombinaison(template: StatisticalTemplate) {\r\n\tif (!template.statistics) return;\r\n\tconst onlycombinaisonStats = Object.fromEntries(\r\n\t\tObject.entries(template.statistics).filter(\r\n\t\t\t([_, value]) => value.combinaison !== undefined\r\n\t\t)\r\n\t);\r\n\tconst allOtherStats = Object.fromEntries(\r\n\t\tObject.entries(template.statistics).filter(([_, value]) => !value.combinaison)\r\n\t);\r\n\tif (Object.keys(onlycombinaisonStats).length === 0) return;\r\n\tconst allStats = Object.keys(template.statistics).filter(\r\n\t\t(stat) => !template.statistics![stat].combinaison\r\n\t);\r\n\tif (allStats.length === 0) throw new NoStatisticsError();\r\n\tconst error = [];\r\n\tfor (const [stat, value] of Object.entries(onlycombinaisonStats)) {\r\n\t\tlet formula = value.combinaison as string;\r\n\t\tfor (const [other, data] of Object.entries(allOtherStats)) {\r\n\t\t\tconst { max, min } = data;\r\n\t\t\tconst total = template.total || 100;\r\n\t\t\tconst randomStatValue = generateRandomStat(total, max, min);\r\n\t\t\tconst regex = new RegExp(other, \"gi\");\r\n\t\t\tformula = formula.replace(regex, randomStatValue.toString());\r\n\t\t}\r\n\t\ttry {\r\n\t\t\tevaluate(formula);\r\n\t\t} catch (e) {\r\n\t\t\terror.push(stat);\r\n\t\t}\r\n\t}\r\n\tif (error.length > 0) throw new FormulaError(error.join(\", \"), \"testStatCombinaison\");\r\n\treturn;\r\n}\r\n\r\n/**\r\n * Generate a random stat based on the template and the statistical min and max\r\n * @param {number|undefined} total\r\n * @param {number | undefined} max\r\n * @param {number | undefined} min\r\n * @returns\r\n */\r\nexport function generateRandomStat(\r\n\ttotal: number | undefined = 100,\r\n\tmax?: number,\r\n\tmin?: number\r\n) {\r\n\tlet randomStatValue = total + 1;\r\n\twhile (randomStatValue >= total || randomStatValue === 0) {\r\n\t\tconst random = new Random();\r\n\t\tif (max && min) randomStatValue = random.integer(min, max);\r\n\t\telse if (max) randomStatValue = random.integer(1, max);\r\n\t\telse if (min) randomStatValue = random.integer(min, total);\r\n\t\telse randomStatValue = random.integer(1, total);\r\n\t}\r\n\treturn randomStatValue;\r\n}\r\n","/**\r\n * Definition of the Zod schema for template data\r\n */\r\nimport { z } from \"zod\";\r\n\r\nconst statisticValueSchema = z\r\n\t.object({\r\n\t\tmax: z.number().positive().optional(),\r\n\t\tmin: z.number().positive().optional(),\r\n\t\tcombinaison: z\r\n\t\t\t.string()\r\n\t\t\t.transform((str) => str.trim() || undefined)\r\n\t\t\t.optional(),\r\n\t})\r\n\t.superRefine((data, ctx) => {\r\n\t\tif (data.max !== undefined && data.min !== undefined && data.max <= data.min) {\r\n\t\t\tctx.addIssue({\r\n\t\t\t\tcode: \"custom\",\r\n\t\t\t\tmessage: `Max_Greater; ${data.min}; ${data.max}`,\r\n\t\t\t\tpath: [\"max\"],\r\n\t\t\t});\r\n\t\t}\r\n\t});\r\n\r\nconst statisticSchema = z\r\n\t.record(statisticValueSchema)\r\n\t.optional()\r\n\t.refine((stats) => !stats || Object.keys(stats).length <= 25, {\r\n\t\tmessage: \"TooManyStats\",\r\n\t});\r\n\r\nconst criticalSchema = z\r\n\t.object({\r\n\t\tsuccess: z.string().or(z.number().positive()).optional(),\r\n\t\tfailure: z.string().or(z.number().positive()).optional(),\r\n\t})\r\n\t.transform((values) => {\r\n\t\tif (values.success === \"\") values.success = undefined;\r\n\t\tif (values.failure === \"\") values.failure = undefined;\r\n\t\tif (values.failure === 0) values.failure = undefined;\r\n\t\tif (values.success === 0) values.success = undefined;\r\n\t\tvalues.success = Number.parseInt(values.success as string, 10);\r\n\t\tvalues.failure = Number.parseInt(values.failure as string, 10);\r\n\t\treturn values;\r\n\t});\r\n\r\nconst criticalValueSchema = z.object({\r\n\tsign: z.enum([\"<\", \">\", \"<=\", \">=\", \"!=\", \"==\"]),\r\n\tvalue: z.string(),\r\n\tonNaturalDice: z.boolean().optional(),\r\n\taffectSkill: z.boolean().optional(),\r\n});\r\n\r\nconst damageSchema = z\r\n\t.record(z.string())\r\n\t.optional()\r\n\t.refine((stats) => !stats || Object.keys(stats).length <= 25, {\r\n\t\tmessage: \"TooManyDice\",\r\n\t});\r\n\r\nconst customCriticalSchema = z\r\n\t.record(criticalValueSchema)\r\n\t.optional()\r\n\t.refine((stats) => !stats || Object.keys(stats).length <= 22, {\r\n\t\tmessage: \"TooManyDice\",\r\n\t});\r\n\r\nexport const templateSchema = z.object({\r\n\tcharName: z.boolean().optional(),\r\n\tstatistics: statisticSchema,\r\n\ttotal: z.number().min(0).optional(),\r\n\tdiceType: z.string().optional(),\r\n\tcritical: criticalSchema.optional(),\r\n\tcustomCritical: customCriticalSchema,\r\n\tdamage: damageSchema,\r\n});\r\n"],"mappings":"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","names":["value","roller","evaluateRoll","diceResult","import_mathjs","import_mathjs","import_uniformize","cleanedDice"]}
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/dice.ts","../src/errors.ts","../src/interfaces/constant.ts","../src/utils.ts","../src/verify_template.ts","../src/interfaces/zod.ts"],"sourcesContent":["export * from \"./dice\";\r\nexport * from \"./interfaces\";\r\nexport * from \"./utils\";\r\nexport * from \"./verify_template\";\r\nexport * from \"./errors\";\r\nexport * from \"./interfaces/constant\";\r\nexport * from \"./interfaces/zod\";\r\nexport * from \"./interfaces/toJsonSchema\";\r\n","import { DiceRoller } from \"@dice-roller/rpg-dice-roller\";\r\nimport { evaluate } from \"mathjs\";\r\n\r\nimport {\r\n\ttype Compare,\r\n\ttype ComparedValue,\r\n\ttype CustomCritical,\r\n\ttype Modifier,\r\n\ttype Resultat,\r\n\ttype Sign,\r\n\ttype StatisticalTemplate,\r\n\tdiceTypeRandomParse,\r\n} from \".\";\r\nimport { DiceTypeError } from \"./errors\";\r\nimport {\r\n\tCOMMENT_REGEX,\r\n\tSIGN_REGEX,\r\n\tSIGN_REGEX_SPACE,\r\n\tSYMBOL_DICE,\r\n} from \"./interfaces/constant\";\r\n\r\nfunction getCompare(\r\n\tdice: string,\r\n\tcompareRegex: RegExpMatchArray\r\n): { dice: string; compare: ComparedValue | undefined } {\r\n\tdice = dice.replace(SIGN_REGEX_SPACE, \"\");\r\n\tlet compare: ComparedValue;\r\n\tconst calc = compareRegex[1];\r\n\tconst sign = calc.match(/[+-\\/*^]/)?.[0];\r\n\tconst compareSign = compareRegex[0].match(SIGN_REGEX)?.[0];\r\n\tif (sign) {\r\n\t\tconst toCalc = calc.replace(SIGN_REGEX, \"\").replace(/\\s/g, \"\").replace(/;(.*)/, \"\");\r\n\t\tconst rCompare = rollCompare(toCalc);\r\n\t\tconst total = evaluate(rCompare.value.toString());\r\n\t\tdice = dice.replace(SIGN_REGEX_SPACE, `${compareSign}${total}`);\r\n\t\tcompare = {\r\n\t\t\tsign: compareSign as \"<\" | \">\" | \">=\" | \"<=\" | \"=\" | \"!=\" | \"==\",\r\n\t\t\tvalue: total,\r\n\t\t\toriginalDice: rCompare.dice,\r\n\t\t\trollValue: rCompare.diceResult,\r\n\t\t};\r\n\t} else {\r\n\t\tconst rcompare = rollCompare(calc);\r\n\t\tcompare = {\r\n\t\t\tsign: compareSign as \"<\" | \">\" | \">=\" | \"<=\" | \"=\" | \"!=\" | \"==\",\r\n\t\t\tvalue: rcompare.value,\r\n\t\t\toriginalDice: rcompare.dice,\r\n\t\t\trollValue: rcompare.diceResult,\r\n\t\t};\r\n\t}\r\n\treturn { dice, compare };\r\n}\r\n\r\nfunction rollCompare(value: unknown) {\r\n\tconst isNumber = (value: unknown): boolean =>\r\n\t\ttypeof value === \"number\" ||\r\n\t\t(!Number.isNaN(Number(value)) && typeof value === \"string\");\r\n\tif (isNumber(value)) return { value: Number.parseInt(value as string, 10) };\r\n\tconst rollComp = roll(value as string);\r\n\tif (!rollComp?.total) //not a dice throw\r\n\t\treturn { value: evaluate(value as string), diceResult: value as string };\r\n\treturn {\r\n\t\tdice: value as string,\r\n\t\tvalue: rollComp.total,\r\n\t\tdiceResult: rollComp?.result,\r\n\t};\r\n}\r\n\r\n/**\r\n * Allow to replace the compare part of a dice and use the critical customized one\r\n * @example\r\n * dice = \"1d20=20\";\r\n * custom critical {sign: \">\", value: \"$/2\"}\r\n * Random stats = 6\r\n * result = \"1d20>3\"\r\n */\r\nexport function createCriticalCustom(\r\n\tdice: string,\r\n\tcustomCritical: CustomCritical,\r\n\ttemplate: StatisticalTemplate\r\n) {\r\n\tconst compareRegex = dice.match(SIGN_REGEX_SPACE);\r\n\tlet customDice = dice;\r\n\tconst compareValue = diceTypeRandomParse(customCritical.value, template);\r\n\tif (compareValue.includes(\"$\"))\r\n\t\tthrow new DiceTypeError(compareValue, \"createCriticalCustom\");\r\n\tconst comparaison = `${customCritical.sign}${compareValue}`;\r\n\tif (compareRegex) customDice = customDice.replace(SIGN_REGEX_SPACE, comparaison);\r\n\telse customDice += comparaison;\r\n\treturn diceTypeRandomParse(customDice, template);\r\n}\r\n\r\nfunction getModifier(dice: string) {\r\n\tconst modifier = dice.matchAll(/(\\+|-|%|\\/|\\^|\\*|\\*{2})(\\d+)/gi);\r\n\tlet modificator: Modifier | undefined;\r\n\tfor (const mod of modifier) {\r\n\t\t//calculate the modifier if multiple\r\n\t\tif (modificator) {\r\n\t\t\tconst sign = modificator.sign;\r\n\t\t\tlet value = modificator.value;\r\n\t\t\tif (sign) value = calculator(sign, value, Number.parseInt(mod[2], 10));\r\n\t\t\tmodificator = {\r\n\t\t\t\tsign: mod[1] as Sign,\r\n\t\t\t\tvalue,\r\n\t\t\t};\r\n\t\t} else {\r\n\t\t\tmodificator = {\r\n\t\t\t\tsign: mod[1] as Sign,\r\n\t\t\t\tvalue: Number.parseInt(mod[2], 10),\r\n\t\t\t};\r\n\t\t}\r\n\t}\r\n\treturn modificator;\r\n}\r\n\r\n/**\r\n * Parse the string provided and turn it as a readable dice for dice parser\r\n * @param dice {string}\r\n */\r\nexport function roll(dice: string): Resultat | undefined {\r\n\t//parse dice string\r\n\tif (!dice.includes(\"d\")) return undefined;\r\n\tconst compareRegex = dice.match(SIGN_REGEX_SPACE);\r\n\tlet compare: ComparedValue | undefined;\r\n\tif (dice.includes(\";\") && dice.includes(\"&\")) return sharedRolls(dice);\r\n\tif (compareRegex) {\r\n\t\tconst compareResult = getCompare(dice, compareRegex);\r\n\t\tdice = compareResult.dice;\r\n\t\tcompare = compareResult.compare;\r\n\t}\r\n\tconst modificator = getModifier(dice);\r\n\r\n\tif (dice.match(/\\d+?#(.*)/)) {\r\n\t\tconst diceArray = dice.split(\"#\");\r\n\t\tconst numberOfDice = Number.parseInt(diceArray[0], 10);\r\n\t\tconst diceToRoll = diceArray[1].replace(COMMENT_REGEX, \"\");\r\n\t\tconst commentsMatch = diceArray[1].match(COMMENT_REGEX);\r\n\t\tconst comments = commentsMatch ? commentsMatch[2] : undefined;\r\n\t\tconst roller = new DiceRoller();\r\n\t\t//remove comments if any\r\n\t\tfor (let i = 0; i < numberOfDice; i++) {\r\n\t\t\ttry {\r\n\t\t\t\troller.roll(diceToRoll);\r\n\t\t\t} catch (error) {\r\n\t\t\t\tthrow new DiceTypeError(diceToRoll, \"roll\", error);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn {\r\n\t\t\tdice: diceToRoll,\r\n\t\t\tresult: roller.output,\r\n\t\t\tcomment: comments,\r\n\t\t\tcompare: compare ? compare : undefined,\r\n\t\t\tmodifier: modificator,\r\n\t\t\ttotal: roller.total,\r\n\t\t};\r\n\t}\r\n\tconst roller = new DiceRoller();\r\n\tconst diceWithoutComment = dice.replace(COMMENT_REGEX, \"\").trimEnd();\r\n\ttry {\r\n\t\troller.roll(diceWithoutComment);\r\n\t} catch (error) {\r\n\t\tthrow new DiceTypeError(diceWithoutComment, \"roll\", error);\r\n\t}\r\n\tconst commentMatch = dice.match(COMMENT_REGEX);\r\n\tconst comment = commentMatch ? commentMatch[2] : undefined;\r\n\treturn {\r\n\t\tdice,\r\n\t\tresult: roller.output,\r\n\t\tcomment,\r\n\t\tcompare: compare ? compare : undefined,\r\n\t\tmodifier: modificator,\r\n\t\ttotal: roller.total,\r\n\t};\r\n}\r\n/**\r\n * Evaluate a formula and replace \"^\" by \"**\" if any\r\n * @param {Sign} sign\r\n * @param {number} value\r\n * @param {number} total\r\n * @returns\r\n */\r\nexport function calculator(sign: Sign, value: number, total: number): number {\r\n\tif (sign === \"^\") sign = \"**\";\r\n\treturn evaluate(`${total} ${sign} ${value}`);\r\n}\r\n\r\nfunction inverseSign(\r\n\tsign: \"<\" | \">\" | \">=\" | \"<=\" | \"=\" | \"!=\" | \"==\"\r\n): \"<\" | \">\" | \">=\" | \"<=\" | \"=\" | \"!=\" | \"==\" {\r\n\tswitch (sign) {\r\n\t\tcase \"<\":\r\n\t\t\treturn \">\";\r\n\t\tcase \">\":\r\n\t\t\treturn \"<\";\r\n\t\tcase \"<=\":\r\n\t\t\treturn \">=\";\r\n\t\tcase \">=\":\r\n\t\t\treturn \"<=\";\r\n\t\tcase \"=\":\r\n\t\t\treturn \"!=\";\r\n\t\tcase \"==\":\r\n\t\t\treturn \"!=\";\r\n\t\tcase \"!=\":\r\n\t\t\treturn \"==\";\r\n\t}\r\n}\r\n\r\nfunction replaceInFormula(\r\n\telement: string,\r\n\tdiceResult: Resultat,\r\n\tcompareResult: { dice: string; compare: Compare | undefined },\r\n\tres: boolean\r\n) {\r\n\tconst { formule, diceAll } = replaceText(\r\n\t\telement,\r\n\t\tdiceResult.total ?? 0,\r\n\t\tdiceResult.dice\r\n\t);\r\n\tconst validSign = res ? \"✓\" : \"✕\";\r\n\tconst invertedSign = res\r\n\t\t? compareResult.compare!.sign\r\n\t\t: inverseSign(compareResult.compare!.sign);\r\n\tlet evaluateRoll: unknown;\r\n\ttry {\r\n\t\tevaluateRoll = evaluate(compareResult.dice);\r\n\t\treturn `${validSign} ${diceAll}: ${formule} = ${evaluateRoll}${invertedSign}${compareResult.compare?.value}`;\r\n\t} catch (error) {\r\n\t\tconst evaluateRoll = roll(compareResult.dice) as Resultat | undefined;\r\n\t\tif (evaluateRoll)\r\n\t\t\treturn `${validSign} ${diceAll}: ${evaluateRoll.result.split(\":\").splice(1).join(\":\")}`;\r\n\r\n\t\treturn `${validSign} ${diceAll}: ${formule} = ${evaluateRoll}${invertedSign}${compareResult.compare?.value}`;\r\n\t}\r\n}\r\n\r\nfunction compareSignFormule(\r\n\ttoRoll: string,\r\n\tcompareRegex: RegExpMatchArray,\r\n\telement: string,\r\n\tdiceResult: Resultat\r\n) {\r\n\tlet results = \"\";\r\n\tconst compareResult = getCompare(toRoll, compareRegex);\r\n\tconst toCompare = `${compareResult.dice}${compareResult.compare?.sign}${compareResult.compare?.value}`;\r\n\tlet res: unknown;\r\n\ttry {\r\n\t\tres = evaluate(toCompare);\r\n\t} catch (error) {\r\n\t\tres = roll(toCompare);\r\n\t}\r\n\tif (typeof res === \"boolean\") {\r\n\t\tresults = replaceInFormula(element, diceResult, compareResult, res);\r\n\t} else if (res instanceof Object) {\r\n\t\tconst diceResult = res as Resultat;\r\n\t\tif (diceResult.compare) {\r\n\t\t\tconst toEvaluate = evaluate(\r\n\t\t\t\t`${diceResult.total}${diceResult.compare.sign}${diceResult.compare.value}`\r\n\t\t\t);\r\n\t\t\tconst sign = toEvaluate ? \"✓\" : \"✕\";\r\n\t\t\tconst invertedSign = toEvaluate\r\n\t\t\t\t? diceResult.compare.sign\r\n\t\t\t\t: inverseSign(diceResult.compare.sign);\r\n\t\t\tconst dice = replaceText(element, 0, diceResult.dice).diceAll;\r\n\r\n\t\t\tresults = `${sign} ${dice}: ${diceResult.result.split(\":\").splice(1).join(\":\").trim()}${invertedSign}${diceResult.compare.value}`;\r\n\t\t}\r\n\t}\r\n\treturn { dice: compareResult.dice, results };\r\n}\r\n\r\nfunction replaceText(element: string, total: number, dice: string) {\r\n\treturn {\r\n\t\tformule: element.replace(SYMBOL_DICE, `[${total}]`).trim(),\r\n\t\tdiceAll: element.replace(SYMBOL_DICE, `[${dice.replace(COMMENT_REGEX, \"\")}]`).trim(),\r\n\t};\r\n}\r\n\r\nfunction sharedRolls(dice: string): Resultat | undefined {\r\n\t/* bulk roll are not allowed in shared rolls */\r\n\tif (dice.includes(\"#\"))\r\n\t\tthrow new DiceTypeError(\r\n\t\t\tdice,\r\n\t\t\t\"noBulkRoll\",\r\n\t\t\t\"bulk roll are not allowed in shared rolls\"\r\n\t\t);\r\n\tconst results = [];\r\n\tconst split = dice.split(\";\");\r\n\tconst diceResult = roll(split[0]);\r\n\tif (!diceResult || !diceResult.total) return undefined;\r\n\tresults.push(`${diceResult.result}`);\r\n\r\n\tlet total = diceResult.total;\r\n\tlet comments = diceResult.comment ?? \"\";\r\n\tif (!total) return diceResult;\r\n\tfor (let element of split.slice(1)) {\r\n\t\tif (!element.includes(SYMBOL_DICE)) {\r\n\t\t\tconst result = roll(element);\r\n\t\t\tif (!result) continue;\r\n\t\t\tresults.push(result.result);\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\t//remove comments & keep it\r\n\t\tconst commentMatch = element.match(COMMENT_REGEX);\r\n\t\telement = element.replace(COMMENT_REGEX, \"\");\r\n\t\tconst comment = commentMatch ? commentMatch[2] : undefined;\r\n\t\tif (comment) comments += ` ${comment}`;\r\n\t\tlet toRoll = element.replace(SYMBOL_DICE, `${diceResult.total}`);\r\n\t\tconst compareRegex = toRoll.match(SIGN_REGEX_SPACE);\r\n\t\tif (compareRegex) {\r\n\t\t\tconst compareResult = compareSignFormule(toRoll, compareRegex, element, diceResult);\r\n\t\t\ttoRoll = compareResult.dice;\r\n\t\t\tresults.push(compareResult.results);\r\n\t\t} else {\r\n\t\t\tconst { formule, diceAll } = replaceText(\r\n\t\t\t\telement,\r\n\t\t\t\tdiceResult.total,\r\n\t\t\t\tdiceResult.dice\r\n\t\t\t);\r\n\r\n\t\t\ttry {\r\n\t\t\t\tconst evaluated = evaluate(toRoll);\r\n\t\t\t\tresults.push(`◈ ${diceAll}: ${formule} = ${evaluated}`);\r\n\t\t\t\ttotal += Number.parseInt(evaluated, 10);\r\n\t\t\t} catch (error) {\r\n\t\t\t\tconst evaluated = roll(toRoll);\r\n\t\t\t\tif (evaluated)\r\n\t\t\t\t\tresults.push(`◈ ${diceAll}: ${evaluated.result.split(\":\").slice(1).join(\":\")}`);\r\n\t\t\t\telse results.push(`◈ ${diceAll}: ${formule} = ${evaluated}`);\r\n\t\t\t\ttotal += evaluated?.total ?? 0;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\treturn {\r\n\t\tdice: split[0],\r\n\t\tresult: results.join(\";\"),\r\n\t\tcomment: comments,\r\n\t\tcompare: diceResult.compare,\r\n\t\tmodifier: diceResult.modifier,\r\n\t\ttotal,\r\n\t};\r\n}\r\n","export class DiceTypeError extends Error {\n\tpublic readonly dice: string;\n\tpublic readonly cause: string | undefined;\n\tpublic readonly method: unknown;\n\n\tconstructor(dice: string, cause?: string, method?: unknown) {\n\t\tsuper(dice);\n\t\tthis.name = \"Invalid_Dice_Type\";\n\t\tthis.dice = dice;\n\t\tthis.cause = cause;\n\t\tthis.method = method;\n\t}\n}\n\nexport class FormulaError extends Error {\n\tpublic readonly formula: string;\n\tpublic readonly cause: string | undefined;\n\tpublic readonly method: unknown;\n\n\tconstructor(formula: string, cause?: string, method?: unknown) {\n\t\tsuper(formula);\n\t\tthis.name = \"Invalid_Formula\";\n\t\tthis.formula = formula;\n\t\tthis.cause = cause;\n\t\tthis.method = method;\n\t}\n}\n\nexport class MaxGreater extends Error {\n\tpublic readonly name: string;\n\tpublic readonly value: number;\n\tpublic readonly max: number;\n\n\tconstructor(value: number, max: number) {\n\t\tsuper(value.toString());\n\t\tthis.name = \"Max_Greater\";\n\t\tthis.value = value;\n\t\tthis.max = max;\n\t}\n}\n\nexport class EmptyObjectError extends Error {\n\tpublic readonly name: string;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.name = \"Empty_Object\";\n\t}\n}\n\nexport class TooManyDice extends Error {\n\tpublic readonly name: string;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.name = \"Too_Many_Dice\";\n\t}\n}\n\nexport class TooManyStats extends Error {\n\tpublic readonly name: string;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.name = \"Too_Many_Stats\";\n\t}\n}\n\nexport class NoStatisticsError extends Error {\n\tpublic readonly name: string;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.name = \"No_Statistics\";\n\t}\n}\n","export const COMMENT_REGEX = /\\s+(#|\\/{2}|\\[|\\/\\*)(.*)/;\nexport const SIGN_REGEX = /[><=!]+/;\nexport const SIGN_REGEX_SPACE = /[><=!]+(\\S+)/;\n\nexport const SYMBOL_DICE = \"&\";\n","import { evaluate } from \"mathjs\";\nimport \"uniformize\";\nimport { FormulaError } from \"./errors\";\n\n/**\n * Escape regex string\n * @param string {string}\n */\nexport function escapeRegex(string: string) {\n\treturn string.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Replace the stat name by their value using stat and after evaluate any formula using `replaceFormulaInDice`\n * @param originalDice {dice}\n * @param stats {Record<string,number>}\n * @param dollarValue\n */\nexport function generateStatsDice(\n\toriginalDice: string,\n\tstats?: Record<string, number>,\n\tdollarValue?: string\n) {\n\tlet dice = originalDice.standardize();\n\tif (stats && Object.keys(stats).length > 0) {\n\t\t//damage field support adding statistic, like : 1d6 + strength\n\t\t//check if the value contains a statistic & calculate if it's okay\n\t\t//the dice will be converted before roll\n\t\tconst allStats = Object.keys(stats);\n\t\tfor (const stat of allStats) {\n\t\t\tconst regex = new RegExp(escapeRegex(stat.standardize()), \"gi\");\n\t\t\tif (dice.match(regex)) {\n\t\t\t\tconst statValue = stats[stat];\n\t\t\t\tdice = dice.replace(regex, statValue.toString());\n\t\t\t}\n\t\t}\n\t}\n\tif (dollarValue) dice = dice.replaceAll(\"$\", dollarValue);\n\treturn replaceFormulaInDice(dice);\n}\n\n/**\n * Replace the {{}} in the dice string and evaluate the interior if any\n * @param dice {string}\n */\nexport function replaceFormulaInDice(dice: string) {\n\tconst formula = /(?<formula>\\{{2}(.+?)}{2})/gim;\n\t// biome-ignore lint/suspicious/noImplicitAnyLet: <explanation>\n\tlet match;\n\tlet modifiedDice = dice.standardize();\n\t// biome-ignore lint/suspicious/noAssignInExpressions: <explanation>\n\twhile ((match = formula.exec(dice)) !== null) {\n\t\tif (match.groups?.formula) {\n\t\t\tconst formulae = match.groups.formula.replaceAll(\"{{\", \"\").replaceAll(\"}}\", \"\");\n\t\t\ttry {\n\t\t\t\tconst result = evaluate(formulae);\n\t\t\t\tmodifiedDice = modifiedDice.replace(match.groups.formula, result.toString());\n\t\t\t} catch (error) {\n\t\t\t\tthrow new FormulaError(match.groups.formula, \"replaceFormulasInDice\", error);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn cleanedDice(modifiedDice);\n}\n\n/**\n * Replace the ++ +- -- by their proper value:\n * - `++` = `+`\n * - `+-` = `-`\n * - `--` = `+`\n * @param dice {string}\n */\nexport function cleanedDice(dice: string) {\n\treturn dice.replaceAll(\"+-\", \"-\").replaceAll(\"--\", \"+\").replaceAll(\"++\", \"+\").trimEnd();\n}\n","/* eslint-disable @typescript-eslint/no-unused-vars */\nimport { evaluate } from \"mathjs\";\nimport { Random } from \"random-js\";\nimport \"uniformize\";\n\nimport type { StatisticalTemplate } from \".\";\nimport { createCriticalCustom, roll } from \"./dice\";\nimport {\n\tDiceTypeError,\n\tEmptyObjectError,\n\tFormulaError,\n\tNoStatisticsError,\n\tTooManyDice,\n} from \"./errors\";\nimport { templateSchema } from \"./interfaces/zod\";\nimport { escapeRegex, replaceFormulaInDice } from \"./utils\";\n\n/**\n * Verify if the provided dice work with random value\n * @param testDice {string}\n * @param allStats {Record<string,number>}\n */\nexport function evalStatsDice(testDice: string, allStats?: Record<string, number>) {\n\tlet dice = testDice.trimEnd();\n\tif (allStats && Object.keys(allStats).length > 0) {\n\t\tconst names = Object.keys(allStats);\n\t\tfor (const name of names) {\n\t\t\tconst regex = new RegExp(escapeRegex(name.standardize()), \"gi\");\n\t\t\tif (dice.standardize().match(regex)) {\n\t\t\t\tconst statValue = allStats[name];\n\t\t\t\tdice = dice.standardize().replace(regex, statValue.toString()).trimEnd();\n\t\t\t}\n\t\t}\n\t}\n\ttry {\n\t\tif (!roll(replaceFormulaInDice(dice)))\n\t\t\tthrow new DiceTypeError(dice, \"evalStatsDice\", \"no roll result\");\n\t\treturn testDice;\n\t} catch (error) {\n\t\tthrow new DiceTypeError(dice, \"evalStatsDice\", error);\n\t}\n}\n\n/**\n * Generate a random dice and remove the formula (+ evaluate it)\n * Used for diceDamage only\n * @param value {string}\n * @param template {StatisticalTemplate}\n * @returns\n */\nexport function diceRandomParse(value: string, template: StatisticalTemplate) {\n\tif (!template.statistics) return value;\n\tvalue = value.standardize();\n\tconst statNames = Object.keys(template.statistics);\n\tlet newDice = value;\n\tfor (const name of statNames) {\n\t\tconst regex = new RegExp(escapeRegex(name.standardize()), \"gi\");\n\t\tif (value.match(regex)) {\n\t\t\tlet max: undefined | number = undefined;\n\t\t\tlet min: undefined | number = undefined;\n\t\t\tconst foundStat = template.statistics?.[name];\n\t\t\tif (foundStat) {\n\t\t\t\tmax = foundStat.max;\n\t\t\t\tmin = foundStat.min;\n\t\t\t}\n\t\t\tconst total = template.total || 100;\n\t\t\tconst randomStatValue = generateRandomStat(total, max, min);\n\t\t\tnewDice = value.replace(regex, randomStatValue.toString());\n\t\t}\n\t}\n\treturn replaceFormulaInDice(newDice);\n}\n\n/**\n * Same as damageDice but for DiceType\n * @param dice {string}\n * @param template {StatisticalTemplate}\n */\nexport function diceTypeRandomParse(dice: string, template: StatisticalTemplate) {\n\tif (!template.statistics) return dice;\n\tconst firstStatNotcombinaison = Object.keys(template.statistics).find(\n\t\t(stat) => !template.statistics?.[stat].combinaison\n\t);\n\tif (!firstStatNotcombinaison) return dice;\n\tconst stats = template.statistics[firstStatNotcombinaison];\n\tconst { min, max } = stats;\n\tconst total = template.total || 100;\n\tconst randomStatValue = generateRandomStat(total, max, min);\n\treturn replaceFormulaInDice(dice.replaceAll(\"$\", randomStatValue.toString()));\n}\n\n/**\n * Random the combinaison and evaluate it to check if everything is valid\n * @param combinaison {Record<string,string>}\n * @param stats {Record<string,number|number>}\n */\nexport function evalCombinaison(\n\tcombinaison: Record<string, string>,\n\tstats: Record<string, number | string>\n) {\n\tconst newStats: Record<string, number> = {};\n\tfor (const [stat, combin] of Object.entries(combinaison)) {\n\t\t//replace the stats in formula\n\t\tlet formula = combin.standardize();\n\t\tfor (const [statName, value] of Object.entries(stats)) {\n\t\t\tconst regex = new RegExp(statName.standardize(), \"gi\");\n\t\t\tformula = formula.replace(regex, value.toString());\n\t\t}\n\t\ttry {\n\t\t\tnewStats[stat] = evaluate(formula);\n\t\t} catch (error) {\n\t\t\tthrow new FormulaError(stat, \"evalCombinaison\", error);\n\t\t}\n\t}\n\treturn newStats;\n}\n\n/**\n * Evaluate one selected combinaison\n * @param combinaison {string}\n * @param stats {[name: string]: string|number}\n */\nexport function evalOneCombinaison(\n\tcombinaison: string,\n\tstats: Record<string, number | string>\n) {\n\tlet formula = combinaison.standardize();\n\tfor (const [statName, value] of Object.entries(stats)) {\n\t\tconst regex = new RegExp(statName.standardize(), \"gi\");\n\t\tformula = formula.replace(regex, value.toString());\n\t}\n\ttry {\n\t\treturn evaluate(formula);\n\t} catch (error) {\n\t\tthrow new FormulaError(combinaison, \"evalOneCombinaison\", error);\n\t}\n}\n\nfunction convertNumber(number: string | number | undefined) {\n\tif (!number) return undefined;\n\tconst isNumber = (value: unknown): boolean =>\n\t\ttypeof value === \"number\" ||\n\t\t(!Number.isNaN(Number(value)) && typeof value === \"string\");\n\tif (number.toString().length === 0) return undefined;\n\tif (isNumber(number)) return Number.parseInt(number.toString(), 10);\n\treturn undefined;\n}\n\n/**\n * Parse the provided JSON and verify each field to check if everything could work when rolling\n * @param {any} template\n * @returns {StatisticalTemplate}\n */\nexport function verifyTemplateValue(template: unknown): StatisticalTemplate {\n\tconst parsedTemplate = templateSchema.parse(template);\n\tconst { success, failure } = parsedTemplate.critical ?? {};\n\tconst criticicalVal = {\n\t\tsuccess: convertNumber(success),\n\t\tfailure: convertNumber(failure),\n\t};\n\tconst statistiqueTemplate: StatisticalTemplate = {\n\t\tdiceType: parsedTemplate.diceType,\n\t\tstatistics: parsedTemplate.statistics,\n\t\tcritical: criticicalVal,\n\t\ttotal: parsedTemplate.total,\n\t\tcharName: parsedTemplate.charName,\n\t\tdamage: parsedTemplate.damage,\n\t\tcustomCritical: parsedTemplate.customCritical,\n\t};\n\tif (statistiqueTemplate.diceType) {\n\t\tconst cleanedDice = diceTypeRandomParse(\n\t\t\tstatistiqueTemplate.diceType,\n\t\t\tstatistiqueTemplate\n\t\t);\n\t\tconst rolled = roll(cleanedDice);\n\t\tif (!rolled) {\n\t\t\tthrow new DiceTypeError(cleanedDice, \"verifyTemplateValue\", \"no roll result\");\n\t\t}\n\t}\n\tif (statistiqueTemplate.customCritical) {\n\t\tif (!statistiqueTemplate.diceType) {\n\t\t\tthrow new DiceTypeError(\"no_dice_type\", \"verifyTemplateValue\", \"no dice type\");\n\t\t}\n\t\tconst customCritical = statistiqueTemplate.customCritical;\n\t\tfor (const [, custom] of Object.entries(customCritical)) {\n\t\t\tconst cleanedDice = createCriticalCustom(\n\t\t\t\tstatistiqueTemplate.diceType!,\n\t\t\t\tcustom,\n\t\t\t\tstatistiqueTemplate\n\t\t\t);\n\t\t\tconst rolled = roll(cleanedDice);\n\t\t\tif (!rolled)\n\t\t\t\tthrow new DiceTypeError(cleanedDice, \"verifyTemplateValue\", \"no roll result\");\n\t\t}\n\t}\n\ttestDiceRegistered(statistiqueTemplate);\n\ttestStatCombinaison(statistiqueTemplate);\n\treturn statistiqueTemplate;\n}\n\n/**\n * Test each damage roll from the template.damage\n * @param {StatisticalTemplate} template\n */\nexport function testDiceRegistered(template: StatisticalTemplate) {\n\tif (!template.damage) return;\n\tif (Object.keys(template.damage).length === 0) throw new EmptyObjectError();\n\tif (Object.keys(template.damage).length > 25) throw new TooManyDice();\n\tfor (const [name, dice] of Object.entries(template.damage)) {\n\t\tif (!dice) continue;\n\t\tconst randomDiceParsed = diceRandomParse(dice, template);\n\t\ttry {\n\t\t\tconst rolled = roll(randomDiceParsed);\n\t\t\tif (!rolled) throw new DiceTypeError(name, \"no_roll_result\", dice);\n\t\t} catch (error) {\n\t\t\tconsole.error(error);\n\t\t\tthrow new DiceTypeError(name, \"testDiceRegistered\", error);\n\t\t}\n\t}\n}\n\n/**\n * Test all combinaison with generated random value\n * @param {StatisticalTemplate} template\n */\nexport function testStatCombinaison(template: StatisticalTemplate) {\n\tif (!template.statistics) return;\n\tconst onlycombinaisonStats = Object.fromEntries(\n\t\tObject.entries(template.statistics).filter(\n\t\t\t([_, value]) => value.combinaison !== undefined\n\t\t)\n\t);\n\tconst allOtherStats = Object.fromEntries(\n\t\tObject.entries(template.statistics).filter(([_, value]) => !value.combinaison)\n\t);\n\tif (Object.keys(onlycombinaisonStats).length === 0) return;\n\tconst allStats = Object.keys(template.statistics).filter(\n\t\t(stat) => !template.statistics![stat].combinaison\n\t);\n\tif (allStats.length === 0) throw new NoStatisticsError();\n\tconst error = [];\n\tfor (const [stat, value] of Object.entries(onlycombinaisonStats)) {\n\t\tlet formula = value.combinaison as string;\n\t\tfor (const [other, data] of Object.entries(allOtherStats)) {\n\t\t\tconst { max, min } = data;\n\t\t\tconst total = template.total || 100;\n\t\t\tconst randomStatValue = generateRandomStat(total, max, min);\n\t\t\tconst regex = new RegExp(other, \"gi\");\n\t\t\tformula = formula.replace(regex, randomStatValue.toString());\n\t\t}\n\t\ttry {\n\t\t\tevaluate(formula);\n\t\t} catch (e) {\n\t\t\terror.push(stat);\n\t\t}\n\t}\n\tif (error.length > 0) throw new FormulaError(error.join(\", \"), \"testStatCombinaison\");\n\treturn;\n}\n\n/**\n * Generate a random stat based on the template and the statistical min and max\n * @param {number|undefined} total\n * @param {number | undefined} max\n * @param {number | undefined} min\n * @returns\n */\nexport function generateRandomStat(\n\ttotal: number | undefined = 100,\n\tmax?: number,\n\tmin?: number\n) {\n\tlet randomStatValue = total + 1;\n\twhile (randomStatValue >= total || randomStatValue === 0) {\n\t\tconst random = new Random();\n\t\tif (max && min) randomStatValue = random.integer(min, max);\n\t\telse if (max) randomStatValue = random.integer(1, max);\n\t\telse if (min) randomStatValue = random.integer(min, total);\n\t\telse randomStatValue = random.integer(1, total);\n\t}\n\treturn randomStatValue;\n}\n","/**\n * Definition of the Zod schema for template data\n */\nimport { z } from \"zod\";\n\nconst statisticValueSchema = z\n\t.object({\n\t\tmax: z.number().positive().optional(),\n\t\tmin: z.number().positive().optional(),\n\t\tcombinaison: z\n\t\t\t.string()\n\t\t\t.transform((str) => str.trim() || undefined)\n\t\t\t.optional(),\n\t\texclude: z.boolean().optional(),\n\t})\n\t.superRefine((data, ctx) => {\n\t\tif (data.max !== undefined && data.min !== undefined && data.max <= data.min) {\n\t\t\tctx.addIssue({\n\t\t\t\tcode: \"custom\",\n\t\t\t\tmessage: `Max_Greater; ${data.min}; ${data.max}`,\n\t\t\t\tpath: [\"max\"],\n\t\t\t});\n\t\t}\n\t});\n\nconst statisticSchema = z\n\t.record(statisticValueSchema)\n\t.optional()\n\t.refine((stats) => !stats || Object.keys(stats).length <= 25, {\n\t\tmessage: \"TooManyStats\",\n\t});\n\nconst criticalSchema = z\n\t.object({\n\t\tsuccess: z.string().or(z.number().positive()).optional(),\n\t\tfailure: z.string().or(z.number().positive()).optional(),\n\t})\n\t.transform((values) => {\n\t\tif (values.success === \"\") values.success = undefined;\n\t\tif (values.failure === \"\") values.failure = undefined;\n\t\tif (values.failure === 0) values.failure = undefined;\n\t\tif (values.success === 0) values.success = undefined;\n\t\tvalues.success = Number.parseInt(values.success as string, 10);\n\t\tvalues.failure = Number.parseInt(values.failure as string, 10);\n\t\treturn values;\n\t});\n\nconst criticalValueSchema = z.object({\n\tsign: z.enum([\"<\", \">\", \"<=\", \">=\", \"!=\", \"==\"]),\n\tvalue: z.string(),\n\tonNaturalDice: z.boolean().optional(),\n\taffectSkill: z.boolean().optional(),\n});\n\nconst damageSchema = z\n\t.record(z.string())\n\t.optional()\n\t.refine((stats) => !stats || Object.keys(stats).length <= 25, {\n\t\tmessage: \"TooManyDice\",\n\t});\n\nconst customCriticalSchema = z\n\t.record(criticalValueSchema)\n\t.optional()\n\t.refine((stats) => !stats || Object.keys(stats).length <= 22, {\n\t\tmessage: \"TooManyDice\",\n\t});\n\nexport const templateSchema = z.object({\n\tcharName: z.boolean().optional(),\n\tstatistics: statisticSchema,\n\ttotal: z.number().min(0).optional(),\n\tdiceType: z.string().optional(),\n\tcritical: criticalSchema.optional(),\n\tcustomCritical: customCriticalSchema,\n\tdamage: damageSchema,\n});\n"],"mappings":"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","names":["value","roller","evaluateRoll","diceResult","import_mathjs","import_mathjs","import_uniformize","cleanedDice"]}
|
package/dist/index.mjs
CHANGED
@@ -338,7 +338,7 @@ import "uniformize";
|
|
338
338
|
function escapeRegex(string) {
|
339
339
|
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
340
340
|
}
|
341
|
-
function generateStatsDice(originalDice, stats) {
|
341
|
+
function generateStatsDice(originalDice, stats, dollarValue) {
|
342
342
|
let dice = originalDice.standardize();
|
343
343
|
if (stats && Object.keys(stats).length > 0) {
|
344
344
|
const allStats = Object.keys(stats);
|
@@ -350,6 +350,7 @@ function generateStatsDice(originalDice, stats) {
|
|
350
350
|
}
|
351
351
|
}
|
352
352
|
}
|
353
|
+
if (dollarValue) dice = dice.replaceAll("$", dollarValue);
|
353
354
|
return replaceFormulaInDice(dice);
|
354
355
|
}
|
355
356
|
function replaceFormulaInDice(dice) {
|
@@ -383,7 +384,8 @@ import { z } from "zod";
|
|
383
384
|
var statisticValueSchema = z.object({
|
384
385
|
max: z.number().positive().optional(),
|
385
386
|
min: z.number().positive().optional(),
|
386
|
-
combinaison: z.string().transform((str) => str.trim() || void 0).optional()
|
387
|
+
combinaison: z.string().transform((str) => str.trim() || void 0).optional(),
|
388
|
+
exclude: z.boolean().optional()
|
387
389
|
}).superRefine((data, ctx) => {
|
388
390
|
if (data.max !== void 0 && data.min !== void 0 && data.max <= data.min) {
|
389
391
|
ctx.addIssue({
|
@@ -553,7 +555,6 @@ function verifyTemplateValue(template) {
|
|
553
555
|
const customCritical = statistiqueTemplate.customCritical;
|
554
556
|
for (const [, custom] of Object.entries(customCritical)) {
|
555
557
|
const cleanedDice2 = createCriticalCustom(
|
556
|
-
// biome-ignore lint/style/noNonNullAssertion: <explanation>
|
557
558
|
statistiqueTemplate.diceType,
|
558
559
|
custom,
|
559
560
|
statistiqueTemplate
|
package/dist/index.mjs.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../src/dice.ts","../src/errors.ts","../src/interfaces/constant.ts","../src/utils.ts","../src/verify_template.ts","../src/interfaces/zod.ts"],"sourcesContent":["import { DiceRoller } from \"@dice-roller/rpg-dice-roller\";\r\nimport { evaluate } from \"mathjs\";\r\n\r\nimport {\r\n\ttype Compare,\r\n\ttype CustomCritical,\r\n\ttype Modifier,\r\n\ttype Resultat,\r\n\ttype Sign,\r\n\ttype StatisticalTemplate,\r\n\tdiceTypeRandomParse,\r\n} from \".\";\r\nimport { DiceTypeError } from \"./errors\";\r\nimport {\r\n\tCOMMENT_REGEX,\r\n\tSIGN_REGEX,\r\n\tSIGN_REGEX_SPACE,\r\n\tSYMBOL_DICE,\r\n} from \"./interfaces/constant\";\r\n\r\nfunction getCompare(\r\n\tdice: string,\r\n\tcompareRegex: RegExpMatchArray\r\n): { dice: string; compare: Compare | undefined } {\r\n\tdice = dice.replace(SIGN_REGEX_SPACE, \"\");\r\n\tlet compare: Compare;\r\n\tconst calc = compareRegex[1];\r\n\tconst sign = calc.match(/[+-\\/*^]/)?.[0];\r\n\tconst compareSign = compareRegex[0].match(SIGN_REGEX)?.[0];\r\n\tif (sign) {\r\n\t\tconst toCalc = calc.replace(SIGN_REGEX, \"\").replace(/\\s/g, \"\").replace(/;(.*)/, \"\");\r\n\t\tconst rCompare = rollCompare(toCalc);\r\n\t\tconst total = evaluate(rCompare.value.toString());\r\n\t\tdice = dice.replace(SIGN_REGEX_SPACE, `${compareSign}${total}`);\r\n\t\tcompare = {\r\n\t\t\tsign: compareSign as \"<\" | \">\" | \">=\" | \"<=\" | \"=\" | \"!=\" | \"==\",\r\n\t\t\tvalue: total,\r\n\t\t\toriginalDice: rCompare.dice,\r\n\t\t\trollValue: rCompare.diceResult,\r\n\t\t};\r\n\t} else {\r\n\t\tconst rcompare = rollCompare(calc);\r\n\t\tcompare = {\r\n\t\t\tsign: compareSign as \"<\" | \">\" | \">=\" | \"<=\" | \"=\" | \"!=\" | \"==\",\r\n\t\t\tvalue: rcompare.value,\r\n\t\t\toriginalDice: rcompare.dice,\r\n\t\t\trollValue: rcompare.diceResult,\r\n\t\t};\r\n\t}\r\n\treturn { dice, compare };\r\n}\r\n\r\nfunction rollCompare(value: unknown) {\r\n\tconst isNumber = (value: unknown): boolean =>\r\n\t\ttypeof value === \"number\" ||\r\n\t\t(!Number.isNaN(Number(value)) && typeof value === \"string\");\r\n\tif (isNumber(value)) return { value: Number.parseInt(value as string, 10) };\r\n\tconst rollComp = roll(value as string);\r\n\tif (!rollComp?.total) //not a dice throw\r\n\t\treturn { value: evaluate(value as string), diceResult: value as string };\r\n\treturn {\r\n\t\tdice: value as string,\r\n\t\tvalue: rollComp.total,\r\n\t\tdiceResult: rollComp?.result,\r\n\t};\r\n}\r\n\r\n/**\r\n * Allow to replace the compare part of a dice and use the critical customized one\r\n * @example\r\n * dice = \"1d20=20\";\r\n * custom critical {sign: \">\", value: \"$/2\"}\r\n * Random stats = 6\r\n * result = \"1d20>3\"\r\n */\r\nexport function createCriticalCustom(\r\n\tdice: string,\r\n\tcustomCritical: CustomCritical,\r\n\ttemplate: StatisticalTemplate\r\n) {\r\n\tconst compareRegex = dice.match(SIGN_REGEX_SPACE);\r\n\tlet customDice = dice;\r\n\tconst compareValue = diceTypeRandomParse(customCritical.value, template);\r\n\tif (compareValue.includes(\"$\"))\r\n\t\tthrow new DiceTypeError(compareValue, \"createCriticalCustom\");\r\n\tconst comparaison = `${customCritical.sign}${compareValue}`;\r\n\tif (compareRegex) customDice = customDice.replace(SIGN_REGEX_SPACE, comparaison);\r\n\telse customDice += comparaison;\r\n\treturn diceTypeRandomParse(customDice, template);\r\n}\r\n\r\nfunction getModifier(dice: string) {\r\n\tconst modifier = dice.matchAll(/(\\+|-|%|\\/|\\^|\\*|\\*{2})(\\d+)/gi);\r\n\tlet modificator: Modifier | undefined;\r\n\tfor (const mod of modifier) {\r\n\t\t//calculate the modifier if multiple\r\n\t\tif (modificator) {\r\n\t\t\tconst sign = modificator.sign;\r\n\t\t\tlet value = modificator.value;\r\n\t\t\tif (sign) value = calculator(sign, value, Number.parseInt(mod[2], 10));\r\n\t\t\tmodificator = {\r\n\t\t\t\tsign: mod[1] as Sign,\r\n\t\t\t\tvalue,\r\n\t\t\t};\r\n\t\t} else {\r\n\t\t\tmodificator = {\r\n\t\t\t\tsign: mod[1] as Sign,\r\n\t\t\t\tvalue: Number.parseInt(mod[2], 10),\r\n\t\t\t};\r\n\t\t}\r\n\t}\r\n\treturn modificator;\r\n}\r\n\r\n/**\r\n * Parse the string provided and turn it as a readable dice for dice parser\r\n * @param dice {string}\r\n */\r\nexport function roll(dice: string): Resultat | undefined {\r\n\t//parse dice string\r\n\tif (!dice.includes(\"d\")) return undefined;\r\n\tconst compareRegex = dice.match(SIGN_REGEX_SPACE);\r\n\tlet compare: Compare | undefined;\r\n\tif (dice.includes(\";\") && dice.includes(\"&\")) return sharedRolls(dice);\r\n\tif (compareRegex) {\r\n\t\tconst compareResult = getCompare(dice, compareRegex);\r\n\t\tdice = compareResult.dice;\r\n\t\tcompare = compareResult.compare;\r\n\t}\r\n\tconst modificator = getModifier(dice);\r\n\r\n\tif (dice.match(/\\d+?#(.*)/)) {\r\n\t\tconst diceArray = dice.split(\"#\");\r\n\t\tconst numberOfDice = Number.parseInt(diceArray[0], 10);\r\n\t\tconst diceToRoll = diceArray[1].replace(COMMENT_REGEX, \"\");\r\n\t\tconst commentsMatch = diceArray[1].match(COMMENT_REGEX);\r\n\t\tconst comments = commentsMatch ? commentsMatch[2] : undefined;\r\n\t\tconst roller = new DiceRoller();\r\n\t\t//remove comments if any\r\n\t\tfor (let i = 0; i < numberOfDice; i++) {\r\n\t\t\ttry {\r\n\t\t\t\troller.roll(diceToRoll);\r\n\t\t\t} catch (error) {\r\n\t\t\t\tthrow new DiceTypeError(diceToRoll, \"roll\", error);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn {\r\n\t\t\tdice: diceToRoll,\r\n\t\t\tresult: roller.output,\r\n\t\t\tcomment: comments,\r\n\t\t\tcompare: compare ? compare : undefined,\r\n\t\t\tmodifier: modificator,\r\n\t\t\ttotal: roller.total,\r\n\t\t};\r\n\t}\r\n\tconst roller = new DiceRoller();\r\n\tconst diceWithoutComment = dice.replace(COMMENT_REGEX, \"\").trimEnd();\r\n\ttry {\r\n\t\troller.roll(diceWithoutComment);\r\n\t} catch (error) {\r\n\t\tthrow new DiceTypeError(diceWithoutComment, \"roll\", error);\r\n\t}\r\n\tconst commentMatch = dice.match(COMMENT_REGEX);\r\n\tconst comment = commentMatch ? commentMatch[2] : undefined;\r\n\treturn {\r\n\t\tdice,\r\n\t\tresult: roller.output,\r\n\t\tcomment,\r\n\t\tcompare: compare ? compare : undefined,\r\n\t\tmodifier: modificator,\r\n\t\ttotal: roller.total,\r\n\t};\r\n}\r\n/**\r\n * Evaluate a formula and replace \"^\" by \"**\" if any\r\n * @param {Sign} sign\r\n * @param {number} value\r\n * @param {number} total\r\n * @returns\r\n */\r\nexport function calculator(sign: Sign, value: number, total: number): number {\r\n\tif (sign === \"^\") sign = \"**\";\r\n\treturn evaluate(`${total} ${sign} ${value}`);\r\n}\r\n\r\nfunction inverseSign(\r\n\tsign: \"<\" | \">\" | \">=\" | \"<=\" | \"=\" | \"!=\" | \"==\"\r\n): \"<\" | \">\" | \">=\" | \"<=\" | \"=\" | \"!=\" | \"==\" {\r\n\tswitch (sign) {\r\n\t\tcase \"<\":\r\n\t\t\treturn \">\";\r\n\t\tcase \">\":\r\n\t\t\treturn \"<\";\r\n\t\tcase \"<=\":\r\n\t\t\treturn \">=\";\r\n\t\tcase \">=\":\r\n\t\t\treturn \"<=\";\r\n\t\tcase \"=\":\r\n\t\t\treturn \"!=\";\r\n\t\tcase \"==\":\r\n\t\t\treturn \"!=\";\r\n\t\tcase \"!=\":\r\n\t\t\treturn \"==\";\r\n\t}\r\n}\r\n\r\nfunction replaceInFormula(\r\n\telement: string,\r\n\tdiceResult: Resultat,\r\n\tcompareResult: { dice: string; compare: Compare | undefined },\r\n\tres: boolean\r\n) {\r\n\tconst { formule, diceAll } = replaceText(\r\n\t\telement,\r\n\t\tdiceResult.total ?? 0,\r\n\t\tdiceResult.dice\r\n\t);\r\n\tconst validSign = res ? \"✓\" : \"✕\";\r\n\tconst invertedSign = res\r\n\t\t? compareResult.compare!.sign\r\n\t\t: inverseSign(compareResult.compare!.sign);\r\n\tlet evaluateRoll: unknown;\r\n\ttry {\r\n\t\tevaluateRoll = evaluate(compareResult.dice);\r\n\t\treturn `${validSign} ${diceAll}: ${formule} = ${evaluateRoll}${invertedSign}${compareResult.compare?.value}`;\r\n\t} catch (error) {\r\n\t\tconst evaluateRoll = roll(compareResult.dice) as Resultat | undefined;\r\n\t\tif (evaluateRoll)\r\n\t\t\treturn `${validSign} ${diceAll}: ${evaluateRoll.result.split(\":\").splice(1).join(\":\")}`;\r\n\r\n\t\treturn `${validSign} ${diceAll}: ${formule} = ${evaluateRoll}${invertedSign}${compareResult.compare?.value}`;\r\n\t}\r\n}\r\n\r\nfunction compareSignFormule(\r\n\ttoRoll: string,\r\n\tcompareRegex: RegExpMatchArray,\r\n\telement: string,\r\n\tdiceResult: Resultat\r\n) {\r\n\tlet results = \"\";\r\n\tconst compareResult = getCompare(toRoll, compareRegex);\r\n\tconst toCompare = `${compareResult.dice}${compareResult.compare?.sign}${compareResult.compare?.value}`;\r\n\tlet res: unknown;\r\n\ttry {\r\n\t\tres = evaluate(toCompare);\r\n\t} catch (error) {\r\n\t\tres = roll(toCompare);\r\n\t}\r\n\tif (typeof res === \"boolean\") {\r\n\t\tresults = replaceInFormula(element, diceResult, compareResult, res);\r\n\t} else if (res instanceof Object) {\r\n\t\tconst diceResult = res as Resultat;\r\n\t\tif (diceResult.compare) {\r\n\t\t\tconst toEvaluate = evaluate(\r\n\t\t\t\t`${diceResult.total}${diceResult.compare.sign}${diceResult.compare.value}`\r\n\t\t\t);\r\n\t\t\tconst sign = toEvaluate ? \"✓\" : \"✕\";\r\n\t\t\tconst invertedSign = toEvaluate\r\n\t\t\t\t? diceResult.compare.sign\r\n\t\t\t\t: inverseSign(diceResult.compare.sign);\r\n\t\t\tconst dice = replaceText(element, 0, diceResult.dice).diceAll;\r\n\r\n\t\t\tresults = `${sign} ${dice}: ${diceResult.result.split(\":\").splice(1).join(\":\").trim()}${invertedSign}${diceResult.compare.value}`;\r\n\t\t}\r\n\t}\r\n\treturn { dice: compareResult.dice, results };\r\n}\r\n\r\nfunction replaceText(element: string, total: number, dice: string) {\r\n\treturn {\r\n\t\tformule: element.replace(SYMBOL_DICE, `[${total}]`).trim(),\r\n\t\tdiceAll: element.replace(SYMBOL_DICE, `[${dice.replace(COMMENT_REGEX, \"\")}]`).trim(),\r\n\t};\r\n}\r\n\r\nfunction sharedRolls(dice: string): Resultat | undefined {\r\n\t/* bulk roll are not allowed in shared rolls */\r\n\tif (dice.includes(\"#\"))\r\n\t\tthrow new DiceTypeError(\r\n\t\t\tdice,\r\n\t\t\t\"noBulkRoll\",\r\n\t\t\t\"bulk roll are not allowed in shared rolls\"\r\n\t\t);\r\n\tconst results = [];\r\n\tconst split = dice.split(\";\");\r\n\tconst diceResult = roll(split[0]);\r\n\tif (!diceResult || !diceResult.total) return undefined;\r\n\tresults.push(`${diceResult.result}`);\r\n\r\n\tlet total = diceResult.total;\r\n\tlet comments = diceResult.comment ?? \"\";\r\n\tif (!total) return diceResult;\r\n\tfor (let element of split.slice(1)) {\r\n\t\tif (!element.includes(SYMBOL_DICE)) {\r\n\t\t\tconst result = roll(element);\r\n\t\t\tif (!result) continue;\r\n\t\t\tresults.push(result.result);\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\t//remove comments & keep it\r\n\t\tconst commentMatch = element.match(COMMENT_REGEX);\r\n\t\telement = element.replace(COMMENT_REGEX, \"\");\r\n\t\tconst comment = commentMatch ? commentMatch[2] : undefined;\r\n\t\tif (comment) comments += ` ${comment}`;\r\n\t\tlet toRoll = element.replace(SYMBOL_DICE, `${diceResult.total}`);\r\n\t\tconst compareRegex = toRoll.match(SIGN_REGEX_SPACE);\r\n\t\tif (compareRegex) {\r\n\t\t\tconst compareResult = compareSignFormule(toRoll, compareRegex, element, diceResult);\r\n\t\t\ttoRoll = compareResult.dice;\r\n\t\t\tresults.push(compareResult.results);\r\n\t\t} else {\r\n\t\t\tconst { formule, diceAll } = replaceText(\r\n\t\t\t\telement,\r\n\t\t\t\tdiceResult.total,\r\n\t\t\t\tdiceResult.dice\r\n\t\t\t);\r\n\r\n\t\t\ttry {\r\n\t\t\t\tconst evaluated = evaluate(toRoll);\r\n\t\t\t\tresults.push(`◈ ${diceAll}: ${formule} = ${evaluated}`);\r\n\t\t\t\ttotal += Number.parseInt(evaluated, 10);\r\n\t\t\t} catch (error) {\r\n\t\t\t\tconst evaluated = roll(toRoll);\r\n\t\t\t\tif (evaluated)\r\n\t\t\t\t\tresults.push(`◈ ${diceAll}: ${evaluated.result.split(\":\").slice(1).join(\":\")}`);\r\n\t\t\t\telse results.push(`◈ ${diceAll}: ${formule} = ${evaluated}`);\r\n\t\t\t\ttotal += evaluated?.total ?? 0;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\treturn {\r\n\t\tdice: split[0],\r\n\t\tresult: results.join(\";\"),\r\n\t\tcomment: comments,\r\n\t\tcompare: diceResult.compare,\r\n\t\tmodifier: diceResult.modifier,\r\n\t\ttotal,\r\n\t};\r\n}\r\n","export class DiceTypeError extends Error {\r\n\tpublic readonly dice: string;\r\n\tpublic readonly cause: string | undefined;\r\n\tpublic readonly method: unknown;\r\n\r\n\tconstructor(dice: string, cause?: string, method?: unknown) {\r\n\t\tsuper(dice);\r\n\t\tthis.name = \"Invalid_Dice_Type\";\r\n\t\tthis.dice = dice;\r\n\t\tthis.cause = cause;\r\n\t\tthis.method = method;\r\n\t}\r\n}\r\n\r\nexport class FormulaError extends Error {\r\n\tpublic readonly formula: string;\r\n\tpublic readonly cause: string | undefined;\r\n\tpublic readonly method: unknown;\r\n\r\n\tconstructor(formula: string, cause?: string, method?: unknown) {\r\n\t\tsuper(formula);\r\n\t\tthis.name = \"Invalid_Formula\";\r\n\t\tthis.formula = formula;\r\n\t\tthis.cause = cause;\r\n\t\tthis.method = method;\r\n\t}\r\n}\r\n\r\nexport class MaxGreater extends Error {\r\n\tpublic readonly name: string;\r\n\tpublic readonly value: number;\r\n\tpublic readonly max: number;\r\n\r\n\tconstructor(value: number, max: number) {\r\n\t\tsuper(value.toString());\r\n\t\tthis.name = \"Max_Greater\";\r\n\t\tthis.value = value;\r\n\t\tthis.max = max;\r\n\t}\r\n}\r\n\r\nexport class EmptyObjectError extends Error {\r\n\tpublic readonly name: string;\r\n\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t\tthis.name = \"Empty_Object\";\r\n\t}\r\n}\r\n\r\nexport class TooManyDice extends Error {\r\n\tpublic readonly name: string;\r\n\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t\tthis.name = \"Too_Many_Dice\";\r\n\t}\r\n}\r\n\r\nexport class TooManyStats extends Error {\r\n\tpublic readonly name: string;\r\n\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t\tthis.name = \"Too_Many_Stats\";\r\n\t}\r\n}\r\n\r\nexport class NoStatisticsError extends Error {\r\n\tpublic readonly name: string;\r\n\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t\tthis.name = \"No_Statistics\";\r\n\t}\r\n}\r\n","export const COMMENT_REGEX = /\\s+(#|\\/{2}|\\[|\\/\\*)(.*)/;\r\nexport const SIGN_REGEX = /[><=!]+/;\r\nexport const SIGN_REGEX_SPACE = /[><=!]+(\\S+)/;\r\n\r\nexport const SYMBOL_DICE = \"&\";\r\n","import { evaluate } from \"mathjs\";\r\nimport \"uniformize\";\r\nimport { FormulaError } from \"./errors\";\r\n\r\n/**\r\n * Escape regex string\r\n * @param string {string}\r\n */\r\nexport function escapeRegex(string: string) {\r\n\treturn string.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\r\n}\r\n\r\n/**\r\n * Replace the stat name by their value using stat and after evaluate any formula using `replaceFormulaInDice`\r\n * @param originalDice {dice}\r\n * @param stats {Record<string,number>}\r\n */\r\nexport function generateStatsDice(originalDice: string, stats?: Record<string, number>) {\r\n\tlet dice = originalDice.standardize();\r\n\tif (stats && Object.keys(stats).length > 0) {\r\n\t\t//damage field support adding statistic, like : 1d6 + strength\r\n\t\t//check if the value contains a statistic & calculate if it's okay\r\n\t\t//the dice will be converted before roll\r\n\t\tconst allStats = Object.keys(stats);\r\n\t\tfor (const stat of allStats) {\r\n\t\t\tconst regex = new RegExp(escapeRegex(stat.standardize()), \"gi\");\r\n\t\t\tif (dice.match(regex)) {\r\n\t\t\t\tconst statValue = stats[stat];\r\n\t\t\t\tdice = dice.replace(regex, statValue.toString());\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn replaceFormulaInDice(dice);\r\n}\r\n\r\n/**\r\n * Replace the {{}} in the dice string and evaluate the interior if any\r\n * @param dice {string}\r\n */\r\nexport function replaceFormulaInDice(dice: string) {\r\n\tconst formula = /(?<formula>\\{{2}(.+?)}{2})/gim;\r\n\t// biome-ignore lint/suspicious/noImplicitAnyLet: <explanation>\r\n\tlet match;\r\n\tlet modifiedDice = dice.standardize();\r\n\twhile ((match = formula.exec(dice)) !== null) {\r\n\t\tif (match.groups?.formula) {\r\n\t\t\tconst formulae = match.groups.formula.replaceAll(\"{{\", \"\").replaceAll(\"}}\", \"\");\r\n\t\t\ttry {\r\n\t\t\t\tconst result = evaluate(formulae);\r\n\t\t\t\tmodifiedDice = modifiedDice.replace(match.groups.formula, result.toString());\r\n\t\t\t} catch (error) {\r\n\t\t\t\tthrow new FormulaError(match.groups.formula, \"replaceFormulasInDice\", error);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\treturn cleanedDice(modifiedDice);\r\n}\r\n\r\n/**\r\n * Replace the ++ +- -- by their proper value:\r\n * - `++` = `+`\r\n * - `+-` = `-`\r\n * - `--` = `+`\r\n * @param dice {string}\r\n */\r\nexport function cleanedDice(dice: string) {\r\n\treturn dice.replaceAll(\"+-\", \"-\").replaceAll(\"--\", \"+\").replaceAll(\"++\", \"+\").trimEnd();\r\n}\r\n","/* eslint-disable @typescript-eslint/no-unused-vars */\r\nimport { evaluate } from \"mathjs\";\r\nimport { Random } from \"random-js\";\r\nimport \"uniformize\";\r\n\r\nimport type { StatisticalTemplate } from \".\";\r\nimport { createCriticalCustom, roll } from \"./dice\";\r\nimport {\r\n\tDiceTypeError,\r\n\tEmptyObjectError,\r\n\tFormulaError,\r\n\tNoStatisticsError,\r\n\tTooManyDice,\r\n} from \"./errors\";\r\nimport { templateSchema } from \"./interfaces/zod\";\r\nimport { escapeRegex, replaceFormulaInDice } from \"./utils\";\r\n\r\n/**\r\n * Verify if the provided dice work with random value\r\n * @param testDice {string}\r\n * @param allStats {Record<string,number>}\r\n */\r\nexport function evalStatsDice(testDice: string, allStats?: Record<string, number>) {\r\n\tlet dice = testDice.trimEnd();\r\n\tif (allStats && Object.keys(allStats).length > 0) {\r\n\t\tconst names = Object.keys(allStats);\r\n\t\tfor (const name of names) {\r\n\t\t\tconst regex = new RegExp(escapeRegex(name.standardize()), \"gi\");\r\n\t\t\tif (dice.standardize().match(regex)) {\r\n\t\t\t\tconst statValue = allStats[name];\r\n\t\t\t\tdice = dice.standardize().replace(regex, statValue.toString()).trimEnd();\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\ttry {\r\n\t\tif (!roll(replaceFormulaInDice(dice)))\r\n\t\t\tthrow new DiceTypeError(dice, \"evalStatsDice\", \"no roll result\");\r\n\t\treturn testDice;\r\n\t} catch (error) {\r\n\t\tthrow new DiceTypeError(dice, \"evalStatsDice\", error);\r\n\t}\r\n}\r\n\r\n/**\r\n * Generate a random dice and remove the formula (+ evaluate it)\r\n * Used for diceDamage only\r\n * @param value {string}\r\n * @param template {StatisticalTemplate}\r\n * @returns\r\n */\r\nexport function diceRandomParse(value: string, template: StatisticalTemplate) {\r\n\tif (!template.statistics) return value;\r\n\tvalue = value.standardize();\r\n\tconst statNames = Object.keys(template.statistics);\r\n\tlet newDice = value;\r\n\tfor (const name of statNames) {\r\n\t\tconst regex = new RegExp(escapeRegex(name.standardize()), \"gi\");\r\n\t\tif (value.match(regex)) {\r\n\t\t\tlet max: undefined | number = undefined;\r\n\t\t\tlet min: undefined | number = undefined;\r\n\t\t\tconst foundStat = template.statistics?.[name];\r\n\t\t\tif (foundStat) {\r\n\t\t\t\tmax = foundStat.max;\r\n\t\t\t\tmin = foundStat.min;\r\n\t\t\t}\r\n\t\t\tconst total = template.total || 100;\r\n\t\t\tconst randomStatValue = generateRandomStat(total, max, min);\r\n\t\t\tnewDice = value.replace(regex, randomStatValue.toString());\r\n\t\t}\r\n\t}\r\n\treturn replaceFormulaInDice(newDice);\r\n}\r\n\r\n/**\r\n * Same as damageDice but for DiceType\r\n * @param dice {string}\r\n * @param template {StatisticalTemplate}\r\n */\r\nexport function diceTypeRandomParse(dice: string, template: StatisticalTemplate) {\r\n\tif (!template.statistics) return dice;\r\n\tconst firstStatNotcombinaison = Object.keys(template.statistics).find(\r\n\t\t(stat) => !template.statistics?.[stat].combinaison\r\n\t);\r\n\tif (!firstStatNotcombinaison) return dice;\r\n\tconst stats = template.statistics[firstStatNotcombinaison];\r\n\tconst { min, max } = stats;\r\n\tconst total = template.total || 100;\r\n\tconst randomStatValue = generateRandomStat(total, max, min);\r\n\treturn replaceFormulaInDice(dice.replaceAll(\"$\", randomStatValue.toString()));\r\n}\r\n\r\n/**\r\n * Random the combinaison and evaluate it to check if everything is valid\r\n * @param combinaison {Record<string,string>}\r\n * @param stats {Record<string,number|number>}\r\n */\r\nexport function evalCombinaison(\r\n\tcombinaison: Record<string, string>,\r\n\tstats: Record<string, number | string>\r\n) {\r\n\tconst newStats: Record<string, number> = {};\r\n\tfor (const [stat, combin] of Object.entries(combinaison)) {\r\n\t\t//replace the stats in formula\r\n\t\tlet formula = combin.standardize();\r\n\t\tfor (const [statName, value] of Object.entries(stats)) {\r\n\t\t\tconst regex = new RegExp(statName.standardize(), \"gi\");\r\n\t\t\tformula = formula.replace(regex, value.toString());\r\n\t\t}\r\n\t\ttry {\r\n\t\t\tnewStats[stat] = evaluate(formula);\r\n\t\t} catch (error) {\r\n\t\t\tthrow new FormulaError(stat, \"evalCombinaison\", error);\r\n\t\t}\r\n\t}\r\n\treturn newStats;\r\n}\r\n\r\n/**\r\n * Evaluate one selected combinaison\r\n * @param combinaison {string}\r\n * @param stats {[name: string]: string|number}\r\n */\r\nexport function evalOneCombinaison(\r\n\tcombinaison: string,\r\n\tstats: Record<string, number | string>\r\n) {\r\n\tlet formula = combinaison.standardize();\r\n\tfor (const [statName, value] of Object.entries(stats)) {\r\n\t\tconst regex = new RegExp(statName.standardize(), \"gi\");\r\n\t\tformula = formula.replace(regex, value.toString());\r\n\t}\r\n\ttry {\r\n\t\treturn evaluate(formula);\r\n\t} catch (error) {\r\n\t\tthrow new FormulaError(combinaison, \"evalOneCombinaison\", error);\r\n\t}\r\n}\r\n\r\nfunction convertNumber(number: string | number | undefined) {\r\n\tif (!number) return undefined;\r\n\tconst isNumber = (value: unknown): boolean =>\r\n\t\ttypeof value === \"number\" ||\r\n\t\t(!Number.isNaN(Number(value)) && typeof value === \"string\");\r\n\tif (number.toString().length === 0) return undefined;\r\n\tif (isNumber(number)) return Number.parseInt(number.toString(), 10);\r\n\treturn undefined;\r\n}\r\n\r\n/**\r\n * Parse the provided JSON and verify each field to check if everything could work when rolling\r\n * @param {any} template\r\n * @returns {StatisticalTemplate}\r\n */\r\nexport function verifyTemplateValue(template: unknown): StatisticalTemplate {\r\n\tconst parsedTemplate = templateSchema.parse(template);\r\n\tconst { success, failure } = parsedTemplate.critical ?? {};\r\n\tconst criticicalVal = {\r\n\t\tsuccess: convertNumber(success),\r\n\t\tfailure: convertNumber(failure),\r\n\t};\r\n\tconst statistiqueTemplate: StatisticalTemplate = {\r\n\t\tdiceType: parsedTemplate.diceType,\r\n\t\tstatistics: parsedTemplate.statistics,\r\n\t\tcritical: criticicalVal,\r\n\t\ttotal: parsedTemplate.total,\r\n\t\tcharName: parsedTemplate.charName,\r\n\t\tdamage: parsedTemplate.damage,\r\n\t\tcustomCritical: parsedTemplate.customCritical,\r\n\t};\r\n\tif (statistiqueTemplate.diceType) {\r\n\t\tconst cleanedDice = diceTypeRandomParse(\r\n\t\t\tstatistiqueTemplate.diceType,\r\n\t\t\tstatistiqueTemplate\r\n\t\t);\r\n\t\tconst rolled = roll(cleanedDice);\r\n\t\tif (!rolled) {\r\n\t\t\tthrow new DiceTypeError(cleanedDice, \"verifyTemplateValue\", \"no roll result\");\r\n\t\t}\r\n\t}\r\n\tif (statistiqueTemplate.customCritical) {\r\n\t\tif (!statistiqueTemplate.diceType) {\r\n\t\t\tthrow new DiceTypeError(\"no_dice_type\", \"verifyTemplateValue\", \"no dice type\");\r\n\t\t}\r\n\t\tconst customCritical = statistiqueTemplate.customCritical;\r\n\t\tfor (const [, custom] of Object.entries(customCritical)) {\r\n\t\t\tconst cleanedDice = createCriticalCustom(\r\n\t\t\t\t// biome-ignore lint/style/noNonNullAssertion: <explanation>\r\n\t\t\t\tstatistiqueTemplate.diceType!,\r\n\t\t\t\tcustom,\r\n\t\t\t\tstatistiqueTemplate\r\n\t\t\t);\r\n\t\t\tconst rolled = roll(cleanedDice);\r\n\t\t\tif (!rolled)\r\n\t\t\t\tthrow new DiceTypeError(cleanedDice, \"verifyTemplateValue\", \"no roll result\");\r\n\t\t}\r\n\t}\r\n\ttestDiceRegistered(statistiqueTemplate);\r\n\ttestStatCombinaison(statistiqueTemplate);\r\n\treturn statistiqueTemplate;\r\n}\r\n\r\n/**\r\n * Test each damage roll from the template.damage\r\n * @param {StatisticalTemplate} template\r\n */\r\nexport function testDiceRegistered(template: StatisticalTemplate) {\r\n\tif (!template.damage) return;\r\n\tif (Object.keys(template.damage).length === 0) throw new EmptyObjectError();\r\n\tif (Object.keys(template.damage).length > 25) throw new TooManyDice();\r\n\tfor (const [name, dice] of Object.entries(template.damage)) {\r\n\t\tif (!dice) continue;\r\n\t\tconst randomDiceParsed = diceRandomParse(dice, template);\r\n\t\ttry {\r\n\t\t\tconst rolled = roll(randomDiceParsed);\r\n\t\t\tif (!rolled) throw new DiceTypeError(name, \"no_roll_result\", dice);\r\n\t\t} catch (error) {\r\n\t\t\tconsole.error(error);\r\n\t\t\tthrow new DiceTypeError(name, \"testDiceRegistered\", error);\r\n\t\t}\r\n\t}\r\n}\r\n\r\n/**\r\n * Test all combinaison with generated random value\r\n * @param {StatisticalTemplate} template\r\n */\r\nexport function testStatCombinaison(template: StatisticalTemplate) {\r\n\tif (!template.statistics) return;\r\n\tconst onlycombinaisonStats = Object.fromEntries(\r\n\t\tObject.entries(template.statistics).filter(\r\n\t\t\t([_, value]) => value.combinaison !== undefined\r\n\t\t)\r\n\t);\r\n\tconst allOtherStats = Object.fromEntries(\r\n\t\tObject.entries(template.statistics).filter(([_, value]) => !value.combinaison)\r\n\t);\r\n\tif (Object.keys(onlycombinaisonStats).length === 0) return;\r\n\tconst allStats = Object.keys(template.statistics).filter(\r\n\t\t(stat) => !template.statistics![stat].combinaison\r\n\t);\r\n\tif (allStats.length === 0) throw new NoStatisticsError();\r\n\tconst error = [];\r\n\tfor (const [stat, value] of Object.entries(onlycombinaisonStats)) {\r\n\t\tlet formula = value.combinaison as string;\r\n\t\tfor (const [other, data] of Object.entries(allOtherStats)) {\r\n\t\t\tconst { max, min } = data;\r\n\t\t\tconst total = template.total || 100;\r\n\t\t\tconst randomStatValue = generateRandomStat(total, max, min);\r\n\t\t\tconst regex = new RegExp(other, \"gi\");\r\n\t\t\tformula = formula.replace(regex, randomStatValue.toString());\r\n\t\t}\r\n\t\ttry {\r\n\t\t\tevaluate(formula);\r\n\t\t} catch (e) {\r\n\t\t\terror.push(stat);\r\n\t\t}\r\n\t}\r\n\tif (error.length > 0) throw new FormulaError(error.join(\", \"), \"testStatCombinaison\");\r\n\treturn;\r\n}\r\n\r\n/**\r\n * Generate a random stat based on the template and the statistical min and max\r\n * @param {number|undefined} total\r\n * @param {number | undefined} max\r\n * @param {number | undefined} min\r\n * @returns\r\n */\r\nexport function generateRandomStat(\r\n\ttotal: number | undefined = 100,\r\n\tmax?: number,\r\n\tmin?: number\r\n) {\r\n\tlet randomStatValue = total + 1;\r\n\twhile (randomStatValue >= total || randomStatValue === 0) {\r\n\t\tconst random = new Random();\r\n\t\tif (max && min) randomStatValue = random.integer(min, max);\r\n\t\telse if (max) randomStatValue = random.integer(1, max);\r\n\t\telse if (min) randomStatValue = random.integer(min, total);\r\n\t\telse randomStatValue = random.integer(1, total);\r\n\t}\r\n\treturn randomStatValue;\r\n}\r\n","/**\r\n * Definition of the Zod schema for template data\r\n */\r\nimport { z } from \"zod\";\r\n\r\nconst statisticValueSchema = z\r\n\t.object({\r\n\t\tmax: z.number().positive().optional(),\r\n\t\tmin: z.number().positive().optional(),\r\n\t\tcombinaison: z\r\n\t\t\t.string()\r\n\t\t\t.transform((str) => str.trim() || undefined)\r\n\t\t\t.optional(),\r\n\t})\r\n\t.superRefine((data, ctx) => {\r\n\t\tif (data.max !== undefined && data.min !== undefined && data.max <= data.min) {\r\n\t\t\tctx.addIssue({\r\n\t\t\t\tcode: \"custom\",\r\n\t\t\t\tmessage: `Max_Greater; ${data.min}; ${data.max}`,\r\n\t\t\t\tpath: [\"max\"],\r\n\t\t\t});\r\n\t\t}\r\n\t});\r\n\r\nconst statisticSchema = z\r\n\t.record(statisticValueSchema)\r\n\t.optional()\r\n\t.refine((stats) => !stats || Object.keys(stats).length <= 25, {\r\n\t\tmessage: \"TooManyStats\",\r\n\t});\r\n\r\nconst criticalSchema = z\r\n\t.object({\r\n\t\tsuccess: z.string().or(z.number().positive()).optional(),\r\n\t\tfailure: z.string().or(z.number().positive()).optional(),\r\n\t})\r\n\t.transform((values) => {\r\n\t\tif (values.success === \"\") values.success = undefined;\r\n\t\tif (values.failure === \"\") values.failure = undefined;\r\n\t\tif (values.failure === 0) values.failure = undefined;\r\n\t\tif (values.success === 0) values.success = undefined;\r\n\t\tvalues.success = Number.parseInt(values.success as string, 10);\r\n\t\tvalues.failure = Number.parseInt(values.failure as string, 10);\r\n\t\treturn values;\r\n\t});\r\n\r\nconst criticalValueSchema = z.object({\r\n\tsign: z.enum([\"<\", \">\", \"<=\", \">=\", \"!=\", \"==\"]),\r\n\tvalue: z.string(),\r\n\tonNaturalDice: z.boolean().optional(),\r\n\taffectSkill: z.boolean().optional(),\r\n});\r\n\r\nconst damageSchema = z\r\n\t.record(z.string())\r\n\t.optional()\r\n\t.refine((stats) => !stats || Object.keys(stats).length <= 25, {\r\n\t\tmessage: \"TooManyDice\",\r\n\t});\r\n\r\nconst customCriticalSchema = z\r\n\t.record(criticalValueSchema)\r\n\t.optional()\r\n\t.refine((stats) => !stats || Object.keys(stats).length <= 22, {\r\n\t\tmessage: \"TooManyDice\",\r\n\t});\r\n\r\nexport const templateSchema = z.object({\r\n\tcharName: z.boolean().optional(),\r\n\tstatistics: statisticSchema,\r\n\ttotal: z.number().min(0).optional(),\r\n\tdiceType: z.string().optional(),\r\n\tcritical: criticalSchema.optional(),\r\n\tcustomCritical: customCriticalSchema,\r\n\tdamage: damageSchema,\r\n});\r\n"],"mappings":"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","names":["value","roller","evaluateRoll","diceResult","evaluate","evaluate","evaluate","evaluate","cleanedDice"]}
|
1
|
+
{"version":3,"sources":["../src/dice.ts","../src/errors.ts","../src/interfaces/constant.ts","../src/utils.ts","../src/verify_template.ts","../src/interfaces/zod.ts"],"sourcesContent":["import { DiceRoller } from \"@dice-roller/rpg-dice-roller\";\r\nimport { evaluate } from \"mathjs\";\r\n\r\nimport {\r\n\ttype Compare,\r\n\ttype ComparedValue,\r\n\ttype CustomCritical,\r\n\ttype Modifier,\r\n\ttype Resultat,\r\n\ttype Sign,\r\n\ttype StatisticalTemplate,\r\n\tdiceTypeRandomParse,\r\n} from \".\";\r\nimport { DiceTypeError } from \"./errors\";\r\nimport {\r\n\tCOMMENT_REGEX,\r\n\tSIGN_REGEX,\r\n\tSIGN_REGEX_SPACE,\r\n\tSYMBOL_DICE,\r\n} from \"./interfaces/constant\";\r\n\r\nfunction getCompare(\r\n\tdice: string,\r\n\tcompareRegex: RegExpMatchArray\r\n): { dice: string; compare: ComparedValue | undefined } {\r\n\tdice = dice.replace(SIGN_REGEX_SPACE, \"\");\r\n\tlet compare: ComparedValue;\r\n\tconst calc = compareRegex[1];\r\n\tconst sign = calc.match(/[+-\\/*^]/)?.[0];\r\n\tconst compareSign = compareRegex[0].match(SIGN_REGEX)?.[0];\r\n\tif (sign) {\r\n\t\tconst toCalc = calc.replace(SIGN_REGEX, \"\").replace(/\\s/g, \"\").replace(/;(.*)/, \"\");\r\n\t\tconst rCompare = rollCompare(toCalc);\r\n\t\tconst total = evaluate(rCompare.value.toString());\r\n\t\tdice = dice.replace(SIGN_REGEX_SPACE, `${compareSign}${total}`);\r\n\t\tcompare = {\r\n\t\t\tsign: compareSign as \"<\" | \">\" | \">=\" | \"<=\" | \"=\" | \"!=\" | \"==\",\r\n\t\t\tvalue: total,\r\n\t\t\toriginalDice: rCompare.dice,\r\n\t\t\trollValue: rCompare.diceResult,\r\n\t\t};\r\n\t} else {\r\n\t\tconst rcompare = rollCompare(calc);\r\n\t\tcompare = {\r\n\t\t\tsign: compareSign as \"<\" | \">\" | \">=\" | \"<=\" | \"=\" | \"!=\" | \"==\",\r\n\t\t\tvalue: rcompare.value,\r\n\t\t\toriginalDice: rcompare.dice,\r\n\t\t\trollValue: rcompare.diceResult,\r\n\t\t};\r\n\t}\r\n\treturn { dice, compare };\r\n}\r\n\r\nfunction rollCompare(value: unknown) {\r\n\tconst isNumber = (value: unknown): boolean =>\r\n\t\ttypeof value === \"number\" ||\r\n\t\t(!Number.isNaN(Number(value)) && typeof value === \"string\");\r\n\tif (isNumber(value)) return { value: Number.parseInt(value as string, 10) };\r\n\tconst rollComp = roll(value as string);\r\n\tif (!rollComp?.total) //not a dice throw\r\n\t\treturn { value: evaluate(value as string), diceResult: value as string };\r\n\treturn {\r\n\t\tdice: value as string,\r\n\t\tvalue: rollComp.total,\r\n\t\tdiceResult: rollComp?.result,\r\n\t};\r\n}\r\n\r\n/**\r\n * Allow to replace the compare part of a dice and use the critical customized one\r\n * @example\r\n * dice = \"1d20=20\";\r\n * custom critical {sign: \">\", value: \"$/2\"}\r\n * Random stats = 6\r\n * result = \"1d20>3\"\r\n */\r\nexport function createCriticalCustom(\r\n\tdice: string,\r\n\tcustomCritical: CustomCritical,\r\n\ttemplate: StatisticalTemplate\r\n) {\r\n\tconst compareRegex = dice.match(SIGN_REGEX_SPACE);\r\n\tlet customDice = dice;\r\n\tconst compareValue = diceTypeRandomParse(customCritical.value, template);\r\n\tif (compareValue.includes(\"$\"))\r\n\t\tthrow new DiceTypeError(compareValue, \"createCriticalCustom\");\r\n\tconst comparaison = `${customCritical.sign}${compareValue}`;\r\n\tif (compareRegex) customDice = customDice.replace(SIGN_REGEX_SPACE, comparaison);\r\n\telse customDice += comparaison;\r\n\treturn diceTypeRandomParse(customDice, template);\r\n}\r\n\r\nfunction getModifier(dice: string) {\r\n\tconst modifier = dice.matchAll(/(\\+|-|%|\\/|\\^|\\*|\\*{2})(\\d+)/gi);\r\n\tlet modificator: Modifier | undefined;\r\n\tfor (const mod of modifier) {\r\n\t\t//calculate the modifier if multiple\r\n\t\tif (modificator) {\r\n\t\t\tconst sign = modificator.sign;\r\n\t\t\tlet value = modificator.value;\r\n\t\t\tif (sign) value = calculator(sign, value, Number.parseInt(mod[2], 10));\r\n\t\t\tmodificator = {\r\n\t\t\t\tsign: mod[1] as Sign,\r\n\t\t\t\tvalue,\r\n\t\t\t};\r\n\t\t} else {\r\n\t\t\tmodificator = {\r\n\t\t\t\tsign: mod[1] as Sign,\r\n\t\t\t\tvalue: Number.parseInt(mod[2], 10),\r\n\t\t\t};\r\n\t\t}\r\n\t}\r\n\treturn modificator;\r\n}\r\n\r\n/**\r\n * Parse the string provided and turn it as a readable dice for dice parser\r\n * @param dice {string}\r\n */\r\nexport function roll(dice: string): Resultat | undefined {\r\n\t//parse dice string\r\n\tif (!dice.includes(\"d\")) return undefined;\r\n\tconst compareRegex = dice.match(SIGN_REGEX_SPACE);\r\n\tlet compare: ComparedValue | undefined;\r\n\tif (dice.includes(\";\") && dice.includes(\"&\")) return sharedRolls(dice);\r\n\tif (compareRegex) {\r\n\t\tconst compareResult = getCompare(dice, compareRegex);\r\n\t\tdice = compareResult.dice;\r\n\t\tcompare = compareResult.compare;\r\n\t}\r\n\tconst modificator = getModifier(dice);\r\n\r\n\tif (dice.match(/\\d+?#(.*)/)) {\r\n\t\tconst diceArray = dice.split(\"#\");\r\n\t\tconst numberOfDice = Number.parseInt(diceArray[0], 10);\r\n\t\tconst diceToRoll = diceArray[1].replace(COMMENT_REGEX, \"\");\r\n\t\tconst commentsMatch = diceArray[1].match(COMMENT_REGEX);\r\n\t\tconst comments = commentsMatch ? commentsMatch[2] : undefined;\r\n\t\tconst roller = new DiceRoller();\r\n\t\t//remove comments if any\r\n\t\tfor (let i = 0; i < numberOfDice; i++) {\r\n\t\t\ttry {\r\n\t\t\t\troller.roll(diceToRoll);\r\n\t\t\t} catch (error) {\r\n\t\t\t\tthrow new DiceTypeError(diceToRoll, \"roll\", error);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn {\r\n\t\t\tdice: diceToRoll,\r\n\t\t\tresult: roller.output,\r\n\t\t\tcomment: comments,\r\n\t\t\tcompare: compare ? compare : undefined,\r\n\t\t\tmodifier: modificator,\r\n\t\t\ttotal: roller.total,\r\n\t\t};\r\n\t}\r\n\tconst roller = new DiceRoller();\r\n\tconst diceWithoutComment = dice.replace(COMMENT_REGEX, \"\").trimEnd();\r\n\ttry {\r\n\t\troller.roll(diceWithoutComment);\r\n\t} catch (error) {\r\n\t\tthrow new DiceTypeError(diceWithoutComment, \"roll\", error);\r\n\t}\r\n\tconst commentMatch = dice.match(COMMENT_REGEX);\r\n\tconst comment = commentMatch ? commentMatch[2] : undefined;\r\n\treturn {\r\n\t\tdice,\r\n\t\tresult: roller.output,\r\n\t\tcomment,\r\n\t\tcompare: compare ? compare : undefined,\r\n\t\tmodifier: modificator,\r\n\t\ttotal: roller.total,\r\n\t};\r\n}\r\n/**\r\n * Evaluate a formula and replace \"^\" by \"**\" if any\r\n * @param {Sign} sign\r\n * @param {number} value\r\n * @param {number} total\r\n * @returns\r\n */\r\nexport function calculator(sign: Sign, value: number, total: number): number {\r\n\tif (sign === \"^\") sign = \"**\";\r\n\treturn evaluate(`${total} ${sign} ${value}`);\r\n}\r\n\r\nfunction inverseSign(\r\n\tsign: \"<\" | \">\" | \">=\" | \"<=\" | \"=\" | \"!=\" | \"==\"\r\n): \"<\" | \">\" | \">=\" | \"<=\" | \"=\" | \"!=\" | \"==\" {\r\n\tswitch (sign) {\r\n\t\tcase \"<\":\r\n\t\t\treturn \">\";\r\n\t\tcase \">\":\r\n\t\t\treturn \"<\";\r\n\t\tcase \"<=\":\r\n\t\t\treturn \">=\";\r\n\t\tcase \">=\":\r\n\t\t\treturn \"<=\";\r\n\t\tcase \"=\":\r\n\t\t\treturn \"!=\";\r\n\t\tcase \"==\":\r\n\t\t\treturn \"!=\";\r\n\t\tcase \"!=\":\r\n\t\t\treturn \"==\";\r\n\t}\r\n}\r\n\r\nfunction replaceInFormula(\r\n\telement: string,\r\n\tdiceResult: Resultat,\r\n\tcompareResult: { dice: string; compare: Compare | undefined },\r\n\tres: boolean\r\n) {\r\n\tconst { formule, diceAll } = replaceText(\r\n\t\telement,\r\n\t\tdiceResult.total ?? 0,\r\n\t\tdiceResult.dice\r\n\t);\r\n\tconst validSign = res ? \"✓\" : \"✕\";\r\n\tconst invertedSign = res\r\n\t\t? compareResult.compare!.sign\r\n\t\t: inverseSign(compareResult.compare!.sign);\r\n\tlet evaluateRoll: unknown;\r\n\ttry {\r\n\t\tevaluateRoll = evaluate(compareResult.dice);\r\n\t\treturn `${validSign} ${diceAll}: ${formule} = ${evaluateRoll}${invertedSign}${compareResult.compare?.value}`;\r\n\t} catch (error) {\r\n\t\tconst evaluateRoll = roll(compareResult.dice) as Resultat | undefined;\r\n\t\tif (evaluateRoll)\r\n\t\t\treturn `${validSign} ${diceAll}: ${evaluateRoll.result.split(\":\").splice(1).join(\":\")}`;\r\n\r\n\t\treturn `${validSign} ${diceAll}: ${formule} = ${evaluateRoll}${invertedSign}${compareResult.compare?.value}`;\r\n\t}\r\n}\r\n\r\nfunction compareSignFormule(\r\n\ttoRoll: string,\r\n\tcompareRegex: RegExpMatchArray,\r\n\telement: string,\r\n\tdiceResult: Resultat\r\n) {\r\n\tlet results = \"\";\r\n\tconst compareResult = getCompare(toRoll, compareRegex);\r\n\tconst toCompare = `${compareResult.dice}${compareResult.compare?.sign}${compareResult.compare?.value}`;\r\n\tlet res: unknown;\r\n\ttry {\r\n\t\tres = evaluate(toCompare);\r\n\t} catch (error) {\r\n\t\tres = roll(toCompare);\r\n\t}\r\n\tif (typeof res === \"boolean\") {\r\n\t\tresults = replaceInFormula(element, diceResult, compareResult, res);\r\n\t} else if (res instanceof Object) {\r\n\t\tconst diceResult = res as Resultat;\r\n\t\tif (diceResult.compare) {\r\n\t\t\tconst toEvaluate = evaluate(\r\n\t\t\t\t`${diceResult.total}${diceResult.compare.sign}${diceResult.compare.value}`\r\n\t\t\t);\r\n\t\t\tconst sign = toEvaluate ? \"✓\" : \"✕\";\r\n\t\t\tconst invertedSign = toEvaluate\r\n\t\t\t\t? diceResult.compare.sign\r\n\t\t\t\t: inverseSign(diceResult.compare.sign);\r\n\t\t\tconst dice = replaceText(element, 0, diceResult.dice).diceAll;\r\n\r\n\t\t\tresults = `${sign} ${dice}: ${diceResult.result.split(\":\").splice(1).join(\":\").trim()}${invertedSign}${diceResult.compare.value}`;\r\n\t\t}\r\n\t}\r\n\treturn { dice: compareResult.dice, results };\r\n}\r\n\r\nfunction replaceText(element: string, total: number, dice: string) {\r\n\treturn {\r\n\t\tformule: element.replace(SYMBOL_DICE, `[${total}]`).trim(),\r\n\t\tdiceAll: element.replace(SYMBOL_DICE, `[${dice.replace(COMMENT_REGEX, \"\")}]`).trim(),\r\n\t};\r\n}\r\n\r\nfunction sharedRolls(dice: string): Resultat | undefined {\r\n\t/* bulk roll are not allowed in shared rolls */\r\n\tif (dice.includes(\"#\"))\r\n\t\tthrow new DiceTypeError(\r\n\t\t\tdice,\r\n\t\t\t\"noBulkRoll\",\r\n\t\t\t\"bulk roll are not allowed in shared rolls\"\r\n\t\t);\r\n\tconst results = [];\r\n\tconst split = dice.split(\";\");\r\n\tconst diceResult = roll(split[0]);\r\n\tif (!diceResult || !diceResult.total) return undefined;\r\n\tresults.push(`${diceResult.result}`);\r\n\r\n\tlet total = diceResult.total;\r\n\tlet comments = diceResult.comment ?? \"\";\r\n\tif (!total) return diceResult;\r\n\tfor (let element of split.slice(1)) {\r\n\t\tif (!element.includes(SYMBOL_DICE)) {\r\n\t\t\tconst result = roll(element);\r\n\t\t\tif (!result) continue;\r\n\t\t\tresults.push(result.result);\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\t//remove comments & keep it\r\n\t\tconst commentMatch = element.match(COMMENT_REGEX);\r\n\t\telement = element.replace(COMMENT_REGEX, \"\");\r\n\t\tconst comment = commentMatch ? commentMatch[2] : undefined;\r\n\t\tif (comment) comments += ` ${comment}`;\r\n\t\tlet toRoll = element.replace(SYMBOL_DICE, `${diceResult.total}`);\r\n\t\tconst compareRegex = toRoll.match(SIGN_REGEX_SPACE);\r\n\t\tif (compareRegex) {\r\n\t\t\tconst compareResult = compareSignFormule(toRoll, compareRegex, element, diceResult);\r\n\t\t\ttoRoll = compareResult.dice;\r\n\t\t\tresults.push(compareResult.results);\r\n\t\t} else {\r\n\t\t\tconst { formule, diceAll } = replaceText(\r\n\t\t\t\telement,\r\n\t\t\t\tdiceResult.total,\r\n\t\t\t\tdiceResult.dice\r\n\t\t\t);\r\n\r\n\t\t\ttry {\r\n\t\t\t\tconst evaluated = evaluate(toRoll);\r\n\t\t\t\tresults.push(`◈ ${diceAll}: ${formule} = ${evaluated}`);\r\n\t\t\t\ttotal += Number.parseInt(evaluated, 10);\r\n\t\t\t} catch (error) {\r\n\t\t\t\tconst evaluated = roll(toRoll);\r\n\t\t\t\tif (evaluated)\r\n\t\t\t\t\tresults.push(`◈ ${diceAll}: ${evaluated.result.split(\":\").slice(1).join(\":\")}`);\r\n\t\t\t\telse results.push(`◈ ${diceAll}: ${formule} = ${evaluated}`);\r\n\t\t\t\ttotal += evaluated?.total ?? 0;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\treturn {\r\n\t\tdice: split[0],\r\n\t\tresult: results.join(\";\"),\r\n\t\tcomment: comments,\r\n\t\tcompare: diceResult.compare,\r\n\t\tmodifier: diceResult.modifier,\r\n\t\ttotal,\r\n\t};\r\n}\r\n","export class DiceTypeError extends Error {\n\tpublic readonly dice: string;\n\tpublic readonly cause: string | undefined;\n\tpublic readonly method: unknown;\n\n\tconstructor(dice: string, cause?: string, method?: unknown) {\n\t\tsuper(dice);\n\t\tthis.name = \"Invalid_Dice_Type\";\n\t\tthis.dice = dice;\n\t\tthis.cause = cause;\n\t\tthis.method = method;\n\t}\n}\n\nexport class FormulaError extends Error {\n\tpublic readonly formula: string;\n\tpublic readonly cause: string | undefined;\n\tpublic readonly method: unknown;\n\n\tconstructor(formula: string, cause?: string, method?: unknown) {\n\t\tsuper(formula);\n\t\tthis.name = \"Invalid_Formula\";\n\t\tthis.formula = formula;\n\t\tthis.cause = cause;\n\t\tthis.method = method;\n\t}\n}\n\nexport class MaxGreater extends Error {\n\tpublic readonly name: string;\n\tpublic readonly value: number;\n\tpublic readonly max: number;\n\n\tconstructor(value: number, max: number) {\n\t\tsuper(value.toString());\n\t\tthis.name = \"Max_Greater\";\n\t\tthis.value = value;\n\t\tthis.max = max;\n\t}\n}\n\nexport class EmptyObjectError extends Error {\n\tpublic readonly name: string;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.name = \"Empty_Object\";\n\t}\n}\n\nexport class TooManyDice extends Error {\n\tpublic readonly name: string;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.name = \"Too_Many_Dice\";\n\t}\n}\n\nexport class TooManyStats extends Error {\n\tpublic readonly name: string;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.name = \"Too_Many_Stats\";\n\t}\n}\n\nexport class NoStatisticsError extends Error {\n\tpublic readonly name: string;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.name = \"No_Statistics\";\n\t}\n}\n","export const COMMENT_REGEX = /\\s+(#|\\/{2}|\\[|\\/\\*)(.*)/;\nexport const SIGN_REGEX = /[><=!]+/;\nexport const SIGN_REGEX_SPACE = /[><=!]+(\\S+)/;\n\nexport const SYMBOL_DICE = \"&\";\n","import { evaluate } from \"mathjs\";\nimport \"uniformize\";\nimport { FormulaError } from \"./errors\";\n\n/**\n * Escape regex string\n * @param string {string}\n */\nexport function escapeRegex(string: string) {\n\treturn string.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Replace the stat name by their value using stat and after evaluate any formula using `replaceFormulaInDice`\n * @param originalDice {dice}\n * @param stats {Record<string,number>}\n * @param dollarValue\n */\nexport function generateStatsDice(\n\toriginalDice: string,\n\tstats?: Record<string, number>,\n\tdollarValue?: string\n) {\n\tlet dice = originalDice.standardize();\n\tif (stats && Object.keys(stats).length > 0) {\n\t\t//damage field support adding statistic, like : 1d6 + strength\n\t\t//check if the value contains a statistic & calculate if it's okay\n\t\t//the dice will be converted before roll\n\t\tconst allStats = Object.keys(stats);\n\t\tfor (const stat of allStats) {\n\t\t\tconst regex = new RegExp(escapeRegex(stat.standardize()), \"gi\");\n\t\t\tif (dice.match(regex)) {\n\t\t\t\tconst statValue = stats[stat];\n\t\t\t\tdice = dice.replace(regex, statValue.toString());\n\t\t\t}\n\t\t}\n\t}\n\tif (dollarValue) dice = dice.replaceAll(\"$\", dollarValue);\n\treturn replaceFormulaInDice(dice);\n}\n\n/**\n * Replace the {{}} in the dice string and evaluate the interior if any\n * @param dice {string}\n */\nexport function replaceFormulaInDice(dice: string) {\n\tconst formula = /(?<formula>\\{{2}(.+?)}{2})/gim;\n\t// biome-ignore lint/suspicious/noImplicitAnyLet: <explanation>\n\tlet match;\n\tlet modifiedDice = dice.standardize();\n\t// biome-ignore lint/suspicious/noAssignInExpressions: <explanation>\n\twhile ((match = formula.exec(dice)) !== null) {\n\t\tif (match.groups?.formula) {\n\t\t\tconst formulae = match.groups.formula.replaceAll(\"{{\", \"\").replaceAll(\"}}\", \"\");\n\t\t\ttry {\n\t\t\t\tconst result = evaluate(formulae);\n\t\t\t\tmodifiedDice = modifiedDice.replace(match.groups.formula, result.toString());\n\t\t\t} catch (error) {\n\t\t\t\tthrow new FormulaError(match.groups.formula, \"replaceFormulasInDice\", error);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn cleanedDice(modifiedDice);\n}\n\n/**\n * Replace the ++ +- -- by their proper value:\n * - `++` = `+`\n * - `+-` = `-`\n * - `--` = `+`\n * @param dice {string}\n */\nexport function cleanedDice(dice: string) {\n\treturn dice.replaceAll(\"+-\", \"-\").replaceAll(\"--\", \"+\").replaceAll(\"++\", \"+\").trimEnd();\n}\n","/* eslint-disable @typescript-eslint/no-unused-vars */\nimport { evaluate } from \"mathjs\";\nimport { Random } from \"random-js\";\nimport \"uniformize\";\n\nimport type { StatisticalTemplate } from \".\";\nimport { createCriticalCustom, roll } from \"./dice\";\nimport {\n\tDiceTypeError,\n\tEmptyObjectError,\n\tFormulaError,\n\tNoStatisticsError,\n\tTooManyDice,\n} from \"./errors\";\nimport { templateSchema } from \"./interfaces/zod\";\nimport { escapeRegex, replaceFormulaInDice } from \"./utils\";\n\n/**\n * Verify if the provided dice work with random value\n * @param testDice {string}\n * @param allStats {Record<string,number>}\n */\nexport function evalStatsDice(testDice: string, allStats?: Record<string, number>) {\n\tlet dice = testDice.trimEnd();\n\tif (allStats && Object.keys(allStats).length > 0) {\n\t\tconst names = Object.keys(allStats);\n\t\tfor (const name of names) {\n\t\t\tconst regex = new RegExp(escapeRegex(name.standardize()), \"gi\");\n\t\t\tif (dice.standardize().match(regex)) {\n\t\t\t\tconst statValue = allStats[name];\n\t\t\t\tdice = dice.standardize().replace(regex, statValue.toString()).trimEnd();\n\t\t\t}\n\t\t}\n\t}\n\ttry {\n\t\tif (!roll(replaceFormulaInDice(dice)))\n\t\t\tthrow new DiceTypeError(dice, \"evalStatsDice\", \"no roll result\");\n\t\treturn testDice;\n\t} catch (error) {\n\t\tthrow new DiceTypeError(dice, \"evalStatsDice\", error);\n\t}\n}\n\n/**\n * Generate a random dice and remove the formula (+ evaluate it)\n * Used for diceDamage only\n * @param value {string}\n * @param template {StatisticalTemplate}\n * @returns\n */\nexport function diceRandomParse(value: string, template: StatisticalTemplate) {\n\tif (!template.statistics) return value;\n\tvalue = value.standardize();\n\tconst statNames = Object.keys(template.statistics);\n\tlet newDice = value;\n\tfor (const name of statNames) {\n\t\tconst regex = new RegExp(escapeRegex(name.standardize()), \"gi\");\n\t\tif (value.match(regex)) {\n\t\t\tlet max: undefined | number = undefined;\n\t\t\tlet min: undefined | number = undefined;\n\t\t\tconst foundStat = template.statistics?.[name];\n\t\t\tif (foundStat) {\n\t\t\t\tmax = foundStat.max;\n\t\t\t\tmin = foundStat.min;\n\t\t\t}\n\t\t\tconst total = template.total || 100;\n\t\t\tconst randomStatValue = generateRandomStat(total, max, min);\n\t\t\tnewDice = value.replace(regex, randomStatValue.toString());\n\t\t}\n\t}\n\treturn replaceFormulaInDice(newDice);\n}\n\n/**\n * Same as damageDice but for DiceType\n * @param dice {string}\n * @param template {StatisticalTemplate}\n */\nexport function diceTypeRandomParse(dice: string, template: StatisticalTemplate) {\n\tif (!template.statistics) return dice;\n\tconst firstStatNotcombinaison = Object.keys(template.statistics).find(\n\t\t(stat) => !template.statistics?.[stat].combinaison\n\t);\n\tif (!firstStatNotcombinaison) return dice;\n\tconst stats = template.statistics[firstStatNotcombinaison];\n\tconst { min, max } = stats;\n\tconst total = template.total || 100;\n\tconst randomStatValue = generateRandomStat(total, max, min);\n\treturn replaceFormulaInDice(dice.replaceAll(\"$\", randomStatValue.toString()));\n}\n\n/**\n * Random the combinaison and evaluate it to check if everything is valid\n * @param combinaison {Record<string,string>}\n * @param stats {Record<string,number|number>}\n */\nexport function evalCombinaison(\n\tcombinaison: Record<string, string>,\n\tstats: Record<string, number | string>\n) {\n\tconst newStats: Record<string, number> = {};\n\tfor (const [stat, combin] of Object.entries(combinaison)) {\n\t\t//replace the stats in formula\n\t\tlet formula = combin.standardize();\n\t\tfor (const [statName, value] of Object.entries(stats)) {\n\t\t\tconst regex = new RegExp(statName.standardize(), \"gi\");\n\t\t\tformula = formula.replace(regex, value.toString());\n\t\t}\n\t\ttry {\n\t\t\tnewStats[stat] = evaluate(formula);\n\t\t} catch (error) {\n\t\t\tthrow new FormulaError(stat, \"evalCombinaison\", error);\n\t\t}\n\t}\n\treturn newStats;\n}\n\n/**\n * Evaluate one selected combinaison\n * @param combinaison {string}\n * @param stats {[name: string]: string|number}\n */\nexport function evalOneCombinaison(\n\tcombinaison: string,\n\tstats: Record<string, number | string>\n) {\n\tlet formula = combinaison.standardize();\n\tfor (const [statName, value] of Object.entries(stats)) {\n\t\tconst regex = new RegExp(statName.standardize(), \"gi\");\n\t\tformula = formula.replace(regex, value.toString());\n\t}\n\ttry {\n\t\treturn evaluate(formula);\n\t} catch (error) {\n\t\tthrow new FormulaError(combinaison, \"evalOneCombinaison\", error);\n\t}\n}\n\nfunction convertNumber(number: string | number | undefined) {\n\tif (!number) return undefined;\n\tconst isNumber = (value: unknown): boolean =>\n\t\ttypeof value === \"number\" ||\n\t\t(!Number.isNaN(Number(value)) && typeof value === \"string\");\n\tif (number.toString().length === 0) return undefined;\n\tif (isNumber(number)) return Number.parseInt(number.toString(), 10);\n\treturn undefined;\n}\n\n/**\n * Parse the provided JSON and verify each field to check if everything could work when rolling\n * @param {any} template\n * @returns {StatisticalTemplate}\n */\nexport function verifyTemplateValue(template: unknown): StatisticalTemplate {\n\tconst parsedTemplate = templateSchema.parse(template);\n\tconst { success, failure } = parsedTemplate.critical ?? {};\n\tconst criticicalVal = {\n\t\tsuccess: convertNumber(success),\n\t\tfailure: convertNumber(failure),\n\t};\n\tconst statistiqueTemplate: StatisticalTemplate = {\n\t\tdiceType: parsedTemplate.diceType,\n\t\tstatistics: parsedTemplate.statistics,\n\t\tcritical: criticicalVal,\n\t\ttotal: parsedTemplate.total,\n\t\tcharName: parsedTemplate.charName,\n\t\tdamage: parsedTemplate.damage,\n\t\tcustomCritical: parsedTemplate.customCritical,\n\t};\n\tif (statistiqueTemplate.diceType) {\n\t\tconst cleanedDice = diceTypeRandomParse(\n\t\t\tstatistiqueTemplate.diceType,\n\t\t\tstatistiqueTemplate\n\t\t);\n\t\tconst rolled = roll(cleanedDice);\n\t\tif (!rolled) {\n\t\t\tthrow new DiceTypeError(cleanedDice, \"verifyTemplateValue\", \"no roll result\");\n\t\t}\n\t}\n\tif (statistiqueTemplate.customCritical) {\n\t\tif (!statistiqueTemplate.diceType) {\n\t\t\tthrow new DiceTypeError(\"no_dice_type\", \"verifyTemplateValue\", \"no dice type\");\n\t\t}\n\t\tconst customCritical = statistiqueTemplate.customCritical;\n\t\tfor (const [, custom] of Object.entries(customCritical)) {\n\t\t\tconst cleanedDice = createCriticalCustom(\n\t\t\t\tstatistiqueTemplate.diceType!,\n\t\t\t\tcustom,\n\t\t\t\tstatistiqueTemplate\n\t\t\t);\n\t\t\tconst rolled = roll(cleanedDice);\n\t\t\tif (!rolled)\n\t\t\t\tthrow new DiceTypeError(cleanedDice, \"verifyTemplateValue\", \"no roll result\");\n\t\t}\n\t}\n\ttestDiceRegistered(statistiqueTemplate);\n\ttestStatCombinaison(statistiqueTemplate);\n\treturn statistiqueTemplate;\n}\n\n/**\n * Test each damage roll from the template.damage\n * @param {StatisticalTemplate} template\n */\nexport function testDiceRegistered(template: StatisticalTemplate) {\n\tif (!template.damage) return;\n\tif (Object.keys(template.damage).length === 0) throw new EmptyObjectError();\n\tif (Object.keys(template.damage).length > 25) throw new TooManyDice();\n\tfor (const [name, dice] of Object.entries(template.damage)) {\n\t\tif (!dice) continue;\n\t\tconst randomDiceParsed = diceRandomParse(dice, template);\n\t\ttry {\n\t\t\tconst rolled = roll(randomDiceParsed);\n\t\t\tif (!rolled) throw new DiceTypeError(name, \"no_roll_result\", dice);\n\t\t} catch (error) {\n\t\t\tconsole.error(error);\n\t\t\tthrow new DiceTypeError(name, \"testDiceRegistered\", error);\n\t\t}\n\t}\n}\n\n/**\n * Test all combinaison with generated random value\n * @param {StatisticalTemplate} template\n */\nexport function testStatCombinaison(template: StatisticalTemplate) {\n\tif (!template.statistics) return;\n\tconst onlycombinaisonStats = Object.fromEntries(\n\t\tObject.entries(template.statistics).filter(\n\t\t\t([_, value]) => value.combinaison !== undefined\n\t\t)\n\t);\n\tconst allOtherStats = Object.fromEntries(\n\t\tObject.entries(template.statistics).filter(([_, value]) => !value.combinaison)\n\t);\n\tif (Object.keys(onlycombinaisonStats).length === 0) return;\n\tconst allStats = Object.keys(template.statistics).filter(\n\t\t(stat) => !template.statistics![stat].combinaison\n\t);\n\tif (allStats.length === 0) throw new NoStatisticsError();\n\tconst error = [];\n\tfor (const [stat, value] of Object.entries(onlycombinaisonStats)) {\n\t\tlet formula = value.combinaison as string;\n\t\tfor (const [other, data] of Object.entries(allOtherStats)) {\n\t\t\tconst { max, min } = data;\n\t\t\tconst total = template.total || 100;\n\t\t\tconst randomStatValue = generateRandomStat(total, max, min);\n\t\t\tconst regex = new RegExp(other, \"gi\");\n\t\t\tformula = formula.replace(regex, randomStatValue.toString());\n\t\t}\n\t\ttry {\n\t\t\tevaluate(formula);\n\t\t} catch (e) {\n\t\t\terror.push(stat);\n\t\t}\n\t}\n\tif (error.length > 0) throw new FormulaError(error.join(\", \"), \"testStatCombinaison\");\n\treturn;\n}\n\n/**\n * Generate a random stat based on the template and the statistical min and max\n * @param {number|undefined} total\n * @param {number | undefined} max\n * @param {number | undefined} min\n * @returns\n */\nexport function generateRandomStat(\n\ttotal: number | undefined = 100,\n\tmax?: number,\n\tmin?: number\n) {\n\tlet randomStatValue = total + 1;\n\twhile (randomStatValue >= total || randomStatValue === 0) {\n\t\tconst random = new Random();\n\t\tif (max && min) randomStatValue = random.integer(min, max);\n\t\telse if (max) randomStatValue = random.integer(1, max);\n\t\telse if (min) randomStatValue = random.integer(min, total);\n\t\telse randomStatValue = random.integer(1, total);\n\t}\n\treturn randomStatValue;\n}\n","/**\n * Definition of the Zod schema for template data\n */\nimport { z } from \"zod\";\n\nconst statisticValueSchema = z\n\t.object({\n\t\tmax: z.number().positive().optional(),\n\t\tmin: z.number().positive().optional(),\n\t\tcombinaison: z\n\t\t\t.string()\n\t\t\t.transform((str) => str.trim() || undefined)\n\t\t\t.optional(),\n\t\texclude: z.boolean().optional(),\n\t})\n\t.superRefine((data, ctx) => {\n\t\tif (data.max !== undefined && data.min !== undefined && data.max <= data.min) {\n\t\t\tctx.addIssue({\n\t\t\t\tcode: \"custom\",\n\t\t\t\tmessage: `Max_Greater; ${data.min}; ${data.max}`,\n\t\t\t\tpath: [\"max\"],\n\t\t\t});\n\t\t}\n\t});\n\nconst statisticSchema = z\n\t.record(statisticValueSchema)\n\t.optional()\n\t.refine((stats) => !stats || Object.keys(stats).length <= 25, {\n\t\tmessage: \"TooManyStats\",\n\t});\n\nconst criticalSchema = z\n\t.object({\n\t\tsuccess: z.string().or(z.number().positive()).optional(),\n\t\tfailure: z.string().or(z.number().positive()).optional(),\n\t})\n\t.transform((values) => {\n\t\tif (values.success === \"\") values.success = undefined;\n\t\tif (values.failure === \"\") values.failure = undefined;\n\t\tif (values.failure === 0) values.failure = undefined;\n\t\tif (values.success === 0) values.success = undefined;\n\t\tvalues.success = Number.parseInt(values.success as string, 10);\n\t\tvalues.failure = Number.parseInt(values.failure as string, 10);\n\t\treturn values;\n\t});\n\nconst criticalValueSchema = z.object({\n\tsign: z.enum([\"<\", \">\", \"<=\", \">=\", \"!=\", \"==\"]),\n\tvalue: z.string(),\n\tonNaturalDice: z.boolean().optional(),\n\taffectSkill: z.boolean().optional(),\n});\n\nconst damageSchema = z\n\t.record(z.string())\n\t.optional()\n\t.refine((stats) => !stats || Object.keys(stats).length <= 25, {\n\t\tmessage: \"TooManyDice\",\n\t});\n\nconst customCriticalSchema = z\n\t.record(criticalValueSchema)\n\t.optional()\n\t.refine((stats) => !stats || Object.keys(stats).length <= 22, {\n\t\tmessage: \"TooManyDice\",\n\t});\n\nexport const templateSchema = z.object({\n\tcharName: z.boolean().optional(),\n\tstatistics: statisticSchema,\n\ttotal: z.number().min(0).optional(),\n\tdiceType: z.string().optional(),\n\tcritical: criticalSchema.optional(),\n\tcustomCritical: customCriticalSchema,\n\tdamage: damageSchema,\n});\n"],"mappings":"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","names":["value","roller","evaluateRoll","diceResult","evaluate","evaluate","evaluate","evaluate","cleanedDice"]}
|