@superbuilders/primer-tives 1.1.1 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -8
- package/dist/client/index.js +60 -88
- package/dist/client/index.js.map +3 -3
- package/dist/contracts/index.d.ts +1 -1
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/contracts/index.js +60 -88
- package/dist/contracts/index.js.map +3 -3
- package/dist/contracts/validation.d.ts +7 -73
- package/dist/contracts/validation.d.ts.map +1 -1
- package/dist/index.js +60 -88
- package/dist/index.js.map +3 -3
- package/package.json +2 -1
package/dist/contracts/index.js
CHANGED
|
@@ -68,12 +68,6 @@ var RendererSubmissionSchema = z2.union([
|
|
|
68
68
|
DivisionRemainderPciSubmissionSchema,
|
|
69
69
|
FractionAdditionPciSubmissionSchema
|
|
70
70
|
]);
|
|
71
|
-
function invalid(issues) {
|
|
72
|
-
return {
|
|
73
|
-
ok: false,
|
|
74
|
-
issues: Array.isArray(issues) ? issues : [issues]
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
71
|
function duplicates(values, keyOf) {
|
|
78
72
|
const seen = new Set;
|
|
79
73
|
const duplicated = new Set;
|
|
@@ -132,10 +126,16 @@ function pciSubmissionSchema(pciId) {
|
|
|
132
126
|
const exhaustiveCheck = pciId;
|
|
133
127
|
return exhaustiveCheck;
|
|
134
128
|
}
|
|
135
|
-
function
|
|
136
|
-
|
|
137
|
-
|
|
129
|
+
function typeMismatch(interactionType, submissionType) {
|
|
130
|
+
return `submission type '${submissionType}' does not match interaction type '${interactionType}'`;
|
|
131
|
+
}
|
|
132
|
+
function buildResult(submission, issues) {
|
|
133
|
+
if (issues.length > 0) {
|
|
134
|
+
return { ok: false, issues };
|
|
138
135
|
}
|
|
136
|
+
return { ok: true, value: submission };
|
|
137
|
+
}
|
|
138
|
+
function validateChoice(interaction, submission) {
|
|
139
139
|
const issues = [];
|
|
140
140
|
if (submission.selectedKeys.length < interaction.minChoices) {
|
|
141
141
|
issues.push(`need at least ${interaction.minChoices} selections`);
|
|
@@ -153,58 +153,31 @@ function validateChoiceSubmission(interaction, submission) {
|
|
|
153
153
|
if (unknownKeys.length > 0) {
|
|
154
154
|
issues.push(`unknown options: ${unknownKeys.join(", ")}`);
|
|
155
155
|
}
|
|
156
|
-
|
|
157
|
-
return invalid(issues);
|
|
158
|
-
}
|
|
159
|
-
return {
|
|
160
|
-
ok: true,
|
|
161
|
-
value: { ...submission }
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
function validateTextEntrySubmission(interaction, submission) {
|
|
165
|
-
if (submission.type !== "text-entry") {
|
|
166
|
-
return invalid(`submission type '${submission.type}' does not match interaction type 'text-entry'`);
|
|
167
|
-
}
|
|
168
|
-
return {
|
|
169
|
-
ok: true,
|
|
170
|
-
value: { ...submission }
|
|
171
|
-
};
|
|
156
|
+
return issues;
|
|
172
157
|
}
|
|
173
|
-
function
|
|
174
|
-
if (submission.type !== "extended-text") {
|
|
175
|
-
return invalid(`submission type '${submission.type}' does not match interaction type 'extended-text'`);
|
|
176
|
-
}
|
|
158
|
+
function validateExtendedText(interaction, submission) {
|
|
177
159
|
const issues = [];
|
|
178
160
|
if (interaction.cardinality === "single") {
|
|
179
161
|
if (submission.values.length !== 1) {
|
|
180
162
|
issues.push("single-cardinality extended-text requires exactly one value");
|
|
181
163
|
}
|
|
182
|
-
|
|
183
|
-
if (submission.values.length < interaction.minStrings) {
|
|
184
|
-
issues.push(`need at least ${interaction.minStrings} values`);
|
|
185
|
-
}
|
|
186
|
-
if (submission.values.length > interaction.maxStrings) {
|
|
187
|
-
issues.push(`at most ${interaction.maxStrings} values`);
|
|
188
|
-
}
|
|
189
|
-
const duplicateValues = duplicates(submission.values, function keyOf(value) {
|
|
190
|
-
return value;
|
|
191
|
-
});
|
|
192
|
-
if (duplicateValues.length > 0) {
|
|
193
|
-
issues.push("duplicate values are not allowed for multiple-cardinality extended-text");
|
|
194
|
-
}
|
|
164
|
+
return issues;
|
|
195
165
|
}
|
|
196
|
-
if (
|
|
197
|
-
|
|
166
|
+
if (submission.values.length < interaction.minStrings) {
|
|
167
|
+
issues.push(`need at least ${interaction.minStrings} values`);
|
|
198
168
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
if (
|
|
206
|
-
|
|
169
|
+
if (submission.values.length > interaction.maxStrings) {
|
|
170
|
+
issues.push(`at most ${interaction.maxStrings} values`);
|
|
171
|
+
}
|
|
172
|
+
const duplicateValues = duplicates(submission.values, function keyOf(value) {
|
|
173
|
+
return value;
|
|
174
|
+
});
|
|
175
|
+
if (duplicateValues.length > 0) {
|
|
176
|
+
issues.push("duplicate values are not allowed for multiple-cardinality extended-text");
|
|
207
177
|
}
|
|
178
|
+
return issues;
|
|
179
|
+
}
|
|
180
|
+
function validateOrder(interaction, submission) {
|
|
208
181
|
const issues = [];
|
|
209
182
|
if (submission.orderedKeys.length < interaction.minChoices) {
|
|
210
183
|
issues.push(`need at least ${interaction.minChoices} selections`);
|
|
@@ -222,18 +195,9 @@ function validateOrderSubmission(interaction, submission) {
|
|
|
222
195
|
if (unknownKeys.length > 0) {
|
|
223
196
|
issues.push(`unknown choices: ${unknownKeys.join(", ")}`);
|
|
224
197
|
}
|
|
225
|
-
|
|
226
|
-
return invalid(issues);
|
|
227
|
-
}
|
|
228
|
-
return {
|
|
229
|
-
ok: true,
|
|
230
|
-
value: { ...submission }
|
|
231
|
-
};
|
|
198
|
+
return issues;
|
|
232
199
|
}
|
|
233
|
-
function
|
|
234
|
-
if (submission.type !== "match") {
|
|
235
|
-
return invalid(`submission type '${submission.type}' does not match interaction type 'match'`);
|
|
236
|
-
}
|
|
200
|
+
function validateMatch(interaction, submission) {
|
|
237
201
|
const issues = [];
|
|
238
202
|
if (submission.pairs.length < interaction.minAssociations) {
|
|
239
203
|
issues.push(`need at least ${interaction.minAssociations} associations`);
|
|
@@ -265,47 +229,55 @@ function validateMatchSubmission(interaction, submission) {
|
|
|
265
229
|
const targetCounts = countByIdentifier(submission.pairs, "target");
|
|
266
230
|
issues.push(...validateUsageBounds(interaction.sourceChoices, sourceCounts, "source"));
|
|
267
231
|
issues.push(...validateUsageBounds(interaction.targetChoices, targetCounts, "target"));
|
|
268
|
-
|
|
269
|
-
return invalid(issues);
|
|
270
|
-
}
|
|
271
|
-
return {
|
|
272
|
-
ok: true,
|
|
273
|
-
value: { ...submission }
|
|
274
|
-
};
|
|
232
|
+
return issues;
|
|
275
233
|
}
|
|
276
|
-
function
|
|
277
|
-
if (submission.type !== "portable-custom") {
|
|
278
|
-
return invalid(`submission type '${submission.type}' does not match interaction type 'portable-custom'`);
|
|
279
|
-
}
|
|
234
|
+
function validatePortableCustom(interaction, submission) {
|
|
280
235
|
if (submission.pciId !== interaction.pciId) {
|
|
281
|
-
return
|
|
236
|
+
return [
|
|
237
|
+
`submission PCI '${submission.pciId}' does not match interaction PCI '${interaction.pciId}'`
|
|
238
|
+
];
|
|
282
239
|
}
|
|
283
240
|
const schema = pciSubmissionSchema(interaction.pciId);
|
|
284
241
|
const result = schema.safeParse(submission.value);
|
|
285
242
|
if (!result.success) {
|
|
286
|
-
return
|
|
243
|
+
return result.error.issues.map(function toIssue(issue) {
|
|
287
244
|
return issue.message;
|
|
288
|
-
})
|
|
245
|
+
});
|
|
289
246
|
}
|
|
290
|
-
return
|
|
291
|
-
ok: true,
|
|
292
|
-
value: { ...submission }
|
|
293
|
-
};
|
|
247
|
+
return [];
|
|
294
248
|
}
|
|
295
249
|
function validateSubmissionForInteraction(interaction, submission) {
|
|
296
250
|
switch (interaction.type) {
|
|
297
251
|
case "choice":
|
|
298
|
-
|
|
252
|
+
if (submission.type !== "choice") {
|
|
253
|
+
return { ok: false, issues: [typeMismatch(interaction.type, submission.type)] };
|
|
254
|
+
}
|
|
255
|
+
return buildResult(submission, validateChoice(interaction, submission));
|
|
299
256
|
case "text-entry":
|
|
300
|
-
|
|
257
|
+
if (submission.type !== "text-entry") {
|
|
258
|
+
return { ok: false, issues: [typeMismatch(interaction.type, submission.type)] };
|
|
259
|
+
}
|
|
260
|
+
return { ok: true, value: submission };
|
|
301
261
|
case "extended-text":
|
|
302
|
-
|
|
262
|
+
if (submission.type !== "extended-text") {
|
|
263
|
+
return { ok: false, issues: [typeMismatch(interaction.type, submission.type)] };
|
|
264
|
+
}
|
|
265
|
+
return buildResult(submission, validateExtendedText(interaction, submission));
|
|
303
266
|
case "order":
|
|
304
|
-
|
|
267
|
+
if (submission.type !== "order") {
|
|
268
|
+
return { ok: false, issues: [typeMismatch(interaction.type, submission.type)] };
|
|
269
|
+
}
|
|
270
|
+
return buildResult(submission, validateOrder(interaction, submission));
|
|
305
271
|
case "match":
|
|
306
|
-
|
|
272
|
+
if (submission.type !== "match") {
|
|
273
|
+
return { ok: false, issues: [typeMismatch(interaction.type, submission.type)] };
|
|
274
|
+
}
|
|
275
|
+
return buildResult(submission, validateMatch(interaction, submission));
|
|
307
276
|
case "portable-custom":
|
|
308
|
-
|
|
277
|
+
if (submission.type !== "portable-custom") {
|
|
278
|
+
return { ok: false, issues: [typeMismatch(interaction.type, submission.type)] };
|
|
279
|
+
}
|
|
280
|
+
return buildResult(submission, validatePortableCustom(interaction, submission));
|
|
309
281
|
}
|
|
310
282
|
}
|
|
311
283
|
function submissionValidationMessage(result) {
|
|
@@ -325,4 +297,4 @@ export {
|
|
|
325
297
|
ChoiceSubmissionSchema
|
|
326
298
|
};
|
|
327
299
|
|
|
328
|
-
//# debugId=
|
|
300
|
+
//# debugId=5A4E82ADE8F4197364756E2164756E21
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/contracts/validation.ts", "../src/contracts/pci-schemas.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import { z } from \"zod\"\n\nimport type { PciId } from \"@superbuilders/primer-tives/client/pci\"\n\nimport {\n\tDivisionRemainderSubmissionSchema,\n\tFractionAdditionSubmissionSchema\n} from \"@superbuilders/primer-tives/contracts/pci-schemas\"\nimport type {\n\tMatchPair,\n\tPciInteraction,\n\tRendererChoice,\n\tRendererInteraction,\n\tRendererMatchChoice,\n\tRendererSubmission\n} from \"@superbuilders/primer-tives/contracts/types\"\n\nconst MatchPairSchema = z.object({\n\tsource: z.string(),\n\ttarget: z.string()\n})\n\nconst ChoiceSubmissionSchema = z.object({\n\ttype: z.literal(\"choice\"),\n\tselectedKeys: z.array(z.string())\n})\n\nconst TextEntrySubmissionSchema = z.object({\n\ttype: z.literal(\"text-entry\"),\n\tvalue: z.string()\n})\n\nconst ExtendedTextSubmissionSchema = z.object({\n\ttype: z.literal(\"extended-text\"),\n\tvalues: z.array(z.string()).min(1)\n})\n\nconst OrderSubmissionSchema = z.object({\n\ttype: z.literal(\"order\"),\n\torderedKeys: z.array(z.string())\n})\n\nconst MatchSubmissionSchema = z.object({\n\ttype: z.literal(\"match\"),\n\tpairs: z.array(MatchPairSchema)\n})\n\nconst DivisionRemainderPciSubmissionSchema = z.object({\n\ttype: z.literal(\"portable-custom\"),\n\tpciId: z.literal(\"urn:primer:pci:division-remainder\"),\n\tvalue: DivisionRemainderSubmissionSchema\n})\n\nconst FractionAdditionPciSubmissionSchema = z.object({\n\ttype: z.literal(\"portable-custom\"),\n\tpciId: z.literal(\"urn:primer:pci:fraction-addition\"),\n\tvalue: FractionAdditionSubmissionSchema\n})\n\nconst RendererSubmissionSchema = z.union([\n\tChoiceSubmissionSchema,\n\tTextEntrySubmissionSchema,\n\tExtendedTextSubmissionSchema,\n\tOrderSubmissionSchema,\n\tMatchSubmissionSchema,\n\tDivisionRemainderPciSubmissionSchema,\n\tFractionAdditionPciSubmissionSchema\n])\n\ntype RendererSubmissionFor<I extends RendererInteraction = RendererInteraction> = I extends {\n\ttype: \"choice\"\n}\n\t? { type: \"choice\"; selectedKeys: string[] }\n\t: I extends { type: \"text-entry\" }\n\t\t? { type: \"text-entry\"; value: string }\n\t\t: I extends { type: \"extended-text\" }\n\t\t\t? { type: \"extended-text\"; values: string[] }\n\t\t\t: I extends { type: \"order\" }\n\t\t\t\t? { type: \"order\"; orderedKeys: string[] }\n\t\t\t\t: I extends { type: \"match\" }\n\t\t\t\t\t? { type: \"match\"; pairs: MatchPair[] }\n\t\t\t\t\t: I extends PciInteraction<infer SupportedPcis extends PciId>\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t[K in SupportedPcis]: {\n\t\t\t\t\t\t\t\t\ttype: \"portable-custom\"\n\t\t\t\t\t\t\t\t\tpciId: K\n\t\t\t\t\t\t\t\t\tvalue: Extract<RendererSubmission, { type: \"portable-custom\"; pciId: K }>[\"value\"]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}[SupportedPcis]\n\t\t\t\t\t\t: never\n\ntype SubmissionValidationSuccess<I extends RendererInteraction = RendererInteraction> = {\n\tok: true\n\tvalue: RendererSubmissionFor<I>\n}\n\ntype SubmissionValidationFailure = {\n\tok: false\n\tissues: string[]\n}\n\ntype SubmissionValidationResult<I extends RendererInteraction = RendererInteraction> =\n\t| SubmissionValidationSuccess<I>\n\t| SubmissionValidationFailure\n\nfunction invalid(issues: string | string[]): SubmissionValidationFailure {\n\treturn {\n\t\tok: false,\n\t\tissues: Array.isArray(issues) ? issues : [issues]\n\t}\n}\n\nfunction duplicates<T>(values: readonly T[], keyOf: (value: T) => string): string[] {\n\tconst seen = new Set<string>()\n\tconst duplicated = new Set<string>()\n\tfor (const value of values) {\n\t\tconst key = keyOf(value)\n\t\tif (seen.has(key)) {\n\t\t\tduplicated.add(key)\n\t\t\tcontinue\n\t\t}\n\t\tseen.add(key)\n\t}\n\treturn [...duplicated]\n}\n\nfunction findUnknownIds(values: readonly string[], choices: RendererChoice[]): string[] {\n\tconst ids = new Set(\n\t\tchoices.map(function getId(choice) {\n\t\t\treturn choice.identifier\n\t\t})\n\t)\n\treturn values.filter(function isUnknown(value) {\n\t\treturn !ids.has(value)\n\t})\n}\n\nfunction countByIdentifier(pairs: MatchPair[], side: \"source\" | \"target\"): Map<string, number> {\n\tconst counts = new Map<string, number>()\n\tfor (const pair of pairs) {\n\t\tconst key = pair[side]\n\t\tconst currentCount = counts.get(key)\n\t\tif (currentCount === undefined) {\n\t\t\tcounts.set(key, 1)\n\t\t\tcontinue\n\t\t}\n\t\tcounts.set(key, currentCount + 1)\n\t}\n\treturn counts\n}\n\nfunction validateUsageBounds(\n\tchoices: RendererMatchChoice[],\n\tcounts: Map<string, number>,\n\tside: \"source\" | \"target\"\n): string[] {\n\tconst issues: string[] = []\n\tfor (const choice of choices) {\n\t\tconst maybeCount = counts.get(choice.identifier)\n\t\tconst count = maybeCount === undefined ? 0 : maybeCount\n\t\tif (choice.matchMax !== 0 && count > choice.matchMax) {\n\t\t\tissues.push(`${side} '${choice.identifier}' used ${count} times, max ${choice.matchMax}`)\n\t\t}\n\t\tif (count < choice.matchMin) {\n\t\t\tissues.push(`${side} '${choice.identifier}' used ${count} times, min ${choice.matchMin}`)\n\t\t}\n\t}\n\treturn issues\n}\n\nfunction pciSubmissionSchema(pciId: PciId) {\n\tswitch (pciId) {\n\t\tcase \"urn:primer:pci:division-remainder\":\n\t\t\treturn DivisionRemainderSubmissionSchema\n\t\tcase \"urn:primer:pci:fraction-addition\":\n\t\t\treturn FractionAdditionSubmissionSchema\n\t}\n\tconst exhaustiveCheck: never = pciId\n\treturn exhaustiveCheck\n}\n\nfunction validateChoiceSubmission(\n\tinteraction: Extract<RendererInteraction, { type: \"choice\" }>,\n\tsubmission: RendererSubmission\n): SubmissionValidationResult<Extract<RendererInteraction, { type: \"choice\" }>> {\n\tif (submission.type !== \"choice\") {\n\t\treturn invalid(`submission type '${submission.type}' does not match interaction type 'choice'`)\n\t}\n\tconst issues: string[] = []\n\tif (submission.selectedKeys.length < interaction.minChoices) {\n\t\tissues.push(`need at least ${interaction.minChoices} selections`)\n\t}\n\tif (submission.selectedKeys.length > interaction.maxChoices) {\n\t\tissues.push(`at most ${interaction.maxChoices} selections`)\n\t}\n\tconst duplicateKeys = duplicates(submission.selectedKeys, function keyOf(value) {\n\t\treturn value\n\t})\n\tif (duplicateKeys.length > 0) {\n\t\tissues.push(\"duplicate selections\")\n\t}\n\tconst unknownKeys = findUnknownIds(submission.selectedKeys, interaction.options)\n\tif (unknownKeys.length > 0) {\n\t\tissues.push(`unknown options: ${unknownKeys.join(\", \")}`)\n\t}\n\tif (issues.length > 0) {\n\t\treturn invalid(issues)\n\t}\n\treturn {\n\t\tok: true,\n\t\tvalue: { ...submission }\n\t}\n}\n\nfunction validateTextEntrySubmission(\n\tinteraction: Extract<RendererInteraction, { type: \"text-entry\" }>,\n\tsubmission: RendererSubmission\n): SubmissionValidationResult<typeof interaction> {\n\tif (submission.type !== \"text-entry\") {\n\t\treturn invalid(\n\t\t\t`submission type '${submission.type}' does not match interaction type 'text-entry'`\n\t\t)\n\t}\n\treturn {\n\t\tok: true,\n\t\tvalue: { ...submission }\n\t}\n}\n\nfunction validateExtendedTextSubmission(\n\tinteraction: Extract<RendererInteraction, { type: \"extended-text\" }>,\n\tsubmission: RendererSubmission\n): SubmissionValidationResult<typeof interaction> {\n\tif (submission.type !== \"extended-text\") {\n\t\treturn invalid(\n\t\t\t`submission type '${submission.type}' does not match interaction type 'extended-text'`\n\t\t)\n\t}\n\tconst issues: string[] = []\n\tif (interaction.cardinality === \"single\") {\n\t\tif (submission.values.length !== 1) {\n\t\t\tissues.push(\"single-cardinality extended-text requires exactly one value\")\n\t\t}\n\t} else {\n\t\tif (submission.values.length < interaction.minStrings) {\n\t\t\tissues.push(`need at least ${interaction.minStrings} values`)\n\t\t}\n\t\tif (submission.values.length > interaction.maxStrings) {\n\t\t\tissues.push(`at most ${interaction.maxStrings} values`)\n\t\t}\n\t\tconst duplicateValues = duplicates(submission.values, function keyOf(value) {\n\t\t\treturn value\n\t\t})\n\t\tif (duplicateValues.length > 0) {\n\t\t\tissues.push(\"duplicate values are not allowed for multiple-cardinality extended-text\")\n\t\t}\n\t}\n\tif (issues.length > 0) {\n\t\treturn invalid(issues)\n\t}\n\treturn {\n\t\tok: true,\n\t\tvalue: { ...submission }\n\t}\n}\n\nfunction validateOrderSubmission(\n\tinteraction: Extract<RendererInteraction, { type: \"order\" }>,\n\tsubmission: RendererSubmission\n): SubmissionValidationResult<typeof interaction> {\n\tif (submission.type !== \"order\") {\n\t\treturn invalid(`submission type '${submission.type}' does not match interaction type 'order'`)\n\t}\n\tconst issues: string[] = []\n\tif (submission.orderedKeys.length < interaction.minChoices) {\n\t\tissues.push(`need at least ${interaction.minChoices} selections`)\n\t}\n\tif (submission.orderedKeys.length > interaction.maxChoices) {\n\t\tissues.push(`at most ${interaction.maxChoices} selections`)\n\t}\n\tconst duplicateKeys = duplicates(submission.orderedKeys, function keyOf(value) {\n\t\treturn value\n\t})\n\tif (duplicateKeys.length > 0) {\n\t\tissues.push(\"duplicate selections\")\n\t}\n\tconst unknownKeys = findUnknownIds(submission.orderedKeys, interaction.choices)\n\tif (unknownKeys.length > 0) {\n\t\tissues.push(`unknown choices: ${unknownKeys.join(\", \")}`)\n\t}\n\tif (issues.length > 0) {\n\t\treturn invalid(issues)\n\t}\n\treturn {\n\t\tok: true,\n\t\tvalue: { ...submission }\n\t}\n}\n\nfunction validateMatchSubmission(\n\tinteraction: Extract<RendererInteraction, { type: \"match\" }>,\n\tsubmission: RendererSubmission\n): SubmissionValidationResult<typeof interaction> {\n\tif (submission.type !== \"match\") {\n\t\treturn invalid(`submission type '${submission.type}' does not match interaction type 'match'`)\n\t}\n\tconst issues: string[] = []\n\tif (submission.pairs.length < interaction.minAssociations) {\n\t\tissues.push(`need at least ${interaction.minAssociations} associations`)\n\t}\n\tif (submission.pairs.length > interaction.maxAssociations) {\n\t\tissues.push(`at most ${interaction.maxAssociations} associations`)\n\t}\n\tconst duplicatePairs = duplicates(submission.pairs, function keyOf(pair) {\n\t\treturn `${pair.source}->${pair.target}`\n\t})\n\tif (duplicatePairs.length > 0) {\n\t\tissues.push(\"duplicate associations are not allowed\")\n\t}\n\tconst sourceIds = new Set(\n\t\tinteraction.sourceChoices.map(function getId(choice) {\n\t\t\treturn choice.identifier\n\t\t})\n\t)\n\tconst targetIds = new Set(\n\t\tinteraction.targetChoices.map(function getId(choice) {\n\t\t\treturn choice.identifier\n\t\t})\n\t)\n\tfor (const pair of submission.pairs) {\n\t\tif (!sourceIds.has(pair.source)) {\n\t\t\tissues.push(`unknown source '${pair.source}'`)\n\t\t}\n\t\tif (!targetIds.has(pair.target)) {\n\t\t\tissues.push(`unknown target '${pair.target}'`)\n\t\t}\n\t}\n\tconst sourceCounts = countByIdentifier(submission.pairs, \"source\")\n\tconst targetCounts = countByIdentifier(submission.pairs, \"target\")\n\tissues.push(...validateUsageBounds(interaction.sourceChoices, sourceCounts, \"source\"))\n\tissues.push(...validateUsageBounds(interaction.targetChoices, targetCounts, \"target\"))\n\tif (issues.length > 0) {\n\t\treturn invalid(issues)\n\t}\n\treturn {\n\t\tok: true,\n\t\tvalue: { ...submission }\n\t}\n}\n\nfunction validatePortableCustomSubmission(\n\tinteraction: Extract<RendererInteraction, { type: \"portable-custom\" }>,\n\tsubmission: RendererSubmission\n): SubmissionValidationResult<typeof interaction> {\n\tif (submission.type !== \"portable-custom\") {\n\t\treturn invalid(\n\t\t\t`submission type '${submission.type}' does not match interaction type 'portable-custom'`\n\t\t)\n\t}\n\tif (submission.pciId !== interaction.pciId) {\n\t\treturn invalid(\n\t\t\t`submission PCI '${submission.pciId}' does not match interaction PCI '${interaction.pciId}'`\n\t\t)\n\t}\n\tconst schema = pciSubmissionSchema(interaction.pciId)\n\tconst result = schema.safeParse(submission.value)\n\tif (!result.success) {\n\t\treturn invalid(\n\t\t\tresult.error.issues.map(function toIssue(issue) {\n\t\t\t\treturn issue.message\n\t\t\t})\n\t\t)\n\t}\n\treturn {\n\t\tok: true,\n\t\tvalue: { ...submission }\n\t}\n}\n\nfunction validateSubmissionForInteraction(\n\tinteraction: Extract<RendererInteraction, { type: \"choice\" }>,\n\tsubmission: RendererSubmission\n): SubmissionValidationResult<Extract<RendererInteraction, { type: \"choice\" }>>\nfunction validateSubmissionForInteraction(\n\tinteraction: Extract<RendererInteraction, { type: \"text-entry\" }>,\n\tsubmission: RendererSubmission\n): SubmissionValidationResult<Extract<RendererInteraction, { type: \"text-entry\" }>>\nfunction validateSubmissionForInteraction(\n\tinteraction: Extract<RendererInteraction, { type: \"extended-text\" }>,\n\tsubmission: RendererSubmission\n): SubmissionValidationResult<Extract<RendererInteraction, { type: \"extended-text\" }>>\nfunction validateSubmissionForInteraction(\n\tinteraction: Extract<RendererInteraction, { type: \"order\" }>,\n\tsubmission: RendererSubmission\n): SubmissionValidationResult<Extract<RendererInteraction, { type: \"order\" }>>\nfunction validateSubmissionForInteraction(\n\tinteraction: Extract<RendererInteraction, { type: \"match\" }>,\n\tsubmission: RendererSubmission\n): SubmissionValidationResult<Extract<RendererInteraction, { type: \"match\" }>>\nfunction validateSubmissionForInteraction(\n\tinteraction: Extract<RendererInteraction, { type: \"portable-custom\" }>,\n\tsubmission: RendererSubmission\n): SubmissionValidationResult<Extract<RendererInteraction, { type: \"portable-custom\" }>>\nfunction validateSubmissionForInteraction<I extends RendererInteraction>(\n\tinteraction: I,\n\tsubmission: RendererSubmission\n): SubmissionValidationResult<I>\nfunction validateSubmissionForInteraction(\n\tinteraction: RendererInteraction,\n\tsubmission: RendererSubmission\n): SubmissionValidationResult {\n\tswitch (interaction.type) {\n\t\tcase \"choice\":\n\t\t\treturn validateChoiceSubmission(interaction, submission)\n\t\tcase \"text-entry\":\n\t\t\treturn validateTextEntrySubmission(interaction, submission)\n\t\tcase \"extended-text\":\n\t\t\treturn validateExtendedTextSubmission(interaction, submission)\n\t\tcase \"order\":\n\t\t\treturn validateOrderSubmission(interaction, submission)\n\t\tcase \"match\":\n\t\t\treturn validateMatchSubmission(interaction, submission)\n\t\tcase \"portable-custom\":\n\t\t\treturn validatePortableCustomSubmission(interaction, submission)\n\t}\n}\n\nfunction submissionValidationMessage(result: SubmissionValidationFailure): string {\n\treturn result.issues.join(\"; \")\n}\n\nexport {\n\tChoiceSubmissionSchema,\n\tDivisionRemainderPciSubmissionSchema,\n\tExtendedTextSubmissionSchema,\n\tFractionAdditionPciSubmissionSchema,\n\tMatchPairSchema,\n\tMatchSubmissionSchema,\n\tOrderSubmissionSchema,\n\tRendererSubmissionSchema,\n\tTextEntrySubmissionSchema,\n\tsubmissionValidationMessage,\n\tvalidateSubmissionForInteraction\n}\nexport type {\n\tRendererSubmissionFor,\n\tSubmissionValidationFailure,\n\tSubmissionValidationResult,\n\tSubmissionValidationSuccess\n}\n",
|
|
5
|
+
"import { z } from \"zod\"\n\nimport type { PciId } from \"@superbuilders/primer-tives/client/pci\"\n\nimport {\n\tDivisionRemainderSubmissionSchema,\n\tFractionAdditionSubmissionSchema\n} from \"@superbuilders/primer-tives/contracts/pci-schemas\"\nimport type {\n\tMatchPair,\n\tRendererChoice,\n\tRendererInteraction,\n\tRendererMatchChoice,\n\tRendererSubmission\n} from \"@superbuilders/primer-tives/contracts/types\"\n\nconst MatchPairSchema = z.object({\n\tsource: z.string(),\n\ttarget: z.string()\n})\n\nconst ChoiceSubmissionSchema = z.object({\n\ttype: z.literal(\"choice\"),\n\tselectedKeys: z.array(z.string())\n})\n\nconst TextEntrySubmissionSchema = z.object({\n\ttype: z.literal(\"text-entry\"),\n\tvalue: z.string()\n})\n\nconst ExtendedTextSubmissionSchema = z.object({\n\ttype: z.literal(\"extended-text\"),\n\tvalues: z.array(z.string()).min(1)\n})\n\nconst OrderSubmissionSchema = z.object({\n\ttype: z.literal(\"order\"),\n\torderedKeys: z.array(z.string())\n})\n\nconst MatchSubmissionSchema = z.object({\n\ttype: z.literal(\"match\"),\n\tpairs: z.array(MatchPairSchema)\n})\n\nconst DivisionRemainderPciSubmissionSchema = z.object({\n\ttype: z.literal(\"portable-custom\"),\n\tpciId: z.literal(\"urn:primer:pci:division-remainder\"),\n\tvalue: DivisionRemainderSubmissionSchema\n})\n\nconst FractionAdditionPciSubmissionSchema = z.object({\n\ttype: z.literal(\"portable-custom\"),\n\tpciId: z.literal(\"urn:primer:pci:fraction-addition\"),\n\tvalue: FractionAdditionSubmissionSchema\n})\n\nconst RendererSubmissionSchema = z.union([\n\tChoiceSubmissionSchema,\n\tTextEntrySubmissionSchema,\n\tExtendedTextSubmissionSchema,\n\tOrderSubmissionSchema,\n\tMatchSubmissionSchema,\n\tDivisionRemainderPciSubmissionSchema,\n\tFractionAdditionPciSubmissionSchema\n])\n\nfunction duplicates<T>(values: readonly T[], keyOf: (value: T) => string): string[] {\n\tconst seen = new Set<string>()\n\tconst duplicated = new Set<string>()\n\tfor (const value of values) {\n\t\tconst key = keyOf(value)\n\t\tif (seen.has(key)) {\n\t\t\tduplicated.add(key)\n\t\t\tcontinue\n\t\t}\n\t\tseen.add(key)\n\t}\n\treturn [...duplicated]\n}\n\nfunction findUnknownIds(values: readonly string[], choices: RendererChoice[]): string[] {\n\tconst ids = new Set(\n\t\tchoices.map(function getId(choice) {\n\t\t\treturn choice.identifier\n\t\t})\n\t)\n\treturn values.filter(function isUnknown(value) {\n\t\treturn !ids.has(value)\n\t})\n}\n\nfunction countByIdentifier(pairs: MatchPair[], side: \"source\" | \"target\"): Map<string, number> {\n\tconst counts = new Map<string, number>()\n\tfor (const pair of pairs) {\n\t\tconst key = pair[side]\n\t\tconst currentCount = counts.get(key)\n\t\tif (currentCount === undefined) {\n\t\t\tcounts.set(key, 1)\n\t\t\tcontinue\n\t\t}\n\t\tcounts.set(key, currentCount + 1)\n\t}\n\treturn counts\n}\n\nfunction validateUsageBounds(\n\tchoices: RendererMatchChoice[],\n\tcounts: Map<string, number>,\n\tside: \"source\" | \"target\"\n): string[] {\n\tconst issues: string[] = []\n\tfor (const choice of choices) {\n\t\tconst maybeCount = counts.get(choice.identifier)\n\t\tconst count = maybeCount === undefined ? 0 : maybeCount\n\t\tif (choice.matchMax !== 0 && count > choice.matchMax) {\n\t\t\tissues.push(`${side} '${choice.identifier}' used ${count} times, max ${choice.matchMax}`)\n\t\t}\n\t\tif (count < choice.matchMin) {\n\t\t\tissues.push(`${side} '${choice.identifier}' used ${count} times, min ${choice.matchMin}`)\n\t\t}\n\t}\n\treturn issues\n}\n\nfunction pciSubmissionSchema(pciId: PciId) {\n\tswitch (pciId) {\n\t\tcase \"urn:primer:pci:division-remainder\":\n\t\t\treturn DivisionRemainderSubmissionSchema\n\t\tcase \"urn:primer:pci:fraction-addition\":\n\t\t\treturn FractionAdditionSubmissionSchema\n\t}\n\tconst exhaustiveCheck: never = pciId\n\treturn exhaustiveCheck\n}\n\ntype SubmissionValidationSuccess = {\n\tok: true\n\tvalue: RendererSubmission\n}\n\ntype SubmissionValidationFailure = {\n\tok: false\n\tissues: readonly string[]\n}\n\ntype SubmissionValidationResult = SubmissionValidationSuccess | SubmissionValidationFailure\n\nfunction typeMismatch(interactionType: string, submissionType: string): string {\n\treturn `submission type '${submissionType}' does not match interaction type '${interactionType}'`\n}\n\nfunction buildResult(\n\tsubmission: RendererSubmission,\n\tissues: readonly string[]\n): SubmissionValidationResult {\n\tif (issues.length > 0) {\n\t\treturn { ok: false, issues }\n\t}\n\treturn { ok: true, value: submission }\n}\n\nfunction validateChoice(\n\tinteraction: Extract<RendererInteraction, { type: \"choice\" }>,\n\tsubmission: Extract<RendererSubmission, { type: \"choice\" }>\n): readonly string[] {\n\tconst issues: string[] = []\n\tif (submission.selectedKeys.length < interaction.minChoices) {\n\t\tissues.push(`need at least ${interaction.minChoices} selections`)\n\t}\n\tif (submission.selectedKeys.length > interaction.maxChoices) {\n\t\tissues.push(`at most ${interaction.maxChoices} selections`)\n\t}\n\tconst duplicateKeys = duplicates(submission.selectedKeys, function keyOf(value) {\n\t\treturn value\n\t})\n\tif (duplicateKeys.length > 0) {\n\t\tissues.push(\"duplicate selections\")\n\t}\n\tconst unknownKeys = findUnknownIds(submission.selectedKeys, interaction.options)\n\tif (unknownKeys.length > 0) {\n\t\tissues.push(`unknown options: ${unknownKeys.join(\", \")}`)\n\t}\n\treturn issues\n}\n\nfunction validateExtendedText(\n\tinteraction: Extract<RendererInteraction, { type: \"extended-text\" }>,\n\tsubmission: Extract<RendererSubmission, { type: \"extended-text\" }>\n): readonly string[] {\n\tconst issues: string[] = []\n\tif (interaction.cardinality === \"single\") {\n\t\tif (submission.values.length !== 1) {\n\t\t\tissues.push(\"single-cardinality extended-text requires exactly one value\")\n\t\t}\n\t\treturn issues\n\t}\n\tif (submission.values.length < interaction.minStrings) {\n\t\tissues.push(`need at least ${interaction.minStrings} values`)\n\t}\n\tif (submission.values.length > interaction.maxStrings) {\n\t\tissues.push(`at most ${interaction.maxStrings} values`)\n\t}\n\tconst duplicateValues = duplicates(submission.values, function keyOf(value) {\n\t\treturn value\n\t})\n\tif (duplicateValues.length > 0) {\n\t\tissues.push(\"duplicate values are not allowed for multiple-cardinality extended-text\")\n\t}\n\treturn issues\n}\n\nfunction validateOrder(\n\tinteraction: Extract<RendererInteraction, { type: \"order\" }>,\n\tsubmission: Extract<RendererSubmission, { type: \"order\" }>\n): readonly string[] {\n\tconst issues: string[] = []\n\tif (submission.orderedKeys.length < interaction.minChoices) {\n\t\tissues.push(`need at least ${interaction.minChoices} selections`)\n\t}\n\tif (submission.orderedKeys.length > interaction.maxChoices) {\n\t\tissues.push(`at most ${interaction.maxChoices} selections`)\n\t}\n\tconst duplicateKeys = duplicates(submission.orderedKeys, function keyOf(value) {\n\t\treturn value\n\t})\n\tif (duplicateKeys.length > 0) {\n\t\tissues.push(\"duplicate selections\")\n\t}\n\tconst unknownKeys = findUnknownIds(submission.orderedKeys, interaction.choices)\n\tif (unknownKeys.length > 0) {\n\t\tissues.push(`unknown choices: ${unknownKeys.join(\", \")}`)\n\t}\n\treturn issues\n}\n\nfunction validateMatch(\n\tinteraction: Extract<RendererInteraction, { type: \"match\" }>,\n\tsubmission: Extract<RendererSubmission, { type: \"match\" }>\n): readonly string[] {\n\tconst issues: string[] = []\n\tif (submission.pairs.length < interaction.minAssociations) {\n\t\tissues.push(`need at least ${interaction.minAssociations} associations`)\n\t}\n\tif (submission.pairs.length > interaction.maxAssociations) {\n\t\tissues.push(`at most ${interaction.maxAssociations} associations`)\n\t}\n\tconst duplicatePairs = duplicates(submission.pairs, function keyOf(pair) {\n\t\treturn `${pair.source}->${pair.target}`\n\t})\n\tif (duplicatePairs.length > 0) {\n\t\tissues.push(\"duplicate associations are not allowed\")\n\t}\n\tconst sourceIds = new Set(\n\t\tinteraction.sourceChoices.map(function getId(choice) {\n\t\t\treturn choice.identifier\n\t\t})\n\t)\n\tconst targetIds = new Set(\n\t\tinteraction.targetChoices.map(function getId(choice) {\n\t\t\treturn choice.identifier\n\t\t})\n\t)\n\tfor (const pair of submission.pairs) {\n\t\tif (!sourceIds.has(pair.source)) {\n\t\t\tissues.push(`unknown source '${pair.source}'`)\n\t\t}\n\t\tif (!targetIds.has(pair.target)) {\n\t\t\tissues.push(`unknown target '${pair.target}'`)\n\t\t}\n\t}\n\tconst sourceCounts = countByIdentifier(submission.pairs, \"source\")\n\tconst targetCounts = countByIdentifier(submission.pairs, \"target\")\n\tissues.push(...validateUsageBounds(interaction.sourceChoices, sourceCounts, \"source\"))\n\tissues.push(...validateUsageBounds(interaction.targetChoices, targetCounts, \"target\"))\n\treturn issues\n}\n\nfunction validatePortableCustom(\n\tinteraction: Extract<RendererInteraction, { type: \"portable-custom\" }>,\n\tsubmission: Extract<RendererSubmission, { type: \"portable-custom\" }>\n): readonly string[] {\n\tif (submission.pciId !== interaction.pciId) {\n\t\treturn [\n\t\t\t`submission PCI '${submission.pciId}' does not match interaction PCI '${interaction.pciId}'`\n\t\t]\n\t}\n\tconst schema = pciSubmissionSchema(interaction.pciId)\n\tconst result = schema.safeParse(submission.value)\n\tif (!result.success) {\n\t\treturn result.error.issues.map(function toIssue(issue) {\n\t\t\treturn issue.message\n\t\t})\n\t}\n\treturn []\n}\n\nfunction validateSubmissionForInteraction(\n\tinteraction: RendererInteraction,\n\tsubmission: RendererSubmission\n): SubmissionValidationResult {\n\tswitch (interaction.type) {\n\t\tcase \"choice\":\n\t\t\tif (submission.type !== \"choice\") {\n\t\t\t\treturn { ok: false, issues: [typeMismatch(interaction.type, submission.type)] }\n\t\t\t}\n\t\t\treturn buildResult(submission, validateChoice(interaction, submission))\n\t\tcase \"text-entry\":\n\t\t\tif (submission.type !== \"text-entry\") {\n\t\t\t\treturn { ok: false, issues: [typeMismatch(interaction.type, submission.type)] }\n\t\t\t}\n\t\t\treturn { ok: true, value: submission }\n\t\tcase \"extended-text\":\n\t\t\tif (submission.type !== \"extended-text\") {\n\t\t\t\treturn { ok: false, issues: [typeMismatch(interaction.type, submission.type)] }\n\t\t\t}\n\t\t\treturn buildResult(submission, validateExtendedText(interaction, submission))\n\t\tcase \"order\":\n\t\t\tif (submission.type !== \"order\") {\n\t\t\t\treturn { ok: false, issues: [typeMismatch(interaction.type, submission.type)] }\n\t\t\t}\n\t\t\treturn buildResult(submission, validateOrder(interaction, submission))\n\t\tcase \"match\":\n\t\t\tif (submission.type !== \"match\") {\n\t\t\t\treturn { ok: false, issues: [typeMismatch(interaction.type, submission.type)] }\n\t\t\t}\n\t\t\treturn buildResult(submission, validateMatch(interaction, submission))\n\t\tcase \"portable-custom\":\n\t\t\tif (submission.type !== \"portable-custom\") {\n\t\t\t\treturn { ok: false, issues: [typeMismatch(interaction.type, submission.type)] }\n\t\t\t}\n\t\t\treturn buildResult(submission, validatePortableCustom(interaction, submission))\n\t}\n}\n\nfunction submissionValidationMessage(result: SubmissionValidationFailure): string {\n\treturn result.issues.join(\"; \")\n}\n\nexport {\n\tChoiceSubmissionSchema,\n\tDivisionRemainderPciSubmissionSchema,\n\tExtendedTextSubmissionSchema,\n\tFractionAdditionPciSubmissionSchema,\n\tMatchPairSchema,\n\tMatchSubmissionSchema,\n\tOrderSubmissionSchema,\n\tRendererSubmissionSchema,\n\tTextEntrySubmissionSchema,\n\tsubmissionValidationMessage,\n\tvalidateSubmissionForInteraction\n}\nexport type { SubmissionValidationFailure, SubmissionValidationResult, SubmissionValidationSuccess }\n",
|
|
6
6
|
"import { z } from \"zod\"\n\nconst DivisionRemainderPropsSchema = z.object({\n\tdividend: z.number(),\n\tdivisor: z.number()\n})\n\nconst DivisionRemainderSubmissionSchema = z.object({\n\tquotient: z.string(),\n\tremainder: z.string()\n})\n\nconst FractionOperandSchema = z.object({\n\tnumerator: z.number(),\n\tdenominator: z.number()\n})\n\nconst FractionAdditionPropsSchema = z.object({\n\tleft: FractionOperandSchema,\n\tright: FractionOperandSchema\n})\n\nconst FractionAdditionSubmissionSchema = z.object({\n\tnumerator: z.string(),\n\tdenominator: z.string()\n})\n\nexport {\n\tDivisionRemainderPropsSchema,\n\tDivisionRemainderSubmissionSchema,\n\tFractionAdditionPropsSchema,\n\tFractionAdditionSubmissionSchema\n}\n"
|
|
7
7
|
],
|
|
8
|
-
"mappings": ";AAAA,cAAS;;;ACAT;AAEA,IAAM,+BAA+B,EAAE,OAAO;AAAA,EAC7C,UAAU,EAAE,OAAO;AAAA,EACnB,SAAS,EAAE,OAAO;AACnB,CAAC;AAED,IAAM,oCAAoC,EAAE,OAAO;AAAA,EAClD,UAAU,EAAE,OAAO;AAAA,EACnB,WAAW,EAAE,OAAO;AACrB,CAAC;AAED,IAAM,wBAAwB,EAAE,OAAO;AAAA,EACtC,WAAW,EAAE,OAAO;AAAA,EACpB,aAAa,EAAE,OAAO;AACvB,CAAC;AAED,IAAM,8BAA8B,EAAE,OAAO;AAAA,EAC5C,MAAM;AAAA,EACN,OAAO;AACR,CAAC;AAED,IAAM,mCAAmC,EAAE,OAAO;AAAA,EACjD,WAAW,EAAE,OAAO;AAAA,EACpB,aAAa,EAAE,OAAO;AACvB,CAAC;;;
|
|
9
|
-
"debugId": "
|
|
8
|
+
"mappings": "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",
|
|
9
|
+
"debugId": "5A4E82ADE8F4197364756E2164756E21",
|
|
10
10
|
"names": []
|
|
11
11
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import type {
|
|
3
|
-
import type { MatchPair, PciInteraction, RendererInteraction, RendererSubmission } from "./types";
|
|
2
|
+
import type { RendererInteraction, RendererSubmission } from "./types";
|
|
4
3
|
declare const MatchPairSchema: z.ZodObject<{
|
|
5
4
|
source: z.ZodString;
|
|
6
5
|
target: z.ZodString;
|
|
@@ -77,82 +76,17 @@ declare const RendererSubmissionSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
77
76
|
denominator: z.ZodString;
|
|
78
77
|
}, z.core.$strip>;
|
|
79
78
|
}, z.core.$strip>]>;
|
|
80
|
-
type
|
|
81
|
-
type: "choice";
|
|
82
|
-
} ? {
|
|
83
|
-
type: "choice";
|
|
84
|
-
selectedKeys: string[];
|
|
85
|
-
} : I extends {
|
|
86
|
-
type: "text-entry";
|
|
87
|
-
} ? {
|
|
88
|
-
type: "text-entry";
|
|
89
|
-
value: string;
|
|
90
|
-
} : I extends {
|
|
91
|
-
type: "extended-text";
|
|
92
|
-
} ? {
|
|
93
|
-
type: "extended-text";
|
|
94
|
-
values: string[];
|
|
95
|
-
} : I extends {
|
|
96
|
-
type: "order";
|
|
97
|
-
} ? {
|
|
98
|
-
type: "order";
|
|
99
|
-
orderedKeys: string[];
|
|
100
|
-
} : I extends {
|
|
101
|
-
type: "match";
|
|
102
|
-
} ? {
|
|
103
|
-
type: "match";
|
|
104
|
-
pairs: MatchPair[];
|
|
105
|
-
} : I extends PciInteraction<infer SupportedPcis extends PciId> ? {
|
|
106
|
-
[K in SupportedPcis]: {
|
|
107
|
-
type: "portable-custom";
|
|
108
|
-
pciId: K;
|
|
109
|
-
value: Extract<RendererSubmission, {
|
|
110
|
-
type: "portable-custom";
|
|
111
|
-
pciId: K;
|
|
112
|
-
}>["value"];
|
|
113
|
-
};
|
|
114
|
-
}[SupportedPcis] : never;
|
|
115
|
-
type SubmissionValidationSuccess<I extends RendererInteraction = RendererInteraction> = {
|
|
79
|
+
type SubmissionValidationSuccess = {
|
|
116
80
|
ok: true;
|
|
117
|
-
value:
|
|
81
|
+
value: RendererSubmission;
|
|
118
82
|
};
|
|
119
83
|
type SubmissionValidationFailure = {
|
|
120
84
|
ok: false;
|
|
121
|
-
issues: string[];
|
|
85
|
+
issues: readonly string[];
|
|
122
86
|
};
|
|
123
|
-
type SubmissionValidationResult
|
|
124
|
-
declare function validateSubmissionForInteraction(interaction:
|
|
125
|
-
type: "choice";
|
|
126
|
-
}>, submission: RendererSubmission): SubmissionValidationResult<Extract<RendererInteraction, {
|
|
127
|
-
type: "choice";
|
|
128
|
-
}>>;
|
|
129
|
-
declare function validateSubmissionForInteraction(interaction: Extract<RendererInteraction, {
|
|
130
|
-
type: "text-entry";
|
|
131
|
-
}>, submission: RendererSubmission): SubmissionValidationResult<Extract<RendererInteraction, {
|
|
132
|
-
type: "text-entry";
|
|
133
|
-
}>>;
|
|
134
|
-
declare function validateSubmissionForInteraction(interaction: Extract<RendererInteraction, {
|
|
135
|
-
type: "extended-text";
|
|
136
|
-
}>, submission: RendererSubmission): SubmissionValidationResult<Extract<RendererInteraction, {
|
|
137
|
-
type: "extended-text";
|
|
138
|
-
}>>;
|
|
139
|
-
declare function validateSubmissionForInteraction(interaction: Extract<RendererInteraction, {
|
|
140
|
-
type: "order";
|
|
141
|
-
}>, submission: RendererSubmission): SubmissionValidationResult<Extract<RendererInteraction, {
|
|
142
|
-
type: "order";
|
|
143
|
-
}>>;
|
|
144
|
-
declare function validateSubmissionForInteraction(interaction: Extract<RendererInteraction, {
|
|
145
|
-
type: "match";
|
|
146
|
-
}>, submission: RendererSubmission): SubmissionValidationResult<Extract<RendererInteraction, {
|
|
147
|
-
type: "match";
|
|
148
|
-
}>>;
|
|
149
|
-
declare function validateSubmissionForInteraction(interaction: Extract<RendererInteraction, {
|
|
150
|
-
type: "portable-custom";
|
|
151
|
-
}>, submission: RendererSubmission): SubmissionValidationResult<Extract<RendererInteraction, {
|
|
152
|
-
type: "portable-custom";
|
|
153
|
-
}>>;
|
|
154
|
-
declare function validateSubmissionForInteraction<I extends RendererInteraction>(interaction: I, submission: RendererSubmission): SubmissionValidationResult<I>;
|
|
87
|
+
type SubmissionValidationResult = SubmissionValidationSuccess | SubmissionValidationFailure;
|
|
88
|
+
declare function validateSubmissionForInteraction(interaction: RendererInteraction, submission: RendererSubmission): SubmissionValidationResult;
|
|
155
89
|
declare function submissionValidationMessage(result: SubmissionValidationFailure): string;
|
|
156
90
|
export { ChoiceSubmissionSchema, DivisionRemainderPciSubmissionSchema, ExtendedTextSubmissionSchema, FractionAdditionPciSubmissionSchema, MatchPairSchema, MatchSubmissionSchema, OrderSubmissionSchema, RendererSubmissionSchema, TextEntrySubmissionSchema, submissionValidationMessage, validateSubmissionForInteraction };
|
|
157
|
-
export type {
|
|
91
|
+
export type { SubmissionValidationFailure, SubmissionValidationResult, SubmissionValidationSuccess };
|
|
158
92
|
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/contracts/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/contracts/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAQvB,OAAO,KAAK,EAGX,mBAAmB,EAEnB,kBAAkB,EAClB,MAAM,6CAA6C,CAAA;AAEpD,QAAA,MAAM,eAAe;;;iBAGnB,CAAA;AAEF,QAAA,MAAM,sBAAsB;;;iBAG1B,CAAA;AAEF,QAAA,MAAM,yBAAyB;;;iBAG7B,CAAA;AAEF,QAAA,MAAM,4BAA4B;;;iBAGhC,CAAA;AAEF,QAAA,MAAM,qBAAqB;;;iBAGzB,CAAA;AAEF,QAAA,MAAM,qBAAqB;;;;;;iBAGzB,CAAA;AAEF,QAAA,MAAM,oCAAoC;;;;;;;iBAIxC,CAAA;AAEF,QAAA,MAAM,mCAAmC;;;;;;;iBAIvC,CAAA;AAEF,QAAA,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAQ5B,CAAA;AAuEF,KAAK,2BAA2B,GAAG;IAClC,EAAE,EAAE,IAAI,CAAA;IACR,KAAK,EAAE,kBAAkB,CAAA;CACzB,CAAA;AAED,KAAK,2BAA2B,GAAG;IAClC,EAAE,EAAE,KAAK,CAAA;IACT,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;CACzB,CAAA;AAED,KAAK,0BAA0B,GAAG,2BAA2B,GAAG,2BAA2B,CAAA;AAuJ3F,iBAAS,gCAAgC,CACxC,WAAW,EAAE,mBAAmB,EAChC,UAAU,EAAE,kBAAkB,GAC5B,0BAA0B,CAiC5B;AAED,iBAAS,2BAA2B,CAAC,MAAM,EAAE,2BAA2B,GAAG,MAAM,CAEhF;AAED,OAAO,EACN,sBAAsB,EACtB,oCAAoC,EACpC,4BAA4B,EAC5B,mCAAmC,EACnC,eAAe,EACf,qBAAqB,EACrB,qBAAqB,EACrB,wBAAwB,EACxB,yBAAyB,EACzB,2BAA2B,EAC3B,gCAAgC,EAChC,CAAA;AACD,YAAY,EAAE,2BAA2B,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,CAAA"}
|