@intellectif/lk-core 0.2.1 → 0.3.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.
Files changed (59) hide show
  1. package/dist/activity-zdcAMtFB.d.cts +626 -0
  2. package/dist/activity-zdcAMtFB.d.ts +626 -0
  3. package/dist/chunk-3YAVDV5F.js +47 -0
  4. package/dist/chunk-3YAVDV5F.js.map +1 -0
  5. package/dist/chunk-55O4M45K.js +57 -0
  6. package/dist/chunk-55O4M45K.js.map +1 -0
  7. package/dist/chunk-5GJJHGY5.js +576 -0
  8. package/dist/chunk-5GJJHGY5.js.map +1 -0
  9. package/dist/{chunk-ZHOX6TO4.js → chunk-HS7BYCGE.js} +65 -7
  10. package/dist/chunk-HS7BYCGE.js.map +1 -0
  11. package/dist/chunk-PIMX4B4D.cjs +47 -0
  12. package/dist/chunk-PIMX4B4D.cjs.map +1 -0
  13. package/dist/chunk-QOAORTA4.cjs +576 -0
  14. package/dist/chunk-QOAORTA4.cjs.map +1 -0
  15. package/dist/chunk-QSVBYTNM.js +94 -0
  16. package/dist/chunk-QSVBYTNM.js.map +1 -0
  17. package/dist/{chunk-PJFDAP54.cjs → chunk-RUGIOQZY.cjs} +66 -8
  18. package/dist/chunk-RUGIOQZY.cjs.map +1 -0
  19. package/dist/chunk-THSZMZND.cjs +94 -0
  20. package/dist/chunk-THSZMZND.cjs.map +1 -0
  21. package/dist/chunk-YNTYWHZI.cjs +57 -0
  22. package/dist/chunk-YNTYWHZI.cjs.map +1 -0
  23. package/dist/index.cjs +185 -6
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.cts +253 -7
  26. package/dist/index.d.ts +253 -7
  27. package/dist/index.js +188 -9
  28. package/dist/index.js.map +1 -1
  29. package/dist/schemas.cjs +29 -2
  30. package/dist/schemas.cjs.map +1 -1
  31. package/dist/schemas.d.cts +310 -29
  32. package/dist/schemas.d.ts +310 -29
  33. package/dist/schemas.js +32 -5
  34. package/dist/scoring.cjs +13 -3
  35. package/dist/scoring.cjs.map +1 -1
  36. package/dist/scoring.d.cts +29 -5
  37. package/dist/scoring.d.ts +29 -5
  38. package/dist/scoring.js +12 -2
  39. package/dist/xapi.cjs +3 -3
  40. package/dist/xapi.d.cts +40 -2
  41. package/dist/xapi.d.ts +40 -2
  42. package/dist/xapi.js +2 -2
  43. package/package.json +7 -2
  44. package/dist/activity-D5tqgx8A.d.cts +0 -330
  45. package/dist/activity-D5tqgx8A.d.ts +0 -330
  46. package/dist/chunk-2T3IL7VL.js +0 -147
  47. package/dist/chunk-2T3IL7VL.js.map +0 -1
  48. package/dist/chunk-3JMLUUFS.cjs +0 -124
  49. package/dist/chunk-3JMLUUFS.cjs.map +0 -1
  50. package/dist/chunk-6VOCV4EX.js +0 -25
  51. package/dist/chunk-6VOCV4EX.js.map +0 -1
  52. package/dist/chunk-DCDOTQNH.cjs +0 -147
  53. package/dist/chunk-DCDOTQNH.cjs.map +0 -1
  54. package/dist/chunk-DV466SBJ.cjs +0 -25
  55. package/dist/chunk-DV466SBJ.cjs.map +0 -1
  56. package/dist/chunk-GZ73G2TS.js +0 -124
  57. package/dist/chunk-GZ73G2TS.js.map +0 -1
  58. package/dist/chunk-PJFDAP54.cjs.map +0 -1
  59. package/dist/chunk-ZHOX6TO4.js.map +0 -1
@@ -0,0 +1,57 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+
5
+
6
+ var _chunkQOAORTA4cjs = require('./chunk-QOAORTA4.cjs');
7
+
8
+
9
+ var _chunkPIMX4B4Dcjs = require('./chunk-PIMX4B4D.cjs');
10
+
11
+ // src/schemas/json-schema.ts
12
+ var _v4 = require('zod/v4');
13
+ var multipleChoiceJsonSchema = _v4.z.toJSONSchema(_chunkQOAORTA4cjs.MultipleChoiceDataSchema, {
14
+ target: "draft-7"
15
+ });
16
+ var fillInTheBlanksJsonSchema = _v4.z.toJSONSchema(_chunkQOAORTA4cjs.FillInTheBlanksDataSchema, {
17
+ target: "draft-7"
18
+ });
19
+ var writtenResponseJsonSchema = _v4.z.toJSONSchema(_chunkQOAORTA4cjs.WrittenResponseDataSchema, {
20
+ target: "draft-7"
21
+ });
22
+ function jsonSchemaFor(type) {
23
+ const descriptor = _chunkQOAORTA4cjs.getActivityTypeDescriptor.call(void 0, type);
24
+ if (descriptor === void 0) {
25
+ throw new (0, _chunkPIMX4B4Dcjs.UnknownActivityTypeError)(type);
26
+ }
27
+ return _v4.z.toJSONSchema(descriptor.schema, { target: "draft-7" });
28
+ }
29
+
30
+ // src/schemas/index.ts
31
+ function validateActivity(type, data) {
32
+ const descriptor = _chunkQOAORTA4cjs.getActivityTypeDescriptor.call(void 0, type);
33
+ if (descriptor === void 0) {
34
+ throw new (0, _chunkPIMX4B4Dcjs.UnknownActivityTypeError)(String(type));
35
+ }
36
+ const result = descriptor.schema.safeParse(data);
37
+ if (result.success) {
38
+ return { success: true, data: result.data };
39
+ }
40
+ return {
41
+ success: false,
42
+ errors: result.error.issues.map((issue) => ({
43
+ path: issue.path.map(String),
44
+ message: issue.message,
45
+ code: issue.code
46
+ }))
47
+ };
48
+ }
49
+
50
+
51
+
52
+
53
+
54
+
55
+
56
+ exports.multipleChoiceJsonSchema = multipleChoiceJsonSchema; exports.fillInTheBlanksJsonSchema = fillInTheBlanksJsonSchema; exports.writtenResponseJsonSchema = writtenResponseJsonSchema; exports.jsonSchemaFor = jsonSchemaFor; exports.validateActivity = validateActivity;
57
+ //# sourceMappingURL=chunk-YNTYWHZI.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/learning-kit/learning-kit/packages/lk-core/dist/chunk-YNTYWHZI.cjs","../src/schemas/json-schema.ts","../src/schemas/index.ts"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACA;ACVA,4BAAkB;AAiBX,IAAM,yBAAA,EAA2B,KAAA,CAAE,YAAA,CAAa,0CAAA,EAA0B;AAAA,EAC/E,MAAA,EAAQ;AACV,CAAC,CAAA;AAOM,IAAM,0BAAA,EAA4B,KAAA,CAAE,YAAA,CAAa,2CAAA,EAA2B;AAAA,EACjF,MAAA,EAAQ;AACV,CAAC,CAAA;AAMM,IAAM,0BAAA,EAA4B,KAAA,CAAE,YAAA,CAAa,2CAAA,EAA2B;AAAA,EACjF,MAAA,EAAQ;AACV,CAAC,CAAA;AAUM,SAAS,aAAA,CAAc,IAAA,EAAuC;AACnE,EAAA,MAAM,WAAA,EAAa,yDAAA,IAA8B,CAAA;AACjD,EAAA,GAAA,CAAI,WAAA,IAAe,KAAA,CAAA,EAAW;AAC5B,IAAA,MAAM,IAAI,+CAAA,CAAyB,IAAI,CAAA;AAAA,EACzC;AACA,EAAA,OAAO,KAAA,CAAE,YAAA,CAAa,UAAA,CAAW,MAAA,EAAiB,EAAE,MAAA,EAAQ,UAAU,CAAC,CAAA;AAIzE;AD3BA;AACA;AEcO,SAAS,gBAAA,CACd,IAAA,EACA,IAAA,EACsC;AACtC,EAAA,MAAM,WAAA,EAAa,yDAAA,IAA8B,CAAA;AACjD,EAAA,GAAA,CAAI,WAAA,IAAe,KAAA,CAAA,EAAW;AAC5B,IAAA,MAAM,IAAI,+CAAA,CAAyB,MAAA,CAAO,IAAI,CAAC,CAAA;AAAA,EACjD;AAEA,EAAA,MAAM,OAAA,EAAS,UAAA,CAAW,MAAA,CAAO,SAAA,CAAU,IAAI,CAAA;AAE/C,EAAA,GAAA,CAAI,MAAA,CAAO,OAAA,EAAS;AAClB,IAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,IAAA,EAAM,MAAA,CAAO,KAA2B,CAAA;AAAA,EAClE;AAEA,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,KAAA;AAAA,IACT,MAAA,EAAQ,MAAA,CAAO,KAAA,CAAM,MAAA,CAAO,GAAA,CAAI,CAAC,KAAA,EAAA,GAAA,CAAW;AAAA,MAC1C,IAAA,EAAM,KAAA,CAAM,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA;AAAA,MAC3B,OAAA,EAAS,KAAA,CAAM,OAAA;AAAA,MACf,IAAA,EAAM,KAAA,CAAM;AAAA,IACd,CAAA,CAAE;AAAA,EACJ,CAAA;AACF;AFlBA;AACA;AACE;AACA;AACA;AACA;AACA;AACF,8QAAC","file":"/home/runner/work/learning-kit/learning-kit/packages/lk-core/dist/chunk-YNTYWHZI.cjs","sourcesContent":[null,"import { z } from 'zod/v4';\nimport { UnknownActivityTypeError } from '../errors.js';\nimport { getActivityTypeDescriptor } from '../registry/index.js';\nimport { FillInTheBlanksDataSchema } from './fill-in-the-blanks.js';\nimport { MultipleChoiceDataSchema } from './multiple-choice.js';\nimport { WrittenResponseDataSchema } from './written-response.js';\n\n/**\n * JSON Schema (Draft 7) representation of the Multiple Choice activity data\n * contract, generated natively by Zod 4. Draft 7 is mandated by Requirement\n * 2.2 for the widest AI-prompt / OpenAPI tooling compatibility. The semantic\n * `.refine()` guards are not representable in JSON Schema and are\n * intentionally omitted — the export captures the *structural* contract only.\n * Since v0.3 the source schemas are loose, so these no longer emit\n * `additionalProperties: false` — the JSON Schema and `validateActivity` now\n * agree on unknown-key handling.\n */\nexport const multipleChoiceJsonSchema = z.toJSONSchema(MultipleChoiceDataSchema, {\n target: 'draft-7',\n});\n\n/**\n * JSON Schema (Draft 7) representation of the Fill-in-the-Blanks activity data\n * contract, generated natively by Zod 4. Structural contract only (semantic\n * `.refine()` guards are Zod-only and not representable in JSON Schema).\n */\nexport const fillInTheBlanksJsonSchema = z.toJSONSchema(FillInTheBlanksDataSchema, {\n target: 'draft-7',\n});\n\n/**\n * JSON Schema (Draft 7) representation of the Written Response activity data\n * contract. Structural contract only.\n */\nexport const writtenResponseJsonSchema = z.toJSONSchema(WrittenResponseDataSchema, {\n target: 'draft-7',\n});\n\n/**\n * Derives the JSON Schema (Draft 7) for any REGISTERED activity type — the\n * live, registry-backed replacement for the static per-type exports above,\n * and the building block for AI generation pipelines (R6.1): pass the result\n * as a structured-output schema so a model can only emit valid items.\n *\n * @throws UnknownActivityTypeError when `type` has no registered descriptor.\n */\nexport function jsonSchemaFor(type: string): Record<string, unknown> {\n const descriptor = getActivityTypeDescriptor(type);\n if (descriptor === undefined) {\n throw new UnknownActivityTypeError(type);\n }\n return z.toJSONSchema(descriptor.schema as never, { target: 'draft-7' }) as Record<\n string,\n unknown\n >;\n}\n","import { UnknownActivityTypeError } from '../errors.js';\nimport { getActivityTypeDescriptor } from '../registry/index.js';\nimport type { ActivityDataMap, ActivityType, ValidationResult } from '../types/activity.js';\n\nexport { FeedbackSchema } from './feedback.js';\nexport {\n BlankConfigSchema,\n FillInTheBlanksDataSchema,\n TextMatchPolicySchema,\n} from './fill-in-the-blanks.js';\nexport {\n fillInTheBlanksJsonSchema,\n jsonSchemaFor,\n multipleChoiceJsonSchema,\n writtenResponseJsonSchema,\n} from './json-schema.js';\nexport { MediaSchema, MediaUrlSchema } from './media.js';\nexport { MultipleChoiceDataSchema, MultipleChoiceOptionSchema } from './multiple-choice.js';\nexport {\n RedactedBlankConfigSchema,\n RedactedFillInTheBlanksDataSchema,\n RedactedMultipleChoiceDataSchema,\n RedactedMultipleChoiceOptionSchema,\n RedactedWrittenResponseDataSchema,\n} from './redacted.js';\nexport {\n WrittenResponseDataSchema,\n WrittenResponseRubricCriterionSchema,\n WrittenResponseRubricSchema,\n} from './written-response.js';\n\n/**\n * Validates raw activity data against the schema registered for the given\n * activity type (built-in or consumer-registered via `registerActivityType`).\n *\n * Unknown keys are PRESERVED, not stripped: every built-in schema is loose,\n * so consumer sidecar fields and forward-version fields survive validation\n * verbatim in the returned `data`.\n *\n * @returns `{ success: true, data }` with the typed, validated data, or\n * `{ success: false, errors }` with one entry per failed constraint.\n * @throws UnknownActivityTypeError when `type` has no registered descriptor.\n */\nexport function validateActivity<T extends ActivityType>(\n type: T,\n data: unknown,\n): ValidationResult<ActivityDataMap[T]> {\n const descriptor = getActivityTypeDescriptor(type);\n if (descriptor === undefined) {\n throw new UnknownActivityTypeError(String(type));\n }\n\n const result = descriptor.schema.safeParse(data);\n\n if (result.success) {\n return { success: true, data: result.data as ActivityDataMap[T] };\n }\n\n return {\n success: false,\n errors: result.error.issues.map((issue) => ({\n path: issue.path.map(String),\n message: issue.message,\n code: issue.code,\n })),\n };\n}\n"]}
package/dist/index.cjs CHANGED
@@ -1,28 +1,27 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }
2
2
 
3
3
 
4
- var _chunk3JMLUUFScjs = require('./chunk-3JMLUUFS.cjs');
5
4
 
6
5
 
6
+ var _chunkTHSZMZNDcjs = require('./chunk-THSZMZND.cjs');
7
7
 
8
8
 
9
9
 
10
- var _chunkPJFDAP54cjs = require('./chunk-PJFDAP54.cjs');
11
10
 
12
11
 
12
+ var _chunkRUGIOQZYcjs = require('./chunk-RUGIOQZY.cjs');
13
13
 
14
- var _chunkDV466SBJcjs = require('./chunk-DV466SBJ.cjs');
15
14
 
16
15
 
17
16
 
18
17
 
19
18
 
19
+ var _chunkYNTYWHZIcjs = require('./chunk-YNTYWHZI.cjs');
20
20
 
21
21
 
22
22
 
23
23
 
24
24
 
25
- var _chunkDCDOTQNHcjs = require('./chunk-DCDOTQNH.cjs');
26
25
 
27
26
 
28
27
 
@@ -41,5 +40,185 @@ var _chunkDCDOTQNHcjs = require('./chunk-DCDOTQNH.cjs');
41
40
 
42
41
 
43
42
 
44
- exports.ActivitySchemaError = _chunkDV466SBJcjs.ActivitySchemaError; exports.BlankConfigSchema = _chunkDCDOTQNHcjs.BlankConfigSchema; exports.FeedbackSchema = _chunkDCDOTQNHcjs.FeedbackSchema; exports.FillInTheBlanksDataSchema = _chunkDCDOTQNHcjs.FillInTheBlanksDataSchema; exports.MediaSchema = _chunkDCDOTQNHcjs.MediaSchema; exports.MultipleChoiceDataSchema = _chunkDCDOTQNHcjs.MultipleChoiceDataSchema; exports.MultipleChoiceOptionSchema = _chunkDCDOTQNHcjs.MultipleChoiceOptionSchema; exports.UnknownActivityTypeError = _chunkDV466SBJcjs.UnknownActivityTypeError; exports.XAPIVerb = _chunkPJFDAP54cjs.XAPIVerb; exports.XAPI_VERB_DISPLAY = _chunkPJFDAP54cjs.XAPI_VERB_DISPLAY; exports.computePassThreshold = _chunk3JMLUUFScjs.computePassThreshold; exports.fillInTheBlanksJsonSchema = _chunkDCDOTQNHcjs.fillInTheBlanksJsonSchema; exports.multipleChoiceJsonSchema = _chunkDCDOTQNHcjs.multipleChoiceJsonSchema; exports.score = _chunk3JMLUUFScjs.score; exports.validateActivity = _chunkDCDOTQNHcjs.validateActivity; exports.validateXAPIStatement = _chunkPJFDAP54cjs.validateXAPIStatement; exports.xAPIBuilder = _chunkPJFDAP54cjs.xAPIBuilder;
43
+
44
+
45
+
46
+
47
+ var _chunkQOAORTA4cjs = require('./chunk-QOAORTA4.cjs');
48
+
49
+
50
+
51
+
52
+
53
+ var _chunkPIMX4B4Dcjs = require('./chunk-PIMX4B4D.cjs');
54
+
55
+ // src/redact.ts
56
+ function mergePolicy(base, overrides) {
57
+ if (overrides === void 0) {
58
+ return base;
59
+ }
60
+ const merged = { ...base };
61
+ for (const [key, override] of Object.entries(overrides)) {
62
+ const current = merged[key];
63
+ merged[key] = typeof override === "object" && typeof current === "object" ? { ...current, ...override } : override;
64
+ }
65
+ return merged;
66
+ }
67
+ function isSensitivity(value) {
68
+ return typeof value === "string";
69
+ }
70
+ function keepField(sensitivity, reveal) {
71
+ if (sensitivity === "public") {
72
+ return true;
73
+ }
74
+ return sensitivity === "answer-key" && reveal === "after-submit";
75
+ }
76
+ function redactValue(value, policy, reveal) {
77
+ if (Array.isArray(value)) {
78
+ return value.map((element) => redactValue(element, policy, reveal));
79
+ }
80
+ if (value === null || typeof value !== "object") {
81
+ return void 0;
82
+ }
83
+ const source = value;
84
+ const output = {};
85
+ for (const [key, fieldValue] of Object.entries(source)) {
86
+ if (fieldValue === void 0) {
87
+ continue;
88
+ }
89
+ const classification = policy[key];
90
+ if (classification === void 0) {
91
+ continue;
92
+ }
93
+ if (isSensitivity(classification)) {
94
+ if (keepField(classification, reveal)) {
95
+ output[key] = fieldValue;
96
+ }
97
+ continue;
98
+ }
99
+ const nested = redactValue(fieldValue, classification, reveal);
100
+ if (nested !== void 0) {
101
+ output[key] = nested;
102
+ }
103
+ }
104
+ return output;
105
+ }
106
+ function redact(data, options = {}) {
107
+ const reveal = _nullishCoalesce(options.reveal, () => ( "none"));
108
+ const descriptor = _chunkQOAORTA4cjs.getActivityTypeDescriptor.call(void 0, data.type);
109
+ if (descriptor === void 0) {
110
+ throw new (0, _chunkPIMX4B4Dcjs.UnknownActivityTypeError)(String(data.type));
111
+ }
112
+ if (descriptor.fieldPolicy === void 0) {
113
+ throw new Error(
114
+ `Activity type "${descriptor.type}" has no fieldPolicy; redact() cannot run fail-closed redaction without one.`
115
+ );
116
+ }
117
+ const effectivePolicy = mergePolicy(descriptor.fieldPolicy, options.policy);
118
+ const projected = redactValue(data, effectivePolicy, reveal);
119
+ const result = { ...projected, redacted: true };
120
+ if (reveal === "none" && descriptor.redactedSchema !== void 0) {
121
+ const parsed = descriptor.redactedSchema.safeParse(result);
122
+ if (!parsed.success) {
123
+ throw new (0, _chunkPIMX4B4Dcjs.ActivitySchemaError)(
124
+ descriptor.type,
125
+ parsed.error.issues.map((issue) => ({
126
+ path: issue.path.map(String),
127
+ message: issue.message,
128
+ code: issue.code
129
+ }))
130
+ );
131
+ }
132
+ }
133
+ return result;
134
+ }
135
+ function assertRedacted(data) {
136
+ if (typeof data !== "object" || data === null) {
137
+ throw new (0, _chunkPIMX4B4Dcjs.ActivitySchemaError)("unknown", [
138
+ { path: [], message: "Redacted activity data must be an object.", code: "invalid_type" }
139
+ ]);
140
+ }
141
+ const candidate = data;
142
+ if (candidate.redacted !== true) {
143
+ throw new (0, _chunkPIMX4B4Dcjs.ActivitySchemaError)(String(_nullishCoalesce(candidate.type, () => ( "unknown"))), [
144
+ {
145
+ path: ["redacted"],
146
+ message: "Missing redacted marker \u2014 this payload is not a redact() projection.",
147
+ code: "custom"
148
+ }
149
+ ]);
150
+ }
151
+ const type = typeof candidate.type === "string" ? candidate.type : "";
152
+ const descriptor = _chunkQOAORTA4cjs.getActivityTypeDescriptor.call(void 0, type);
153
+ if (descriptor === void 0) {
154
+ throw new (0, _chunkPIMX4B4Dcjs.UnknownActivityTypeError)(type);
155
+ }
156
+ if (descriptor.redactedSchema === void 0) {
157
+ throw new (0, _chunkPIMX4B4Dcjs.ActivitySchemaError)(descriptor.type, [
158
+ {
159
+ path: [],
160
+ message: `Activity type "${descriptor.type}" registers no redactedSchema; assertRedacted cannot prove this payload is learner-safe.`,
161
+ code: "custom"
162
+ }
163
+ ]);
164
+ }
165
+ const parsed = descriptor.redactedSchema.safeParse(candidate);
166
+ if (!parsed.success) {
167
+ throw new (0, _chunkPIMX4B4Dcjs.ActivitySchemaError)(
168
+ descriptor.type,
169
+ parsed.error.issues.map((issue) => ({
170
+ path: issue.path.map(String),
171
+ message: issue.message,
172
+ code: issue.code
173
+ }))
174
+ );
175
+ }
176
+ }
177
+
178
+
179
+
180
+
181
+
182
+
183
+
184
+
185
+
186
+
187
+
188
+
189
+
190
+
191
+
192
+
193
+
194
+
195
+
196
+
197
+
198
+
199
+
200
+
201
+
202
+
203
+
204
+
205
+
206
+
207
+
208
+
209
+
210
+
211
+
212
+
213
+
214
+
215
+
216
+
217
+
218
+
219
+
220
+
221
+
222
+
223
+ exports.ActivitySchemaError = _chunkPIMX4B4Dcjs.ActivitySchemaError; exports.BlankConfigSchema = _chunkQOAORTA4cjs.BlankConfigSchema; exports.DEFAULT_PASS_THRESHOLD = _chunkTHSZMZNDcjs.DEFAULT_PASS_THRESHOLD; exports.DeferredScoringError = _chunkPIMX4B4Dcjs.DeferredScoringError; exports.FeedbackSchema = _chunkQOAORTA4cjs.FeedbackSchema; exports.FillInTheBlanksDataSchema = _chunkQOAORTA4cjs.FillInTheBlanksDataSchema; exports.MediaSchema = _chunkQOAORTA4cjs.MediaSchema; exports.MediaUrlSchema = _chunkQOAORTA4cjs.MediaUrlSchema; exports.MultipleChoiceDataSchema = _chunkQOAORTA4cjs.MultipleChoiceDataSchema; exports.MultipleChoiceOptionSchema = _chunkQOAORTA4cjs.MultipleChoiceOptionSchema; exports.RedactedBlankConfigSchema = _chunkQOAORTA4cjs.RedactedBlankConfigSchema; exports.RedactedFillInTheBlanksDataSchema = _chunkQOAORTA4cjs.RedactedFillInTheBlanksDataSchema; exports.RedactedMultipleChoiceDataSchema = _chunkQOAORTA4cjs.RedactedMultipleChoiceDataSchema; exports.RedactedMultipleChoiceOptionSchema = _chunkQOAORTA4cjs.RedactedMultipleChoiceOptionSchema; exports.RedactedScoringError = _chunkPIMX4B4Dcjs.RedactedScoringError; exports.RedactedWrittenResponseDataSchema = _chunkQOAORTA4cjs.RedactedWrittenResponseDataSchema; exports.TextMatchPolicySchema = _chunkQOAORTA4cjs.TextMatchPolicySchema; exports.UnknownActivityTypeError = _chunkPIMX4B4Dcjs.UnknownActivityTypeError; exports.WrittenResponseDataSchema = _chunkQOAORTA4cjs.WrittenResponseDataSchema; exports.WrittenResponseRubricCriterionSchema = _chunkQOAORTA4cjs.WrittenResponseRubricCriterionSchema; exports.WrittenResponseRubricSchema = _chunkQOAORTA4cjs.WrittenResponseRubricSchema; exports.XAPIVerb = _chunkRUGIOQZYcjs.XAPIVerb; exports.XAPI_VERB_DISPLAY = _chunkRUGIOQZYcjs.XAPI_VERB_DISPLAY; exports.assertRedacted = assertRedacted; exports.computePassThreshold = _chunkTHSZMZNDcjs.computePassThreshold; exports.countWords = _chunkQOAORTA4cjs.countWords; exports.defineActivityType = _chunkQOAORTA4cjs.defineActivityType; exports.evaluate = _chunkTHSZMZNDcjs.evaluate; exports.fillInTheBlanksJsonSchema = _chunkYNTYWHZIcjs.fillInTheBlanksJsonSchema; exports.fillInTheBlanksType = _chunkQOAORTA4cjs.fillInTheBlanksType; exports.getActivityTypeDescriptor = _chunkQOAORTA4cjs.getActivityTypeDescriptor; exports.jsonSchemaFor = _chunkYNTYWHZIcjs.jsonSchemaFor; exports.levenshteinDistance = _chunkQOAORTA4cjs.levenshteinDistance; exports.matchText = _chunkQOAORTA4cjs.matchText; exports.multipleChoiceJsonSchema = _chunkYNTYWHZIcjs.multipleChoiceJsonSchema; exports.multipleChoiceType = _chunkQOAORTA4cjs.multipleChoiceType; exports.redact = redact; exports.registerActivityType = _chunkQOAORTA4cjs.registerActivityType; exports.registeredActivityTypes = _chunkQOAORTA4cjs.registeredActivityTypes; exports.score = _chunkTHSZMZNDcjs.score; exports.validateActivity = _chunkYNTYWHZIcjs.validateActivity; exports.validateXAPIStatement = _chunkRUGIOQZYcjs.validateXAPIStatement; exports.writtenResponseJsonSchema = _chunkYNTYWHZIcjs.writtenResponseJsonSchema; exports.writtenResponseType = _chunkQOAORTA4cjs.writtenResponseType; exports.xAPIBuilder = _chunkRUGIOQZYcjs.xAPIBuilder;
45
224
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/learning-kit/learning-kit/packages/lk-core/dist/index.cjs"],"names":[],"mappings":"AAAA;AACE;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,onCAAC","file":"/home/runner/work/learning-kit/learning-kit/packages/lk-core/dist/index.cjs"}
1
+ {"version":3,"sources":["/home/runner/work/learning-kit/learning-kit/packages/lk-core/dist/index.cjs","../src/redact.ts"],"names":[],"mappings":"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","file":"/home/runner/work/learning-kit/learning-kit/packages/lk-core/dist/index.cjs","sourcesContent":[null,"import { ActivitySchemaError, UnknownActivityTypeError } from './errors.js';\nimport { getActivityTypeDescriptor } from './registry/index.js';\nimport type { FieldPolicy, Sensitivity } from './registry/registry.js';\n\n/**\n * A learner-safe projection of activity data produced by {@link redact}:\n * the activity's public fields plus the `redacted: true` marker. Renderable\n * and validatable (each built-in type registers a strict redacted schema),\n * but stripped of the answer key, scoring rules, authored feedback, and\n * author-only assets.\n */\nexport interface RedactedActivityData {\n redacted: true;\n schemaVersion: string;\n type: string;\n id: string;\n title: string;\n [key: string]: unknown;\n}\n\n/** Options for {@link redact}. */\nexport interface RedactOptions {\n /**\n * Which sensitivity tiers to keep beyond `public`:\n * - `'none'` (default) — public fields only; the output satisfies the\n * type's strict redacted schema and `assertRedacted`.\n * - `'after-submit'` — public + answer-key fields (for post-submission\n * review renders). `author-only` fields and unclassified fields are\n * STILL removed; the output will NOT pass `assertRedacted`.\n */\n reveal?: 'none' | 'after-submit';\n /**\n * Per-call sensitivity overrides, merged over the type's registered\n * `fieldPolicy` (top-level keys replace; nested objects merge one level).\n *\n * Sensitivity is partly a PEDAGOGICAL decision, not purely a security one —\n * whether a rubric or a hint is learner-visible differs legitimately between\n * deployments — and the SDK must not freeze that choice. Use this to tighten\n * a field the SDK ships as `public`:\n *\n * ```ts\n * redact(essay, { policy: { rubric: 'author-only' } });\n * ```\n *\n * Overrides can only be applied to fields; they cannot re-open a field the\n * caller has not classified, because unclassified still means removed.\n * Note that tightening below what the type's `redactedSchema` requires is\n * allowed — the schema check only rejects payloads that reveal MORE than\n * the learner-safe shape.\n */\n policy?: FieldPolicy;\n}\n\n/** Merges per-call overrides over a registered policy, one level deep. */\nfunction mergePolicy(base: FieldPolicy, overrides: FieldPolicy | undefined): FieldPolicy {\n if (overrides === undefined) {\n return base;\n }\n const merged: Record<string, Sensitivity | FieldPolicy> = { ...base };\n for (const [key, override] of Object.entries(overrides)) {\n const current = merged[key];\n merged[key] =\n typeof override === 'object' && typeof current === 'object'\n ? { ...current, ...override }\n : override;\n }\n return merged;\n}\n\nfunction isSensitivity(value: Sensitivity | FieldPolicy): value is Sensitivity {\n return typeof value === 'string';\n}\n\nfunction keepField(sensitivity: Sensitivity, reveal: 'none' | 'after-submit'): boolean {\n if (sensitivity === 'public') {\n return true;\n }\n return sensitivity === 'answer-key' && reveal === 'after-submit';\n}\n\nfunction redactValue(\n value: unknown,\n policy: FieldPolicy,\n reveal: 'none' | 'after-submit',\n): unknown {\n if (Array.isArray(value)) {\n return value.map((element) => redactValue(element, policy, reveal));\n }\n if (value === null || typeof value !== 'object') {\n // A nested FieldPolicy cannot classify a primitive's sub-fields; the\n // policy author classified an object shape that is not there. Fail\n // closed: drop it (handled by the caller returning undefined).\n return undefined;\n }\n\n const source = value as Record<string, unknown>;\n const output: Record<string, unknown> = {};\n for (const [key, fieldValue] of Object.entries(source)) {\n if (fieldValue === undefined) {\n continue;\n }\n const classification = policy[key];\n if (classification === undefined) {\n // Fail closed: unclassified fields are never emitted, at any reveal\n // level. Adding a field without classifying it hides it — never leaks it.\n continue;\n }\n if (isSensitivity(classification)) {\n if (keepField(classification, reveal)) {\n output[key] = fieldValue;\n }\n continue;\n }\n const nested = redactValue(fieldValue, classification, reveal);\n if (nested !== undefined) {\n output[key] = nested;\n }\n }\n return output;\n}\n\n/**\n * Produces the learner-safe projection of activity data (R7), driven by the\n * `fieldPolicy` registered for `data.type`. Fail-closed and exhaustive by\n * construction: a field the policy does not classify is removed — including\n * unknown passthrough fields — so a NEW field added by a future SDK or a\n * consumer sidecar can never leak through an out-of-date redactor.\n *\n * With the default `reveal: 'none'`, the output validates against the type's\n * strict redacted schema (verified here; an invalid projection throws\n * {@link ActivitySchemaError} rather than shipping an unproven payload).\n *\n * @throws UnknownActivityTypeError when `data.type` is not registered.\n * @throws Error when the registered descriptor declares no `fieldPolicy`\n * (redaction cannot guess sensitivities).\n */\nexport function redact<T extends { type: string }>(\n data: T,\n options: RedactOptions = {},\n): RedactedActivityData {\n const reveal = options.reveal ?? 'none';\n const descriptor = getActivityTypeDescriptor(data.type);\n if (descriptor === undefined) {\n throw new UnknownActivityTypeError(String(data.type));\n }\n if (descriptor.fieldPolicy === undefined) {\n throw new Error(\n `Activity type \"${descriptor.type}\" has no fieldPolicy; redact() cannot run fail-closed redaction without one.`,\n );\n }\n\n const effectivePolicy = mergePolicy(descriptor.fieldPolicy, options.policy);\n const projected = redactValue(data, effectivePolicy, reveal) as Record<string, unknown>;\n const result = { ...projected, redacted: true as const } as RedactedActivityData;\n\n if (reveal === 'none' && descriptor.redactedSchema !== undefined) {\n const parsed = descriptor.redactedSchema.safeParse(result);\n if (!parsed.success) {\n throw new ActivitySchemaError(\n descriptor.type,\n parsed.error.issues.map((issue) => ({\n path: issue.path.map(String),\n message: issue.message,\n code: issue.code,\n })),\n );\n }\n }\n\n return result;\n}\n\n/**\n * Asserts that `data` is a learner-safe redacted projection: it carries the\n * `redacted: true` marker and, when its type registers a strict redacted\n * schema, validates against it (proving the absence of answer-key fields).\n * Use this at the server boundary before sending activity data to a client\n * that must not hold the key.\n */\nexport function assertRedacted(data: unknown): asserts data is RedactedActivityData {\n if (typeof data !== 'object' || data === null) {\n throw new ActivitySchemaError('unknown', [\n { path: [], message: 'Redacted activity data must be an object.', code: 'invalid_type' },\n ]);\n }\n const candidate = data as Record<string, unknown>;\n if (candidate.redacted !== true) {\n throw new ActivitySchemaError(String(candidate.type ?? 'unknown'), [\n {\n path: ['redacted'],\n message: 'Missing redacted marker — this payload is not a redact() projection.',\n code: 'custom',\n },\n ]);\n }\n const type = typeof candidate.type === 'string' ? candidate.type : '';\n const descriptor = getActivityTypeDescriptor(type);\n if (descriptor === undefined) {\n throw new UnknownActivityTypeError(type);\n }\n if (descriptor.redactedSchema === undefined) {\n // Fail closed: without a registered redacted schema there is no way to\n // PROVE the absence of answer-key fields, and a marker alone proves\n // nothing (any object can carry `redacted: true`).\n throw new ActivitySchemaError(descriptor.type, [\n {\n path: [],\n message: `Activity type \"${descriptor.type}\" registers no redactedSchema; assertRedacted cannot prove this payload is learner-safe.`,\n code: 'custom',\n },\n ]);\n }\n const parsed = descriptor.redactedSchema.safeParse(candidate);\n if (!parsed.success) {\n throw new ActivitySchemaError(\n descriptor.type,\n parsed.error.issues.map((issue) => ({\n path: issue.path.map(String),\n message: issue.message,\n code: issue.code,\n })),\n );\n }\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -1,9 +1,18 @@
1
- import { V as ValidationError } from './activity-D5tqgx8A.cjs';
2
- export { A as ActivityData, a as ActivityDataMap, b as ActivityFeedback, c as ActivityMedia, d as ActivityResult, e as ActivityType, B as BlankConfig, F as FillInTheBlanksData, f as FillInTheBlanksLearnerResponse, I as InteractionEvent, L as LearnerResponse, M as MultipleChoiceData, g as MultipleChoiceLearnerResponse, h as MultipleChoiceOption, S as ScoringDetail, i as ScoringResult, j as ValidationResult, X as XAPIActor, k as XAPIConfig, l as XAPIContext, m as XAPIError, n as XAPIObject, o as XAPIResult, p as XAPIScore, q as XAPIStatement, r as XAPIVerbObject } from './activity-D5tqgx8A.cjs';
3
- export { BlankConfigSchema, FeedbackSchema, FillInTheBlanksDataSchema, MediaSchema, MultipleChoiceDataSchema, MultipleChoiceOptionSchema, fillInTheBlanksJsonSchema, multipleChoiceJsonSchema, validateActivity } from './schemas.cjs';
4
- export { computePassThreshold, score } from './scoring.cjs';
5
- export { AnsweredStatementParams, CompletedStatementParams, XAPIObjectParams, XAPIStatementParams, XAPIVerb, XAPIVerbKey, XAPI_VERB_DISPLAY, validateXAPIStatement, xAPIBuilder } from './xapi.cjs';
6
- import 'zod/v4';
1
+ import { V as ValidationError, m as ScoringResult, D as DeferredScoringPartial, F as FillInTheBlanksData, f as FillInTheBlanksLearnerResponse, M as MultipleChoiceData, j as MultipleChoiceLearnerResponse, W as WrittenResponseData, p as WrittenResponseLearnerResponse } from './activity-zdcAMtFB.cjs';
2
+ export { A as ActivityData, a as ActivityDataMap, b as ActivityFeedback, c as ActivityMedia, d as ActivityResult, e as ActivityType, B as BlankConfig, I as InteractionEvent, g as InteractionKind, h as ItemOutcome, L as LearnerResponse, i as LearnerResponseMap, k as MultipleChoiceOption, S as ScoringDetail, l as ScoringOutcome, T as TextMatchPolicy, n as TextMatchResult, o as ValidationResult, q as WrittenResponseRubric, r as WrittenResponseRubricCriterion, X as XAPIActor, s as XAPIConfig, t as XAPIContext, u as XAPIContextActivities, v as XAPIError, w as XAPIObject, x as XAPIResult, y as XAPIScore, z as XAPIStatement, C as XAPIVerbObject, E as levenshteinDistance, G as matchText } from './activity-zdcAMtFB.cjs';
3
+ import { z } from 'zod/v4';
4
+ export { BlankConfigSchema, FeedbackSchema, FillInTheBlanksDataSchema, MediaSchema, MediaUrlSchema, MultipleChoiceDataSchema, MultipleChoiceOptionSchema, RedactedBlankConfigSchema, RedactedFillInTheBlanksDataSchema, RedactedMultipleChoiceDataSchema, RedactedMultipleChoiceOptionSchema, RedactedWrittenResponseDataSchema, TextMatchPolicySchema, WrittenResponseDataSchema, WrittenResponseRubricCriterionSchema, WrittenResponseRubricSchema, fillInTheBlanksJsonSchema, jsonSchemaFor, multipleChoiceJsonSchema, validateActivity, writtenResponseJsonSchema } from './schemas.cjs';
5
+ export { DEFAULT_PASS_THRESHOLD, computePassThreshold, evaluate, score } from './scoring.cjs';
6
+ export { AnsweredStatementParams, CompletedStatementParams, SubmittedStatementParams, XAPIObjectParams, XAPIStatementParams, XAPIVerb, XAPIVerbKey, XAPI_VERB_DISPLAY, validateXAPIStatement, xAPIBuilder } from './xapi.cjs';
7
+
8
+ /**
9
+ * Canonical word counter for written-response bounds (Req 22.9): tokens are
10
+ * maximal runs of non-whitespace (split on `\s+`), so hyphenated forms
11
+ * (`well-known`) count as one word. The empty / whitespace-only string counts
12
+ * 0. Consumers must use this helper rather than re-implementing the split so
13
+ * client previews, SDK scoring, and stored `wordCount` values always agree.
14
+ */
15
+ declare function countWords(text: string): number;
7
16
 
8
17
  /** Thrown when activity data fails schema validation at a component boundary. */
9
18
  declare class ActivitySchemaError extends Error {
@@ -16,6 +25,243 @@ declare class UnknownActivityTypeError extends Error {
16
25
  readonly activityType: string;
17
26
  constructor(activityType: string);
18
27
  }
28
+ /**
29
+ * Thrown when `score()` is asked to grade a `redact()` projection (or any
30
+ * activity data whose answer key is missing, yielding a non-finite score).
31
+ * Redacted data is learner-safe precisely because the key was removed, so a
32
+ * score derived from it is meaningless — previously this produced a silent
33
+ * `NaN` that serialized to `null` in a grade column. `evaluate()` returns
34
+ * `{ status: 'unscorable' }` for the same input instead of throwing.
35
+ */
36
+ declare class RedactedScoringError extends Error {
37
+ readonly activityType: string;
38
+ constructor(activityType: string);
39
+ }
40
+ /**
41
+ * Thrown when `score()` is called for an activity type whose grading is
42
+ * deferred (asynchronous AI/human grading, e.g. `written-response`). A
43
+ * deferred submission has no synchronous score — treating it as 0 would show
44
+ * a learner a failing grade for work that simply has not been graded yet.
45
+ * Call `evaluate()` instead, which returns `{ status: 'deferred', ... }`.
46
+ */
47
+ declare class DeferredScoringError extends Error {
48
+ readonly activityType: string;
49
+ constructor(activityType: string);
50
+ }
51
+
52
+ /** ScoringResult without `passed` — the public `score()` / `evaluate()` fill that in. */
53
+ type PartialScoringResult = Omit<ScoringResult, 'passed'>;
54
+ /**
55
+ * Sensitivity classification of a single activity-data field, driving
56
+ * `redact()`:
57
+ * - `public` — safe to send to a learner before they answer.
58
+ * - `answer-key` — reveals (or helps infer) the correct answer or the scoring
59
+ * rules; removed unless `reveal: 'after-submit'` is requested.
60
+ * - `author-only` — never leaves the authoring/grading context (e.g. rubrics).
61
+ */
62
+ type Sensitivity = 'public' | 'answer-key' | 'author-only';
63
+ /**
64
+ * Per-field sensitivity map for an activity type. A `Sensitivity` value
65
+ * classifies the whole field (objects and arrays included); a nested
66
+ * `FieldPolicy` recurses into an object field — and, for an array field,
67
+ * applies to every element. Fail-closed: any field a policy does not mention
68
+ * is treated as `author-only` and removed by `redact()` — adding a field
69
+ * without classifying it hides it, never leaks it.
70
+ */
71
+ interface FieldPolicy {
72
+ readonly [field: string]: Sensitivity | FieldPolicy;
73
+ }
74
+ /** xAPI interaction types defined by xAPI 1.0.3 (cmi.interaction vocabulary). */
75
+ type XAPIInteractionType = 'choice' | 'fill-in' | 'long-fill-in' | 'matching' | 'sequencing' | 'performance' | 'true-false' | 'other';
76
+ /** Interop facts a generic statement builder cannot infer from data alone. */
77
+ interface ActivityTypeInterop<TData> {
78
+ /** IRI for the xAPI Activity `definition.type`. */
79
+ readonly xapiActivityTypeIri?: string;
80
+ /** xAPI `definition.interactionType` for this activity type. */
81
+ readonly xapiInteractionType?: XAPIInteractionType;
82
+ /** Builds the xAPI `correctResponsesPattern` strings for an item. */
83
+ readonly correctResponsesPattern?: (data: TData) => string[];
84
+ }
85
+ /**
86
+ * How responses to an activity type are graded:
87
+ * - `sync` — a pure function produces the grade at submit time.
88
+ * - `deferred` — grading happens asynchronously (AI or human) after
89
+ * submission; `partial` reports the facts computable synchronously
90
+ * (e.g. word counts), surfaced in `ItemOutcome.partial`.
91
+ */
92
+ type ActivityTypeScoring<TData, TResponse> = {
93
+ readonly kind: 'sync';
94
+ readonly score: (data: TData, response: TResponse) => PartialScoringResult;
95
+ } | {
96
+ readonly kind: 'deferred';
97
+ readonly reason: 'requires_async_grading';
98
+ readonly partial?: (data: TData, response: TResponse | undefined) => DeferredScoringPartial;
99
+ };
100
+ /**
101
+ * A value-level description of an activity type: its contract (schema), its
102
+ * grading, its redaction policy, and its interop facts. Registering a
103
+ * descriptor makes `validateActivity`, `score`, `evaluate`, `redact`, and
104
+ * `jsonSchemaFor` work for the type — an activity type is a value, not a
105
+ * hardcoded union member (R1).
106
+ */
107
+ interface ActivityTypeDescriptor<TData extends {
108
+ type: string;
109
+ }, TResponse> {
110
+ /** The `type` discriminator string (kebab-case by convention). */
111
+ readonly type: TData['type'];
112
+ /** Zod schema validating the activity's data contract. */
113
+ readonly schema: z.ZodType<TData>;
114
+ /** How responses are graded. */
115
+ readonly scoring: ActivityTypeScoring<TData, TResponse>;
116
+ /** Whether a response counts as an answer (vs. blank/untouched). */
117
+ readonly isAnswered?: (response: TResponse | undefined) => boolean;
118
+ /** Per-field sensitivity map driving `redact()`. Fail-closed. */
119
+ readonly fieldPolicy?: FieldPolicy;
120
+ /**
121
+ * Schema the output of `redact(data)` (with default `reveal: 'none'`) must
122
+ * satisfy. Strict by design: it proves the ABSENCE of answer-key fields,
123
+ * so `assertRedacted` can guarantee a payload is safe to send to a learner.
124
+ */
125
+ readonly redactedSchema?: z.ZodType<unknown>;
126
+ /** Interop facts for xAPI (and later QTI) statement building. */
127
+ readonly interop?: ActivityTypeInterop<TData>;
128
+ /** The interaction-event kinds components for this type emit. */
129
+ readonly interactions?: readonly string[];
130
+ }
131
+ /**
132
+ * Internal type-erased descriptor shape stored in the registry. Dispatch call
133
+ * sites cast payloads back; the public generic API preserves inference.
134
+ */
135
+ interface RegisteredActivityTypeDescriptor {
136
+ readonly type: string;
137
+ readonly schema: z.ZodType<unknown>;
138
+ readonly scoring: {
139
+ readonly kind: 'sync';
140
+ readonly score: (data: unknown, response: unknown) => PartialScoringResult;
141
+ } | {
142
+ readonly kind: 'deferred';
143
+ readonly reason: 'requires_async_grading';
144
+ readonly partial?: (data: unknown, response: unknown) => DeferredScoringPartial;
145
+ };
146
+ readonly isAnswered?: (response: unknown) => boolean;
147
+ readonly fieldPolicy?: FieldPolicy;
148
+ readonly redactedSchema?: z.ZodType<unknown>;
149
+ readonly interop?: ActivityTypeInterop<unknown>;
150
+ readonly interactions?: readonly string[];
151
+ }
152
+ /**
153
+ * Identity helper that gives full type inference when authoring a descriptor:
154
+ *
155
+ * ```ts
156
+ * const myType = defineActivityType<MyTypeData, MyTypeLearnerResponse>({ ... });
157
+ * registerActivityType(myType);
158
+ * ```
159
+ */
160
+ declare function defineActivityType<TData extends {
161
+ type: string;
162
+ }, TResponse>(descriptor: ActivityTypeDescriptor<TData, TResponse>): ActivityTypeDescriptor<TData, TResponse>;
163
+ /**
164
+ * Registers an activity type on the default registry, making it live for
165
+ * `validateActivity`, `score`, `evaluate`, `redact`, and `jsonSchemaFor`.
166
+ * Re-registering the same descriptor object is a no-op; registering a
167
+ * DIFFERENT descriptor under an existing type throws — silently replacing a
168
+ * type's contract or scoring is exactly the class of accident a summative
169
+ * SDK must not allow.
170
+ */
171
+ declare function registerActivityType<TData extends {
172
+ type: string;
173
+ }, TResponse>(descriptor: ActivityTypeDescriptor<TData, TResponse>): void;
174
+ /** Returns the registered descriptor for `type`, or `undefined`. */
175
+ declare function getActivityTypeDescriptor(type: string): RegisteredActivityTypeDescriptor | undefined;
176
+ /** The type strings currently registered (built-ins plus consumer-registered). */
177
+ declare function registeredActivityTypes(): string[];
178
+
179
+ /**
180
+ * A learner-safe projection of activity data produced by {@link redact}:
181
+ * the activity's public fields plus the `redacted: true` marker. Renderable
182
+ * and validatable (each built-in type registers a strict redacted schema),
183
+ * but stripped of the answer key, scoring rules, authored feedback, and
184
+ * author-only assets.
185
+ */
186
+ interface RedactedActivityData {
187
+ redacted: true;
188
+ schemaVersion: string;
189
+ type: string;
190
+ id: string;
191
+ title: string;
192
+ [key: string]: unknown;
193
+ }
194
+ /** Options for {@link redact}. */
195
+ interface RedactOptions {
196
+ /**
197
+ * Which sensitivity tiers to keep beyond `public`:
198
+ * - `'none'` (default) — public fields only; the output satisfies the
199
+ * type's strict redacted schema and `assertRedacted`.
200
+ * - `'after-submit'` — public + answer-key fields (for post-submission
201
+ * review renders). `author-only` fields and unclassified fields are
202
+ * STILL removed; the output will NOT pass `assertRedacted`.
203
+ */
204
+ reveal?: 'none' | 'after-submit';
205
+ /**
206
+ * Per-call sensitivity overrides, merged over the type's registered
207
+ * `fieldPolicy` (top-level keys replace; nested objects merge one level).
208
+ *
209
+ * Sensitivity is partly a PEDAGOGICAL decision, not purely a security one —
210
+ * whether a rubric or a hint is learner-visible differs legitimately between
211
+ * deployments — and the SDK must not freeze that choice. Use this to tighten
212
+ * a field the SDK ships as `public`:
213
+ *
214
+ * ```ts
215
+ * redact(essay, { policy: { rubric: 'author-only' } });
216
+ * ```
217
+ *
218
+ * Overrides can only be applied to fields; they cannot re-open a field the
219
+ * caller has not classified, because unclassified still means removed.
220
+ * Note that tightening below what the type's `redactedSchema` requires is
221
+ * allowed — the schema check only rejects payloads that reveal MORE than
222
+ * the learner-safe shape.
223
+ */
224
+ policy?: FieldPolicy;
225
+ }
226
+ /**
227
+ * Produces the learner-safe projection of activity data (R7), driven by the
228
+ * `fieldPolicy` registered for `data.type`. Fail-closed and exhaustive by
229
+ * construction: a field the policy does not classify is removed — including
230
+ * unknown passthrough fields — so a NEW field added by a future SDK or a
231
+ * consumer sidecar can never leak through an out-of-date redactor.
232
+ *
233
+ * With the default `reveal: 'none'`, the output validates against the type's
234
+ * strict redacted schema (verified here; an invalid projection throws
235
+ * {@link ActivitySchemaError} rather than shipping an unproven payload).
236
+ *
237
+ * @throws UnknownActivityTypeError when `data.type` is not registered.
238
+ * @throws Error when the registered descriptor declares no `fieldPolicy`
239
+ * (redaction cannot guess sensitivities).
240
+ */
241
+ declare function redact<T extends {
242
+ type: string;
243
+ }>(data: T, options?: RedactOptions): RedactedActivityData;
244
+ /**
245
+ * Asserts that `data` is a learner-safe redacted projection: it carries the
246
+ * `redacted: true` marker and, when its type registers a strict redacted
247
+ * schema, validates against it (proving the absence of answer-key fields).
248
+ * Use this at the server boundary before sending activity data to a client
249
+ * that must not hold the key.
250
+ */
251
+ declare function assertRedacted(data: unknown): asserts data is RedactedActivityData;
252
+
253
+ /** Built-in Multiple Choice descriptor. */
254
+ declare const multipleChoiceType: ActivityTypeDescriptor<MultipleChoiceData, MultipleChoiceLearnerResponse>;
255
+ /** Built-in Fill-in-the-Blanks descriptor. */
256
+ declare const fillInTheBlanksType: ActivityTypeDescriptor<FillInTheBlanksData, FillInTheBlanksLearnerResponse>;
257
+ /**
258
+ * Built-in Written Response descriptor. Grading is DEFERRED: submissions are
259
+ * graded asynchronously (AI or human) by the consumer; the synchronous
260
+ * outcome reports only word-count facts. `wordCount` is recomputed from the
261
+ * submitted text with the canonical `countWords()` — the client-supplied
262
+ * count is informational, never trusted.
263
+ */
264
+ declare const writtenResponseType: ActivityTypeDescriptor<WrittenResponseData, WrittenResponseLearnerResponse>;
19
265
 
20
266
  /**
21
267
  * All CSS custom property tokens consumed by learning-kit components.
@@ -53,4 +299,4 @@ interface ThemeTokens {
53
299
  '--lk-transition-base': string;
54
300
  }
55
301
 
56
- export { ActivitySchemaError, type ThemeTokens, UnknownActivityTypeError, ValidationError };
302
+ export { ActivitySchemaError, type ActivityTypeDescriptor, type ActivityTypeInterop, type ActivityTypeScoring, DeferredScoringError, DeferredScoringPartial, type FieldPolicy, FillInTheBlanksData, FillInTheBlanksLearnerResponse, MultipleChoiceData, MultipleChoiceLearnerResponse, type PartialScoringResult, type RedactOptions, type RedactedActivityData, RedactedScoringError, type RegisteredActivityTypeDescriptor, ScoringResult, type Sensitivity, type ThemeTokens, UnknownActivityTypeError, ValidationError, WrittenResponseData, WrittenResponseLearnerResponse, type XAPIInteractionType, assertRedacted, countWords, defineActivityType, fillInTheBlanksType, getActivityTypeDescriptor, multipleChoiceType, redact, registerActivityType, registeredActivityTypes, writtenResponseType };