@mathscan/math-exercise-engine 1.0.9 → 1.0.10
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.ts +67 -63
- package/dist/index.js +20 -9
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +20 -9
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -191,12 +191,6 @@ export declare function compile(dsl: string): ExerciseJSON;
|
|
|
191
191
|
*/
|
|
192
192
|
export declare function compileWithAST(dsl: string): {
|
|
193
193
|
ast: {
|
|
194
|
-
validation: {
|
|
195
|
-
type: "SimpleValidation";
|
|
196
|
-
} | {
|
|
197
|
-
expression: string;
|
|
198
|
-
type: "ExpressionValidation";
|
|
199
|
-
};
|
|
200
194
|
type: "ExerciseDocument";
|
|
201
195
|
lines: ({
|
|
202
196
|
type: "LineBlock";
|
|
@@ -324,6 +318,12 @@ export declare function compileWithAST(dsl: string): {
|
|
|
324
318
|
value: string;
|
|
325
319
|
type: "TextBlock";
|
|
326
320
|
} | undefined;
|
|
321
|
+
validation?: {
|
|
322
|
+
type: "SimpleValidation";
|
|
323
|
+
} | {
|
|
324
|
+
expression: string;
|
|
325
|
+
type: "ExpressionValidation";
|
|
326
|
+
} | undefined;
|
|
327
327
|
tools?: ({
|
|
328
328
|
type: "DragOptions";
|
|
329
329
|
options: string[];
|
|
@@ -334,12 +334,6 @@ export declare function compileWithAST(dsl: string): {
|
|
|
334
334
|
})[] | undefined;
|
|
335
335
|
};
|
|
336
336
|
json: {
|
|
337
|
-
validation: {
|
|
338
|
-
mode: "simple" | "expression";
|
|
339
|
-
expression?: string | undefined;
|
|
340
|
-
answers?: Record<string, string | number> | undefined;
|
|
341
|
-
variables?: string[] | undefined;
|
|
342
|
-
};
|
|
343
337
|
version: "2.0";
|
|
344
338
|
layout: any[];
|
|
345
339
|
widgets: Record<string, {
|
|
@@ -361,6 +355,12 @@ export declare function compileWithAST(dsl: string): {
|
|
|
361
355
|
includeOperators?: boolean | undefined;
|
|
362
356
|
includeDecimal?: boolean | undefined;
|
|
363
357
|
}>;
|
|
358
|
+
validation?: {
|
|
359
|
+
mode: "simple" | "expression";
|
|
360
|
+
expression?: string | undefined;
|
|
361
|
+
answers?: Record<string, string | number> | undefined;
|
|
362
|
+
variables?: string[] | undefined;
|
|
363
|
+
} | undefined;
|
|
364
364
|
id?: string | undefined;
|
|
365
365
|
meta?: {
|
|
366
366
|
createdAt?: string | undefined;
|
|
@@ -1314,7 +1314,7 @@ export declare function createDragOptions(options: string[]): DragOptionsTool;
|
|
|
1314
1314
|
/**
|
|
1315
1315
|
* Create an exercise document
|
|
1316
1316
|
*/
|
|
1317
|
-
export declare function createExerciseDocument(question: z.infer<typeof TextBlockSchema> | undefined, lines: ContentBlock[], validation
|
|
1317
|
+
export declare function createExerciseDocument(question: z.infer<typeof TextBlockSchema> | undefined, lines: ContentBlock[], validation?: z.infer<typeof ValidationNodeSchema>, tools?: z.infer<typeof ToolNodeSchema>[]): ExerciseDocument;
|
|
1318
1318
|
|
|
1319
1319
|
/**
|
|
1320
1320
|
* Create an expression validation node
|
|
@@ -2415,7 +2415,7 @@ export declare const ExerciseDocumentSchema: z.ZodObject<{
|
|
|
2415
2415
|
includeOperators?: boolean | undefined;
|
|
2416
2416
|
includeDecimal?: boolean | undefined;
|
|
2417
2417
|
}>]>, "many">>;
|
|
2418
|
-
validation: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
2418
|
+
validation: z.ZodOptional<z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
2419
2419
|
type: z.ZodLiteral<"SimpleValidation">;
|
|
2420
2420
|
}, "strip", z.ZodTypeAny, {
|
|
2421
2421
|
type: "SimpleValidation";
|
|
@@ -2430,14 +2430,8 @@ export declare const ExerciseDocumentSchema: z.ZodObject<{
|
|
|
2430
2430
|
}, {
|
|
2431
2431
|
expression: string;
|
|
2432
2432
|
type: "ExpressionValidation";
|
|
2433
|
-
}>]
|
|
2433
|
+
}>]>>;
|
|
2434
2434
|
}, "strip", z.ZodTypeAny, {
|
|
2435
|
-
validation: {
|
|
2436
|
-
type: "SimpleValidation";
|
|
2437
|
-
} | {
|
|
2438
|
-
expression: string;
|
|
2439
|
-
type: "ExpressionValidation";
|
|
2440
|
-
};
|
|
2441
2435
|
type: "ExerciseDocument";
|
|
2442
2436
|
lines: ({
|
|
2443
2437
|
type: "LineBlock";
|
|
@@ -2565,6 +2559,12 @@ export declare const ExerciseDocumentSchema: z.ZodObject<{
|
|
|
2565
2559
|
value: string;
|
|
2566
2560
|
type: "TextBlock";
|
|
2567
2561
|
} | undefined;
|
|
2562
|
+
validation?: {
|
|
2563
|
+
type: "SimpleValidation";
|
|
2564
|
+
} | {
|
|
2565
|
+
expression: string;
|
|
2566
|
+
type: "ExpressionValidation";
|
|
2567
|
+
} | undefined;
|
|
2568
2568
|
tools?: ({
|
|
2569
2569
|
type: "DragOptions";
|
|
2570
2570
|
options: string[];
|
|
@@ -2574,12 +2574,6 @@ export declare const ExerciseDocumentSchema: z.ZodObject<{
|
|
|
2574
2574
|
includeDecimal?: boolean | undefined;
|
|
2575
2575
|
})[] | undefined;
|
|
2576
2576
|
}, {
|
|
2577
|
-
validation: {
|
|
2578
|
-
type: "SimpleValidation";
|
|
2579
|
-
} | {
|
|
2580
|
-
expression: string;
|
|
2581
|
-
type: "ExpressionValidation";
|
|
2582
|
-
};
|
|
2583
2577
|
type: "ExerciseDocument";
|
|
2584
2578
|
lines: ({
|
|
2585
2579
|
type: "LineBlock";
|
|
@@ -2707,6 +2701,12 @@ export declare const ExerciseDocumentSchema: z.ZodObject<{
|
|
|
2707
2701
|
value: string;
|
|
2708
2702
|
type: "TextBlock";
|
|
2709
2703
|
} | undefined;
|
|
2704
|
+
validation?: {
|
|
2705
|
+
type: "SimpleValidation";
|
|
2706
|
+
} | {
|
|
2707
|
+
expression: string;
|
|
2708
|
+
type: "ExpressionValidation";
|
|
2709
|
+
} | undefined;
|
|
2710
2710
|
tools?: ({
|
|
2711
2711
|
type: "DragOptions";
|
|
2712
2712
|
options: string[];
|
|
@@ -2778,7 +2778,7 @@ export declare const ExerciseJSONSchema: z.ZodObject<{
|
|
|
2778
2778
|
includeOperators?: boolean | undefined;
|
|
2779
2779
|
includeDecimal?: boolean | undefined;
|
|
2780
2780
|
}>]>>;
|
|
2781
|
-
validation: z.ZodObject<{
|
|
2781
|
+
validation: z.ZodOptional<z.ZodObject<{
|
|
2782
2782
|
mode: z.ZodEnum<["simple", "expression"]>;
|
|
2783
2783
|
answers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodNumber]>>>;
|
|
2784
2784
|
expression: z.ZodOptional<z.ZodString>;
|
|
@@ -2793,7 +2793,7 @@ export declare const ExerciseJSONSchema: z.ZodObject<{
|
|
|
2793
2793
|
expression?: string | undefined;
|
|
2794
2794
|
answers?: Record<string, string | number> | undefined;
|
|
2795
2795
|
variables?: string[] | undefined;
|
|
2796
|
-
}
|
|
2796
|
+
}>>;
|
|
2797
2797
|
meta: z.ZodOptional<z.ZodObject<{
|
|
2798
2798
|
createdAt: z.ZodOptional<z.ZodString>;
|
|
2799
2799
|
author: z.ZodOptional<z.ZodString>;
|
|
@@ -2811,12 +2811,6 @@ export declare const ExerciseJSONSchema: z.ZodObject<{
|
|
|
2811
2811
|
difficulty?: number | undefined;
|
|
2812
2812
|
}>>;
|
|
2813
2813
|
}, "strip", z.ZodTypeAny, {
|
|
2814
|
-
validation: {
|
|
2815
|
-
mode: "simple" | "expression";
|
|
2816
|
-
expression?: string | undefined;
|
|
2817
|
-
answers?: Record<string, string | number> | undefined;
|
|
2818
|
-
variables?: string[] | undefined;
|
|
2819
|
-
};
|
|
2820
2814
|
version: "2.0";
|
|
2821
2815
|
layout: any[];
|
|
2822
2816
|
widgets: Record<string, {
|
|
@@ -2838,6 +2832,12 @@ export declare const ExerciseJSONSchema: z.ZodObject<{
|
|
|
2838
2832
|
includeOperators?: boolean | undefined;
|
|
2839
2833
|
includeDecimal?: boolean | undefined;
|
|
2840
2834
|
}>;
|
|
2835
|
+
validation?: {
|
|
2836
|
+
mode: "simple" | "expression";
|
|
2837
|
+
expression?: string | undefined;
|
|
2838
|
+
answers?: Record<string, string | number> | undefined;
|
|
2839
|
+
variables?: string[] | undefined;
|
|
2840
|
+
} | undefined;
|
|
2841
2841
|
id?: string | undefined;
|
|
2842
2842
|
meta?: {
|
|
2843
2843
|
createdAt?: string | undefined;
|
|
@@ -2846,12 +2846,6 @@ export declare const ExerciseJSONSchema: z.ZodObject<{
|
|
|
2846
2846
|
difficulty?: number | undefined;
|
|
2847
2847
|
} | undefined;
|
|
2848
2848
|
}, {
|
|
2849
|
-
validation: {
|
|
2850
|
-
mode: "simple" | "expression";
|
|
2851
|
-
expression?: string | undefined;
|
|
2852
|
-
answers?: Record<string, string | number> | undefined;
|
|
2853
|
-
variables?: string[] | undefined;
|
|
2854
|
-
};
|
|
2855
2849
|
version: "2.0";
|
|
2856
2850
|
layout: any[];
|
|
2857
2851
|
widgets: Record<string, {
|
|
@@ -2873,6 +2867,12 @@ export declare const ExerciseJSONSchema: z.ZodObject<{
|
|
|
2873
2867
|
includeOperators?: boolean | undefined;
|
|
2874
2868
|
includeDecimal?: boolean | undefined;
|
|
2875
2869
|
}>;
|
|
2870
|
+
validation?: {
|
|
2871
|
+
mode: "simple" | "expression";
|
|
2872
|
+
expression?: string | undefined;
|
|
2873
|
+
answers?: Record<string, string | number> | undefined;
|
|
2874
|
+
variables?: string[] | undefined;
|
|
2875
|
+
} | undefined;
|
|
2876
2876
|
id?: string | undefined;
|
|
2877
2877
|
meta?: {
|
|
2878
2878
|
createdAt?: string | undefined;
|
|
@@ -4944,6 +4944,10 @@ export declare function validate(exercise: ExerciseJSON, userInputs: Record<stri
|
|
|
4944
4944
|
*/
|
|
4945
4945
|
export declare function validateBooleanExpression(expression: string): string | null;
|
|
4946
4946
|
|
|
4947
|
+
declare type ValidatedExerciseJSON = ExerciseJSON & {
|
|
4948
|
+
validation: ValidationJSON;
|
|
4949
|
+
};
|
|
4950
|
+
|
|
4947
4951
|
/**
|
|
4948
4952
|
* Validate an exercise JSON object at runtime
|
|
4949
4953
|
*
|
|
@@ -4962,12 +4966,6 @@ export declare function validateBooleanExpression(expression: string): string |
|
|
|
4962
4966
|
* ```
|
|
4963
4967
|
*/
|
|
4964
4968
|
export declare function validateExerciseJSON(data: unknown): {
|
|
4965
|
-
validation: {
|
|
4966
|
-
mode: "simple" | "expression";
|
|
4967
|
-
expression?: string | undefined;
|
|
4968
|
-
answers?: Record<string, string | number> | undefined;
|
|
4969
|
-
variables?: string[] | undefined;
|
|
4970
|
-
};
|
|
4971
4969
|
version: "2.0";
|
|
4972
4970
|
layout: any[];
|
|
4973
4971
|
widgets: Record<string, {
|
|
@@ -4989,6 +4987,12 @@ export declare function validateExerciseJSON(data: unknown): {
|
|
|
4989
4987
|
includeOperators?: boolean | undefined;
|
|
4990
4988
|
includeDecimal?: boolean | undefined;
|
|
4991
4989
|
}>;
|
|
4990
|
+
validation?: {
|
|
4991
|
+
mode: "simple" | "expression";
|
|
4992
|
+
expression?: string | undefined;
|
|
4993
|
+
answers?: Record<string, string | number> | undefined;
|
|
4994
|
+
variables?: string[] | undefined;
|
|
4995
|
+
} | undefined;
|
|
4992
4996
|
id?: string | undefined;
|
|
4993
4997
|
meta?: {
|
|
4994
4998
|
createdAt?: string | undefined;
|
|
@@ -5015,12 +5019,6 @@ export declare function validateExerciseJSON(data: unknown): {
|
|
|
5015
5019
|
* ```
|
|
5016
5020
|
*/
|
|
5017
5021
|
export declare function validateExerciseJSONSafe(data: unknown): z.SafeParseReturnType<{
|
|
5018
|
-
validation: {
|
|
5019
|
-
mode: "simple" | "expression";
|
|
5020
|
-
expression?: string | undefined;
|
|
5021
|
-
answers?: Record<string, string | number> | undefined;
|
|
5022
|
-
variables?: string[] | undefined;
|
|
5023
|
-
};
|
|
5024
5022
|
version: "2.0";
|
|
5025
5023
|
layout: any[];
|
|
5026
5024
|
widgets: Record<string, {
|
|
@@ -5042,6 +5040,12 @@ export declare function validateExerciseJSONSafe(data: unknown): z.SafeParseRetu
|
|
|
5042
5040
|
includeOperators?: boolean | undefined;
|
|
5043
5041
|
includeDecimal?: boolean | undefined;
|
|
5044
5042
|
}>;
|
|
5043
|
+
validation?: {
|
|
5044
|
+
mode: "simple" | "expression";
|
|
5045
|
+
expression?: string | undefined;
|
|
5046
|
+
answers?: Record<string, string | number> | undefined;
|
|
5047
|
+
variables?: string[] | undefined;
|
|
5048
|
+
} | undefined;
|
|
5045
5049
|
id?: string | undefined;
|
|
5046
5050
|
meta?: {
|
|
5047
5051
|
createdAt?: string | undefined;
|
|
@@ -5050,12 +5054,6 @@ export declare function validateExerciseJSONSafe(data: unknown): z.SafeParseRetu
|
|
|
5050
5054
|
difficulty?: number | undefined;
|
|
5051
5055
|
} | undefined;
|
|
5052
5056
|
}, {
|
|
5053
|
-
validation: {
|
|
5054
|
-
mode: "simple" | "expression";
|
|
5055
|
-
expression?: string | undefined;
|
|
5056
|
-
answers?: Record<string, string | number> | undefined;
|
|
5057
|
-
variables?: string[] | undefined;
|
|
5058
|
-
};
|
|
5059
5057
|
version: "2.0";
|
|
5060
5058
|
layout: any[];
|
|
5061
5059
|
widgets: Record<string, {
|
|
@@ -5077,6 +5075,12 @@ export declare function validateExerciseJSONSafe(data: unknown): z.SafeParseRetu
|
|
|
5077
5075
|
includeOperators?: boolean | undefined;
|
|
5078
5076
|
includeDecimal?: boolean | undefined;
|
|
5079
5077
|
}>;
|
|
5078
|
+
validation?: {
|
|
5079
|
+
mode: "simple" | "expression";
|
|
5080
|
+
expression?: string | undefined;
|
|
5081
|
+
answers?: Record<string, string | number> | undefined;
|
|
5082
|
+
variables?: string[] | undefined;
|
|
5083
|
+
} | undefined;
|
|
5080
5084
|
id?: string | undefined;
|
|
5081
5085
|
meta?: {
|
|
5082
5086
|
createdAt?: string | undefined;
|
|
@@ -5089,11 +5093,11 @@ export declare function validateExerciseJSONSafe(data: unknown): z.SafeParseRetu
|
|
|
5089
5093
|
/**
|
|
5090
5094
|
* Validate using expression mode
|
|
5091
5095
|
*
|
|
5092
|
-
* @param exercise - The exercise JSON
|
|
5096
|
+
* @param exercise - The exercise JSON (with validation present)
|
|
5093
5097
|
* @param userInputs - User's answers keyed by widget ID (variable names)
|
|
5094
5098
|
* @returns Validation result
|
|
5095
5099
|
*/
|
|
5096
|
-
export declare function validateExpression(exercise:
|
|
5100
|
+
export declare function validateExpression(exercise: ValidatedExerciseJSON, userInputs: Record<string, string | number>): ValidationResult;
|
|
5097
5101
|
|
|
5098
5102
|
/**
|
|
5099
5103
|
* Check if user inputs are valid (proper format, etc.)
|
|
@@ -5108,11 +5112,11 @@ export declare function validateInputFormats(exercise: ExerciseJSON, userInputs:
|
|
|
5108
5112
|
/**
|
|
5109
5113
|
* Validate using simple mode (predetermined answers)
|
|
5110
5114
|
*
|
|
5111
|
-
* @param exercise - The exercise JSON
|
|
5115
|
+
* @param exercise - The exercise JSON (with validation present)
|
|
5112
5116
|
* @param userInputs - User's answers keyed by widget ID
|
|
5113
5117
|
* @returns Validation result
|
|
5114
5118
|
*/
|
|
5115
|
-
export declare function validateSimple(exercise:
|
|
5119
|
+
export declare function validateSimple(exercise: ValidatedExerciseJSON, userInputs: Record<string, string | number>): ValidationResult;
|
|
5116
5120
|
|
|
5117
5121
|
/**
|
|
5118
5122
|
* Validate a widget JSON object at runtime
|
package/dist/index.js
CHANGED
|
@@ -445,7 +445,9 @@ class MathExerciseParser extends chevrotain.CstParser {
|
|
|
445
445
|
this.MANY3(() => {
|
|
446
446
|
this.SUBRULE(this.tool);
|
|
447
447
|
});
|
|
448
|
-
this.
|
|
448
|
+
this.OPTION2(() => {
|
|
449
|
+
this.SUBRULE(this.validation);
|
|
450
|
+
});
|
|
449
451
|
this.MANY4(() => {
|
|
450
452
|
this.OR2([
|
|
451
453
|
{ ALT: () => this.CONSUME2(Newline) },
|
|
@@ -1203,7 +1205,7 @@ const ExerciseDocumentSchema = zod.z.object({
|
|
|
1203
1205
|
question: TextBlockSchema.optional(),
|
|
1204
1206
|
lines: zod.z.array(ContentBlockSchema),
|
|
1205
1207
|
tools: zod.z.array(ToolNodeSchema).optional(),
|
|
1206
|
-
validation: ValidationNodeSchema
|
|
1208
|
+
validation: ValidationNodeSchema.optional()
|
|
1207
1209
|
});
|
|
1208
1210
|
function createExerciseDocument(question, lines, validation, tools) {
|
|
1209
1211
|
return ExerciseDocumentSchema.parse({
|
|
@@ -1230,7 +1232,7 @@ class NaturalDSLVisitor extends BaseCstVisitor {
|
|
|
1230
1232
|
const question = ctx.question ? this.visit(ctx.question) : void 0;
|
|
1231
1233
|
const contentBlocks = ctx.contentBlock ? ctx.contentBlock.map((cb) => this.visit(cb)) : [];
|
|
1232
1234
|
const tools = ctx.tool ? ctx.tool.map((t) => this.visit(t)) : [];
|
|
1233
|
-
const validation = this.visit(ctx.validation);
|
|
1235
|
+
const validation = ctx.validation ? this.visit(ctx.validation) : void 0;
|
|
1234
1236
|
return createExerciseDocument(question, contentBlocks, validation, tools);
|
|
1235
1237
|
}
|
|
1236
1238
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -1695,7 +1697,7 @@ const ExerciseJSONSchema = zod.z.object({
|
|
|
1695
1697
|
id: zod.z.string().optional(),
|
|
1696
1698
|
layout: zod.z.array(LayoutItemSchema),
|
|
1697
1699
|
widgets: zod.z.record(WidgetJSONSchema),
|
|
1698
|
-
validation: ValidationJSONSchema,
|
|
1700
|
+
validation: ValidationJSONSchema.optional(),
|
|
1699
1701
|
meta: ExerciseMetaSchema.optional()
|
|
1700
1702
|
});
|
|
1701
1703
|
function validateExerciseJSON(data) {
|
|
@@ -1852,13 +1854,12 @@ function toJSON(ast) {
|
|
|
1852
1854
|
}
|
|
1853
1855
|
}
|
|
1854
1856
|
}
|
|
1855
|
-
const validation = transformValidation(ast.validation, answers, widgets);
|
|
1856
1857
|
return {
|
|
1857
1858
|
version: "2.0",
|
|
1858
1859
|
// Natural DSL version
|
|
1859
1860
|
layout,
|
|
1860
1861
|
widgets,
|
|
1861
|
-
validation
|
|
1862
|
+
...ast.validation ? { validation: transformValidation(ast.validation, answers, widgets) } : {}
|
|
1862
1863
|
};
|
|
1863
1864
|
}
|
|
1864
1865
|
function collectAllInlines(blocks) {
|
|
@@ -2329,11 +2330,18 @@ function findValidCombination(expression, ranges) {
|
|
|
2329
2330
|
return null;
|
|
2330
2331
|
}
|
|
2331
2332
|
function validate(exercise, userInputs) {
|
|
2332
|
-
|
|
2333
|
+
if (!exercise.validation) {
|
|
2334
|
+
return {
|
|
2335
|
+
isCorrect: true,
|
|
2336
|
+
details: {}
|
|
2337
|
+
};
|
|
2338
|
+
}
|
|
2339
|
+
const validatedExercise = exercise;
|
|
2340
|
+
switch (validatedExercise.validation.mode) {
|
|
2333
2341
|
case VALIDATION_MODES.SIMPLE:
|
|
2334
|
-
return validateSimple(
|
|
2342
|
+
return validateSimple(validatedExercise, userInputs);
|
|
2335
2343
|
case VALIDATION_MODES.EXPRESSION:
|
|
2336
|
-
return validateExpression(
|
|
2344
|
+
return validateExpression(validatedExercise, userInputs);
|
|
2337
2345
|
default:
|
|
2338
2346
|
return {
|
|
2339
2347
|
isCorrect: false,
|
|
@@ -2344,6 +2352,9 @@ function validate(exercise, userInputs) {
|
|
|
2344
2352
|
}
|
|
2345
2353
|
function getMissingInputs(exercise, userInputs) {
|
|
2346
2354
|
const missing = [];
|
|
2355
|
+
if (!exercise.validation) {
|
|
2356
|
+
return missing;
|
|
2357
|
+
}
|
|
2347
2358
|
if (exercise.validation.mode === VALIDATION_MODES.SIMPLE && exercise.validation.answers) {
|
|
2348
2359
|
for (const widgetId of Object.keys(exercise.validation.answers)) {
|
|
2349
2360
|
if (!(widgetId in userInputs) || userInputs[widgetId] === "") {
|