@superbuilders/primer-tives 1.1.1 → 1.1.2

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 (73) hide show
  1. package/package.json +1 -1
  2. package/dist/client/choice-state.d.ts +0 -8
  3. package/dist/client/choice-state.d.ts.map +0 -1
  4. package/dist/client/consumed.d.ts +0 -3
  5. package/dist/client/consumed.d.ts.map +0 -1
  6. package/dist/client/content.d.ts +0 -20
  7. package/dist/client/content.d.ts.map +0 -1
  8. package/dist/client/create.d.ts +0 -20
  9. package/dist/client/create.d.ts.map +0 -1
  10. package/dist/client/extended-text-state.d.ts +0 -8
  11. package/dist/client/extended-text-state.d.ts.map +0 -1
  12. package/dist/client/feedback-state.d.ts +0 -7
  13. package/dist/client/feedback-state.d.ts.map +0 -1
  14. package/dist/client/index.d.ts +0 -11
  15. package/dist/client/index.d.ts.map +0 -1
  16. package/dist/client/index.js +0 -1123
  17. package/dist/client/index.js.map +0 -26
  18. package/dist/client/match-state.d.ts +0 -8
  19. package/dist/client/match-state.d.ts.map +0 -1
  20. package/dist/client/observation-state.d.ts +0 -6
  21. package/dist/client/observation-state.d.ts.map +0 -1
  22. package/dist/client/order-state.d.ts +0 -8
  23. package/dist/client/order-state.d.ts.map +0 -1
  24. package/dist/client/pci-state.d.ts +0 -6
  25. package/dist/client/pci-state.d.ts.map +0 -1
  26. package/dist/client/pci.d.ts +0 -38
  27. package/dist/client/pci.d.ts.map +0 -1
  28. package/dist/client/session-context.d.ts +0 -19
  29. package/dist/client/session-context.d.ts.map +0 -1
  30. package/dist/client/session.d.ts +0 -18
  31. package/dist/client/session.d.ts.map +0 -1
  32. package/dist/client/text-entry-state.d.ts +0 -8
  33. package/dist/client/text-entry-state.d.ts.map +0 -1
  34. package/dist/client/transport.d.ts +0 -46
  35. package/dist/client/transport.d.ts.map +0 -1
  36. package/dist/client/types.d.ts +0 -194
  37. package/dist/client/types.d.ts.map +0 -1
  38. package/dist/contracts/index.d.ts +0 -4
  39. package/dist/contracts/index.d.ts.map +0 -1
  40. package/dist/contracts/index.js +0 -328
  41. package/dist/contracts/index.js.map +0 -11
  42. package/dist/contracts/pci-schemas.d.ts +0 -25
  43. package/dist/contracts/pci-schemas.d.ts.map +0 -1
  44. package/dist/contracts/types.d.ts +0 -118
  45. package/dist/contracts/types.d.ts.map +0 -1
  46. package/dist/contracts/validation.d.ts +0 -158
  47. package/dist/contracts/validation.d.ts.map +0 -1
  48. package/dist/errors.d.ts +0 -23
  49. package/dist/errors.d.ts.map +0 -1
  50. package/dist/errors.js +0 -48
  51. package/dist/errors.js.map +0 -10
  52. package/dist/grade-level.d.ts +0 -5
  53. package/dist/grade-level.d.ts.map +0 -1
  54. package/dist/index.d.ts +0 -3
  55. package/dist/index.d.ts.map +0 -1
  56. package/dist/index.js +0 -372
  57. package/dist/index.js.map +0 -12
  58. package/dist/logger.d.ts +0 -8
  59. package/dist/logger.d.ts.map +0 -1
  60. package/dist/server/create-server.d.ts +0 -44
  61. package/dist/server/create-server.d.ts.map +0 -1
  62. package/dist/server/exchange.d.ts +0 -22
  63. package/dist/server/exchange.d.ts.map +0 -1
  64. package/dist/server/hints.d.ts +0 -25
  65. package/dist/server/hints.d.ts.map +0 -1
  66. package/dist/server/index.d.ts +0 -9
  67. package/dist/server/index.d.ts.map +0 -1
  68. package/dist/server/index.js +0 -531
  69. package/dist/server/index.js.map +0 -15
  70. package/dist/server/students.d.ts +0 -12
  71. package/dist/server/students.d.ts.map +0 -1
  72. package/dist/subject.d.ts +0 -6
  73. package/dist/subject.d.ts.map +0 -1
package/dist/index.js DELETED
@@ -1,372 +0,0 @@
1
- // src/contracts/validation.ts
2
- import { z as z2 } from "zod";
3
-
4
- // src/contracts/pci-schemas.ts
5
- import { z } from "zod";
6
- var DivisionRemainderPropsSchema = z.object({
7
- dividend: z.number(),
8
- divisor: z.number()
9
- });
10
- var DivisionRemainderSubmissionSchema = z.object({
11
- quotient: z.string(),
12
- remainder: z.string()
13
- });
14
- var FractionOperandSchema = z.object({
15
- numerator: z.number(),
16
- denominator: z.number()
17
- });
18
- var FractionAdditionPropsSchema = z.object({
19
- left: FractionOperandSchema,
20
- right: FractionOperandSchema
21
- });
22
- var FractionAdditionSubmissionSchema = z.object({
23
- numerator: z.string(),
24
- denominator: z.string()
25
- });
26
-
27
- // src/contracts/validation.ts
28
- var MatchPairSchema = z2.object({
29
- source: z2.string(),
30
- target: z2.string()
31
- });
32
- var ChoiceSubmissionSchema = z2.object({
33
- type: z2.literal("choice"),
34
- selectedKeys: z2.array(z2.string())
35
- });
36
- var TextEntrySubmissionSchema = z2.object({
37
- type: z2.literal("text-entry"),
38
- value: z2.string()
39
- });
40
- var ExtendedTextSubmissionSchema = z2.object({
41
- type: z2.literal("extended-text"),
42
- values: z2.array(z2.string()).min(1)
43
- });
44
- var OrderSubmissionSchema = z2.object({
45
- type: z2.literal("order"),
46
- orderedKeys: z2.array(z2.string())
47
- });
48
- var MatchSubmissionSchema = z2.object({
49
- type: z2.literal("match"),
50
- pairs: z2.array(MatchPairSchema)
51
- });
52
- var DivisionRemainderPciSubmissionSchema = z2.object({
53
- type: z2.literal("portable-custom"),
54
- pciId: z2.literal("urn:primer:pci:division-remainder"),
55
- value: DivisionRemainderSubmissionSchema
56
- });
57
- var FractionAdditionPciSubmissionSchema = z2.object({
58
- type: z2.literal("portable-custom"),
59
- pciId: z2.literal("urn:primer:pci:fraction-addition"),
60
- value: FractionAdditionSubmissionSchema
61
- });
62
- var RendererSubmissionSchema = z2.union([
63
- ChoiceSubmissionSchema,
64
- TextEntrySubmissionSchema,
65
- ExtendedTextSubmissionSchema,
66
- OrderSubmissionSchema,
67
- MatchSubmissionSchema,
68
- DivisionRemainderPciSubmissionSchema,
69
- FractionAdditionPciSubmissionSchema
70
- ]);
71
- function invalid(issues) {
72
- return {
73
- ok: false,
74
- issues: Array.isArray(issues) ? issues : [issues]
75
- };
76
- }
77
- function duplicates(values, keyOf) {
78
- const seen = new Set;
79
- const duplicated = new Set;
80
- for (const value of values) {
81
- const key = keyOf(value);
82
- if (seen.has(key)) {
83
- duplicated.add(key);
84
- continue;
85
- }
86
- seen.add(key);
87
- }
88
- return [...duplicated];
89
- }
90
- function findUnknownIds(values, choices) {
91
- const ids = new Set(choices.map(function getId(choice) {
92
- return choice.identifier;
93
- }));
94
- return values.filter(function isUnknown(value) {
95
- return !ids.has(value);
96
- });
97
- }
98
- function countByIdentifier(pairs, side) {
99
- const counts = new Map;
100
- for (const pair of pairs) {
101
- const key = pair[side];
102
- const currentCount = counts.get(key);
103
- if (currentCount === undefined) {
104
- counts.set(key, 1);
105
- continue;
106
- }
107
- counts.set(key, currentCount + 1);
108
- }
109
- return counts;
110
- }
111
- function validateUsageBounds(choices, counts, side) {
112
- const issues = [];
113
- for (const choice of choices) {
114
- const maybeCount = counts.get(choice.identifier);
115
- const count = maybeCount === undefined ? 0 : maybeCount;
116
- if (choice.matchMax !== 0 && count > choice.matchMax) {
117
- issues.push(`${side} '${choice.identifier}' used ${count} times, max ${choice.matchMax}`);
118
- }
119
- if (count < choice.matchMin) {
120
- issues.push(`${side} '${choice.identifier}' used ${count} times, min ${choice.matchMin}`);
121
- }
122
- }
123
- return issues;
124
- }
125
- function pciSubmissionSchema(pciId) {
126
- switch (pciId) {
127
- case "urn:primer:pci:division-remainder":
128
- return DivisionRemainderSubmissionSchema;
129
- case "urn:primer:pci:fraction-addition":
130
- return FractionAdditionSubmissionSchema;
131
- }
132
- const exhaustiveCheck = pciId;
133
- return exhaustiveCheck;
134
- }
135
- function validateChoiceSubmission(interaction, submission) {
136
- if (submission.type !== "choice") {
137
- return invalid(`submission type '${submission.type}' does not match interaction type 'choice'`);
138
- }
139
- const issues = [];
140
- if (submission.selectedKeys.length < interaction.minChoices) {
141
- issues.push(`need at least ${interaction.minChoices} selections`);
142
- }
143
- if (submission.selectedKeys.length > interaction.maxChoices) {
144
- issues.push(`at most ${interaction.maxChoices} selections`);
145
- }
146
- const duplicateKeys = duplicates(submission.selectedKeys, function keyOf(value) {
147
- return value;
148
- });
149
- if (duplicateKeys.length > 0) {
150
- issues.push("duplicate selections");
151
- }
152
- const unknownKeys = findUnknownIds(submission.selectedKeys, interaction.options);
153
- if (unknownKeys.length > 0) {
154
- issues.push(`unknown options: ${unknownKeys.join(", ")}`);
155
- }
156
- if (issues.length > 0) {
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
- };
172
- }
173
- function validateExtendedTextSubmission(interaction, submission) {
174
- if (submission.type !== "extended-text") {
175
- return invalid(`submission type '${submission.type}' does not match interaction type 'extended-text'`);
176
- }
177
- const issues = [];
178
- if (interaction.cardinality === "single") {
179
- if (submission.values.length !== 1) {
180
- issues.push("single-cardinality extended-text requires exactly one value");
181
- }
182
- } else {
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
- }
195
- }
196
- if (issues.length > 0) {
197
- return invalid(issues);
198
- }
199
- return {
200
- ok: true,
201
- value: { ...submission }
202
- };
203
- }
204
- function validateOrderSubmission(interaction, submission) {
205
- if (submission.type !== "order") {
206
- return invalid(`submission type '${submission.type}' does not match interaction type 'order'`);
207
- }
208
- const issues = [];
209
- if (submission.orderedKeys.length < interaction.minChoices) {
210
- issues.push(`need at least ${interaction.minChoices} selections`);
211
- }
212
- if (submission.orderedKeys.length > interaction.maxChoices) {
213
- issues.push(`at most ${interaction.maxChoices} selections`);
214
- }
215
- const duplicateKeys = duplicates(submission.orderedKeys, function keyOf(value) {
216
- return value;
217
- });
218
- if (duplicateKeys.length > 0) {
219
- issues.push("duplicate selections");
220
- }
221
- const unknownKeys = findUnknownIds(submission.orderedKeys, interaction.choices);
222
- if (unknownKeys.length > 0) {
223
- issues.push(`unknown choices: ${unknownKeys.join(", ")}`);
224
- }
225
- if (issues.length > 0) {
226
- return invalid(issues);
227
- }
228
- return {
229
- ok: true,
230
- value: { ...submission }
231
- };
232
- }
233
- function validateMatchSubmission(interaction, submission) {
234
- if (submission.type !== "match") {
235
- return invalid(`submission type '${submission.type}' does not match interaction type 'match'`);
236
- }
237
- const issues = [];
238
- if (submission.pairs.length < interaction.minAssociations) {
239
- issues.push(`need at least ${interaction.minAssociations} associations`);
240
- }
241
- if (submission.pairs.length > interaction.maxAssociations) {
242
- issues.push(`at most ${interaction.maxAssociations} associations`);
243
- }
244
- const duplicatePairs = duplicates(submission.pairs, function keyOf(pair) {
245
- return `${pair.source}->${pair.target}`;
246
- });
247
- if (duplicatePairs.length > 0) {
248
- issues.push("duplicate associations are not allowed");
249
- }
250
- const sourceIds = new Set(interaction.sourceChoices.map(function getId(choice) {
251
- return choice.identifier;
252
- }));
253
- const targetIds = new Set(interaction.targetChoices.map(function getId(choice) {
254
- return choice.identifier;
255
- }));
256
- for (const pair of submission.pairs) {
257
- if (!sourceIds.has(pair.source)) {
258
- issues.push(`unknown source '${pair.source}'`);
259
- }
260
- if (!targetIds.has(pair.target)) {
261
- issues.push(`unknown target '${pair.target}'`);
262
- }
263
- }
264
- const sourceCounts = countByIdentifier(submission.pairs, "source");
265
- const targetCounts = countByIdentifier(submission.pairs, "target");
266
- issues.push(...validateUsageBounds(interaction.sourceChoices, sourceCounts, "source"));
267
- issues.push(...validateUsageBounds(interaction.targetChoices, targetCounts, "target"));
268
- if (issues.length > 0) {
269
- return invalid(issues);
270
- }
271
- return {
272
- ok: true,
273
- value: { ...submission }
274
- };
275
- }
276
- function validatePortableCustomSubmission(interaction, submission) {
277
- if (submission.type !== "portable-custom") {
278
- return invalid(`submission type '${submission.type}' does not match interaction type 'portable-custom'`);
279
- }
280
- if (submission.pciId !== interaction.pciId) {
281
- return invalid(`submission PCI '${submission.pciId}' does not match interaction PCI '${interaction.pciId}'`);
282
- }
283
- const schema = pciSubmissionSchema(interaction.pciId);
284
- const result = schema.safeParse(submission.value);
285
- if (!result.success) {
286
- return invalid(result.error.issues.map(function toIssue(issue) {
287
- return issue.message;
288
- }));
289
- }
290
- return {
291
- ok: true,
292
- value: { ...submission }
293
- };
294
- }
295
- function validateSubmissionForInteraction(interaction, submission) {
296
- switch (interaction.type) {
297
- case "choice":
298
- return validateChoiceSubmission(interaction, submission);
299
- case "text-entry":
300
- return validateTextEntrySubmission(interaction, submission);
301
- case "extended-text":
302
- return validateExtendedTextSubmission(interaction, submission);
303
- case "order":
304
- return validateOrderSubmission(interaction, submission);
305
- case "match":
306
- return validateMatchSubmission(interaction, submission);
307
- case "portable-custom":
308
- return validatePortableCustomSubmission(interaction, submission);
309
- }
310
- }
311
- function submissionValidationMessage(result) {
312
- return result.issues.join("; ");
313
- }
314
- // src/errors.ts
315
- import * as errors from "@superbuilders/errors";
316
- var ErrNetwork = errors.new("network");
317
- var ErrJsonParse = errors.new("json parse");
318
- var ErrUnsupportedPci = errors.new("unsupported pci");
319
- var ErrInvalidAccessToken = errors.new("invalid access token");
320
- var ErrMalformedAccessToken = errors.new("malformed access token");
321
- var ErrTokenExpired = errors.new("access token expired");
322
- var ErrBadRequest = errors.new("bad request");
323
- var ErrServerError = errors.new("server error");
324
- var ErrTimeout = errors.new("timeout");
325
- var ErrForbidden = errors.new("forbidden");
326
- var ErrNotFound = errors.new("not found");
327
- var ErrConflict = errors.new("conflict");
328
- var ErrExternalAuthorityRequired = errors.new("external authority required");
329
- var ErrRateLimited = errors.new("rate limited");
330
- var ErrServiceUnavailable = errors.new("service unavailable");
331
- var ErrNotSerializable = errors.new("PrimerState is live in-memory state and must not be serialized or stored");
332
- var ErrInvalidSubmission = errors.new("invalid submission");
333
- var ErrInvalidSecretKey = errors.new("invalid secret key");
334
- var ErrStudentNotFound = errors.new("student not found");
335
- var ErrUnsupportedGrade = errors.new("unsupported grade");
336
- var ErrTimebackUnavailable = errors.new("timeback unavailable");
337
- export {
338
- validateSubmissionForInteraction,
339
- submissionValidationMessage,
340
- TextEntrySubmissionSchema,
341
- RendererSubmissionSchema,
342
- OrderSubmissionSchema,
343
- MatchSubmissionSchema,
344
- MatchPairSchema,
345
- FractionAdditionPciSubmissionSchema,
346
- ExtendedTextSubmissionSchema,
347
- ErrUnsupportedPci,
348
- ErrUnsupportedGrade,
349
- ErrTokenExpired,
350
- ErrTimeout,
351
- ErrTimebackUnavailable,
352
- ErrStudentNotFound,
353
- ErrServiceUnavailable,
354
- ErrServerError,
355
- ErrRateLimited,
356
- ErrNotSerializable,
357
- ErrNotFound,
358
- ErrNetwork,
359
- ErrMalformedAccessToken,
360
- ErrJsonParse,
361
- ErrInvalidSubmission,
362
- ErrInvalidSecretKey,
363
- ErrInvalidAccessToken,
364
- ErrForbidden,
365
- ErrExternalAuthorityRequired,
366
- ErrConflict,
367
- ErrBadRequest,
368
- DivisionRemainderPciSubmissionSchema,
369
- ChoiceSubmissionSchema
370
- };
371
-
372
- //# debugId=FB2D695B2780D29264756E2164756E21
package/dist/index.js.map DELETED
@@ -1,12 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/contracts/validation.ts", "../src/contracts/pci-schemas.ts", "../src/errors.ts"],
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",
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
- "import * as errors from \"@superbuilders/errors\"\n\nconst ErrNetwork = errors.new(\"network\")\nconst ErrJsonParse = errors.new(\"json parse\")\nconst ErrUnsupportedPci = errors.new(\"unsupported pci\")\nconst ErrInvalidAccessToken = errors.new(\"invalid access token\")\nconst ErrMalformedAccessToken = errors.new(\"malformed access token\")\nconst ErrTokenExpired = errors.new(\"access token expired\")\nconst ErrBadRequest = errors.new(\"bad request\")\nconst ErrServerError = errors.new(\"server error\")\nconst ErrTimeout = errors.new(\"timeout\")\nconst ErrForbidden = errors.new(\"forbidden\")\nconst ErrNotFound = errors.new(\"not found\")\nconst ErrConflict = errors.new(\"conflict\")\nconst ErrExternalAuthorityRequired = errors.new(\"external authority required\")\nconst ErrRateLimited = errors.new(\"rate limited\")\nconst ErrServiceUnavailable = errors.new(\"service unavailable\")\nconst ErrNotSerializable = errors.new(\n\t\"PrimerState is live in-memory state and must not be serialized or stored\"\n)\nconst ErrInvalidSubmission = errors.new(\"invalid submission\")\n\nconst ErrInvalidSecretKey = errors.new(\"invalid secret key\")\nconst ErrStudentNotFound = errors.new(\"student not found\")\nconst ErrUnsupportedGrade = errors.new(\"unsupported grade\")\nconst ErrTimebackUnavailable = errors.new(\"timeback unavailable\")\n\nexport {\n\tErrBadRequest,\n\tErrConflict,\n\tErrExternalAuthorityRequired,\n\tErrForbidden,\n\tErrInvalidAccessToken,\n\tErrInvalidSecretKey,\n\tErrInvalidSubmission,\n\tErrJsonParse,\n\tErrMalformedAccessToken,\n\tErrNetwork,\n\tErrNotFound,\n\tErrNotSerializable,\n\tErrRateLimited,\n\tErrServerError,\n\tErrServiceUnavailable,\n\tErrStudentNotFound,\n\tErrTimebackUnavailable,\n\tErrTimeout,\n\tErrTokenExpired,\n\tErrUnsupportedGrade,\n\tErrUnsupportedPci\n}\n"
8
- ],
9
- "mappings": "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",
10
- "debugId": "FB2D695B2780D29264756E2164756E21",
11
- "names": []
12
- }
package/dist/logger.d.ts DELETED
@@ -1,8 +0,0 @@
1
- interface PrimerLogger {
2
- debug(message: string, attributes?: Record<string, unknown>): void;
3
- info(message: string, attributes?: Record<string, unknown>): void;
4
- warn(message: string, attributes?: Record<string, unknown>): void;
5
- error(message: string, attributes?: Record<string, unknown>): void;
6
- }
7
- export type { PrimerLogger };
8
- //# sourceMappingURL=logger.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,UAAU,YAAY;IACrB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IAClE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IACjE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IACjE,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;CAClE;AAED,YAAY,EAAE,YAAY,EAAE,CAAA"}
@@ -1,44 +0,0 @@
1
- import type { PrimerLogger } from "../logger";
2
- import { type SessionToken, type TimebackSession } from "./exchange";
3
- import { type PlacementHints, type PlacementHintsResult } from "./hints";
4
- interface PrimerServerConfig {
5
- readonly origin: string;
6
- readonly secretKey: string;
7
- readonly fetch?: typeof globalThis.fetch;
8
- readonly abort?: AbortController;
9
- readonly logger: PrimerLogger;
10
- }
11
- interface PrimerServer {
12
- /**
13
- * Provisions a frontend-owned Primer student and returns the stable
14
- * student id you persist in your own DB keyed by your user. Native
15
- * students are created hint-less; call `setStudentHints` at least
16
- * once (with a `gradeLevel`) before the student's first session, or
17
- * the first `/advance` call will 500.
18
- */
19
- createStudent(): Promise<string>;
20
- /**
21
- * Partial update of a student's placement-routing hints. Pass only
22
- * the fields you want to set; omitted fields are left untouched.
23
- * Returns the persisted state after upsert. Today the only hint is
24
- * `gradeLevel`; future hint kinds (raw context, interests, etc.)
25
- * will appear as additional optional fields.
26
- */
27
- setStudentHints(studentId: string, hints: PlacementHints): Promise<PlacementHintsResult>;
28
- /**
29
- * Exchanges a frontend-owned native/manual student id for a short-lived
30
- * access token. Pass `accessToken` from the returned `SessionToken` to
31
- * `create()` on the browser SDK.
32
- */
33
- exchangeStudentForAccessToken(studentId: string): Promise<SessionToken>;
34
- /**
35
- * Verifies the learner against live Timeback authority, resolves or
36
- * provisions the corresponding frontend-owned Primer student, and
37
- * returns both the stable student id and a short-lived access token.
38
- */
39
- exchangeTimebackStudentForAccessToken(sourcedId: string): Promise<TimebackSession>;
40
- }
41
- declare function createPrimerServer(config: PrimerServerConfig): PrimerServer;
42
- export type { PrimerServer, PrimerServerConfig };
43
- export { createPrimerServer };
44
- //# sourceMappingURL=create-server.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-server.d.ts","sourceRoot":"","sources":["../../src/server/create-server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAA;AACtE,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,eAAe,EAGpB,MAAM,6CAA6C,CAAA;AAEpD,OAAO,EACN,KAAK,cAAc,EACnB,KAAK,oBAAoB,EAEzB,MAAM,0CAA0C,CAAA;AAGjD,UAAU,kBAAkB;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;IACxC,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,CAAA;IAChC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;CAC7B;AAED,UAAU,YAAY;IACrB;;;;;;OAMG;IACH,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;IAEhC;;;;;;OAMG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAA;IAExF;;;;OAIG;IACH,6BAA6B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;IAEvE;;;;OAIG;IACH,qCAAqC,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAA;CAClF;AAED,iBAAS,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,YAAY,CAepE;AAED,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,CAAA;AAChD,OAAO,EAAE,kBAAkB,EAAE,CAAA"}
@@ -1,22 +0,0 @@
1
- import type { PrimerLogger } from "../logger";
2
- interface ExchangeConfig {
3
- readonly origin: string;
4
- readonly secretKey: string;
5
- readonly fetch?: typeof globalThis.fetch;
6
- readonly abort?: AbortController;
7
- readonly logger: PrimerLogger;
8
- }
9
- interface SessionToken {
10
- readonly accessToken: string;
11
- readonly expiresInSeconds: number;
12
- }
13
- interface TimebackSession {
14
- readonly studentId: string;
15
- readonly accessToken: string;
16
- readonly expiresInSeconds: number;
17
- }
18
- declare function exchangeStudent(config: ExchangeConfig, studentId: string): Promise<SessionToken>;
19
- declare function exchangeTimebackStudent(config: ExchangeConfig, sourcedId: string): Promise<TimebackSession>;
20
- export type { ExchangeConfig, SessionToken, TimebackSession };
21
- export { exchangeStudent, exchangeTimebackStudent };
22
- //# sourceMappingURL=exchange.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"exchange.d.ts","sourceRoot":"","sources":["../../src/server/exchange.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAA;AAKtE,UAAU,cAAc;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;IACxC,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,CAAA;IAChC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;CAC7B;AAED,UAAU,YAAY;IACrB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;CACjC;AAED,UAAU,eAAe;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;CACjC;AA8OD,iBAAe,eAAe,CAAC,MAAM,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAmB/F;AAED,iBAAe,uBAAuB,CACrC,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,MAAM,GACf,OAAO,CAAC,eAAe,CAAC,CAmB1B;AAED,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,eAAe,EAAE,CAAA;AAC7D,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,CAAA"}
@@ -1,25 +0,0 @@
1
- import { type GradeLevel } from "../grade-level";
2
- import type { PrimerLogger } from "../logger";
3
- interface HintsConfig {
4
- readonly origin: string;
5
- readonly secretKey: string;
6
- readonly fetch?: typeof globalThis.fetch;
7
- readonly abort?: AbortController;
8
- readonly logger: PrimerLogger;
9
- }
10
- /**
11
- * Partial update of a student's placement hints. Pass only the fields
12
- * you want to set; omitted fields are left untouched. The server
13
- * returns the persisted state after upsert.
14
- */
15
- interface PlacementHints {
16
- readonly gradeLevel?: GradeLevel;
17
- }
18
- interface PlacementHintsResult {
19
- readonly studentId: string;
20
- readonly gradeLevel: GradeLevel | null;
21
- }
22
- declare function setStudentHints(config: HintsConfig, studentId: string, hints: PlacementHints): Promise<PlacementHintsResult>;
23
- export type { HintsConfig, PlacementHints, PlacementHintsResult };
24
- export { setStudentHints };
25
- //# sourceMappingURL=hints.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hints.d.ts","sourceRoot":"","sources":["../../src/server/hints.ts"],"names":[],"mappings":"AAUA,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,yCAAyC,CAAA;AACvF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAA;AAItE,UAAU,WAAW;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;IACxC,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,CAAA;IAChC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;CAC7B;AAED;;;;GAIG;AACH,UAAU,cAAc;IACvB,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAA;CAChC;AAED,UAAU,oBAAoB;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAA;CACtC;AAwKD,iBAAe,eAAe,CAC7B,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,cAAc,GACnB,OAAO,CAAC,oBAAoB,CAAC,CAkB/B;AAED,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,oBAAoB,EAAE,CAAA;AACjE,OAAO,EAAE,eAAe,EAAE,CAAA"}
@@ -1,9 +0,0 @@
1
- export { createPrimerServer } from "./create-server";
2
- export type { PrimerServer, PrimerServerConfig } from "./create-server";
3
- export type { SessionToken, TimebackSession } from "./exchange";
4
- export type { PlacementHints, PlacementHintsResult } from "./hints";
5
- export type { GradeLevel } from "../grade-level";
6
- export { GRADE_LEVELS } from "../grade-level";
7
- export type { PrimerLogger } from "../logger";
8
- export { ErrBadRequest, ErrConflict, ErrExternalAuthorityRequired, ErrInvalidSecretKey, ErrJsonParse, ErrNetwork, ErrServerError, ErrStudentNotFound, ErrTimebackUnavailable, ErrTimeout, ErrUnsupportedGrade } from "../errors";
9
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kDAAkD,CAAA;AACrF,YAAY,EACX,YAAY,EACZ,kBAAkB,EAClB,MAAM,kDAAkD,CAAA;AAEzD,YAAY,EACX,YAAY,EACZ,eAAe,EACf,MAAM,6CAA6C,CAAA;AAEpD,YAAY,EACX,cAAc,EACd,oBAAoB,EACpB,MAAM,0CAA0C,CAAA;AACjD,YAAY,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAA;AACzE,OAAO,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAA;AACtE,YAAY,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAA;AAEtE,OAAO,EACN,aAAa,EACb,WAAW,EACX,4BAA4B,EAC5B,mBAAmB,EACnB,YAAY,EACZ,UAAU,EACV,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,UAAU,EACV,mBAAmB,EACnB,MAAM,oCAAoC,CAAA"}