@playcademy/vite-plugin 1.1.1 → 1.1.2-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +120 -8
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -23746,7 +23746,7 @@ import path from "node:path";
|
|
|
23746
23746
|
// package.json
|
|
23747
23747
|
var package_default = {
|
|
23748
23748
|
name: "@playcademy/vite-plugin",
|
|
23749
|
-
version: "1.1.
|
|
23749
|
+
version: "1.1.2-beta.2",
|
|
23750
23750
|
type: "module",
|
|
23751
23751
|
exports: {
|
|
23752
23752
|
".": {
|
|
@@ -24476,6 +24476,7 @@ var init_game = __esm(() => {
|
|
|
24476
24476
|
COLLABORATOR: "collaborator"
|
|
24477
24477
|
};
|
|
24478
24478
|
});
|
|
24479
|
+
var PLAYCADEMY_BROWSER_TIME_ZONE_HEADER = "x-playcademy-browser-time-zone";
|
|
24479
24480
|
var CORE_GAME_UUIDS;
|
|
24480
24481
|
var init_platform = __esm(() => {
|
|
24481
24482
|
CORE_GAME_UUIDS = {
|
|
@@ -25344,7 +25345,7 @@ var package_default2;
|
|
|
25344
25345
|
var init_package = __esm(() => {
|
|
25345
25346
|
package_default2 = {
|
|
25346
25347
|
name: "@playcademy/sandbox",
|
|
25347
|
-
version: "0.6.
|
|
25348
|
+
version: "0.6.1-beta.1",
|
|
25348
25349
|
description: "Local development server for Playcademy game development",
|
|
25349
25350
|
type: "module",
|
|
25350
25351
|
exports: {
|
|
@@ -35335,6 +35336,11 @@ var init_table3 = __esm(() => {
|
|
|
35335
35336
|
email: text("email").notNull().unique(),
|
|
35336
35337
|
isAnonymous: boolean("is_anonymous").notNull().default(false),
|
|
35337
35338
|
timebackId: text("timeback_id").unique(),
|
|
35339
|
+
learningTimeZone: text("learning_time_zone"),
|
|
35340
|
+
learningTimeZoneUpdatedAt: timestamp("learning_time_zone_updated_at", {
|
|
35341
|
+
mode: "date",
|
|
35342
|
+
withTimezone: true
|
|
35343
|
+
}),
|
|
35338
35344
|
emailVerified: boolean("email_verified").notNull().default(false),
|
|
35339
35345
|
image: text("image"),
|
|
35340
35346
|
role: userRoleEnum("role").notNull().default("player"),
|
|
@@ -100786,6 +100792,7 @@ class AnalyticsXp {
|
|
|
100786
100792
|
this.core = core3;
|
|
100787
100793
|
}
|
|
100788
100794
|
async get(studentId, options) {
|
|
100795
|
+
const timezone2 = options?.timezone ?? PLATFORM_TIMEZONE;
|
|
100789
100796
|
const enrollments = await this.core.api.edubridge.enrollments.list({ userId: studentId });
|
|
100790
100797
|
const filteredEnrollments = options?.courseIds?.length ? enrollments.filter((e) => options.courseIds.includes(e.course.id)) : enrollments;
|
|
100791
100798
|
if (filteredEnrollments.length === 0) {
|
|
@@ -100799,7 +100806,7 @@ class AnalyticsXp {
|
|
|
100799
100806
|
try {
|
|
100800
100807
|
const analytics = await this.core.api.edubridge.analytics.getEnrollmentFacts({
|
|
100801
100808
|
enrollmentId: enrollment.id,
|
|
100802
|
-
timezone:
|
|
100809
|
+
timezone: timezone2
|
|
100803
100810
|
});
|
|
100804
100811
|
return { enrollment, analytics };
|
|
100805
100812
|
} catch (error88) {
|
|
@@ -100811,7 +100818,7 @@ class AnalyticsXp {
|
|
|
100811
100818
|
return { enrollment, analytics: null };
|
|
100812
100819
|
}
|
|
100813
100820
|
}));
|
|
100814
|
-
const today = formatDateYMDInTimezone(
|
|
100821
|
+
const today = formatDateYMDInTimezone(timezone2);
|
|
100815
100822
|
let totalXp = 0;
|
|
100816
100823
|
let todayXp = 0;
|
|
100817
100824
|
const courses = [];
|
|
@@ -106772,13 +106779,24 @@ var init_timeback_service = __esm(async () => {
|
|
|
106772
106779
|
};
|
|
106773
106780
|
}
|
|
106774
106781
|
}
|
|
106782
|
+
const timezone2 = await this.getLearningTimeZoneForStudent(timebackId);
|
|
106775
106783
|
const result = await client.analytics.getXp(timebackId, {
|
|
106776
106784
|
courseIds: courseIds.length > 0 ? courseIds : undefined,
|
|
106785
|
+
timezone: timezone2,
|
|
106777
106786
|
include: options?.include
|
|
106778
106787
|
});
|
|
106779
106788
|
return result;
|
|
106780
106789
|
});
|
|
106781
106790
|
}
|
|
106791
|
+
async getLearningTimeZoneForStudent(timebackId) {
|
|
106792
|
+
const user = await this.deps.db.query.users.findFirst({
|
|
106793
|
+
where: eq(users.timebackId, timebackId),
|
|
106794
|
+
columns: {
|
|
106795
|
+
learningTimeZone: true
|
|
106796
|
+
}
|
|
106797
|
+
});
|
|
106798
|
+
return user?.learningTimeZone ?? PLATFORM_TIMEZONE;
|
|
106799
|
+
}
|
|
106782
106800
|
async getStudentMastery(timebackId, user, options) {
|
|
106783
106801
|
return this.withClientTelemetry(async () => {
|
|
106784
106802
|
const client = this.requireClient();
|
|
@@ -107540,13 +107558,26 @@ var init_session_service = __esm(() => {
|
|
|
107540
107558
|
init_spans();
|
|
107541
107559
|
init_errors();
|
|
107542
107560
|
});
|
|
107561
|
+
function normalizeIanaTimeZone(value) {
|
|
107562
|
+
const timeZone = value?.trim();
|
|
107563
|
+
if (!timeZone || timeZone.length > MAX_IANA_TIME_ZONE_LENGTH) {
|
|
107564
|
+
return;
|
|
107565
|
+
}
|
|
107566
|
+
try {
|
|
107567
|
+
new Intl.DateTimeFormat("en-US", { timeZone }).format(new Date);
|
|
107568
|
+
return timeZone;
|
|
107569
|
+
} catch {
|
|
107570
|
+
return;
|
|
107571
|
+
}
|
|
107572
|
+
}
|
|
107573
|
+
var MAX_IANA_TIME_ZONE_LENGTH = 100;
|
|
107543
107574
|
|
|
107544
107575
|
class UserService {
|
|
107545
107576
|
deps;
|
|
107546
107577
|
constructor(deps) {
|
|
107547
107578
|
this.deps = deps;
|
|
107548
107579
|
}
|
|
107549
|
-
async getMe(user, gameId) {
|
|
107580
|
+
async getMe(user, gameId, observedTimeZone) {
|
|
107550
107581
|
const db2 = this.deps.db;
|
|
107551
107582
|
const userData = await db2.query.users.findFirst({
|
|
107552
107583
|
where: eq(users.id, user.id)
|
|
@@ -107559,6 +107590,7 @@ class UserService {
|
|
|
107559
107590
|
"app.user.has_timeback_account": Boolean(userData.timebackId),
|
|
107560
107591
|
"app.user.timeback_enriched": false
|
|
107561
107592
|
});
|
|
107593
|
+
const localDay = await this.resolveLocalDay(userData, observedTimeZone);
|
|
107562
107594
|
const timeback2 = userData.timebackId ? await this.fetchTimebackData(userData.timebackId, gameId) : undefined;
|
|
107563
107595
|
setAttribute("app.user.timeback_enriched", Boolean(timeback2));
|
|
107564
107596
|
if (gameId) {
|
|
@@ -107568,6 +107600,7 @@ class UserService {
|
|
|
107568
107600
|
role: userData.role,
|
|
107569
107601
|
username: userData.username,
|
|
107570
107602
|
email: userData.email,
|
|
107603
|
+
localDay,
|
|
107571
107604
|
timeback: timeback2
|
|
107572
107605
|
};
|
|
107573
107606
|
}
|
|
@@ -107587,6 +107620,7 @@ class UserService {
|
|
|
107587
107620
|
createdAt: userData.createdAt,
|
|
107588
107621
|
updatedAt: userData.updatedAt,
|
|
107589
107622
|
hasTimebackAccount: Boolean(timebackAccount),
|
|
107623
|
+
localDay,
|
|
107590
107624
|
timeback: timeback2
|
|
107591
107625
|
};
|
|
107592
107626
|
}
|
|
@@ -107624,6 +107658,44 @@ class UserService {
|
|
|
107624
107658
|
isDefault: updatedUser.name === DEMO_DISPLAY_NAME_PLACEHOLDER
|
|
107625
107659
|
};
|
|
107626
107660
|
}
|
|
107661
|
+
async resolveLocalDay(userData, observedTimeZone) {
|
|
107662
|
+
const normalizedTimeZone = normalizeIanaTimeZone(observedTimeZone);
|
|
107663
|
+
if (normalizedTimeZone) {
|
|
107664
|
+
const observedAt = new Date;
|
|
107665
|
+
const shouldPersist = userData.learningTimeZone !== normalizedTimeZone || !userData.learningTimeZoneUpdatedAt || observedAt.getTime() - userData.learningTimeZoneUpdatedAt.getTime() >= LEARNING_TIME_ZONE_REFRESH_INTERVAL_MS;
|
|
107666
|
+
if (shouldPersist) {
|
|
107667
|
+
await this.deps.db.update(users).set({
|
|
107668
|
+
learningTimeZone: normalizedTimeZone,
|
|
107669
|
+
learningTimeZoneUpdatedAt: observedAt
|
|
107670
|
+
}).where(eq(users.id, userData.id));
|
|
107671
|
+
}
|
|
107672
|
+
setAttributes({
|
|
107673
|
+
"app.user.learning_time_zone_observed": true,
|
|
107674
|
+
"app.user.learning_time_zone_persisted": shouldPersist
|
|
107675
|
+
});
|
|
107676
|
+
return {
|
|
107677
|
+
timeZone: normalizedTimeZone,
|
|
107678
|
+
source: "browser_last_seen",
|
|
107679
|
+
observedAt: (shouldPersist ? observedAt : userData.learningTimeZoneUpdatedAt)?.toISOString() ?? null
|
|
107680
|
+
};
|
|
107681
|
+
}
|
|
107682
|
+
setAttributes({
|
|
107683
|
+
"app.user.learning_time_zone_observed": false,
|
|
107684
|
+
"app.user.learning_time_zone_persisted": false
|
|
107685
|
+
});
|
|
107686
|
+
if (userData.learningTimeZone) {
|
|
107687
|
+
return {
|
|
107688
|
+
timeZone: userData.learningTimeZone,
|
|
107689
|
+
source: "browser_last_seen",
|
|
107690
|
+
observedAt: userData.learningTimeZoneUpdatedAt?.toISOString() ?? null
|
|
107691
|
+
};
|
|
107692
|
+
}
|
|
107693
|
+
return {
|
|
107694
|
+
timeZone: PLATFORM_TIMEZONE,
|
|
107695
|
+
source: "platform_default",
|
|
107696
|
+
observedAt: null
|
|
107697
|
+
};
|
|
107698
|
+
}
|
|
107627
107699
|
async fetchTimebackData(timebackId, gameId) {
|
|
107628
107700
|
const [{ role, organizations: allOrganizations }, allEnrollments] = await Promise.all([
|
|
107629
107701
|
withSpan("timeback.fetch_profile", () => this.fetchStudentProfile(timebackId)),
|
|
@@ -107705,6 +107777,7 @@ class UserService {
|
|
|
107705
107777
|
return organizations.filter((o) => enrollmentOrgIds.has(o.id));
|
|
107706
107778
|
}
|
|
107707
107779
|
}
|
|
107780
|
+
var LEARNING_TIME_ZONE_REFRESH_INTERVAL_MS;
|
|
107708
107781
|
var init_user_service = __esm(() => {
|
|
107709
107782
|
init_drizzle_orm();
|
|
107710
107783
|
init_src();
|
|
@@ -107713,6 +107786,7 @@ var init_user_service = __esm(() => {
|
|
|
107713
107786
|
init_spans();
|
|
107714
107787
|
init_errors();
|
|
107715
107788
|
init_timeback_util();
|
|
107789
|
+
LEARNING_TIME_ZONE_REFRESH_INTERVAL_MS = 86400000;
|
|
107716
107790
|
});
|
|
107717
107791
|
|
|
107718
107792
|
class VerifyService {
|
|
@@ -168001,9 +168075,10 @@ var getDemoProfile;
|
|
|
168001
168075
|
var updateDemoProfile;
|
|
168002
168076
|
var users2;
|
|
168003
168077
|
var init_user_controller = __esm(() => {
|
|
168078
|
+
init_src();
|
|
168004
168079
|
init_schemas_index();
|
|
168005
168080
|
init_utils11();
|
|
168006
|
-
getMe = requireNonAnonymous(async (ctx) => ctx.services.user.getMe(ctx.user, ctx.gameId));
|
|
168081
|
+
getMe = requireNonAnonymous(async (ctx) => ctx.services.user.getMe(ctx.user, ctx.gameId, ctx.request.headers.get(PLAYCADEMY_BROWSER_TIME_ZONE_HEADER)));
|
|
168007
168082
|
getDemoProfile = requireAnonymous(async (ctx) => ctx.services.user.getDemoProfile(ctx.user.id));
|
|
168008
168083
|
updateDemoProfile = requireAnonymous(async (ctx) => {
|
|
168009
168084
|
const body2 = await parseRequestBody(ctx.request, DemoProfileSchema);
|
|
@@ -168148,8 +168223,39 @@ function getMockHighestGradeMastered(enrollments, subject) {
|
|
|
168148
168223
|
const subjectGrades = enrollments.filter((enrollment) => enrollment.subject === subject).map((enrollment) => enrollment.grade);
|
|
168149
168224
|
return subjectGrades.length > 0 ? Math.max(...subjectGrades) : null;
|
|
168150
168225
|
}
|
|
168151
|
-
async function
|
|
168226
|
+
async function buildLocalDayContext(db2, user, observedTimeZone) {
|
|
168227
|
+
const normalizedTimeZone = normalizeIanaTimeZone(observedTimeZone);
|
|
168228
|
+
if (normalizedTimeZone) {
|
|
168229
|
+
const observedAt = new Date;
|
|
168230
|
+
const shouldPersist = user.learningTimeZone !== normalizedTimeZone || !user.learningTimeZoneUpdatedAt || observedAt.getTime() - user.learningTimeZoneUpdatedAt.getTime() >= LEARNING_TIME_ZONE_REFRESH_INTERVAL_MS2;
|
|
168231
|
+
if (shouldPersist) {
|
|
168232
|
+
await db2.update(users).set({
|
|
168233
|
+
learningTimeZone: normalizedTimeZone,
|
|
168234
|
+
learningTimeZoneUpdatedAt: observedAt
|
|
168235
|
+
}).where(eq(users.id, user.id));
|
|
168236
|
+
}
|
|
168237
|
+
return {
|
|
168238
|
+
timeZone: normalizedTimeZone,
|
|
168239
|
+
source: "browser_last_seen",
|
|
168240
|
+
observedAt: (shouldPersist ? observedAt : user.learningTimeZoneUpdatedAt)?.toISOString() ?? null
|
|
168241
|
+
};
|
|
168242
|
+
}
|
|
168243
|
+
if (user.learningTimeZone) {
|
|
168244
|
+
return {
|
|
168245
|
+
timeZone: user.learningTimeZone,
|
|
168246
|
+
source: "browser_last_seen",
|
|
168247
|
+
observedAt: user.learningTimeZoneUpdatedAt?.toISOString() ?? null
|
|
168248
|
+
};
|
|
168249
|
+
}
|
|
168250
|
+
return {
|
|
168251
|
+
timeZone: PLATFORM_TIMEZONE,
|
|
168252
|
+
source: "platform_default",
|
|
168253
|
+
observedAt: null
|
|
168254
|
+
};
|
|
168255
|
+
}
|
|
168256
|
+
async function buildMockUserResponse(db2, user, gameId, observedTimeZone) {
|
|
168152
168257
|
const timeback3 = user.timebackId ? await getMockTimebackData(db2, user.timebackId, gameId) : undefined;
|
|
168258
|
+
const localDay = await buildLocalDayContext(db2, user, observedTimeZone);
|
|
168153
168259
|
if (gameId) {
|
|
168154
168260
|
return {
|
|
168155
168261
|
id: user.id,
|
|
@@ -168157,6 +168263,7 @@ async function buildMockUserResponse(db2, user, gameId) {
|
|
|
168157
168263
|
role: user.role,
|
|
168158
168264
|
username: user.username,
|
|
168159
168265
|
email: user.email,
|
|
168266
|
+
localDay,
|
|
168160
168267
|
timeback: timeback3
|
|
168161
168268
|
};
|
|
168162
168269
|
}
|
|
@@ -168175,15 +168282,19 @@ async function buildMockUserResponse(db2, user, gameId) {
|
|
|
168175
168282
|
createdAt: user.createdAt,
|
|
168176
168283
|
updatedAt: user.updatedAt,
|
|
168177
168284
|
hasTimebackAccount: Boolean(timebackAccount),
|
|
168285
|
+
localDay,
|
|
168178
168286
|
timeback: timeback3
|
|
168179
168287
|
};
|
|
168180
168288
|
}
|
|
168289
|
+
var LEARNING_TIME_ZONE_REFRESH_INTERVAL_MS2;
|
|
168181
168290
|
var init_timeback6 = __esm(() => {
|
|
168182
168291
|
init_drizzle_orm();
|
|
168183
168292
|
init_utils11();
|
|
168293
|
+
init_src();
|
|
168184
168294
|
init_tables_index();
|
|
168185
168295
|
init_src2();
|
|
168186
168296
|
init_config();
|
|
168297
|
+
LEARNING_TIME_ZONE_REFRESH_INTERVAL_MS2 = 86400000;
|
|
168187
168298
|
});
|
|
168188
168299
|
var usersRouter;
|
|
168189
168300
|
var init_users = __esm(async () => {
|
|
@@ -168191,6 +168302,7 @@ var init_users = __esm(async () => {
|
|
|
168191
168302
|
init_dist7();
|
|
168192
168303
|
init_controllers();
|
|
168193
168304
|
init_errors();
|
|
168305
|
+
init_src();
|
|
168194
168306
|
init_tables_index();
|
|
168195
168307
|
init_error_handler();
|
|
168196
168308
|
init_timeback6();
|
|
@@ -168212,7 +168324,7 @@ var init_users = __esm(async () => {
|
|
|
168212
168324
|
const error89 = ApiError.notFound("User not found");
|
|
168213
168325
|
return c2.json(createErrorResponse(error89), error89.status);
|
|
168214
168326
|
}
|
|
168215
|
-
const response = await buildMockUserResponse(db2, userData, gameId);
|
|
168327
|
+
const response = await buildMockUserResponse(db2, userData, gameId, c2.req.header(PLAYCADEMY_BROWSER_TIME_ZONE_HEADER));
|
|
168216
168328
|
return c2.json(response);
|
|
168217
168329
|
}
|
|
168218
168330
|
return handle2(users2.getMe)(c2);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@playcademy/vite-plugin",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2-beta.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -19,14 +19,14 @@
|
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"archiver": "^7.0.1",
|
|
21
21
|
"picocolors": "^1.1.1",
|
|
22
|
-
"playcademy": "0.26.
|
|
22
|
+
"playcademy": "0.26.1-beta.2"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@electric-sql/pglite": "^0.3.16",
|
|
26
26
|
"@inquirer/prompts": "^7.8.6",
|
|
27
27
|
"@playcademy/constants": "0.0.1",
|
|
28
|
-
"@playcademy/sandbox": "0.6.
|
|
29
|
-
"@playcademy/sdk": "0.14.
|
|
28
|
+
"@playcademy/sandbox": "0.6.1-beta.1",
|
|
29
|
+
"@playcademy/sdk": "0.14.1-beta.1",
|
|
30
30
|
"@playcademy/types": "0.0.1",
|
|
31
31
|
"@playcademy/utils": "0.0.1",
|
|
32
32
|
"@types/archiver": "^6.0.3",
|