@playcademy/sandbox 0.3.17-beta.24 → 0.3.17-beta.26
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/cli.js +140 -110
- package/dist/server.js +140 -110
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1330,7 +1330,7 @@ var package_default;
|
|
|
1330
1330
|
var init_package = __esm(() => {
|
|
1331
1331
|
package_default = {
|
|
1332
1332
|
name: "@playcademy/sandbox",
|
|
1333
|
-
version: "0.3.17-beta.
|
|
1333
|
+
version: "0.3.17-beta.26",
|
|
1334
1334
|
description: "Local development server for Playcademy game development",
|
|
1335
1335
|
type: "module",
|
|
1336
1336
|
exports: {
|
|
@@ -30268,8 +30268,17 @@ function kebabToTitleCase(kebabStr) {
|
|
|
30268
30268
|
return kebabStr.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
30269
30269
|
}
|
|
30270
30270
|
// ../utils/src/timezone.ts
|
|
30271
|
-
function
|
|
30272
|
-
|
|
30271
|
+
function formatDateYMDInTimezone(timeZone, date3 = new Date) {
|
|
30272
|
+
const parts2 = new Intl.DateTimeFormat("en-US", {
|
|
30273
|
+
timeZone,
|
|
30274
|
+
year: "numeric",
|
|
30275
|
+
month: "2-digit",
|
|
30276
|
+
day: "2-digit"
|
|
30277
|
+
}).formatToParts(date3);
|
|
30278
|
+
const y = parts2.find((p) => p.type === "year").value;
|
|
30279
|
+
const m = parts2.find((p) => p.type === "month").value;
|
|
30280
|
+
const d = parts2.find((p) => p.type === "day").value;
|
|
30281
|
+
return `${y}-${m}-${d}`;
|
|
30273
30282
|
}
|
|
30274
30283
|
function getUtcInstantForMidnight(date3, timeZone) {
|
|
30275
30284
|
const parts2 = new Intl.DateTimeFormat("en-US", {
|
|
@@ -30340,6 +30349,19 @@ function getDayBoundariesInTimezone(date3, timezone) {
|
|
|
30340
30349
|
const endOfDay = getUtcInstantForMidnight(nextDayNoon, timezone);
|
|
30341
30350
|
return { startOfDay, endOfDay };
|
|
30342
30351
|
}
|
|
30352
|
+
// ../utils/src/url.ts
|
|
30353
|
+
function buildPath(path, params) {
|
|
30354
|
+
const url = new URL(path, "http://n");
|
|
30355
|
+
if (params) {
|
|
30356
|
+
for (const [key, value] of Object.entries(params)) {
|
|
30357
|
+
if (value != null) {
|
|
30358
|
+
url.searchParams.set(key, value);
|
|
30359
|
+
}
|
|
30360
|
+
}
|
|
30361
|
+
}
|
|
30362
|
+
return `${url.pathname}${url.search}`;
|
|
30363
|
+
}
|
|
30364
|
+
|
|
30343
30365
|
// ../utils/src/pure/index.ts
|
|
30344
30366
|
var init_pure = __esm(() => {
|
|
30345
30367
|
init_uuid2();
|
|
@@ -30392,11 +30414,11 @@ function isRecord2(value) {
|
|
|
30392
30414
|
function getStringValue(value) {
|
|
30393
30415
|
return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
|
|
30394
30416
|
}
|
|
30395
|
-
function parseSourcedIdFromUrl(
|
|
30396
|
-
if (!
|
|
30417
|
+
function parseSourcedIdFromUrl(url2) {
|
|
30418
|
+
if (!url2) {
|
|
30397
30419
|
return;
|
|
30398
30420
|
}
|
|
30399
|
-
const trimmed =
|
|
30421
|
+
const trimmed = url2.trim().replace(/\/$/, "");
|
|
30400
30422
|
if (!trimmed) {
|
|
30401
30423
|
return;
|
|
30402
30424
|
}
|
|
@@ -30785,7 +30807,7 @@ class TimebackAdminService {
|
|
|
30785
30807
|
history: []
|
|
30786
30808
|
};
|
|
30787
30809
|
}
|
|
30788
|
-
const today =
|
|
30810
|
+
const today = formatDateYMDInTimezone(PLATFORM_TIMEZONE);
|
|
30789
30811
|
const history = [];
|
|
30790
30812
|
let totalXpRaw = 0;
|
|
30791
30813
|
let todayXpRaw = 0;
|
|
@@ -30951,7 +30973,9 @@ class TimebackAdminService {
|
|
|
30951
30973
|
const uniqueEnrollmentIds = [...new Set(enrollmentIds)];
|
|
30952
30974
|
const results = await TimebackAdminService.runWithConcurrency(uniqueEnrollmentIds, TimebackAdminService.ANALYTICS_CONCURRENCY, async (enrollmentId) => {
|
|
30953
30975
|
try {
|
|
30954
|
-
const analytics = await client.edubridge.analytics.getEnrollmentFacts(enrollmentId
|
|
30976
|
+
const analytics = await client.edubridge.analytics.getEnrollmentFacts(enrollmentId, {
|
|
30977
|
+
timezone: PLATFORM_TIMEZONE
|
|
30978
|
+
});
|
|
30955
30979
|
return [enrollmentId, this.summarizeAnalyticsFacts(analytics.facts)];
|
|
30956
30980
|
} catch (error) {
|
|
30957
30981
|
logger16.warn("Failed to load enrollment analytics summary", {
|
|
@@ -31225,7 +31249,7 @@ class TimebackAdminService {
|
|
|
31225
31249
|
const enrollment = await this.assertStudentEnrolledInCourse(client, data.studentId, data.courseId);
|
|
31226
31250
|
let currentMastered = 0;
|
|
31227
31251
|
try {
|
|
31228
|
-
const analytics = await client.edubridge.analytics.getEnrollmentFacts(enrollment.id);
|
|
31252
|
+
const analytics = await client.edubridge.analytics.getEnrollmentFacts(enrollment.id, { timezone: PLATFORM_TIMEZONE });
|
|
31229
31253
|
const summary = this.summarizeAnalyticsFacts(analytics.facts);
|
|
31230
31254
|
currentMastered = summary.masteredUnits;
|
|
31231
31255
|
} catch {
|
|
@@ -31415,6 +31439,7 @@ class TimebackAdminService {
|
|
|
31415
31439
|
var logger16;
|
|
31416
31440
|
var init_timeback_admin_service = __esm(() => {
|
|
31417
31441
|
init_drizzle_orm();
|
|
31442
|
+
init_src();
|
|
31418
31443
|
init_tables_index();
|
|
31419
31444
|
init_src2();
|
|
31420
31445
|
init_constants4();
|
|
@@ -33372,13 +33397,13 @@ var init_events = () => {};
|
|
|
33372
33397
|
|
|
33373
33398
|
// ../api-core/src/services/notification.service.ts
|
|
33374
33399
|
function convertWebSocketUrlToHttp(wsUrl) {
|
|
33375
|
-
return wsUrl.replace(/^wss?:\/\//, (
|
|
33400
|
+
return wsUrl.replace(/^wss?:\/\//, (url2) => url2 === "wss://" ? "https://" : "http://");
|
|
33376
33401
|
}
|
|
33377
33402
|
async function publishToUser(baseUrl, secret, userId, type, payload) {
|
|
33378
|
-
const
|
|
33379
|
-
|
|
33403
|
+
const url2 = new URL(baseUrl);
|
|
33404
|
+
url2.pathname = "/publish";
|
|
33380
33405
|
try {
|
|
33381
|
-
const res = await fetch(
|
|
33406
|
+
const res = await fetch(url2.toString(), {
|
|
33382
33407
|
method: "POST",
|
|
33383
33408
|
headers: { "content-type": "application/json" },
|
|
33384
33409
|
body: JSON.stringify({ userId, type, payload, secret })
|
|
@@ -35230,14 +35255,14 @@ function debugSensitive(label, value, showChars = 4) {
|
|
|
35230
35255
|
const masked = value.length > showChars * 2 ? `${value.slice(0, showChars)}...${value.slice(-showChars)}` : `${value.slice(0, showChars)}...`;
|
|
35231
35256
|
console.log(`[DEBUG] ${label}: ${masked}`);
|
|
35232
35257
|
}
|
|
35233
|
-
function debugRequest(method,
|
|
35258
|
+
function debugRequest(method, url2, headers, body2) {
|
|
35234
35259
|
if (!isDebugEnabled()) {
|
|
35235
35260
|
return;
|
|
35236
35261
|
}
|
|
35237
35262
|
console.log(`
|
|
35238
35263
|
[DEBUG] HTTP Request:`);
|
|
35239
35264
|
console.log(` Method: ${method}`);
|
|
35240
|
-
console.log(` URL: ${
|
|
35265
|
+
console.log(` URL: ${url2}`);
|
|
35241
35266
|
if (headers) {
|
|
35242
35267
|
console.log(` Headers:`);
|
|
35243
35268
|
Object.entries(headers).forEach(([key, value]) => {
|
|
@@ -35310,7 +35335,7 @@ async function getTimebackTokenResponse(config2) {
|
|
|
35310
35335
|
function getAuthUrl(environment = "production") {
|
|
35311
35336
|
return TIMEBACK_AUTH_URLS4[environment];
|
|
35312
35337
|
}
|
|
35313
|
-
function handleHttpError(res, errorBody, attempt, retries,
|
|
35338
|
+
function handleHttpError(res, errorBody, attempt, retries, url2) {
|
|
35314
35339
|
const error = new TimebackApiError(res.status, res.statusText, errorBody);
|
|
35315
35340
|
if (res.status >= HTTP_STATUS4.CLIENT_ERROR_MIN && res.status < HTTP_STATUS4.CLIENT_ERROR_MAX) {
|
|
35316
35341
|
throw error;
|
|
@@ -35321,7 +35346,7 @@ function handleHttpError(res, errorBody, attempt, retries, url) {
|
|
|
35321
35346
|
attempt: attempt + 1,
|
|
35322
35347
|
maxRetries: retries,
|
|
35323
35348
|
status: res.status,
|
|
35324
|
-
url
|
|
35349
|
+
url: url2
|
|
35325
35350
|
});
|
|
35326
35351
|
return { retry: true, error };
|
|
35327
35352
|
}
|
|
@@ -35352,7 +35377,7 @@ async function request({
|
|
|
35352
35377
|
retries = 3,
|
|
35353
35378
|
timeout = 1e4
|
|
35354
35379
|
}) {
|
|
35355
|
-
const
|
|
35380
|
+
const url2 = baseUrl.replace(/\/$/, "") + (path.startsWith("/") ? path : `/${path}`);
|
|
35356
35381
|
const headers = { ...extraHeaders };
|
|
35357
35382
|
let payload;
|
|
35358
35383
|
if (body2 instanceof FormData) {
|
|
@@ -35369,8 +35394,8 @@ async function request({
|
|
|
35369
35394
|
try {
|
|
35370
35395
|
const controller = new AbortController;
|
|
35371
35396
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
35372
|
-
debugRequest(method,
|
|
35373
|
-
const res = await fetch(
|
|
35397
|
+
debugRequest(method, url2, headers, body2);
|
|
35398
|
+
const res = await fetch(url2, {
|
|
35374
35399
|
method,
|
|
35375
35400
|
headers,
|
|
35376
35401
|
body: payload,
|
|
@@ -35386,7 +35411,7 @@ async function request({
|
|
|
35386
35411
|
if (errorBody) {
|
|
35387
35412
|
debugResponse(res.status, res.statusText, errorBody);
|
|
35388
35413
|
}
|
|
35389
|
-
const result = handleHttpError(res, errorBody, attempt, retries,
|
|
35414
|
+
const result = handleHttpError(res, errorBody, attempt, retries, url2);
|
|
35390
35415
|
lastError = result.error;
|
|
35391
35416
|
if (result.retry) {
|
|
35392
35417
|
const delay = HTTP_DEFAULTS4.retryBackoffBase ** attempt * 1000;
|
|
@@ -35406,7 +35431,7 @@ async function request({
|
|
|
35406
35431
|
attempt: attempt + 1,
|
|
35407
35432
|
maxRetries: retries,
|
|
35408
35433
|
error: lastError.message,
|
|
35409
|
-
url
|
|
35434
|
+
url: url2
|
|
35410
35435
|
});
|
|
35411
35436
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
35412
35437
|
}
|
|
@@ -35645,7 +35670,9 @@ function createEduBridgeNamespace(client) {
|
|
|
35645
35670
|
}
|
|
35646
35671
|
};
|
|
35647
35672
|
const analytics = {
|
|
35648
|
-
getEnrollmentFacts: async (enrollmentId) => client["request"](`/edubridge/analytics/enrollment/${enrollmentId}`,
|
|
35673
|
+
getEnrollmentFacts: async (enrollmentId, options) => client["request"](buildPath(`/edubridge/analytics/enrollment/${enrollmentId}`, {
|
|
35674
|
+
timezone: options?.timezone
|
|
35675
|
+
}), "GET")
|
|
35649
35676
|
};
|
|
35650
35677
|
return {
|
|
35651
35678
|
enrollments,
|
|
@@ -35736,8 +35763,8 @@ function createOneRosterNamespace(client) {
|
|
|
35736
35763
|
queryParams.set("offset", String(options.offset));
|
|
35737
35764
|
}
|
|
35738
35765
|
const endpoint = `${ONEROSTER_ENDPOINTS4.users}/${userSourcedId}/classes`;
|
|
35739
|
-
const
|
|
35740
|
-
const res = await client["request"](
|
|
35766
|
+
const url2 = queryParams.toString() ? `${endpoint}?${queryParams}` : endpoint;
|
|
35767
|
+
const res = await client["request"](url2, "GET");
|
|
35741
35768
|
return res.classes || [];
|
|
35742
35769
|
}
|
|
35743
35770
|
},
|
|
@@ -35755,9 +35782,9 @@ function createOneRosterNamespace(client) {
|
|
|
35755
35782
|
if (options?.offset) {
|
|
35756
35783
|
queryParams.set("offset", String(options.offset));
|
|
35757
35784
|
}
|
|
35758
|
-
const
|
|
35785
|
+
const url2 = `${ONEROSTER_ENDPOINTS4.enrollments}?${queryParams}`;
|
|
35759
35786
|
try {
|
|
35760
|
-
const response = await client["request"](
|
|
35787
|
+
const response = await client["request"](url2, "GET");
|
|
35761
35788
|
return response.enrollments || [];
|
|
35762
35789
|
} catch (error) {
|
|
35763
35790
|
logTimebackError("list enrollments for class", error, { classSourcedId });
|
|
@@ -35788,8 +35815,8 @@ function createOneRosterNamespace(client) {
|
|
|
35788
35815
|
}
|
|
35789
35816
|
queryParams.set("filter", filters.join(" AND "));
|
|
35790
35817
|
queryParams.set("limit", "3000");
|
|
35791
|
-
const
|
|
35792
|
-
const response = await client["request"](
|
|
35818
|
+
const url2 = `${ONEROSTER_ENDPOINTS4.enrollments}?${queryParams}`;
|
|
35819
|
+
const response = await client["request"](url2, "GET");
|
|
35793
35820
|
return response.enrollments || [];
|
|
35794
35821
|
}));
|
|
35795
35822
|
const enrollments = enrollmentGroups.flat();
|
|
@@ -35954,8 +35981,8 @@ function createOneRosterNamespace(client) {
|
|
|
35954
35981
|
getAttemptStats: async (studentId, lineItemId) => {
|
|
35955
35982
|
try {
|
|
35956
35983
|
const filter = `student.sourcedId='${studentId}' AND assessmentLineItem.sourcedId='${lineItemId}'`;
|
|
35957
|
-
const
|
|
35958
|
-
const response = await client["request"](
|
|
35984
|
+
const url2 = `${ONEROSTER_ENDPOINTS4.assessmentResults}?filter=${encodeURIComponent(filter)}`;
|
|
35985
|
+
const response = await client["request"](url2, "GET");
|
|
35959
35986
|
const results = response.assessmentResults || [];
|
|
35960
35987
|
const firstResult = results[0];
|
|
35961
35988
|
if (!firstResult) {
|
|
@@ -36561,7 +36588,7 @@ class MasteryTracker {
|
|
|
36561
36588
|
});
|
|
36562
36589
|
return;
|
|
36563
36590
|
}
|
|
36564
|
-
const analytics = await this.edubridgeNamespace.analytics.getEnrollmentFacts(enrollment.id);
|
|
36591
|
+
const analytics = await this.edubridgeNamespace.analytics.getEnrollmentFacts(enrollment.id, { timezone: PLATFORM_TIMEZONE });
|
|
36565
36592
|
return analytics.facts;
|
|
36566
36593
|
} catch (error) {
|
|
36567
36594
|
log.error("[MasteryTracker] Failed to load enrollment analytics facts", {
|
|
@@ -37284,7 +37311,7 @@ class TimebackClient {
|
|
|
37284
37311
|
}
|
|
37285
37312
|
const analyticsResults = await Promise.all(filteredEnrollments.map(async (enrollment) => {
|
|
37286
37313
|
try {
|
|
37287
|
-
const analytics = await this.edubridge.analytics.getEnrollmentFacts(enrollment.id);
|
|
37314
|
+
const analytics = await this.edubridge.analytics.getEnrollmentFacts(enrollment.id, { timezone: PLATFORM_TIMEZONE });
|
|
37288
37315
|
return { enrollment, analytics };
|
|
37289
37316
|
} catch (error) {
|
|
37290
37317
|
log.warn("[TimebackClient] Failed to fetch analytics for enrollment", {
|
|
@@ -37294,7 +37321,7 @@ class TimebackClient {
|
|
|
37294
37321
|
return { enrollment, analytics: null };
|
|
37295
37322
|
}
|
|
37296
37323
|
}));
|
|
37297
|
-
const today =
|
|
37324
|
+
const today = formatDateYMDInTimezone(PLATFORM_TIMEZONE);
|
|
37298
37325
|
let totalXp = 0;
|
|
37299
37326
|
let todayXp = 0;
|
|
37300
37327
|
const courses = [];
|
|
@@ -37393,6 +37420,7 @@ var __defProp2, __export2 = (target, all) => {
|
|
|
37393
37420
|
});
|
|
37394
37421
|
}, __esm5 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), TIMEBACK_API_URLS4, TIMEBACK_AUTH_URLS4, CALIPER_API_URLS4, ONEROSTER_ENDPOINTS4, CALIPER_ENDPOINTS4, CALIPER_CONSTANTS4, TIMEBACK_EVENT_TYPES4, TIMEBACK_ACTIONS4, TIMEBACK_TYPES4, ACTIVITY_METRIC_TYPES4, TIME_METRIC_TYPES4, TIMEBACK_SUBJECTS4, TIMEBACK_GRADE_LEVELS4, TIMEBACK_GRADE_LEVEL_LABELS4, CALIPER_SUBJECTS4, ONEROSTER_STATUS4, SCORE_STATUS4, ENV_VARS4, HTTP_DEFAULTS4, AUTH_DEFAULTS4, CACHE_DEFAULTS4, CONFIG_DEFAULTS4, PLAYCADEMY_DEFAULTS4, RESOURCE_DEFAULTS4, HTTP_STATUS4, ERROR_NAMES4, init_constants8, exports_verify, init_verify, TimebackError, TimebackApiError, TimebackAuthenticationError, StudentNotFoundError, ConfigurationError, ResourceNotFoundError, SUBJECT_VALUES2, GRADE_VALUES2, TimebackAuthError, PERFECT_ACCURACY_THRESHOLD = 0.999999, EmailSchema, StudentSourcedIdSchema, StudentIdentifierSchema;
|
|
37395
37422
|
var init_dist3 = __esm(() => {
|
|
37423
|
+
init_src();
|
|
37396
37424
|
init_src();
|
|
37397
37425
|
init_src2();
|
|
37398
37426
|
init_src4();
|
|
@@ -37407,9 +37435,11 @@ var init_dist3 = __esm(() => {
|
|
|
37407
37435
|
init_src2();
|
|
37408
37436
|
init_src2();
|
|
37409
37437
|
init_src2();
|
|
37438
|
+
init_src4();
|
|
37410
37439
|
init_src2();
|
|
37411
37440
|
init_src2();
|
|
37412
37441
|
init_src2();
|
|
37442
|
+
init_src();
|
|
37413
37443
|
init_src2();
|
|
37414
37444
|
init_src2();
|
|
37415
37445
|
init_src2();
|
|
@@ -38262,20 +38292,20 @@ var splitPath = (path) => {
|
|
|
38262
38292
|
});
|
|
38263
38293
|
}
|
|
38264
38294
|
}, tryDecodeURI = (str) => tryDecode(str, decodeURI), getPath = (request2) => {
|
|
38265
|
-
const
|
|
38266
|
-
const start2 =
|
|
38295
|
+
const url2 = request2.url;
|
|
38296
|
+
const start2 = url2.indexOf("/", url2.indexOf(":") + 4);
|
|
38267
38297
|
let i2 = start2;
|
|
38268
|
-
for (;i2 <
|
|
38269
|
-
const charCode =
|
|
38298
|
+
for (;i2 < url2.length; i2++) {
|
|
38299
|
+
const charCode = url2.charCodeAt(i2);
|
|
38270
38300
|
if (charCode === 37) {
|
|
38271
|
-
const queryIndex =
|
|
38272
|
-
const path =
|
|
38301
|
+
const queryIndex = url2.indexOf("?", i2);
|
|
38302
|
+
const path = url2.slice(start2, queryIndex === -1 ? undefined : queryIndex);
|
|
38273
38303
|
return tryDecodeURI(path.includes("%25") ? path.replace(/%25/g, "%2525") : path);
|
|
38274
38304
|
} else if (charCode === 63) {
|
|
38275
38305
|
break;
|
|
38276
38306
|
}
|
|
38277
38307
|
}
|
|
38278
|
-
return
|
|
38308
|
+
return url2.slice(start2, i2);
|
|
38279
38309
|
}, getPathNoStrict = (request2) => {
|
|
38280
38310
|
const result = getPath(request2);
|
|
38281
38311
|
return result.length > 1 && result.at(-1) === "/" ? result.slice(0, -1) : result;
|
|
@@ -38318,42 +38348,42 @@ var splitPath = (path) => {
|
|
|
38318
38348
|
value = value.replace(/\+/g, " ");
|
|
38319
38349
|
}
|
|
38320
38350
|
return value.indexOf("%") !== -1 ? tryDecode(value, decodeURIComponent_) : value;
|
|
38321
|
-
}, _getQueryParam = (
|
|
38351
|
+
}, _getQueryParam = (url2, key, multiple) => {
|
|
38322
38352
|
let encoded;
|
|
38323
38353
|
if (!multiple && key && !/[%+]/.test(key)) {
|
|
38324
|
-
let keyIndex2 =
|
|
38354
|
+
let keyIndex2 = url2.indexOf("?", 8);
|
|
38325
38355
|
if (keyIndex2 === -1) {
|
|
38326
38356
|
return;
|
|
38327
38357
|
}
|
|
38328
|
-
if (!
|
|
38329
|
-
keyIndex2 =
|
|
38358
|
+
if (!url2.startsWith(key, keyIndex2 + 1)) {
|
|
38359
|
+
keyIndex2 = url2.indexOf(`&${key}`, keyIndex2 + 1);
|
|
38330
38360
|
}
|
|
38331
38361
|
while (keyIndex2 !== -1) {
|
|
38332
|
-
const trailingKeyCode =
|
|
38362
|
+
const trailingKeyCode = url2.charCodeAt(keyIndex2 + key.length + 1);
|
|
38333
38363
|
if (trailingKeyCode === 61) {
|
|
38334
38364
|
const valueIndex = keyIndex2 + key.length + 2;
|
|
38335
|
-
const endIndex =
|
|
38336
|
-
return _decodeURI(
|
|
38365
|
+
const endIndex = url2.indexOf("&", valueIndex);
|
|
38366
|
+
return _decodeURI(url2.slice(valueIndex, endIndex === -1 ? undefined : endIndex));
|
|
38337
38367
|
} else if (trailingKeyCode == 38 || isNaN(trailingKeyCode)) {
|
|
38338
38368
|
return "";
|
|
38339
38369
|
}
|
|
38340
|
-
keyIndex2 =
|
|
38370
|
+
keyIndex2 = url2.indexOf(`&${key}`, keyIndex2 + 1);
|
|
38341
38371
|
}
|
|
38342
|
-
encoded = /[%+]/.test(
|
|
38372
|
+
encoded = /[%+]/.test(url2);
|
|
38343
38373
|
if (!encoded) {
|
|
38344
38374
|
return;
|
|
38345
38375
|
}
|
|
38346
38376
|
}
|
|
38347
38377
|
const results = {};
|
|
38348
|
-
encoded ??= /[%+]/.test(
|
|
38349
|
-
let keyIndex =
|
|
38378
|
+
encoded ??= /[%+]/.test(url2);
|
|
38379
|
+
let keyIndex = url2.indexOf("?", 8);
|
|
38350
38380
|
while (keyIndex !== -1) {
|
|
38351
|
-
const nextKeyIndex =
|
|
38352
|
-
let valueIndex =
|
|
38381
|
+
const nextKeyIndex = url2.indexOf("&", keyIndex + 1);
|
|
38382
|
+
let valueIndex = url2.indexOf("=", keyIndex);
|
|
38353
38383
|
if (valueIndex > nextKeyIndex && nextKeyIndex !== -1) {
|
|
38354
38384
|
valueIndex = -1;
|
|
38355
38385
|
}
|
|
38356
|
-
let name3 =
|
|
38386
|
+
let name3 = url2.slice(keyIndex + 1, valueIndex === -1 ? nextKeyIndex === -1 ? undefined : nextKeyIndex : valueIndex);
|
|
38357
38387
|
if (encoded) {
|
|
38358
38388
|
name3 = _decodeURI(name3);
|
|
38359
38389
|
}
|
|
@@ -38365,7 +38395,7 @@ var splitPath = (path) => {
|
|
|
38365
38395
|
if (valueIndex === -1) {
|
|
38366
38396
|
value = "";
|
|
38367
38397
|
} else {
|
|
38368
|
-
value =
|
|
38398
|
+
value = url2.slice(valueIndex + 1, nextKeyIndex === -1 ? undefined : nextKeyIndex);
|
|
38369
38399
|
if (encoded) {
|
|
38370
38400
|
value = _decodeURI(value);
|
|
38371
38401
|
}
|
|
@@ -38380,8 +38410,8 @@ var splitPath = (path) => {
|
|
|
38380
38410
|
}
|
|
38381
38411
|
}
|
|
38382
38412
|
return key ? results[key] : results;
|
|
38383
|
-
}, getQueryParam, getQueryParams = (
|
|
38384
|
-
return _getQueryParam(
|
|
38413
|
+
}, getQueryParam, getQueryParams = (url2, key) => {
|
|
38414
|
+
return _getQueryParam(url2, key, true);
|
|
38385
38415
|
}, decodeURIComponent_;
|
|
38386
38416
|
var init_url = __esm(() => {
|
|
38387
38417
|
patternCache = {};
|
|
@@ -38860,9 +38890,9 @@ var notFoundHandler = (c) => {
|
|
|
38860
38890
|
const mergedPath = mergePath(this._basePath, path);
|
|
38861
38891
|
const pathPrefixLength = mergedPath === "/" ? 0 : mergedPath.length;
|
|
38862
38892
|
return (request2) => {
|
|
38863
|
-
const
|
|
38864
|
-
|
|
38865
|
-
return new Request(
|
|
38893
|
+
const url2 = new URL(request2.url);
|
|
38894
|
+
url2.pathname = url2.pathname.slice(pathPrefixLength) || "/";
|
|
38895
|
+
return new Request(url2, request2);
|
|
38866
38896
|
};
|
|
38867
38897
|
})();
|
|
38868
38898
|
const handler = async (c, next) => {
|
|
@@ -39800,8 +39830,8 @@ var humanize = (times) => {
|
|
|
39800
39830
|
return `${status}`;
|
|
39801
39831
|
}, logger35 = (fn = console.log) => {
|
|
39802
39832
|
return async function logger2(c, next) {
|
|
39803
|
-
const { method, url } = c.req;
|
|
39804
|
-
const path =
|
|
39833
|
+
const { method, url: url2 } = c.req;
|
|
39834
|
+
const path = url2.slice(url2.indexOf("/", 8));
|
|
39805
39835
|
await log4(fn, "<--", method, path);
|
|
39806
39836
|
const start2 = Date.now();
|
|
39807
39837
|
await next();
|
|
@@ -47559,34 +47589,34 @@ var require_node3 = __commonJS((exports) => {
|
|
|
47559
47589
|
}
|
|
47560
47590
|
exports2.urlParse = urlParse;
|
|
47561
47591
|
function urlGenerate(aParsedUrl) {
|
|
47562
|
-
var
|
|
47592
|
+
var url2 = "";
|
|
47563
47593
|
if (aParsedUrl.scheme) {
|
|
47564
|
-
|
|
47594
|
+
url2 += aParsedUrl.scheme + ":";
|
|
47565
47595
|
}
|
|
47566
|
-
|
|
47596
|
+
url2 += "//";
|
|
47567
47597
|
if (aParsedUrl.auth) {
|
|
47568
|
-
|
|
47598
|
+
url2 += aParsedUrl.auth + "@";
|
|
47569
47599
|
}
|
|
47570
47600
|
if (aParsedUrl.host) {
|
|
47571
|
-
|
|
47601
|
+
url2 += aParsedUrl.host;
|
|
47572
47602
|
}
|
|
47573
47603
|
if (aParsedUrl.port) {
|
|
47574
|
-
|
|
47604
|
+
url2 += ":" + aParsedUrl.port;
|
|
47575
47605
|
}
|
|
47576
47606
|
if (aParsedUrl.path) {
|
|
47577
|
-
|
|
47607
|
+
url2 += aParsedUrl.path;
|
|
47578
47608
|
}
|
|
47579
|
-
return
|
|
47609
|
+
return url2;
|
|
47580
47610
|
}
|
|
47581
47611
|
exports2.urlGenerate = urlGenerate;
|
|
47582
47612
|
function normalize(aPath) {
|
|
47583
47613
|
var path = aPath;
|
|
47584
|
-
var
|
|
47585
|
-
if (
|
|
47586
|
-
if (!
|
|
47614
|
+
var url2 = urlParse(aPath);
|
|
47615
|
+
if (url2) {
|
|
47616
|
+
if (!url2.path) {
|
|
47587
47617
|
return aPath;
|
|
47588
47618
|
}
|
|
47589
|
-
path =
|
|
47619
|
+
path = url2.path;
|
|
47590
47620
|
}
|
|
47591
47621
|
var isAbsolute2 = exports2.isAbsolute(path);
|
|
47592
47622
|
var parts2 = path.split(/\/+/);
|
|
@@ -47610,9 +47640,9 @@ var require_node3 = __commonJS((exports) => {
|
|
|
47610
47640
|
if (path === "") {
|
|
47611
47641
|
path = isAbsolute2 ? "/" : ".";
|
|
47612
47642
|
}
|
|
47613
|
-
if (
|
|
47614
|
-
|
|
47615
|
-
return urlGenerate(
|
|
47643
|
+
if (url2) {
|
|
47644
|
+
url2.path = path;
|
|
47645
|
+
return urlGenerate(url2);
|
|
47616
47646
|
}
|
|
47617
47647
|
return path;
|
|
47618
47648
|
}
|
|
@@ -48638,13 +48668,13 @@ var require_node3 = __commonJS((exports) => {
|
|
|
48638
48668
|
if (this.sourceRoot != null) {
|
|
48639
48669
|
relativeSource = util3.relative(this.sourceRoot, relativeSource);
|
|
48640
48670
|
}
|
|
48641
|
-
var
|
|
48642
|
-
if (this.sourceRoot != null && (
|
|
48671
|
+
var url2;
|
|
48672
|
+
if (this.sourceRoot != null && (url2 = util3.urlParse(this.sourceRoot))) {
|
|
48643
48673
|
var fileUriAbsPath = relativeSource.replace(/^file:\/\//, "");
|
|
48644
|
-
if (
|
|
48674
|
+
if (url2.scheme == "file" && this._sources.has(fileUriAbsPath)) {
|
|
48645
48675
|
return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)];
|
|
48646
48676
|
}
|
|
48647
|
-
if ((!
|
|
48677
|
+
if ((!url2.path || url2.path == "/") && this._sources.has("/" + relativeSource)) {
|
|
48648
48678
|
return this.sourcesContent[this._sources.indexOf("/" + relativeSource)];
|
|
48649
48679
|
}
|
|
48650
48680
|
}
|
|
@@ -49212,18 +49242,18 @@ var require_node3 = __commonJS((exports) => {
|
|
|
49212
49242
|
} catch (er2) {}
|
|
49213
49243
|
return fileContentsCache[path2] = contents;
|
|
49214
49244
|
});
|
|
49215
|
-
function supportRelativeURL(file,
|
|
49245
|
+
function supportRelativeURL(file, url2) {
|
|
49216
49246
|
if (!file)
|
|
49217
|
-
return
|
|
49247
|
+
return url2;
|
|
49218
49248
|
var dir = path.dirname(file);
|
|
49219
49249
|
var match2 = /^\w+:\/\/[^\/]*/.exec(dir);
|
|
49220
49250
|
var protocol = match2 ? match2[0] : "";
|
|
49221
49251
|
var startPath = dir.slice(protocol.length);
|
|
49222
49252
|
if (protocol && /^\/\w\:/.test(startPath)) {
|
|
49223
49253
|
protocol += "/";
|
|
49224
|
-
return protocol + path.resolve(dir.slice(protocol.length),
|
|
49254
|
+
return protocol + path.resolve(dir.slice(protocol.length), url2).replace(/\\/g, "/");
|
|
49225
49255
|
}
|
|
49226
|
-
return protocol + path.resolve(dir.slice(protocol.length),
|
|
49256
|
+
return protocol + path.resolve(dir.slice(protocol.length), url2);
|
|
49227
49257
|
}
|
|
49228
49258
|
function retrieveSourceMapURL(source) {
|
|
49229
49259
|
var fileData;
|
|
@@ -49283,8 +49313,8 @@ var require_node3 = __commonJS((exports) => {
|
|
|
49283
49313
|
sourceMap.map.sources.forEach(function(source, i3) {
|
|
49284
49314
|
var contents = sourceMap.map.sourcesContent[i3];
|
|
49285
49315
|
if (contents) {
|
|
49286
|
-
var
|
|
49287
|
-
fileContentsCache[
|
|
49316
|
+
var url2 = supportRelativeURL(sourceMap.url, source);
|
|
49317
|
+
fileContentsCache[url2] = contents;
|
|
49288
49318
|
}
|
|
49289
49319
|
});
|
|
49290
49320
|
}
|
|
@@ -94831,8 +94861,8 @@ var init_bucket_controller = __esm(() => {
|
|
|
94831
94861
|
if (!slug2) {
|
|
94832
94862
|
throw ApiError.badRequest("Missing game slug");
|
|
94833
94863
|
}
|
|
94834
|
-
const
|
|
94835
|
-
const prefix2 =
|
|
94864
|
+
const url2 = ctx.url;
|
|
94865
|
+
const prefix2 = url2.searchParams.get("prefix") || undefined;
|
|
94836
94866
|
logger40.debug("Listing files", { userId: ctx.user.id, slug: slug2, prefix: prefix2 });
|
|
94837
94867
|
const files = await ctx.services.bucket.listFiles(slug2, ctx.user, prefix2);
|
|
94838
94868
|
return { files };
|
|
@@ -95680,8 +95710,8 @@ var init_kv_controller = __esm(() => {
|
|
|
95680
95710
|
if (!slug2) {
|
|
95681
95711
|
throw ApiError.badRequest("Missing game slug");
|
|
95682
95712
|
}
|
|
95683
|
-
const
|
|
95684
|
-
const prefix2 =
|
|
95713
|
+
const url2 = ctx.url;
|
|
95714
|
+
const prefix2 = url2.searchParams.get("prefix") || undefined;
|
|
95685
95715
|
logger50.debug("Listing keys", { userId: ctx.user.id, slug: slug2, prefix: prefix2 });
|
|
95686
95716
|
const keys = await ctx.services.kv.listKeys(slug2, ctx.user, prefix2);
|
|
95687
95717
|
return { keys };
|
|
@@ -95804,17 +95834,17 @@ var init_leaderboard_controller = __esm(() => {
|
|
|
95804
95834
|
return ctx.services.leaderboard.submitScore(gameId, ctx.user.id, { score: body2.score, metadata: body2.metadata }, ctx.user.isAnonymous, ctx.params.sessionId);
|
|
95805
95835
|
});
|
|
95806
95836
|
getGlobalLeaderboard = requireAuth(async (ctx) => {
|
|
95807
|
-
const
|
|
95808
|
-
const gameId =
|
|
95837
|
+
const url2 = ctx.url;
|
|
95838
|
+
const gameId = url2.searchParams.get("gameId");
|
|
95809
95839
|
if (!gameId) {
|
|
95810
95840
|
throw ApiError.badRequest("Game ID is required");
|
|
95811
95841
|
}
|
|
95812
95842
|
let query;
|
|
95813
95843
|
try {
|
|
95814
95844
|
query = LeaderboardQuerySchema.parse({
|
|
95815
|
-
timeframe:
|
|
95816
|
-
limit: Number(
|
|
95817
|
-
offset: Number(
|
|
95845
|
+
timeframe: url2.searchParams.get("timeframe") || "all_time",
|
|
95846
|
+
limit: Number(url2.searchParams.get("limit") || "10"),
|
|
95847
|
+
offset: Number(url2.searchParams.get("offset") || "0")
|
|
95818
95848
|
});
|
|
95819
95849
|
} catch (error2) {
|
|
95820
95850
|
if (error2 instanceof exports_external.ZodError) {
|
|
@@ -95836,13 +95866,13 @@ var init_leaderboard_controller = __esm(() => {
|
|
|
95836
95866
|
if (!gameId) {
|
|
95837
95867
|
throw ApiError.badRequest("Game ID is required");
|
|
95838
95868
|
}
|
|
95839
|
-
const
|
|
95869
|
+
const url2 = ctx.url;
|
|
95840
95870
|
let query;
|
|
95841
95871
|
try {
|
|
95842
95872
|
query = LeaderboardQuerySchema.parse({
|
|
95843
|
-
timeframe:
|
|
95844
|
-
limit: Number(
|
|
95845
|
-
offset: Number(
|
|
95873
|
+
timeframe: url2.searchParams.get("timeframe") || "all_time",
|
|
95874
|
+
limit: Number(url2.searchParams.get("limit") || "10"),
|
|
95875
|
+
offset: Number(url2.searchParams.get("offset") || "0")
|
|
95846
95876
|
});
|
|
95847
95877
|
} catch (error2) {
|
|
95848
95878
|
if (error2 instanceof exports_external.ZodError) {
|
|
@@ -95876,9 +95906,9 @@ var init_leaderboard_controller = __esm(() => {
|
|
|
95876
95906
|
if (!userId) {
|
|
95877
95907
|
throw ApiError.badRequest("User ID is required");
|
|
95878
95908
|
}
|
|
95879
|
-
const
|
|
95880
|
-
const limit = Math.min(Number(
|
|
95881
|
-
const gameId =
|
|
95909
|
+
const url2 = ctx.url;
|
|
95910
|
+
const limit = Math.min(Number(url2.searchParams.get("limit") || "50"), 100);
|
|
95911
|
+
const gameId = url2.searchParams.get("gameId") || undefined;
|
|
95882
95912
|
logger51.debug("Getting user all scores", {
|
|
95883
95913
|
requesterId: ctx.user.id,
|
|
95884
95914
|
targetUserId: userId,
|
|
@@ -95892,8 +95922,8 @@ var init_leaderboard_controller = __esm(() => {
|
|
|
95892
95922
|
if (!gameId || !userId) {
|
|
95893
95923
|
throw ApiError.badRequest("Game ID and User ID are required");
|
|
95894
95924
|
}
|
|
95895
|
-
const
|
|
95896
|
-
const limit = Math.min(Number(
|
|
95925
|
+
const url2 = ctx.url;
|
|
95926
|
+
const limit = Math.min(Number(url2.searchParams.get("limit") || "10"), 100);
|
|
95897
95927
|
logger51.debug("Getting user scores", {
|
|
95898
95928
|
requesterId: ctx.user.id,
|
|
95899
95929
|
gameId,
|
|
@@ -98193,10 +98223,10 @@ var init_timeback6 = __esm(() => {
|
|
|
98193
98223
|
return c2.json(createErrorResponse(error2), error2.status);
|
|
98194
98224
|
}
|
|
98195
98225
|
if (shouldMockTimeback()) {
|
|
98196
|
-
const
|
|
98197
|
-
const gradeParam =
|
|
98198
|
-
const subjectParam =
|
|
98199
|
-
const includeParam =
|
|
98226
|
+
const url2 = new URL(c2.req.url);
|
|
98227
|
+
const gradeParam = url2.searchParams.get("grade");
|
|
98228
|
+
const subjectParam = url2.searchParams.get("subject");
|
|
98229
|
+
const includeParam = url2.searchParams.get("include") || "";
|
|
98200
98230
|
const includeOptions = includeParam.split(",").map((opt) => opt.trim().toLowerCase());
|
|
98201
98231
|
const includePerCourse = includeOptions.includes("percourse");
|
|
98202
98232
|
const includeToday = includeOptions.includes("today");
|
package/dist/server.js
CHANGED
|
@@ -1329,7 +1329,7 @@ var package_default;
|
|
|
1329
1329
|
var init_package = __esm(() => {
|
|
1330
1330
|
package_default = {
|
|
1331
1331
|
name: "@playcademy/sandbox",
|
|
1332
|
-
version: "0.3.17-beta.
|
|
1332
|
+
version: "0.3.17-beta.26",
|
|
1333
1333
|
description: "Local development server for Playcademy game development",
|
|
1334
1334
|
type: "module",
|
|
1335
1335
|
exports: {
|
|
@@ -30267,8 +30267,17 @@ function kebabToTitleCase(kebabStr) {
|
|
|
30267
30267
|
return kebabStr.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
30268
30268
|
}
|
|
30269
30269
|
// ../utils/src/timezone.ts
|
|
30270
|
-
function
|
|
30271
|
-
|
|
30270
|
+
function formatDateYMDInTimezone(timeZone, date3 = new Date) {
|
|
30271
|
+
const parts2 = new Intl.DateTimeFormat("en-US", {
|
|
30272
|
+
timeZone,
|
|
30273
|
+
year: "numeric",
|
|
30274
|
+
month: "2-digit",
|
|
30275
|
+
day: "2-digit"
|
|
30276
|
+
}).formatToParts(date3);
|
|
30277
|
+
const y = parts2.find((p) => p.type === "year").value;
|
|
30278
|
+
const m = parts2.find((p) => p.type === "month").value;
|
|
30279
|
+
const d = parts2.find((p) => p.type === "day").value;
|
|
30280
|
+
return `${y}-${m}-${d}`;
|
|
30272
30281
|
}
|
|
30273
30282
|
function getUtcInstantForMidnight(date3, timeZone) {
|
|
30274
30283
|
const parts2 = new Intl.DateTimeFormat("en-US", {
|
|
@@ -30339,6 +30348,19 @@ function getDayBoundariesInTimezone(date3, timezone) {
|
|
|
30339
30348
|
const endOfDay = getUtcInstantForMidnight(nextDayNoon, timezone);
|
|
30340
30349
|
return { startOfDay, endOfDay };
|
|
30341
30350
|
}
|
|
30351
|
+
// ../utils/src/url.ts
|
|
30352
|
+
function buildPath(path, params) {
|
|
30353
|
+
const url = new URL(path, "http://n");
|
|
30354
|
+
if (params) {
|
|
30355
|
+
for (const [key, value] of Object.entries(params)) {
|
|
30356
|
+
if (value != null) {
|
|
30357
|
+
url.searchParams.set(key, value);
|
|
30358
|
+
}
|
|
30359
|
+
}
|
|
30360
|
+
}
|
|
30361
|
+
return `${url.pathname}${url.search}`;
|
|
30362
|
+
}
|
|
30363
|
+
|
|
30342
30364
|
// ../utils/src/pure/index.ts
|
|
30343
30365
|
var init_pure = __esm(() => {
|
|
30344
30366
|
init_uuid2();
|
|
@@ -30391,11 +30413,11 @@ function isRecord2(value) {
|
|
|
30391
30413
|
function getStringValue(value) {
|
|
30392
30414
|
return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
|
|
30393
30415
|
}
|
|
30394
|
-
function parseSourcedIdFromUrl(
|
|
30395
|
-
if (!
|
|
30416
|
+
function parseSourcedIdFromUrl(url2) {
|
|
30417
|
+
if (!url2) {
|
|
30396
30418
|
return;
|
|
30397
30419
|
}
|
|
30398
|
-
const trimmed =
|
|
30420
|
+
const trimmed = url2.trim().replace(/\/$/, "");
|
|
30399
30421
|
if (!trimmed) {
|
|
30400
30422
|
return;
|
|
30401
30423
|
}
|
|
@@ -30784,7 +30806,7 @@ class TimebackAdminService {
|
|
|
30784
30806
|
history: []
|
|
30785
30807
|
};
|
|
30786
30808
|
}
|
|
30787
|
-
const today =
|
|
30809
|
+
const today = formatDateYMDInTimezone(PLATFORM_TIMEZONE);
|
|
30788
30810
|
const history = [];
|
|
30789
30811
|
let totalXpRaw = 0;
|
|
30790
30812
|
let todayXpRaw = 0;
|
|
@@ -30950,7 +30972,9 @@ class TimebackAdminService {
|
|
|
30950
30972
|
const uniqueEnrollmentIds = [...new Set(enrollmentIds)];
|
|
30951
30973
|
const results = await TimebackAdminService.runWithConcurrency(uniqueEnrollmentIds, TimebackAdminService.ANALYTICS_CONCURRENCY, async (enrollmentId) => {
|
|
30952
30974
|
try {
|
|
30953
|
-
const analytics = await client.edubridge.analytics.getEnrollmentFacts(enrollmentId
|
|
30975
|
+
const analytics = await client.edubridge.analytics.getEnrollmentFacts(enrollmentId, {
|
|
30976
|
+
timezone: PLATFORM_TIMEZONE
|
|
30977
|
+
});
|
|
30954
30978
|
return [enrollmentId, this.summarizeAnalyticsFacts(analytics.facts)];
|
|
30955
30979
|
} catch (error) {
|
|
30956
30980
|
logger16.warn("Failed to load enrollment analytics summary", {
|
|
@@ -31224,7 +31248,7 @@ class TimebackAdminService {
|
|
|
31224
31248
|
const enrollment = await this.assertStudentEnrolledInCourse(client, data.studentId, data.courseId);
|
|
31225
31249
|
let currentMastered = 0;
|
|
31226
31250
|
try {
|
|
31227
|
-
const analytics = await client.edubridge.analytics.getEnrollmentFacts(enrollment.id);
|
|
31251
|
+
const analytics = await client.edubridge.analytics.getEnrollmentFacts(enrollment.id, { timezone: PLATFORM_TIMEZONE });
|
|
31228
31252
|
const summary = this.summarizeAnalyticsFacts(analytics.facts);
|
|
31229
31253
|
currentMastered = summary.masteredUnits;
|
|
31230
31254
|
} catch {
|
|
@@ -31414,6 +31438,7 @@ class TimebackAdminService {
|
|
|
31414
31438
|
var logger16;
|
|
31415
31439
|
var init_timeback_admin_service = __esm(() => {
|
|
31416
31440
|
init_drizzle_orm();
|
|
31441
|
+
init_src();
|
|
31417
31442
|
init_tables_index();
|
|
31418
31443
|
init_src2();
|
|
31419
31444
|
init_constants4();
|
|
@@ -33371,13 +33396,13 @@ var init_events = () => {};
|
|
|
33371
33396
|
|
|
33372
33397
|
// ../api-core/src/services/notification.service.ts
|
|
33373
33398
|
function convertWebSocketUrlToHttp(wsUrl) {
|
|
33374
|
-
return wsUrl.replace(/^wss?:\/\//, (
|
|
33399
|
+
return wsUrl.replace(/^wss?:\/\//, (url2) => url2 === "wss://" ? "https://" : "http://");
|
|
33375
33400
|
}
|
|
33376
33401
|
async function publishToUser(baseUrl, secret, userId, type, payload) {
|
|
33377
|
-
const
|
|
33378
|
-
|
|
33402
|
+
const url2 = new URL(baseUrl);
|
|
33403
|
+
url2.pathname = "/publish";
|
|
33379
33404
|
try {
|
|
33380
|
-
const res = await fetch(
|
|
33405
|
+
const res = await fetch(url2.toString(), {
|
|
33381
33406
|
method: "POST",
|
|
33382
33407
|
headers: { "content-type": "application/json" },
|
|
33383
33408
|
body: JSON.stringify({ userId, type, payload, secret })
|
|
@@ -35229,14 +35254,14 @@ function debugSensitive(label, value, showChars = 4) {
|
|
|
35229
35254
|
const masked = value.length > showChars * 2 ? `${value.slice(0, showChars)}...${value.slice(-showChars)}` : `${value.slice(0, showChars)}...`;
|
|
35230
35255
|
console.log(`[DEBUG] ${label}: ${masked}`);
|
|
35231
35256
|
}
|
|
35232
|
-
function debugRequest(method,
|
|
35257
|
+
function debugRequest(method, url2, headers, body2) {
|
|
35233
35258
|
if (!isDebugEnabled()) {
|
|
35234
35259
|
return;
|
|
35235
35260
|
}
|
|
35236
35261
|
console.log(`
|
|
35237
35262
|
[DEBUG] HTTP Request:`);
|
|
35238
35263
|
console.log(` Method: ${method}`);
|
|
35239
|
-
console.log(` URL: ${
|
|
35264
|
+
console.log(` URL: ${url2}`);
|
|
35240
35265
|
if (headers) {
|
|
35241
35266
|
console.log(` Headers:`);
|
|
35242
35267
|
Object.entries(headers).forEach(([key, value]) => {
|
|
@@ -35309,7 +35334,7 @@ async function getTimebackTokenResponse(config2) {
|
|
|
35309
35334
|
function getAuthUrl(environment = "production") {
|
|
35310
35335
|
return TIMEBACK_AUTH_URLS4[environment];
|
|
35311
35336
|
}
|
|
35312
|
-
function handleHttpError(res, errorBody, attempt, retries,
|
|
35337
|
+
function handleHttpError(res, errorBody, attempt, retries, url2) {
|
|
35313
35338
|
const error = new TimebackApiError(res.status, res.statusText, errorBody);
|
|
35314
35339
|
if (res.status >= HTTP_STATUS4.CLIENT_ERROR_MIN && res.status < HTTP_STATUS4.CLIENT_ERROR_MAX) {
|
|
35315
35340
|
throw error;
|
|
@@ -35320,7 +35345,7 @@ function handleHttpError(res, errorBody, attempt, retries, url) {
|
|
|
35320
35345
|
attempt: attempt + 1,
|
|
35321
35346
|
maxRetries: retries,
|
|
35322
35347
|
status: res.status,
|
|
35323
|
-
url
|
|
35348
|
+
url: url2
|
|
35324
35349
|
});
|
|
35325
35350
|
return { retry: true, error };
|
|
35326
35351
|
}
|
|
@@ -35351,7 +35376,7 @@ async function request({
|
|
|
35351
35376
|
retries = 3,
|
|
35352
35377
|
timeout = 1e4
|
|
35353
35378
|
}) {
|
|
35354
|
-
const
|
|
35379
|
+
const url2 = baseUrl.replace(/\/$/, "") + (path.startsWith("/") ? path : `/${path}`);
|
|
35355
35380
|
const headers = { ...extraHeaders };
|
|
35356
35381
|
let payload;
|
|
35357
35382
|
if (body2 instanceof FormData) {
|
|
@@ -35368,8 +35393,8 @@ async function request({
|
|
|
35368
35393
|
try {
|
|
35369
35394
|
const controller = new AbortController;
|
|
35370
35395
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
35371
|
-
debugRequest(method,
|
|
35372
|
-
const res = await fetch(
|
|
35396
|
+
debugRequest(method, url2, headers, body2);
|
|
35397
|
+
const res = await fetch(url2, {
|
|
35373
35398
|
method,
|
|
35374
35399
|
headers,
|
|
35375
35400
|
body: payload,
|
|
@@ -35385,7 +35410,7 @@ async function request({
|
|
|
35385
35410
|
if (errorBody) {
|
|
35386
35411
|
debugResponse(res.status, res.statusText, errorBody);
|
|
35387
35412
|
}
|
|
35388
|
-
const result = handleHttpError(res, errorBody, attempt, retries,
|
|
35413
|
+
const result = handleHttpError(res, errorBody, attempt, retries, url2);
|
|
35389
35414
|
lastError = result.error;
|
|
35390
35415
|
if (result.retry) {
|
|
35391
35416
|
const delay = HTTP_DEFAULTS4.retryBackoffBase ** attempt * 1000;
|
|
@@ -35405,7 +35430,7 @@ async function request({
|
|
|
35405
35430
|
attempt: attempt + 1,
|
|
35406
35431
|
maxRetries: retries,
|
|
35407
35432
|
error: lastError.message,
|
|
35408
|
-
url
|
|
35433
|
+
url: url2
|
|
35409
35434
|
});
|
|
35410
35435
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
35411
35436
|
}
|
|
@@ -35644,7 +35669,9 @@ function createEduBridgeNamespace(client) {
|
|
|
35644
35669
|
}
|
|
35645
35670
|
};
|
|
35646
35671
|
const analytics = {
|
|
35647
|
-
getEnrollmentFacts: async (enrollmentId) => client["request"](`/edubridge/analytics/enrollment/${enrollmentId}`,
|
|
35672
|
+
getEnrollmentFacts: async (enrollmentId, options) => client["request"](buildPath(`/edubridge/analytics/enrollment/${enrollmentId}`, {
|
|
35673
|
+
timezone: options?.timezone
|
|
35674
|
+
}), "GET")
|
|
35648
35675
|
};
|
|
35649
35676
|
return {
|
|
35650
35677
|
enrollments,
|
|
@@ -35735,8 +35762,8 @@ function createOneRosterNamespace(client) {
|
|
|
35735
35762
|
queryParams.set("offset", String(options.offset));
|
|
35736
35763
|
}
|
|
35737
35764
|
const endpoint = `${ONEROSTER_ENDPOINTS4.users}/${userSourcedId}/classes`;
|
|
35738
|
-
const
|
|
35739
|
-
const res = await client["request"](
|
|
35765
|
+
const url2 = queryParams.toString() ? `${endpoint}?${queryParams}` : endpoint;
|
|
35766
|
+
const res = await client["request"](url2, "GET");
|
|
35740
35767
|
return res.classes || [];
|
|
35741
35768
|
}
|
|
35742
35769
|
},
|
|
@@ -35754,9 +35781,9 @@ function createOneRosterNamespace(client) {
|
|
|
35754
35781
|
if (options?.offset) {
|
|
35755
35782
|
queryParams.set("offset", String(options.offset));
|
|
35756
35783
|
}
|
|
35757
|
-
const
|
|
35784
|
+
const url2 = `${ONEROSTER_ENDPOINTS4.enrollments}?${queryParams}`;
|
|
35758
35785
|
try {
|
|
35759
|
-
const response = await client["request"](
|
|
35786
|
+
const response = await client["request"](url2, "GET");
|
|
35760
35787
|
return response.enrollments || [];
|
|
35761
35788
|
} catch (error) {
|
|
35762
35789
|
logTimebackError("list enrollments for class", error, { classSourcedId });
|
|
@@ -35787,8 +35814,8 @@ function createOneRosterNamespace(client) {
|
|
|
35787
35814
|
}
|
|
35788
35815
|
queryParams.set("filter", filters.join(" AND "));
|
|
35789
35816
|
queryParams.set("limit", "3000");
|
|
35790
|
-
const
|
|
35791
|
-
const response = await client["request"](
|
|
35817
|
+
const url2 = `${ONEROSTER_ENDPOINTS4.enrollments}?${queryParams}`;
|
|
35818
|
+
const response = await client["request"](url2, "GET");
|
|
35792
35819
|
return response.enrollments || [];
|
|
35793
35820
|
}));
|
|
35794
35821
|
const enrollments = enrollmentGroups.flat();
|
|
@@ -35953,8 +35980,8 @@ function createOneRosterNamespace(client) {
|
|
|
35953
35980
|
getAttemptStats: async (studentId, lineItemId) => {
|
|
35954
35981
|
try {
|
|
35955
35982
|
const filter = `student.sourcedId='${studentId}' AND assessmentLineItem.sourcedId='${lineItemId}'`;
|
|
35956
|
-
const
|
|
35957
|
-
const response = await client["request"](
|
|
35983
|
+
const url2 = `${ONEROSTER_ENDPOINTS4.assessmentResults}?filter=${encodeURIComponent(filter)}`;
|
|
35984
|
+
const response = await client["request"](url2, "GET");
|
|
35958
35985
|
const results = response.assessmentResults || [];
|
|
35959
35986
|
const firstResult = results[0];
|
|
35960
35987
|
if (!firstResult) {
|
|
@@ -36560,7 +36587,7 @@ class MasteryTracker {
|
|
|
36560
36587
|
});
|
|
36561
36588
|
return;
|
|
36562
36589
|
}
|
|
36563
|
-
const analytics = await this.edubridgeNamespace.analytics.getEnrollmentFacts(enrollment.id);
|
|
36590
|
+
const analytics = await this.edubridgeNamespace.analytics.getEnrollmentFacts(enrollment.id, { timezone: PLATFORM_TIMEZONE });
|
|
36564
36591
|
return analytics.facts;
|
|
36565
36592
|
} catch (error) {
|
|
36566
36593
|
log.error("[MasteryTracker] Failed to load enrollment analytics facts", {
|
|
@@ -37283,7 +37310,7 @@ class TimebackClient {
|
|
|
37283
37310
|
}
|
|
37284
37311
|
const analyticsResults = await Promise.all(filteredEnrollments.map(async (enrollment) => {
|
|
37285
37312
|
try {
|
|
37286
|
-
const analytics = await this.edubridge.analytics.getEnrollmentFacts(enrollment.id);
|
|
37313
|
+
const analytics = await this.edubridge.analytics.getEnrollmentFacts(enrollment.id, { timezone: PLATFORM_TIMEZONE });
|
|
37287
37314
|
return { enrollment, analytics };
|
|
37288
37315
|
} catch (error) {
|
|
37289
37316
|
log.warn("[TimebackClient] Failed to fetch analytics for enrollment", {
|
|
@@ -37293,7 +37320,7 @@ class TimebackClient {
|
|
|
37293
37320
|
return { enrollment, analytics: null };
|
|
37294
37321
|
}
|
|
37295
37322
|
}));
|
|
37296
|
-
const today =
|
|
37323
|
+
const today = formatDateYMDInTimezone(PLATFORM_TIMEZONE);
|
|
37297
37324
|
let totalXp = 0;
|
|
37298
37325
|
let todayXp = 0;
|
|
37299
37326
|
const courses = [];
|
|
@@ -37392,6 +37419,7 @@ var __defProp2, __export2 = (target, all) => {
|
|
|
37392
37419
|
});
|
|
37393
37420
|
}, __esm5 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), TIMEBACK_API_URLS4, TIMEBACK_AUTH_URLS4, CALIPER_API_URLS4, ONEROSTER_ENDPOINTS4, CALIPER_ENDPOINTS4, CALIPER_CONSTANTS4, TIMEBACK_EVENT_TYPES4, TIMEBACK_ACTIONS4, TIMEBACK_TYPES4, ACTIVITY_METRIC_TYPES4, TIME_METRIC_TYPES4, TIMEBACK_SUBJECTS4, TIMEBACK_GRADE_LEVELS4, TIMEBACK_GRADE_LEVEL_LABELS4, CALIPER_SUBJECTS4, ONEROSTER_STATUS4, SCORE_STATUS4, ENV_VARS4, HTTP_DEFAULTS4, AUTH_DEFAULTS4, CACHE_DEFAULTS4, CONFIG_DEFAULTS4, PLAYCADEMY_DEFAULTS4, RESOURCE_DEFAULTS4, HTTP_STATUS4, ERROR_NAMES4, init_constants8, exports_verify, init_verify, TimebackError, TimebackApiError, TimebackAuthenticationError, StudentNotFoundError, ConfigurationError, ResourceNotFoundError, SUBJECT_VALUES2, GRADE_VALUES2, TimebackAuthError, PERFECT_ACCURACY_THRESHOLD = 0.999999, EmailSchema, StudentSourcedIdSchema, StudentIdentifierSchema;
|
|
37394
37421
|
var init_dist3 = __esm(() => {
|
|
37422
|
+
init_src();
|
|
37395
37423
|
init_src();
|
|
37396
37424
|
init_src2();
|
|
37397
37425
|
init_src4();
|
|
@@ -37406,9 +37434,11 @@ var init_dist3 = __esm(() => {
|
|
|
37406
37434
|
init_src2();
|
|
37407
37435
|
init_src2();
|
|
37408
37436
|
init_src2();
|
|
37437
|
+
init_src4();
|
|
37409
37438
|
init_src2();
|
|
37410
37439
|
init_src2();
|
|
37411
37440
|
init_src2();
|
|
37441
|
+
init_src();
|
|
37412
37442
|
init_src2();
|
|
37413
37443
|
init_src2();
|
|
37414
37444
|
init_src2();
|
|
@@ -38261,20 +38291,20 @@ var splitPath = (path) => {
|
|
|
38261
38291
|
});
|
|
38262
38292
|
}
|
|
38263
38293
|
}, tryDecodeURI = (str) => tryDecode(str, decodeURI), getPath = (request2) => {
|
|
38264
|
-
const
|
|
38265
|
-
const start2 =
|
|
38294
|
+
const url2 = request2.url;
|
|
38295
|
+
const start2 = url2.indexOf("/", url2.indexOf(":") + 4);
|
|
38266
38296
|
let i2 = start2;
|
|
38267
|
-
for (;i2 <
|
|
38268
|
-
const charCode =
|
|
38297
|
+
for (;i2 < url2.length; i2++) {
|
|
38298
|
+
const charCode = url2.charCodeAt(i2);
|
|
38269
38299
|
if (charCode === 37) {
|
|
38270
|
-
const queryIndex =
|
|
38271
|
-
const path =
|
|
38300
|
+
const queryIndex = url2.indexOf("?", i2);
|
|
38301
|
+
const path = url2.slice(start2, queryIndex === -1 ? undefined : queryIndex);
|
|
38272
38302
|
return tryDecodeURI(path.includes("%25") ? path.replace(/%25/g, "%2525") : path);
|
|
38273
38303
|
} else if (charCode === 63) {
|
|
38274
38304
|
break;
|
|
38275
38305
|
}
|
|
38276
38306
|
}
|
|
38277
|
-
return
|
|
38307
|
+
return url2.slice(start2, i2);
|
|
38278
38308
|
}, getPathNoStrict = (request2) => {
|
|
38279
38309
|
const result = getPath(request2);
|
|
38280
38310
|
return result.length > 1 && result.at(-1) === "/" ? result.slice(0, -1) : result;
|
|
@@ -38317,42 +38347,42 @@ var splitPath = (path) => {
|
|
|
38317
38347
|
value = value.replace(/\+/g, " ");
|
|
38318
38348
|
}
|
|
38319
38349
|
return value.indexOf("%") !== -1 ? tryDecode(value, decodeURIComponent_) : value;
|
|
38320
|
-
}, _getQueryParam = (
|
|
38350
|
+
}, _getQueryParam = (url2, key, multiple) => {
|
|
38321
38351
|
let encoded;
|
|
38322
38352
|
if (!multiple && key && !/[%+]/.test(key)) {
|
|
38323
|
-
let keyIndex2 =
|
|
38353
|
+
let keyIndex2 = url2.indexOf("?", 8);
|
|
38324
38354
|
if (keyIndex2 === -1) {
|
|
38325
38355
|
return;
|
|
38326
38356
|
}
|
|
38327
|
-
if (!
|
|
38328
|
-
keyIndex2 =
|
|
38357
|
+
if (!url2.startsWith(key, keyIndex2 + 1)) {
|
|
38358
|
+
keyIndex2 = url2.indexOf(`&${key}`, keyIndex2 + 1);
|
|
38329
38359
|
}
|
|
38330
38360
|
while (keyIndex2 !== -1) {
|
|
38331
|
-
const trailingKeyCode =
|
|
38361
|
+
const trailingKeyCode = url2.charCodeAt(keyIndex2 + key.length + 1);
|
|
38332
38362
|
if (trailingKeyCode === 61) {
|
|
38333
38363
|
const valueIndex = keyIndex2 + key.length + 2;
|
|
38334
|
-
const endIndex =
|
|
38335
|
-
return _decodeURI(
|
|
38364
|
+
const endIndex = url2.indexOf("&", valueIndex);
|
|
38365
|
+
return _decodeURI(url2.slice(valueIndex, endIndex === -1 ? undefined : endIndex));
|
|
38336
38366
|
} else if (trailingKeyCode == 38 || isNaN(trailingKeyCode)) {
|
|
38337
38367
|
return "";
|
|
38338
38368
|
}
|
|
38339
|
-
keyIndex2 =
|
|
38369
|
+
keyIndex2 = url2.indexOf(`&${key}`, keyIndex2 + 1);
|
|
38340
38370
|
}
|
|
38341
|
-
encoded = /[%+]/.test(
|
|
38371
|
+
encoded = /[%+]/.test(url2);
|
|
38342
38372
|
if (!encoded) {
|
|
38343
38373
|
return;
|
|
38344
38374
|
}
|
|
38345
38375
|
}
|
|
38346
38376
|
const results = {};
|
|
38347
|
-
encoded ??= /[%+]/.test(
|
|
38348
|
-
let keyIndex =
|
|
38377
|
+
encoded ??= /[%+]/.test(url2);
|
|
38378
|
+
let keyIndex = url2.indexOf("?", 8);
|
|
38349
38379
|
while (keyIndex !== -1) {
|
|
38350
|
-
const nextKeyIndex =
|
|
38351
|
-
let valueIndex =
|
|
38380
|
+
const nextKeyIndex = url2.indexOf("&", keyIndex + 1);
|
|
38381
|
+
let valueIndex = url2.indexOf("=", keyIndex);
|
|
38352
38382
|
if (valueIndex > nextKeyIndex && nextKeyIndex !== -1) {
|
|
38353
38383
|
valueIndex = -1;
|
|
38354
38384
|
}
|
|
38355
|
-
let name3 =
|
|
38385
|
+
let name3 = url2.slice(keyIndex + 1, valueIndex === -1 ? nextKeyIndex === -1 ? undefined : nextKeyIndex : valueIndex);
|
|
38356
38386
|
if (encoded) {
|
|
38357
38387
|
name3 = _decodeURI(name3);
|
|
38358
38388
|
}
|
|
@@ -38364,7 +38394,7 @@ var splitPath = (path) => {
|
|
|
38364
38394
|
if (valueIndex === -1) {
|
|
38365
38395
|
value = "";
|
|
38366
38396
|
} else {
|
|
38367
|
-
value =
|
|
38397
|
+
value = url2.slice(valueIndex + 1, nextKeyIndex === -1 ? undefined : nextKeyIndex);
|
|
38368
38398
|
if (encoded) {
|
|
38369
38399
|
value = _decodeURI(value);
|
|
38370
38400
|
}
|
|
@@ -38379,8 +38409,8 @@ var splitPath = (path) => {
|
|
|
38379
38409
|
}
|
|
38380
38410
|
}
|
|
38381
38411
|
return key ? results[key] : results;
|
|
38382
|
-
}, getQueryParam, getQueryParams = (
|
|
38383
|
-
return _getQueryParam(
|
|
38412
|
+
}, getQueryParam, getQueryParams = (url2, key) => {
|
|
38413
|
+
return _getQueryParam(url2, key, true);
|
|
38384
38414
|
}, decodeURIComponent_;
|
|
38385
38415
|
var init_url = __esm(() => {
|
|
38386
38416
|
patternCache = {};
|
|
@@ -38859,9 +38889,9 @@ var notFoundHandler = (c) => {
|
|
|
38859
38889
|
const mergedPath = mergePath(this._basePath, path);
|
|
38860
38890
|
const pathPrefixLength = mergedPath === "/" ? 0 : mergedPath.length;
|
|
38861
38891
|
return (request2) => {
|
|
38862
|
-
const
|
|
38863
|
-
|
|
38864
|
-
return new Request(
|
|
38892
|
+
const url2 = new URL(request2.url);
|
|
38893
|
+
url2.pathname = url2.pathname.slice(pathPrefixLength) || "/";
|
|
38894
|
+
return new Request(url2, request2);
|
|
38865
38895
|
};
|
|
38866
38896
|
})();
|
|
38867
38897
|
const handler = async (c, next) => {
|
|
@@ -39799,8 +39829,8 @@ var humanize = (times) => {
|
|
|
39799
39829
|
return `${status}`;
|
|
39800
39830
|
}, logger35 = (fn = console.log) => {
|
|
39801
39831
|
return async function logger2(c, next) {
|
|
39802
|
-
const { method, url } = c.req;
|
|
39803
|
-
const path =
|
|
39832
|
+
const { method, url: url2 } = c.req;
|
|
39833
|
+
const path = url2.slice(url2.indexOf("/", 8));
|
|
39804
39834
|
await log4(fn, "<--", method, path);
|
|
39805
39835
|
const start2 = Date.now();
|
|
39806
39836
|
await next();
|
|
@@ -47558,34 +47588,34 @@ var require_node3 = __commonJS((exports) => {
|
|
|
47558
47588
|
}
|
|
47559
47589
|
exports2.urlParse = urlParse;
|
|
47560
47590
|
function urlGenerate(aParsedUrl) {
|
|
47561
|
-
var
|
|
47591
|
+
var url2 = "";
|
|
47562
47592
|
if (aParsedUrl.scheme) {
|
|
47563
|
-
|
|
47593
|
+
url2 += aParsedUrl.scheme + ":";
|
|
47564
47594
|
}
|
|
47565
|
-
|
|
47595
|
+
url2 += "//";
|
|
47566
47596
|
if (aParsedUrl.auth) {
|
|
47567
|
-
|
|
47597
|
+
url2 += aParsedUrl.auth + "@";
|
|
47568
47598
|
}
|
|
47569
47599
|
if (aParsedUrl.host) {
|
|
47570
|
-
|
|
47600
|
+
url2 += aParsedUrl.host;
|
|
47571
47601
|
}
|
|
47572
47602
|
if (aParsedUrl.port) {
|
|
47573
|
-
|
|
47603
|
+
url2 += ":" + aParsedUrl.port;
|
|
47574
47604
|
}
|
|
47575
47605
|
if (aParsedUrl.path) {
|
|
47576
|
-
|
|
47606
|
+
url2 += aParsedUrl.path;
|
|
47577
47607
|
}
|
|
47578
|
-
return
|
|
47608
|
+
return url2;
|
|
47579
47609
|
}
|
|
47580
47610
|
exports2.urlGenerate = urlGenerate;
|
|
47581
47611
|
function normalize(aPath) {
|
|
47582
47612
|
var path = aPath;
|
|
47583
|
-
var
|
|
47584
|
-
if (
|
|
47585
|
-
if (!
|
|
47613
|
+
var url2 = urlParse(aPath);
|
|
47614
|
+
if (url2) {
|
|
47615
|
+
if (!url2.path) {
|
|
47586
47616
|
return aPath;
|
|
47587
47617
|
}
|
|
47588
|
-
path =
|
|
47618
|
+
path = url2.path;
|
|
47589
47619
|
}
|
|
47590
47620
|
var isAbsolute2 = exports2.isAbsolute(path);
|
|
47591
47621
|
var parts2 = path.split(/\/+/);
|
|
@@ -47609,9 +47639,9 @@ var require_node3 = __commonJS((exports) => {
|
|
|
47609
47639
|
if (path === "") {
|
|
47610
47640
|
path = isAbsolute2 ? "/" : ".";
|
|
47611
47641
|
}
|
|
47612
|
-
if (
|
|
47613
|
-
|
|
47614
|
-
return urlGenerate(
|
|
47642
|
+
if (url2) {
|
|
47643
|
+
url2.path = path;
|
|
47644
|
+
return urlGenerate(url2);
|
|
47615
47645
|
}
|
|
47616
47646
|
return path;
|
|
47617
47647
|
}
|
|
@@ -48637,13 +48667,13 @@ var require_node3 = __commonJS((exports) => {
|
|
|
48637
48667
|
if (this.sourceRoot != null) {
|
|
48638
48668
|
relativeSource = util3.relative(this.sourceRoot, relativeSource);
|
|
48639
48669
|
}
|
|
48640
|
-
var
|
|
48641
|
-
if (this.sourceRoot != null && (
|
|
48670
|
+
var url2;
|
|
48671
|
+
if (this.sourceRoot != null && (url2 = util3.urlParse(this.sourceRoot))) {
|
|
48642
48672
|
var fileUriAbsPath = relativeSource.replace(/^file:\/\//, "");
|
|
48643
|
-
if (
|
|
48673
|
+
if (url2.scheme == "file" && this._sources.has(fileUriAbsPath)) {
|
|
48644
48674
|
return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)];
|
|
48645
48675
|
}
|
|
48646
|
-
if ((!
|
|
48676
|
+
if ((!url2.path || url2.path == "/") && this._sources.has("/" + relativeSource)) {
|
|
48647
48677
|
return this.sourcesContent[this._sources.indexOf("/" + relativeSource)];
|
|
48648
48678
|
}
|
|
48649
48679
|
}
|
|
@@ -49211,18 +49241,18 @@ var require_node3 = __commonJS((exports) => {
|
|
|
49211
49241
|
} catch (er2) {}
|
|
49212
49242
|
return fileContentsCache[path2] = contents;
|
|
49213
49243
|
});
|
|
49214
|
-
function supportRelativeURL(file,
|
|
49244
|
+
function supportRelativeURL(file, url2) {
|
|
49215
49245
|
if (!file)
|
|
49216
|
-
return
|
|
49246
|
+
return url2;
|
|
49217
49247
|
var dir = path.dirname(file);
|
|
49218
49248
|
var match2 = /^\w+:\/\/[^\/]*/.exec(dir);
|
|
49219
49249
|
var protocol = match2 ? match2[0] : "";
|
|
49220
49250
|
var startPath = dir.slice(protocol.length);
|
|
49221
49251
|
if (protocol && /^\/\w\:/.test(startPath)) {
|
|
49222
49252
|
protocol += "/";
|
|
49223
|
-
return protocol + path.resolve(dir.slice(protocol.length),
|
|
49253
|
+
return protocol + path.resolve(dir.slice(protocol.length), url2).replace(/\\/g, "/");
|
|
49224
49254
|
}
|
|
49225
|
-
return protocol + path.resolve(dir.slice(protocol.length),
|
|
49255
|
+
return protocol + path.resolve(dir.slice(protocol.length), url2);
|
|
49226
49256
|
}
|
|
49227
49257
|
function retrieveSourceMapURL(source) {
|
|
49228
49258
|
var fileData;
|
|
@@ -49282,8 +49312,8 @@ var require_node3 = __commonJS((exports) => {
|
|
|
49282
49312
|
sourceMap.map.sources.forEach(function(source, i3) {
|
|
49283
49313
|
var contents = sourceMap.map.sourcesContent[i3];
|
|
49284
49314
|
if (contents) {
|
|
49285
|
-
var
|
|
49286
|
-
fileContentsCache[
|
|
49315
|
+
var url2 = supportRelativeURL(sourceMap.url, source);
|
|
49316
|
+
fileContentsCache[url2] = contents;
|
|
49287
49317
|
}
|
|
49288
49318
|
});
|
|
49289
49319
|
}
|
|
@@ -94830,8 +94860,8 @@ var init_bucket_controller = __esm(() => {
|
|
|
94830
94860
|
if (!slug2) {
|
|
94831
94861
|
throw ApiError.badRequest("Missing game slug");
|
|
94832
94862
|
}
|
|
94833
|
-
const
|
|
94834
|
-
const prefix2 =
|
|
94863
|
+
const url2 = ctx.url;
|
|
94864
|
+
const prefix2 = url2.searchParams.get("prefix") || undefined;
|
|
94835
94865
|
logger40.debug("Listing files", { userId: ctx.user.id, slug: slug2, prefix: prefix2 });
|
|
94836
94866
|
const files = await ctx.services.bucket.listFiles(slug2, ctx.user, prefix2);
|
|
94837
94867
|
return { files };
|
|
@@ -95679,8 +95709,8 @@ var init_kv_controller = __esm(() => {
|
|
|
95679
95709
|
if (!slug2) {
|
|
95680
95710
|
throw ApiError.badRequest("Missing game slug");
|
|
95681
95711
|
}
|
|
95682
|
-
const
|
|
95683
|
-
const prefix2 =
|
|
95712
|
+
const url2 = ctx.url;
|
|
95713
|
+
const prefix2 = url2.searchParams.get("prefix") || undefined;
|
|
95684
95714
|
logger50.debug("Listing keys", { userId: ctx.user.id, slug: slug2, prefix: prefix2 });
|
|
95685
95715
|
const keys = await ctx.services.kv.listKeys(slug2, ctx.user, prefix2);
|
|
95686
95716
|
return { keys };
|
|
@@ -95803,17 +95833,17 @@ var init_leaderboard_controller = __esm(() => {
|
|
|
95803
95833
|
return ctx.services.leaderboard.submitScore(gameId, ctx.user.id, { score: body2.score, metadata: body2.metadata }, ctx.user.isAnonymous, ctx.params.sessionId);
|
|
95804
95834
|
});
|
|
95805
95835
|
getGlobalLeaderboard = requireAuth(async (ctx) => {
|
|
95806
|
-
const
|
|
95807
|
-
const gameId =
|
|
95836
|
+
const url2 = ctx.url;
|
|
95837
|
+
const gameId = url2.searchParams.get("gameId");
|
|
95808
95838
|
if (!gameId) {
|
|
95809
95839
|
throw ApiError.badRequest("Game ID is required");
|
|
95810
95840
|
}
|
|
95811
95841
|
let query;
|
|
95812
95842
|
try {
|
|
95813
95843
|
query = LeaderboardQuerySchema.parse({
|
|
95814
|
-
timeframe:
|
|
95815
|
-
limit: Number(
|
|
95816
|
-
offset: Number(
|
|
95844
|
+
timeframe: url2.searchParams.get("timeframe") || "all_time",
|
|
95845
|
+
limit: Number(url2.searchParams.get("limit") || "10"),
|
|
95846
|
+
offset: Number(url2.searchParams.get("offset") || "0")
|
|
95817
95847
|
});
|
|
95818
95848
|
} catch (error2) {
|
|
95819
95849
|
if (error2 instanceof exports_external.ZodError) {
|
|
@@ -95835,13 +95865,13 @@ var init_leaderboard_controller = __esm(() => {
|
|
|
95835
95865
|
if (!gameId) {
|
|
95836
95866
|
throw ApiError.badRequest("Game ID is required");
|
|
95837
95867
|
}
|
|
95838
|
-
const
|
|
95868
|
+
const url2 = ctx.url;
|
|
95839
95869
|
let query;
|
|
95840
95870
|
try {
|
|
95841
95871
|
query = LeaderboardQuerySchema.parse({
|
|
95842
|
-
timeframe:
|
|
95843
|
-
limit: Number(
|
|
95844
|
-
offset: Number(
|
|
95872
|
+
timeframe: url2.searchParams.get("timeframe") || "all_time",
|
|
95873
|
+
limit: Number(url2.searchParams.get("limit") || "10"),
|
|
95874
|
+
offset: Number(url2.searchParams.get("offset") || "0")
|
|
95845
95875
|
});
|
|
95846
95876
|
} catch (error2) {
|
|
95847
95877
|
if (error2 instanceof exports_external.ZodError) {
|
|
@@ -95875,9 +95905,9 @@ var init_leaderboard_controller = __esm(() => {
|
|
|
95875
95905
|
if (!userId) {
|
|
95876
95906
|
throw ApiError.badRequest("User ID is required");
|
|
95877
95907
|
}
|
|
95878
|
-
const
|
|
95879
|
-
const limit = Math.min(Number(
|
|
95880
|
-
const gameId =
|
|
95908
|
+
const url2 = ctx.url;
|
|
95909
|
+
const limit = Math.min(Number(url2.searchParams.get("limit") || "50"), 100);
|
|
95910
|
+
const gameId = url2.searchParams.get("gameId") || undefined;
|
|
95881
95911
|
logger51.debug("Getting user all scores", {
|
|
95882
95912
|
requesterId: ctx.user.id,
|
|
95883
95913
|
targetUserId: userId,
|
|
@@ -95891,8 +95921,8 @@ var init_leaderboard_controller = __esm(() => {
|
|
|
95891
95921
|
if (!gameId || !userId) {
|
|
95892
95922
|
throw ApiError.badRequest("Game ID and User ID are required");
|
|
95893
95923
|
}
|
|
95894
|
-
const
|
|
95895
|
-
const limit = Math.min(Number(
|
|
95924
|
+
const url2 = ctx.url;
|
|
95925
|
+
const limit = Math.min(Number(url2.searchParams.get("limit") || "10"), 100);
|
|
95896
95926
|
logger51.debug("Getting user scores", {
|
|
95897
95927
|
requesterId: ctx.user.id,
|
|
95898
95928
|
gameId,
|
|
@@ -98192,10 +98222,10 @@ var init_timeback6 = __esm(() => {
|
|
|
98192
98222
|
return c2.json(createErrorResponse(error2), error2.status);
|
|
98193
98223
|
}
|
|
98194
98224
|
if (shouldMockTimeback()) {
|
|
98195
|
-
const
|
|
98196
|
-
const gradeParam =
|
|
98197
|
-
const subjectParam =
|
|
98198
|
-
const includeParam =
|
|
98225
|
+
const url2 = new URL(c2.req.url);
|
|
98226
|
+
const gradeParam = url2.searchParams.get("grade");
|
|
98227
|
+
const subjectParam = url2.searchParams.get("subject");
|
|
98228
|
+
const includeParam = url2.searchParams.get("include") || "";
|
|
98199
98229
|
const includeOptions = includeParam.split(",").map((opt) => opt.trim().toLowerCase());
|
|
98200
98230
|
const includePerCourse = includeOptions.includes("percourse");
|
|
98201
98231
|
const includeToday = includeOptions.includes("today");
|