@playcademy/sdk 0.2.10 → 0.2.12
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 +107 -12
- package/dist/index.js +70 -2
- package/dist/internal.d.ts +351 -596
- package/dist/internal.js +72 -4
- package/dist/server.d.ts +33 -0
- package/dist/server.js +28 -2
- package/dist/types.d.ts +135 -57
- 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?.sort().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
|
},
|
|
@@ -1769,9 +1837,9 @@ function createDevNamespace(client) {
|
|
|
1769
1837
|
}
|
|
1770
1838
|
throw new Error("No deployment actions specified (need metadata, file, or backend)");
|
|
1771
1839
|
},
|
|
1772
|
-
seed: async (slug, code, environment) => {
|
|
1840
|
+
seed: async (slug, code, environment, secrets) => {
|
|
1773
1841
|
return client["request"](`/games/${slug}/seed`, "POST", {
|
|
1774
|
-
body: { code, environment }
|
|
1842
|
+
body: { code, environment, secrets }
|
|
1775
1843
|
});
|
|
1776
1844
|
},
|
|
1777
1845
|
upsert: async (slug, metadata) => client["request"](`/games/${slug}`, "PUT", { body: metadata }),
|
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
|
|
@@ -588,6 +609,13 @@ declare class PlaycademyClient {
|
|
|
588
609
|
* ```
|
|
589
610
|
*/
|
|
590
611
|
static init(config: PlaycademyServerClientConfig): Promise<PlaycademyClient>;
|
|
612
|
+
/**
|
|
613
|
+
* Fetch gameId from API using the API token.
|
|
614
|
+
*
|
|
615
|
+
* @private
|
|
616
|
+
* @throws {Error} Always throws - gameId fetching not yet implemented
|
|
617
|
+
* @todo Implement API endpoint to fetch gameId from API token
|
|
618
|
+
*/
|
|
591
619
|
private fetchGameId;
|
|
592
620
|
/**
|
|
593
621
|
* Makes an authenticated HTTP request to the API.
|
|
@@ -617,6 +645,11 @@ declare class PlaycademyClient {
|
|
|
617
645
|
/** TimeBack integration methods (endActivity) */
|
|
618
646
|
timeback: {
|
|
619
647
|
endActivity: (studentId: string, payload: EndActivityPayload) => Promise<EndActivityResponse>;
|
|
648
|
+
getStudentXp: (studentId: string, options?: {
|
|
649
|
+
grade?: number;
|
|
650
|
+
subject?: string;
|
|
651
|
+
include?: ("perCourse" | "today")[];
|
|
652
|
+
}) => Promise<StudentXpResponse>;
|
|
620
653
|
};
|
|
621
654
|
}
|
|
622
655
|
|
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
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -800,7 +800,7 @@ declare const users: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
800
800
|
tableName: "user";
|
|
801
801
|
dataType: "string";
|
|
802
802
|
columnType: "PgEnumColumn";
|
|
803
|
-
data: "admin" | "
|
|
803
|
+
data: "admin" | "player" | "developer";
|
|
804
804
|
driverParam: string;
|
|
805
805
|
notNull: true;
|
|
806
806
|
hasDefault: true;
|
|
@@ -817,7 +817,7 @@ declare const users: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
817
817
|
tableName: "user";
|
|
818
818
|
dataType: "string";
|
|
819
819
|
columnType: "PgEnumColumn";
|
|
820
|
-
data: "
|
|
820
|
+
data: "none" | "pending" | "approved";
|
|
821
821
|
driverParam: string;
|
|
822
822
|
notNull: true;
|
|
823
823
|
hasDefault: true;
|
|
@@ -1006,7 +1006,7 @@ declare const games: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
1006
1006
|
tableName: "games";
|
|
1007
1007
|
dataType: "string";
|
|
1008
1008
|
columnType: "PgEnumColumn";
|
|
1009
|
-
data: "
|
|
1009
|
+
data: "hosted" | "external";
|
|
1010
1010
|
driverParam: string;
|
|
1011
1011
|
notNull: true;
|
|
1012
1012
|
hasDefault: true;
|
|
@@ -1057,7 +1057,7 @@ declare const games: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
1057
1057
|
tableName: "games";
|
|
1058
1058
|
dataType: "string";
|
|
1059
1059
|
columnType: "PgEnumColumn";
|
|
1060
|
-
data: "
|
|
1060
|
+
data: "web" | "godot" | "unity";
|
|
1061
1061
|
driverParam: string;
|
|
1062
1062
|
notNull: true;
|
|
1063
1063
|
hasDefault: true;
|
|
@@ -1333,7 +1333,7 @@ declare const gameCustomHostnames: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
1333
1333
|
tableName: "game_custom_hostnames";
|
|
1334
1334
|
dataType: "string";
|
|
1335
1335
|
columnType: "PgEnumColumn";
|
|
1336
|
-
data: "
|
|
1336
|
+
data: "staging" | "production";
|
|
1337
1337
|
driverParam: string;
|
|
1338
1338
|
notNull: true;
|
|
1339
1339
|
hasDefault: true;
|
|
@@ -1350,7 +1350,7 @@ declare const gameCustomHostnames: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
1350
1350
|
tableName: "game_custom_hostnames";
|
|
1351
1351
|
dataType: "string";
|
|
1352
1352
|
columnType: "PgEnumColumn";
|
|
1353
|
-
data: "
|
|
1353
|
+
data: "pending" | "active" | "pending_validation" | "pending_deployment" | "pending_deletion" | "blocked" | "deleted";
|
|
1354
1354
|
driverParam: string;
|
|
1355
1355
|
notNull: true;
|
|
1356
1356
|
hasDefault: true;
|
|
@@ -1367,7 +1367,7 @@ declare const gameCustomHostnames: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
1367
1367
|
tableName: "game_custom_hostnames";
|
|
1368
1368
|
dataType: "string";
|
|
1369
1369
|
columnType: "PgEnumColumn";
|
|
1370
|
-
data: "active" | "
|
|
1370
|
+
data: "active" | "pending_validation" | "pending_deployment" | "deleted" | "initializing" | "pending_issuance";
|
|
1371
1371
|
driverParam: string;
|
|
1372
1372
|
notNull: true;
|
|
1373
1373
|
hasDefault: true;
|
|
@@ -1529,7 +1529,7 @@ declare const items: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
1529
1529
|
tableName: "items";
|
|
1530
1530
|
dataType: "string";
|
|
1531
1531
|
columnType: "PgEnumColumn";
|
|
1532
|
-
data: "
|
|
1532
|
+
data: "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "accessory" | "other";
|
|
1533
1533
|
driverParam: string;
|
|
1534
1534
|
notNull: true;
|
|
1535
1535
|
hasDefault: true;
|
|
@@ -2220,7 +2220,7 @@ declare const mapElements: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
2220
2220
|
tableName: "map_elements";
|
|
2221
2221
|
dataType: "string";
|
|
2222
2222
|
columnType: "PgEnumColumn";
|
|
2223
|
-
data: "
|
|
2223
|
+
data: "info" | "game_entry" | "game_registry" | "teleport" | "door_in" | "door_out" | "npc_interaction" | "quest_trigger";
|
|
2224
2224
|
driverParam: string;
|
|
2225
2225
|
notNull: true;
|
|
2226
2226
|
hasDefault: false;
|
|
@@ -2773,7 +2773,7 @@ declare const characterComponents: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
2773
2773
|
tableName: "character_components";
|
|
2774
2774
|
dataType: "string";
|
|
2775
2775
|
columnType: "PgEnumColumn";
|
|
2776
|
-
data: "accessory" | "body" | "
|
|
2776
|
+
data: "accessory" | "body" | "outfit" | "hairstyle" | "eyes";
|
|
2777
2777
|
driverParam: string;
|
|
2778
2778
|
notNull: true;
|
|
2779
2779
|
hasDefault: false;
|
|
@@ -3299,7 +3299,7 @@ declare const notifications: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
3299
3299
|
tableName: "notifications";
|
|
3300
3300
|
dataType: "string";
|
|
3301
3301
|
columnType: "PgEnumColumn";
|
|
3302
|
-
data: "
|
|
3302
|
+
data: "low" | "normal" | "high" | "urgent";
|
|
3303
3303
|
driverParam: string;
|
|
3304
3304
|
notNull: true;
|
|
3305
3305
|
hasDefault: true;
|
|
@@ -3316,7 +3316,7 @@ declare const notifications: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
3316
3316
|
tableName: "notifications";
|
|
3317
3317
|
dataType: "string";
|
|
3318
3318
|
columnType: "PgEnumColumn";
|
|
3319
|
-
data: "
|
|
3319
|
+
data: "pending" | "delivered" | "seen" | "clicked" | "dismissed" | "expired";
|
|
3320
3320
|
driverParam: string;
|
|
3321
3321
|
notNull: true;
|
|
3322
3322
|
hasDefault: true;
|
|
@@ -3477,33 +3477,33 @@ declare const UpsertGameMetadataSchema: z.ZodEffects<z.ZodObject<{
|
|
|
3477
3477
|
gameType: z.ZodDefault<z.ZodOptional<z.ZodEnum<["hosted", "external"]>>>;
|
|
3478
3478
|
externalUrl: z.ZodOptional<z.ZodString>;
|
|
3479
3479
|
}, "strip", z.ZodTypeAny, {
|
|
3480
|
-
displayName: string;
|
|
3481
|
-
mapElementId?: string | null | undefined;
|
|
3482
|
-
platform: "godot" | "unity" | "web";
|
|
3483
3480
|
metadata: Record<string, unknown>;
|
|
3484
|
-
|
|
3481
|
+
displayName: string;
|
|
3482
|
+
gameType: "hosted" | "external";
|
|
3483
|
+
platform: "web" | "godot" | "unity";
|
|
3485
3484
|
externalUrl?: string | undefined;
|
|
3485
|
+
mapElementId?: string | null | undefined;
|
|
3486
3486
|
}, {
|
|
3487
3487
|
displayName: string;
|
|
3488
|
-
|
|
3489
|
-
platform: "godot" | "unity" | "web";
|
|
3488
|
+
platform: "web" | "godot" | "unity";
|
|
3490
3489
|
metadata?: Record<string, unknown> | undefined;
|
|
3491
|
-
gameType?: "
|
|
3490
|
+
gameType?: "hosted" | "external" | undefined;
|
|
3492
3491
|
externalUrl?: string | undefined;
|
|
3493
|
-
}>, {
|
|
3494
|
-
displayName: string;
|
|
3495
3492
|
mapElementId?: string | null | undefined;
|
|
3496
|
-
|
|
3493
|
+
}>, {
|
|
3497
3494
|
metadata: Record<string, unknown>;
|
|
3498
|
-
|
|
3495
|
+
displayName: string;
|
|
3496
|
+
gameType: "hosted" | "external";
|
|
3497
|
+
platform: "web" | "godot" | "unity";
|
|
3499
3498
|
externalUrl?: string | undefined;
|
|
3499
|
+
mapElementId?: string | null | undefined;
|
|
3500
3500
|
}, {
|
|
3501
3501
|
displayName: string;
|
|
3502
|
-
|
|
3503
|
-
platform: "godot" | "unity" | "web";
|
|
3502
|
+
platform: "web" | "godot" | "unity";
|
|
3504
3503
|
metadata?: Record<string, unknown> | undefined;
|
|
3505
|
-
gameType?: "
|
|
3504
|
+
gameType?: "hosted" | "external" | undefined;
|
|
3506
3505
|
externalUrl?: string | undefined;
|
|
3506
|
+
mapElementId?: string | null | undefined;
|
|
3507
3507
|
}>;
|
|
3508
3508
|
|
|
3509
3509
|
declare const InsertItemSchema: drizzle_zod.BuildSchema<"insert", {
|
|
@@ -3597,7 +3597,7 @@ declare const InsertItemSchema: drizzle_zod.BuildSchema<"insert", {
|
|
|
3597
3597
|
tableName: "items";
|
|
3598
3598
|
dataType: "string";
|
|
3599
3599
|
columnType: "PgEnumColumn";
|
|
3600
|
-
data: "
|
|
3600
|
+
data: "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "accessory" | "other";
|
|
3601
3601
|
driverParam: string;
|
|
3602
3602
|
notNull: true;
|
|
3603
3603
|
hasDefault: true;
|
|
@@ -3692,24 +3692,24 @@ declare const UpdateItemSchema: z.ZodObject<Omit<{
|
|
|
3692
3692
|
imageUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
3693
3693
|
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
3694
3694
|
createdAt: z.ZodOptional<z.ZodDate>;
|
|
3695
|
-
}, "
|
|
3695
|
+
}, "id" | "createdAt">, "strip", z.ZodTypeAny, {
|
|
3696
|
+
description?: string | null | undefined;
|
|
3697
|
+
metadata?: Record<string, unknown> | undefined;
|
|
3698
|
+
type?: "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "accessory" | "other" | undefined;
|
|
3696
3699
|
slug?: string | undefined;
|
|
3697
|
-
gameId?: string | null | undefined;
|
|
3698
3700
|
displayName?: string | undefined;
|
|
3699
|
-
|
|
3700
|
-
type?: "accessory" | "badge" | "collectible" | "consumable" | "currency" | "other" | "trophy" | "unlock" | "upgrade" | undefined;
|
|
3701
|
+
gameId?: string | null | undefined;
|
|
3701
3702
|
isPlaceable?: boolean | undefined;
|
|
3702
3703
|
imageUrl?: string | null | undefined;
|
|
3703
|
-
metadata?: Record<string, unknown> | undefined;
|
|
3704
3704
|
}, {
|
|
3705
|
+
description?: string | null | undefined;
|
|
3706
|
+
metadata?: Record<string, unknown> | undefined;
|
|
3707
|
+
type?: "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "accessory" | "other" | undefined;
|
|
3705
3708
|
slug?: string | undefined;
|
|
3706
|
-
gameId?: string | null | undefined;
|
|
3707
3709
|
displayName?: string | undefined;
|
|
3708
|
-
|
|
3709
|
-
type?: "accessory" | "badge" | "collectible" | "consumable" | "currency" | "other" | "trophy" | "unlock" | "upgrade" | undefined;
|
|
3710
|
+
gameId?: string | null | undefined;
|
|
3710
3711
|
isPlaceable?: boolean | undefined;
|
|
3711
3712
|
imageUrl?: string | null | undefined;
|
|
3712
|
-
metadata?: Record<string, unknown> | undefined;
|
|
3713
3713
|
}>;
|
|
3714
3714
|
declare const InsertCurrencySchema: drizzle_zod.BuildSchema<"insert", {
|
|
3715
3715
|
id: drizzle_orm_pg_core.PgColumn<{
|
|
@@ -3819,16 +3819,16 @@ declare const InsertCurrencySchema: drizzle_zod.BuildSchema<"insert", {
|
|
|
3819
3819
|
isPrimary: z.ZodDefault<z.ZodBoolean>;
|
|
3820
3820
|
}>;
|
|
3821
3821
|
declare const UpdateCurrencySchema: z.ZodObject<{
|
|
3822
|
-
itemId: z.ZodOptional<z.ZodString>;
|
|
3823
3822
|
symbol: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
|
|
3823
|
+
itemId: z.ZodOptional<z.ZodString>;
|
|
3824
3824
|
isPrimary: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
3825
3825
|
}, "strip", z.ZodTypeAny, {
|
|
3826
|
-
itemId?: string | undefined;
|
|
3827
3826
|
symbol?: string | null | undefined;
|
|
3827
|
+
itemId?: string | undefined;
|
|
3828
3828
|
isPrimary?: boolean | undefined;
|
|
3829
3829
|
}, {
|
|
3830
|
-
itemId?: string | undefined;
|
|
3831
3830
|
symbol?: string | null | undefined;
|
|
3831
|
+
itemId?: string | undefined;
|
|
3832
3832
|
isPrimary?: boolean | undefined;
|
|
3833
3833
|
}>;
|
|
3834
3834
|
declare const InsertShopListingSchema: drizzle_zod.BuildSchema<"insert", {
|
|
@@ -4039,28 +4039,28 @@ declare const UpdateShopListingSchema: z.ZodObject<{
|
|
|
4039
4039
|
updatedAt: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodDate>>>;
|
|
4040
4040
|
}, "strip", z.ZodTypeAny, {
|
|
4041
4041
|
id?: string | undefined;
|
|
4042
|
+
createdAt?: Date | undefined;
|
|
4043
|
+
updatedAt?: Date | null | undefined;
|
|
4044
|
+
isActive?: boolean | undefined;
|
|
4042
4045
|
itemId?: string | undefined;
|
|
4043
4046
|
currencyId?: string | undefined;
|
|
4044
4047
|
price?: number | undefined;
|
|
4045
4048
|
sellBackPercentage?: number | null | undefined;
|
|
4046
4049
|
stock?: number | null | undefined;
|
|
4047
|
-
isActive?: boolean | undefined;
|
|
4048
4050
|
availableFrom?: Date | null | undefined;
|
|
4049
4051
|
availableUntil?: Date | null | undefined;
|
|
4050
|
-
createdAt?: Date | undefined;
|
|
4051
|
-
updatedAt?: Date | null | undefined;
|
|
4052
4052
|
}, {
|
|
4053
4053
|
id?: string | undefined;
|
|
4054
|
+
createdAt?: Date | undefined;
|
|
4055
|
+
updatedAt?: Date | null | undefined;
|
|
4056
|
+
isActive?: boolean | undefined;
|
|
4054
4057
|
itemId?: string | undefined;
|
|
4055
4058
|
currencyId?: string | undefined;
|
|
4056
4059
|
price?: number | undefined;
|
|
4057
4060
|
sellBackPercentage?: number | null | undefined;
|
|
4058
4061
|
stock?: number | null | undefined;
|
|
4059
|
-
isActive?: boolean | undefined;
|
|
4060
4062
|
availableFrom?: Date | null | undefined;
|
|
4061
4063
|
availableUntil?: Date | null | undefined;
|
|
4062
|
-
createdAt?: Date | undefined;
|
|
4063
|
-
updatedAt?: Date | null | undefined;
|
|
4064
4064
|
}>;
|
|
4065
4065
|
|
|
4066
4066
|
type GameRow = typeof games.$inferSelect;
|
|
@@ -4873,6 +4873,9 @@ declare abstract class PlaycademyBaseClient {
|
|
|
4873
4873
|
* Initializes connection monitoring if enabled.
|
|
4874
4874
|
*/
|
|
4875
4875
|
private _initializeConnectionMonitor;
|
|
4876
|
+
/**
|
|
4877
|
+
* Initializes an internal game session for automatic session management.
|
|
4878
|
+
*/
|
|
4876
4879
|
private _initializeInternalSession;
|
|
4877
4880
|
/**
|
|
4878
4881
|
* Current user data and inventory management.
|
|
@@ -4916,8 +4919,8 @@ declare class PlaycademyClient extends PlaycademyBaseClient {
|
|
|
4916
4919
|
*/
|
|
4917
4920
|
runtime: {
|
|
4918
4921
|
getGameToken: (gameId: string, options?: {
|
|
4919
|
-
apply?: boolean
|
|
4920
|
-
}
|
|
4922
|
+
apply?: boolean;
|
|
4923
|
+
}) => Promise<GameTokenResponse>;
|
|
4921
4924
|
exit: () => Promise<void>;
|
|
4922
4925
|
onInit: (handler: (context: GameContextPayload) => void) => void;
|
|
4923
4926
|
onTokenRefresh: (handler: (data: {
|
|
@@ -4941,7 +4944,7 @@ declare class PlaycademyClient extends PlaycademyBaseClient {
|
|
|
4941
4944
|
getListenerCounts: () => Record<string, number>;
|
|
4942
4945
|
assets: {
|
|
4943
4946
|
url(pathOrStrings: string | TemplateStringsArray, ...values: unknown[]): string;
|
|
4944
|
-
fetch: (path: string, options?: RequestInit
|
|
4947
|
+
fetch: (path: string, options?: RequestInit) => Promise<Response>;
|
|
4945
4948
|
json: <T = unknown>(path: string) => Promise<T>;
|
|
4946
4949
|
blob: (path: string) => Promise<Blob>;
|
|
4947
4950
|
text: (path: string) => Promise<string>;
|
|
@@ -4984,7 +4987,7 @@ declare class PlaycademyClient extends PlaycademyBaseClient {
|
|
|
4984
4987
|
* - `submit(gameId, score, metadata?)` - Record a game score
|
|
4985
4988
|
*/
|
|
4986
4989
|
scores: {
|
|
4987
|
-
submit: (gameId: string, score: number, metadata?: Record<string, unknown>
|
|
4990
|
+
submit: (gameId: string, score: number, metadata?: Record<string, unknown>) => Promise<ScoreSubmission>;
|
|
4988
4991
|
};
|
|
4989
4992
|
/**
|
|
4990
4993
|
* Realtime multiplayer authentication.
|
|
@@ -5001,13 +5004,13 @@ declare class PlaycademyClient extends PlaycademyBaseClient {
|
|
|
5001
5004
|
* - Routes are relative to your game's deployment (e.g., '/hello' → your-game.playcademy.gg/api/hello)
|
|
5002
5005
|
*/
|
|
5003
5006
|
backend: {
|
|
5004
|
-
get<T = unknown>(path: string, headers?: Record<string, string>
|
|
5005
|
-
post<T = unknown>(path: string, body?: unknown, headers?: Record<string, string>
|
|
5006
|
-
put<T = unknown>(path: string, body?: unknown, headers?: Record<string, string>
|
|
5007
|
-
patch<T = unknown>(path: string, body?: unknown, headers?: Record<string, string>
|
|
5008
|
-
delete<T = unknown>(path: string, headers?: Record<string, string>
|
|
5009
|
-
request<T = unknown>(path: string, method: Method, body?: unknown, headers?: Record<string, string>
|
|
5010
|
-
download(path: string, method?: Method, body?: unknown, headers?: Record<string, string>
|
|
5007
|
+
get<T = unknown>(path: string, headers?: Record<string, string>): Promise<T>;
|
|
5008
|
+
post<T = unknown>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T>;
|
|
5009
|
+
put<T = unknown>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T>;
|
|
5010
|
+
patch<T = unknown>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T>;
|
|
5011
|
+
delete<T = unknown>(path: string, headers?: Record<string, string>): Promise<T>;
|
|
5012
|
+
request<T = unknown>(path: string, method: Method, body?: unknown, headers?: Record<string, string>): Promise<T>;
|
|
5013
|
+
download(path: string, method?: Method, body?: unknown, headers?: Record<string, string>): Promise<Response>;
|
|
5011
5014
|
url(pathOrStrings: string | TemplateStringsArray, ...values: unknown[]): string;
|
|
5012
5015
|
};
|
|
5013
5016
|
/** Auto-initializes a PlaycademyClient with context from the environment */
|
|
@@ -5065,6 +5068,45 @@ interface TimebackUserContext {
|
|
|
5065
5068
|
/** User's organizations (schools/districts) */
|
|
5066
5069
|
organizations: TimebackOrganization[];
|
|
5067
5070
|
}
|
|
5071
|
+
/**
|
|
5072
|
+
* XP data access for the current user.
|
|
5073
|
+
* Results are cached for 5 seconds to avoid redundant network requests.
|
|
5074
|
+
*/
|
|
5075
|
+
interface TimebackUserXp {
|
|
5076
|
+
/**
|
|
5077
|
+
* Fetch XP data from the server.
|
|
5078
|
+
* Returns XP for all courses in this game, or filter by grade/subject.
|
|
5079
|
+
* Results are cached for 5 seconds (use `force: true` to bypass).
|
|
5080
|
+
*
|
|
5081
|
+
* @param options - Query options
|
|
5082
|
+
* @param options.grade - Grade level to filter (must be used with subject)
|
|
5083
|
+
* @param options.subject - Subject to filter (must be used with grade)
|
|
5084
|
+
* @param options.include - Additional data to include: 'perCourse', 'today'
|
|
5085
|
+
* @param options.force - Bypass cache and fetch fresh data (default: false)
|
|
5086
|
+
* @returns Promise resolving to XP data
|
|
5087
|
+
*
|
|
5088
|
+
* @example
|
|
5089
|
+
* ```typescript
|
|
5090
|
+
* // Get total XP for all game courses
|
|
5091
|
+
* const xp = await client.timeback.user.xp.fetch()
|
|
5092
|
+
*
|
|
5093
|
+
* // Get XP for a specific grade/subject
|
|
5094
|
+
* const xp = await client.timeback.user.xp.fetch({
|
|
5095
|
+
* grade: 3,
|
|
5096
|
+
* subject: 'Math'
|
|
5097
|
+
* })
|
|
5098
|
+
*
|
|
5099
|
+
* // Get XP with per-course breakdown
|
|
5100
|
+
* const xp = await client.timeback.user.xp.fetch({
|
|
5101
|
+
* include: ['perCourse', 'today']
|
|
5102
|
+
* })
|
|
5103
|
+
*
|
|
5104
|
+
* // Force fresh data
|
|
5105
|
+
* const xp = await client.timeback.user.xp.fetch({ force: true })
|
|
5106
|
+
* ```
|
|
5107
|
+
*/
|
|
5108
|
+
fetch(options?: GetXpOptions): Promise<XpResponse>;
|
|
5109
|
+
}
|
|
5068
5110
|
/**
|
|
5069
5111
|
* TimeBack user object with both cached getters and fetch method.
|
|
5070
5112
|
*/
|
|
@@ -5078,6 +5120,42 @@ interface TimebackUser extends TimebackUserContext {
|
|
|
5078
5120
|
fetch(options?: {
|
|
5079
5121
|
force?: boolean;
|
|
5080
5122
|
}): Promise<TimebackUserContext>;
|
|
5123
|
+
/**
|
|
5124
|
+
* XP data for the current user.
|
|
5125
|
+
* Call `xp.fetch()` to get XP from the server.
|
|
5126
|
+
*/
|
|
5127
|
+
xp: TimebackUserXp;
|
|
5128
|
+
}
|
|
5129
|
+
/**
|
|
5130
|
+
* Options for querying student XP.
|
|
5131
|
+
*/
|
|
5132
|
+
interface GetXpOptions {
|
|
5133
|
+
/** Grade level to filter (must be used with subject) */
|
|
5134
|
+
grade?: TimebackGrade;
|
|
5135
|
+
/** Subject to filter (must be used with grade) */
|
|
5136
|
+
subject?: TimebackSubject;
|
|
5137
|
+
/** Additional data to include: 'perCourse', 'today' */
|
|
5138
|
+
include?: ('perCourse' | 'today')[];
|
|
5139
|
+
/** Bypass cache and fetch fresh data (default: false) */
|
|
5140
|
+
force?: boolean;
|
|
5141
|
+
}
|
|
5142
|
+
/**
|
|
5143
|
+
* XP data for a single course.
|
|
5144
|
+
*/
|
|
5145
|
+
interface CourseXp {
|
|
5146
|
+
grade: TimebackGrade;
|
|
5147
|
+
subject: TimebackSubject;
|
|
5148
|
+
title: string;
|
|
5149
|
+
totalXp: number;
|
|
5150
|
+
todayXp?: number;
|
|
5151
|
+
}
|
|
5152
|
+
/**
|
|
5153
|
+
* Response from XP query.
|
|
5154
|
+
*/
|
|
5155
|
+
interface XpResponse {
|
|
5156
|
+
totalXp: number;
|
|
5157
|
+
todayXp?: number;
|
|
5158
|
+
courses?: CourseXp[];
|
|
5081
5159
|
}
|
|
5082
5160
|
|
|
5083
5161
|
/**
|
|
@@ -5716,4 +5794,4 @@ interface PlaycademyServerClientState {
|
|
|
5716
5794
|
}
|
|
5717
5795
|
|
|
5718
5796
|
export { AchievementCompletionType, NotificationStatus, NotificationType, PlaycademyClient };
|
|
5719
|
-
export type { AchievementCurrent, AchievementHistoryEntry, AchievementProgressResponse, AchievementScopeType, AchievementWithStatus, AuthCallbackPayload, AuthOptions, AuthProviderType, AuthResult, AuthServerMessage, AuthStateChangePayload, AuthStateUpdate, AuthenticatedUser, BetterAuthApiKey, BetterAuthApiKeyResponse, BetterAuthSignInResponse, BucketFile, CharacterComponentRow as CharacterComponent, CharacterComponentType, CharacterComponentWithSpriteUrl, CharacterComponentsOptions, ClientConfig, ClientEvents, ConnectionStatePayload, CreateCharacterData, CreateMapObjectData, CurrencyRow as Currency, DevUploadEvent, DevUploadHooks, DeveloperStatusEnumType, DeveloperStatusResponse, DeveloperStatusValue, DisconnectContext, DisconnectHandler, DisplayAlertPayload, EventListeners, ExternalGame, FetchedGame, Game, GameContextPayload, GameCustomHostname, GameInitUser, GameLeaderboardEntry, MapRow as GameMap, GamePlatform, GameRow as GameRecord, GameSessionRow as GameSession, GameTimebackIntegration, GameTokenResponse, GameType, GameUser, HostedGame, InitPayload, InsertCurrencyInput, InsertItemInput, InsertShopListingInput, InteractionType, InventoryItemRow as InventoryItem, InventoryItemWithItem, InventoryMutationResponse, ItemRow as Item, ItemType, KVKeyEntry, KVKeyMetadata, KVSeedEntry, KVStatsResponse, KeyEventPayload, LeaderboardEntry, LeaderboardOptions, LeaderboardTimeframe, LevelConfigRow as LevelConfig, LevelProgressResponse, LevelUpCheckResult, LoginResponse, ManifestV1, MapData, MapElementRow as MapElement, MapElementMetadata, MapElementWithGame, MapObjectRow as MapObject, MapObjectWithItem, NotificationRow as Notification, NotificationStats, PlaceableItemMetadata, PlatformTimebackUser, PlatformTimebackUserContext, PlaycademyServerClientConfig, PlaycademyServerClientState, PlayerCharacterRow as PlayerCharacter, PlayerCharacterAccessoryRow as PlayerCharacterAccessory, PlayerCurrency, PlayerInventoryItem, PlayerProfile, PlayerSessionPayload, PopulateStudentResponse, RealtimeTokenResponse, ScoreSubmission, ShopCurrency, ShopDisplayItem, ShopListingRow as ShopListing, ShopViewResponse, SpriteAnimationFrame, SpriteConfigWithDimensions, SpriteTemplateRow as SpriteTemplate, SpriteTemplateData, StartSessionResponse, TelemetryPayload, TimebackEnrollment, TimebackInitContext, TimebackOrganization, TimebackUser, TimebackUserContext, TodayXpResponse, TokenRefreshPayload, TokenType, TotalXpResponse, UpdateCharacterData, UpdateCurrencyInput, UpdateItemInput, UpdateShopListingInput, UpsertGameMetadataInput, UserRow as User, UserEnrollment, UserInfo, UserLevelRow as UserLevel, UserLevelWithConfig, UserOrganization, UserRank, UserRankResponse, UserRoleEnumType, UserScore, UserTimebackData, XPAddResult, XpHistoryResponse, XpSummaryResponse };
|
|
5797
|
+
export type { AchievementCurrent, AchievementHistoryEntry, AchievementProgressResponse, AchievementScopeType, AchievementWithStatus, AuthCallbackPayload, AuthOptions, AuthProviderType, AuthResult, AuthServerMessage, AuthStateChangePayload, AuthStateUpdate, AuthenticatedUser, BetterAuthApiKey, BetterAuthApiKeyResponse, BetterAuthSignInResponse, BucketFile, CharacterComponentRow as CharacterComponent, CharacterComponentType, CharacterComponentWithSpriteUrl, CharacterComponentsOptions, ClientConfig, ClientEvents, ConnectionStatePayload, CourseXp, CreateCharacterData, CreateMapObjectData, CurrencyRow as Currency, DevUploadEvent, DevUploadHooks, DeveloperStatusEnumType, DeveloperStatusResponse, DeveloperStatusValue, DisconnectContext, DisconnectHandler, DisplayAlertPayload, EventListeners, ExternalGame, FetchedGame, Game, GameContextPayload, GameCustomHostname, GameInitUser, GameLeaderboardEntry, MapRow as GameMap, GamePlatform, GameRow as GameRecord, GameSessionRow as GameSession, GameTimebackIntegration, GameTokenResponse, GameType, GameUser, GetXpOptions, HostedGame, InitPayload, InsertCurrencyInput, InsertItemInput, InsertShopListingInput, InteractionType, InventoryItemRow as InventoryItem, InventoryItemWithItem, InventoryMutationResponse, ItemRow as Item, ItemType, KVKeyEntry, KVKeyMetadata, KVSeedEntry, KVStatsResponse, KeyEventPayload, LeaderboardEntry, LeaderboardOptions, LeaderboardTimeframe, LevelConfigRow as LevelConfig, LevelProgressResponse, LevelUpCheckResult, LoginResponse, ManifestV1, MapData, MapElementRow as MapElement, MapElementMetadata, MapElementWithGame, MapObjectRow as MapObject, MapObjectWithItem, NotificationRow as Notification, NotificationStats, PlaceableItemMetadata, PlatformTimebackUser, PlatformTimebackUserContext, PlaycademyServerClientConfig, PlaycademyServerClientState, PlayerCharacterRow as PlayerCharacter, PlayerCharacterAccessoryRow as PlayerCharacterAccessory, PlayerCurrency, PlayerInventoryItem, PlayerProfile, PlayerSessionPayload, PopulateStudentResponse, RealtimeTokenResponse, ScoreSubmission, ShopCurrency, ShopDisplayItem, ShopListingRow as ShopListing, ShopViewResponse, SpriteAnimationFrame, SpriteConfigWithDimensions, SpriteTemplateRow as SpriteTemplate, SpriteTemplateData, StartSessionResponse, TelemetryPayload, TimebackEnrollment, TimebackInitContext, TimebackOrganization, TimebackUser, TimebackUserContext, TimebackUserXp, TodayXpResponse, TokenRefreshPayload, TokenType, TotalXpResponse, UpdateCharacterData, UpdateCurrencyInput, UpdateItemInput, UpdateShopListingInput, UpsertGameMetadataInput, UserRow as User, UserEnrollment, UserInfo, UserLevelRow as UserLevel, UserLevelWithConfig, UserOrganization, UserRank, UserRankResponse, UserRoleEnumType, UserScore, UserTimebackData, XPAddResult, XpHistoryResponse, XpResponse, XpSummaryResponse };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@playcademy/sdk",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.12",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -44,12 +44,12 @@
|
|
|
44
44
|
"@playcademy/data": "0.0.1",
|
|
45
45
|
"@playcademy/logger": "0.0.1",
|
|
46
46
|
"@playcademy/types": "0.0.1",
|
|
47
|
-
"@playcademy/sandbox": "0.3.
|
|
47
|
+
"@playcademy/sandbox": "0.3.13",
|
|
48
48
|
"@playcademy/test": "0.0.1",
|
|
49
49
|
"@playcademy/timeback": "0.0.1",
|
|
50
50
|
"@playcademy/utils": "0.0.1",
|
|
51
51
|
"@types/bun": "latest",
|
|
52
|
-
"playcademy": "0.16.
|
|
52
|
+
"playcademy": "0.16.5",
|
|
53
53
|
"rollup": "^4.50.2",
|
|
54
54
|
"rollup-plugin-dts": "^6.2.3",
|
|
55
55
|
"typescript": "^5.7.2"
|