@playcademy/sdk 0.2.11 → 0.2.13
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 +172 -77
- package/dist/index.js +70 -2
- package/dist/internal.d.ts +417 -787
- package/dist/internal.js +70 -2
- package/dist/server.d.ts +36 -0
- package/dist/server.js +28 -2
- package/dist/types.d.ts +203 -122
- package/package.json +3 -3
package/dist/internal.js
CHANGED
|
@@ -1185,7 +1185,7 @@ var ACHIEVEMENT_DEFINITIONS = [
|
|
|
1185
1185
|
}
|
|
1186
1186
|
];
|
|
1187
1187
|
// ../constants/src/typescript.ts
|
|
1188
|
-
var TSC_PACKAGE = "
|
|
1188
|
+
var TSC_PACKAGE = "typescript";
|
|
1189
1189
|
var USE_NATIVE_TSC = TSC_PACKAGE.includes("native-preview");
|
|
1190
1190
|
// ../constants/src/overworld.ts
|
|
1191
1191
|
var ITEM_SLUGS = {
|
|
@@ -1212,7 +1212,8 @@ var BADGES = {
|
|
|
1212
1212
|
};
|
|
1213
1213
|
// ../constants/src/timeback.ts
|
|
1214
1214
|
var TIMEBACK_ROUTES = {
|
|
1215
|
-
END_ACTIVITY: "/integrations/timeback/end-activity"
|
|
1215
|
+
END_ACTIVITY: "/integrations/timeback/end-activity",
|
|
1216
|
+
GET_XP: "/integrations/timeback/xp"
|
|
1216
1217
|
};
|
|
1217
1218
|
// src/core/cache/singleton-cache.ts
|
|
1218
1219
|
function createSingletonCache() {
|
|
@@ -1390,6 +1391,26 @@ function createTTLCache(options) {
|
|
|
1390
1391
|
return { get, clear, size, prune, getKeys, has };
|
|
1391
1392
|
}
|
|
1392
1393
|
|
|
1394
|
+
// src/core/guards.ts
|
|
1395
|
+
var VALID_GRADES = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
|
|
1396
|
+
var VALID_SUBJECTS = [
|
|
1397
|
+
"Reading",
|
|
1398
|
+
"Language",
|
|
1399
|
+
"Vocabulary",
|
|
1400
|
+
"Social Studies",
|
|
1401
|
+
"Writing",
|
|
1402
|
+
"Science",
|
|
1403
|
+
"FastMath",
|
|
1404
|
+
"Math",
|
|
1405
|
+
"None"
|
|
1406
|
+
];
|
|
1407
|
+
function isValidGrade(value) {
|
|
1408
|
+
return typeof value === "number" && Number.isInteger(value) && VALID_GRADES.includes(value);
|
|
1409
|
+
}
|
|
1410
|
+
function isValidSubject(value) {
|
|
1411
|
+
return typeof value === "string" && VALID_SUBJECTS.includes(value);
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1393
1414
|
// src/namespaces/game/timeback.ts
|
|
1394
1415
|
function createTimebackNamespace(client) {
|
|
1395
1416
|
let currentActivity = null;
|
|
@@ -1397,6 +1418,10 @@ function createTimebackNamespace(client) {
|
|
|
1397
1418
|
ttl: 5 * 60 * 1000,
|
|
1398
1419
|
keyPrefix: "game.timeback.user"
|
|
1399
1420
|
});
|
|
1421
|
+
const xpCache = createTTLCache({
|
|
1422
|
+
ttl: 5000,
|
|
1423
|
+
keyPrefix: "game.timeback.xp"
|
|
1424
|
+
});
|
|
1400
1425
|
const getTimeback = () => client["initPayload"]?.timeback;
|
|
1401
1426
|
return {
|
|
1402
1427
|
get user() {
|
|
@@ -1427,6 +1452,49 @@ function createTimebackNamespace(client) {
|
|
|
1427
1452
|
organizations: response.organizations
|
|
1428
1453
|
};
|
|
1429
1454
|
}, options);
|
|
1455
|
+
},
|
|
1456
|
+
xp: {
|
|
1457
|
+
fetch: async (options) => {
|
|
1458
|
+
const hasGrade = options?.grade !== undefined;
|
|
1459
|
+
const hasSubject = options?.subject !== undefined;
|
|
1460
|
+
if (hasGrade !== hasSubject) {
|
|
1461
|
+
throw new Error("Both grade and subject must be provided together");
|
|
1462
|
+
}
|
|
1463
|
+
if (hasGrade && !isValidGrade(options.grade)) {
|
|
1464
|
+
throw new Error(`Invalid grade: ${options.grade}. Valid grades: ${VALID_GRADES.join(", ")}`);
|
|
1465
|
+
}
|
|
1466
|
+
if (hasSubject && !isValidSubject(options.subject)) {
|
|
1467
|
+
throw new Error(`Invalid subject: ${options.subject}. Valid subjects: ${VALID_SUBJECTS.join(", ")}`);
|
|
1468
|
+
}
|
|
1469
|
+
const validIncludeOptions = ["perCourse", "today"];
|
|
1470
|
+
if (options?.include?.length) {
|
|
1471
|
+
for (const opt of options.include) {
|
|
1472
|
+
if (!validIncludeOptions.includes(opt)) {
|
|
1473
|
+
throw new Error(`Invalid include option: ${opt}. Valid options: ${validIncludeOptions.join(", ")}`);
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
const cacheKey = [
|
|
1478
|
+
options?.grade ?? "",
|
|
1479
|
+
options?.subject ?? "",
|
|
1480
|
+
options?.include?.toSorted().join(",") ?? ""
|
|
1481
|
+
].join(":");
|
|
1482
|
+
return xpCache.get(cacheKey, async () => {
|
|
1483
|
+
const params = new URLSearchParams;
|
|
1484
|
+
if (hasGrade) {
|
|
1485
|
+
params.set("grade", String(options.grade));
|
|
1486
|
+
}
|
|
1487
|
+
if (hasSubject) {
|
|
1488
|
+
params.set("subject", options.subject);
|
|
1489
|
+
}
|
|
1490
|
+
if (options?.include?.length) {
|
|
1491
|
+
params.set("include", options.include.join(","));
|
|
1492
|
+
}
|
|
1493
|
+
const queryString = params.toString();
|
|
1494
|
+
const endpoint = `${TIMEBACK_ROUTES.GET_XP}${queryString ? `?${queryString}` : ""}`;
|
|
1495
|
+
return client["requestGameBackend"](endpoint, "GET");
|
|
1496
|
+
}, { force: options?.force });
|
|
1497
|
+
}
|
|
1430
1498
|
}
|
|
1431
1499
|
};
|
|
1432
1500
|
},
|
package/dist/server.d.ts
CHANGED
|
@@ -295,6 +295,27 @@ interface EndActivityResponse {
|
|
|
295
295
|
scoreStatus?: string;
|
|
296
296
|
inProgress?: string;
|
|
297
297
|
}
|
|
298
|
+
/**
|
|
299
|
+
* XP data for a single course.
|
|
300
|
+
*/
|
|
301
|
+
interface StudentCourseXp {
|
|
302
|
+
grade: number;
|
|
303
|
+
subject: string;
|
|
304
|
+
title: string;
|
|
305
|
+
totalXp: number;
|
|
306
|
+
todayXp?: number;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Response from student XP query.
|
|
310
|
+
*/
|
|
311
|
+
interface StudentXpResponse {
|
|
312
|
+
/** Total XP across all queried courses */
|
|
313
|
+
totalXp: number;
|
|
314
|
+
/** Today's XP (if requested) */
|
|
315
|
+
todayXp?: number;
|
|
316
|
+
/** Per-course XP breakdown (if requested) */
|
|
317
|
+
courses?: StudentCourseXp[];
|
|
318
|
+
}
|
|
298
319
|
|
|
299
320
|
/**
|
|
300
321
|
* @fileoverview Server SDK Type Definitions
|
|
@@ -361,6 +382,9 @@ interface CustomRoutesIntegration {
|
|
|
361
382
|
interface DatabaseIntegration {
|
|
362
383
|
/** Database directory (defaults to 'db') */
|
|
363
384
|
directory?: string;
|
|
385
|
+
/** Schema strategy: 'push' uses drizzle-kit push-style diffing, 'migrate' uses migration files.
|
|
386
|
+
* When omitted, auto-detects based on presence of a migrations directory with _journal.json. */
|
|
387
|
+
strategy?: 'push' | 'migrate';
|
|
364
388
|
}
|
|
365
389
|
/**
|
|
366
390
|
* Integrations configuration
|
|
@@ -588,6 +612,13 @@ declare class PlaycademyClient {
|
|
|
588
612
|
* ```
|
|
589
613
|
*/
|
|
590
614
|
static init(config: PlaycademyServerClientConfig): Promise<PlaycademyClient>;
|
|
615
|
+
/**
|
|
616
|
+
* Fetch gameId from API using the API token.
|
|
617
|
+
*
|
|
618
|
+
* @private
|
|
619
|
+
* @throws {Error} Always throws - gameId fetching not yet implemented
|
|
620
|
+
* @todo Implement API endpoint to fetch gameId from API token
|
|
621
|
+
*/
|
|
591
622
|
private fetchGameId;
|
|
592
623
|
/**
|
|
593
624
|
* Makes an authenticated HTTP request to the API.
|
|
@@ -617,6 +648,11 @@ declare class PlaycademyClient {
|
|
|
617
648
|
/** TimeBack integration methods (endActivity) */
|
|
618
649
|
timeback: {
|
|
619
650
|
endActivity: (studentId: string, payload: EndActivityPayload) => Promise<EndActivityResponse>;
|
|
651
|
+
getStudentXp: (studentId: string, options?: {
|
|
652
|
+
grade?: number;
|
|
653
|
+
subject?: string;
|
|
654
|
+
include?: ("perCourse" | "today")[];
|
|
655
|
+
}) => Promise<StudentXpResponse>;
|
|
620
656
|
};
|
|
621
657
|
}
|
|
622
658
|
|
package/dist/server.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// src/
|
|
1
|
+
// src/core/guards.ts
|
|
2
2
|
var VALID_GRADES = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
|
|
3
3
|
var VALID_SUBJECTS = [
|
|
4
4
|
"Reading",
|
|
@@ -17,7 +17,6 @@ function isValidGrade(value) {
|
|
|
17
17
|
function isValidSubject(value) {
|
|
18
18
|
return typeof value === "string" && VALID_SUBJECTS.includes(value);
|
|
19
19
|
}
|
|
20
|
-
|
|
21
20
|
// src/server/namespaces/timeback.ts
|
|
22
21
|
function createTimebackNamespace(client) {
|
|
23
22
|
function enrichActivityData(data) {
|
|
@@ -44,6 +43,33 @@ function createTimebackNamespace(client) {
|
|
|
44
43
|
xpEarned: payload.xpEarned,
|
|
45
44
|
masteredUnits: payload.masteredUnits
|
|
46
45
|
});
|
|
46
|
+
},
|
|
47
|
+
getStudentXp: async (studentId, options) => {
|
|
48
|
+
const hasGrade = options?.grade !== undefined;
|
|
49
|
+
const hasSubject = options?.subject !== undefined;
|
|
50
|
+
if (hasGrade !== hasSubject) {
|
|
51
|
+
throw new Error("Both grade and subject must be provided together");
|
|
52
|
+
}
|
|
53
|
+
if (hasGrade && !isValidGrade(options.grade)) {
|
|
54
|
+
throw new Error(`Invalid grade: ${options.grade}. Valid grades: ${VALID_GRADES.join(", ")}`);
|
|
55
|
+
}
|
|
56
|
+
if (hasSubject && !isValidSubject(options.subject)) {
|
|
57
|
+
throw new Error(`Invalid subject: ${options.subject}. Valid subjects: ${VALID_SUBJECTS.join(", ")}`);
|
|
58
|
+
}
|
|
59
|
+
const params = new URLSearchParams;
|
|
60
|
+
params.set("gameId", client.gameId);
|
|
61
|
+
if (options?.grade !== undefined) {
|
|
62
|
+
params.set("grade", String(options.grade));
|
|
63
|
+
}
|
|
64
|
+
if (options?.subject) {
|
|
65
|
+
params.set("subject", options.subject);
|
|
66
|
+
}
|
|
67
|
+
if (options?.include?.length) {
|
|
68
|
+
params.set("include", options.include.join(","));
|
|
69
|
+
}
|
|
70
|
+
const queryString = params.toString();
|
|
71
|
+
const endpoint = `/api/timeback/student-xp/${studentId}?${queryString}`;
|
|
72
|
+
return client["request"](endpoint, "GET");
|
|
47
73
|
}
|
|
48
74
|
};
|
|
49
75
|
}
|