@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,476 @@
1
+ import { z } from "zod";
2
+
3
+ import { LowerYesNoSchema, addIssue, looseObject, strictObject } from "./shared";
4
+
5
+ const LomAggregationLevelValueSchema = z.enum(["1", "2", "3", "4"]);
6
+ const LomContextValueSchema = z.enum(["school", "higher education", "training", "other"]);
7
+ const LomDifficultyValueSchema = z.enum(["very easy", "easy", "medium", "difficult", "very difficult"]);
8
+ const LomInteractivityLevelValueSchema = z.enum(["very low", "low", "medium", "high", "very high"]);
9
+ const LomInteractivityTypeValueSchema = z.enum(["active", "expositive", "mixed"]);
10
+ const LomKindValueSchema = z.enum([
11
+ "ispartof",
12
+ "haspart",
13
+ "isversionof",
14
+ "hasversion",
15
+ "isformatof",
16
+ "hasformat",
17
+ "references",
18
+ "isreferencedby",
19
+ "isbasedon",
20
+ "isbasisfor",
21
+ "requires",
22
+ "isrequiredby",
23
+ ]);
24
+ const LomLearningResourceTypeValueSchema = z.enum([
25
+ "exercise",
26
+ "simulation",
27
+ "questionnaire",
28
+ "diagram",
29
+ "figure",
30
+ "graph",
31
+ "index",
32
+ "slide",
33
+ "table",
34
+ "narrative text",
35
+ "exam",
36
+ "experiment",
37
+ "problem statement",
38
+ "self assessment",
39
+ "lecture",
40
+ ]);
41
+ const LomNameValueSchema = z.enum([
42
+ "pc-dos",
43
+ "ms-windows",
44
+ "macos",
45
+ "unix",
46
+ "multi-os",
47
+ "none",
48
+ "any",
49
+ "netscape communicator",
50
+ "ms-internet explorer",
51
+ "opera",
52
+ "amaya",
53
+ ]);
54
+ const LomPurposeValueSchema = z.enum([
55
+ "discipline",
56
+ "idea",
57
+ "prerequisite",
58
+ "educational objective",
59
+ "accessibility restrictions",
60
+ "educational level",
61
+ "skill level",
62
+ "security level",
63
+ "competency",
64
+ ]);
65
+ const LomRoleLifeCycleValueSchema = z.enum([
66
+ "author",
67
+ "publisher",
68
+ "unknown",
69
+ "initiator",
70
+ "terminator",
71
+ "validator",
72
+ "editor",
73
+ "graphical designer",
74
+ "technical implementer",
75
+ "content provider",
76
+ "technical validator",
77
+ "educational validator",
78
+ "script writer",
79
+ "instructional designer",
80
+ "subject matter expert",
81
+ ]);
82
+ const LomRoleMetaMetadataValueSchema = z.enum(["creator", "validator"]);
83
+ const LomSemanticDensityValueSchema = z.enum(["very low", "low", "medium", "high", "very high"]);
84
+ const LomStatusValueSchema = z.enum(["draft", "final", "revised", "unavailable"]);
85
+ const LomStructureValueSchema = z.enum(["atomic", "collection", "networked", "hierarchical", "linear"]);
86
+ const LomTypeValueSchema = z.enum(["operating system", "browser"]);
87
+
88
+ type LomVocabularySchemaConfig = {
89
+ aggregationLevel: z.ZodTypeAny;
90
+ context: z.ZodTypeAny;
91
+ copyrightAndOtherRestrictions: z.ZodTypeAny;
92
+ cost: z.ZodTypeAny;
93
+ difficulty: z.ZodTypeAny;
94
+ intendedEndUserRole: z.ZodTypeAny;
95
+ interactivityLevel: z.ZodTypeAny;
96
+ interactivityType: z.ZodTypeAny;
97
+ kind: z.ZodTypeAny;
98
+ learningResourceType: z.ZodTypeAny;
99
+ name: z.ZodTypeAny;
100
+ purpose: z.ZodTypeAny;
101
+ roleLifeCycle: z.ZodTypeAny;
102
+ roleMetaMetadata: z.ZodTypeAny;
103
+ semanticDensity: z.ZodTypeAny;
104
+ status: z.ZodTypeAny;
105
+ structure: z.ZodTypeAny;
106
+ type: z.ZodTypeAny;
107
+ };
108
+
109
+ function createLomProfileSchemas(config: {
110
+ allowExtensions: boolean;
111
+ values: LomVocabularySchemaConfig;
112
+ requirements?: {
113
+ requireGeneral?: boolean;
114
+ requireGeneralTitle?: boolean;
115
+ requireGeneralKeyword?: boolean;
116
+ requireEducational?: boolean;
117
+ requireEducationalIntendedEndUserRole?: boolean;
118
+ requireEducationalTypicalAgeRange?: boolean;
119
+ };
120
+ }) {
121
+ const object = config.allowExtensions ? looseObject : strictObject;
122
+
123
+ const LanguageStringSchema = object({
124
+ value: z.string(),
125
+ language: z.string().optional(),
126
+ });
127
+
128
+ const LangStringSchema = object({
129
+ string: z.array(LanguageStringSchema),
130
+ });
131
+
132
+ const vocabulary = (valueSchema: z.ZodTypeAny) =>
133
+ object({
134
+ source: z.string().optional(),
135
+ value: valueSchema.optional(),
136
+ });
137
+
138
+ const AggregationLevelSchema = vocabulary(config.values.aggregationLevel);
139
+ const ContextSchema = vocabulary(config.values.context);
140
+ const CopyrightAndOtherRestrictionsSchema = vocabulary(config.values.copyrightAndOtherRestrictions);
141
+ const CostSchema = vocabulary(config.values.cost);
142
+ const DifficultySchema = vocabulary(config.values.difficulty);
143
+ const IntendedEndUserRoleSchema = vocabulary(config.values.intendedEndUserRole);
144
+ const InteractivityLevelSchema = vocabulary(config.values.interactivityLevel);
145
+ const InteractivityTypeSchema = vocabulary(config.values.interactivityType);
146
+ const KindSchema = vocabulary(config.values.kind);
147
+ const LearningResourceTypeSchema = vocabulary(config.values.learningResourceType);
148
+ const NameSchema = vocabulary(config.values.name);
149
+ const PurposeSchema = vocabulary(config.values.purpose);
150
+ const RoleLifeCycleSchema = vocabulary(config.values.roleLifeCycle);
151
+ const RoleMetaMetadataSchema = vocabulary(config.values.roleMetaMetadata);
152
+ const SemanticDensitySchema = vocabulary(config.values.semanticDensity);
153
+ const StatusSchema = vocabulary(config.values.status);
154
+ const StructureSchema = vocabulary(config.values.structure);
155
+ const TypeSchema = vocabulary(config.values.type);
156
+
157
+ const IdentifierSchema = object({
158
+ catalog: z.string().optional(),
159
+ entry: z.string().optional(),
160
+ });
161
+
162
+ const DateTimeSchema = object({
163
+ dateTime: z.string().optional(),
164
+ description: LangStringSchema.optional(),
165
+ });
166
+
167
+ const ContributeLifeCycleSchema = object({
168
+ role: RoleLifeCycleSchema.optional(),
169
+ entity: z.array(z.string()).optional(),
170
+ date: DateTimeSchema.optional(),
171
+ });
172
+
173
+ const ContributeMetaMetadataSchema = object({
174
+ role: RoleMetaMetadataSchema.optional(),
175
+ entity: z.array(z.string()).optional(),
176
+ date: DateTimeSchema.optional(),
177
+ });
178
+
179
+ const DurationSchema = object({
180
+ duration: z.string().optional(),
181
+ description: LangStringSchema.optional(),
182
+ });
183
+
184
+ const ResourceSchema = object({
185
+ identifier: z.array(IdentifierSchema).optional(),
186
+ description: z.array(LangStringSchema).optional(),
187
+ });
188
+
189
+ const RelationSchema = object({
190
+ kind: KindSchema.optional(),
191
+ resource: ResourceSchema.optional(),
192
+ });
193
+
194
+ const OrCompositeSchema = object({
195
+ type: TypeSchema.optional(),
196
+ name: NameSchema.optional(),
197
+ minimumVersion: z.string().optional(),
198
+ maximumVersion: z.string().optional(),
199
+ });
200
+
201
+ const RequirementSchema = object({
202
+ orComposite: z.array(OrCompositeSchema).optional(),
203
+ });
204
+
205
+ const TechnicalSchema = object({
206
+ format: z.array(z.string()).optional(),
207
+ size: z.string().optional(),
208
+ location: z.array(z.string()).optional(),
209
+ requirement: z.array(RequirementSchema).optional(),
210
+ installationRemarks: LangStringSchema.optional(),
211
+ otherPlatformRequirements: LangStringSchema.optional(),
212
+ duration: DurationSchema.optional(),
213
+ });
214
+
215
+ const AnnotationSchema = object({
216
+ entity: z.string().optional(),
217
+ date: DateTimeSchema.optional(),
218
+ description: LangStringSchema.optional(),
219
+ });
220
+
221
+ const TaxonSchema = object({
222
+ id: z.string().optional(),
223
+ entry: LangStringSchema.optional(),
224
+ });
225
+
226
+ const TaxonPathSchema = object({
227
+ source: LangStringSchema.optional(),
228
+ taxon: z.array(TaxonSchema).optional(),
229
+ });
230
+
231
+ const ClassificationSchema = object({
232
+ purpose: PurposeSchema.optional(),
233
+ taxonPath: z.array(TaxonPathSchema).optional(),
234
+ description: LangStringSchema.optional(),
235
+ keyword: z.array(LangStringSchema).optional(),
236
+ });
237
+
238
+ const EducationalSchema = object({
239
+ interactivityType: InteractivityTypeSchema.optional(),
240
+ learningResourceType: z.array(LearningResourceTypeSchema).optional(),
241
+ interactivityLevel: InteractivityLevelSchema.optional(),
242
+ semanticDensity: SemanticDensitySchema.optional(),
243
+ intendedEndUserRole: z.array(IntendedEndUserRoleSchema).optional(),
244
+ context: z.array(ContextSchema).optional(),
245
+ typicalAgeRange: z.array(LangStringSchema).optional(),
246
+ difficulty: DifficultySchema.optional(),
247
+ typicalLearningTime: DurationSchema.optional(),
248
+ description: LangStringSchema.optional(),
249
+ language: z.array(z.string()).optional(),
250
+ });
251
+
252
+ const GeneralSchema = object({
253
+ identifier: z.array(IdentifierSchema).optional(),
254
+ title: LangStringSchema.optional(),
255
+ language: z.array(z.string()).optional(),
256
+ description: z.array(LangStringSchema).optional(),
257
+ keyword: z.array(LangStringSchema).optional(),
258
+ coverage: z.array(LangStringSchema).optional(),
259
+ structure: StructureSchema.optional(),
260
+ aggregationLevel: AggregationLevelSchema.optional(),
261
+ });
262
+
263
+ const LifeCycleSchema = object({
264
+ version: LangStringSchema.optional(),
265
+ status: StatusSchema.optional(),
266
+ contribute: z.array(ContributeLifeCycleSchema).optional(),
267
+ });
268
+
269
+ const MetaMetadataSchema = object({
270
+ identifier: z.array(IdentifierSchema).optional(),
271
+ contribute: z.array(ContributeMetaMetadataSchema).optional(),
272
+ metadataschema: z.array(z.string()).optional(),
273
+ language: z.string().optional(),
274
+ });
275
+
276
+ const RightsSchema = object({
277
+ cost: CostSchema.optional(),
278
+ copyrightAndOtherRestrictions: CopyrightAndOtherRestrictionsSchema.optional(),
279
+ description: LangStringSchema.optional(),
280
+ });
281
+
282
+ const LomSchema = object({
283
+ general: GeneralSchema.optional(),
284
+ lifeCycle: LifeCycleSchema.optional(),
285
+ metaMetadata: MetaMetadataSchema.optional(),
286
+ technical: TechnicalSchema.optional(),
287
+ educational: z.array(EducationalSchema).optional(),
288
+ rights: RightsSchema.optional(),
289
+ relation: z.array(RelationSchema).optional(),
290
+ annotation: z.array(AnnotationSchema).optional(),
291
+ classification: z.array(ClassificationSchema).optional(),
292
+ }).superRefine((lom, context) => {
293
+ const singletonChecks: Array<{ key: keyof typeof lom; label: string }> = [
294
+ { key: "general", label: "general" },
295
+ { key: "lifeCycle", label: "lifeCycle" },
296
+ { key: "metaMetadata", label: "metaMetadata" },
297
+ { key: "technical", label: "technical" },
298
+ { key: "rights", label: "rights" },
299
+ ];
300
+
301
+ for (const check of singletonChecks) {
302
+ const value = lom[check.key];
303
+ if (Array.isArray(value) && value.length > 1) {
304
+ addIssue(
305
+ context,
306
+ [check.key],
307
+ `LOM Schematron treats ${check.label} as 0..1 even though the XSD uses unordered repeated choices.`,
308
+ );
309
+ }
310
+ }
311
+
312
+ const requirements = config.requirements;
313
+ if (!requirements) {
314
+ return;
315
+ }
316
+
317
+ const educational = lom.educational ?? [];
318
+
319
+ if (requirements.requireGeneral && !lom.general) {
320
+ addIssue(context, ["general"], "This LOM profile requires a general block.");
321
+ }
322
+
323
+ if (lom.general) {
324
+ if (requirements.requireGeneralTitle && !lom.general.title) {
325
+ addIssue(context, ["general", "title"], "This LOM profile requires general.title.");
326
+ }
327
+
328
+ if (requirements.requireGeneralKeyword && (!lom.general.keyword || lom.general.keyword.length === 0)) {
329
+ addIssue(context, ["general", "keyword"], "This LOM profile requires at least one general.keyword entry.");
330
+ }
331
+ }
332
+
333
+ if (requirements.requireEducational && educational.length === 0) {
334
+ addIssue(context, ["educational"], "This LOM profile requires at least one educational block.");
335
+ }
336
+
337
+ educational.forEach((block, index) => {
338
+ if (
339
+ requirements.requireEducationalIntendedEndUserRole &&
340
+ (!block.intendedEndUserRole || block.intendedEndUserRole.length === 0)
341
+ ) {
342
+ addIssue(
343
+ context,
344
+ ["educational", index, "intendedEndUserRole"],
345
+ "This LOM profile requires at least one educational.intendedEndUserRole entry.",
346
+ );
347
+ }
348
+
349
+ if (
350
+ requirements.requireEducationalTypicalAgeRange &&
351
+ (!block.typicalAgeRange || block.typicalAgeRange.length === 0)
352
+ ) {
353
+ addIssue(
354
+ context,
355
+ ["educational", index, "typicalAgeRange"],
356
+ "This LOM profile requires at least one educational.typicalAgeRange entry.",
357
+ );
358
+ }
359
+ });
360
+ });
361
+
362
+ return {
363
+ LanguageStringSchema,
364
+ LangStringSchema,
365
+ AggregationLevelSchema,
366
+ ContextSchema,
367
+ CopyrightAndOtherRestrictionsSchema,
368
+ CostSchema,
369
+ DifficultySchema,
370
+ IntendedEndUserRoleSchema,
371
+ InteractivityLevelSchema,
372
+ InteractivityTypeSchema,
373
+ KindSchema,
374
+ LearningResourceTypeSchema,
375
+ NameSchema,
376
+ PurposeSchema,
377
+ RoleLifeCycleSchema,
378
+ RoleMetaMetadataSchema,
379
+ SemanticDensitySchema,
380
+ StatusSchema,
381
+ StructureSchema,
382
+ TypeSchema,
383
+ IdentifierSchema,
384
+ DateTimeSchema,
385
+ ContributeLifeCycleSchema,
386
+ ContributeMetaMetadataSchema,
387
+ DurationSchema,
388
+ ResourceSchema,
389
+ RelationSchema,
390
+ OrCompositeSchema,
391
+ RequirementSchema,
392
+ TechnicalSchema,
393
+ AnnotationSchema,
394
+ TaxonSchema,
395
+ TaxonPathSchema,
396
+ ClassificationSchema,
397
+ EducationalSchema,
398
+ GeneralSchema,
399
+ LifeCycleSchema,
400
+ MetaMetadataSchema,
401
+ RightsSchema,
402
+ LomSchema,
403
+ };
404
+ }
405
+
406
+ const looseLomValueSchema = z.string();
407
+
408
+ function createLooseLomProfileSchemas(requirements?: Parameters<typeof createLomProfileSchemas>[0]["requirements"]) {
409
+ return createLomProfileSchemas({
410
+ allowExtensions: true,
411
+ values: {
412
+ aggregationLevel: looseLomValueSchema,
413
+ context: looseLomValueSchema,
414
+ copyrightAndOtherRestrictions: looseLomValueSchema,
415
+ cost: looseLomValueSchema,
416
+ difficulty: looseLomValueSchema,
417
+ intendedEndUserRole: looseLomValueSchema,
418
+ interactivityLevel: looseLomValueSchema,
419
+ interactivityType: looseLomValueSchema,
420
+ kind: looseLomValueSchema,
421
+ learningResourceType: looseLomValueSchema,
422
+ name: looseLomValueSchema,
423
+ purpose: looseLomValueSchema,
424
+ roleLifeCycle: looseLomValueSchema,
425
+ roleMetaMetadata: looseLomValueSchema,
426
+ semanticDensity: looseLomValueSchema,
427
+ status: looseLomValueSchema,
428
+ structure: looseLomValueSchema,
429
+ type: looseLomValueSchema,
430
+ },
431
+ requirements,
432
+ });
433
+ }
434
+
435
+ export const LomManifestProfileSchemas = createLooseLomProfileSchemas();
436
+ export const LomResourceProfileSchemas = LomManifestProfileSchemas;
437
+ export const LomThinManifestProfileSchemas = LomManifestProfileSchemas;
438
+ export const LomThinResourceProfileSchemas = LomResourceProfileSchemas;
439
+ export const LomK12ManifestProfileSchemas = createLooseLomProfileSchemas({
440
+ requireGeneral: true,
441
+ requireGeneralKeyword: true,
442
+ });
443
+ export const LomK12ResourceProfileSchemas = createLooseLomProfileSchemas({
444
+ requireGeneral: true,
445
+ requireGeneralTitle: true,
446
+ requireGeneralKeyword: true,
447
+ requireEducational: true,
448
+ requireEducationalIntendedEndUserRole: true,
449
+ requireEducationalTypicalAgeRange: true,
450
+ });
451
+ export const LomK12ThinManifestProfileSchemas = LomThinManifestProfileSchemas;
452
+ export const LomK12ThinResourceProfileSchemas = LomThinResourceProfileSchemas;
453
+
454
+ export const LomCcLtiLinkProfileSchemas = createLomProfileSchemas({
455
+ allowExtensions: false,
456
+ values: {
457
+ aggregationLevel: LomAggregationLevelValueSchema,
458
+ context: LomContextValueSchema,
459
+ copyrightAndOtherRestrictions: LowerYesNoSchema,
460
+ cost: LowerYesNoSchema,
461
+ difficulty: LomDifficultyValueSchema,
462
+ intendedEndUserRole: z.enum(["teacher", "author", "learner", "manager"]),
463
+ interactivityLevel: LomInteractivityLevelValueSchema,
464
+ interactivityType: LomInteractivityTypeValueSchema,
465
+ kind: LomKindValueSchema,
466
+ learningResourceType: LomLearningResourceTypeValueSchema,
467
+ name: LomNameValueSchema,
468
+ purpose: LomPurposeValueSchema,
469
+ roleLifeCycle: LomRoleLifeCycleValueSchema,
470
+ roleMetaMetadata: LomRoleMetaMetadataValueSchema,
471
+ semanticDensity: LomSemanticDensityValueSchema,
472
+ status: LomStatusValueSchema,
473
+ structure: LomStructureValueSchema,
474
+ type: LomTypeValueSchema,
475
+ },
476
+ });
@@ -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,36 @@
1
+ import { z } from "zod";
2
+
3
+ import { NonEmptyStringSchema, UriReferenceSchema, strictObject } from "../shared";
4
+
5
+ export const CurriculumStandardsLabelledGUIDSchema = strictObject({
6
+ label: z.string().optional(),
7
+ caseItemURI: UriReferenceSchema.optional(),
8
+ GUID: NonEmptyStringSchema,
9
+ });
10
+
11
+ export const CurriculumStandardsSetOfGUIDsSchema = strictObject({
12
+ labelledGUID: z.array(CurriculumStandardsLabelledGUIDSchema).min(1),
13
+ region: z.string().optional(),
14
+ version: z.string().optional(),
15
+ });
16
+
17
+ export const CurriculumStandardsMetadataSchema = strictObject({
18
+ setOfGUIDs: z.array(CurriculumStandardsSetOfGUIDsSchema).min(1),
19
+ providerId: z.string().optional(),
20
+ });
21
+
22
+ export const CurriculumStandardsMetadataSetSchema = strictObject({
23
+ curriculumStandardsMetadata: z.array(CurriculumStandardsMetadataSchema).min(1),
24
+ resourceLabel: z.string().optional(),
25
+ resourcePartId: z.string().optional(),
26
+ });
27
+
28
+ export const CurriculumStandardsMetadataSetDocumentSchema = strictObject({
29
+ curriculumStandardsMetadataSet: CurriculumStandardsMetadataSetSchema,
30
+ });
31
+ // Inferred types from exported Zod validators.
32
+ export type CurriculumStandardsLabelledGUID = z.infer<typeof CurriculumStandardsLabelledGUIDSchema>;
33
+ export type CurriculumStandardsSetOfGUIDs = z.infer<typeof CurriculumStandardsSetOfGUIDsSchema>;
34
+ export type CurriculumStandardsMetadata = z.infer<typeof CurriculumStandardsMetadataSchema>;
35
+ export type CurriculumStandardsMetadataSet = z.infer<typeof CurriculumStandardsMetadataSetSchema>;
36
+ 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,45 @@
1
+ import { z } from "zod";
2
+
3
+ import { NonEmptyStringSchema, XmlExtensionNodeListSchema, XmlForeignAttributesSchema, strictObject } from "../shared";
4
+ import { CurriculumStandardsMetadataSetSchema } from "./ccv1p4_imscsmd_v1p1";
5
+ import { LomCcLtiLinkSchema } from "./ccv1p4_lomccltilink_v1p0";
6
+ import { BasicLTILinkSchema } from "./imsbasiclti_v1p0p1";
7
+ import { PropertySetSchema } from "./imslticm_v1p0";
8
+ import { ToolLocatorSchema } from "./imslticp_v1p0";
9
+
10
+ export const CartridgeResourceRefSchema = strictObject({
11
+ value: z.string(),
12
+ identifierref: NonEmptyStringSchema,
13
+ foreignAttributes: XmlForeignAttributesSchema.optional(),
14
+ });
15
+
16
+ export const CartridgeBasicLtiMetadataSchema = strictObject({
17
+ lom: LomCcLtiLinkSchema.optional(),
18
+ curriculumStandardsMetadataSet: z.array(CurriculumStandardsMetadataSetSchema).optional(),
19
+ });
20
+
21
+ export const CartridgeBasicLTILinkSchema = BasicLTILinkSchema.extend({
22
+ cartridge_bundle: CartridgeResourceRefSchema.optional(),
23
+ cartridge_icon: CartridgeResourceRefSchema.optional(),
24
+ metadata: CartridgeBasicLtiMetadataSchema.optional(),
25
+ });
26
+
27
+ export const CartridgeToolLocatorSchema = ToolLocatorSchema.extend({
28
+ tool_settings: PropertySetSchema.optional(),
29
+ extensions: XmlExtensionNodeListSchema.optional(),
30
+ });
31
+
32
+ export const CartridgeBasicLTILinkDocumentSchema = strictObject({
33
+ cartridge_basiclti_link: CartridgeBasicLTILinkSchema,
34
+ });
35
+
36
+ export const CartridgeToolLocatorDocumentSchema = strictObject({
37
+ lti_tool_locator: CartridgeToolLocatorSchema,
38
+ });
39
+ // Inferred types from exported Zod validators.
40
+ export type CartridgeResourceRef = z.infer<typeof CartridgeResourceRefSchema>;
41
+ export type CartridgeBasicLtiMetadata = z.infer<typeof CartridgeBasicLtiMetadataSchema>;
42
+ export type CartridgeBasicLTILink = z.infer<typeof CartridgeBasicLTILinkSchema>;
43
+ export type CartridgeToolLocator = z.infer<typeof CartridgeToolLocatorSchema>;
44
+ export type CartridgeBasicLTILinkDocument = z.infer<typeof CartridgeBasicLTILinkDocumentSchema>;
45
+ export type CartridgeToolLocatorDocument = z.infer<typeof CartridgeToolLocatorDocumentSchema>;
@@ -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>;