@playcademy/sdk 0.18.0 → 0.18.1-beta.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.
- package/README.md +61 -4
- package/dist/index.d.ts +2 -1
- package/dist/index.js +51 -32
- package/dist/internal.d.ts +1 -1
- package/dist/internal.js +51 -32
- package/dist/server/edge.d.ts +2 -1
- package/dist/server/edge.js +15 -2
- package/dist/server.d.ts +2 -1
- package/dist/server.js +15 -2
- package/dist/types.d.ts +3 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# @playcademy/sdk
|
|
2
2
|
|
|
3
|
-
TypeScript SDK for building games on the Playcademy platform
|
|
3
|
+
**TypeScript SDK for building games on the Playcademy platform.**
|
|
4
|
+
|
|
5
|
+
Use the browser client to connect a game to platform services, or the server client to handle
|
|
6
|
+
authenticated operations in a game backend. Platform tooling uses the separate internal entry point.
|
|
4
7
|
|
|
5
8
|
## Overview
|
|
6
9
|
|
|
@@ -21,6 +24,21 @@ The SDK is the interface between your game and the Playcademy platform. It provi
|
|
|
21
24
|
| `@playcademy/sdk/types` | Type-only imports |
|
|
22
25
|
| `@playcademy/sdk/test` | Test utilities |
|
|
23
26
|
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
Install the SDK in your game project:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
bun add @playcademy/sdk
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
For Vite-based games, add the development plugin and follow its
|
|
36
|
+
[setup guide](../vite-plugin/README.md):
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
bun add -d @playcademy/vite-plugin
|
|
40
|
+
```
|
|
41
|
+
|
|
24
42
|
## Quick Start
|
|
25
43
|
|
|
26
44
|
```typescript
|
|
@@ -160,8 +178,10 @@ navigation, feedback, and submission independently:
|
|
|
160
178
|
resume.
|
|
161
179
|
- `platform-routed-item-submit` is used for adaptive diagnostics. Render only
|
|
162
180
|
`routing.next.itemIdentifier`, submit it with `routing.next.nodeKey`, and replace local state with
|
|
163
|
-
the returned canonical routing snapshot.
|
|
164
|
-
|
|
181
|
+
the returned canonical routing snapshot. Each receipt includes the trusted item `score` and
|
|
182
|
+
`isCorrect` verdict used by Platform to choose that snapshot; authored answers and private routing
|
|
183
|
+
data remain server-only. `submit()` becomes available only after routing reports
|
|
184
|
+
`ready-to-complete`.
|
|
165
185
|
|
|
166
186
|
The host rejects the wrong mutation for each flow, rejects premature finalization, and enforces
|
|
167
187
|
`expectedResponseVersion` for every mutation. Hosted and local providers execute the same routing
|
|
@@ -309,9 +329,46 @@ try {
|
|
|
309
329
|
|
|
310
330
|
## Development
|
|
311
331
|
|
|
312
|
-
|
|
332
|
+
For SDK contributors working in this monorepo, the primary workflow starts at the repository root:
|
|
333
|
+
|
|
334
|
+
```bash
|
|
335
|
+
bun dev
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
This starts the shared platform development environment. Run validation from the root as well:
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
bun run check
|
|
342
|
+
bun run test unit
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
For game developers consuming the SDK outside the monorepo, run your game's development command
|
|
346
|
+
with `@playcademy/vite-plugin` configured. The plugin starts a local sandbox with mock auth, a local
|
|
347
|
+
API, and game asset serving — no platform account or monorepo checkout is needed.
|
|
313
348
|
|
|
314
349
|
```typescript
|
|
315
350
|
// Automatic — vite plugin handles everything
|
|
316
351
|
const client = await PlaycademyClient.init()
|
|
317
352
|
```
|
|
353
|
+
|
|
354
|
+
## Dependencies
|
|
355
|
+
|
|
356
|
+
- Peer dependencies: TypeScript (`^5 || ^6`) and Drizzle ORM (`^0.42.0`), as declared in
|
|
357
|
+
[package.json](./package.json).
|
|
358
|
+
- Workspace development dependencies include `@playcademy/types`, `@playcademy/constants`,
|
|
359
|
+
`@playcademy/utils`, and `@playcademy/test-utils`. Contributors install these through the root
|
|
360
|
+
workspace; game projects do not need to install private workspace packages.
|
|
361
|
+
- `@playcademy/vite-plugin` provides local sandbox integration for Vite games.
|
|
362
|
+
|
|
363
|
+
## Examples
|
|
364
|
+
|
|
365
|
+
- [Basic game](../../examples/basic) — browser SDK initialization and platform services.
|
|
366
|
+
- [Full-stack game](../../examples/full-stack) — game backend routes and server-side integration.
|
|
367
|
+
- [TimeBack game](../../examples/timeback) — activity tracking, hosted assessments, and local fixtures.
|
|
368
|
+
|
|
369
|
+
## Related Packages
|
|
370
|
+
|
|
371
|
+
- [@playcademy/vite-plugin](../vite-plugin) — Vite integration and local game development.
|
|
372
|
+
- [playcademy](../cli) — CLI for game setup, deployment, and platform operations.
|
|
373
|
+
- [@playcademy/types](../types) — shared platform API contracts.
|
|
374
|
+
- [@playcademy/ui-react](../ui-react) — React assessment rendering and game UI components.
|
package/dist/index.d.ts
CHANGED
|
@@ -1555,7 +1555,8 @@ declare class PlaycademyClient extends PlaycademyBaseClient {
|
|
|
1555
1555
|
*/
|
|
1556
1556
|
timeback: {
|
|
1557
1557
|
assessments: {
|
|
1558
|
-
|
|
1558
|
+
prepare: (input: _playcademy_types.StartAssessmentInput) => Promise<_playcademy_types.AssessmentPreparationResult>;
|
|
1559
|
+
start: (input: _playcademy_types.StartAssessmentInput, options?: _playcademy_types.StartAssessmentOptions) => Promise<_playcademy_types.AssessmentAttemptSnapshot>;
|
|
1559
1560
|
latest: (options: _playcademy_types.GetLatestAssessmentOptions) => Promise<_playcademy_types.LatestAssessmentResult | null>;
|
|
1560
1561
|
get: (attemptId: string) => Promise<_playcademy_types.AssessmentAttemptSnapshot>;
|
|
1561
1562
|
stop: (attemptId: string) => Promise<{
|
package/dist/index.js
CHANGED
|
@@ -2780,6 +2780,13 @@ function createScoresNamespace(client) {
|
|
|
2780
2780
|
}
|
|
2781
2781
|
};
|
|
2782
2782
|
}
|
|
2783
|
+
// src/core/timeback/assessment-request.ts
|
|
2784
|
+
function canonicalAssessmentInput(input) {
|
|
2785
|
+
const request = { ...input };
|
|
2786
|
+
delete request.preparationReceipt;
|
|
2787
|
+
return request;
|
|
2788
|
+
}
|
|
2789
|
+
|
|
2783
2790
|
// src/core/cache/ttl-cache.ts
|
|
2784
2791
|
function createTTLCache(options) {
|
|
2785
2792
|
const cache = new Map;
|
|
@@ -3065,6 +3072,38 @@ function validateAssessmentFilters(options) {
|
|
|
3065
3072
|
}
|
|
3066
3073
|
}
|
|
3067
3074
|
}
|
|
3075
|
+
function validateStartAssessmentInput(input) {
|
|
3076
|
+
if (!input.activityId?.trim()) {
|
|
3077
|
+
throw new Error("activityId is required");
|
|
3078
|
+
}
|
|
3079
|
+
validateAssessmentFilters(input);
|
|
3080
|
+
if (input.purpose === "diagnostic" && !input.diagnosticKey?.trim()) {
|
|
3081
|
+
throw new Error("diagnosticKey is required for diagnostic assessments");
|
|
3082
|
+
}
|
|
3083
|
+
if (input.purpose === "diagnostic" && input.diagnosticKey.trim().length > 200) {
|
|
3084
|
+
throw new Error("diagnosticKey must contain at most 200 characters");
|
|
3085
|
+
}
|
|
3086
|
+
if (input.purpose !== "review") {
|
|
3087
|
+
return;
|
|
3088
|
+
}
|
|
3089
|
+
if (!Array.isArray(input.standards) || input.standards.length === 0) {
|
|
3090
|
+
throw new Error("standards must contain at least one standard for review");
|
|
3091
|
+
}
|
|
3092
|
+
if (input.standards.length > TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.standards) {
|
|
3093
|
+
throw new Error(`standards must contain at most ${TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.standards} standards`);
|
|
3094
|
+
}
|
|
3095
|
+
for (const standard of input.standards) {
|
|
3096
|
+
if (!standard || typeof standard !== "object" || !standard.framework?.trim() || !standard.identifier?.trim()) {
|
|
3097
|
+
throw new Error("review standards require a framework and identifier");
|
|
3098
|
+
}
|
|
3099
|
+
if (standard.framework.trim().length > TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.standardFieldLength || standard.identifier.trim().length > TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.standardFieldLength) {
|
|
3100
|
+
throw new Error(`review standard fields must be at most ${TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.standardFieldLength} characters`);
|
|
3101
|
+
}
|
|
3102
|
+
}
|
|
3103
|
+
if (input.candidateItemsPerStandard !== undefined && (!Number.isInteger(input.candidateItemsPerStandard) || input.candidateItemsPerStandard <= 0 || input.candidateItemsPerStandard > TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.candidateItemsPerStandard)) {
|
|
3104
|
+
throw new Error(`candidateItemsPerStandard must be a positive integer at most ${TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.candidateItemsPerStandard}`);
|
|
3105
|
+
}
|
|
3106
|
+
}
|
|
3068
3107
|
function createTimebackNamespace(client) {
|
|
3069
3108
|
const engine = createTimebackEngine(client);
|
|
3070
3109
|
const pendingAssessmentSubmissions = new Map;
|
|
@@ -3149,38 +3188,18 @@ function createTimebackNamespace(client) {
|
|
|
3149
3188
|
registerPauseProbe(client, () => engine.activity.isManuallyPaused());
|
|
3150
3189
|
return {
|
|
3151
3190
|
assessments: {
|
|
3152
|
-
|
|
3191
|
+
prepare: async (input) => {
|
|
3192
|
+
assertPlatformMode(client, "timeback.assessments.prepare()");
|
|
3193
|
+
validateStartAssessmentInput(input);
|
|
3194
|
+
return client["requestGameBackend"](`${ASSESSMENTS_ROUTE}/prepare`, "POST", canonicalAssessmentInput(input));
|
|
3195
|
+
},
|
|
3196
|
+
start: async (input, options) => {
|
|
3153
3197
|
assertPlatformMode(client, "timeback.assessments.start()");
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
throw new Error("diagnosticKey is required for diagnostic assessments");
|
|
3160
|
-
}
|
|
3161
|
-
if (input.purpose === "diagnostic" && input.diagnosticKey.trim().length > 200) {
|
|
3162
|
-
throw new Error("diagnosticKey must contain at most 200 characters");
|
|
3163
|
-
}
|
|
3164
|
-
if (input.purpose === "review") {
|
|
3165
|
-
if (!Array.isArray(input.standards) || input.standards.length === 0) {
|
|
3166
|
-
throw new Error("standards must contain at least one standard for review");
|
|
3167
|
-
}
|
|
3168
|
-
if (input.standards.length > TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.standards) {
|
|
3169
|
-
throw new Error(`standards must contain at most ${TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.standards} standards`);
|
|
3170
|
-
}
|
|
3171
|
-
for (const standard of input.standards) {
|
|
3172
|
-
if (!standard || typeof standard !== "object" || !standard.framework?.trim() || !standard.identifier?.trim()) {
|
|
3173
|
-
throw new Error("review standards require a framework and identifier");
|
|
3174
|
-
}
|
|
3175
|
-
if (standard.framework.trim().length > TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.standardFieldLength || standard.identifier.trim().length > TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.standardFieldLength) {
|
|
3176
|
-
throw new Error(`review standard fields must be at most ${TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.standardFieldLength} characters`);
|
|
3177
|
-
}
|
|
3178
|
-
}
|
|
3179
|
-
if (input.candidateItemsPerStandard !== undefined && (!Number.isInteger(input.candidateItemsPerStandard) || input.candidateItemsPerStandard <= 0 || input.candidateItemsPerStandard > TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.candidateItemsPerStandard)) {
|
|
3180
|
-
throw new Error(`candidateItemsPerStandard must be a positive integer at most ${TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.candidateItemsPerStandard}`);
|
|
3181
|
-
}
|
|
3182
|
-
}
|
|
3183
|
-
const snapshot = await client["requestGameBackend"](`${ASSESSMENTS_ROUTE}/start`, "POST", input);
|
|
3198
|
+
validateStartAssessmentInput(input);
|
|
3199
|
+
const snapshot = await client["requestGameBackend"](`${ASSESSMENTS_ROUTE}/start`, "POST", {
|
|
3200
|
+
...canonicalAssessmentInput(input),
|
|
3201
|
+
...options?.preparationReceipt === undefined ? {} : { preparationReceipt: options.preparationReceipt }
|
|
3202
|
+
});
|
|
3184
3203
|
return syncAssessmentTracking(snapshot);
|
|
3185
3204
|
},
|
|
3186
3205
|
latest: async (options) => {
|
|
@@ -3706,7 +3725,7 @@ async function request({
|
|
|
3706
3725
|
return rawText && rawText.length > 0 ? rawText : undefined;
|
|
3707
3726
|
}
|
|
3708
3727
|
// src/version.ts
|
|
3709
|
-
var SDK_VERSION = "0.18.
|
|
3728
|
+
var SDK_VERSION = "0.18.1-beta.2";
|
|
3710
3729
|
|
|
3711
3730
|
// src/clients/base.ts
|
|
3712
3731
|
class PlaycademyBaseClient {
|
package/dist/internal.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SchemaInfo } from '@playcademy/cloudflare';
|
|
2
2
|
import { GamePermission, AUTH_PROVIDER_IDS } from '@playcademy/constants';
|
|
3
3
|
import { TimebackGrade, TimebackSubject, ELevel, HeartbeatRequest, EndActivityRequest, EndActivityScoreData, EndActivityResponse, TimebackCourseConfig, CourseConfig, OrganizationConfig, ComponentConfig, ResourceConfig, ComponentResourceConfig } from '@playcademy/types/timeback';
|
|
4
|
-
export { AssessmentAttemptSnapshot, AssessmentAwardRecord, AssessmentFinalizeResult, AssessmentFlow, AssessmentItemSubmission, AssessmentMasteryAward, AssessmentResponseUpdate, AssessmentResponseValue, AssessmentResponses, AssessmentSaveResult, AssessmentScore, AssessmentStandardRef, AssessmentSubmitResult, ConventionalAssessmentAttemptSnapshot, ConventionalAssessmentSubmitResult, DiagnosticAssessmentItemReceipt, DiagnosticAssessmentSubmitResult, DiagnosticRoutingSnapshot, DiagnosticRoutingTrackSnapshot, ELevel, FinalizeAssessmentInput, PlatformRoutedDiagnosticAttemptSnapshot, PlatformRoutedDiagnosticSelectionContext, PlayableAssessment, PlayableAssessmentAttemptSnapshot, PlayableAssessmentChoice, PlayableAssessmentGraphic, PlayableAssessmentHotspot, PlayableAssessmentInteraction, PlayableAssessmentItem, PlayableContentNode, SaveAssessmentInput, SettledAssessmentAttemptSnapshot, StartAssessmentInput, StartDiagnosticAssessmentInput, SubmitAssessmentInput, SubmitAssessmentItemInput, SubmitAssessmentItemResult, SubmitDiagnosticAssessmentItemInput, SubmitDiagnosticAssessmentItemResult } from '@playcademy/types/timeback';
|
|
4
|
+
export { AssessmentAttemptSnapshot, AssessmentAwardRecord, AssessmentFinalizeResult, AssessmentFlow, AssessmentItemGrading, AssessmentItemSubmission, AssessmentMasteryAward, AssessmentPreparationResult, AssessmentResponseUpdate, AssessmentResponseValue, AssessmentResponses, AssessmentSaveResult, AssessmentScore, AssessmentStandardRef, AssessmentSubmitResult, ConventionalAssessmentAttemptSnapshot, ConventionalAssessmentSubmitResult, DiagnosticAssessmentItemReceipt, DiagnosticAssessmentSubmitResult, DiagnosticRoutingSnapshot, DiagnosticRoutingTrackSnapshot, ELevel, FinalizeAssessmentInput, PlatformRoutedDiagnosticAttemptSnapshot, PlatformRoutedDiagnosticSelectionContext, PlayableAssessment, PlayableAssessmentAttemptSnapshot, PlayableAssessmentChoice, PlayableAssessmentGraphic, PlayableAssessmentHotspot, PlayableAssessmentInteraction, PlayableAssessmentItem, PlayableContentNode, SaveAssessmentInput, SettledAssessmentAttemptSnapshot, StartAssessmentInput, StartAssessmentOptions, StartDiagnosticAssessmentInput, SubmitAssessmentInput, SubmitAssessmentItemInput, SubmitAssessmentItemResult, SubmitDiagnosticAssessmentItemInput, SubmitDiagnosticAssessmentItemResult } from '@playcademy/types/timeback';
|
|
5
5
|
import * as _playcademy_types from '@playcademy/types';
|
|
6
6
|
import { GameManifest, LocalDayContext } from '@playcademy/types';
|
|
7
7
|
export { AuthenticatedUser, DeveloperStatusEnumType, DeveloperStatusResponse, DeveloperStatusValue, GameCourseMetrics, GameLeaderboardEntry, GameManifest, GameMetricComparisonKind, GameMetricComparisonMetric, GameMetricComparisonRow, GameMetricComparisonRowStatus, GameMetricsProxyResponse, GameMetricsResponse, GameMetricsUnsupportedReason, GamePlatform, GameRunMetrics, GameRunMetricsComparison, GameRunMetricsComparisonStatus, GameRunMetricsComparisonSummary, GameTimebackIntegration, GameType, GameUser, LeaderboardEntry, LeaderboardOptions, LeaderboardTimeframe, LocalDayContext, LocalDaySource, ManifestV1, ManifestV2, ManifestVersions, PopulateStudentResponse, UserEnrollment, UserInfo, UserOrganization, UserRank, UserRankResponse, UserRoleEnumType, UserScore, UserTimebackData } from '@playcademy/types';
|
package/dist/internal.js
CHANGED
|
@@ -2780,6 +2780,13 @@ function createScoresNamespace(client) {
|
|
|
2780
2780
|
}
|
|
2781
2781
|
};
|
|
2782
2782
|
}
|
|
2783
|
+
// src/core/timeback/assessment-request.ts
|
|
2784
|
+
function canonicalAssessmentInput(input) {
|
|
2785
|
+
const request = { ...input };
|
|
2786
|
+
delete request.preparationReceipt;
|
|
2787
|
+
return request;
|
|
2788
|
+
}
|
|
2789
|
+
|
|
2783
2790
|
// src/core/cache/ttl-cache.ts
|
|
2784
2791
|
function createTTLCache(options) {
|
|
2785
2792
|
const cache = new Map;
|
|
@@ -3065,6 +3072,38 @@ function validateAssessmentFilters(options) {
|
|
|
3065
3072
|
}
|
|
3066
3073
|
}
|
|
3067
3074
|
}
|
|
3075
|
+
function validateStartAssessmentInput(input) {
|
|
3076
|
+
if (!input.activityId?.trim()) {
|
|
3077
|
+
throw new Error("activityId is required");
|
|
3078
|
+
}
|
|
3079
|
+
validateAssessmentFilters(input);
|
|
3080
|
+
if (input.purpose === "diagnostic" && !input.diagnosticKey?.trim()) {
|
|
3081
|
+
throw new Error("diagnosticKey is required for diagnostic assessments");
|
|
3082
|
+
}
|
|
3083
|
+
if (input.purpose === "diagnostic" && input.diagnosticKey.trim().length > 200) {
|
|
3084
|
+
throw new Error("diagnosticKey must contain at most 200 characters");
|
|
3085
|
+
}
|
|
3086
|
+
if (input.purpose !== "review") {
|
|
3087
|
+
return;
|
|
3088
|
+
}
|
|
3089
|
+
if (!Array.isArray(input.standards) || input.standards.length === 0) {
|
|
3090
|
+
throw new Error("standards must contain at least one standard for review");
|
|
3091
|
+
}
|
|
3092
|
+
if (input.standards.length > TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.standards) {
|
|
3093
|
+
throw new Error(`standards must contain at most ${TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.standards} standards`);
|
|
3094
|
+
}
|
|
3095
|
+
for (const standard of input.standards) {
|
|
3096
|
+
if (!standard || typeof standard !== "object" || !standard.framework?.trim() || !standard.identifier?.trim()) {
|
|
3097
|
+
throw new Error("review standards require a framework and identifier");
|
|
3098
|
+
}
|
|
3099
|
+
if (standard.framework.trim().length > TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.standardFieldLength || standard.identifier.trim().length > TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.standardFieldLength) {
|
|
3100
|
+
throw new Error(`review standard fields must be at most ${TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.standardFieldLength} characters`);
|
|
3101
|
+
}
|
|
3102
|
+
}
|
|
3103
|
+
if (input.candidateItemsPerStandard !== undefined && (!Number.isInteger(input.candidateItemsPerStandard) || input.candidateItemsPerStandard <= 0 || input.candidateItemsPerStandard > TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.candidateItemsPerStandard)) {
|
|
3104
|
+
throw new Error(`candidateItemsPerStandard must be a positive integer at most ${TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.candidateItemsPerStandard}`);
|
|
3105
|
+
}
|
|
3106
|
+
}
|
|
3068
3107
|
function createTimebackNamespace(client) {
|
|
3069
3108
|
const engine = createTimebackEngine(client);
|
|
3070
3109
|
const pendingAssessmentSubmissions = new Map;
|
|
@@ -3149,38 +3188,18 @@ function createTimebackNamespace(client) {
|
|
|
3149
3188
|
registerPauseProbe(client, () => engine.activity.isManuallyPaused());
|
|
3150
3189
|
return {
|
|
3151
3190
|
assessments: {
|
|
3152
|
-
|
|
3191
|
+
prepare: async (input) => {
|
|
3192
|
+
assertPlatformMode(client, "timeback.assessments.prepare()");
|
|
3193
|
+
validateStartAssessmentInput(input);
|
|
3194
|
+
return client["requestGameBackend"](`${ASSESSMENTS_ROUTE}/prepare`, "POST", canonicalAssessmentInput(input));
|
|
3195
|
+
},
|
|
3196
|
+
start: async (input, options) => {
|
|
3153
3197
|
assertPlatformMode(client, "timeback.assessments.start()");
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
throw new Error("diagnosticKey is required for diagnostic assessments");
|
|
3160
|
-
}
|
|
3161
|
-
if (input.purpose === "diagnostic" && input.diagnosticKey.trim().length > 200) {
|
|
3162
|
-
throw new Error("diagnosticKey must contain at most 200 characters");
|
|
3163
|
-
}
|
|
3164
|
-
if (input.purpose === "review") {
|
|
3165
|
-
if (!Array.isArray(input.standards) || input.standards.length === 0) {
|
|
3166
|
-
throw new Error("standards must contain at least one standard for review");
|
|
3167
|
-
}
|
|
3168
|
-
if (input.standards.length > TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.standards) {
|
|
3169
|
-
throw new Error(`standards must contain at most ${TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.standards} standards`);
|
|
3170
|
-
}
|
|
3171
|
-
for (const standard of input.standards) {
|
|
3172
|
-
if (!standard || typeof standard !== "object" || !standard.framework?.trim() || !standard.identifier?.trim()) {
|
|
3173
|
-
throw new Error("review standards require a framework and identifier");
|
|
3174
|
-
}
|
|
3175
|
-
if (standard.framework.trim().length > TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.standardFieldLength || standard.identifier.trim().length > TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.standardFieldLength) {
|
|
3176
|
-
throw new Error(`review standard fields must be at most ${TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.standardFieldLength} characters`);
|
|
3177
|
-
}
|
|
3178
|
-
}
|
|
3179
|
-
if (input.candidateItemsPerStandard !== undefined && (!Number.isInteger(input.candidateItemsPerStandard) || input.candidateItemsPerStandard <= 0 || input.candidateItemsPerStandard > TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.candidateItemsPerStandard)) {
|
|
3180
|
-
throw new Error(`candidateItemsPerStandard must be a positive integer at most ${TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.candidateItemsPerStandard}`);
|
|
3181
|
-
}
|
|
3182
|
-
}
|
|
3183
|
-
const snapshot = await client["requestGameBackend"](`${ASSESSMENTS_ROUTE}/start`, "POST", input);
|
|
3198
|
+
validateStartAssessmentInput(input);
|
|
3199
|
+
const snapshot = await client["requestGameBackend"](`${ASSESSMENTS_ROUTE}/start`, "POST", {
|
|
3200
|
+
...canonicalAssessmentInput(input),
|
|
3201
|
+
...options?.preparationReceipt === undefined ? {} : { preparationReceipt: options.preparationReceipt }
|
|
3202
|
+
});
|
|
3184
3203
|
return syncAssessmentTracking(snapshot);
|
|
3185
3204
|
},
|
|
3186
3205
|
latest: async (options) => {
|
|
@@ -4598,7 +4617,7 @@ async function request({
|
|
|
4598
4617
|
return rawText && rawText.length > 0 ? rawText : undefined;
|
|
4599
4618
|
}
|
|
4600
4619
|
// src/version.ts
|
|
4601
|
-
var SDK_VERSION = "0.18.
|
|
4620
|
+
var SDK_VERSION = "0.18.1-beta.2";
|
|
4602
4621
|
|
|
4603
4622
|
// src/clients/base.ts
|
|
4604
4623
|
class PlaycademyBaseClient {
|
package/dist/server/edge.d.ts
CHANGED
|
@@ -370,7 +370,8 @@ declare class PlaycademyClient {
|
|
|
370
370
|
/** TimeBack integration methods (endActivity) */
|
|
371
371
|
timeback: {
|
|
372
372
|
assessments: {
|
|
373
|
-
|
|
373
|
+
prepare: (studentId: string, input: _playcademy_types.StartAssessmentInput) => Promise<_playcademy_types.AssessmentPreparationResult>;
|
|
374
|
+
start: (studentId: string, input: _playcademy_types.StartAssessmentInput, options?: _playcademy_types.StartAssessmentOptions) => Promise<_playcademy_types.AssessmentAttemptSnapshot>;
|
|
374
375
|
latest: (studentId: string, options: _playcademy_types.GetLatestAssessmentOptions) => Promise<_playcademy_types.LatestAssessmentResult | null>;
|
|
375
376
|
get: (studentId: string, attemptId: string) => Promise<_playcademy_types.AssessmentAttemptSnapshot>;
|
|
376
377
|
save: (studentId: string, attemptId: string, input: _playcademy_types.SaveAssessmentInput) => Promise<_playcademy_types.AssessmentSaveResult>;
|
package/dist/server/edge.js
CHANGED
|
@@ -10,6 +10,13 @@ var __export = (target, all) => {
|
|
|
10
10
|
};
|
|
11
11
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
12
12
|
|
|
13
|
+
// src/core/timeback/assessment-request.ts
|
|
14
|
+
function canonicalAssessmentInput(input) {
|
|
15
|
+
const request = { ...input };
|
|
16
|
+
delete request.preparationReceipt;
|
|
17
|
+
return request;
|
|
18
|
+
}
|
|
19
|
+
|
|
13
20
|
// ../constants/src/auth.ts
|
|
14
21
|
var DEFAULT_PERSONAL_API_KEY_PERMISSIONS = {
|
|
15
22
|
games: ["read", "write", "delete"],
|
|
@@ -86,7 +93,13 @@ function createTimebackNamespace(client) {
|
|
|
86
93
|
}
|
|
87
94
|
return {
|
|
88
95
|
assessments: {
|
|
89
|
-
|
|
96
|
+
prepare: (studentId, input) => client["request"]("/api/timeback/assessments/prepare", "POST", { ...canonicalAssessmentInput(input), gameId: client.gameId, studentId }),
|
|
97
|
+
start: (studentId, input, options) => client["request"]("/api/timeback/assessments/start", "POST", {
|
|
98
|
+
...canonicalAssessmentInput(input),
|
|
99
|
+
...options?.preparationReceipt === undefined ? {} : { preparationReceipt: options.preparationReceipt },
|
|
100
|
+
gameId: client.gameId,
|
|
101
|
+
studentId
|
|
102
|
+
}),
|
|
90
103
|
latest: (studentId, options) => {
|
|
91
104
|
const params = new URLSearchParams({
|
|
92
105
|
gameId: client.gameId,
|
|
@@ -322,7 +335,7 @@ function extractApiErrorInfo(error) {
|
|
|
322
335
|
}
|
|
323
336
|
|
|
324
337
|
// src/version.ts
|
|
325
|
-
var SDK_VERSION = "0.18.
|
|
338
|
+
var SDK_VERSION = "0.18.1-beta.2";
|
|
326
339
|
|
|
327
340
|
// src/server/request.ts
|
|
328
341
|
async function makeApiRequest(opts) {
|
package/dist/server.d.ts
CHANGED
|
@@ -370,7 +370,8 @@ declare class PlaycademyClient$1 {
|
|
|
370
370
|
/** TimeBack integration methods (endActivity) */
|
|
371
371
|
timeback: {
|
|
372
372
|
assessments: {
|
|
373
|
-
|
|
373
|
+
prepare: (studentId: string, input: _playcademy_types.StartAssessmentInput) => Promise<_playcademy_types.AssessmentPreparationResult>;
|
|
374
|
+
start: (studentId: string, input: _playcademy_types.StartAssessmentInput, options?: _playcademy_types.StartAssessmentOptions) => Promise<_playcademy_types.AssessmentAttemptSnapshot>;
|
|
374
375
|
latest: (studentId: string, options: _playcademy_types.GetLatestAssessmentOptions) => Promise<_playcademy_types.LatestAssessmentResult | null>;
|
|
375
376
|
get: (studentId: string, attemptId: string) => Promise<_playcademy_types.AssessmentAttemptSnapshot>;
|
|
376
377
|
save: (studentId: string, attemptId: string, input: _playcademy_types.SaveAssessmentInput) => Promise<_playcademy_types.AssessmentSaveResult>;
|
package/dist/server.js
CHANGED
|
@@ -199,6 +199,13 @@ var init_config_loader = __esm(() => {
|
|
|
199
199
|
init_file_loader();
|
|
200
200
|
});
|
|
201
201
|
|
|
202
|
+
// src/core/timeback/assessment-request.ts
|
|
203
|
+
function canonicalAssessmentInput(input) {
|
|
204
|
+
const request = { ...input };
|
|
205
|
+
delete request.preparationReceipt;
|
|
206
|
+
return request;
|
|
207
|
+
}
|
|
208
|
+
|
|
202
209
|
// ../constants/src/auth.ts
|
|
203
210
|
var DEFAULT_PERSONAL_API_KEY_PERMISSIONS = {
|
|
204
211
|
games: ["read", "write", "delete"],
|
|
@@ -275,7 +282,13 @@ function createTimebackNamespace(client) {
|
|
|
275
282
|
}
|
|
276
283
|
return {
|
|
277
284
|
assessments: {
|
|
278
|
-
|
|
285
|
+
prepare: (studentId, input) => client["request"]("/api/timeback/assessments/prepare", "POST", { ...canonicalAssessmentInput(input), gameId: client.gameId, studentId }),
|
|
286
|
+
start: (studentId, input, options) => client["request"]("/api/timeback/assessments/start", "POST", {
|
|
287
|
+
...canonicalAssessmentInput(input),
|
|
288
|
+
...options?.preparationReceipt === undefined ? {} : { preparationReceipt: options.preparationReceipt },
|
|
289
|
+
gameId: client.gameId,
|
|
290
|
+
studentId
|
|
291
|
+
}),
|
|
279
292
|
latest: (studentId, options) => {
|
|
280
293
|
const params = new URLSearchParams({
|
|
281
294
|
gameId: client.gameId,
|
|
@@ -511,7 +524,7 @@ function extractApiErrorInfo(error) {
|
|
|
511
524
|
}
|
|
512
525
|
|
|
513
526
|
// src/version.ts
|
|
514
|
-
var SDK_VERSION = "0.18.
|
|
527
|
+
var SDK_VERSION = "0.18.1-beta.2";
|
|
515
528
|
|
|
516
529
|
// src/server/request.ts
|
|
517
530
|
async function makeApiRequest(opts) {
|
package/dist/types.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as _playcademy_types from '@playcademy/types';
|
|
|
2
2
|
import { GameManifest, LocalDayContext } from '@playcademy/types';
|
|
3
3
|
export { AuthenticatedUser, DeveloperStatusEnumType, DeveloperStatusResponse, DeveloperStatusValue, GameCourseMetrics, GameLeaderboardEntry, GameManifest, GameMetricComparisonKind, GameMetricComparisonMetric, GameMetricComparisonRow, GameMetricComparisonRowStatus, GameMetricsProxyResponse, GameMetricsResponse, GameMetricsUnsupportedReason, GamePlatform, GameRunMetrics, GameRunMetricsComparison, GameRunMetricsComparisonStatus, GameRunMetricsComparisonSummary, GameTimebackIntegration, GameType, GameUser, LeaderboardEntry, LeaderboardOptions, LeaderboardTimeframe, LocalDayContext, LocalDaySource, ManifestV1, ManifestV2, ManifestVersions, PopulateStudentResponse, UserEnrollment, UserInfo, UserOrganization, UserRank, UserRankResponse, UserRoleEnumType, UserScore, UserTimebackData } from '@playcademy/types';
|
|
4
4
|
import { TimebackCourseConfig, CourseConfig, OrganizationConfig, ComponentConfig, ResourceConfig, ComponentResourceConfig, TimebackGrade, TimebackSubject, ELevel, EndActivityRequest, HeartbeatRequest, EndActivityScoreData, EndActivityResponse } from '@playcademy/types/timeback';
|
|
5
|
-
export { AssessmentAttemptSnapshot, AssessmentAwardRecord, AssessmentFinalizeResult, AssessmentFlow, AssessmentItemSubmission, AssessmentMasteryAward, AssessmentResponseUpdate, AssessmentResponseValue, AssessmentResponses, AssessmentSaveResult, AssessmentScore, AssessmentStandardRef, AssessmentSubmitResult, ConventionalAssessmentAttemptSnapshot, ConventionalAssessmentSubmitResult, DiagnosticAssessmentItemReceipt, DiagnosticAssessmentSubmitResult, DiagnosticRoutingSnapshot, DiagnosticRoutingTrackSnapshot, ELevel, FinalizeAssessmentInput, PlatformRoutedDiagnosticAttemptSnapshot, PlatformRoutedDiagnosticSelectionContext, PlayableAssessment, PlayableAssessmentAttemptSnapshot, PlayableAssessmentChoice, PlayableAssessmentGraphic, PlayableAssessmentHotspot, PlayableAssessmentInteraction, PlayableAssessmentItem, PlayableContentNode, SaveAssessmentInput, SettledAssessmentAttemptSnapshot, StartAssessmentInput, StartDiagnosticAssessmentInput, SubmitAssessmentInput, SubmitAssessmentItemInput, SubmitAssessmentItemResult, SubmitDiagnosticAssessmentItemInput, SubmitDiagnosticAssessmentItemResult } from '@playcademy/types/timeback';
|
|
5
|
+
export { AssessmentAttemptSnapshot, AssessmentAwardRecord, AssessmentFinalizeResult, AssessmentFlow, AssessmentItemGrading, AssessmentItemSubmission, AssessmentMasteryAward, AssessmentPreparationResult, AssessmentResponseUpdate, AssessmentResponseValue, AssessmentResponses, AssessmentSaveResult, AssessmentScore, AssessmentStandardRef, AssessmentSubmitResult, ConventionalAssessmentAttemptSnapshot, ConventionalAssessmentSubmitResult, DiagnosticAssessmentItemReceipt, DiagnosticAssessmentSubmitResult, DiagnosticRoutingSnapshot, DiagnosticRoutingTrackSnapshot, ELevel, FinalizeAssessmentInput, PlatformRoutedDiagnosticAttemptSnapshot, PlatformRoutedDiagnosticSelectionContext, PlayableAssessment, PlayableAssessmentAttemptSnapshot, PlayableAssessmentChoice, PlayableAssessmentGraphic, PlayableAssessmentHotspot, PlayableAssessmentInteraction, PlayableAssessmentItem, PlayableContentNode, SaveAssessmentInput, SettledAssessmentAttemptSnapshot, StartAssessmentInput, StartAssessmentOptions, StartDiagnosticAssessmentInput, SubmitAssessmentInput, SubmitAssessmentItemInput, SubmitAssessmentItemResult, SubmitDiagnosticAssessmentItemInput, SubmitDiagnosticAssessmentItemResult } from '@playcademy/types/timeback';
|
|
6
6
|
import { TimebackUserRole, UserEnrollment, UserOrganization, UserInfo } from '@playcademy/types/user';
|
|
7
7
|
import { GamePermission, AUTH_PROVIDER_IDS } from '@playcademy/constants';
|
|
8
8
|
import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
|
|
@@ -2011,7 +2011,8 @@ declare class PlaycademyClient extends PlaycademyBaseClient {
|
|
|
2011
2011
|
*/
|
|
2012
2012
|
timeback: {
|
|
2013
2013
|
assessments: {
|
|
2014
|
-
|
|
2014
|
+
prepare: (input: _playcademy_types.StartAssessmentInput) => Promise<_playcademy_types.AssessmentPreparationResult>;
|
|
2015
|
+
start: (input: _playcademy_types.StartAssessmentInput, options?: _playcademy_types.StartAssessmentOptions) => Promise<_playcademy_types.AssessmentAttemptSnapshot>;
|
|
2015
2016
|
latest: (options: _playcademy_types.GetLatestAssessmentOptions) => Promise<_playcademy_types.LatestAssessmentResult | null>;
|
|
2016
2017
|
get: (attemptId: string) => Promise<_playcademy_types.AssessmentAttemptSnapshot>;
|
|
2017
2018
|
stop: (attemptId: string) => Promise<{
|