@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,360 @@
1
+ import { z } from "zod";
2
+
3
+ import { CurriculumStandardsMetadataSetSchema } from "../shared/ccv1p4_imscsmd_v1p1";
4
+ import { CommonCartridgeAuthorizationsSchema } from "../shared/ccv1p4_imsccauth_v1p4";
5
+ import { LomManifestSchema } from "./ccv1p4_lommanifest_v1p0";
6
+ import { LomResourceSchema } from "./ccv1p4_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_xmlv1p4/assessment",
20
+ "imsqti_xmlv1p2/imscc_xmlv1p4/question-bank",
21
+ "associatedcontent/imscc_xmlv1p4/learning-application-resource",
22
+ "imsdt_xmlv1p4",
23
+ "imswl_xmlv1p4",
24
+ "imsbasiclti_xmlv1p4",
25
+ "idpfepub_epubv3p0",
26
+ "imsapip_zipv1p0",
27
+ "imsiwb_iwbv1p0",
28
+ "assignment_xmlv1p0",
29
+ "imsov_xmlv1p0",
30
+ "imsov_zipv1p0",
31
+ "imsqti_zipv3p0",
32
+ ]);
33
+
34
+ export const CommonCartridgeIntendedUseSchema = z.enum(["assignment", "lessonplan", "syllabus", "unspecified"]);
35
+
36
+ export const CommonCartridgeGenericMetadataSchema = strictObject({
37
+ extensions: XmlExtensionNodeListSchema.optional(),
38
+ });
39
+
40
+ export const CommonCartridgeDependencySchema = strictObject({
41
+ identifierref: NonEmptyStringSchema,
42
+ });
43
+
44
+ export const CommonCartridgeFileSchema = strictObject({
45
+ href: UriReferenceSchema,
46
+ metadata: CommonCartridgeGenericMetadataSchema.optional(),
47
+ });
48
+
49
+ export const CommonCartridgeItemSchema: z.ZodTypeAny = z.lazy(() =>
50
+ strictObject({
51
+ identifier: NonEmptyStringSchema,
52
+ identifierref: NonEmptyStringSchema.optional(),
53
+ title: z.string(),
54
+ item: z.array(CommonCartridgeItemSchema).optional(),
55
+ metadata: CommonCartridgeGenericMetadataSchema.optional(),
56
+ }),
57
+ );
58
+
59
+ export const CommonCartridgeItemOrgSchema: z.ZodTypeAny = z.lazy(() =>
60
+ strictObject({
61
+ identifier: NonEmptyStringSchema,
62
+ item: z.array(CommonCartridgeItemSchema).optional(),
63
+ metadata: CommonCartridgeGenericMetadataSchema.optional(),
64
+ }),
65
+ );
66
+
67
+ export const CommonCartridgeOrganizationSchema = strictObject({
68
+ identifier: NonEmptyStringSchema,
69
+ structure: z.literal("rooted-hierarchy"),
70
+ title: z.string().optional(),
71
+ item: CommonCartridgeItemOrgSchema,
72
+ metadata: CommonCartridgeGenericMetadataSchema.optional(),
73
+ });
74
+
75
+ export const CommonCartridgeOrganizationsSchema = strictObject({
76
+ organization: CommonCartridgeOrganizationSchema.optional(),
77
+ });
78
+
79
+ export const CommonCartridgeManifestMetadataSchema = strictObject({
80
+ schema: z.enum([
81
+ "IMS Common Cartridge",
82
+ "IMS K-12 Common Cartridge",
83
+ "IMS Thin Common Cartridge",
84
+ "IMS K-12 Thin Common Cartridge",
85
+ ]),
86
+ schemaversion: z.literal("1.4.0"),
87
+ lom: LomManifestSchema,
88
+ curriculumStandardsMetadataSet: CurriculumStandardsMetadataSetSchema.optional(),
89
+ });
90
+
91
+ export const CommonCartridgeResourceMetadataSchema = strictObject({
92
+ schema: z.string().optional(),
93
+ schemaversion: z.string().optional(),
94
+ lom: LomResourceSchema.optional(),
95
+ curriculumStandardsMetadataSet: z.array(CurriculumStandardsMetadataSetSchema).optional(),
96
+ });
97
+
98
+ export const CommonCartridgeResourceSchema = strictObject({
99
+ identifier: NonEmptyStringSchema,
100
+ type: CommonCartridgeResourceTypeSchema,
101
+ href: UriReferenceSchema.optional(),
102
+ xmlBase: z.string().optional(),
103
+ intendeduse: CommonCartridgeIntendedUseSchema.optional(),
104
+ // `protected` is imported from `imsccauth` as a global `xs:boolean` attribute. The manifest
105
+ // profile applies a schema-level default of `false`, but parsed XML objects do not reliably
106
+ // materialize XSD defaults, so the normalized JS model keeps it optional.
107
+ protected: z.boolean().optional(),
108
+ metadata: CommonCartridgeResourceMetadataSchema.optional(),
109
+ file: z.array(CommonCartridgeFileSchema).optional(),
110
+ dependency: z.array(CommonCartridgeDependencySchema).optional(),
111
+ extensions: XmlExtensionNodeListSchema.optional(),
112
+ });
113
+
114
+ export const CommonCartridgeResourcesSchema = strictObject({
115
+ xmlBase: z.string().optional(),
116
+ resource: z.array(CommonCartridgeResourceSchema).optional(),
117
+ });
118
+
119
+ export const CommonCartridgeManifestRawSchema = strictObject({
120
+ identifier: NonEmptyStringSchema,
121
+ xmlBase: z.string().optional(),
122
+ metadata: CommonCartridgeManifestMetadataSchema,
123
+ organizations: CommonCartridgeOrganizationsSchema,
124
+ resources: CommonCartridgeResourcesSchema,
125
+ authorizations: CommonCartridgeAuthorizationsSchema.optional(),
126
+ });
127
+
128
+ type CommonCartridgeTraversalItem = {
129
+ identifier: string;
130
+ identifierref?: string;
131
+ item?: CommonCartridgeTraversalItem[];
132
+ };
133
+
134
+ type CommonCartridgeTraversalManifest = {
135
+ organizations: {
136
+ organization?: {
137
+ item: {
138
+ item?: CommonCartridgeTraversalItem[];
139
+ };
140
+ };
141
+ };
142
+ };
143
+
144
+ function walkCommonCartridgeItems(
145
+ item: CommonCartridgeTraversalItem,
146
+ visit: (candidate: CommonCartridgeTraversalItem) => void,
147
+ ) {
148
+ visit(item);
149
+ for (const child of asArray(item.item)) {
150
+ walkCommonCartridgeItems(child, visit);
151
+ }
152
+ }
153
+
154
+ function collectCommonCartridgeItems(manifest: CommonCartridgeTraversalManifest): CommonCartridgeTraversalItem[] {
155
+ const items: CommonCartridgeTraversalItem[] = [];
156
+ const rootItem = manifest.organizations.organization?.item;
157
+
158
+ if (!rootItem) {
159
+ return items;
160
+ }
161
+
162
+ for (const child of asArray(rootItem.item)) {
163
+ walkCommonCartridgeItems(child, (candidate) => {
164
+ items.push(candidate);
165
+ });
166
+ }
167
+
168
+ return items;
169
+ }
170
+
171
+ const resourceTypesThatForbidHref = new Set<string>([
172
+ "imsdt_xmlv1p4",
173
+ "imswl_xmlv1p4",
174
+ "imsqti_xmlv1p2/imscc_xmlv1p4/assessment",
175
+ "imsqti_xmlv1p2/imscc_xmlv1p4/question-bank",
176
+ ]);
177
+
178
+ const resourceTypesThatForbidAllDependencies = new Set<string>(["imswl_xmlv1p4"]);
179
+
180
+ const prohibitedDependencyTargetsByType: Record<string, ReadonlySet<string>> = {
181
+ imsdt_xmlv1p4: new Set([
182
+ "imsdt_xmlv1p4",
183
+ "imswl_xmlv1p4",
184
+ "imsqti_xmlv1p2/imscc_xmlv1p4/assessment",
185
+ "imsqti_xmlv1p2/imscc_xmlv1p4/question-bank",
186
+ "imsbasiclti_xmlv1p4",
187
+ ]),
188
+ "imsqti_xmlv1p2/imscc_xmlv1p4/assessment": new Set([
189
+ "imsdt_xmlv1p4",
190
+ "imswl_xmlv1p4",
191
+ "imsqti_xmlv1p2/imscc_xmlv1p4/assessment",
192
+ "imsqti_xmlv1p2/imscc_xmlv1p4/question-bank",
193
+ "imsbasiclti_xmlv1p4",
194
+ ]),
195
+ "imsqti_xmlv1p2/imscc_xmlv1p4/question-bank": new Set([
196
+ "imsdt_xmlv1p4",
197
+ "imswl_xmlv1p4",
198
+ "imsqti_xmlv1p2/imscc_xmlv1p4/assessment",
199
+ "imsqti_xmlv1p2/imscc_xmlv1p4/question-bank",
200
+ "imsbasiclti_xmlv1p4",
201
+ ]),
202
+ webcontent: new Set([
203
+ "imsdt_xmlv1p4",
204
+ "imswl_xmlv1p4",
205
+ "imsqti_xmlv1p2/imscc_xmlv1p4/assessment",
206
+ "imsqti_xmlv1p2/imscc_xmlv1p4/question-bank",
207
+ "associatedcontent/imscc_xmlv1p4/learning-application-resource",
208
+ "imsbasiclti_xmlv1p4",
209
+ ]),
210
+ "associatedcontent/imscc_xmlv1p4/learning-application-resource": new Set([
211
+ "imsdt_xmlv1p4",
212
+ "imswl_xmlv1p4",
213
+ "imsqti_xmlv1p2/imscc_xmlv1p4/assessment",
214
+ "imsqti_xmlv1p2/imscc_xmlv1p4/question-bank",
215
+ "associatedcontent/imscc_xmlv1p4/learning-application-resource",
216
+ "imsbasiclti_xmlv1p4",
217
+ ]),
218
+ imsbasiclti_xmlv1p4: new Set([
219
+ "imsdt_xmlv1p4",
220
+ "imswl_xmlv1p4",
221
+ "imsqti_xmlv1p2/imscc_xmlv1p4/assessment",
222
+ "imsqti_xmlv1p2/imscc_xmlv1p4/question-bank",
223
+ "webcontent",
224
+ "imsbasiclti_xmlv1p4",
225
+ ]),
226
+ };
227
+
228
+ export const CommonCartridgeManifestProfileSchema = CommonCartridgeManifestRawSchema.superRefine(
229
+ (manifest, context) => {
230
+ const resources = asArray(manifest.resources.resource);
231
+ const resourcesByIdentifier = new Map(resources.map((resource) => [resource.identifier, resource] as const));
232
+
233
+ for (const duplicate of collectDuplicates(resources.map((resource) => resource.identifier))) {
234
+ addIssue(context, ["resources", "resource"], `Duplicate resource identifier: ${duplicate}`);
235
+ }
236
+
237
+ resources.forEach((resource, resourceIndex) => {
238
+ const files = asArray(resource.file);
239
+ const dependencies = asArray(resource.dependency);
240
+
241
+ for (const duplicate of collectDuplicates(files.map((file) => file.href))) {
242
+ addIssue(
243
+ context,
244
+ ["resources", "resource", resourceIndex, "file"],
245
+ `Resource ${resource.identifier} contains duplicate file href values: ${duplicate}`,
246
+ );
247
+ }
248
+
249
+ for (const duplicate of collectDuplicates(dependencies.map((dependency) => dependency.identifierref))) {
250
+ addIssue(
251
+ context,
252
+ ["resources", "resource", resourceIndex, "dependency"],
253
+ `Resource ${resource.identifier} contains duplicate dependency identifierref values: ${duplicate}`,
254
+ );
255
+ }
256
+
257
+ if (resourceTypesThatForbidHref.has(resource.type) && resource.href) {
258
+ addIssue(
259
+ context,
260
+ ["resources", "resource", resourceIndex, "href"],
261
+ `Resources of type ${resource.type} must not carry href in the active Schematron profile.`,
262
+ );
263
+ }
264
+
265
+ if (resource.href && files.length === 0) {
266
+ addIssue(
267
+ context,
268
+ ["resources", "resource", resourceIndex, "file"],
269
+ `Resource ${resource.identifier} has href but no file entries.`,
270
+ );
271
+ }
272
+
273
+ if (resource.href && !files.some((file) => file.href === resource.href)) {
274
+ addIssue(
275
+ context,
276
+ ["resources", "resource", resourceIndex, "href"],
277
+ `Resource ${resource.identifier} has href ${resource.href} but no matching file/@href.`,
278
+ );
279
+ }
280
+
281
+ if (resourceTypesThatForbidAllDependencies.has(resource.type) && dependencies.length > 0) {
282
+ addIssue(
283
+ context,
284
+ ["resources", "resource", resourceIndex, "dependency"],
285
+ `Resources of type ${resource.type} must not contain dependency entries in the active Schematron profile.`,
286
+ );
287
+ }
288
+
289
+ for (const [dependencyIndex, dependency] of dependencies.entries()) {
290
+ if (dependency.identifierref === resource.identifier) {
291
+ addIssue(
292
+ context,
293
+ ["resources", "resource", resourceIndex, "dependency", dependencyIndex, "identifierref"],
294
+ `Resource ${resource.identifier} has a circular dependency on itself.`,
295
+ );
296
+ }
297
+
298
+ const target = resourcesByIdentifier.get(dependency.identifierref);
299
+ const prohibitedTargets = prohibitedDependencyTargetsByType[resource.type];
300
+
301
+ if (target && prohibitedTargets?.has(target.type)) {
302
+ addIssue(
303
+ context,
304
+ ["resources", "resource", resourceIndex, "dependency", dependencyIndex, "identifierref"],
305
+ `Resource ${resource.identifier} (${resource.type}) must not depend on ${target.identifier} (${target.type}).`,
306
+ );
307
+ }
308
+ }
309
+ });
310
+
311
+ const items = collectCommonCartridgeItems(manifest as CommonCartridgeTraversalManifest);
312
+ const questionBankIdentifiers = new Set(
313
+ resources
314
+ .filter((resource) => resource.type === "imsqti_xmlv1p2/imscc_xmlv1p4/question-bank")
315
+ .map((resource) => resource.identifier),
316
+ );
317
+
318
+ items.forEach((item, itemIndex) => {
319
+ if (item.identifierref && questionBankIdentifiers.has(item.identifierref)) {
320
+ addIssue(
321
+ context,
322
+ ["organizations", "organization", "item", itemIndex, "identifierref"],
323
+ `Item ${item.identifier} must not reference a question-bank resource.`,
324
+ );
325
+ }
326
+
327
+ if (item.identifierref && asArray(item.item).length > 0) {
328
+ addIssue(
329
+ context,
330
+ ["organizations", "organization", "item", itemIndex, "item"],
331
+ `Learning-object item ${item.identifier} must not contain child items when identifierref is present.`,
332
+ );
333
+ }
334
+ });
335
+ },
336
+ );
337
+
338
+ export const CommonCartridgeManifestRawDocumentSchema = strictObject({
339
+ manifest: CommonCartridgeManifestRawSchema,
340
+ });
341
+
342
+ export const CommonCartridgeManifestProfileDocumentSchema = strictObject({
343
+ manifest: CommonCartridgeManifestProfileSchema,
344
+ });
345
+ // Inferred types from exported Zod validators.
346
+ export type CommonCartridgeResourceType = z.infer<typeof CommonCartridgeResourceTypeSchema>;
347
+ export type CommonCartridgeIntendedUse = z.infer<typeof CommonCartridgeIntendedUseSchema>;
348
+ export type CommonCartridgeGenericMetadata = z.infer<typeof CommonCartridgeGenericMetadataSchema>;
349
+ export type CommonCartridgeDependency = z.infer<typeof CommonCartridgeDependencySchema>;
350
+ export type CommonCartridgeFile = z.infer<typeof CommonCartridgeFileSchema>;
351
+ export type CommonCartridgeOrganization = z.infer<typeof CommonCartridgeOrganizationSchema>;
352
+ export type CommonCartridgeOrganizations = z.infer<typeof CommonCartridgeOrganizationsSchema>;
353
+ export type CommonCartridgeManifestMetadata = z.infer<typeof CommonCartridgeManifestMetadataSchema>;
354
+ export type CommonCartridgeResourceMetadata = z.infer<typeof CommonCartridgeResourceMetadataSchema>;
355
+ export type CommonCartridgeResource = z.infer<typeof CommonCartridgeResourceSchema>;
356
+ export type CommonCartridgeResources = z.infer<typeof CommonCartridgeResourcesSchema>;
357
+ export type CommonCartridgeManifestRaw = z.infer<typeof CommonCartridgeManifestRawSchema>;
358
+ export type CommonCartridgeManifestProfile = z.infer<typeof CommonCartridgeManifestProfileSchema>;
359
+ export type CommonCartridgeManifestRawDocument = z.infer<typeof CommonCartridgeManifestRawDocumentSchema>;
360
+ export type CommonCartridgeManifestProfileDocument = z.infer<typeof CommonCartridgeManifestProfileDocumentSchema>;
@@ -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>;
@@ -0,0 +1,61 @@
1
+ import { z } from "zod";
2
+
3
+ import { NonEmptyStringSchema, UriReferenceSchema, XmlExtensionNodeListSchema, strictObject } from "../shared";
4
+
5
+ export const AssignmentTextTypeSchema = z.enum(["text/plain", "text/html"]);
6
+ export const AssignmentAttachmentRoleSchema = z.enum(["All", "Learner", "Manager", "Instructor"]);
7
+ export const AssignmentSubmissionFormatTypeSchema = z.enum(["text", "html", "url", "file"]);
8
+
9
+ export const AssignmentTextSchema = strictObject({
10
+ value: z.string(),
11
+ texttype: AssignmentTextTypeSchema,
12
+ });
13
+
14
+ export const AssignmentAttachmentSchema = strictObject({
15
+ href: UriReferenceSchema,
16
+ role: AssignmentAttachmentRoleSchema,
17
+ });
18
+
19
+ export const AssignmentAttachmentsSchema = strictObject({
20
+ attachment: z.array(AssignmentAttachmentSchema).min(1),
21
+ });
22
+
23
+ export const AssignmentSubmissionFormatSchema = strictObject({
24
+ type: AssignmentSubmissionFormatTypeSchema,
25
+ });
26
+
27
+ export const AssignmentSubmissionFormatsSchema = strictObject({
28
+ format: z.array(AssignmentSubmissionFormatSchema).min(1),
29
+ });
30
+
31
+ export const AssignmentExtensionsSchema = strictObject({
32
+ platform: z.string().optional(),
33
+ extensions: XmlExtensionNodeListSchema.optional(),
34
+ });
35
+
36
+ export const AssignmentSchema = strictObject({
37
+ identifier: NonEmptyStringSchema,
38
+ title: z.string(),
39
+ text: AssignmentTextSchema.optional(),
40
+ instructor_text: AssignmentTextSchema.optional(),
41
+ attachments: AssignmentAttachmentsSchema.optional(),
42
+ gradable: z.boolean().optional(),
43
+ submission_formats: AssignmentSubmissionFormatsSchema.optional(),
44
+ extensions: AssignmentExtensionsSchema.optional(),
45
+ });
46
+
47
+ export const AssignmentDocumentSchema = strictObject({
48
+ assignment: AssignmentSchema,
49
+ });
50
+ // Inferred types from exported Zod validators.
51
+ export type AssignmentTextType = z.infer<typeof AssignmentTextTypeSchema>;
52
+ export type AssignmentAttachmentRole = z.infer<typeof AssignmentAttachmentRoleSchema>;
53
+ export type AssignmentSubmissionFormatType = z.infer<typeof AssignmentSubmissionFormatTypeSchema>;
54
+ export type AssignmentText = z.infer<typeof AssignmentTextSchema>;
55
+ export type AssignmentAttachment = z.infer<typeof AssignmentAttachmentSchema>;
56
+ export type AssignmentAttachments = z.infer<typeof AssignmentAttachmentsSchema>;
57
+ export type AssignmentSubmissionFormat = z.infer<typeof AssignmentSubmissionFormatSchema>;
58
+ export type AssignmentSubmissionFormats = z.infer<typeof AssignmentSubmissionFormatsSchema>;
59
+ export type AssignmentExtensions = z.infer<typeof AssignmentExtensionsSchema>;
60
+ export type Assignment = z.infer<typeof AssignmentSchema>;
61
+ export type AssignmentDocument = z.infer<typeof AssignmentDocumentSchema>;
@@ -0,0 +1,20 @@
1
+ import type { z } from "zod";
2
+ import { NonEmptyStringSchema, XmlExtensionNodeListSchema, strictObject } from "../shared";
3
+
4
+ export const CpxMetadataSchema = strictObject({
5
+ extensions: XmlExtensionNodeListSchema.optional(),
6
+ });
7
+
8
+ export const CpxVariantSchema = strictObject({
9
+ metadata: CpxMetadataSchema,
10
+ identifier: NonEmptyStringSchema,
11
+ identifierref: NonEmptyStringSchema,
12
+ });
13
+
14
+ export const CpxVariantDocumentSchema = strictObject({
15
+ variant: CpxVariantSchema,
16
+ });
17
+ // Inferred types from exported Zod validators.
18
+ export type CpxMetadata = z.infer<typeof CpxMetadataSchema>;
19
+ export type CpxVariant = z.infer<typeof CpxVariantSchema>;
20
+ export type CpxVariantDocument = z.infer<typeof CpxVariantDocumentSchema>;