@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.
Files changed (187) hide show
  1. package/.turbo/turbo-build.log +2 -0
  2. package/.turbo/turbo-format.log +6 -0
  3. package/.turbo/turbo-lint.log +4 -0
  4. package/.turbo/turbo-test.log +196 -0
  5. package/.turbo/turbo-typecheck.log +2 -0
  6. package/README.md +52 -0
  7. package/caliper-v1_2-zod-templates.md +123 -0
  8. package/case-v1_1-zod-templates.md +290 -0
  9. package/cat-v1_0-zod-templates.md +73 -0
  10. package/cc-v1_3-zod-templates.md +531 -0
  11. package/cc-v1_4-zod-templates.md +247 -0
  12. package/clr-v2_0-zod-templates.md +117 -0
  13. package/cmi5-v1_0-zod-templates.md +9 -0
  14. package/lti-zod-templates.md +11 -0
  15. package/oneroster-v1_2-zod-templates.md +76 -0
  16. package/open-badges-v3_0-zod-templates.md +66 -0
  17. package/package.json +42 -0
  18. package/qti-v2_1-zod-templates.md +45 -0
  19. package/qti-v2_2-zod-templates.md +32 -0
  20. package/qti-v3_0_1-zod-templates.md +421 -0
  21. package/src/adapter.ts +83 -0
  22. package/src/caliper/v1_2/caliper_v1p2_bootcamp_schema.ts +781 -0
  23. package/src/caliper/v1_2/index.ts +37 -0
  24. package/src/caliper/v1_2/shared.ts +122 -0
  25. package/src/caliper/v1_2/textual_requirements.ts +219 -0
  26. package/src/case/v1_1/case_v1p1_cfassociation_jsonschema1.ts +1 -0
  27. package/src/case/v1_1/case_v1p1_cfassociationgrouping_jsonschema1.ts +1 -0
  28. package/src/case/v1_1/case_v1p1_cfassociationset_jsonschema1.ts +1 -0
  29. package/src/case/v1_1/case_v1p1_cfconceptset_jsonschema1.ts +1 -0
  30. package/src/case/v1_1/case_v1p1_cfdocument_jsonschema1.ts +1 -0
  31. package/src/case/v1_1/case_v1p1_cfdocumentset_jsonschema1.ts +1 -0
  32. package/src/case/v1_1/case_v1p1_cfitem_jsonschema1.ts +1 -0
  33. package/src/case/v1_1/case_v1p1_cfitemtypeset_jsonschema1.ts +1 -0
  34. package/src/case/v1_1/case_v1p1_cflicense_jsonschema1.ts +1 -0
  35. package/src/case/v1_1/case_v1p1_cfpackage_jsonschema1.ts +1 -0
  36. package/src/case/v1_1/case_v1p1_cfrubric_jsonschema1.ts +1 -0
  37. package/src/case/v1_1/case_v1p1_cfsubjectset_jsonschema1.ts +1 -0
  38. package/src/case/v1_1/case_v1p1_imsx_statusinfo_jsonschema1.ts +1 -0
  39. package/src/case/v1_1/case_v1p1_openapi3_restbinding_schema.ts +113 -0
  40. package/src/case/v1_1/index.ts +95 -0
  41. package/src/case/v1_1/shared.ts +384 -0
  42. package/src/cat/v1_0/cat_v1p0_restbinding_operations_schema.ts +75 -0
  43. package/src/cat/v1_0/index.ts +124 -0
  44. package/src/cat/v1_0/shared.ts +345 -0
  45. package/src/clr/v2_0/clr_v2p0_achievementcredential_schema.ts +16 -0
  46. package/src/clr/v2_0/clr_v2p0_clrcredential_schema.ts +9 -0
  47. package/src/clr/v2_0/clr_v2p0_endorsementcredential_schema.ts +11 -0
  48. package/src/clr/v2_0/clr_v2p0_getclrcredentialsresponse_schema.ts +1 -0
  49. package/src/clr/v2_0/clr_v2p0_imsx_statusinfo_schema.ts +8 -0
  50. package/src/clr/v2_0/clr_v2p0_profile_schema.ts +9 -0
  51. package/src/clr/v2_0/index.ts +22 -0
  52. package/src/clr/v2_0/shared.ts +206 -0
  53. package/src/cmi5/index.ts +3 -0
  54. package/src/cmi5/v1_0/index.ts +134 -0
  55. package/src/common-cartridge/v1_3/ccv1p3_imsccauth_v1p3.ts +26 -0
  56. package/src/common-cartridge/v1_3/ccv1p3_imscp_v1p2_v1p0.ts +352 -0
  57. package/src/common-cartridge/v1_3/ccv1p3_imscsmd_v1p0.ts +35 -0
  58. package/src/common-cartridge/v1_3/ccv1p3_imsdt_v1p3.ts +33 -0
  59. package/src/common-cartridge/v1_3/ccv1p3_imswl_v1p3.ts +23 -0
  60. package/src/common-cartridge/v1_3/ccv1p3_lomccltilink_v1p0.ts +14 -0
  61. package/src/common-cartridge/v1_3/ccv1p3_lommanifest_v1p0.ts +14 -0
  62. package/src/common-cartridge/v1_3/ccv1p3_lomresource_v1p0.ts +14 -0
  63. package/src/common-cartridge/v1_3/ccv1p3_qtiasiv1p2p1_v1p0.ts +964 -0
  64. package/src/common-cartridge/v1_3/index.ts +41 -0
  65. package/src/common-cartridge/v1_3/lom-internal.ts +396 -0
  66. package/src/common-cartridge/v1_3/shared.ts +68 -0
  67. package/src/common-cartridge/v1_4/core/ccv1p4_imscp_v1p2_v1p0.ts +360 -0
  68. package/src/common-cartridge/v1_4/core/ccv1p4_lommanifest_v1p0.ts +14 -0
  69. package/src/common-cartridge/v1_4/core/ccv1p4_lomresource_v1p0.ts +14 -0
  70. package/src/common-cartridge/v1_4/extension/cc_extresource_assignmentv1p0_v1p0.ts +61 -0
  71. package/src/common-cartridge/v1_4/extension/ccv1p4_cpextensionv1p2_v1p0.ts +20 -0
  72. package/src/common-cartridge/v1_4/extension/ims_openvideov1p0_v1p0.ts +325 -0
  73. package/src/common-cartridge/v1_4/index.ts +104 -0
  74. package/src/common-cartridge/v1_4/k12/ccv1p4_imscp_v1p2_v1p0.ts +19 -0
  75. package/src/common-cartridge/v1_4/k12/ccv1p4_imscp_v1p2_v1p0_thin.ts +17 -0
  76. package/src/common-cartridge/v1_4/k12/ccv1p4_lommanifest_v1p0.ts +14 -0
  77. package/src/common-cartridge/v1_4/k12/ccv1p4_lomresource_v1p0.ts +14 -0
  78. package/src/common-cartridge/v1_4/lom-internal.ts +476 -0
  79. package/src/common-cartridge/v1_4/shared/ccv1p4_imsccauth_v1p4.ts +26 -0
  80. package/src/common-cartridge/v1_4/shared/ccv1p4_imscsmd_v1p1.ts +36 -0
  81. package/src/common-cartridge/v1_4/shared/ccv1p4_imsdt_v1p4.ts +33 -0
  82. package/src/common-cartridge/v1_4/shared/ccv1p4_imslticc_v1p4.ts +45 -0
  83. package/src/common-cartridge/v1_4/shared/ccv1p4_imswl_v1p4.ts +23 -0
  84. package/src/common-cartridge/v1_4/shared/ccv1p4_lomccltilink_v1p0.ts +14 -0
  85. package/src/common-cartridge/v1_4/shared/ccv1p4_qtiasiv1p2p1_v1p0.ts +964 -0
  86. package/src/common-cartridge/v1_4/shared/imsbasiclti_v1p0p1.ts +24 -0
  87. package/src/common-cartridge/v1_4/shared/imslticm_v1p0.ts +23 -0
  88. package/src/common-cartridge/v1_4/shared/imslticp_v1p0.ts +57 -0
  89. package/src/common-cartridge/v1_4/shared/lineitem_v1p0.ts +35 -0
  90. package/src/common-cartridge/v1_4/shared/resourcea11ymetadata-20210915.ts +110 -0
  91. package/src/common-cartridge/v1_4/shared.ts +68 -0
  92. package/src/common-cartridge/v1_4/thin/ccv1p4_imscp_v1p2_v1p0.ts +243 -0
  93. package/src/common-cartridge/v1_4/thin/ccv1p4_lommanifest_v1p0.ts +14 -0
  94. package/src/common-cartridge/v1_4/thin/ccv1p4_lomresource_v1p0.ts +14 -0
  95. package/src/common-cartridge/v1_4/vdex/imsmd_loose_v1p3p2.ts +13 -0
  96. package/src/common-cartridge/v1_4/vdex/imsvdex_v1p0.ts +124 -0
  97. package/src/config.ts +121 -0
  98. package/src/index.ts +32 -0
  99. package/src/lti/ags/v2_0/index.ts +97 -0
  100. package/src/lti/deep-linking/v2_0/index.ts +100 -0
  101. package/src/lti/index.ts +26 -0
  102. package/src/lti/nrps/v2_0/index.ts +69 -0
  103. package/src/lti/proctoring/v1_0/index.ts +131 -0
  104. package/src/lti/shared.ts +66 -0
  105. package/src/lti/v1_3/index.ts +84 -0
  106. package/src/oneroster/v1_2/index.ts +156 -0
  107. package/src/oneroster/v1_2/or_v1p2_csv_binding_schema.ts +427 -0
  108. package/src/oneroster/v1_2/or_v1p2_gradebook_restbinding_schema.ts +120 -0
  109. package/src/oneroster/v1_2/or_v1p2_gradebook_service_schema.ts +243 -0
  110. package/src/oneroster/v1_2/or_v1p2_resource_restbinding_schema.ts +24 -0
  111. package/src/oneroster/v1_2/or_v1p2_resource_service_schema.ts +47 -0
  112. package/src/oneroster/v1_2/or_v1p2_rostering_restbinding_schema.ts +84 -0
  113. package/src/oneroster/v1_2/or_v1p2_rostering_service_schema.ts +288 -0
  114. package/src/oneroster/v1_2/shared.ts +90 -0
  115. package/src/open-badges/v3_0/index.ts +20 -0
  116. package/src/open-badges/v3_0/ob_v3p0_achievementcredential_schema.ts +17 -0
  117. package/src/open-badges/v3_0/ob_v3p0_endorsementcredential_schema.ts +11 -0
  118. package/src/open-badges/v3_0/ob_v3p0_getopenbadgecredentialsresponse_schema.ts +1 -0
  119. package/src/open-badges/v3_0/ob_v3p0_imsx_statusinfo_schema.ts +8 -0
  120. package/src/open-badges/v3_0/ob_v3p0_profile_schema.ts +9 -0
  121. package/src/open-badges/v3_0/shared.ts +458 -0
  122. package/src/qti/v2-internal.ts +1683 -0
  123. package/src/qti/v2_1/apipv1p0_qtiextv2p1_v1p0.ts +3 -0
  124. package/src/qti/v2_1/imsqti_metadata_v2p1.ts +3 -0
  125. package/src/qti/v2_1/imsqti_result_v2p1.ts +3 -0
  126. package/src/qti/v2_1/imsqti_usagedata_v2p1.ts +3 -0
  127. package/src/qti/v2_1/imsqti_v2p1p2.ts +71 -0
  128. package/src/qti/v2_1/index.ts +53 -0
  129. package/src/qti/v2_1/qtiv2p1_imscpv1p2_v1p0.ts +3 -0
  130. package/src/qti/v2_1/schemas.ts +15 -0
  131. package/src/qti/v2_1/shared.ts +3 -0
  132. package/src/qti/v2_2/apipv1p0_qtiextv2p2_v1p0p1.ts +3 -0
  133. package/src/qti/v2_2/imsqti_metadata_v2p2.ts +3 -0
  134. package/src/qti/v2_2/imsqti_result_v2p2.ts +3 -0
  135. package/src/qti/v2_2/imsqti_usagedata_v2p2.ts +3 -0
  136. package/src/qti/v2_2/imsqti_v2p2p4.ts +76 -0
  137. package/src/qti/v2_2/imsqtiv2p2p4_html5_v1p0.ts +8 -0
  138. package/src/qti/v2_2/index.ts +59 -0
  139. package/src/qti/v2_2/qtiv2p2_csm_v2p2.ts +4 -0
  140. package/src/qti/v2_2/qtiv2p2_imscpv1p2_v1p0.ts +3 -0
  141. package/src/qti/v2_2/schemas.ts +19 -0
  142. package/src/qti/v2_2/shared.ts +3 -0
  143. package/src/qti/v3_0_1/assessment-internal.ts +1509 -0
  144. package/src/qti/v3_0_1/imsqti_asiv3p0p1_v1p0.ts +57 -0
  145. package/src/qti/v3_0_1/imsqti_itemv3p0p1_v1p0.ts +60 -0
  146. package/src/qti/v3_0_1/imsqti_metadatav3p0_v1p0.ts +73 -0
  147. package/src/qti/v3_0_1/imsqti_outcomev3p0p1_v1p0.ts +11 -0
  148. package/src/qti/v3_0_1/imsqti_responseprocessingv3p0p1_v1p0.ts +17 -0
  149. package/src/qti/v3_0_1/imsqti_resultv3p0_v1p0.ts +222 -0
  150. package/src/qti/v3_0_1/imsqti_sectionv3p0p1_v1p0.ts +15 -0
  151. package/src/qti/v3_0_1/imsqti_stimulusv3p0p1_v1p0.ts +15 -0
  152. package/src/qti/v3_0_1/imsqti_testv3p0p1_v1p0.ts +49 -0
  153. package/src/qti/v3_0_1/imsqti_usagedatav3p0_v1p0.ts +77 -0
  154. package/src/qti/v3_0_1/imsqtiv3p0_afa3p0pnp_v1p0.ts +269 -0
  155. package/src/qti/v3_0_1/index.ts +50 -0
  156. package/src/qti/v3_0_1/processing-internal.ts +667 -0
  157. package/src/qti/v3_0_1/shared.ts +146 -0
  158. package/src/qti/v3_0_1/variables-internal.ts +274 -0
  159. package/src/shared/imsx-status.ts +49 -0
  160. package/src/summary.ts +70 -0
  161. package/src/vc-data-model/v2_0/index.ts +27 -0
  162. package/src/vc-data-model/v2_0/shared.ts +206 -0
  163. package/src/xapi/index.ts +12 -0
  164. package/src/xapi/shared.ts +444 -0
  165. package/src/xapi/v1_0_3/index.ts +169 -0
  166. package/src/xapi/v2_0/index.ts +256 -0
  167. package/test/caliper-v1_2.test.ts +270 -0
  168. package/test/case-v1_1.test.ts +147 -0
  169. package/test/cat-v1_0.test.ts +338 -0
  170. package/test/cc-v1_4.test.ts +239 -0
  171. package/test/clr-v2_0.test.ts +225 -0
  172. package/test/cmi5-v1_0.test.ts +196 -0
  173. package/test/contracts.test.ts +125 -0
  174. package/test/fixtures/cmi5/extended-cmi5.xml +72 -0
  175. package/test/fixtures/cmi5/simple-cmi5.xml +26 -0
  176. package/test/lti.test.ts +146 -0
  177. package/test/oneroster-v1_2.test.ts +234 -0
  178. package/test/open-badges-v3_0.test.ts +144 -0
  179. package/test/qti-v2_1.test.ts +146 -0
  180. package/test/qti-v2_2.test.ts +154 -0
  181. package/test/qti-v3_0_1.test.ts +576 -0
  182. package/test/schema-examples.test.ts +101 -0
  183. package/test/vc-data-model-v2_0.test.ts +63 -0
  184. package/test/xapi.test.ts +384 -0
  185. package/tsconfig.json +7 -0
  186. package/vc-data-model-v2_0-zod-templates.md +43 -0
  187. package/xapi-zod-templates.md +95 -0
@@ -0,0 +1,134 @@
1
+ import { z } from "zod";
2
+
3
+ function strictObject<T extends z.ZodRawShape>(shape: T) {
4
+ return z.object(shape).strict();
5
+ }
6
+
7
+ const UriSchema = z.string().regex(/^[a-zA-Z][a-zA-Z0-9+.-]*:.+$/u);
8
+
9
+ export const Cmi5LanguageStringSchema = strictObject({
10
+ lang: z.string().min(1).optional(),
11
+ value: z.string(),
12
+ });
13
+
14
+ export const Cmi5TextSchema = strictObject({
15
+ langstrings: z.array(Cmi5LanguageStringSchema).min(1),
16
+ });
17
+
18
+ export const Cmi5ObjectiveSchema = strictObject({
19
+ id: UriSchema,
20
+ title: Cmi5TextSchema,
21
+ description: Cmi5TextSchema,
22
+ });
23
+
24
+ export const Cmi5ObjectiveReferenceSchema = strictObject({
25
+ idref: UriSchema,
26
+ });
27
+
28
+ export const Cmi5KeywordReferenceSchema = strictObject({
29
+ idref: UriSchema,
30
+ });
31
+
32
+ export const Cmi5KeywordDefinitionSchema = strictObject({
33
+ id: UriSchema,
34
+ title: Cmi5TextSchema,
35
+ description: Cmi5TextSchema.optional(),
36
+ });
37
+
38
+ export const Cmi5KeywordExtensionSchema = strictObject({
39
+ keywords: z.array(Cmi5KeywordDefinitionSchema).min(1),
40
+ });
41
+
42
+ let Cmi5BlockSchema: z.ZodTypeAny;
43
+
44
+ export const Cmi5AuSchema = strictObject({
45
+ id: UriSchema,
46
+ title: Cmi5TextSchema,
47
+ description: Cmi5TextSchema,
48
+ objectives: z.array(Cmi5ObjectiveReferenceSchema).min(1).optional(),
49
+ url: UriSchema,
50
+ launchParameters: z.string().optional(),
51
+ entitlementKey: z.string().optional(),
52
+ moveOn: z.enum(["NotApplicable", "Passed", "Completed", "CompletedAndPassed", "CompletedOrPassed"]).optional(),
53
+ masteryScore: z.number().min(0).max(1).optional(),
54
+ launchMethod: z.enum(["AnyWindow", "OwnWindow"]).optional(),
55
+ activityType: UriSchema.optional(),
56
+ keywords: z.array(Cmi5KeywordReferenceSchema).min(1).optional(),
57
+ });
58
+
59
+ export const Cmi5CourseStructureItemSchema = z.lazy(() => z.union([Cmi5AuSchema, Cmi5BlockSchema]));
60
+
61
+ Cmi5BlockSchema = strictObject({
62
+ id: UriSchema,
63
+ title: Cmi5TextSchema,
64
+ description: Cmi5TextSchema,
65
+ objectives: z.array(Cmi5ObjectiveReferenceSchema).min(1).optional(),
66
+ children: z.array(Cmi5CourseStructureItemSchema).min(1),
67
+ });
68
+
69
+ export const Cmi5CourseSchema = strictObject({
70
+ id: UriSchema,
71
+ title: Cmi5TextSchema,
72
+ description: Cmi5TextSchema,
73
+ });
74
+
75
+ export const Cmi5CourseStructureSchema = strictObject({
76
+ course: Cmi5CourseSchema,
77
+ objectives: z.array(Cmi5ObjectiveSchema).min(1).optional(),
78
+ children: z.array(Cmi5CourseStructureItemSchema).min(1),
79
+ });
80
+
81
+ export const Cmi5CourseStructureDocumentSchema = strictObject({
82
+ courseStructure: Cmi5CourseStructureSchema,
83
+ keywords: Cmi5KeywordExtensionSchema.optional(),
84
+ });
85
+
86
+ export namespace Cmi5V1_0 {
87
+ export namespace Schemas {
88
+ export const LanguageString = Cmi5LanguageStringSchema;
89
+ export const Text = Cmi5TextSchema;
90
+ export const Objective = Cmi5ObjectiveSchema;
91
+ export const ObjectiveReference = Cmi5ObjectiveReferenceSchema;
92
+ export const KeywordReference = Cmi5KeywordReferenceSchema;
93
+ export const KeywordDefinition = Cmi5KeywordDefinitionSchema;
94
+ export const KeywordExtension = Cmi5KeywordExtensionSchema;
95
+ export const Course = Cmi5CourseSchema;
96
+ export const Au = Cmi5AuSchema;
97
+ export const Block = Cmi5BlockSchema;
98
+ export const CourseStructure = Cmi5CourseStructureSchema;
99
+ export const CourseStructureDocument = Cmi5CourseStructureDocumentSchema;
100
+ }
101
+ }
102
+
103
+ export const Schemas = Cmi5V1_0.Schemas;
104
+
105
+ export type Cmi5V1_0Schemas = typeof Cmi5V1_0.Schemas;
106
+
107
+ export const Cmi5V1_0DerivedZodTemplates = {
108
+ description: "cmi5 Quartz Zod schemas for course-structure XML and keyword extension documents",
109
+ specLinks: {
110
+ main: "https://github.com/AICC/CMI-5_Spec_Current/tree/quartz",
111
+ courseStructure: "https://github.com/AICC/CMI-5_Spec_Current/blob/quartz/v1/CourseStructure.xsd",
112
+ keywordExtension: "https://github.com/AICC/CMI-5_Spec_Current/blob/quartz/v1/examples/extended-cmi5.xsd",
113
+ },
114
+ scope: "Course structure XML plus keyword extension documents",
115
+ notes: [
116
+ "This bundle models the official cmi5 course-structure XSD and keyword extension XSD, not the runtime xAPI launch flow.",
117
+ "The XML examples in the Quartz repository map cleanly to a normalized object model with course, objectives, blocks, AUs, and keyword dictionaries.",
118
+ ],
119
+ } as const;
120
+
121
+ export const DerivedZodTemplates = Cmi5V1_0DerivedZodTemplates;
122
+ // Inferred types from exported Zod validators.
123
+ export type Cmi5LanguageString = z.infer<typeof Cmi5LanguageStringSchema>;
124
+ export type Cmi5Text = z.infer<typeof Cmi5TextSchema>;
125
+ export type Cmi5Objective = z.infer<typeof Cmi5ObjectiveSchema>;
126
+ export type Cmi5ObjectiveReference = z.infer<typeof Cmi5ObjectiveReferenceSchema>;
127
+ export type Cmi5KeywordReference = z.infer<typeof Cmi5KeywordReferenceSchema>;
128
+ export type Cmi5KeywordDefinition = z.infer<typeof Cmi5KeywordDefinitionSchema>;
129
+ export type Cmi5KeywordExtension = z.infer<typeof Cmi5KeywordExtensionSchema>;
130
+ export type Cmi5Au = z.infer<typeof Cmi5AuSchema>;
131
+ export type Cmi5CourseStructureItem = z.infer<typeof Cmi5CourseStructureItemSchema>;
132
+ export type Cmi5Course = z.infer<typeof Cmi5CourseSchema>;
133
+ export type Cmi5CourseStructure = z.infer<typeof Cmi5CourseStructureSchema>;
134
+ export type Cmi5CourseStructureDocument = z.infer<typeof Cmi5CourseStructureDocumentSchema>;
@@ -0,0 +1,26 @@
1
+ import { z } from "zod";
2
+
3
+ import { NonEmptyStringSchema, XmlExtensionNodeListSchema, strictObject } from "./shared";
4
+
5
+ export const CommonCartridgeAuthorizationAccessSchema = z.enum(["cartridge", "resource"]);
6
+
7
+ export const CommonCartridgeAuthorizationSchema = strictObject({
8
+ cartridgeId: NonEmptyStringSchema,
9
+ webservice: z.string().optional(),
10
+ });
11
+
12
+ export const CommonCartridgeAuthorizationsSchema = strictObject({
13
+ authorization: CommonCartridgeAuthorizationSchema,
14
+ access: CommonCartridgeAuthorizationAccessSchema,
15
+ import: z.boolean().optional(),
16
+ extensions: XmlExtensionNodeListSchema.optional(),
17
+ });
18
+
19
+ export const CommonCartridgeAuthorizationsDocumentSchema = strictObject({
20
+ authorizations: CommonCartridgeAuthorizationsSchema,
21
+ });
22
+ // Inferred types from exported Zod validators.
23
+ export type CommonCartridgeAuthorizationAccess = z.infer<typeof CommonCartridgeAuthorizationAccessSchema>;
24
+ export type CommonCartridgeAuthorization = z.infer<typeof CommonCartridgeAuthorizationSchema>;
25
+ export type CommonCartridgeAuthorizations = z.infer<typeof CommonCartridgeAuthorizationsSchema>;
26
+ export type CommonCartridgeAuthorizationsDocument = z.infer<typeof CommonCartridgeAuthorizationsDocumentSchema>;
@@ -0,0 +1,352 @@
1
+ import { z } from "zod";
2
+
3
+ import { CurriculumStandardsMetadataSetSchema } from "./ccv1p3_imscsmd_v1p0";
4
+ import { CommonCartridgeAuthorizationsSchema } from "./ccv1p3_imsccauth_v1p3";
5
+ import { LomManifestSchema } from "./ccv1p3_lommanifest_v1p0";
6
+ import { LomResourceSchema } from "./ccv1p3_lomresource_v1p0";
7
+ import {
8
+ NonEmptyStringSchema,
9
+ UriReferenceSchema,
10
+ XmlExtensionNodeListSchema,
11
+ addIssue,
12
+ asArray,
13
+ collectDuplicates,
14
+ strictObject,
15
+ } from "./shared";
16
+
17
+ export const CommonCartridgeResourceTypeSchema = z.enum([
18
+ "webcontent",
19
+ "imsqti_xmlv1p2/imscc_xmlv1p3/assessment",
20
+ "imsqti_xmlv1p2/imscc_xmlv1p3/question-bank",
21
+ "associatedcontent/imscc_xmlv1p3/learning-application-resource",
22
+ "imsdt_xmlv1p3",
23
+ "imswl_xmlv1p3",
24
+ "imsbasiclti_xmlv1p3",
25
+ "idpfepub_epubv3p0",
26
+ "imsapip_zipv1p0",
27
+ "imsiwb_iwbv1p0",
28
+ "assignment_xmlv1p0",
29
+ ]);
30
+
31
+ export const CommonCartridgeIntendedUseSchema = z.enum(["assignment", "lessonplan", "syllabus", "unspecified"]);
32
+
33
+ export const CommonCartridgeGenericMetadataSchema = strictObject({
34
+ extensions: XmlExtensionNodeListSchema.optional(),
35
+ });
36
+
37
+ export const CommonCartridgeDependencySchema = strictObject({
38
+ identifierref: NonEmptyStringSchema,
39
+ });
40
+
41
+ export const CommonCartridgeFileSchema = strictObject({
42
+ href: UriReferenceSchema,
43
+ metadata: CommonCartridgeGenericMetadataSchema.optional(),
44
+ });
45
+
46
+ export const CommonCartridgeItemSchema: z.ZodTypeAny = z.lazy(() =>
47
+ strictObject({
48
+ identifier: NonEmptyStringSchema,
49
+ identifierref: NonEmptyStringSchema.optional(),
50
+ title: z.string(),
51
+ item: z.array(CommonCartridgeItemSchema).optional(),
52
+ metadata: CommonCartridgeGenericMetadataSchema.optional(),
53
+ }),
54
+ );
55
+
56
+ export const CommonCartridgeItemOrgSchema: z.ZodTypeAny = z.lazy(() =>
57
+ strictObject({
58
+ identifier: NonEmptyStringSchema,
59
+ item: z.array(CommonCartridgeItemSchema).optional(),
60
+ metadata: CommonCartridgeGenericMetadataSchema.optional(),
61
+ }),
62
+ );
63
+
64
+ export const CommonCartridgeOrganizationSchema = strictObject({
65
+ identifier: NonEmptyStringSchema,
66
+ structure: z.literal("rooted-hierarchy"),
67
+ title: z.string().optional(),
68
+ item: CommonCartridgeItemOrgSchema,
69
+ metadata: CommonCartridgeGenericMetadataSchema.optional(),
70
+ });
71
+
72
+ export const CommonCartridgeOrganizationsSchema = strictObject({
73
+ organization: CommonCartridgeOrganizationSchema.optional(),
74
+ });
75
+
76
+ export const CommonCartridgeManifestMetadataSchema = strictObject({
77
+ schema: z.enum(["IMS Common Cartridge", "IMS Thin Common Cartridge"]),
78
+ schemaversion: z.literal("1.3.0"),
79
+ lom: LomManifestSchema,
80
+ curriculumStandardsMetadataSet: CurriculumStandardsMetadataSetSchema.optional(),
81
+ });
82
+
83
+ export const CommonCartridgeResourceMetadataSchema = strictObject({
84
+ schema: z.string().optional(),
85
+ schemaversion: z.string().optional(),
86
+ lom: LomResourceSchema.optional(),
87
+ curriculumStandardsMetadataSet: z.array(CurriculumStandardsMetadataSetSchema).optional(),
88
+ });
89
+
90
+ export const CommonCartridgeResourceSchema = strictObject({
91
+ identifier: NonEmptyStringSchema,
92
+ type: CommonCartridgeResourceTypeSchema,
93
+ href: UriReferenceSchema.optional(),
94
+ xmlBase: z.string().optional(),
95
+ intendeduse: CommonCartridgeIntendedUseSchema.optional(),
96
+ // `protected` is imported from `imsccauth` as a global `xs:boolean` attribute. The manifest
97
+ // profile applies a schema-level default of `false`, but parsed XML objects do not reliably
98
+ // materialize XSD defaults, so the normalized JS model keeps it optional.
99
+ protected: z.boolean().optional(),
100
+ metadata: CommonCartridgeResourceMetadataSchema.optional(),
101
+ file: z.array(CommonCartridgeFileSchema).optional(),
102
+ dependency: z.array(CommonCartridgeDependencySchema).optional(),
103
+ extensions: XmlExtensionNodeListSchema.optional(),
104
+ });
105
+
106
+ export const CommonCartridgeResourcesSchema = strictObject({
107
+ xmlBase: z.string().optional(),
108
+ resource: z.array(CommonCartridgeResourceSchema).optional(),
109
+ });
110
+
111
+ export const CommonCartridgeManifestRawSchema = strictObject({
112
+ identifier: NonEmptyStringSchema,
113
+ xmlBase: z.string().optional(),
114
+ metadata: CommonCartridgeManifestMetadataSchema,
115
+ organizations: CommonCartridgeOrganizationsSchema,
116
+ resources: CommonCartridgeResourcesSchema,
117
+ authorizations: CommonCartridgeAuthorizationsSchema.optional(),
118
+ });
119
+
120
+ type CommonCartridgeTraversalItem = {
121
+ identifier: string;
122
+ identifierref?: string;
123
+ item?: CommonCartridgeTraversalItem[];
124
+ };
125
+
126
+ type CommonCartridgeTraversalManifest = {
127
+ organizations: {
128
+ organization?: {
129
+ item: {
130
+ item?: CommonCartridgeTraversalItem[];
131
+ };
132
+ };
133
+ };
134
+ };
135
+
136
+ function walkCommonCartridgeItems(
137
+ item: CommonCartridgeTraversalItem,
138
+ visit: (candidate: CommonCartridgeTraversalItem) => void,
139
+ ) {
140
+ visit(item);
141
+ for (const child of asArray(item.item)) {
142
+ walkCommonCartridgeItems(child, visit);
143
+ }
144
+ }
145
+
146
+ function collectCommonCartridgeItems(manifest: CommonCartridgeTraversalManifest): CommonCartridgeTraversalItem[] {
147
+ const items: CommonCartridgeTraversalItem[] = [];
148
+ const rootItem = manifest.organizations.organization?.item;
149
+
150
+ if (!rootItem) {
151
+ return items;
152
+ }
153
+
154
+ for (const child of asArray(rootItem.item)) {
155
+ walkCommonCartridgeItems(child, (candidate) => {
156
+ items.push(candidate);
157
+ });
158
+ }
159
+
160
+ return items;
161
+ }
162
+
163
+ const resourceTypesThatForbidHref = new Set<string>([
164
+ "imsdt_xmlv1p3",
165
+ "imswl_xmlv1p3",
166
+ "imsqti_xmlv1p2/imscc_xmlv1p3/assessment",
167
+ "imsqti_xmlv1p2/imscc_xmlv1p3/question-bank",
168
+ ]);
169
+
170
+ const resourceTypesThatForbidAllDependencies = new Set<string>(["imswl_xmlv1p3"]);
171
+
172
+ const prohibitedDependencyTargetsByType: Record<string, ReadonlySet<string>> = {
173
+ imsdt_xmlv1p3: new Set([
174
+ "imsdt_xmlv1p3",
175
+ "imswl_xmlv1p3",
176
+ "imsqti_xmlv1p2/imscc_xmlv1p3/assessment",
177
+ "imsqti_xmlv1p2/imscc_xmlv1p3/question-bank",
178
+ "imsbasiclti_xmlv1p3",
179
+ ]),
180
+ "imsqti_xmlv1p2/imscc_xmlv1p3/assessment": new Set([
181
+ "imsdt_xmlv1p3",
182
+ "imswl_xmlv1p3",
183
+ "imsqti_xmlv1p2/imscc_xmlv1p3/assessment",
184
+ "imsqti_xmlv1p2/imscc_xmlv1p3/question-bank",
185
+ "imsbasiclti_xmlv1p3",
186
+ ]),
187
+ "imsqti_xmlv1p2/imscc_xmlv1p3/question-bank": new Set([
188
+ "imsdt_xmlv1p3",
189
+ "imswl_xmlv1p3",
190
+ "imsqti_xmlv1p2/imscc_xmlv1p3/assessment",
191
+ "imsqti_xmlv1p2/imscc_xmlv1p3/question-bank",
192
+ "imsbasiclti_xmlv1p3",
193
+ ]),
194
+ webcontent: new Set([
195
+ "imsdt_xmlv1p3",
196
+ "imswl_xmlv1p3",
197
+ "imsqti_xmlv1p2/imscc_xmlv1p3/assessment",
198
+ "imsqti_xmlv1p2/imscc_xmlv1p3/question-bank",
199
+ "associatedcontent/imscc_xmlv1p3/learning-application-resource",
200
+ "imsbasiclti_xmlv1p3",
201
+ ]),
202
+ "associatedcontent/imscc_xmlv1p3/learning-application-resource": new Set([
203
+ "imsdt_xmlv1p3",
204
+ "imswl_xmlv1p3",
205
+ "imsqti_xmlv1p2/imscc_xmlv1p3/assessment",
206
+ "imsqti_xmlv1p2/imscc_xmlv1p3/question-bank",
207
+ "associatedcontent/imscc_xmlv1p3/learning-application-resource",
208
+ "imsbasiclti_xmlv1p3",
209
+ ]),
210
+ imsbasiclti_xmlv1p3: new Set([
211
+ "imsdt_xmlv1p3",
212
+ "imswl_xmlv1p3",
213
+ "imsqti_xmlv1p2/imscc_xmlv1p3/assessment",
214
+ "imsqti_xmlv1p2/imscc_xmlv1p3/question-bank",
215
+ "webcontent",
216
+ "imsbasiclti_xmlv1p3",
217
+ ]),
218
+ };
219
+
220
+ export const CommonCartridgeManifestProfileSchema = CommonCartridgeManifestRawSchema.superRefine(
221
+ (manifest, context) => {
222
+ const resources = asArray(manifest.resources.resource);
223
+ const resourcesByIdentifier = new Map(resources.map((resource) => [resource.identifier, resource] as const));
224
+
225
+ for (const duplicate of collectDuplicates(resources.map((resource) => resource.identifier))) {
226
+ addIssue(context, ["resources", "resource"], `Duplicate resource identifier: ${duplicate}`);
227
+ }
228
+
229
+ resources.forEach((resource, resourceIndex) => {
230
+ const files = asArray(resource.file);
231
+ const dependencies = asArray(resource.dependency);
232
+
233
+ for (const duplicate of collectDuplicates(files.map((file) => file.href))) {
234
+ addIssue(
235
+ context,
236
+ ["resources", "resource", resourceIndex, "file"],
237
+ `Resource ${resource.identifier} contains duplicate file href values: ${duplicate}`,
238
+ );
239
+ }
240
+
241
+ for (const duplicate of collectDuplicates(dependencies.map((dependency) => dependency.identifierref))) {
242
+ addIssue(
243
+ context,
244
+ ["resources", "resource", resourceIndex, "dependency"],
245
+ `Resource ${resource.identifier} contains duplicate dependency identifierref values: ${duplicate}`,
246
+ );
247
+ }
248
+
249
+ if (resourceTypesThatForbidHref.has(resource.type) && resource.href) {
250
+ addIssue(
251
+ context,
252
+ ["resources", "resource", resourceIndex, "href"],
253
+ `Resources of type ${resource.type} must not carry href in the active Schematron profile.`,
254
+ );
255
+ }
256
+
257
+ if (resource.href && files.length === 0) {
258
+ addIssue(
259
+ context,
260
+ ["resources", "resource", resourceIndex, "file"],
261
+ `Resource ${resource.identifier} has href but no file entries.`,
262
+ );
263
+ }
264
+
265
+ if (resource.href && !files.some((file) => file.href === resource.href)) {
266
+ addIssue(
267
+ context,
268
+ ["resources", "resource", resourceIndex, "href"],
269
+ `Resource ${resource.identifier} has href ${resource.href} but no matching file/@href.`,
270
+ );
271
+ }
272
+
273
+ if (resourceTypesThatForbidAllDependencies.has(resource.type) && dependencies.length > 0) {
274
+ addIssue(
275
+ context,
276
+ ["resources", "resource", resourceIndex, "dependency"],
277
+ `Resources of type ${resource.type} must not contain dependency entries in the active Schematron profile.`,
278
+ );
279
+ }
280
+
281
+ for (const [dependencyIndex, dependency] of dependencies.entries()) {
282
+ if (dependency.identifierref === resource.identifier) {
283
+ addIssue(
284
+ context,
285
+ ["resources", "resource", resourceIndex, "dependency", dependencyIndex, "identifierref"],
286
+ `Resource ${resource.identifier} has a circular dependency on itself.`,
287
+ );
288
+ }
289
+
290
+ const target = resourcesByIdentifier.get(dependency.identifierref);
291
+ const prohibitedTargets = prohibitedDependencyTargetsByType[resource.type];
292
+
293
+ if (target && prohibitedTargets?.has(target.type)) {
294
+ addIssue(
295
+ context,
296
+ ["resources", "resource", resourceIndex, "dependency", dependencyIndex, "identifierref"],
297
+ `Resource ${resource.identifier} (${resource.type}) must not depend on ${target.identifier} (${target.type}).`,
298
+ );
299
+ }
300
+ }
301
+ });
302
+
303
+ const items = collectCommonCartridgeItems(manifest as CommonCartridgeTraversalManifest);
304
+ const questionBankIdentifiers = new Set(
305
+ resources
306
+ .filter((resource) => resource.type === "imsqti_xmlv1p2/imscc_xmlv1p3/question-bank")
307
+ .map((resource) => resource.identifier),
308
+ );
309
+
310
+ items.forEach((item, itemIndex) => {
311
+ if (item.identifierref && questionBankIdentifiers.has(item.identifierref)) {
312
+ addIssue(
313
+ context,
314
+ ["organizations", "organization", "item", itemIndex, "identifierref"],
315
+ `Item ${item.identifier} must not reference a question-bank resource.`,
316
+ );
317
+ }
318
+
319
+ if (item.identifierref && asArray(item.item).length > 0) {
320
+ addIssue(
321
+ context,
322
+ ["organizations", "organization", "item", itemIndex, "item"],
323
+ `Learning-object item ${item.identifier} must not contain child items when identifierref is present.`,
324
+ );
325
+ }
326
+ });
327
+ },
328
+ );
329
+
330
+ export const CommonCartridgeManifestRawDocumentSchema = strictObject({
331
+ manifest: CommonCartridgeManifestRawSchema,
332
+ });
333
+
334
+ export const CommonCartridgeManifestProfileDocumentSchema = strictObject({
335
+ manifest: CommonCartridgeManifestProfileSchema,
336
+ });
337
+ // Inferred types from exported Zod validators.
338
+ export type CommonCartridgeResourceType = z.infer<typeof CommonCartridgeResourceTypeSchema>;
339
+ export type CommonCartridgeIntendedUse = z.infer<typeof CommonCartridgeIntendedUseSchema>;
340
+ export type CommonCartridgeGenericMetadata = z.infer<typeof CommonCartridgeGenericMetadataSchema>;
341
+ export type CommonCartridgeDependency = z.infer<typeof CommonCartridgeDependencySchema>;
342
+ export type CommonCartridgeFile = z.infer<typeof CommonCartridgeFileSchema>;
343
+ export type CommonCartridgeOrganization = z.infer<typeof CommonCartridgeOrganizationSchema>;
344
+ export type CommonCartridgeOrganizations = z.infer<typeof CommonCartridgeOrganizationsSchema>;
345
+ export type CommonCartridgeManifestMetadata = z.infer<typeof CommonCartridgeManifestMetadataSchema>;
346
+ export type CommonCartridgeResourceMetadata = z.infer<typeof CommonCartridgeResourceMetadataSchema>;
347
+ export type CommonCartridgeResource = z.infer<typeof CommonCartridgeResourceSchema>;
348
+ export type CommonCartridgeResources = z.infer<typeof CommonCartridgeResourcesSchema>;
349
+ export type CommonCartridgeManifestRaw = z.infer<typeof CommonCartridgeManifestRawSchema>;
350
+ export type CommonCartridgeManifestProfile = z.infer<typeof CommonCartridgeManifestProfileSchema>;
351
+ export type CommonCartridgeManifestRawDocument = z.infer<typeof CommonCartridgeManifestRawDocumentSchema>;
352
+ export type CommonCartridgeManifestProfileDocument = z.infer<typeof CommonCartridgeManifestProfileDocumentSchema>;
@@ -0,0 +1,35 @@
1
+ import { z } from "zod";
2
+
3
+ import { NonEmptyStringSchema, strictObject } from "./shared";
4
+
5
+ export const CurriculumStandardsLabelledGUIDSchema = strictObject({
6
+ label: z.string().optional(),
7
+ GUID: NonEmptyStringSchema,
8
+ });
9
+
10
+ export const CurriculumStandardsSetOfGUIDsSchema = strictObject({
11
+ labelledGUID: z.array(CurriculumStandardsLabelledGUIDSchema).min(1),
12
+ region: z.string().optional(),
13
+ version: z.string().optional(),
14
+ });
15
+
16
+ export const CurriculumStandardsMetadataSchema = strictObject({
17
+ setOfGUIDs: z.array(CurriculumStandardsSetOfGUIDsSchema).min(1),
18
+ providerId: z.string().optional(),
19
+ });
20
+
21
+ export const CurriculumStandardsMetadataSetSchema = strictObject({
22
+ curriculumStandardsMetadata: z.array(CurriculumStandardsMetadataSchema).min(1),
23
+ resourceLabel: z.string().optional(),
24
+ resourcePartId: z.string().optional(),
25
+ });
26
+
27
+ export const CurriculumStandardsMetadataSetDocumentSchema = strictObject({
28
+ curriculumStandardsMetadataSet: CurriculumStandardsMetadataSetSchema,
29
+ });
30
+ // Inferred types from exported Zod validators.
31
+ export type CurriculumStandardsLabelledGUID = z.infer<typeof CurriculumStandardsLabelledGUIDSchema>;
32
+ export type CurriculumStandardsSetOfGUIDs = z.infer<typeof CurriculumStandardsSetOfGUIDsSchema>;
33
+ export type CurriculumStandardsMetadata = z.infer<typeof CurriculumStandardsMetadataSchema>;
34
+ export type CurriculumStandardsMetadataSet = z.infer<typeof CurriculumStandardsMetadataSetSchema>;
35
+ export type CurriculumStandardsMetadataSetDocument = z.infer<typeof CurriculumStandardsMetadataSetDocumentSchema>;
@@ -0,0 +1,33 @@
1
+ import { z } from "zod";
2
+
3
+ import { NonEmptyStringSchema, UriReferenceSchema, XmlExtensionNodeListSchema, strictObject } from "./shared";
4
+
5
+ export const DiscussionTopicAttachmentSchema = strictObject({
6
+ href: UriReferenceSchema,
7
+ });
8
+
9
+ export const DiscussionTopicAttachmentsSchema = strictObject({
10
+ attachment: z.array(DiscussionTopicAttachmentSchema).min(1),
11
+ });
12
+
13
+ export const DiscussionTopicTextSchema = strictObject({
14
+ value: z.string(),
15
+ texttype: z.enum(["text/plain", "text/html"]),
16
+ });
17
+
18
+ export const DiscussionTopicSchema = strictObject({
19
+ title: NonEmptyStringSchema,
20
+ text: DiscussionTopicTextSchema,
21
+ attachments: DiscussionTopicAttachmentsSchema.optional(),
22
+ extensions: XmlExtensionNodeListSchema.optional(),
23
+ });
24
+
25
+ export const DiscussionTopicDocumentSchema = strictObject({
26
+ topic: DiscussionTopicSchema,
27
+ });
28
+ // Inferred types from exported Zod validators.
29
+ export type DiscussionTopicAttachment = z.infer<typeof DiscussionTopicAttachmentSchema>;
30
+ export type DiscussionTopicAttachments = z.infer<typeof DiscussionTopicAttachmentsSchema>;
31
+ export type DiscussionTopicText = z.infer<typeof DiscussionTopicTextSchema>;
32
+ export type DiscussionTopic = z.infer<typeof DiscussionTopicSchema>;
33
+ export type DiscussionTopicDocument = z.infer<typeof DiscussionTopicDocumentSchema>;
@@ -0,0 +1,23 @@
1
+ import { z } from "zod";
2
+
3
+ import { NonEmptyStringSchema, UriReferenceSchema, XmlExtensionNodeListSchema, strictObject } from "./shared";
4
+
5
+ export const WebLinkUrlSchema = strictObject({
6
+ href: UriReferenceSchema,
7
+ target: z.string().optional(),
8
+ windowFeatures: z.string().optional(),
9
+ });
10
+
11
+ export const WebLinkSchema = strictObject({
12
+ title: NonEmptyStringSchema,
13
+ url: WebLinkUrlSchema,
14
+ extensions: XmlExtensionNodeListSchema.optional(),
15
+ });
16
+
17
+ export const WebLinkDocumentSchema = strictObject({
18
+ webLink: WebLinkSchema,
19
+ });
20
+ // Inferred types from exported Zod validators.
21
+ export type WebLinkUrl = z.infer<typeof WebLinkUrlSchema>;
22
+ export type WebLink = z.infer<typeof WebLinkSchema>;
23
+ export type WebLinkDocument = z.infer<typeof WebLinkDocumentSchema>;
@@ -0,0 +1,14 @@
1
+ import type { z } from "zod";
2
+ import { strictObject } from "./shared";
3
+ import { LomCcLtiLinkProfileSchemas } from "./lom-internal";
4
+
5
+ export { LomCcLtiLinkProfileSchemas } from "./lom-internal";
6
+
7
+ export const LomCcLtiLinkSchema = LomCcLtiLinkProfileSchemas.LomSchema;
8
+
9
+ export const LomCcLtiLinkDocumentSchema = strictObject({
10
+ lom: LomCcLtiLinkSchema,
11
+ });
12
+ // Inferred types from exported Zod validators.
13
+ export type LomCcLtiLink = z.infer<typeof LomCcLtiLinkSchema>;
14
+ export type LomCcLtiLinkDocument = z.infer<typeof LomCcLtiLinkDocumentSchema>;
@@ -0,0 +1,14 @@
1
+ import type { z } from "zod";
2
+ import { strictObject } from "./shared";
3
+ import { LomManifestProfileSchemas } from "./lom-internal";
4
+
5
+ export { LomManifestProfileSchemas } from "./lom-internal";
6
+
7
+ export const LomManifestSchema = LomManifestProfileSchemas.LomSchema;
8
+
9
+ export const LomManifestDocumentSchema = strictObject({
10
+ lom: LomManifestSchema,
11
+ });
12
+ // Inferred types from exported Zod validators.
13
+ export type LomManifest = z.infer<typeof LomManifestSchema>;
14
+ export type LomManifestDocument = z.infer<typeof LomManifestDocumentSchema>;
@@ -0,0 +1,14 @@
1
+ import type { z } from "zod";
2
+ import { strictObject } from "./shared";
3
+ import { LomResourceProfileSchemas } from "./lom-internal";
4
+
5
+ export { LomResourceProfileSchemas } from "./lom-internal";
6
+
7
+ export const LomResourceSchema = LomResourceProfileSchemas.LomSchema;
8
+
9
+ export const LomResourceDocumentSchema = strictObject({
10
+ lom: LomResourceSchema,
11
+ });
12
+ // Inferred types from exported Zod validators.
13
+ export type LomResource = z.infer<typeof LomResourceSchema>;
14
+ export type LomResourceDocument = z.infer<typeof LomResourceDocumentSchema>;