@playcademy/sdk 0.24.0 → 0.24.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/dist/index.d.ts +170 -127
- package/dist/index.js +20 -3
- package/dist/internal.d.ts +2041 -1970
- package/dist/internal.js +22 -3
- package/dist/server/edge.d.ts +24 -1
- package/dist/server/edge.js +1 -1
- package/dist/server.d.ts +24 -1
- package/dist/server.js +1 -1
- package/dist/types.d.ts +458 -411
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -225,132 +225,6 @@ declare const ASSESSMENT_PURPOSES: readonly ['end_of_course', 'diagnostic', 'rev
|
|
|
225
225
|
*/
|
|
226
226
|
declare const PLAYCADEMY_ASSESSMENT_CONTRACT_VERSION: 2;
|
|
227
227
|
|
|
228
|
-
/**
|
|
229
|
-
* User Types
|
|
230
|
-
*
|
|
231
|
-
* Enums, DTOs and API response types. Database row types are in @playcademy/data/types.
|
|
232
|
-
*
|
|
233
|
-
* @module types/user
|
|
234
|
-
*/
|
|
235
|
-
|
|
236
|
-
type UserRoleEnumType = UserRole;
|
|
237
|
-
type DeveloperStatusEnumType = 'none' | 'pending' | 'approved';
|
|
238
|
-
type TimebackUserRole = 'administrator' | 'aide' | 'guardian' | 'parent' | 'proctor' | 'relative' | 'student' | 'teacher';
|
|
239
|
-
type TimebackOrgType = 'department' | 'school' | 'district' | 'local' | 'state' | 'national';
|
|
240
|
-
interface UserEnrollment {
|
|
241
|
-
gameId?: string;
|
|
242
|
-
courseId: string;
|
|
243
|
-
id?: string;
|
|
244
|
-
grade: number;
|
|
245
|
-
subject: string;
|
|
246
|
-
orgId?: string;
|
|
247
|
-
}
|
|
248
|
-
interface UserOrganization {
|
|
249
|
-
id: string;
|
|
250
|
-
name: string | null;
|
|
251
|
-
type: TimebackOrgType | string;
|
|
252
|
-
isPrimary: boolean;
|
|
253
|
-
}
|
|
254
|
-
interface TimebackStudentProfile {
|
|
255
|
-
role: TimebackUserRole;
|
|
256
|
-
organizations: UserOrganization[];
|
|
257
|
-
}
|
|
258
|
-
/**
|
|
259
|
-
* Timeback identity on `/users/me`: who the student is, without enrollments.
|
|
260
|
-
* Enrollments come from `/timeback/user` (or `client.timeback.user`).
|
|
261
|
-
*/
|
|
262
|
-
interface UserTimebackProfile extends TimebackStudentProfile {
|
|
263
|
-
id: string;
|
|
264
|
-
}
|
|
265
|
-
type LocalDaySource = 'browser_last_seen' | 'platform_default';
|
|
266
|
-
interface LocalDayContext {
|
|
267
|
-
timeZone: string;
|
|
268
|
-
source: LocalDaySource;
|
|
269
|
-
/** ISO 8601 timestamp for the last persisted timezone observation. */
|
|
270
|
-
observedAt: string | null;
|
|
271
|
-
}
|
|
272
|
-
/**
|
|
273
|
-
* OpenID Connect UserInfo claims (NOT a database row).
|
|
274
|
-
*/
|
|
275
|
-
interface UserInfo {
|
|
276
|
-
sub: string;
|
|
277
|
-
email: string;
|
|
278
|
-
name: string | null;
|
|
279
|
-
email_verified?: boolean;
|
|
280
|
-
given_name?: string;
|
|
281
|
-
family_name?: string;
|
|
282
|
-
issuer?: string;
|
|
283
|
-
lti_roles?: unknown;
|
|
284
|
-
lti_context?: unknown;
|
|
285
|
-
lti_resource_link?: unknown;
|
|
286
|
-
timeback_id?: string;
|
|
287
|
-
}
|
|
288
|
-
interface DemoProfile {
|
|
289
|
-
displayName: string;
|
|
290
|
-
isDefault: boolean;
|
|
291
|
-
}
|
|
292
|
-
/**
|
|
293
|
-
* Update shape for `client.demo.profile.update(...)`.
|
|
294
|
-
*
|
|
295
|
-
* Kept as a named type so callers typed against it pick up new fields
|
|
296
|
-
* automatically, but `displayName` is the only updatable field today and
|
|
297
|
-
* the server's `DemoProfileSchema` requires it — a no-field payload would
|
|
298
|
-
* 400 at runtime, so we model that at the type level too. When additional
|
|
299
|
-
* fields land, make them required/optional individually based on server
|
|
300
|
-
* validation, rather than blanket-optional.
|
|
301
|
-
*/
|
|
302
|
-
interface DemoProfileUpdate {
|
|
303
|
-
displayName: string;
|
|
304
|
-
}
|
|
305
|
-
/**
|
|
306
|
-
* Authenticated user for API responses.
|
|
307
|
-
* Differs from UserRow: omits timebackId, adds hasTimebackAccount and timeback.
|
|
308
|
-
*/
|
|
309
|
-
interface AuthenticatedUser {
|
|
310
|
-
id: string;
|
|
311
|
-
email: string;
|
|
312
|
-
emailVerified: boolean;
|
|
313
|
-
name: string | null;
|
|
314
|
-
image: string | null;
|
|
315
|
-
username: string | null;
|
|
316
|
-
role: UserRoleEnumType;
|
|
317
|
-
developerStatus: DeveloperStatusEnumType;
|
|
318
|
-
createdAt: Date;
|
|
319
|
-
updatedAt: Date;
|
|
320
|
-
hasTimebackAccount: boolean;
|
|
321
|
-
localDay: LocalDayContext;
|
|
322
|
-
timeback?: UserTimebackProfile;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
/**
|
|
326
|
-
* Leaderboard Types
|
|
327
|
-
*
|
|
328
|
-
* @module types/leaderboard
|
|
329
|
-
*/
|
|
330
|
-
type LeaderboardTimeframe = 'all_time' | 'monthly' | 'weekly' | 'daily';
|
|
331
|
-
interface LeaderboardOptions {
|
|
332
|
-
timeframe?: LeaderboardTimeframe;
|
|
333
|
-
limit?: number;
|
|
334
|
-
offset?: number;
|
|
335
|
-
gameId?: string;
|
|
336
|
-
}
|
|
337
|
-
/**
|
|
338
|
-
* Leaderboard entry with required game context.
|
|
339
|
-
* Used when fetching leaderboards for a specific game.
|
|
340
|
-
*/
|
|
341
|
-
interface GameLeaderboardEntry {
|
|
342
|
-
rank: number;
|
|
343
|
-
userId: string;
|
|
344
|
-
username: string;
|
|
345
|
-
userImage?: string | null;
|
|
346
|
-
score: number;
|
|
347
|
-
achievedAt: Date;
|
|
348
|
-
metadata?: Record<string, unknown>;
|
|
349
|
-
gameId: string;
|
|
350
|
-
gameTitle: string;
|
|
351
|
-
gameSlug: string;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
228
|
/**
|
|
355
229
|
* TimeBack Enums & Literal Types
|
|
356
230
|
*
|
|
@@ -423,8 +297,18 @@ interface ActivityData {
|
|
|
423
297
|
subject: CaliperSubject;
|
|
424
298
|
/** Activity display name (optional) */
|
|
425
299
|
activityName?: string;
|
|
426
|
-
/**
|
|
300
|
+
/**
|
|
301
|
+
* Optional course to report against. When omitted, the SDK fills it from
|
|
302
|
+
* the student's enrollment for this grade/subject (preferring a
|
|
303
|
+
* hole-filling course). The platform uses it if it's the base course or one
|
|
304
|
+
* of that grade/subject's hole-filling courses, otherwise the base course.
|
|
305
|
+
*/
|
|
427
306
|
courseId?: string;
|
|
307
|
+
/**
|
|
308
|
+
* The student's enrollment in `courseId`. Filled by the SDK alongside an
|
|
309
|
+
* automatic `courseId`; recorded on hole-filling Caliper events.
|
|
310
|
+
*/
|
|
311
|
+
enrollmentId?: string;
|
|
428
312
|
/** Course display name (auto-filled from config if not provided) */
|
|
429
313
|
courseName?: string;
|
|
430
314
|
/** Student email address (optional) */
|
|
@@ -494,6 +378,12 @@ interface EndActivityScoreData {
|
|
|
494
378
|
* @module types/timeback/api
|
|
495
379
|
*/
|
|
496
380
|
|
|
381
|
+
/**
|
|
382
|
+
* `base` courses form a game's grade ladder (one active per grade and subject).
|
|
383
|
+
* `hole_filling` courses are remediation courses Timeback enrolls students into
|
|
384
|
+
* after a failed test; each sits beside a base course.
|
|
385
|
+
*/
|
|
386
|
+
type GameTimebackIntegrationKind = 'base' | 'hole_filling';
|
|
497
387
|
interface HeartbeatRequestBase {
|
|
498
388
|
gameId: string;
|
|
499
389
|
studentId: string;
|
|
@@ -515,6 +405,8 @@ interface HeartbeatRequestBase {
|
|
|
515
405
|
appName?: string;
|
|
516
406
|
sensorUrl?: string;
|
|
517
407
|
courseId?: string;
|
|
408
|
+
/** The student's enrollment in `courseId`, sent by the SDK with the course hint. */
|
|
409
|
+
enrollmentId?: string;
|
|
518
410
|
courseName?: string;
|
|
519
411
|
studentEmail?: string;
|
|
520
412
|
};
|
|
@@ -568,6 +460,8 @@ interface EndActivityRequest {
|
|
|
568
460
|
appName?: string;
|
|
569
461
|
sensorUrl?: string;
|
|
570
462
|
courseId?: string;
|
|
463
|
+
/** The student's enrollment in `courseId`, sent by the SDK with the course hint. */
|
|
464
|
+
enrollmentId?: string;
|
|
571
465
|
courseName?: string;
|
|
572
466
|
studentEmail?: string;
|
|
573
467
|
};
|
|
@@ -597,7 +491,14 @@ interface TimebackPromotionResult {
|
|
|
597
491
|
}
|
|
598
492
|
interface EndActivityResponse {
|
|
599
493
|
status: 'ok';
|
|
494
|
+
/** The course the activity was recorded against. */
|
|
600
495
|
courseId: string;
|
|
496
|
+
/**
|
|
497
|
+
* `'hole_filling'` when the activity was recorded against a hole-filling
|
|
498
|
+
* course (the student is enrolled there, or the game passed its
|
|
499
|
+
* `courseId`); `'base'` otherwise.
|
|
500
|
+
*/
|
|
501
|
+
courseKind?: GameTimebackIntegrationKind;
|
|
601
502
|
xpAwarded: number;
|
|
602
503
|
masteredUnits?: number;
|
|
603
504
|
pctCompleteApp?: number;
|
|
@@ -1353,6 +1254,146 @@ interface FinalizeAssessmentInput extends AssessmentMasteryAward {
|
|
|
1353
1254
|
xpAwarded: number;
|
|
1354
1255
|
}
|
|
1355
1256
|
|
|
1257
|
+
/**
|
|
1258
|
+
* User Types
|
|
1259
|
+
*
|
|
1260
|
+
* Enums, DTOs and API response types. Database row types are in @playcademy/data/types.
|
|
1261
|
+
*
|
|
1262
|
+
* @module types/user
|
|
1263
|
+
*/
|
|
1264
|
+
|
|
1265
|
+
type UserRoleEnumType = UserRole;
|
|
1266
|
+
type DeveloperStatusEnumType = 'none' | 'pending' | 'approved';
|
|
1267
|
+
type TimebackUserRole = 'administrator' | 'aide' | 'guardian' | 'parent' | 'proctor' | 'relative' | 'student' | 'teacher';
|
|
1268
|
+
type TimebackOrgType = 'department' | 'school' | 'district' | 'local' | 'state' | 'national';
|
|
1269
|
+
interface UserEnrollment {
|
|
1270
|
+
gameId?: string;
|
|
1271
|
+
courseId: string;
|
|
1272
|
+
id?: string;
|
|
1273
|
+
grade: number;
|
|
1274
|
+
subject: string;
|
|
1275
|
+
orgId?: string;
|
|
1276
|
+
/**
|
|
1277
|
+
* `base` for the game's grade courses, `hole_filling` for a remediation
|
|
1278
|
+
* course Timeback enrolled the student in. Absent means `base`.
|
|
1279
|
+
*/
|
|
1280
|
+
kind?: GameTimebackIntegrationKind;
|
|
1281
|
+
/** For hole-filling enrollments: the course ID of the base course it belongs to. */
|
|
1282
|
+
baseCourseId?: string;
|
|
1283
|
+
/** For hole-filling enrollments: when the enrollment started (ISO 8601). */
|
|
1284
|
+
beginDate?: string | null;
|
|
1285
|
+
/**
|
|
1286
|
+
* For hole-filling enrollments: enrollment metadata as set by Timeback
|
|
1287
|
+
* (e.g. `assignmentId`, `testType`). Every field is optional.
|
|
1288
|
+
*/
|
|
1289
|
+
enrollmentMetadata?: Record<string, unknown>;
|
|
1290
|
+
}
|
|
1291
|
+
interface UserOrganization {
|
|
1292
|
+
id: string;
|
|
1293
|
+
name: string | null;
|
|
1294
|
+
type: TimebackOrgType | string;
|
|
1295
|
+
isPrimary: boolean;
|
|
1296
|
+
}
|
|
1297
|
+
interface TimebackStudentProfile {
|
|
1298
|
+
role: TimebackUserRole;
|
|
1299
|
+
organizations: UserOrganization[];
|
|
1300
|
+
}
|
|
1301
|
+
/**
|
|
1302
|
+
* Timeback identity on `/users/me`: who the student is, without enrollments.
|
|
1303
|
+
* Enrollments come from `/timeback/user` (or `client.timeback.user`).
|
|
1304
|
+
*/
|
|
1305
|
+
interface UserTimebackProfile extends TimebackStudentProfile {
|
|
1306
|
+
id: string;
|
|
1307
|
+
}
|
|
1308
|
+
type LocalDaySource = 'browser_last_seen' | 'platform_default';
|
|
1309
|
+
interface LocalDayContext {
|
|
1310
|
+
timeZone: string;
|
|
1311
|
+
source: LocalDaySource;
|
|
1312
|
+
/** ISO 8601 timestamp for the last persisted timezone observation. */
|
|
1313
|
+
observedAt: string | null;
|
|
1314
|
+
}
|
|
1315
|
+
/**
|
|
1316
|
+
* OpenID Connect UserInfo claims (NOT a database row).
|
|
1317
|
+
*/
|
|
1318
|
+
interface UserInfo {
|
|
1319
|
+
sub: string;
|
|
1320
|
+
email: string;
|
|
1321
|
+
name: string | null;
|
|
1322
|
+
email_verified?: boolean;
|
|
1323
|
+
given_name?: string;
|
|
1324
|
+
family_name?: string;
|
|
1325
|
+
issuer?: string;
|
|
1326
|
+
lti_roles?: unknown;
|
|
1327
|
+
lti_context?: unknown;
|
|
1328
|
+
lti_resource_link?: unknown;
|
|
1329
|
+
timeback_id?: string;
|
|
1330
|
+
}
|
|
1331
|
+
interface DemoProfile {
|
|
1332
|
+
displayName: string;
|
|
1333
|
+
isDefault: boolean;
|
|
1334
|
+
}
|
|
1335
|
+
/**
|
|
1336
|
+
* Update shape for `client.demo.profile.update(...)`.
|
|
1337
|
+
*
|
|
1338
|
+
* Kept as a named type so callers typed against it pick up new fields
|
|
1339
|
+
* automatically, but `displayName` is the only updatable field today and
|
|
1340
|
+
* the server's `DemoProfileSchema` requires it — a no-field payload would
|
|
1341
|
+
* 400 at runtime, so we model that at the type level too. When additional
|
|
1342
|
+
* fields land, make them required/optional individually based on server
|
|
1343
|
+
* validation, rather than blanket-optional.
|
|
1344
|
+
*/
|
|
1345
|
+
interface DemoProfileUpdate {
|
|
1346
|
+
displayName: string;
|
|
1347
|
+
}
|
|
1348
|
+
/**
|
|
1349
|
+
* Authenticated user for API responses.
|
|
1350
|
+
* Differs from UserRow: omits timebackId, adds hasTimebackAccount and timeback.
|
|
1351
|
+
*/
|
|
1352
|
+
interface AuthenticatedUser {
|
|
1353
|
+
id: string;
|
|
1354
|
+
email: string;
|
|
1355
|
+
emailVerified: boolean;
|
|
1356
|
+
name: string | null;
|
|
1357
|
+
image: string | null;
|
|
1358
|
+
username: string | null;
|
|
1359
|
+
role: UserRoleEnumType;
|
|
1360
|
+
developerStatus: DeveloperStatusEnumType;
|
|
1361
|
+
createdAt: Date;
|
|
1362
|
+
updatedAt: Date;
|
|
1363
|
+
hasTimebackAccount: boolean;
|
|
1364
|
+
localDay: LocalDayContext;
|
|
1365
|
+
timeback?: UserTimebackProfile;
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
/**
|
|
1369
|
+
* Leaderboard Types
|
|
1370
|
+
*
|
|
1371
|
+
* @module types/leaderboard
|
|
1372
|
+
*/
|
|
1373
|
+
type LeaderboardTimeframe = 'all_time' | 'monthly' | 'weekly' | 'daily';
|
|
1374
|
+
interface LeaderboardOptions {
|
|
1375
|
+
timeframe?: LeaderboardTimeframe;
|
|
1376
|
+
limit?: number;
|
|
1377
|
+
offset?: number;
|
|
1378
|
+
gameId?: string;
|
|
1379
|
+
}
|
|
1380
|
+
/**
|
|
1381
|
+
* Leaderboard entry with required game context.
|
|
1382
|
+
* Used when fetching leaderboards for a specific game.
|
|
1383
|
+
*/
|
|
1384
|
+
interface GameLeaderboardEntry {
|
|
1385
|
+
rank: number;
|
|
1386
|
+
userId: string;
|
|
1387
|
+
username: string;
|
|
1388
|
+
userImage?: string | null;
|
|
1389
|
+
score: number;
|
|
1390
|
+
achievedAt: Date;
|
|
1391
|
+
metadata?: Record<string, unknown>;
|
|
1392
|
+
gameId: string;
|
|
1393
|
+
gameTitle: string;
|
|
1394
|
+
gameSlug: string;
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1356
1397
|
/**
|
|
1357
1398
|
* Cache configuration types for runtime customization
|
|
1358
1399
|
*/
|
|
@@ -3020,6 +3061,8 @@ interface EmbedTimebackRecording {
|
|
|
3020
3061
|
subject: TimebackSubject;
|
|
3021
3062
|
/** Course id hint, same semantics as `startActivity()`. */
|
|
3022
3063
|
courseId?: string;
|
|
3064
|
+
/** The student's enrollment in `courseId`; filled with it automatically. */
|
|
3065
|
+
enrollmentId?: string;
|
|
3023
3066
|
}
|
|
3024
3067
|
/**
|
|
3025
3068
|
* Everything a parent needs to resume an interrupted launch later. The
|
package/dist/index.js
CHANGED
|
@@ -2289,6 +2289,23 @@ function createTimebackActivityTracker(client) {
|
|
|
2289
2289
|
};
|
|
2290
2290
|
}
|
|
2291
2291
|
|
|
2292
|
+
// src/core/timeback/course-hint.ts
|
|
2293
|
+
function withEnrollmentCourseHint(metadata, enrollments) {
|
|
2294
|
+
if (metadata.courseId !== undefined) {
|
|
2295
|
+
return metadata;
|
|
2296
|
+
}
|
|
2297
|
+
const matching = enrollments.filter((enrollment) => enrollment.grade === metadata.grade && enrollment.subject === metadata.subject);
|
|
2298
|
+
const enrollment = matching.find((candidate) => candidate.kind === "hole_filling") ?? matching[0];
|
|
2299
|
+
if (!enrollment) {
|
|
2300
|
+
return metadata;
|
|
2301
|
+
}
|
|
2302
|
+
return {
|
|
2303
|
+
...metadata,
|
|
2304
|
+
courseId: enrollment.courseId,
|
|
2305
|
+
...enrollment.id && { enrollmentId: enrollment.id }
|
|
2306
|
+
};
|
|
2307
|
+
}
|
|
2308
|
+
|
|
2292
2309
|
// src/namespaces/game/embed.ts
|
|
2293
2310
|
function createEmbedNamespace(client) {
|
|
2294
2311
|
return {
|
|
@@ -2325,7 +2342,7 @@ function createEmbedNamespace(client) {
|
|
|
2325
2342
|
const session = new ChildSession({
|
|
2326
2343
|
slug: options.slug,
|
|
2327
2344
|
container: options.container,
|
|
2328
|
-
timeback: options.timeback,
|
|
2345
|
+
timeback: options.timeback && withEnrollmentCourseHint(options.timeback, client.timeback.user?.enrollments ?? []),
|
|
2329
2346
|
resume: resume.envelope,
|
|
2330
2347
|
resumeStore: resume.store,
|
|
2331
2348
|
reporter: {
|
|
@@ -3023,7 +3040,7 @@ function createTimebackEngine(client) {
|
|
|
3023
3040
|
activity: {
|
|
3024
3041
|
currentRunId: activityTracker.currentRunId,
|
|
3025
3042
|
isManuallyPaused: activityTracker.isActivityManuallyPaused,
|
|
3026
|
-
start: activityTracker.startActivity,
|
|
3043
|
+
start: (metadata, options) => activityTracker.startActivity(withEnrollmentCourseHint(metadata, userStore.snapshot()?.enrollments ?? []), options),
|
|
3027
3044
|
tryStartAssessment: activityTracker.tryStartAssessmentTracking,
|
|
3028
3045
|
pause: activityTracker.pauseActivity,
|
|
3029
3046
|
resume: activityTracker.resumeActivity,
|
|
@@ -3765,7 +3782,7 @@ async function request({
|
|
|
3765
3782
|
return rawText && rawText.length > 0 ? rawText : undefined;
|
|
3766
3783
|
}
|
|
3767
3784
|
// src/version.ts
|
|
3768
|
-
var SDK_VERSION = "0.24.
|
|
3785
|
+
var SDK_VERSION = "0.24.1-beta.2";
|
|
3769
3786
|
|
|
3770
3787
|
// src/clients/base.ts
|
|
3771
3788
|
class PlaycademyBaseClient {
|