@conform-ed/contracts 0.0.4 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@conform-ed/contracts",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "type": "module",
5
5
  "module": "src/index.ts",
6
6
  "exports": {
@@ -72,17 +72,21 @@ export const GroupSchema = strictObject({
72
72
  openid: UriSchema.optional(),
73
73
  account: AgentAccountSchema.optional(),
74
74
  member: z.array(AgentSchema).min(1).optional(),
75
- }).refine(
76
- (value) =>
77
- hasDefined(value.mbox) ||
78
- hasDefined(value.mbox_sha1sum) ||
79
- hasDefined(value.openid) ||
80
- hasDefined(value.account) ||
81
- hasDefined(value.member),
82
- {
83
- message: "An xAPI Group requires an identifier or member list",
84
- },
85
- );
75
+ }).superRefine((value, ctx) => {
76
+ const ifiCount = [value.mbox, value.mbox_sha1sum, value.openid, value.account].filter(hasDefined).length;
77
+ if (ifiCount > 1) {
78
+ ctx.addIssue({
79
+ code: z.ZodIssueCode.custom,
80
+ message: "An identified xAPI Group MUST have exactly one Inverse Functional Identifier",
81
+ });
82
+ }
83
+ if (ifiCount === 0 && !hasDefined(value.member)) {
84
+ ctx.addIssue({
85
+ code: z.ZodIssueCode.custom,
86
+ message: "An anonymous xAPI Group requires a member list",
87
+ });
88
+ }
89
+ });
86
90
 
87
91
  export const PersonSchema = strictObject({
88
92
  objectType: z.literal("Person"),
@@ -132,6 +136,8 @@ export const InteractionComponentSchema = strictObject({
132
136
  description: LanguageMapSchema.optional(),
133
137
  });
134
138
 
139
+ const interactionSubProperties = ["correctResponsesPattern", "choices", "scale", "source", "target", "steps"] as const;
140
+
135
141
  export const ActivityDefinitionSchema = strictObject({
136
142
  name: LanguageMapSchema.optional(),
137
143
  description: LanguageMapSchema.optional(),
@@ -145,6 +151,17 @@ export const ActivityDefinitionSchema = strictObject({
145
151
  target: z.array(InteractionComponentSchema).min(1).optional(),
146
152
  steps: z.array(InteractionComponentSchema).min(1).optional(),
147
153
  extensions: ExtensionsSchema.optional(),
154
+ }).superRefine((value, ctx) => {
155
+ if (value.interactionType !== undefined) return;
156
+ for (const prop of interactionSubProperties) {
157
+ if (value[prop] !== undefined) {
158
+ ctx.addIssue({
159
+ code: z.ZodIssueCode.custom,
160
+ message: `Activity definition property '${prop}' requires interactionType to be set`,
161
+ path: [prop],
162
+ });
163
+ }
164
+ }
148
165
  });
149
166
 
150
167
  export const ActivitySchema = strictObject({
@@ -163,6 +180,29 @@ export const ScoreSchema = strictObject({
163
180
  raw: z.number().optional(),
164
181
  min: z.number().optional(),
165
182
  max: z.number().optional(),
183
+ }).superRefine((value, ctx) => {
184
+ const { min, max, raw } = value;
185
+ if (min !== undefined && max !== undefined && min >= max) {
186
+ ctx.addIssue({
187
+ code: z.ZodIssueCode.custom,
188
+ message: "Score max must be greater than min",
189
+ path: ["max"],
190
+ });
191
+ }
192
+ if (raw !== undefined && min !== undefined && raw < min) {
193
+ ctx.addIssue({
194
+ code: z.ZodIssueCode.custom,
195
+ message: "Score raw must be greater than or equal to min",
196
+ path: ["raw"],
197
+ });
198
+ }
199
+ if (raw !== undefined && max !== undefined && raw > max) {
200
+ ctx.addIssue({
201
+ code: z.ZodIssueCode.custom,
202
+ message: "Score raw must be less than or equal to max",
203
+ path: ["raw"],
204
+ });
205
+ }
166
206
  });
167
207
 
168
208
  export const ResultSchema = strictObject({
@@ -285,11 +325,16 @@ export const ActivityProfileDocumentListingQuerySchema = strictObject({
285
325
 
286
326
  export const XapiDocumentIdListSchema = z.array(NonEmptyStringSchema);
287
327
 
328
+ // When Agent or Group is used as a Statement Object, objectType is required per spec.
329
+ // "When Agent is used as a Statement Object, the objectType property MUST be included."
330
+ export const AgentAsObjectSchema = AgentSchema.and(z.object({ objectType: z.literal("Agent") }));
331
+ export const GroupAsObjectSchema = GroupSchema.and(z.object({ objectType: z.literal("Group") }));
332
+
288
333
  export const SubStatementSchema = strictObject({
289
334
  objectType: z.literal("SubStatement"),
290
335
  actor: z.union([AgentSchema, GroupSchema]),
291
336
  verb: VerbSchema,
292
- object: z.union([ActivitySchema, AgentSchema, GroupSchema, StatementRefSchema]),
337
+ object: z.union([ActivitySchema, AgentAsObjectSchema, GroupAsObjectSchema, StatementRefSchema]),
293
338
  result: ResultSchema.optional(),
294
339
  context: ContextSchema.optional(),
295
340
  timestamp: Iso8601TimestampSchema.optional(),
@@ -297,8 +342,8 @@ export const SubStatementSchema = strictObject({
297
342
 
298
343
  export const StatementObjectSchema = z.union([
299
344
  ActivitySchema,
300
- AgentSchema,
301
- GroupSchema,
345
+ AgentAsObjectSchema,
346
+ GroupAsObjectSchema,
302
347
  StatementRefSchema,
303
348
  SubStatementSchema,
304
349
  ]);
@@ -47,6 +47,8 @@ import {
47
47
  XapiResourceSchema,
48
48
  XapiResponseHeaderSchema,
49
49
  XapiVersionSchema,
50
+ AgentAsObjectSchema,
51
+ GroupAsObjectSchema,
50
52
  } from "../shared";
51
53
 
52
54
  export const ContextAgentSchema = strictObject({
@@ -70,7 +72,7 @@ export const SubStatementV2Schema = strictObject({
70
72
  objectType: z.literal("SubStatement"),
71
73
  actor: z.union([AgentSchema, GroupSchema]),
72
74
  verb: VerbSchema,
73
- object: z.union([ActivitySchema, AgentSchema, GroupSchema, StatementRefSchema]),
75
+ object: z.union([ActivitySchema, AgentAsObjectSchema, GroupAsObjectSchema, StatementRefSchema]),
74
76
  result: ResultSchema.optional(),
75
77
  context: ContextV2Schema.optional(),
76
78
  timestamp: Iso8601TimestampSchema.optional(),
@@ -78,8 +80,8 @@ export const SubStatementV2Schema = strictObject({
78
80
 
79
81
  export const StatementObjectV2Schema = z.union([
80
82
  ActivitySchema,
81
- AgentSchema,
82
- GroupSchema,
83
+ AgentAsObjectSchema,
84
+ GroupAsObjectSchema,
83
85
  StatementRefSchema,
84
86
  SubStatementV2Schema,
85
87
  ]);