@intellectif/lk-core 0.8.2 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/README.md +5 -4
- package/dist/{chunk-2M76F32Y.js → chunk-6DM2H6BD.js} +2 -2
- package/dist/{chunk-HCOWSGEZ.js → chunk-AHEUYOT3.js} +705 -17
- package/dist/chunk-AHEUYOT3.js.map +1 -0
- package/dist/{chunk-FKH4YT5X.cjs → chunk-CVRALNUK.cjs} +706 -18
- package/dist/chunk-CVRALNUK.cjs.map +1 -0
- package/dist/{chunk-NHGXOOZ2.js → chunk-ELTP5P6V.js} +2 -2
- package/dist/{chunk-YJZY5TPY.cjs → chunk-MOLL5KXO.cjs} +8 -8
- package/dist/{chunk-YJZY5TPY.cjs.map → chunk-MOLL5KXO.cjs.map} +1 -1
- package/dist/{chunk-LNA33IK7.js → chunk-QX7P3CHP.js} +2 -2
- package/dist/{chunk-7ACNBDSF.cjs → chunk-RL2PQLCY.cjs} +4 -4
- package/dist/{chunk-7ACNBDSF.cjs.map → chunk-RL2PQLCY.cjs.map} +1 -1
- package/dist/{chunk-FVLKIL6W.cjs → chunk-YVZCFUGP.cjs} +12 -12
- package/dist/{chunk-FVLKIL6W.cjs.map → chunk-YVZCFUGP.cjs.map} +1 -1
- package/dist/index.cjs +134 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +157 -6
- package/dist/index.d.ts +157 -6
- package/dist/index.js +115 -23
- package/dist/index.js.map +1 -1
- package/dist/schemas.cjs +3 -3
- package/dist/schemas.js +2 -2
- package/dist/scoring.cjs +3 -3
- package/dist/scoring.js +2 -2
- package/dist/xapi.cjs +3 -3
- package/dist/xapi.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-FKH4YT5X.cjs.map +0 -1
- package/dist/chunk-HCOWSGEZ.js.map +0 -1
- /package/dist/{chunk-2M76F32Y.js.map → chunk-6DM2H6BD.js.map} +0 -0
- /package/dist/{chunk-NHGXOOZ2.js.map → chunk-ELTP5P6V.js.map} +0 -0
- /package/dist/{chunk-LNA33IK7.js.map → chunk-QX7P3CHP.js.map} +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ScoredItem } from './scoring.js';
|
|
2
2
|
export { AssessmentScore, AssessmentSectionInput, Band, CompositionPolicy, DEFAULT_PASS_THRESHOLD, PassFailureReason, RoundingMode, RoundingPolicy, SectionScore, classifyBand, composeAssessmentScore, computePassThreshold, evaluate, gte, roundGrade, score } from './scoring.js';
|
|
3
|
-
import { m as ItemOutcome, A as ActivityData, L as LearnerResponse, V as ValidationError, C as CriterionScore, G as GradeRecord, N as NativeControlHint, c as ActivityMedia, r as ScoringResult, D as DeferredScoringPartial, F as FillInTheBlanksData, f as FillInTheBlanksLearnerResponse, M as MultipleChoiceData, o as MultipleChoiceLearnerResponse, W as WrittenResponseData, u as WrittenResponseLearnerResponse } from './activity-CPtJUBek.js';
|
|
4
|
-
export {
|
|
3
|
+
import { m as ItemOutcome, A as ActivityData, L as LearnerResponse, V as ValidationError, e as ActivityType, a as ActivityDataMap, C as CriterionScore, G as GradeRecord, N as NativeControlHint, c as ActivityMedia, r as ScoringResult, D as DeferredScoringPartial, F as FillInTheBlanksData, f as FillInTheBlanksLearnerResponse, M as MultipleChoiceData, o as MultipleChoiceLearnerResponse, W as WrittenResponseData, u as WrittenResponseLearnerResponse } from './activity-CPtJUBek.js';
|
|
4
|
+
export { b as ActivityFeedback, d as ActivityResult, B as BlankConfig, g as Grader, h as GraderKind, i as GraderUsage, j as GradingState, I as InlineCorrection, k as InteractionEvent, l as InteractionKind, n as LearnerResponseMap, p as MultipleChoiceOption, S as ScoringDetail, q as ScoringOutcome, T as TextMatchPolicy, s as TextMatchResult, t as ValidationResult, v as WrittenResponseRubric, w as WrittenResponseRubricCriterion, X as XAPIActor, x as XAPIConfig, y as XAPIContext, z as XAPIContextActivities, E as XAPIError, H as XAPIObject, J as XAPIResult, K as XAPIScore, O as XAPIStatement, P as XAPIVerbObject, Q as levenshteinDistance, R as matchText } from './activity-CPtJUBek.js';
|
|
5
5
|
import { u as SequenceSlot, S as SequenceEntry, I as ItemGroup } from './index-BvrA8nIV.js';
|
|
6
6
|
export { B as BlankConfigSchema, F as FeedbackSchema, a as FillInTheBlanksDataSchema, b as ItemGroupSchema, M as MediaPlaybackSchema, c as MediaSchema, d as MediaUrlSchema, e as MultipleChoiceDataSchema, f as MultipleChoiceOptionSchema, N as NativeControlHintSchema, R as RedactedActivity, g as RedactedBlankConfig, h as RedactedBlankConfigSchema, i as RedactedFillInTheBlanksData, j as RedactedFillInTheBlanksDataSchema, k as RedactedItemGroupSchema, l as RedactedMediaSchema, m as RedactedMultipleChoiceData, n as RedactedMultipleChoiceDataSchema, o as RedactedMultipleChoiceOption, p as RedactedMultipleChoiceOptionSchema, q as RedactedStimulus, r as RedactedStimulusSchema, s as RedactedWrittenResponseData, t as RedactedWrittenResponseDataSchema, v as SequenceSlotGroup, w as Stimulus, x as StimulusKind, y as StimulusSchema, T as TextMatchPolicySchema, W as WrittenResponseDataSchema, z as WrittenResponseRubricCriterionSchema, A as WrittenResponseRubricSchema, C as fillInTheBlanksJsonSchema, D as itemGroupJsonSchema, E as jsonSchemaFor, G as multipleChoiceJsonSchema, H as stimulusJsonSchema, J as validateActivity, K as validateItemGroup, L as writtenResponseJsonSchema } from './index-BvrA8nIV.js';
|
|
7
7
|
import { z } from 'zod/v4';
|
|
@@ -327,6 +327,118 @@ declare function restoreAttemptState(plan: AttemptPlan, state: AttemptState): At
|
|
|
327
327
|
*/
|
|
328
328
|
declare function diffResponses(before: Pick<AttemptState, 'responses'>, after: Pick<AttemptState, 'responses'>): ResponseDiffEntry[];
|
|
329
329
|
|
|
330
|
+
/**
|
|
331
|
+
* Why a draft is not an activity yet.
|
|
332
|
+
*
|
|
333
|
+
* - `incomplete` — something the author has not written yet: an empty title, an
|
|
334
|
+
* option with no text, no option marked correct. The fix is to add it.
|
|
335
|
+
* - `invalid` — something is wrong in a way that writing more cannot fix: two
|
|
336
|
+
* correct options on a single-selection question, a maximum word count below
|
|
337
|
+
* the minimum, a media address with a scheme the SDK refuses, a `null` in an
|
|
338
|
+
* optional field that accepts none. The fix is to change it.
|
|
339
|
+
*/
|
|
340
|
+
type DraftSeverity = 'incomplete' | 'invalid';
|
|
341
|
+
/**
|
|
342
|
+
* One problem with a draft. A {@link ValidationError} with a severity, so code
|
|
343
|
+
* that already lists `validateActivity` errors can list these unchanged.
|
|
344
|
+
*/
|
|
345
|
+
interface DraftIssue extends ValidationError {
|
|
346
|
+
severity: DraftSeverity;
|
|
347
|
+
}
|
|
348
|
+
/** A draft that is a valid activity and has nothing left to write. */
|
|
349
|
+
interface DraftComplete<T> {
|
|
350
|
+
status: 'complete';
|
|
351
|
+
/** The validated activity, exactly as `validateActivity` returns it. */
|
|
352
|
+
data: T;
|
|
353
|
+
/** Always empty. Present so that every result can be read the same way. */
|
|
354
|
+
issues: DraftIssue[];
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* A draft that is not an activity yet: `invalid` when any issue is invalid,
|
|
358
|
+
* otherwise `incomplete`. It carries no `data`, because nothing here may be
|
|
359
|
+
* stored or rendered as an activity.
|
|
360
|
+
*/
|
|
361
|
+
interface DraftNotComplete {
|
|
362
|
+
status: 'incomplete' | 'invalid';
|
|
363
|
+
issues: DraftIssue[];
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* The result of `validateDraft`.
|
|
367
|
+
*
|
|
368
|
+
* There is deliberately no `success` boolean. A boolean has to call an
|
|
369
|
+
* incomplete draft either a success, which lets a half-written answer key
|
|
370
|
+
* through anything that checks it, or a failure, which is the conflation this
|
|
371
|
+
* result exists to remove. Branch on `status`.
|
|
372
|
+
*/
|
|
373
|
+
type DraftValidationResult<T> = DraftComplete<T> | DraftNotComplete;
|
|
374
|
+
/** What `createDraft` hands an activity type's `authoring.createDraft`. */
|
|
375
|
+
interface DraftContext {
|
|
376
|
+
/**
|
|
377
|
+
* Returns a new id on every call. The SDK invents none: an id made here would
|
|
378
|
+
* need `crypto`, which plain-http origins do not have, or would be positional —
|
|
379
|
+
* and option ids reach the learner, so ids like `"a"` and `"b"` would tell them
|
|
380
|
+
* which option was written first.
|
|
381
|
+
*/
|
|
382
|
+
newId: () => string;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Tells a draft that is not finished from a draft that is wrong.
|
|
387
|
+
*
|
|
388
|
+
* `validateActivity` answers "may this be stored?", and to that question an
|
|
389
|
+
* empty new question and a broken one are the same answer: no. An editor needs
|
|
390
|
+
* the difference — "Add a title" is a to-do, "Only one option can be marked
|
|
391
|
+
* correct" is an error — so a freshly added question does not read as a
|
|
392
|
+
* failure, disable a whole form, or blank a preview.
|
|
393
|
+
*
|
|
394
|
+
* - `complete` — the draft is a valid activity with nothing left to write.
|
|
395
|
+
* `data` is exactly what `validateActivity` returns for it.
|
|
396
|
+
* - `incomplete` — every problem is something not yet written.
|
|
397
|
+
* - `invalid` — at least one problem is wrong in a way writing more cannot fix.
|
|
398
|
+
*
|
|
399
|
+
* It is stricter than `validateActivity`, never looser: `complete` requires the
|
|
400
|
+
* activity's schema to pass, and a draft can fail here that the schema accepts
|
|
401
|
+
* (a title that is only whitespace). Content stored by an older build can
|
|
402
|
+
* therefore be valid and still not `complete`. `validateActivity` stays the
|
|
403
|
+
* check at your write boundary.
|
|
404
|
+
*
|
|
405
|
+
* Issues come from the type's `authoring.checkDraft`, plus every schema failure
|
|
406
|
+
* it did not already report at that path or inside it. (A failure at the root of
|
|
407
|
+
* the draft counts as reported only by an issue at the root, since every path is
|
|
408
|
+
* inside the root.) Such a failure is added as `invalid`: under the code
|
|
409
|
+
* `null_not_allowed` when the schema refused a `null` there, or an `undefined`
|
|
410
|
+
* entry in a list, and otherwise under the schema's own code and message. A type
|
|
411
|
+
* with no `checkDraft` therefore reports every schema failure as `invalid`.
|
|
412
|
+
*
|
|
413
|
+
* The codes documented in `docs/authoring.md` are a contract, and each is
|
|
414
|
+
* reported with its documented severity, whichever check reports it. A code
|
|
415
|
+
* passed through from the schema is not a contract: the code and its English
|
|
416
|
+
* message belong to the schema library, so give a code you do not recognise a
|
|
417
|
+
* generic message of your own.
|
|
418
|
+
*
|
|
419
|
+
* @throws UnknownActivityTypeError when `type` has no registered descriptor —
|
|
420
|
+
* including `'item-group'`, which is a container, not an activity type.
|
|
421
|
+
*/
|
|
422
|
+
declare function validateDraft<T extends ActivityType>(type: T, draft: unknown): DraftValidationResult<ActivityDataMap[T]>;
|
|
423
|
+
/**
|
|
424
|
+
* A new, empty draft of an activity type, for an editor to start from.
|
|
425
|
+
*
|
|
426
|
+
* Every required field is present and nothing is authored, so the draft comes
|
|
427
|
+
* back from {@link validateDraft} as `incomplete`, and `validateActivity`
|
|
428
|
+
* rejects it until someone writes it. The SDK invents no ids: `newId` is called
|
|
429
|
+
* once per id the draft needs, and must return a different non-empty string each
|
|
430
|
+
* time.
|
|
431
|
+
*
|
|
432
|
+
* ```ts
|
|
433
|
+
* const draft = createDraft('multiple-choice', { newId: () => crypto.randomUUID() });
|
|
434
|
+
* ```
|
|
435
|
+
*
|
|
436
|
+
* @throws UnknownActivityTypeError when `type` has no registered descriptor.
|
|
437
|
+
* @throws Error when the type declares no `authoring.createDraft`, or when
|
|
438
|
+
* `newId` returns an empty or repeated id.
|
|
439
|
+
*/
|
|
440
|
+
declare function createDraft<T extends ActivityType>(type: T, context: DraftContext): ActivityDataMap[T];
|
|
441
|
+
|
|
330
442
|
/**
|
|
331
443
|
* Content fingerprinting — "is this the same content the learner was served?"
|
|
332
444
|
*
|
|
@@ -706,12 +818,48 @@ type ActivityTypeScoring<TData, TResponse> = {
|
|
|
706
818
|
readonly reason: 'requires_async_grading';
|
|
707
819
|
readonly partial?: (data: TData, response: TResponse | undefined) => DeferredScoringPartial;
|
|
708
820
|
};
|
|
821
|
+
/**
|
|
822
|
+
* Authoring support for an activity type: the empty draft an editor starts
|
|
823
|
+
* from, and the rules that tell a draft that is unfinished from one that is
|
|
824
|
+
* wrong. Both are optional. Without `checkDraft`, `validateDraft` still works
|
|
825
|
+
* and reports every schema failure as `invalid`; without `createDraft`,
|
|
826
|
+
* `createDraft()` throws for the type.
|
|
827
|
+
*/
|
|
828
|
+
interface ActivityTypeAuthoring<TData> {
|
|
829
|
+
/**
|
|
830
|
+
* A new draft: every required field present, nothing authored yet. It must
|
|
831
|
+
* come back from `validateDraft` as `incomplete` — never `invalid`, and never
|
|
832
|
+
* `complete` — so a freshly added question is not reported as an error, and
|
|
833
|
+
* cannot pass validation before anyone has written it.
|
|
834
|
+
*/
|
|
835
|
+
readonly createDraft?: (context: DraftContext) => TData;
|
|
836
|
+
/**
|
|
837
|
+
* Reports what is missing (`incomplete`) and what is wrong (`invalid`) in a
|
|
838
|
+
* draft. Receives any plain object and must not throw on one.
|
|
839
|
+
*
|
|
840
|
+
* Report each problem at the path the schema reports it. `validateDraft` adds
|
|
841
|
+
* every schema failure as `invalid` unless an issue returned here sits at that
|
|
842
|
+
* path or inside it — so an issue at the wrong path leaves the schema's
|
|
843
|
+
* message standing beside yours, and makes an unfinished draft read as wrong.
|
|
844
|
+
* An issue inside a path accounts for every failure at that path, a list's
|
|
845
|
+
* length included, so report a rule about a whole list at the list's own path.
|
|
846
|
+
* A failure at the root of the draft is accounted for only by an issue at the
|
|
847
|
+
* root. A `null` the schema refuses, where nothing here reports it, comes back
|
|
848
|
+
* as `null_not_allowed` — except inside a plain `z.union`, which reports a
|
|
849
|
+
* failure once, at the union's own path, under its own code.
|
|
850
|
+
*
|
|
851
|
+
* A code documented in `docs/authoring.md` is reported with its documented
|
|
852
|
+
* severity. For a code of your own, a severity other than `'incomplete'` is
|
|
853
|
+
* reported as `invalid`.
|
|
854
|
+
*/
|
|
855
|
+
readonly checkDraft?: (draft: Readonly<Record<string, unknown>>) => DraftIssue[];
|
|
856
|
+
}
|
|
709
857
|
/**
|
|
710
858
|
* A value-level description of an activity type: its contract (schema), its
|
|
711
859
|
* grading, its redaction policy, and its interop facts. Registering a
|
|
712
|
-
* descriptor makes `validateActivity`, `
|
|
713
|
-
* `jsonSchemaFor` work for the type — an activity type is a value,
|
|
714
|
-
* hardcoded union member (R1).
|
|
860
|
+
* descriptor makes `validateActivity`, `validateDraft`, `score`, `evaluate`,
|
|
861
|
+
* `redact`, and `jsonSchemaFor` work for the type — an activity type is a value,
|
|
862
|
+
* not a hardcoded union member (R1).
|
|
715
863
|
*/
|
|
716
864
|
interface ActivityTypeDescriptor<TData extends {
|
|
717
865
|
type: string;
|
|
@@ -736,6 +884,8 @@ interface ActivityTypeDescriptor<TData extends {
|
|
|
736
884
|
readonly interop?: ActivityTypeInterop<TData>;
|
|
737
885
|
/** The interaction-event kinds components for this type emit. */
|
|
738
886
|
readonly interactions?: readonly string[];
|
|
887
|
+
/** Draft support for authoring tools. See {@link ActivityTypeAuthoring}. */
|
|
888
|
+
readonly authoring?: ActivityTypeAuthoring<TData>;
|
|
739
889
|
}
|
|
740
890
|
/**
|
|
741
891
|
* Internal type-erased descriptor shape stored in the registry. Dispatch call
|
|
@@ -757,6 +907,7 @@ interface RegisteredActivityTypeDescriptor {
|
|
|
757
907
|
readonly redactedSchema?: z.ZodType<unknown>;
|
|
758
908
|
readonly interop?: ActivityTypeInterop<unknown>;
|
|
759
909
|
readonly interactions?: readonly string[];
|
|
910
|
+
readonly authoring?: ActivityTypeAuthoring<unknown>;
|
|
760
911
|
}
|
|
761
912
|
/**
|
|
762
913
|
* Identity helper that gives full type inference when authoring a descriptor:
|
|
@@ -997,4 +1148,4 @@ interface ThemeTokens {
|
|
|
997
1148
|
'--lk-transition-base': string;
|
|
998
1149
|
}
|
|
999
1150
|
|
|
1000
|
-
export { ActivityData, ActivityMedia, ActivitySchemaError, type ActivityTypeDescriptor, type ActivityTypeInterop, type ActivityTypeScoring, type AttemptPlan, type AttemptPlanDrift, type AttemptPlanSlot, type AttemptProgress, type AttemptState, CriterionScore, DeferredScoringError, DeferredScoringPartial, type FieldPolicy, FillInTheBlanksData, FillInTheBlanksLearnerResponse, type FlattenSequenceOptions, type GradeFromRubricOptions, GradeRecord, ItemGroup, ItemOutcome, LearnerResponse, type MediaBudgetRef, type MediaPlayClaim, type MediaPlayGrant, type MediaPlayLedger, type MediaPlayLedgerEntry, type MissingOutcomePolicy, MultipleChoiceData, MultipleChoiceLearnerResponse, type PartialScoringResult, type PlanAttemptOptions, type PlannableEntry, type RedactOptions, type RedactedActivityData, type RedactedItemGroup, RedactedScoringError, type RegisteredActivityTypeDescriptor, type ResolvedPlaybackPolicy, type ResponseDiffEntry, ScoredItem, ScoringResult, type SeededShuffleOptions, type Sensitivity, SequenceEntry, SequenceSlot, type ShuffleVersion, type ThemeTokens, UnknownActivityTypeError, ValidationError, WrittenResponseData, WrittenResponseLearnerResponse, type XAPIInteractionType, assertRedacted, assertRedactedItemGroup, canonicalJson, contentHash, countWords, defineActivityType, diffResponses, entryKeyOf, fillInTheBlanksType, fingerprint, flattenSequence, getActivityTypeDescriptor, gradeFromRubric, hasGrade, hashSeed, isItemGroup, multipleChoiceType, outcomeFromGrade, planAttempt, planMediaBudgets, redact, redactItemGroup, registerActivityType, registeredActivityTypes, resolvePlaybackPolicy, restoreAttemptState, restoreMediaPlayLedger, scoredItemsFromPlan, seededShuffle, serializeAttemptState, serializeMediaPlayLedger, slotMediaKey, stimulusMediaKey, verifyAttemptPlan, writtenResponseType };
|
|
1151
|
+
export { ActivityData, ActivityDataMap, ActivityMedia, ActivitySchemaError, ActivityType, type ActivityTypeAuthoring, type ActivityTypeDescriptor, type ActivityTypeInterop, type ActivityTypeScoring, type AttemptPlan, type AttemptPlanDrift, type AttemptPlanSlot, type AttemptProgress, type AttemptState, CriterionScore, DeferredScoringError, DeferredScoringPartial, type DraftComplete, type DraftContext, type DraftIssue, type DraftNotComplete, type DraftSeverity, type DraftValidationResult, type FieldPolicy, FillInTheBlanksData, FillInTheBlanksLearnerResponse, type FlattenSequenceOptions, type GradeFromRubricOptions, GradeRecord, ItemGroup, ItemOutcome, LearnerResponse, type MediaBudgetRef, type MediaPlayClaim, type MediaPlayGrant, type MediaPlayLedger, type MediaPlayLedgerEntry, type MissingOutcomePolicy, MultipleChoiceData, MultipleChoiceLearnerResponse, type PartialScoringResult, type PlanAttemptOptions, type PlannableEntry, type RedactOptions, type RedactedActivityData, type RedactedItemGroup, RedactedScoringError, type RegisteredActivityTypeDescriptor, type ResolvedPlaybackPolicy, type ResponseDiffEntry, ScoredItem, ScoringResult, type SeededShuffleOptions, type Sensitivity, SequenceEntry, SequenceSlot, type ShuffleVersion, type ThemeTokens, UnknownActivityTypeError, ValidationError, WrittenResponseData, WrittenResponseLearnerResponse, type XAPIInteractionType, assertRedacted, assertRedactedItemGroup, canonicalJson, contentHash, countWords, createDraft, defineActivityType, diffResponses, entryKeyOf, fillInTheBlanksType, fingerprint, flattenSequence, getActivityTypeDescriptor, gradeFromRubric, hasGrade, hashSeed, isItemGroup, multipleChoiceType, outcomeFromGrade, planAttempt, planMediaBudgets, redact, redactItemGroup, registerActivityType, registeredActivityTypes, resolvePlaybackPolicy, restoreAttemptState, restoreMediaPlayLedger, scoredItemsFromPlan, seededShuffle, serializeAttemptState, serializeMediaPlayLedger, slotMediaKey, stimulusMediaKey, validateDraft, verifyAttemptPlan, writtenResponseType };
|
package/dist/index.js
CHANGED
|
@@ -10,14 +10,14 @@ import {
|
|
|
10
10
|
outcomeFromGrade,
|
|
11
11
|
roundGrade,
|
|
12
12
|
score
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-QX7P3CHP.js";
|
|
14
14
|
import {
|
|
15
15
|
XAPIVerb,
|
|
16
16
|
XAPI_VERB_DISPLAY,
|
|
17
17
|
validateXAPIStatement,
|
|
18
18
|
xAPIBuilder,
|
|
19
19
|
xapiDefinitionFor
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-ELTP5P6V.js";
|
|
21
21
|
import {
|
|
22
22
|
ItemGroupSchema,
|
|
23
23
|
RedactedItemGroupSchema,
|
|
@@ -31,10 +31,11 @@ import {
|
|
|
31
31
|
validateActivity,
|
|
32
32
|
validateItemGroup,
|
|
33
33
|
writtenResponseJsonSchema
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-6DM2H6BD.js";
|
|
35
35
|
import {
|
|
36
36
|
ActivitySchemaError,
|
|
37
37
|
BlankConfigSchema,
|
|
38
|
+
DRAFT_ISSUE_SEVERITY,
|
|
38
39
|
DeferredScoringError,
|
|
39
40
|
FeedbackSchema,
|
|
40
41
|
FillInTheBlanksDataSchema,
|
|
@@ -61,13 +62,16 @@ import {
|
|
|
61
62
|
defineActivityType,
|
|
62
63
|
fillInTheBlanksType,
|
|
63
64
|
getActivityTypeDescriptor,
|
|
65
|
+
isRecord,
|
|
66
|
+
issue,
|
|
64
67
|
levenshteinDistance,
|
|
65
68
|
matchText,
|
|
66
69
|
multipleChoiceType,
|
|
70
|
+
refusesEmpty,
|
|
67
71
|
registerActivityType,
|
|
68
72
|
registeredActivityTypes,
|
|
69
73
|
writtenResponseType
|
|
70
|
-
} from "./chunk-
|
|
74
|
+
} from "./chunk-AHEUYOT3.js";
|
|
71
75
|
|
|
72
76
|
// src/content-hash.ts
|
|
73
77
|
function canonicalJson(value, seen = /* @__PURE__ */ new Set()) {
|
|
@@ -571,6 +575,92 @@ function diffResponses(before, after) {
|
|
|
571
575
|
return entries;
|
|
572
576
|
}
|
|
573
577
|
|
|
578
|
+
// src/authoring/index.ts
|
|
579
|
+
function validateDraft(type, draft) {
|
|
580
|
+
const descriptor = getActivityTypeDescriptor(type);
|
|
581
|
+
if (descriptor === void 0) {
|
|
582
|
+
throw new UnknownActivityTypeError(String(type));
|
|
583
|
+
}
|
|
584
|
+
const reported = isRecord(draft) && descriptor.authoring?.checkDraft !== void 0 ? descriptor.authoring.checkDraft(draft).map(normalise) : [];
|
|
585
|
+
const issues = [...reported];
|
|
586
|
+
const parsed = descriptor.schema.safeParse(draft, { reportInput: true });
|
|
587
|
+
if (!parsed.success) {
|
|
588
|
+
const reportedEmpty = /* @__PURE__ */ new Set();
|
|
589
|
+
for (const schemaIssue of parsed.error.issues) {
|
|
590
|
+
const path = schemaIssue.path.map(String);
|
|
591
|
+
if (reported.some((known) => covers(known.path, path))) {
|
|
592
|
+
continue;
|
|
593
|
+
}
|
|
594
|
+
if (path.length > 0 && refusesEmpty(draft, schemaIssue)) {
|
|
595
|
+
const key = JSON.stringify(path);
|
|
596
|
+
if (!reportedEmpty.has(key)) {
|
|
597
|
+
reportedEmpty.add(key);
|
|
598
|
+
issues.push(
|
|
599
|
+
issue(
|
|
600
|
+
"null_not_allowed",
|
|
601
|
+
path,
|
|
602
|
+
typeof schemaIssue.path.at(-1) === "number" ? "This entry has no value. Remove it, or fill it in." : "This field cannot be null. Leave it out if it is optional, or give it a value."
|
|
603
|
+
)
|
|
604
|
+
);
|
|
605
|
+
}
|
|
606
|
+
continue;
|
|
607
|
+
}
|
|
608
|
+
issues.push({
|
|
609
|
+
path,
|
|
610
|
+
message: schemaIssue.message,
|
|
611
|
+
code: schemaIssue.code,
|
|
612
|
+
severity: "invalid"
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
if (parsed.success && issues.length === 0) {
|
|
617
|
+
return { status: "complete", data: parsed.data, issues };
|
|
618
|
+
}
|
|
619
|
+
const invalid = issues.some((found) => found.severity !== "incomplete");
|
|
620
|
+
return { status: invalid ? "invalid" : "incomplete", issues };
|
|
621
|
+
}
|
|
622
|
+
function createDraft(type, context) {
|
|
623
|
+
const descriptor = getActivityTypeDescriptor(type);
|
|
624
|
+
if (descriptor === void 0) {
|
|
625
|
+
throw new UnknownActivityTypeError(String(type));
|
|
626
|
+
}
|
|
627
|
+
const create = descriptor.authoring?.createDraft;
|
|
628
|
+
if (create === void 0) {
|
|
629
|
+
throw new Error(
|
|
630
|
+
`Activity type "${String(type)}" declares no authoring.createDraft, so there is no empty draft to create. Build the draft yourself; validateDraft works for every registered type.`
|
|
631
|
+
);
|
|
632
|
+
}
|
|
633
|
+
const issued = /* @__PURE__ */ new Set();
|
|
634
|
+
const newId = () => {
|
|
635
|
+
const id = context.newId();
|
|
636
|
+
if (typeof id !== "string" || id === "") {
|
|
637
|
+
throw new Error("createDraft: newId() must return a non-empty string.");
|
|
638
|
+
}
|
|
639
|
+
if (issued.has(id)) {
|
|
640
|
+
throw new Error(
|
|
641
|
+
`createDraft: newId() returned "${id}" twice. Ids within one draft must differ \u2014 two options sharing an id cannot be scored apart.`
|
|
642
|
+
);
|
|
643
|
+
}
|
|
644
|
+
issued.add(id);
|
|
645
|
+
return id;
|
|
646
|
+
};
|
|
647
|
+
return create({ newId });
|
|
648
|
+
}
|
|
649
|
+
function normalise(found) {
|
|
650
|
+
const documented = Object.hasOwn(DRAFT_ISSUE_SEVERITY, found.code) ? DRAFT_ISSUE_SEVERITY[found.code] : void 0;
|
|
651
|
+
return {
|
|
652
|
+
...found,
|
|
653
|
+
path: found.path.map(String),
|
|
654
|
+
severity: documented ?? (found.severity === "incomplete" ? "incomplete" : "invalid")
|
|
655
|
+
};
|
|
656
|
+
}
|
|
657
|
+
function covers(reported, failed) {
|
|
658
|
+
if (failed.length === 0) {
|
|
659
|
+
return reported.length === 0;
|
|
660
|
+
}
|
|
661
|
+
return failed.every((segment, index) => reported[index] === segment);
|
|
662
|
+
}
|
|
663
|
+
|
|
574
664
|
// src/redact.ts
|
|
575
665
|
function mergePolicy(base, overrides) {
|
|
576
666
|
if (overrides === void 0) {
|
|
@@ -644,10 +734,10 @@ function redact(data, options = {}) {
|
|
|
644
734
|
if (!parsed.success) {
|
|
645
735
|
throw new ActivitySchemaError(
|
|
646
736
|
descriptor.type,
|
|
647
|
-
parsed.error.issues.map((
|
|
648
|
-
path:
|
|
649
|
-
message:
|
|
650
|
-
code:
|
|
737
|
+
parsed.error.issues.map((issue2) => ({
|
|
738
|
+
path: issue2.path.map(String),
|
|
739
|
+
message: issue2.message,
|
|
740
|
+
code: issue2.code
|
|
651
741
|
}))
|
|
652
742
|
);
|
|
653
743
|
}
|
|
@@ -688,10 +778,10 @@ function assertRedacted(data) {
|
|
|
688
778
|
if (!parsed.success) {
|
|
689
779
|
throw new ActivitySchemaError(
|
|
690
780
|
descriptor.type,
|
|
691
|
-
parsed.error.issues.map((
|
|
692
|
-
path:
|
|
693
|
-
message:
|
|
694
|
-
code:
|
|
781
|
+
parsed.error.issues.map((issue2) => ({
|
|
782
|
+
path: issue2.path.map(String),
|
|
783
|
+
message: issue2.message,
|
|
784
|
+
code: issue2.code
|
|
695
785
|
}))
|
|
696
786
|
);
|
|
697
787
|
}
|
|
@@ -732,10 +822,10 @@ function redactItemGroup(group, options = {}) {
|
|
|
732
822
|
if (!parsed.success) {
|
|
733
823
|
throw new ActivitySchemaError(
|
|
734
824
|
"item-group",
|
|
735
|
-
parsed.error.issues.map((
|
|
736
|
-
path:
|
|
737
|
-
message:
|
|
738
|
-
code:
|
|
825
|
+
parsed.error.issues.map((issue2) => ({
|
|
826
|
+
path: issue2.path.map(String),
|
|
827
|
+
message: issue2.message,
|
|
828
|
+
code: issue2.code
|
|
739
829
|
}))
|
|
740
830
|
);
|
|
741
831
|
}
|
|
@@ -762,10 +852,10 @@ function assertRedactedItemGroup(data) {
|
|
|
762
852
|
if (!parsed.success) {
|
|
763
853
|
throw new ActivitySchemaError(
|
|
764
854
|
"item-group",
|
|
765
|
-
parsed.error.issues.map((
|
|
766
|
-
path:
|
|
767
|
-
message:
|
|
768
|
-
code:
|
|
855
|
+
parsed.error.issues.map((issue2) => ({
|
|
856
|
+
path: issue2.path.map(String),
|
|
857
|
+
message: issue2.message,
|
|
858
|
+
code: issue2.code
|
|
769
859
|
}))
|
|
770
860
|
);
|
|
771
861
|
}
|
|
@@ -776,9 +866,9 @@ function assertRedactedItemGroup(data) {
|
|
|
776
866
|
if (error instanceof ActivitySchemaError) {
|
|
777
867
|
throw new ActivitySchemaError(
|
|
778
868
|
"item-group",
|
|
779
|
-
error.errors.map((
|
|
780
|
-
...
|
|
781
|
-
path: ["items", String(index), ...
|
|
869
|
+
error.errors.map((issue2) => ({
|
|
870
|
+
...issue2,
|
|
871
|
+
path: ["items", String(index), ...issue2.path]
|
|
782
872
|
}))
|
|
783
873
|
);
|
|
784
874
|
}
|
|
@@ -825,6 +915,7 @@ export {
|
|
|
825
915
|
computePassThreshold,
|
|
826
916
|
contentHash,
|
|
827
917
|
countWords,
|
|
918
|
+
createDraft,
|
|
828
919
|
defineActivityType,
|
|
829
920
|
diffResponses,
|
|
830
921
|
entryKeyOf,
|
|
@@ -865,6 +956,7 @@ export {
|
|
|
865
956
|
stimulusJsonSchema,
|
|
866
957
|
stimulusMediaKey,
|
|
867
958
|
validateActivity,
|
|
959
|
+
validateDraft,
|
|
868
960
|
validateItemGroup,
|
|
869
961
|
validateXAPIStatement,
|
|
870
962
|
verifyAttemptPlan,
|