@playcademy/vite-plugin 0.2.26-beta.8 → 0.2.27-beta.1
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.js +85 -20
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -25370,7 +25370,7 @@ var package_default;
|
|
|
25370
25370
|
var init_package = __esm(() => {
|
|
25371
25371
|
package_default = {
|
|
25372
25372
|
name: "@playcademy/sandbox",
|
|
25373
|
-
version: "0.3.17-beta.
|
|
25373
|
+
version: "0.3.17-beta.24",
|
|
25374
25374
|
description: "Local development server for Playcademy game development",
|
|
25375
25375
|
type: "module",
|
|
25376
25376
|
exports: {
|
|
@@ -54793,13 +54793,54 @@ class TimebackAdminService {
|
|
|
54793
54793
|
const remediationItems = events.map((event) => mapCaliperEventToRemediationActivity(event, relevantCourseIds)).filter((item) => Boolean(item));
|
|
54794
54794
|
return [...groupedGameplayItems, ...remediationItems].toSorted((a, b) => b.occurredAt.localeCompare(a.occurredAt));
|
|
54795
54795
|
}
|
|
54796
|
-
async getStudentEnrollmentsByCourseId(client, studentId, courseIds) {
|
|
54797
|
-
const
|
|
54798
|
-
const
|
|
54799
|
-
|
|
54796
|
+
async getStudentEnrollmentsByCourseId(client, studentId, courseIds, options) {
|
|
54797
|
+
const enrollments = new Map;
|
|
54798
|
+
const entries = await Promise.all(courseIds.map(async (courseId) => {
|
|
54799
|
+
const roster = await client.oneroster.enrollments.listByCourse(courseId, {
|
|
54800
|
+
includeInactive: options?.includeInactive,
|
|
54801
|
+
includeUsers: false
|
|
54802
|
+
});
|
|
54803
|
+
const matches = roster.filter((entry) => entry.enrollment.user.sourcedId === studentId).toSorted((a, b) => {
|
|
54804
|
+
const aActive = a.enrollment.status === "active";
|
|
54805
|
+
const bActive = b.enrollment.status === "active";
|
|
54806
|
+
if (aActive !== bActive) {
|
|
54807
|
+
return aActive ? -1 : 1;
|
|
54808
|
+
}
|
|
54809
|
+
return (b.enrollment.dateLastModified ?? "").localeCompare(a.enrollment.dateLastModified ?? "");
|
|
54810
|
+
});
|
|
54811
|
+
return { courseId, match: matches[0] ?? null };
|
|
54812
|
+
}));
|
|
54813
|
+
for (const { courseId, match } of entries) {
|
|
54814
|
+
if (match) {
|
|
54815
|
+
enrollments.set(courseId, {
|
|
54816
|
+
id: match.enrollment.sourcedId,
|
|
54817
|
+
status: match.enrollment.status ?? "active",
|
|
54818
|
+
role: match.enrollment.role ?? "student",
|
|
54819
|
+
beginDate: match.enrollment.beginDate ?? null,
|
|
54820
|
+
endDate: match.enrollment.endDate ?? null,
|
|
54821
|
+
course: {
|
|
54822
|
+
id: courseId,
|
|
54823
|
+
title: match.class?.title ?? "",
|
|
54824
|
+
subjects: null,
|
|
54825
|
+
grades: null
|
|
54826
|
+
}
|
|
54827
|
+
});
|
|
54828
|
+
}
|
|
54829
|
+
}
|
|
54830
|
+
return { enrollments };
|
|
54800
54831
|
}
|
|
54801
54832
|
async assertStudentEnrolledInCourse(client, studentId, courseId) {
|
|
54802
|
-
const
|
|
54833
|
+
const enrollments = await client.edubridge.enrollments.listByUser(studentId);
|
|
54834
|
+
const match = enrollments.find((e) => e.course.id === courseId);
|
|
54835
|
+
if (!match) {
|
|
54836
|
+
throw new NotFoundError("Student enrollment", `${studentId}:${courseId}`);
|
|
54837
|
+
}
|
|
54838
|
+
return match;
|
|
54839
|
+
}
|
|
54840
|
+
async assertStudentHasEnrollmentInCourse(client, studentId, courseId) {
|
|
54841
|
+
const { enrollments: enrollmentsByCourseId } = await this.getStudentEnrollmentsByCourseId(client, studentId, [courseId], {
|
|
54842
|
+
includeInactive: true
|
|
54843
|
+
});
|
|
54803
54844
|
if (!enrollmentsByCourseId.has(courseId)) {
|
|
54804
54845
|
throw new NotFoundError("Student enrollment", `${studentId}:${courseId}`);
|
|
54805
54846
|
}
|
|
@@ -54852,7 +54893,7 @@ class TimebackAdminService {
|
|
|
54852
54893
|
return [];
|
|
54853
54894
|
}
|
|
54854
54895
|
}
|
|
54855
|
-
async listStudentsForCourse(gameId, courseId, user) {
|
|
54896
|
+
async listStudentsForCourse(gameId, courseId, user, options) {
|
|
54856
54897
|
const client = this.requireClient();
|
|
54857
54898
|
await this.deps.validateGameManagementAccess(user, gameId);
|
|
54858
54899
|
const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
|
|
@@ -54862,7 +54903,8 @@ class TimebackAdminService {
|
|
|
54862
54903
|
throw new NotFoundError("Timeback integration", `${gameId}:${courseId}`);
|
|
54863
54904
|
}
|
|
54864
54905
|
const roster = await client.oneroster.enrollments.listByCourse(courseId, {
|
|
54865
|
-
role: "student"
|
|
54906
|
+
role: "student",
|
|
54907
|
+
includeInactive: options?.includeInactive
|
|
54866
54908
|
});
|
|
54867
54909
|
const analyticsByEnrollmentId = await this.loadEnrollmentAnalyticsSummaries(roster.map((rosterEntry) => rosterEntry.enrollment.sourcedId).filter((enrollmentId) => Boolean(enrollmentId)));
|
|
54868
54910
|
const masterableUnits = await this.getMasterableUnits(courseId);
|
|
@@ -54871,6 +54913,7 @@ class TimebackAdminService {
|
|
|
54871
54913
|
const summary = enrollmentId ? analyticsByEnrollmentId.get(enrollmentId) : undefined;
|
|
54872
54914
|
const analyticsUnavailable = Boolean(enrollmentId) && summary?.analyticsAvailable !== true;
|
|
54873
54915
|
const name3 = rosterEntry.user ? `${rosterEntry.user.givenName} ${rosterEntry.user.familyName}`.trim() : rosterEntry.enrollment.user.sourcedId;
|
|
54916
|
+
const inactive = rosterEntry.enrollment.status === "tobedeleted";
|
|
54874
54917
|
return {
|
|
54875
54918
|
studentId: rosterEntry.enrollment.user.sourcedId,
|
|
54876
54919
|
enrollmentId,
|
|
@@ -54884,11 +54927,25 @@ class TimebackAdminService {
|
|
|
54884
54927
|
activeTimeSeconds: summary?.activeTimeSeconds ?? 0,
|
|
54885
54928
|
masteredUnits: summary?.masteredUnits ?? 0,
|
|
54886
54929
|
masterableUnits,
|
|
54887
|
-
pctCompleteApp: TimebackAdminService.computeCompletionPct(summary?.masteredUnits ?? 0, masterableUnits)
|
|
54930
|
+
pctCompleteApp: TimebackAdminService.computeCompletionPct(summary?.masteredUnits ?? 0, masterableUnits),
|
|
54931
|
+
...inactive ? { inactive } : {}
|
|
54888
54932
|
};
|
|
54889
54933
|
});
|
|
54890
|
-
|
|
54891
|
-
|
|
54934
|
+
const studentMap = new Map;
|
|
54935
|
+
for (const student of students) {
|
|
54936
|
+
const existing = studentMap.get(student.studentId);
|
|
54937
|
+
if (!existing || existing.inactive && !student.inactive) {
|
|
54938
|
+
studentMap.set(student.studentId, student);
|
|
54939
|
+
}
|
|
54940
|
+
}
|
|
54941
|
+
const deduped = [...studentMap.values()];
|
|
54942
|
+
deduped.sort((a, b) => {
|
|
54943
|
+
if (a.inactive !== b.inactive) {
|
|
54944
|
+
return a.inactive ? 1 : -1;
|
|
54945
|
+
}
|
|
54946
|
+
return a.name.localeCompare(b.name);
|
|
54947
|
+
});
|
|
54948
|
+
return { gameId, courseId, students: deduped };
|
|
54892
54949
|
}
|
|
54893
54950
|
async getStudentOverview(gameId, studentId, user, courseId) {
|
|
54894
54951
|
const client = this.requireClient();
|
|
@@ -54900,7 +54957,9 @@ class TimebackAdminService {
|
|
|
54900
54957
|
throw new NotFoundError("Timeback integration", gameId);
|
|
54901
54958
|
}
|
|
54902
54959
|
const courseIds = new Set(integrations.map((integration) => integration.courseId));
|
|
54903
|
-
const enrollmentsByCourseId = await this.getStudentEnrollmentsByCourseId(client, studentId, [...courseIds]
|
|
54960
|
+
const { enrollments: enrollmentsByCourseId } = await this.getStudentEnrollmentsByCourseId(client, studentId, [...courseIds], {
|
|
54961
|
+
includeInactive: true
|
|
54962
|
+
});
|
|
54904
54963
|
if (enrollmentsByCourseId.size === 0) {
|
|
54905
54964
|
throw new NotFoundError("Student enrollment", courseId ? `${studentId}:${courseId}` : `${studentId}:${gameId}`);
|
|
54906
54965
|
}
|
|
@@ -54915,6 +54974,7 @@ class TimebackAdminService {
|
|
|
54915
54974
|
const summary = enrollment ? analyticsByEnrollmentId.get(enrollment.id) : undefined;
|
|
54916
54975
|
const masterableUnits = masterableUnitsByCourse.get(integration.courseId);
|
|
54917
54976
|
const analyticsUnavailable = Boolean(enrollment?.id) && summary?.analyticsAvailable !== true;
|
|
54977
|
+
const inactive = enrollment?.status === "tobedeleted";
|
|
54918
54978
|
return {
|
|
54919
54979
|
courseId: integration.courseId,
|
|
54920
54980
|
title: enrollment?.course.title || `${integration.subject} Grade ${integration.grade}`,
|
|
@@ -54929,7 +54989,8 @@ class TimebackAdminService {
|
|
|
54929
54989
|
masterableUnits,
|
|
54930
54990
|
pctCompleteApp: TimebackAdminService.computeCompletionPct(summary?.masteredUnits ?? 0, masterableUnits),
|
|
54931
54991
|
completionStatus: completionStatusByCourse.get(integration.courseId) ?? "none",
|
|
54932
|
-
history: summary?.history ?? []
|
|
54992
|
+
history: summary?.history ?? [],
|
|
54993
|
+
...inactive ? { inactive } : {}
|
|
54933
54994
|
};
|
|
54934
54995
|
});
|
|
54935
54996
|
return {
|
|
@@ -54956,7 +55017,7 @@ class TimebackAdminService {
|
|
|
54956
55017
|
if (!integration) {
|
|
54957
55018
|
throw new NotFoundError("Timeback integration", `${gameId}:${courseId}`);
|
|
54958
55019
|
}
|
|
54959
|
-
await this.
|
|
55020
|
+
await this.assertStudentHasEnrollmentInCourse(client, studentId, courseId);
|
|
54960
55021
|
const relevantCourseIds = new Set([courseId]);
|
|
54961
55022
|
const fetchLimit = Math.min(safeOffset + safeLimit + 1, TimebackAdminService.MAX_STUDENT_ACTIVITY_OFFSET + TimebackAdminService.MAX_STUDENT_ACTIVITY_LIMIT + 1);
|
|
54962
55023
|
const allActivities = await this.listRecentActivityForStudent(client, studentId, gameSource, relevantCourseIds, fetchLimit);
|
|
@@ -54977,7 +55038,7 @@ class TimebackAdminService {
|
|
|
54977
55038
|
if (!integration) {
|
|
54978
55039
|
throw new NotFoundError("Timeback integration", `${gameId}:${courseId}`);
|
|
54979
55040
|
}
|
|
54980
|
-
await this.
|
|
55041
|
+
await this.assertStudentHasEnrollmentInCourse(client, studentId, courseId);
|
|
54981
55042
|
const events = await this.fetchCaliperEventsForStudent(client, studentId, gameSource, TimebackAdminService.MAX_RECENT_ACTIVITY_EVENT_FETCH);
|
|
54982
55043
|
const relevantCourseIds = new Set([courseId]);
|
|
54983
55044
|
let matchedEvents;
|
|
@@ -59540,7 +59601,7 @@ function createOneRosterNamespace(client) {
|
|
|
59540
59601
|
listByClass: async (classSourcedId, options) => {
|
|
59541
59602
|
const queryParams = new URLSearchParams;
|
|
59542
59603
|
const filters = [`class.sourcedId='${escapeFilterValue2(classSourcedId)}'`];
|
|
59543
|
-
if (options?.
|
|
59604
|
+
if (!options?.includeInactive) {
|
|
59544
59605
|
filters.push(`status='active'`);
|
|
59545
59606
|
}
|
|
59546
59607
|
queryParams.set("filter", filters.join(" AND "));
|
|
@@ -59575,7 +59636,7 @@ function createOneRosterNamespace(client) {
|
|
|
59575
59636
|
const queryParams = new URLSearchParams;
|
|
59576
59637
|
const classFilter = batch.map((classId) => `class.sourcedId='${escapeFilterValue2(classId)}'`).join(" OR ");
|
|
59577
59638
|
const filters = [batch.length > 1 ? `(${classFilter})` : classFilter];
|
|
59578
|
-
if (options?.
|
|
59639
|
+
if (!options?.includeInactive) {
|
|
59579
59640
|
filters.push(`status='active'`);
|
|
59580
59641
|
}
|
|
59581
59642
|
if (options?.role) {
|
|
@@ -123479,15 +123540,19 @@ var init_timeback_controller = __esm(() => {
|
|
|
123479
123540
|
getRoster = requireGameManagementAccess(async (ctx) => {
|
|
123480
123541
|
const gameId = ctx.params.gameId;
|
|
123481
123542
|
const courseId = ctx.params.courseId;
|
|
123543
|
+
const includeInactive = ctx.url.searchParams.get("includeInactive") === "true";
|
|
123482
123544
|
if (!gameId || !courseId) {
|
|
123483
123545
|
throw ApiError.badRequest("Missing gameId or courseId parameter");
|
|
123484
123546
|
}
|
|
123485
123547
|
logger64.debug("Getting course roster", {
|
|
123486
123548
|
requesterId: ctx.user.id,
|
|
123487
123549
|
gameId,
|
|
123488
|
-
courseId
|
|
123550
|
+
courseId,
|
|
123551
|
+
includeInactive
|
|
123552
|
+
});
|
|
123553
|
+
return ctx.services.timebackAdmin.listStudentsForCourse(gameId, courseId, ctx.user, {
|
|
123554
|
+
includeInactive
|
|
123489
123555
|
});
|
|
123490
|
-
return ctx.services.timebackAdmin.listStudentsForCourse(gameId, courseId, ctx.user);
|
|
123491
123556
|
});
|
|
123492
123557
|
getStudentOverview = requireGameManagementAccess(async (ctx) => {
|
|
123493
123558
|
const timebackId = ctx.params.timebackId;
|
|
@@ -126480,7 +126545,7 @@ var import_picocolors12 = __toESM(require_picocolors(), 1);
|
|
|
126480
126545
|
// package.json
|
|
126481
126546
|
var package_default2 = {
|
|
126482
126547
|
name: "@playcademy/vite-plugin",
|
|
126483
|
-
version: "0.2.
|
|
126548
|
+
version: "0.2.27-beta.1",
|
|
126484
126549
|
type: "module",
|
|
126485
126550
|
exports: {
|
|
126486
126551
|
".": {
|