@conform-ed/contracts 0.0.3
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/.turbo/turbo-build.log +2 -0
- package/.turbo/turbo-format.log +6 -0
- package/.turbo/turbo-lint.log +4 -0
- package/.turbo/turbo-test.log +196 -0
- package/.turbo/turbo-typecheck.log +2 -0
- package/README.md +52 -0
- package/caliper-v1_2-zod-templates.md +123 -0
- package/case-v1_1-zod-templates.md +290 -0
- package/cat-v1_0-zod-templates.md +73 -0
- package/cc-v1_3-zod-templates.md +531 -0
- package/cc-v1_4-zod-templates.md +247 -0
- package/clr-v2_0-zod-templates.md +117 -0
- package/cmi5-v1_0-zod-templates.md +9 -0
- package/lti-zod-templates.md +11 -0
- package/oneroster-v1_2-zod-templates.md +76 -0
- package/open-badges-v3_0-zod-templates.md +66 -0
- package/package.json +42 -0
- package/qti-v2_1-zod-templates.md +45 -0
- package/qti-v2_2-zod-templates.md +32 -0
- package/qti-v3_0_1-zod-templates.md +421 -0
- package/src/adapter.ts +83 -0
- package/src/caliper/v1_2/caliper_v1p2_bootcamp_schema.ts +781 -0
- package/src/caliper/v1_2/index.ts +37 -0
- package/src/caliper/v1_2/shared.ts +122 -0
- package/src/caliper/v1_2/textual_requirements.ts +219 -0
- package/src/case/v1_1/case_v1p1_cfassociation_jsonschema1.ts +1 -0
- package/src/case/v1_1/case_v1p1_cfassociationgrouping_jsonschema1.ts +1 -0
- package/src/case/v1_1/case_v1p1_cfassociationset_jsonschema1.ts +1 -0
- package/src/case/v1_1/case_v1p1_cfconceptset_jsonschema1.ts +1 -0
- package/src/case/v1_1/case_v1p1_cfdocument_jsonschema1.ts +1 -0
- package/src/case/v1_1/case_v1p1_cfdocumentset_jsonschema1.ts +1 -0
- package/src/case/v1_1/case_v1p1_cfitem_jsonschema1.ts +1 -0
- package/src/case/v1_1/case_v1p1_cfitemtypeset_jsonschema1.ts +1 -0
- package/src/case/v1_1/case_v1p1_cflicense_jsonschema1.ts +1 -0
- package/src/case/v1_1/case_v1p1_cfpackage_jsonschema1.ts +1 -0
- package/src/case/v1_1/case_v1p1_cfrubric_jsonschema1.ts +1 -0
- package/src/case/v1_1/case_v1p1_cfsubjectset_jsonschema1.ts +1 -0
- package/src/case/v1_1/case_v1p1_imsx_statusinfo_jsonschema1.ts +1 -0
- package/src/case/v1_1/case_v1p1_openapi3_restbinding_schema.ts +113 -0
- package/src/case/v1_1/index.ts +95 -0
- package/src/case/v1_1/shared.ts +384 -0
- package/src/cat/v1_0/cat_v1p0_restbinding_operations_schema.ts +75 -0
- package/src/cat/v1_0/index.ts +124 -0
- package/src/cat/v1_0/shared.ts +345 -0
- package/src/clr/v2_0/clr_v2p0_achievementcredential_schema.ts +16 -0
- package/src/clr/v2_0/clr_v2p0_clrcredential_schema.ts +9 -0
- package/src/clr/v2_0/clr_v2p0_endorsementcredential_schema.ts +11 -0
- package/src/clr/v2_0/clr_v2p0_getclrcredentialsresponse_schema.ts +1 -0
- package/src/clr/v2_0/clr_v2p0_imsx_statusinfo_schema.ts +8 -0
- package/src/clr/v2_0/clr_v2p0_profile_schema.ts +9 -0
- package/src/clr/v2_0/index.ts +22 -0
- package/src/clr/v2_0/shared.ts +206 -0
- package/src/cmi5/index.ts +3 -0
- package/src/cmi5/v1_0/index.ts +134 -0
- package/src/common-cartridge/v1_3/ccv1p3_imsccauth_v1p3.ts +26 -0
- package/src/common-cartridge/v1_3/ccv1p3_imscp_v1p2_v1p0.ts +352 -0
- package/src/common-cartridge/v1_3/ccv1p3_imscsmd_v1p0.ts +35 -0
- package/src/common-cartridge/v1_3/ccv1p3_imsdt_v1p3.ts +33 -0
- package/src/common-cartridge/v1_3/ccv1p3_imswl_v1p3.ts +23 -0
- package/src/common-cartridge/v1_3/ccv1p3_lomccltilink_v1p0.ts +14 -0
- package/src/common-cartridge/v1_3/ccv1p3_lommanifest_v1p0.ts +14 -0
- package/src/common-cartridge/v1_3/ccv1p3_lomresource_v1p0.ts +14 -0
- package/src/common-cartridge/v1_3/ccv1p3_qtiasiv1p2p1_v1p0.ts +964 -0
- package/src/common-cartridge/v1_3/index.ts +41 -0
- package/src/common-cartridge/v1_3/lom-internal.ts +396 -0
- package/src/common-cartridge/v1_3/shared.ts +68 -0
- package/src/common-cartridge/v1_4/core/ccv1p4_imscp_v1p2_v1p0.ts +360 -0
- package/src/common-cartridge/v1_4/core/ccv1p4_lommanifest_v1p0.ts +14 -0
- package/src/common-cartridge/v1_4/core/ccv1p4_lomresource_v1p0.ts +14 -0
- package/src/common-cartridge/v1_4/extension/cc_extresource_assignmentv1p0_v1p0.ts +61 -0
- package/src/common-cartridge/v1_4/extension/ccv1p4_cpextensionv1p2_v1p0.ts +20 -0
- package/src/common-cartridge/v1_4/extension/ims_openvideov1p0_v1p0.ts +325 -0
- package/src/common-cartridge/v1_4/index.ts +104 -0
- package/src/common-cartridge/v1_4/k12/ccv1p4_imscp_v1p2_v1p0.ts +19 -0
- package/src/common-cartridge/v1_4/k12/ccv1p4_imscp_v1p2_v1p0_thin.ts +17 -0
- package/src/common-cartridge/v1_4/k12/ccv1p4_lommanifest_v1p0.ts +14 -0
- package/src/common-cartridge/v1_4/k12/ccv1p4_lomresource_v1p0.ts +14 -0
- package/src/common-cartridge/v1_4/lom-internal.ts +476 -0
- package/src/common-cartridge/v1_4/shared/ccv1p4_imsccauth_v1p4.ts +26 -0
- package/src/common-cartridge/v1_4/shared/ccv1p4_imscsmd_v1p1.ts +36 -0
- package/src/common-cartridge/v1_4/shared/ccv1p4_imsdt_v1p4.ts +33 -0
- package/src/common-cartridge/v1_4/shared/ccv1p4_imslticc_v1p4.ts +45 -0
- package/src/common-cartridge/v1_4/shared/ccv1p4_imswl_v1p4.ts +23 -0
- package/src/common-cartridge/v1_4/shared/ccv1p4_lomccltilink_v1p0.ts +14 -0
- package/src/common-cartridge/v1_4/shared/ccv1p4_qtiasiv1p2p1_v1p0.ts +964 -0
- package/src/common-cartridge/v1_4/shared/imsbasiclti_v1p0p1.ts +24 -0
- package/src/common-cartridge/v1_4/shared/imslticm_v1p0.ts +23 -0
- package/src/common-cartridge/v1_4/shared/imslticp_v1p0.ts +57 -0
- package/src/common-cartridge/v1_4/shared/lineitem_v1p0.ts +35 -0
- package/src/common-cartridge/v1_4/shared/resourcea11ymetadata-20210915.ts +110 -0
- package/src/common-cartridge/v1_4/shared.ts +68 -0
- package/src/common-cartridge/v1_4/thin/ccv1p4_imscp_v1p2_v1p0.ts +243 -0
- package/src/common-cartridge/v1_4/thin/ccv1p4_lommanifest_v1p0.ts +14 -0
- package/src/common-cartridge/v1_4/thin/ccv1p4_lomresource_v1p0.ts +14 -0
- package/src/common-cartridge/v1_4/vdex/imsmd_loose_v1p3p2.ts +13 -0
- package/src/common-cartridge/v1_4/vdex/imsvdex_v1p0.ts +124 -0
- package/src/config.ts +121 -0
- package/src/index.ts +32 -0
- package/src/lti/ags/v2_0/index.ts +97 -0
- package/src/lti/deep-linking/v2_0/index.ts +100 -0
- package/src/lti/index.ts +26 -0
- package/src/lti/nrps/v2_0/index.ts +69 -0
- package/src/lti/proctoring/v1_0/index.ts +131 -0
- package/src/lti/shared.ts +66 -0
- package/src/lti/v1_3/index.ts +84 -0
- package/src/oneroster/v1_2/index.ts +156 -0
- package/src/oneroster/v1_2/or_v1p2_csv_binding_schema.ts +427 -0
- package/src/oneroster/v1_2/or_v1p2_gradebook_restbinding_schema.ts +120 -0
- package/src/oneroster/v1_2/or_v1p2_gradebook_service_schema.ts +243 -0
- package/src/oneroster/v1_2/or_v1p2_resource_restbinding_schema.ts +24 -0
- package/src/oneroster/v1_2/or_v1p2_resource_service_schema.ts +47 -0
- package/src/oneroster/v1_2/or_v1p2_rostering_restbinding_schema.ts +84 -0
- package/src/oneroster/v1_2/or_v1p2_rostering_service_schema.ts +288 -0
- package/src/oneroster/v1_2/shared.ts +90 -0
- package/src/open-badges/v3_0/index.ts +20 -0
- package/src/open-badges/v3_0/ob_v3p0_achievementcredential_schema.ts +17 -0
- package/src/open-badges/v3_0/ob_v3p0_endorsementcredential_schema.ts +11 -0
- package/src/open-badges/v3_0/ob_v3p0_getopenbadgecredentialsresponse_schema.ts +1 -0
- package/src/open-badges/v3_0/ob_v3p0_imsx_statusinfo_schema.ts +8 -0
- package/src/open-badges/v3_0/ob_v3p0_profile_schema.ts +9 -0
- package/src/open-badges/v3_0/shared.ts +458 -0
- package/src/qti/v2-internal.ts +1683 -0
- package/src/qti/v2_1/apipv1p0_qtiextv2p1_v1p0.ts +3 -0
- package/src/qti/v2_1/imsqti_metadata_v2p1.ts +3 -0
- package/src/qti/v2_1/imsqti_result_v2p1.ts +3 -0
- package/src/qti/v2_1/imsqti_usagedata_v2p1.ts +3 -0
- package/src/qti/v2_1/imsqti_v2p1p2.ts +71 -0
- package/src/qti/v2_1/index.ts +53 -0
- package/src/qti/v2_1/qtiv2p1_imscpv1p2_v1p0.ts +3 -0
- package/src/qti/v2_1/schemas.ts +15 -0
- package/src/qti/v2_1/shared.ts +3 -0
- package/src/qti/v2_2/apipv1p0_qtiextv2p2_v1p0p1.ts +3 -0
- package/src/qti/v2_2/imsqti_metadata_v2p2.ts +3 -0
- package/src/qti/v2_2/imsqti_result_v2p2.ts +3 -0
- package/src/qti/v2_2/imsqti_usagedata_v2p2.ts +3 -0
- package/src/qti/v2_2/imsqti_v2p2p4.ts +76 -0
- package/src/qti/v2_2/imsqtiv2p2p4_html5_v1p0.ts +8 -0
- package/src/qti/v2_2/index.ts +59 -0
- package/src/qti/v2_2/qtiv2p2_csm_v2p2.ts +4 -0
- package/src/qti/v2_2/qtiv2p2_imscpv1p2_v1p0.ts +3 -0
- package/src/qti/v2_2/schemas.ts +19 -0
- package/src/qti/v2_2/shared.ts +3 -0
- package/src/qti/v3_0_1/assessment-internal.ts +1509 -0
- package/src/qti/v3_0_1/imsqti_asiv3p0p1_v1p0.ts +57 -0
- package/src/qti/v3_0_1/imsqti_itemv3p0p1_v1p0.ts +60 -0
- package/src/qti/v3_0_1/imsqti_metadatav3p0_v1p0.ts +73 -0
- package/src/qti/v3_0_1/imsqti_outcomev3p0p1_v1p0.ts +11 -0
- package/src/qti/v3_0_1/imsqti_responseprocessingv3p0p1_v1p0.ts +17 -0
- package/src/qti/v3_0_1/imsqti_resultv3p0_v1p0.ts +222 -0
- package/src/qti/v3_0_1/imsqti_sectionv3p0p1_v1p0.ts +15 -0
- package/src/qti/v3_0_1/imsqti_stimulusv3p0p1_v1p0.ts +15 -0
- package/src/qti/v3_0_1/imsqti_testv3p0p1_v1p0.ts +49 -0
- package/src/qti/v3_0_1/imsqti_usagedatav3p0_v1p0.ts +77 -0
- package/src/qti/v3_0_1/imsqtiv3p0_afa3p0pnp_v1p0.ts +269 -0
- package/src/qti/v3_0_1/index.ts +50 -0
- package/src/qti/v3_0_1/processing-internal.ts +667 -0
- package/src/qti/v3_0_1/shared.ts +146 -0
- package/src/qti/v3_0_1/variables-internal.ts +274 -0
- package/src/shared/imsx-status.ts +49 -0
- package/src/summary.ts +70 -0
- package/src/vc-data-model/v2_0/index.ts +27 -0
- package/src/vc-data-model/v2_0/shared.ts +206 -0
- package/src/xapi/index.ts +12 -0
- package/src/xapi/shared.ts +444 -0
- package/src/xapi/v1_0_3/index.ts +169 -0
- package/src/xapi/v2_0/index.ts +256 -0
- package/test/caliper-v1_2.test.ts +270 -0
- package/test/case-v1_1.test.ts +147 -0
- package/test/cat-v1_0.test.ts +338 -0
- package/test/cc-v1_4.test.ts +239 -0
- package/test/clr-v2_0.test.ts +225 -0
- package/test/cmi5-v1_0.test.ts +196 -0
- package/test/contracts.test.ts +125 -0
- package/test/fixtures/cmi5/extended-cmi5.xml +72 -0
- package/test/fixtures/cmi5/simple-cmi5.xml +26 -0
- package/test/lti.test.ts +146 -0
- package/test/oneroster-v1_2.test.ts +234 -0
- package/test/open-badges-v3_0.test.ts +144 -0
- package/test/qti-v2_1.test.ts +146 -0
- package/test/qti-v2_2.test.ts +154 -0
- package/test/qti-v3_0_1.test.ts +576 -0
- package/test/schema-examples.test.ts +101 -0
- package/test/vc-data-model-v2_0.test.ts +63 -0
- package/test/xapi.test.ts +384 -0
- package/tsconfig.json +7 -0
- package/vc-data-model-v2_0-zod-templates.md +43 -0
- package/xapi-zod-templates.md +95 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
export * from "../shared";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
ActivitiesResourceQuerySchema,
|
|
5
|
+
AboutResourceSchema,
|
|
6
|
+
ActivityProfileDocumentListingQuerySchema,
|
|
7
|
+
ActivityProfileDocumentQuerySchema,
|
|
8
|
+
ActivitySchema,
|
|
9
|
+
AgentAccountSchema,
|
|
10
|
+
AgentsResourceQuerySchema,
|
|
11
|
+
AgentProfileDocumentListingQuerySchema,
|
|
12
|
+
AgentProfileDocumentQuerySchema,
|
|
13
|
+
AgentSchema,
|
|
14
|
+
AttachmentSchema,
|
|
15
|
+
ContextActivitiesSchema,
|
|
16
|
+
ContextSchema,
|
|
17
|
+
GroupSchema,
|
|
18
|
+
InteractionComponentSchema,
|
|
19
|
+
InteractionTypeSchema,
|
|
20
|
+
Iso8601DurationSchema,
|
|
21
|
+
Iso8601TimestampSchema,
|
|
22
|
+
LanguageMapSchema,
|
|
23
|
+
LanguageTagSchema,
|
|
24
|
+
NonEmptyStringSchema,
|
|
25
|
+
PersonSchema,
|
|
26
|
+
ResultSchema,
|
|
27
|
+
ScoreSchema,
|
|
28
|
+
StatementsQuerySchema,
|
|
29
|
+
StatementObjectSchema,
|
|
30
|
+
StatementResultSchema,
|
|
31
|
+
StatementRefSchema,
|
|
32
|
+
StatementSchema,
|
|
33
|
+
StatementSubmissionSchema,
|
|
34
|
+
StateDocumentListingQuerySchema,
|
|
35
|
+
StateDocumentQuerySchema,
|
|
36
|
+
SubStatementSchema,
|
|
37
|
+
UuidSchema,
|
|
38
|
+
VerbSchema,
|
|
39
|
+
XapiDocumentSchema,
|
|
40
|
+
XapiDocumentIdListSchema,
|
|
41
|
+
IriSchema,
|
|
42
|
+
XapiVersionSchema,
|
|
43
|
+
XapiHttpMethodSchema,
|
|
44
|
+
XapiResourceSchema,
|
|
45
|
+
XapiRequestHeaderSchema,
|
|
46
|
+
XapiResponseHeaderSchema,
|
|
47
|
+
XapiErrorCodeSchema,
|
|
48
|
+
XapiErrorResponseSchema,
|
|
49
|
+
XapiConcurrencySchema,
|
|
50
|
+
XapiMultipartAttachmentPartSchema,
|
|
51
|
+
XapiMultipartRequestSchema,
|
|
52
|
+
} from "../shared";
|
|
53
|
+
|
|
54
|
+
export namespace XapiV1_0_3 {
|
|
55
|
+
export namespace Schemas {
|
|
56
|
+
export const AgentAccount = AgentAccountSchema;
|
|
57
|
+
export const Agent = AgentSchema;
|
|
58
|
+
export const Group = GroupSchema;
|
|
59
|
+
export const Verb = VerbSchema;
|
|
60
|
+
export const InteractionComponent = InteractionComponentSchema;
|
|
61
|
+
export const Activity = ActivitySchema;
|
|
62
|
+
export const StatementRef = StatementRefSchema;
|
|
63
|
+
export const SubStatement = SubStatementSchema;
|
|
64
|
+
export const Score = ScoreSchema;
|
|
65
|
+
export const Result = ResultSchema;
|
|
66
|
+
export const ContextActivities = ContextActivitiesSchema;
|
|
67
|
+
export const Context = ContextSchema;
|
|
68
|
+
export const Attachment = AttachmentSchema;
|
|
69
|
+
export const StatementObject = StatementObjectSchema;
|
|
70
|
+
export const Statement = StatementSchema;
|
|
71
|
+
export const StatementSubmission = StatementSubmissionSchema;
|
|
72
|
+
export const StatementResult = StatementResultSchema;
|
|
73
|
+
export const Person = PersonSchema;
|
|
74
|
+
export const AboutResource = AboutResourceSchema;
|
|
75
|
+
export const StatementsQuery = StatementsQuerySchema;
|
|
76
|
+
export const AgentsResourceQuery = AgentsResourceQuerySchema;
|
|
77
|
+
export const ActivitiesResourceQuery = ActivitiesResourceQuerySchema;
|
|
78
|
+
export const StateDocumentQuery = StateDocumentQuerySchema;
|
|
79
|
+
export const StateDocumentListingQuery = StateDocumentListingQuerySchema;
|
|
80
|
+
export const AgentProfileDocumentQuery = AgentProfileDocumentQuerySchema;
|
|
81
|
+
export const AgentProfileDocumentListingQuery = AgentProfileDocumentListingQuerySchema;
|
|
82
|
+
export const ActivityProfileDocumentQuery = ActivityProfileDocumentQuerySchema;
|
|
83
|
+
export const ActivityProfileDocumentListingQuery = ActivityProfileDocumentListingQuerySchema;
|
|
84
|
+
export const XapiDocument = XapiDocumentSchema;
|
|
85
|
+
export const XapiDocumentIdList = XapiDocumentIdListSchema;
|
|
86
|
+
export const HttpMethod = XapiHttpMethodSchema;
|
|
87
|
+
export const Resource = XapiResourceSchema;
|
|
88
|
+
export const RequestHeader = XapiRequestHeaderSchema;
|
|
89
|
+
export const ResponseHeader = XapiResponseHeaderSchema;
|
|
90
|
+
export const ErrorCode = XapiErrorCodeSchema;
|
|
91
|
+
export const ErrorResponse = XapiErrorResponseSchema;
|
|
92
|
+
export const Concurrency = XapiConcurrencySchema;
|
|
93
|
+
export const MultipartAttachmentPart = XapiMultipartAttachmentPartSchema;
|
|
94
|
+
export const MultipartRequest = XapiMultipartRequestSchema;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export namespace Shared {
|
|
98
|
+
export const Uuid = UuidSchema;
|
|
99
|
+
export const Version = XapiVersionSchema;
|
|
100
|
+
export const Iri = IriSchema;
|
|
101
|
+
export const LanguageTag = LanguageTagSchema;
|
|
102
|
+
export const LanguageMap = LanguageMapSchema;
|
|
103
|
+
export const Timestamp = Iso8601TimestampSchema;
|
|
104
|
+
export const Duration = Iso8601DurationSchema;
|
|
105
|
+
export const NonEmptyString = NonEmptyStringSchema;
|
|
106
|
+
export const InteractionType = InteractionTypeSchema;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export type XapiV1_0_3Schemas = typeof XapiV1_0_3.Schemas;
|
|
111
|
+
|
|
112
|
+
export const XapiV1_0_3DerivedZodTemplates = {
|
|
113
|
+
description:
|
|
114
|
+
"xAPI 1.0.3 Zod schemas for statements, statement result/person objects, document resources, LRS transport, and about metadata",
|
|
115
|
+
specLinks: {
|
|
116
|
+
about: "https://github.com/adlnet/xAPI-Spec/blob/ca782a1129bc6ae848640ff4e8e262334bdd0ba5/xAPI-About.md",
|
|
117
|
+
data: "https://github.com/adlnet/xAPI-Spec/blob/ca782a1129bc6ae848640ff4e8e262334bdd0ba5/xAPI-Data.md",
|
|
118
|
+
communication:
|
|
119
|
+
"https://github.com/adlnet/xAPI-Spec/blob/ca782a1129bc6ae848640ff4e8e262334bdd0ba5/xAPI-Communication.md",
|
|
120
|
+
lrsContent:
|
|
121
|
+
"https://github.com/adlnet/xAPI-Spec/blob/ca782a1129bc6ae848640ff4e8e262334bdd0ba5/xAPI-Communication.md#lrs",
|
|
122
|
+
},
|
|
123
|
+
scope:
|
|
124
|
+
"Statements, statement-like objects, statement result/person objects, statement and resource queries, LRS document resources and id lists, transport headers, concurrency control, multipart attachment handling, and about/version metadata",
|
|
125
|
+
designNotes: [
|
|
126
|
+
"Structured statement data is modeled strictly; document bodies are intentionally permissive because xAPI allows arbitrary document content types.",
|
|
127
|
+
"Agent and Group validators require at least one identifier or member list, matching the data model intent rather than relying on shape alone.",
|
|
128
|
+
"The transport- and header-level parts of the spec are represented as helper schemas rather than being forced into a single statement object.",
|
|
129
|
+
"Concurrency control (ETags, If-Match/If-None-Match) and multipart attachment transmission are modeled as separate concerns for flexibility.",
|
|
130
|
+
"Error codes and response envelopes follow HTTP semantics with explicit status codes and optional detail messaging.",
|
|
131
|
+
],
|
|
132
|
+
coreSchemas: [
|
|
133
|
+
"Agent",
|
|
134
|
+
"Group",
|
|
135
|
+
"Verb",
|
|
136
|
+
"Activity",
|
|
137
|
+
"SubStatement",
|
|
138
|
+
"Result",
|
|
139
|
+
"Context",
|
|
140
|
+
"Attachment",
|
|
141
|
+
"Statement",
|
|
142
|
+
"StatementResult",
|
|
143
|
+
"Person",
|
|
144
|
+
"AboutResource",
|
|
145
|
+
"StatementsQuery",
|
|
146
|
+
"AgentsResourceQuery",
|
|
147
|
+
"ActivitiesResourceQuery",
|
|
148
|
+
"StateDocumentQuery",
|
|
149
|
+
"StateDocumentListingQuery",
|
|
150
|
+
"AgentProfileDocumentQuery",
|
|
151
|
+
"AgentProfileDocumentListingQuery",
|
|
152
|
+
"ActivityProfileDocumentQuery",
|
|
153
|
+
"ActivityProfileDocumentListingQuery",
|
|
154
|
+
"XapiDocumentIdList",
|
|
155
|
+
"HttpMethod",
|
|
156
|
+
"Resource",
|
|
157
|
+
"RequestHeader",
|
|
158
|
+
"ResponseHeader",
|
|
159
|
+
"ErrorCode",
|
|
160
|
+
"ErrorResponse",
|
|
161
|
+
"Concurrency",
|
|
162
|
+
"MultipartAttachmentPart",
|
|
163
|
+
"MultipartRequest",
|
|
164
|
+
],
|
|
165
|
+
} as const;
|
|
166
|
+
|
|
167
|
+
export const Schemas = XapiV1_0_3.Schemas;
|
|
168
|
+
export const Shared = XapiV1_0_3.Shared;
|
|
169
|
+
export const DerivedZodTemplates = XapiV1_0_3DerivedZodTemplates;
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
export * from "../shared";
|
|
2
|
+
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
strictObject,
|
|
7
|
+
ActivitiesResourceQuerySchema,
|
|
8
|
+
AboutResourceSchema,
|
|
9
|
+
ActivityProfileDocumentListingQuerySchema,
|
|
10
|
+
ActivityProfileDocumentQuerySchema,
|
|
11
|
+
ActivitySchema,
|
|
12
|
+
AgentAccountSchema,
|
|
13
|
+
AgentProfileDocumentListingQuerySchema,
|
|
14
|
+
AgentProfileDocumentQuerySchema,
|
|
15
|
+
AgentSchema,
|
|
16
|
+
AgentsResourceQuerySchema,
|
|
17
|
+
AttachmentSchema,
|
|
18
|
+
ContextActivitiesSchema,
|
|
19
|
+
ContextSchema,
|
|
20
|
+
GroupSchema,
|
|
21
|
+
InteractionComponentSchema,
|
|
22
|
+
InteractionTypeSchema,
|
|
23
|
+
IriSchema,
|
|
24
|
+
Iso8601DurationSchema,
|
|
25
|
+
Iso8601TimestampSchema,
|
|
26
|
+
LanguageMapSchema,
|
|
27
|
+
LanguageTagSchema,
|
|
28
|
+
NonEmptyStringSchema,
|
|
29
|
+
PersonSchema,
|
|
30
|
+
ResultSchema,
|
|
31
|
+
ScoreSchema,
|
|
32
|
+
StatementsQuerySchema,
|
|
33
|
+
StatementRefSchema,
|
|
34
|
+
StatementResultMoreSchema,
|
|
35
|
+
StateDocumentListingQuerySchema,
|
|
36
|
+
StateDocumentQuerySchema,
|
|
37
|
+
UuidSchema,
|
|
38
|
+
VerbSchema,
|
|
39
|
+
XapiConcurrencySchema,
|
|
40
|
+
XapiDocumentIdListSchema,
|
|
41
|
+
XapiDocumentSchema,
|
|
42
|
+
XapiErrorCodeSchema,
|
|
43
|
+
XapiErrorResponseSchema,
|
|
44
|
+
XapiHttpMethodSchema,
|
|
45
|
+
XapiMultipartAttachmentPartSchema,
|
|
46
|
+
XapiRequestHeaderSchema,
|
|
47
|
+
XapiResourceSchema,
|
|
48
|
+
XapiResponseHeaderSchema,
|
|
49
|
+
XapiVersionSchema,
|
|
50
|
+
} from "../shared";
|
|
51
|
+
|
|
52
|
+
export const ContextAgentSchema = strictObject({
|
|
53
|
+
objectType: z.literal("contextAgent"),
|
|
54
|
+
agent: AgentSchema,
|
|
55
|
+
relevantTypes: z.array(IriSchema).min(1).optional(),
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
export const ContextGroupSchema = strictObject({
|
|
59
|
+
objectType: z.literal("contextGroup"),
|
|
60
|
+
group: GroupSchema,
|
|
61
|
+
relevantTypes: z.array(IriSchema).min(1).optional(),
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
export const ContextV2Schema = ContextSchema.extend({
|
|
65
|
+
contextAgents: z.array(ContextAgentSchema).min(1).optional(),
|
|
66
|
+
contextGroups: z.array(ContextGroupSchema).min(1).optional(),
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
export const SubStatementV2Schema = strictObject({
|
|
70
|
+
objectType: z.literal("SubStatement"),
|
|
71
|
+
actor: z.union([AgentSchema, GroupSchema]),
|
|
72
|
+
verb: VerbSchema,
|
|
73
|
+
object: z.union([ActivitySchema, AgentSchema, GroupSchema, StatementRefSchema]),
|
|
74
|
+
result: ResultSchema.optional(),
|
|
75
|
+
context: ContextV2Schema.optional(),
|
|
76
|
+
timestamp: Iso8601TimestampSchema.optional(),
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
export const StatementObjectV2Schema = z.union([
|
|
80
|
+
ActivitySchema,
|
|
81
|
+
AgentSchema,
|
|
82
|
+
GroupSchema,
|
|
83
|
+
StatementRefSchema,
|
|
84
|
+
SubStatementV2Schema,
|
|
85
|
+
]);
|
|
86
|
+
|
|
87
|
+
export const StatementV2Schema = strictObject({
|
|
88
|
+
id: UuidSchema.optional(),
|
|
89
|
+
actor: z.union([AgentSchema, GroupSchema]),
|
|
90
|
+
verb: VerbSchema,
|
|
91
|
+
object: StatementObjectV2Schema,
|
|
92
|
+
result: ResultSchema.optional(),
|
|
93
|
+
context: ContextV2Schema.optional(),
|
|
94
|
+
timestamp: Iso8601TimestampSchema.optional(),
|
|
95
|
+
stored: Iso8601TimestampSchema.optional(),
|
|
96
|
+
authority: z.union([AgentSchema, GroupSchema]).optional(),
|
|
97
|
+
version: XapiVersionSchema.optional(),
|
|
98
|
+
attachments: z.array(AttachmentSchema).min(1).optional(),
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
export const StatementSubmissionV2Schema = z.union([StatementV2Schema, z.array(StatementV2Schema).min(1)]);
|
|
102
|
+
|
|
103
|
+
export const StatementResultV2Schema = strictObject({
|
|
104
|
+
statements: z.array(StatementV2Schema),
|
|
105
|
+
more: StatementResultMoreSchema.optional(),
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
export const XapiMultipartRequestV2Schema = strictObject({
|
|
109
|
+
contentType: z.literal("multipart/mixed"),
|
|
110
|
+
parts: z.tuple([
|
|
111
|
+
strictObject({
|
|
112
|
+
contentType: z.literal("application/json"),
|
|
113
|
+
body: z.union([StatementV2Schema, z.array(StatementV2Schema).min(1)]),
|
|
114
|
+
}),
|
|
115
|
+
z.array(XapiMultipartAttachmentPartSchema).min(1),
|
|
116
|
+
]),
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
export namespace XapiV2_0 {
|
|
120
|
+
export namespace Schemas {
|
|
121
|
+
export const AgentAccount = AgentAccountSchema;
|
|
122
|
+
export const Agent = AgentSchema;
|
|
123
|
+
export const Group = GroupSchema;
|
|
124
|
+
export const Person = PersonSchema;
|
|
125
|
+
export const Verb = VerbSchema;
|
|
126
|
+
export const InteractionComponent = InteractionComponentSchema;
|
|
127
|
+
export const Activity = ActivitySchema;
|
|
128
|
+
export const StatementRef = StatementRefSchema;
|
|
129
|
+
export const ContextAgent = ContextAgentSchema;
|
|
130
|
+
export const ContextGroup = ContextGroupSchema;
|
|
131
|
+
export const SubStatement = SubStatementV2Schema;
|
|
132
|
+
export const Score = ScoreSchema;
|
|
133
|
+
export const Result = ResultSchema;
|
|
134
|
+
export const ContextActivities = ContextActivitiesSchema;
|
|
135
|
+
export const Context = ContextV2Schema;
|
|
136
|
+
export const Attachment = AttachmentSchema;
|
|
137
|
+
export const StatementObject = StatementObjectV2Schema;
|
|
138
|
+
export const Statement = StatementV2Schema;
|
|
139
|
+
export const StatementSubmission = StatementSubmissionV2Schema;
|
|
140
|
+
export const StatementResult = StatementResultV2Schema;
|
|
141
|
+
export const AboutResource = AboutResourceSchema;
|
|
142
|
+
export const StatementsQuery = StatementsQuerySchema;
|
|
143
|
+
export const AgentsResourceQuery = AgentsResourceQuerySchema;
|
|
144
|
+
export const ActivitiesResourceQuery = ActivitiesResourceQuerySchema;
|
|
145
|
+
export const StateDocumentQuery = StateDocumentQuerySchema;
|
|
146
|
+
export const StateDocumentListingQuery = StateDocumentListingQuerySchema;
|
|
147
|
+
export const AgentProfileDocumentQuery = AgentProfileDocumentQuerySchema;
|
|
148
|
+
export const AgentProfileDocumentListingQuery = AgentProfileDocumentListingQuerySchema;
|
|
149
|
+
export const ActivityProfileDocumentQuery = ActivityProfileDocumentQuerySchema;
|
|
150
|
+
export const ActivityProfileDocumentListingQuery = ActivityProfileDocumentListingQuerySchema;
|
|
151
|
+
export const XapiDocument = XapiDocumentSchema;
|
|
152
|
+
export const XapiDocumentIdList = XapiDocumentIdListSchema;
|
|
153
|
+
export const HttpMethod = XapiHttpMethodSchema;
|
|
154
|
+
export const Resource = XapiResourceSchema;
|
|
155
|
+
export const RequestHeader = XapiRequestHeaderSchema;
|
|
156
|
+
export const ResponseHeader = XapiResponseHeaderSchema;
|
|
157
|
+
export const ErrorCode = XapiErrorCodeSchema;
|
|
158
|
+
export const ErrorResponse = XapiErrorResponseSchema;
|
|
159
|
+
export const Concurrency = XapiConcurrencySchema;
|
|
160
|
+
export const MultipartAttachmentPart = XapiMultipartAttachmentPartSchema;
|
|
161
|
+
export const MultipartRequest = XapiMultipartRequestV2Schema;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export namespace Shared {
|
|
165
|
+
export const Uuid = UuidSchema;
|
|
166
|
+
export const Version = XapiVersionSchema;
|
|
167
|
+
export const Iri = IriSchema;
|
|
168
|
+
export const LanguageTag = LanguageTagSchema;
|
|
169
|
+
export const LanguageMap = LanguageMapSchema;
|
|
170
|
+
export const Timestamp = Iso8601TimestampSchema;
|
|
171
|
+
export const Duration = Iso8601DurationSchema;
|
|
172
|
+
export const NonEmptyString = NonEmptyStringSchema;
|
|
173
|
+
export const InteractionType = InteractionTypeSchema;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export type XapiV2_0Schemas = typeof XapiV2_0.Schemas;
|
|
178
|
+
|
|
179
|
+
export const XapiV2_0DerivedZodTemplates = {
|
|
180
|
+
description:
|
|
181
|
+
"IEEE xAPI 2.0 Zod schemas for statements, 2.0 context objects, statement result/person objects, document resources, LRS transport, and about metadata",
|
|
182
|
+
specLinks: {
|
|
183
|
+
overview:
|
|
184
|
+
"https://github.com/madebyraygun/xapi-base-standard-documentation/blob/134afd8c108b4d1b98294a1613db38a6b8fe73d8/9274.1.1%20xAPI%20Base%20Standard%20Overview.md",
|
|
185
|
+
content:
|
|
186
|
+
"https://github.com/madebyraygun/xapi-base-standard-documentation/blob/134afd8c108b4d1b98294a1613db38a6b8fe73d8/9274.1.1%20xAPI%20Base%20Standard%20for%20Content.md",
|
|
187
|
+
lrs: "https://github.com/madebyraygun/xapi-base-standard-documentation/blob/134afd8c108b4d1b98294a1613db38a6b8fe73d8/9274.1.1%20xAPI%20Base%20Standard%20for%20LRSs.md",
|
|
188
|
+
},
|
|
189
|
+
scope:
|
|
190
|
+
"Statements, IEEE 2.0 contextAgent/contextGroup objects, statement result/person objects, statement and resource queries, LRS document resources and id lists, transport headers, concurrency control, multipart attachment handling, and service metadata for IEEE xAPI 2.0",
|
|
191
|
+
designNotes: [
|
|
192
|
+
"The 2.0 bundle reuses the 1.0.3 data model where the standard remains structurally equivalent, but overrides Context, SubStatement, Statement, StatementSubmission, StatementResult, and multipart request schemas to capture 2.0-only contextAgent/contextGroup support.",
|
|
193
|
+
"Version-specific differences are isolated in the package boundary and documentation rather than duplicated across the shared primitives.",
|
|
194
|
+
"Transport-level concerns such as headers and concurrency are represented as companion helper schemas rather than being merged into statement data.",
|
|
195
|
+
"LRS resource and concurrency models follow HTTP semantics with ETags, conditional requests (If-Match/If-None-Match), and standard error codes including 412 Precondition Failed.",
|
|
196
|
+
],
|
|
197
|
+
coreSchemas: [
|
|
198
|
+
"Agent",
|
|
199
|
+
"Group",
|
|
200
|
+
"Person",
|
|
201
|
+
"Verb",
|
|
202
|
+
"Activity",
|
|
203
|
+
"ContextAgent",
|
|
204
|
+
"ContextGroup",
|
|
205
|
+
"SubStatement",
|
|
206
|
+
"Result",
|
|
207
|
+
"Context",
|
|
208
|
+
"Attachment",
|
|
209
|
+
"Statement",
|
|
210
|
+
"StatementResult",
|
|
211
|
+
"AboutResource",
|
|
212
|
+
"StatementsQuery",
|
|
213
|
+
"AgentsResourceQuery",
|
|
214
|
+
"ActivitiesResourceQuery",
|
|
215
|
+
"StateDocumentQuery",
|
|
216
|
+
"StateDocumentListingQuery",
|
|
217
|
+
"AgentProfileDocumentQuery",
|
|
218
|
+
"AgentProfileDocumentListingQuery",
|
|
219
|
+
"ActivityProfileDocumentQuery",
|
|
220
|
+
"ActivityProfileDocumentListingQuery",
|
|
221
|
+
"XapiDocumentIdList",
|
|
222
|
+
"HttpMethod",
|
|
223
|
+
"Resource",
|
|
224
|
+
"RequestHeader",
|
|
225
|
+
"ResponseHeader",
|
|
226
|
+
"ErrorCode",
|
|
227
|
+
"ErrorResponse",
|
|
228
|
+
"Concurrency",
|
|
229
|
+
"MultipartAttachmentPart",
|
|
230
|
+
"MultipartRequest",
|
|
231
|
+
],
|
|
232
|
+
} as const;
|
|
233
|
+
|
|
234
|
+
export {
|
|
235
|
+
ContextV2Schema as ContextSchema,
|
|
236
|
+
StatementObjectV2Schema as StatementObjectSchema,
|
|
237
|
+
StatementResultV2Schema as StatementResultSchema,
|
|
238
|
+
StatementSubmissionV2Schema as StatementSubmissionSchema,
|
|
239
|
+
StatementV2Schema as StatementSchema,
|
|
240
|
+
SubStatementV2Schema as SubStatementSchema,
|
|
241
|
+
XapiMultipartRequestV2Schema as XapiMultipartRequestSchema,
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
export const Schemas = XapiV2_0.Schemas;
|
|
245
|
+
export const Shared = XapiV2_0.Shared;
|
|
246
|
+
export const DerivedZodTemplates = XapiV2_0DerivedZodTemplates;
|
|
247
|
+
// Inferred types from exported Zod validators.
|
|
248
|
+
export type ContextAgent = z.infer<typeof ContextAgentSchema>;
|
|
249
|
+
export type ContextGroup = z.infer<typeof ContextGroupSchema>;
|
|
250
|
+
export type ContextV2 = z.infer<typeof ContextV2Schema>;
|
|
251
|
+
export type SubStatementV2 = z.infer<typeof SubStatementV2Schema>;
|
|
252
|
+
export type StatementObjectV2 = z.infer<typeof StatementObjectV2Schema>;
|
|
253
|
+
export type StatementV2 = z.infer<typeof StatementV2Schema>;
|
|
254
|
+
export type StatementSubmissionV2 = z.infer<typeof StatementSubmissionV2Schema>;
|
|
255
|
+
export type StatementResultV2 = z.infer<typeof StatementResultV2Schema>;
|
|
256
|
+
export type XapiMultipartRequestV2 = z.infer<typeof XapiMultipartRequestV2Schema>;
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import { expect, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import { CaliperV1_2 } from "../src";
|
|
4
|
+
|
|
5
|
+
test("ActionSchema validates Caliper action vocabulary", () => {
|
|
6
|
+
expect(CaliperV1_2.ActionSchema.safeParse("Viewed").success).toBe(true);
|
|
7
|
+
expect(CaliperV1_2.ActionSchema.safeParse("ViewedSomethingElse").success).toBe(false);
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
test("PersonSchema requires top-level @context for described entity documents", () => {
|
|
11
|
+
const withContext = CaliperV1_2.PersonSchema.safeParse({
|
|
12
|
+
id: "https://example.edu/users/ada",
|
|
13
|
+
type: "Person",
|
|
14
|
+
"@context": "http://purl.imsglobal.org/ctx/caliper/v1p2",
|
|
15
|
+
name: "Ada Lovelace",
|
|
16
|
+
});
|
|
17
|
+
const withoutContext = CaliperV1_2.PersonSchema.safeParse({
|
|
18
|
+
id: "https://example.edu/users/ada",
|
|
19
|
+
type: "Person",
|
|
20
|
+
name: "Ada Lovelace",
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
expect(withContext.success).toBe(true);
|
|
24
|
+
expect(withoutContext.success).toBe(false);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test("EventSchema enforces URN UUID ids and UTC-millisecond eventTime", () => {
|
|
28
|
+
const valid = CaliperV1_2.EventSchema.safeParse({
|
|
29
|
+
type: "Event",
|
|
30
|
+
"@context": "http://purl.imsglobal.org/ctx/caliper/v1p2",
|
|
31
|
+
id: "urn:uuid:87a9fdf1-2f57-4d2d-b7e9-963cb0f89f9f",
|
|
32
|
+
actor: "https://example.edu/users/ada",
|
|
33
|
+
action: "Viewed",
|
|
34
|
+
object: "https://example.edu/resources/chapter-1",
|
|
35
|
+
eventTime: "2026-01-15T12:45:00.000Z",
|
|
36
|
+
});
|
|
37
|
+
const badId = CaliperV1_2.EventSchema.safeParse({
|
|
38
|
+
type: "Event",
|
|
39
|
+
"@context": "http://purl.imsglobal.org/ctx/caliper/v1p2",
|
|
40
|
+
id: "https://example.edu/events/123",
|
|
41
|
+
actor: "https://example.edu/users/ada",
|
|
42
|
+
action: "Viewed",
|
|
43
|
+
object: "https://example.edu/resources/chapter-1",
|
|
44
|
+
eventTime: "2026-01-15T12:45:00.000Z",
|
|
45
|
+
});
|
|
46
|
+
const badTime = CaliperV1_2.EventSchema.safeParse({
|
|
47
|
+
type: "Event",
|
|
48
|
+
"@context": "http://purl.imsglobal.org/ctx/caliper/v1p2",
|
|
49
|
+
id: "urn:uuid:87a9fdf1-2f57-4d2d-b7e9-963cb0f89f9f",
|
|
50
|
+
actor: "https://example.edu/users/ada",
|
|
51
|
+
action: "Viewed",
|
|
52
|
+
object: "https://example.edu/resources/chapter-1",
|
|
53
|
+
eventTime: "2026-01-15T12:45:00+08:00",
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
expect(valid.success).toBe(true);
|
|
57
|
+
expect(badId.success).toBe(false);
|
|
58
|
+
expect(badTime.success).toBe(false);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test("AnnotationEventSchema enforces textual actor/action/object constraints", () => {
|
|
62
|
+
const valid = CaliperV1_2.AnnotationEventSchema.safeParse({
|
|
63
|
+
type: "AnnotationEvent",
|
|
64
|
+
"@context": "http://purl.imsglobal.org/ctx/caliper/v1p2",
|
|
65
|
+
id: "urn:uuid:87a9fdf1-2f57-4d2d-b7e9-963cb0f89f9f",
|
|
66
|
+
actor: {
|
|
67
|
+
id: "https://example.edu/users/ada",
|
|
68
|
+
type: "Person",
|
|
69
|
+
},
|
|
70
|
+
action: "Bookmarked",
|
|
71
|
+
object: {
|
|
72
|
+
id: "https://example.edu/resources/chapter-1",
|
|
73
|
+
type: "DigitalResource",
|
|
74
|
+
},
|
|
75
|
+
generated: {
|
|
76
|
+
id: "https://example.edu/annotations/1",
|
|
77
|
+
type: "BookmarkAnnotation",
|
|
78
|
+
},
|
|
79
|
+
eventTime: "2026-01-15T12:45:00.000Z",
|
|
80
|
+
profile: "AnnotationProfile",
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
const badAction = CaliperV1_2.AnnotationEventSchema.safeParse({
|
|
84
|
+
type: "AnnotationEvent",
|
|
85
|
+
"@context": "http://purl.imsglobal.org/ctx/caliper/v1p2",
|
|
86
|
+
id: "urn:uuid:87a9fdf1-2f57-4d2d-b7e9-963cb0f89f9f",
|
|
87
|
+
actor: {
|
|
88
|
+
id: "https://example.edu/users/ada",
|
|
89
|
+
type: "Person",
|
|
90
|
+
},
|
|
91
|
+
action: "NavigatedTo",
|
|
92
|
+
object: {
|
|
93
|
+
id: "https://example.edu/resources/chapter-1",
|
|
94
|
+
type: "DigitalResource",
|
|
95
|
+
},
|
|
96
|
+
eventTime: "2026-01-15T12:45:00.000Z",
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
const badObjectType = CaliperV1_2.AnnotationEventSchema.safeParse({
|
|
100
|
+
type: "AnnotationEvent",
|
|
101
|
+
"@context": "http://purl.imsglobal.org/ctx/caliper/v1p2",
|
|
102
|
+
id: "urn:uuid:87a9fdf1-2f57-4d2d-b7e9-963cb0f89f9f",
|
|
103
|
+
actor: {
|
|
104
|
+
id: "https://example.edu/users/ada",
|
|
105
|
+
type: "Person",
|
|
106
|
+
},
|
|
107
|
+
action: "Bookmarked",
|
|
108
|
+
object: {
|
|
109
|
+
id: "https://example.edu/resources/chapter-1",
|
|
110
|
+
type: "Assessment",
|
|
111
|
+
},
|
|
112
|
+
eventTime: "2026-01-15T12:45:00.000Z",
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
expect(valid.success).toBe(true);
|
|
116
|
+
expect(badAction.success).toBe(false);
|
|
117
|
+
expect(badObjectType.success).toBe(false);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
test("MessageEventSchema accepts MarkedAsUnRead textual alias", () => {
|
|
121
|
+
const parsed = CaliperV1_2.MessageEventSchema.safeParse({
|
|
122
|
+
type: "MessageEvent",
|
|
123
|
+
"@context": "http://purl.imsglobal.org/ctx/caliper/v1p2",
|
|
124
|
+
id: "urn:uuid:87a9fdf1-2f57-4d2d-b7e9-963cb0f89f9f",
|
|
125
|
+
actor: {
|
|
126
|
+
id: "https://example.edu/users/ada",
|
|
127
|
+
type: "Person",
|
|
128
|
+
},
|
|
129
|
+
action: "MarkedAsUnRead",
|
|
130
|
+
object: {
|
|
131
|
+
id: "https://example.edu/messages/1",
|
|
132
|
+
type: "Message",
|
|
133
|
+
},
|
|
134
|
+
eventTime: "2026-01-15T12:45:00.000Z",
|
|
135
|
+
profile: "ForumProfile",
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
expect(parsed.success).toBe(true);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
test("ViewEventSchema restricts target entity type to Frame", () => {
|
|
142
|
+
const valid = CaliperV1_2.ViewEventSchema.safeParse({
|
|
143
|
+
type: "ViewEvent",
|
|
144
|
+
"@context": "http://purl.imsglobal.org/ctx/caliper/v1p2",
|
|
145
|
+
id: "urn:uuid:87a9fdf1-2f57-4d2d-b7e9-963cb0f89f9f",
|
|
146
|
+
actor: {
|
|
147
|
+
id: "https://example.edu/users/ada",
|
|
148
|
+
type: "Person",
|
|
149
|
+
},
|
|
150
|
+
action: "Viewed",
|
|
151
|
+
object: {
|
|
152
|
+
id: "https://example.edu/resources/chapter-1",
|
|
153
|
+
type: "Page",
|
|
154
|
+
},
|
|
155
|
+
target: {
|
|
156
|
+
id: "https://example.edu/resources/chapter-1#fragment",
|
|
157
|
+
type: "Frame",
|
|
158
|
+
},
|
|
159
|
+
eventTime: "2026-01-15T12:45:00.000Z",
|
|
160
|
+
});
|
|
161
|
+
const invalidTarget = CaliperV1_2.ViewEventSchema.safeParse({
|
|
162
|
+
type: "ViewEvent",
|
|
163
|
+
"@context": "http://purl.imsglobal.org/ctx/caliper/v1p2",
|
|
164
|
+
id: "urn:uuid:87a9fdf1-2f57-4d2d-b7e9-963cb0f89f9f",
|
|
165
|
+
actor: {
|
|
166
|
+
id: "https://example.edu/users/ada",
|
|
167
|
+
type: "Person",
|
|
168
|
+
},
|
|
169
|
+
action: "Viewed",
|
|
170
|
+
object: {
|
|
171
|
+
id: "https://example.edu/resources/chapter-1",
|
|
172
|
+
type: "Page",
|
|
173
|
+
},
|
|
174
|
+
target: {
|
|
175
|
+
id: "https://example.edu/resources/chapter-1#fragment",
|
|
176
|
+
type: "MediaLocation",
|
|
177
|
+
},
|
|
178
|
+
eventTime: "2026-01-15T12:45:00.000Z",
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
expect(valid.success).toBe(true);
|
|
182
|
+
expect(invalidTarget.success).toBe(false);
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
test("EnvelopeSchema enforces required fields and disallows custom top-level properties", () => {
|
|
186
|
+
const valid = CaliperV1_2.EnvelopeSchema.safeParse({
|
|
187
|
+
sensor: "https://example.edu/sensors/lms",
|
|
188
|
+
dataVersion: "http://purl.imsglobal.org/ctx/caliper/v1p2",
|
|
189
|
+
sendTime: "2026-01-15T12:50:00.000Z",
|
|
190
|
+
data: [
|
|
191
|
+
{
|
|
192
|
+
type: "ViewEvent",
|
|
193
|
+
"@context": "http://purl.imsglobal.org/ctx/caliper/v1p2",
|
|
194
|
+
id: "urn:uuid:87a9fdf1-2f57-4d2d-b7e9-963cb0f89f9f",
|
|
195
|
+
actor: "https://example.edu/users/ada",
|
|
196
|
+
action: "Viewed",
|
|
197
|
+
object: "https://example.edu/resources/chapter-1",
|
|
198
|
+
eventTime: "2026-01-15T12:45:00.000Z",
|
|
199
|
+
},
|
|
200
|
+
],
|
|
201
|
+
});
|
|
202
|
+
const missingRequired = CaliperV1_2.EnvelopeSchema.safeParse({
|
|
203
|
+
sensor: "https://example.edu/sensors/lms",
|
|
204
|
+
dataVersion: "http://purl.imsglobal.org/ctx/caliper/v1p2",
|
|
205
|
+
data: [],
|
|
206
|
+
});
|
|
207
|
+
const extraProperty = CaliperV1_2.EnvelopeSchema.safeParse({
|
|
208
|
+
sensor: "https://example.edu/sensors/lms",
|
|
209
|
+
dataVersion: "http://purl.imsglobal.org/ctx/caliper/v1p2",
|
|
210
|
+
sendTime: "2026-01-15T12:50:00.000Z",
|
|
211
|
+
data: [
|
|
212
|
+
{
|
|
213
|
+
type: "ViewEvent",
|
|
214
|
+
"@context": "http://purl.imsglobal.org/ctx/caliper/v1p2",
|
|
215
|
+
id: "urn:uuid:87a9fdf1-2f57-4d2d-b7e9-963cb0f89f9f",
|
|
216
|
+
actor: "https://example.edu/users/ada",
|
|
217
|
+
action: "Viewed",
|
|
218
|
+
object: "https://example.edu/resources/chapter-1",
|
|
219
|
+
eventTime: "2026-01-15T12:45:00.000Z",
|
|
220
|
+
},
|
|
221
|
+
],
|
|
222
|
+
custom: true,
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
expect(valid.success).toBe(true);
|
|
226
|
+
expect(missingRequired.success).toBe(false);
|
|
227
|
+
expect(extraProperty.success).toBe(false);
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
test("TextPositionSelectorSchema requires type/start/end", () => {
|
|
231
|
+
const valid = CaliperV1_2.TextPositionSelectorSchema.safeParse({
|
|
232
|
+
type: "TextPositionSelector",
|
|
233
|
+
start: 12,
|
|
234
|
+
end: 24,
|
|
235
|
+
});
|
|
236
|
+
const invalid = CaliperV1_2.TextPositionSelectorSchema.safeParse({
|
|
237
|
+
start: 12,
|
|
238
|
+
end: 24,
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
expect(valid.success).toBe(true);
|
|
242
|
+
expect(invalid.success).toBe(false);
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
test("SystemIdentifierSchema validates required identifier fields", () => {
|
|
246
|
+
const valid = CaliperV1_2.SystemIdentifierSchema.safeParse({
|
|
247
|
+
type: "SystemIdentifier",
|
|
248
|
+
identifier: "user-123",
|
|
249
|
+
identifierType: "LtiUserId",
|
|
250
|
+
});
|
|
251
|
+
const invalid = CaliperV1_2.SystemIdentifierSchema.safeParse({
|
|
252
|
+
type: "SystemIdentifier",
|
|
253
|
+
identifier: "user-123",
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
expect(valid.success).toBe(true);
|
|
257
|
+
expect(invalid.success).toBe(false);
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
test("Caliper12DerivedZodTemplates exposes key Caliper entry points and conformance metadata", () => {
|
|
261
|
+
expect(CaliperV1_2.Caliper12DerivedZodTemplates.envelope).toBe(CaliperV1_2.EnvelopeSchema);
|
|
262
|
+
expect(CaliperV1_2.Caliper12DerivedZodTemplates.event).toBe(CaliperV1_2.EventSchema);
|
|
263
|
+
expect(CaliperV1_2.Caliper12DerivedZodTemplates.person).toBe(CaliperV1_2.PersonSchema);
|
|
264
|
+
expect(CaliperV1_2.Caliper12DerivedZodTemplates.systemIdentifier).toBe(CaliperV1_2.SystemIdentifierSchema);
|
|
265
|
+
expect(CaliperV1_2.Caliper12DerivedZodTemplates.jsonSchemaEntryPoints.Action).toBe(CaliperV1_2.ActionSchema);
|
|
266
|
+
const annotationRule =
|
|
267
|
+
CaliperV1_2.Caliper12DerivedZodTemplates.conformance.supportedTextualEventRules.AnnotationEvent;
|
|
268
|
+
expect(annotationRule).toBeDefined();
|
|
269
|
+
expect(annotationRule?.profile).toBe("AnnotationProfile");
|
|
270
|
+
});
|