@playcademy/vite-plugin 0.2.24 → 0.2.25-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 +255 -108
- package/dist/lib/sandbox/token.d.ts +11 -1
- package/dist/server/hotkeys/toggle-mode.d.ts +1 -1
- package/dist/server/modes.d.ts +4 -0
- package/dist/server/platform-mode.d.ts +3 -3
- package/dist/types/internal.d.ts +3 -3
- package/dist/types/options.d.ts +6 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -23954,6 +23954,20 @@ import fs7 from "node:fs";
|
|
|
23954
23954
|
import path4 from "node:path";
|
|
23955
23955
|
import { CONFIG_FILE_NAMES } from "playcademy/constants";
|
|
23956
23956
|
|
|
23957
|
+
// src/server/modes.ts
|
|
23958
|
+
function isShellMode(mode) {
|
|
23959
|
+
return mode !== "standalone";
|
|
23960
|
+
}
|
|
23961
|
+
function getNextMode(mode) {
|
|
23962
|
+
if (mode === "platform") {
|
|
23963
|
+
return "demo";
|
|
23964
|
+
}
|
|
23965
|
+
if (mode === "demo") {
|
|
23966
|
+
return "standalone";
|
|
23967
|
+
}
|
|
23968
|
+
return "platform";
|
|
23969
|
+
}
|
|
23970
|
+
|
|
23957
23971
|
// src/server/recreate-sandbox.ts
|
|
23958
23972
|
var import_picocolors7 = __toESM(require_picocolors(), 1);
|
|
23959
23973
|
|
|
@@ -24306,6 +24320,7 @@ var init_achievements = __esm(() => {
|
|
|
24306
24320
|
];
|
|
24307
24321
|
});
|
|
24308
24322
|
var AUTH_PROVIDER_IDS;
|
|
24323
|
+
var DEMO_DISPLAY_NAME_PLACEHOLDER = "Demo Player";
|
|
24309
24324
|
var init_auth = __esm(() => {
|
|
24310
24325
|
AUTH_PROVIDER_IDS = {
|
|
24311
24326
|
TIMEBACK: "timeback",
|
|
@@ -24391,7 +24406,8 @@ var init_overworld = __esm(() => {
|
|
|
24391
24406
|
ERROR: 4000
|
|
24392
24407
|
};
|
|
24393
24408
|
CORE_GAME_UUIDS = {
|
|
24394
|
-
PLAYGROUND: "00000000-0000-0000-0000-000000000001"
|
|
24409
|
+
PLAYGROUND: "00000000-0000-0000-0000-000000000001",
|
|
24410
|
+
DEMO: "00000000-0000-0000-0000-000000000002"
|
|
24395
24411
|
};
|
|
24396
24412
|
});
|
|
24397
24413
|
var PLATFORM_TIMEZONE = "America/New_York";
|
|
@@ -24471,13 +24487,15 @@ var DEMO_USER_IDS;
|
|
|
24471
24487
|
var DEMO_USERS;
|
|
24472
24488
|
var DEMO_USER;
|
|
24473
24489
|
var init_demo_users = __esm(() => {
|
|
24490
|
+
init_src();
|
|
24474
24491
|
now = new Date;
|
|
24475
24492
|
DEMO_USER_IDS = {
|
|
24476
24493
|
player: "00000000-0000-0000-0000-000000000001",
|
|
24477
24494
|
developer: "00000000-0000-0000-0000-000000000002",
|
|
24478
24495
|
admin: "00000000-0000-0000-0000-000000000003",
|
|
24479
24496
|
pendingDeveloper: "00000000-0000-0000-0000-000000000004",
|
|
24480
|
-
unverifiedPlayer: "00000000-0000-0000-0000-000000000005"
|
|
24497
|
+
unverifiedPlayer: "00000000-0000-0000-0000-000000000005",
|
|
24498
|
+
anonymousPlayer: "00000000-0000-0000-0000-000000000006"
|
|
24481
24499
|
};
|
|
24482
24500
|
DEMO_USERS = {
|
|
24483
24501
|
admin: {
|
|
@@ -24539,6 +24557,19 @@ var init_demo_users = __esm(() => {
|
|
|
24539
24557
|
developerStatus: "none",
|
|
24540
24558
|
createdAt: now,
|
|
24541
24559
|
updatedAt: now
|
|
24560
|
+
},
|
|
24561
|
+
anonymousPlayer: {
|
|
24562
|
+
id: DEMO_USER_IDS.anonymousPlayer,
|
|
24563
|
+
name: DEMO_DISPLAY_NAME_PLACEHOLDER,
|
|
24564
|
+
username: "anonymous_demo_player",
|
|
24565
|
+
email: "player@anon.demo.playcademy.gg",
|
|
24566
|
+
emailVerified: false,
|
|
24567
|
+
image: null,
|
|
24568
|
+
isAnonymous: true,
|
|
24569
|
+
role: "player",
|
|
24570
|
+
developerStatus: "none",
|
|
24571
|
+
createdAt: now,
|
|
24572
|
+
updatedAt: now
|
|
24542
24573
|
}
|
|
24543
24574
|
};
|
|
24544
24575
|
DEMO_USER = DEMO_USERS.player;
|
|
@@ -24553,6 +24584,7 @@ var init_demo_tokens = __esm(() => {
|
|
|
24553
24584
|
"sandbox-demo-token": DEMO_USERS.player,
|
|
24554
24585
|
"sandbox-admin-token": DEMO_USERS.admin,
|
|
24555
24586
|
"sandbox-player-token": DEMO_USERS.player,
|
|
24587
|
+
"sandbox-anonymous-token": DEMO_USERS.anonymousPlayer,
|
|
24556
24588
|
"sandbox-developer-token": DEMO_USERS.developer,
|
|
24557
24589
|
"sandbox-pending-dev-token": DEMO_USERS.pendingDeveloper,
|
|
24558
24590
|
"sandbox-unverified-token": DEMO_USERS.unverifiedPlayer,
|
|
@@ -24561,6 +24593,7 @@ var init_demo_tokens = __esm(() => {
|
|
|
24561
24593
|
};
|
|
24562
24594
|
SANDBOX_TOKENS = {
|
|
24563
24595
|
player: "sandbox-player-token",
|
|
24596
|
+
anonymous: "sandbox-anonymous-token",
|
|
24564
24597
|
developer: "sandbox-developer-token",
|
|
24565
24598
|
admin: "sandbox-admin-token",
|
|
24566
24599
|
pendingDeveloper: "sandbox-pending-dev-token",
|
|
@@ -25336,7 +25369,7 @@ var package_default;
|
|
|
25336
25369
|
var init_package = __esm(() => {
|
|
25337
25370
|
package_default = {
|
|
25338
25371
|
name: "@playcademy/sandbox",
|
|
25339
|
-
version: "0.3.
|
|
25372
|
+
version: "0.3.17-beta.14",
|
|
25340
25373
|
description: "Local development server for Playcademy game development",
|
|
25341
25374
|
type: "module",
|
|
25342
25375
|
exports: {
|
|
@@ -35621,6 +35654,7 @@ var init_table6 = __esm(() => {
|
|
|
35621
35654
|
name: text("name").notNull(),
|
|
35622
35655
|
username: text("username").unique(),
|
|
35623
35656
|
email: text("email").notNull().unique(),
|
|
35657
|
+
isAnonymous: boolean("is_anonymous").notNull().default(false),
|
|
35624
35658
|
timebackId: text("timeback_id").unique(),
|
|
35625
35659
|
emailVerified: boolean("email_verified").notNull().default(false),
|
|
35626
35660
|
image: text("image"),
|
|
@@ -56465,7 +56499,7 @@ class LeaderboardService {
|
|
|
56465
56499
|
constructor(deps) {
|
|
56466
56500
|
this.deps = deps;
|
|
56467
56501
|
}
|
|
56468
|
-
async submitScore(gameId, userId, input, sessionId) {
|
|
56502
|
+
async submitScore(gameId, userId, input, isAnonymousUser, sessionId) {
|
|
56469
56503
|
const db2 = this.deps.db;
|
|
56470
56504
|
const game = await db2.select({ displayName: games.displayName }).from(games).where(eq(games.id, gameId)).limit(1).then((rows) => rows[0]);
|
|
56471
56505
|
if (!game) {
|
|
@@ -56476,7 +56510,7 @@ class LeaderboardService {
|
|
|
56476
56510
|
const prevBestScore = prevBestScoreRows[0]?.score ?? null;
|
|
56477
56511
|
let prevRank = null;
|
|
56478
56512
|
if (prevBestScore !== null && prevBestScore !== undefined) {
|
|
56479
|
-
const higherCountRows = await db2.select({ count: sql`count(distinct ${gameScores.userId})` }).from(gameScores).where(and(eq(gameScores.gameId, gameId), sql`${gameScores.userId} != ${userId}`, sql`${gameScores.score} > ${prevBestScore}`));
|
|
56513
|
+
const higherCountRows = await db2.select({ count: sql`count(distinct ${gameScores.userId})` }).from(gameScores).innerJoin(users, eq(gameScores.userId, users.id)).where(and(eq(gameScores.gameId, gameId), eq(users.isAnonymous, isAnonymousUser), sql`${gameScores.userId} != ${userId}`, sql`${gameScores.score} > ${prevBestScore}`));
|
|
56480
56514
|
const higherCount = higherCountRows[0]?.count ?? 0;
|
|
56481
56515
|
prevRank = Number(higherCount) + 1;
|
|
56482
56516
|
}
|
|
@@ -56493,13 +56527,13 @@ class LeaderboardService {
|
|
|
56493
56527
|
}
|
|
56494
56528
|
const bestScoreRows = await db2.select({ score: sql`MAX(${gameScores.score})` }).from(gameScores).where(and(eq(gameScores.gameId, gameId), eq(gameScores.userId, userId)));
|
|
56495
56529
|
const bestScore = bestScoreRows[0]?.score ?? input.score;
|
|
56496
|
-
const higherCountNowRows = await db2.select({ count: sql`count(distinct ${gameScores.userId})` }).from(gameScores).where(and(eq(gameScores.gameId, gameId), sql`${gameScores.userId} != ${userId}`, sql`${gameScores.score} > ${bestScore}`));
|
|
56530
|
+
const higherCountNowRows = await db2.select({ count: sql`count(distinct ${gameScores.userId})` }).from(gameScores).innerJoin(users, eq(gameScores.userId, users.id)).where(and(eq(gameScores.gameId, gameId), eq(users.isAnonymous, isAnonymousUser), sql`${gameScores.userId} != ${userId}`, sql`${gameScores.score} > ${bestScore}`));
|
|
56497
56531
|
const higherCountNow = higherCountNowRows[0]?.count ?? 0;
|
|
56498
56532
|
const newRank = Number(higherCountNow) + 1;
|
|
56499
|
-
const totalPlayersRows = await db2.select({ count: sql`count(distinct ${gameScores.userId})` }).from(gameScores).where(eq(gameScores.gameId, gameId));
|
|
56533
|
+
const totalPlayersRows = await db2.select({ count: sql`count(distinct ${gameScores.userId})` }).from(gameScores).innerJoin(users, eq(gameScores.userId, users.id)).where(and(eq(gameScores.gameId, gameId), eq(users.isAnonymous, isAnonymousUser)));
|
|
56500
56534
|
const totalPlayers = Number(totalPlayersRows[0]?.count ?? 1);
|
|
56501
56535
|
const { shouldNotify, crossedIntoTop3, movedUpWithinTop3, isFirstScore, isPersonalBest } = shouldNotifyRankChange(prevRank, newRank, prevBestScore, input.score);
|
|
56502
|
-
if (shouldNotify) {
|
|
56536
|
+
if (shouldNotify && !isAnonymousUser) {
|
|
56503
56537
|
await this.publishScoreNotifications({
|
|
56504
56538
|
userId,
|
|
56505
56539
|
gameId,
|
|
@@ -56519,6 +56553,7 @@ class LeaderboardService {
|
|
|
56519
56553
|
logger21.info("Score submitted", {
|
|
56520
56554
|
gameId,
|
|
56521
56555
|
userId,
|
|
56556
|
+
isAnonymousUser,
|
|
56522
56557
|
score: input.score,
|
|
56523
56558
|
newRank,
|
|
56524
56559
|
isFirstScore,
|
|
@@ -56595,7 +56630,7 @@ class LeaderboardService {
|
|
|
56595
56630
|
logger21.warn("Failed to publish notification", { error });
|
|
56596
56631
|
}
|
|
56597
56632
|
}
|
|
56598
|
-
async getLeaderboard(gameId, query) {
|
|
56633
|
+
async getLeaderboard(gameId, query, isAnonymousUser) {
|
|
56599
56634
|
const { timeframe, limit, offset } = query;
|
|
56600
56635
|
const db2 = this.deps.db;
|
|
56601
56636
|
const dateFilter = getTimeframeFilter(timeframe);
|
|
@@ -56607,31 +56642,35 @@ class LeaderboardService {
|
|
|
56607
56642
|
score: gameScores.score,
|
|
56608
56643
|
achievedAt: gameScores.achievedAt,
|
|
56609
56644
|
metadata: gameScores.metadata
|
|
56610
|
-
}).from(gameScores).innerJoin(users, eq(gameScores.userId, users.id)).where(and(eq(gameScores.gameId, gameId), dateFilter)).orderBy(desc(gameScores.score)).limit(limit).offset(offset);
|
|
56645
|
+
}).from(gameScores).innerJoin(users, eq(gameScores.userId, users.id)).where(and(eq(gameScores.gameId, gameId), dateFilter, eq(users.isAnonymous, isAnonymousUser))).orderBy(desc(gameScores.score)).limit(limit).offset(offset);
|
|
56611
56646
|
return scores.map((score, index2) => ({
|
|
56612
56647
|
rank: offset + index2 + 1,
|
|
56613
56648
|
userId: score.userId,
|
|
56614
|
-
username: score.
|
|
56649
|
+
username: score.name || score.username || "Unknown User",
|
|
56615
56650
|
userImage: score.userImage,
|
|
56616
56651
|
score: score.score,
|
|
56617
56652
|
achievedAt: score.achievedAt,
|
|
56618
56653
|
metadata: score.metadata
|
|
56619
56654
|
}));
|
|
56620
56655
|
}
|
|
56621
|
-
async getGlobalLeaderboard(gameId, query) {
|
|
56656
|
+
async getGlobalLeaderboard(gameId, query, isAnonymousUser) {
|
|
56622
56657
|
if (!gameId) {
|
|
56623
56658
|
return [];
|
|
56624
56659
|
}
|
|
56625
56660
|
const { timeframe, limit, offset } = query;
|
|
56626
56661
|
const db2 = this.deps.db;
|
|
56627
56662
|
const dateFilter = getTimeframeFilter(timeframe);
|
|
56628
|
-
const conditions2 = [
|
|
56663
|
+
const conditions2 = [
|
|
56664
|
+
dateFilter,
|
|
56665
|
+
eq(gameScores.gameId, gameId),
|
|
56666
|
+
eq(users.isAnonymous, isAnonymousUser)
|
|
56667
|
+
];
|
|
56629
56668
|
const bestScoresSubquery = db2.select({
|
|
56630
56669
|
userId: gameScores.userId,
|
|
56631
56670
|
gameId: gameScores.gameId,
|
|
56632
56671
|
score: sql`MAX(${gameScores.score})`.as("max_score"),
|
|
56633
56672
|
achievedAt: sql`MAX(${gameScores.achievedAt})`.as("max_achieved_at")
|
|
56634
|
-
}).from(gameScores).where(and(...conditions2)).groupBy(gameScores.userId, gameScores.gameId).as("best_scores");
|
|
56673
|
+
}).from(gameScores).innerJoin(users, eq(gameScores.userId, users.id)).where(and(...conditions2)).groupBy(gameScores.userId, gameScores.gameId).as("best_scores");
|
|
56635
56674
|
const scores = await db2.select({
|
|
56636
56675
|
userId: users.id,
|
|
56637
56676
|
username: users.username,
|
|
@@ -56647,7 +56686,7 @@ class LeaderboardService {
|
|
|
56647
56686
|
return scores.map((score, index2) => ({
|
|
56648
56687
|
rank: offset + index2 + 1,
|
|
56649
56688
|
userId: score.userId,
|
|
56650
|
-
username: score.
|
|
56689
|
+
username: score.name || score.username || "Unknown User",
|
|
56651
56690
|
userImage: score.userImage,
|
|
56652
56691
|
score: score.score,
|
|
56653
56692
|
achievedAt: score.achievedAt,
|
|
@@ -56657,15 +56696,15 @@ class LeaderboardService {
|
|
|
56657
56696
|
gameSlug: score.gameSlug || ""
|
|
56658
56697
|
}));
|
|
56659
56698
|
}
|
|
56660
|
-
async getUserRank(gameId, userId) {
|
|
56699
|
+
async getUserRank(gameId, userId, isAnonymousUser) {
|
|
56661
56700
|
const db2 = this.deps.db;
|
|
56662
|
-
const userScoreResult = await db2.select({ score: gameScores.score }).from(gameScores).where(and(eq(gameScores.gameId, gameId), eq(gameScores.userId, userId))).orderBy(desc(gameScores.score)).limit(1);
|
|
56701
|
+
const userScoreResult = await db2.select({ score: gameScores.score }).from(gameScores).innerJoin(users, eq(gameScores.userId, users.id)).where(and(eq(gameScores.gameId, gameId), eq(gameScores.userId, userId), eq(users.isAnonymous, isAnonymousUser))).orderBy(desc(gameScores.score)).limit(1);
|
|
56663
56702
|
if (!userScoreResult.length || !userScoreResult[0]) {
|
|
56664
56703
|
return null;
|
|
56665
56704
|
}
|
|
56666
56705
|
const score = userScoreResult[0].score;
|
|
56667
|
-
const countResult = await db2.select({ count: sql`count(distinct ${gameScores.userId})` }).from(gameScores).where(and(eq(gameScores.gameId, gameId), sql`${gameScores.score} > ${score}`));
|
|
56668
|
-
const totalResult = await db2.select({ total: sql`count(distinct ${gameScores.userId})` }).from(gameScores).where(eq(gameScores.gameId, gameId));
|
|
56706
|
+
const countResult = await db2.select({ count: sql`count(distinct ${gameScores.userId})` }).from(gameScores).innerJoin(users, eq(gameScores.userId, users.id)).where(and(eq(gameScores.gameId, gameId), eq(users.isAnonymous, isAnonymousUser), sql`${gameScores.score} > ${score}`));
|
|
56707
|
+
const totalResult = await db2.select({ total: sql`count(distinct ${gameScores.userId})` }).from(gameScores).innerJoin(users, eq(gameScores.userId, users.id)).where(and(eq(gameScores.gameId, gameId), eq(users.isAnonymous, isAnonymousUser)));
|
|
56669
56708
|
const count = Number(countResult[0]?.count ?? 0);
|
|
56670
56709
|
const total = Number(totalResult[0]?.total ?? 0);
|
|
56671
56710
|
const rank = count + 1;
|
|
@@ -58100,6 +58139,35 @@ class UserService {
|
|
|
58100
58139
|
timeback: timeback2
|
|
58101
58140
|
};
|
|
58102
58141
|
}
|
|
58142
|
+
async getDemoProfile(userId) {
|
|
58143
|
+
const userData = await this.deps.db.query.users.findFirst({
|
|
58144
|
+
where: eq(users.id, userId),
|
|
58145
|
+
columns: { name: true }
|
|
58146
|
+
});
|
|
58147
|
+
if (!userData) {
|
|
58148
|
+
logger32.error("Demo user not found", { userId });
|
|
58149
|
+
throw new NotFoundError("User", userId);
|
|
58150
|
+
}
|
|
58151
|
+
return {
|
|
58152
|
+
displayName: userData.name,
|
|
58153
|
+
isDefault: userData.name === DEMO_DISPLAY_NAME_PLACEHOLDER
|
|
58154
|
+
};
|
|
58155
|
+
}
|
|
58156
|
+
async updateDemoProfile(userId, displayName) {
|
|
58157
|
+
const [updatedUser] = await this.deps.db.update(users).set({
|
|
58158
|
+
name: displayName,
|
|
58159
|
+
updatedAt: new Date
|
|
58160
|
+
}).where(eq(users.id, userId)).returning({ name: users.name });
|
|
58161
|
+
if (!updatedUser) {
|
|
58162
|
+
logger32.error("Demo user not found for profile update", { userId });
|
|
58163
|
+
throw new NotFoundError("User", userId);
|
|
58164
|
+
}
|
|
58165
|
+
logger32.debug("Updated demo profile", { userId, displayName });
|
|
58166
|
+
return {
|
|
58167
|
+
displayName: updatedUser.name,
|
|
58168
|
+
isDefault: updatedUser.name === DEMO_DISPLAY_NAME_PLACEHOLDER
|
|
58169
|
+
};
|
|
58170
|
+
}
|
|
58103
58171
|
async fetchTimebackData(timebackId, gameId) {
|
|
58104
58172
|
const [{ role, organizations: allOrganizations }, allEnrollments] = await Promise.all([
|
|
58105
58173
|
this.fetchStudentProfile(timebackId),
|
|
@@ -58192,6 +58260,7 @@ class UserService {
|
|
|
58192
58260
|
var logger32;
|
|
58193
58261
|
var init_user_service = __esm(() => {
|
|
58194
58262
|
init_drizzle_orm();
|
|
58263
|
+
init_src();
|
|
58195
58264
|
init_tables_index();
|
|
58196
58265
|
init_src2();
|
|
58197
58266
|
init_errors();
|
|
@@ -119909,7 +119978,11 @@ var init_drizzle_zod = __esm(() => {
|
|
|
119909
119978
|
nullable: (column6) => !column6.notNull
|
|
119910
119979
|
};
|
|
119911
119980
|
});
|
|
119981
|
+
function normalizeDisplayName(value) {
|
|
119982
|
+
return value.trim().replace(/\s+/g, " ");
|
|
119983
|
+
}
|
|
119912
119984
|
var InsertUserSchema;
|
|
119985
|
+
var DemoProfileSchema;
|
|
119913
119986
|
var init_schemas = __esm(() => {
|
|
119914
119987
|
init_drizzle_zod();
|
|
119915
119988
|
init_esm();
|
|
@@ -119918,6 +119991,9 @@ var init_schemas = __esm(() => {
|
|
|
119918
119991
|
email: exports_external.string().email(),
|
|
119919
119992
|
name: exports_external.string().optional()
|
|
119920
119993
|
});
|
|
119994
|
+
DemoProfileSchema = exports_external.object({
|
|
119995
|
+
displayName: exports_external.string().transform(normalizeDisplayName).refine((value) => value.length >= 2, "Display name must be at least 2 characters").refine((value) => value.length <= 12, "Display name must be 12 characters or fewer")
|
|
119996
|
+
});
|
|
119921
119997
|
});
|
|
119922
119998
|
var InsertGameSchema;
|
|
119923
119999
|
var UpdateGameSchema;
|
|
@@ -120572,6 +120648,28 @@ function requireAuth(handler) {
|
|
|
120572
120648
|
return handler(ctx);
|
|
120573
120649
|
};
|
|
120574
120650
|
}
|
|
120651
|
+
function requireNonAnonymous(handler) {
|
|
120652
|
+
return async (ctx) => {
|
|
120653
|
+
if (!isAuthenticated(ctx)) {
|
|
120654
|
+
throw ApiError.unauthorized("Valid session or bearer token required");
|
|
120655
|
+
}
|
|
120656
|
+
if (ctx.user.isAnonymous) {
|
|
120657
|
+
throw ApiError.forbidden("This operation is not available for demo/anonymous users");
|
|
120658
|
+
}
|
|
120659
|
+
return handler(ctx);
|
|
120660
|
+
};
|
|
120661
|
+
}
|
|
120662
|
+
function requireAnonymous(handler) {
|
|
120663
|
+
return async (ctx) => {
|
|
120664
|
+
if (!isAuthenticated(ctx)) {
|
|
120665
|
+
throw ApiError.unauthorized("Valid session or bearer token required");
|
|
120666
|
+
}
|
|
120667
|
+
if (!ctx.user.isAnonymous) {
|
|
120668
|
+
throw ApiError.forbidden("This operation is only available for demo/anonymous users");
|
|
120669
|
+
}
|
|
120670
|
+
return handler(ctx);
|
|
120671
|
+
};
|
|
120672
|
+
}
|
|
120575
120673
|
function requireRole(roles2, handler) {
|
|
120576
120674
|
return async (ctx) => {
|
|
120577
120675
|
if (!isAuthenticated(ctx)) {
|
|
@@ -120806,16 +120904,16 @@ var init_achievement_controller = __esm(() => {
|
|
|
120806
120904
|
init_errors();
|
|
120807
120905
|
init_utils11();
|
|
120808
120906
|
logger37 = log.scope("AchievementController");
|
|
120809
|
-
listCurrent =
|
|
120907
|
+
listCurrent = requireNonAnonymous(async (ctx) => {
|
|
120810
120908
|
logger37.debug("Listing current achievements", { userId: ctx.user.id, gameId: ctx.gameId });
|
|
120811
120909
|
return ctx.services.achievement.listCurrent(ctx.user, ctx.gameId);
|
|
120812
120910
|
});
|
|
120813
|
-
listHistory =
|
|
120911
|
+
listHistory = requireNonAnonymous(async (ctx) => {
|
|
120814
120912
|
const limit = Math.max(1, Math.min(100, Number(ctx.url.searchParams.get("limit")) || 20));
|
|
120815
120913
|
logger37.debug("Listing achievement history", { userId: ctx.user.id, limit });
|
|
120816
120914
|
return ctx.services.achievement.listHistory(ctx.user, limit);
|
|
120817
120915
|
});
|
|
120818
|
-
postProgress =
|
|
120916
|
+
postProgress = requireNonAnonymous(async (ctx) => {
|
|
120819
120917
|
let body2;
|
|
120820
120918
|
try {
|
|
120821
120919
|
const json4 = await ctx.request.json();
|
|
@@ -120976,11 +121074,11 @@ var init_character_controller = __esm(() => {
|
|
|
120976
121074
|
init_errors();
|
|
120977
121075
|
init_utils11();
|
|
120978
121076
|
logger40 = log.scope("CharacterController");
|
|
120979
|
-
get =
|
|
121077
|
+
get = requireNonAnonymous(async (ctx) => {
|
|
120980
121078
|
logger40.debug("Getting character", { userId: ctx.user.id });
|
|
120981
121079
|
return ctx.services.character.getByUser(ctx.user);
|
|
120982
121080
|
});
|
|
120983
|
-
getByUserId =
|
|
121081
|
+
getByUserId = requireNonAnonymous(async (ctx) => {
|
|
120984
121082
|
const userId = ctx.params.userId;
|
|
120985
121083
|
if (!userId) {
|
|
120986
121084
|
throw ApiError.badRequest("User ID is required in the URL path");
|
|
@@ -120988,7 +121086,7 @@ var init_character_controller = __esm(() => {
|
|
|
120988
121086
|
logger40.debug("Getting character by user ID", { requestedUserId: userId });
|
|
120989
121087
|
return ctx.services.character.getByUserId(userId);
|
|
120990
121088
|
});
|
|
120991
|
-
create =
|
|
121089
|
+
create = requireNonAnonymous(async (ctx) => {
|
|
120992
121090
|
let body2;
|
|
120993
121091
|
try {
|
|
120994
121092
|
const json4 = await ctx.request.json();
|
|
@@ -121008,7 +121106,7 @@ var init_character_controller = __esm(() => {
|
|
|
121008
121106
|
});
|
|
121009
121107
|
return ctx.services.character.create(body2, ctx.user);
|
|
121010
121108
|
});
|
|
121011
|
-
update2 =
|
|
121109
|
+
update2 = requireNonAnonymous(async (ctx) => {
|
|
121012
121110
|
let body2;
|
|
121013
121111
|
try {
|
|
121014
121112
|
const json4 = await ctx.request.json();
|
|
@@ -121029,7 +121127,7 @@ var init_character_controller = __esm(() => {
|
|
|
121029
121127
|
});
|
|
121030
121128
|
return ctx.services.character.update(body2, ctx.user);
|
|
121031
121129
|
});
|
|
121032
|
-
equipAccessory =
|
|
121130
|
+
equipAccessory = requireNonAnonymous(async (ctx) => {
|
|
121033
121131
|
let body2;
|
|
121034
121132
|
try {
|
|
121035
121133
|
const json4 = await ctx.request.json();
|
|
@@ -121049,7 +121147,7 @@ var init_character_controller = __esm(() => {
|
|
|
121049
121147
|
});
|
|
121050
121148
|
return ctx.services.character.equipAccessory(body2.slot, body2.accessoryComponentId, ctx.user);
|
|
121051
121149
|
});
|
|
121052
|
-
removeAccessory =
|
|
121150
|
+
removeAccessory = requireNonAnonymous(async (ctx) => {
|
|
121053
121151
|
const slot = ctx.params.slot;
|
|
121054
121152
|
if (!slot) {
|
|
121055
121153
|
throw ApiError.badRequest("Slot is required in the URL path");
|
|
@@ -121083,11 +121181,11 @@ var init_currency_controller = __esm(() => {
|
|
|
121083
121181
|
init_errors();
|
|
121084
121182
|
init_utils11();
|
|
121085
121183
|
logger41 = log.scope("CurrencyController");
|
|
121086
|
-
list =
|
|
121184
|
+
list = requireNonAnonymous(async (ctx) => {
|
|
121087
121185
|
logger41.debug("Listing currencies", { userId: ctx.user.id });
|
|
121088
121186
|
return ctx.services.currency.list();
|
|
121089
121187
|
});
|
|
121090
|
-
getById =
|
|
121188
|
+
getById = requireNonAnonymous(async (ctx) => {
|
|
121091
121189
|
const currencyId = ctx.params.currencyId;
|
|
121092
121190
|
if (!currencyId) {
|
|
121093
121191
|
throw ApiError.badRequest("Missing currency ID");
|
|
@@ -121261,11 +121359,11 @@ var init_developer_controller = __esm(() => {
|
|
|
121261
121359
|
init_src2();
|
|
121262
121360
|
init_utils11();
|
|
121263
121361
|
logger44 = log.scope("DeveloperController");
|
|
121264
|
-
apply =
|
|
121362
|
+
apply = requireNonAnonymous(async (ctx) => {
|
|
121265
121363
|
logger44.debug("Applying for developer status", { userId: ctx.user.id });
|
|
121266
121364
|
await ctx.services.developer.apply(ctx.user);
|
|
121267
121365
|
});
|
|
121268
|
-
getStatus =
|
|
121366
|
+
getStatus = requireNonAnonymous(async (ctx) => {
|
|
121269
121367
|
logger44.debug("Getting developer status", { userId: ctx.user.id });
|
|
121270
121368
|
const status = await ctx.services.developer.getStatus(ctx.user.id);
|
|
121271
121369
|
return { status };
|
|
@@ -121377,19 +121475,19 @@ var init_game_controller = __esm(() => {
|
|
|
121377
121475
|
init_errors();
|
|
121378
121476
|
init_utils11();
|
|
121379
121477
|
logger46 = log.scope("GameController");
|
|
121380
|
-
list3 =
|
|
121478
|
+
list3 = requireNonAnonymous(async (ctx) => {
|
|
121381
121479
|
logger46.debug("Listing games", { userId: ctx.user.id });
|
|
121382
121480
|
return ctx.services.game.list(ctx.user);
|
|
121383
121481
|
});
|
|
121384
|
-
listManageable =
|
|
121482
|
+
listManageable = requireNonAnonymous(async (ctx) => {
|
|
121385
121483
|
logger46.debug("Listing manageable games", { userId: ctx.user.id });
|
|
121386
121484
|
return ctx.services.game.listManageable(ctx.user);
|
|
121387
121485
|
});
|
|
121388
|
-
getSubjects =
|
|
121486
|
+
getSubjects = requireNonAnonymous(async (ctx) => {
|
|
121389
121487
|
logger46.debug("Getting game subjects", { userId: ctx.user.id });
|
|
121390
121488
|
return ctx.services.game.getSubjects();
|
|
121391
121489
|
});
|
|
121392
|
-
getById2 =
|
|
121490
|
+
getById2 = requireNonAnonymous(async (ctx) => {
|
|
121393
121491
|
const gameId = ctx.params.gameId;
|
|
121394
121492
|
if (!gameId) {
|
|
121395
121493
|
throw ApiError.badRequest("Missing game ID");
|
|
@@ -121400,7 +121498,7 @@ var init_game_controller = __esm(() => {
|
|
|
121400
121498
|
logger46.debug("Getting game by ID", { userId: ctx.user.id, gameId, launchId: ctx.launchId });
|
|
121401
121499
|
return ctx.services.game.getById(gameId, ctx.user);
|
|
121402
121500
|
});
|
|
121403
|
-
getBySlug =
|
|
121501
|
+
getBySlug = requireNonAnonymous(async (ctx) => {
|
|
121404
121502
|
const slug2 = ctx.params.slug;
|
|
121405
121503
|
if (!slug2) {
|
|
121406
121504
|
throw ApiError.badRequest("Missing game slug");
|
|
@@ -121408,7 +121506,7 @@ var init_game_controller = __esm(() => {
|
|
|
121408
121506
|
logger46.debug("Getting game by slug", { userId: ctx.user.id, slug: slug2, launchId: ctx.launchId });
|
|
121409
121507
|
return ctx.services.game.getBySlug(slug2, ctx.user);
|
|
121410
121508
|
});
|
|
121411
|
-
getManifest =
|
|
121509
|
+
getManifest = requireNonAnonymous(async (ctx) => {
|
|
121412
121510
|
const gameId = ctx.params.gameId;
|
|
121413
121511
|
if (!gameId) {
|
|
121414
121512
|
throw ApiError.badRequest("Missing game ID");
|
|
@@ -121423,7 +121521,7 @@ var init_game_controller = __esm(() => {
|
|
|
121423
121521
|
});
|
|
121424
121522
|
return ctx.services.game.getManifest(gameId, ctx.user);
|
|
121425
121523
|
});
|
|
121426
|
-
upsertBySlug =
|
|
121524
|
+
upsertBySlug = requireNonAnonymous(async (ctx) => {
|
|
121427
121525
|
const slug2 = ctx.params.slug;
|
|
121428
121526
|
if (!slug2) {
|
|
121429
121527
|
throw ApiError.badRequest("Missing game slug");
|
|
@@ -121443,7 +121541,7 @@ var init_game_controller = __esm(() => {
|
|
|
121443
121541
|
logger46.debug("Upserting game", { userId: ctx.user.id, slug: slug2, displayName: body2.displayName });
|
|
121444
121542
|
return ctx.services.game.upsertBySlug(slug2, body2, ctx.user);
|
|
121445
121543
|
});
|
|
121446
|
-
remove3 =
|
|
121544
|
+
remove3 = requireNonAnonymous(async (ctx) => {
|
|
121447
121545
|
const gameId = ctx.params.gameId;
|
|
121448
121546
|
if (!gameId) {
|
|
121449
121547
|
throw ApiError.badRequest("Missing game ID");
|
|
@@ -121477,11 +121575,11 @@ var init_inventory_controller = __esm(() => {
|
|
|
121477
121575
|
init_errors();
|
|
121478
121576
|
init_utils11();
|
|
121479
121577
|
logger47 = log.scope("InventoryController");
|
|
121480
|
-
list4 =
|
|
121578
|
+
list4 = requireNonAnonymous(async (ctx) => {
|
|
121481
121579
|
logger47.debug("Listing inventory", { userId: ctx.user.id });
|
|
121482
121580
|
return ctx.services.inventory.list(ctx.user);
|
|
121483
121581
|
});
|
|
121484
|
-
addItem =
|
|
121582
|
+
addItem = requireNonAnonymous(async (ctx) => {
|
|
121485
121583
|
let body2;
|
|
121486
121584
|
try {
|
|
121487
121585
|
const json4 = await ctx.request.json();
|
|
@@ -121501,7 +121599,7 @@ var init_inventory_controller = __esm(() => {
|
|
|
121501
121599
|
});
|
|
121502
121600
|
return ctx.services.inventory.addItem(body2.itemId, body2.qty, ctx.user);
|
|
121503
121601
|
});
|
|
121504
|
-
removeItem =
|
|
121602
|
+
removeItem = requireNonAnonymous(async (ctx) => {
|
|
121505
121603
|
let body2;
|
|
121506
121604
|
try {
|
|
121507
121605
|
const json4 = await ctx.request.json();
|
|
@@ -121547,12 +121645,12 @@ var init_item_controller = __esm(() => {
|
|
|
121547
121645
|
init_errors();
|
|
121548
121646
|
init_utils11();
|
|
121549
121647
|
logger48 = log.scope("ItemController");
|
|
121550
|
-
list5 =
|
|
121648
|
+
list5 = requireNonAnonymous(async (ctx) => {
|
|
121551
121649
|
const gameId = ctx.url.searchParams.get("gameId") || undefined;
|
|
121552
121650
|
logger48.debug("Listing items", { userId: ctx.user.id, gameId });
|
|
121553
121651
|
return ctx.services.item.list(gameId);
|
|
121554
121652
|
});
|
|
121555
|
-
getById3 =
|
|
121653
|
+
getById3 = requireNonAnonymous(async (ctx) => {
|
|
121556
121654
|
const itemId = ctx.params.itemId;
|
|
121557
121655
|
if (!itemId) {
|
|
121558
121656
|
throw ApiError.badRequest("Missing item ID");
|
|
@@ -121563,7 +121661,7 @@ var init_item_controller = __esm(() => {
|
|
|
121563
121661
|
logger48.debug("Getting item", { userId: ctx.user.id, itemId });
|
|
121564
121662
|
return ctx.services.item.getById(itemId);
|
|
121565
121663
|
});
|
|
121566
|
-
resolve2 =
|
|
121664
|
+
resolve2 = requireNonAnonymous(async (ctx) => {
|
|
121567
121665
|
const slug2 = ctx.url.searchParams.get("slug");
|
|
121568
121666
|
const gameId = ctx.url.searchParams.get("gameId") || undefined;
|
|
121569
121667
|
if (!slug2) {
|
|
@@ -121638,7 +121736,7 @@ var init_item_controller = __esm(() => {
|
|
|
121638
121736
|
logger48.debug("Deleting item", { userId: ctx.user.id, itemId });
|
|
121639
121737
|
await ctx.services.item.delete(itemId);
|
|
121640
121738
|
});
|
|
121641
|
-
listByGame =
|
|
121739
|
+
listByGame = requireNonAnonymous(async (ctx) => {
|
|
121642
121740
|
const gameId = ctx.params.gameId;
|
|
121643
121741
|
if (!gameId) {
|
|
121644
121742
|
throw ApiError.badRequest("Missing game ID");
|
|
@@ -121649,7 +121747,7 @@ var init_item_controller = __esm(() => {
|
|
|
121649
121747
|
logger48.debug("Listing game items", { userId: ctx.user.id, gameId });
|
|
121650
121748
|
return ctx.services.item.listByGame(gameId);
|
|
121651
121749
|
});
|
|
121652
|
-
createForGame =
|
|
121750
|
+
createForGame = requireNonAnonymous(async (ctx) => {
|
|
121653
121751
|
const gameId = ctx.params.gameId;
|
|
121654
121752
|
if (!gameId) {
|
|
121655
121753
|
throw ApiError.badRequest("Missing game ID");
|
|
@@ -121677,7 +121775,7 @@ var init_item_controller = __esm(() => {
|
|
|
121677
121775
|
});
|
|
121678
121776
|
return ctx.services.item.createForGame(gameId, body2, ctx.user);
|
|
121679
121777
|
});
|
|
121680
|
-
updateForGame =
|
|
121778
|
+
updateForGame = requireNonAnonymous(async (ctx) => {
|
|
121681
121779
|
const gameId = ctx.params.gameId;
|
|
121682
121780
|
const itemId = ctx.params.itemId;
|
|
121683
121781
|
if (!gameId || !itemId) {
|
|
@@ -121714,7 +121812,7 @@ var init_item_controller = __esm(() => {
|
|
|
121714
121812
|
});
|
|
121715
121813
|
return ctx.services.item.updateForGame(gameId, itemId, body2, ctx.user);
|
|
121716
121814
|
});
|
|
121717
|
-
deleteForGame =
|
|
121815
|
+
deleteForGame = requireNonAnonymous(async (ctx) => {
|
|
121718
121816
|
const gameId = ctx.params.gameId;
|
|
121719
121817
|
const itemId = ctx.params.itemId;
|
|
121720
121818
|
if (!gameId || !itemId) {
|
|
@@ -121889,7 +121987,7 @@ var init_leaderboard_controller = __esm(() => {
|
|
|
121889
121987
|
gameId,
|
|
121890
121988
|
score: body2.score
|
|
121891
121989
|
});
|
|
121892
|
-
return ctx.services.leaderboard.submitScore(gameId, ctx.user.id, { score: body2.score, metadata: body2.metadata }, ctx.params.sessionId);
|
|
121990
|
+
return ctx.services.leaderboard.submitScore(gameId, ctx.user.id, { score: body2.score, metadata: body2.metadata }, ctx.user.isAnonymous, ctx.params.sessionId);
|
|
121893
121991
|
});
|
|
121894
121992
|
getGlobalLeaderboard = requireAuth(async (ctx) => {
|
|
121895
121993
|
const url = ctx.url;
|
|
@@ -121917,7 +122015,7 @@ var init_leaderboard_controller = __esm(() => {
|
|
|
121917
122015
|
gameId,
|
|
121918
122016
|
...query
|
|
121919
122017
|
});
|
|
121920
|
-
return ctx.services.leaderboard.getGlobalLeaderboard(gameId, query);
|
|
122018
|
+
return ctx.services.leaderboard.getGlobalLeaderboard(gameId, query, ctx.user.isAnonymous);
|
|
121921
122019
|
});
|
|
121922
122020
|
getLeaderboard = requireAuth(async (ctx) => {
|
|
121923
122021
|
const gameId = ctx.params.gameId;
|
|
@@ -121945,9 +122043,9 @@ var init_leaderboard_controller = __esm(() => {
|
|
|
121945
122043
|
gameId,
|
|
121946
122044
|
...query
|
|
121947
122045
|
});
|
|
121948
|
-
return ctx.services.leaderboard.getLeaderboard(gameId, query);
|
|
122046
|
+
return ctx.services.leaderboard.getLeaderboard(gameId, query, ctx.user.isAnonymous);
|
|
121949
122047
|
});
|
|
121950
|
-
getUserRank =
|
|
122048
|
+
getUserRank = requireNonAnonymous(async (ctx) => {
|
|
121951
122049
|
const { gameId, userId } = ctx.params;
|
|
121952
122050
|
if (!gameId || !userId) {
|
|
121953
122051
|
throw ApiError.badRequest("Game ID and User ID are required");
|
|
@@ -121957,9 +122055,9 @@ var init_leaderboard_controller = __esm(() => {
|
|
|
121957
122055
|
gameId,
|
|
121958
122056
|
targetUserId: userId
|
|
121959
122057
|
});
|
|
121960
|
-
return ctx.services.leaderboard.getUserRank(gameId, userId);
|
|
122058
|
+
return ctx.services.leaderboard.getUserRank(gameId, userId, ctx.user.isAnonymous);
|
|
121961
122059
|
});
|
|
121962
|
-
getUserAllScores =
|
|
122060
|
+
getUserAllScores = requireNonAnonymous(async (ctx) => {
|
|
121963
122061
|
const userId = ctx.params.userId;
|
|
121964
122062
|
if (!userId) {
|
|
121965
122063
|
throw ApiError.badRequest("User ID is required");
|
|
@@ -121975,7 +122073,7 @@ var init_leaderboard_controller = __esm(() => {
|
|
|
121975
122073
|
});
|
|
121976
122074
|
return ctx.services.leaderboard.getUserAllScores(userId, { limit, gameId });
|
|
121977
122075
|
});
|
|
121978
|
-
getUserScores =
|
|
122076
|
+
getUserScores = requireNonAnonymous(async (ctx) => {
|
|
121979
122077
|
const { gameId, userId } = ctx.params;
|
|
121980
122078
|
if (!gameId || !userId) {
|
|
121981
122079
|
throw ApiError.badRequest("Game ID and User ID are required");
|
|
@@ -122024,11 +122122,11 @@ var init_level_controller = __esm(() => {
|
|
|
122024
122122
|
init_errors();
|
|
122025
122123
|
init_utils11();
|
|
122026
122124
|
logger51 = log.scope("LevelController");
|
|
122027
|
-
getByUser =
|
|
122125
|
+
getByUser = requireNonAnonymous(async (ctx) => {
|
|
122028
122126
|
logger51.debug("Getting user level", { userId: ctx.user.id });
|
|
122029
122127
|
return ctx.services.level.getByUser(ctx.user);
|
|
122030
122128
|
});
|
|
122031
|
-
getProgress =
|
|
122129
|
+
getProgress = requireNonAnonymous(async (ctx) => {
|
|
122032
122130
|
logger51.debug("Getting level progress", { userId: ctx.user.id });
|
|
122033
122131
|
return ctx.services.level.getProgress(ctx.user);
|
|
122034
122132
|
});
|
|
@@ -122083,7 +122181,7 @@ var init_lti_controller = __esm(() => {
|
|
|
122083
122181
|
init_src2();
|
|
122084
122182
|
init_utils11();
|
|
122085
122183
|
logger53 = log.scope("LtiController");
|
|
122086
|
-
getStatus3 =
|
|
122184
|
+
getStatus3 = requireNonAnonymous(async (ctx) => {
|
|
122087
122185
|
logger53.debug("Getting status", { userId: ctx.user.id });
|
|
122088
122186
|
return ctx.services.lti.getStatus(ctx.user);
|
|
122089
122187
|
});
|
|
@@ -122106,7 +122204,7 @@ var init_map_controller = __esm(() => {
|
|
|
122106
122204
|
init_errors();
|
|
122107
122205
|
init_utils11();
|
|
122108
122206
|
logger54 = log.scope("MapController");
|
|
122109
|
-
getByIdentifier =
|
|
122207
|
+
getByIdentifier = requireNonAnonymous(async (ctx) => {
|
|
122110
122208
|
const identifier = ctx.params.identifier;
|
|
122111
122209
|
if (!identifier) {
|
|
122112
122210
|
throw ApiError.badRequest("Missing map identifier");
|
|
@@ -122114,7 +122212,7 @@ var init_map_controller = __esm(() => {
|
|
|
122114
122212
|
logger54.debug("Getting map", { userId: ctx.user.id, identifier });
|
|
122115
122213
|
return ctx.services.map.getByIdentifier(identifier);
|
|
122116
122214
|
});
|
|
122117
|
-
getElements =
|
|
122215
|
+
getElements = requireNonAnonymous(async (ctx) => {
|
|
122118
122216
|
const mapId = ctx.url.searchParams.get("mapId");
|
|
122119
122217
|
if (!mapId) {
|
|
122120
122218
|
throw ApiError.badRequest("Missing required query parameter: mapId");
|
|
@@ -122125,7 +122223,7 @@ var init_map_controller = __esm(() => {
|
|
|
122125
122223
|
logger54.debug("Getting map elements", { userId: ctx.user.id, mapId });
|
|
122126
122224
|
return ctx.services.map.getElements(mapId);
|
|
122127
122225
|
});
|
|
122128
|
-
getObjects =
|
|
122226
|
+
getObjects = requireNonAnonymous(async (ctx) => {
|
|
122129
122227
|
const mapId = ctx.params.mapId;
|
|
122130
122228
|
if (!mapId) {
|
|
122131
122229
|
throw ApiError.badRequest("Missing mapId");
|
|
@@ -122136,7 +122234,7 @@ var init_map_controller = __esm(() => {
|
|
|
122136
122234
|
logger54.debug("Getting map objects", { userId: ctx.user.id, mapId });
|
|
122137
122235
|
return ctx.services.map.getObjects(mapId, ctx.user.id);
|
|
122138
122236
|
});
|
|
122139
|
-
createObject =
|
|
122237
|
+
createObject = requireNonAnonymous(async (ctx) => {
|
|
122140
122238
|
const mapId = ctx.params.mapId;
|
|
122141
122239
|
if (!mapId) {
|
|
122142
122240
|
throw ApiError.badRequest("Missing mapId");
|
|
@@ -122170,7 +122268,7 @@ var init_map_controller = __esm(() => {
|
|
|
122170
122268
|
const { mapId: _mapId, ...data } = body2;
|
|
122171
122269
|
return ctx.services.map.createObject(mapId, data, ctx.user);
|
|
122172
122270
|
});
|
|
122173
|
-
deleteObject =
|
|
122271
|
+
deleteObject = requireNonAnonymous(async (ctx) => {
|
|
122174
122272
|
const { mapId, objectId } = ctx.params;
|
|
122175
122273
|
if (!mapId) {
|
|
122176
122274
|
throw ApiError.badRequest("Missing mapId");
|
|
@@ -122209,7 +122307,7 @@ var init_notification_controller = __esm(() => {
|
|
|
122209
122307
|
init_errors();
|
|
122210
122308
|
init_utils11();
|
|
122211
122309
|
logger55 = log.scope("NotificationController");
|
|
122212
|
-
list6 =
|
|
122310
|
+
list6 = requireNonAnonymous(async (ctx) => {
|
|
122213
122311
|
const query = {
|
|
122214
122312
|
status: ctx.url.searchParams.get("status") || undefined,
|
|
122215
122313
|
type: ctx.url.searchParams.get("type") || undefined,
|
|
@@ -122225,7 +122323,7 @@ var init_notification_controller = __esm(() => {
|
|
|
122225
122323
|
logger55.debug("Listing notifications", { userId: ctx.user.id, ...result.data });
|
|
122226
122324
|
return ctx.services.notification.list(ctx.user, result.data);
|
|
122227
122325
|
});
|
|
122228
|
-
updateStatus =
|
|
122326
|
+
updateStatus = requireNonAnonymous(async (ctx) => {
|
|
122229
122327
|
const notificationId = ctx.params.notificationId;
|
|
122230
122328
|
if (!notificationId) {
|
|
122231
122329
|
throw ApiError.badRequest("Notification ID required");
|
|
@@ -122249,7 +122347,7 @@ var init_notification_controller = __esm(() => {
|
|
|
122249
122347
|
});
|
|
122250
122348
|
return ctx.services.notification.updateStatus(notificationId, body2.status, body2.method);
|
|
122251
122349
|
});
|
|
122252
|
-
getStats2 =
|
|
122350
|
+
getStats2 = requireNonAnonymous(async (ctx) => {
|
|
122253
122351
|
const startDate = ctx.url.searchParams.get("startDate");
|
|
122254
122352
|
const endDate = ctx.url.searchParams.get("endDate");
|
|
122255
122353
|
logger55.debug("Getting stats", { userId: ctx.user.id, startDate, endDate });
|
|
@@ -122258,7 +122356,7 @@ var init_notification_controller = __esm(() => {
|
|
|
122258
122356
|
endDate: endDate ? new Date(endDate) : undefined
|
|
122259
122357
|
});
|
|
122260
122358
|
});
|
|
122261
|
-
create4 =
|
|
122359
|
+
create4 = requireNonAnonymous(async (ctx) => {
|
|
122262
122360
|
let body2;
|
|
122263
122361
|
try {
|
|
122264
122362
|
const json4 = await ctx.request.json();
|
|
@@ -122288,7 +122386,7 @@ var init_notification_controller = __esm(() => {
|
|
|
122288
122386
|
metadata: body2.metadata
|
|
122289
122387
|
});
|
|
122290
122388
|
});
|
|
122291
|
-
deliver =
|
|
122389
|
+
deliver = requireNonAnonymous(async (ctx) => {
|
|
122292
122390
|
logger55.debug("Delivering notifications", { userId: ctx.user.id });
|
|
122293
122391
|
try {
|
|
122294
122392
|
await ctx.services.notification.deliverPending(ctx.user.id);
|
|
@@ -122313,7 +122411,7 @@ var init_realtime_controller = __esm(() => {
|
|
|
122313
122411
|
init_src2();
|
|
122314
122412
|
init_utils11();
|
|
122315
122413
|
logger56 = log.scope("RealtimeController");
|
|
122316
|
-
generateToken2 =
|
|
122414
|
+
generateToken2 = requireNonAnonymous(async (ctx) => {
|
|
122317
122415
|
const gameIdOrSlug = ctx.params.gameId;
|
|
122318
122416
|
logger56.debug("Generating token", {
|
|
122319
122417
|
userId: ctx.user.id,
|
|
@@ -122482,7 +122580,7 @@ var init_shop_controller = __esm(() => {
|
|
|
122482
122580
|
init_src2();
|
|
122483
122581
|
init_utils11();
|
|
122484
122582
|
logger60 = log.scope("ShopController");
|
|
122485
|
-
getShopView =
|
|
122583
|
+
getShopView = requireNonAnonymous(async (ctx) => {
|
|
122486
122584
|
logger60.debug("Getting shop view", { userId: ctx.user.id });
|
|
122487
122585
|
return ctx.services.shop.getShopView(ctx.user);
|
|
122488
122586
|
});
|
|
@@ -122586,7 +122684,7 @@ var init_shop_listing_controller = __esm(() => {
|
|
|
122586
122684
|
logger61.debug("Deleting listing", { userId: ctx.user.id, listingId });
|
|
122587
122685
|
await ctx.services.shopListing.delete(listingId);
|
|
122588
122686
|
});
|
|
122589
|
-
listByGame2 =
|
|
122687
|
+
listByGame2 = requireNonAnonymous(async (ctx) => {
|
|
122590
122688
|
const gameId = ctx.params.gameId;
|
|
122591
122689
|
if (!gameId) {
|
|
122592
122690
|
throw ApiError.badRequest("Missing game ID");
|
|
@@ -122597,7 +122695,7 @@ var init_shop_listing_controller = __esm(() => {
|
|
|
122597
122695
|
logger61.debug("Listing game listings", { userId: ctx.user.id, gameId });
|
|
122598
122696
|
return ctx.services.shopListing.listByGame(gameId, ctx.user);
|
|
122599
122697
|
});
|
|
122600
|
-
getByGameItem =
|
|
122698
|
+
getByGameItem = requireNonAnonymous(async (ctx) => {
|
|
122601
122699
|
const gameId = ctx.params.gameId;
|
|
122602
122700
|
const itemId = ctx.params.itemId;
|
|
122603
122701
|
if (!gameId || !itemId) {
|
|
@@ -122612,7 +122710,7 @@ var init_shop_listing_controller = __esm(() => {
|
|
|
122612
122710
|
logger61.debug("Getting game item listing", { userId: ctx.user.id, gameId, itemId });
|
|
122613
122711
|
return ctx.services.shopListing.getByGameItem(gameId, itemId, ctx.user);
|
|
122614
122712
|
});
|
|
122615
|
-
createForGameItem =
|
|
122713
|
+
createForGameItem = requireNonAnonymous(async (ctx) => {
|
|
122616
122714
|
const gameId = ctx.params.gameId;
|
|
122617
122715
|
const itemId = ctx.params.itemId;
|
|
122618
122716
|
if (!gameId || !itemId) {
|
|
@@ -122645,7 +122743,7 @@ var init_shop_listing_controller = __esm(() => {
|
|
|
122645
122743
|
});
|
|
122646
122744
|
return ctx.services.shopListing.createForGameItem(gameId, itemId, body2, ctx.user);
|
|
122647
122745
|
});
|
|
122648
|
-
updateForGameItem =
|
|
122746
|
+
updateForGameItem = requireNonAnonymous(async (ctx) => {
|
|
122649
122747
|
const gameId = ctx.params.gameId;
|
|
122650
122748
|
const itemId = ctx.params.itemId;
|
|
122651
122749
|
if (!gameId || !itemId) {
|
|
@@ -122679,7 +122777,7 @@ var init_shop_listing_controller = __esm(() => {
|
|
|
122679
122777
|
});
|
|
122680
122778
|
return ctx.services.shopListing.updateForGameItem(gameId, itemId, body2, ctx.user);
|
|
122681
122779
|
});
|
|
122682
|
-
deleteForGameItem =
|
|
122780
|
+
deleteForGameItem = requireNonAnonymous(async (ctx) => {
|
|
122683
122781
|
const gameId = ctx.params.gameId;
|
|
122684
122782
|
const itemId = ctx.params.itemId;
|
|
122685
122783
|
if (!gameId || !itemId) {
|
|
@@ -122764,17 +122862,17 @@ var init_timeback_controller = __esm(() => {
|
|
|
122764
122862
|
init_errors();
|
|
122765
122863
|
init_utils11();
|
|
122766
122864
|
logger63 = log.scope("TimebackController");
|
|
122767
|
-
getTodayXp =
|
|
122865
|
+
getTodayXp = requireNonAnonymous(async (ctx) => {
|
|
122768
122866
|
const date4 = ctx.url.searchParams.get("date") || undefined;
|
|
122769
122867
|
const tz = ctx.url.searchParams.get("tz") || undefined;
|
|
122770
122868
|
logger63.debug("Getting today XP", { userId: ctx.user.id, date: date4, tz });
|
|
122771
122869
|
return ctx.services.timeback.getTodayXp(ctx.user.id, date4, tz);
|
|
122772
122870
|
});
|
|
122773
|
-
getTotalXp =
|
|
122871
|
+
getTotalXp = requireNonAnonymous(async (ctx) => {
|
|
122774
122872
|
logger63.debug("Getting total XP", { userId: ctx.user.id });
|
|
122775
122873
|
return ctx.services.timeback.getTotalXp(ctx.user.id);
|
|
122776
122874
|
});
|
|
122777
|
-
updateTodayXp =
|
|
122875
|
+
updateTodayXp = requireNonAnonymous(async (ctx) => {
|
|
122778
122876
|
let body2;
|
|
122779
122877
|
try {
|
|
122780
122878
|
const json4 = await ctx.request.json();
|
|
@@ -122790,13 +122888,13 @@ var init_timeback_controller = __esm(() => {
|
|
|
122790
122888
|
logger63.debug("Updating today XP", { userId: ctx.user.id, xp: body2.xp });
|
|
122791
122889
|
return ctx.services.timeback.updateTodayXp(ctx.user.id, body2);
|
|
122792
122890
|
});
|
|
122793
|
-
getXpHistory =
|
|
122891
|
+
getXpHistory = requireNonAnonymous(async (ctx) => {
|
|
122794
122892
|
const startDate = ctx.url.searchParams.get("startDate") || undefined;
|
|
122795
122893
|
const endDate = ctx.url.searchParams.get("endDate") || undefined;
|
|
122796
122894
|
logger63.debug("Getting XP history", { userId: ctx.user.id, startDate, endDate });
|
|
122797
122895
|
return ctx.services.timeback.getXpHistory(ctx.user.id, startDate, endDate);
|
|
122798
122896
|
});
|
|
122799
|
-
populateStudent =
|
|
122897
|
+
populateStudent = requireNonAnonymous(async (ctx) => {
|
|
122800
122898
|
let providedNames;
|
|
122801
122899
|
try {
|
|
122802
122900
|
const json4 = await ctx.request.json();
|
|
@@ -122814,11 +122912,11 @@ var init_timeback_controller = __esm(() => {
|
|
|
122814
122912
|
});
|
|
122815
122913
|
return ctx.services.timeback.populateStudent(ctx.user, providedNames);
|
|
122816
122914
|
});
|
|
122817
|
-
getUser =
|
|
122915
|
+
getUser = requireNonAnonymous(async (ctx) => {
|
|
122818
122916
|
logger63.debug("Getting user", { userId: ctx.user.id, gameId: ctx.gameId });
|
|
122819
122917
|
return ctx.services.timeback.getUserData(ctx.user.id, ctx.gameId);
|
|
122820
122918
|
});
|
|
122821
|
-
getUserById =
|
|
122919
|
+
getUserById = requireNonAnonymous(async (ctx) => {
|
|
122822
122920
|
const timebackId = ctx.params.timebackId;
|
|
122823
122921
|
if (!timebackId) {
|
|
122824
122922
|
throw ApiError.badRequest("Missing timebackId parameter");
|
|
@@ -123216,17 +123314,34 @@ var init_upload_controller = __esm(() => {
|
|
|
123216
123314
|
});
|
|
123217
123315
|
var logger65;
|
|
123218
123316
|
var getMe;
|
|
123317
|
+
var getDemoProfile;
|
|
123318
|
+
var updateDemoProfile;
|
|
123219
123319
|
var users2;
|
|
123220
123320
|
var init_user_controller = __esm(() => {
|
|
123321
|
+
init_schemas_index();
|
|
123221
123322
|
init_src2();
|
|
123222
123323
|
init_utils11();
|
|
123223
123324
|
logger65 = log.scope("UserController");
|
|
123224
|
-
getMe =
|
|
123325
|
+
getMe = requireNonAnonymous(async (ctx) => {
|
|
123225
123326
|
logger65.debug("Getting current user", { userId: ctx.user.id, gameId: ctx.gameId });
|
|
123226
123327
|
return ctx.services.user.getMe(ctx.user, ctx.gameId);
|
|
123227
123328
|
});
|
|
123329
|
+
getDemoProfile = requireAnonymous(async (ctx) => {
|
|
123330
|
+
logger65.debug("Getting demo profile", { userId: ctx.user.id });
|
|
123331
|
+
return ctx.services.user.getDemoProfile(ctx.user.id);
|
|
123332
|
+
});
|
|
123333
|
+
updateDemoProfile = requireAnonymous(async (ctx) => {
|
|
123334
|
+
const body2 = await parseRequestBody(ctx.request, DemoProfileSchema);
|
|
123335
|
+
logger65.debug("Updating demo profile", {
|
|
123336
|
+
userId: ctx.user.id,
|
|
123337
|
+
displayName: body2.displayName
|
|
123338
|
+
});
|
|
123339
|
+
return ctx.services.user.updateDemoProfile(ctx.user.id, body2.displayName);
|
|
123340
|
+
});
|
|
123228
123341
|
users2 = {
|
|
123229
|
-
getMe
|
|
123342
|
+
getMe,
|
|
123343
|
+
getDemoProfile,
|
|
123344
|
+
updateDemoProfile
|
|
123230
123345
|
};
|
|
123231
123346
|
});
|
|
123232
123347
|
var logger66;
|
|
@@ -123422,6 +123537,8 @@ var init_users = __esm(() => {
|
|
|
123422
123537
|
}
|
|
123423
123538
|
return handle2(users2.getMe)(c2);
|
|
123424
123539
|
});
|
|
123540
|
+
usersRouter.get("/demo-profile", handle2(users2.getDemoProfile));
|
|
123541
|
+
usersRouter.patch("/demo-profile", handle2(users2.updateDemoProfile));
|
|
123425
123542
|
usersRouter.get("/level", handle2(levels.getByUser));
|
|
123426
123543
|
usersRouter.get("/level/progress", handle2(levels.getProgress));
|
|
123427
123544
|
usersRouter.get("/:userId/scores", handle2(leaderboard.getUserAllScores));
|
|
@@ -123753,6 +123870,8 @@ var init_scores = __esm(() => {
|
|
|
123753
123870
|
init_api();
|
|
123754
123871
|
gameScoresRouter = new Hono2;
|
|
123755
123872
|
gameScoresRouter.post("/:gameId/scores", handle2(leaderboard.submitScore, { status: 201 }));
|
|
123873
|
+
gameScoresRouter.get("/:gameId/leaderboard", handle2(leaderboard.getLeaderboard));
|
|
123874
|
+
gameScoresRouter.get("/:gameId/users/:userId/rank", handle2(leaderboard.getUserRank));
|
|
123756
123875
|
gameScoresRouter.get("/:gameId/users/:userId/scores", handle2(leaderboard.getUserScores));
|
|
123757
123876
|
});
|
|
123758
123877
|
var gameSecretsRouter;
|
|
@@ -124450,6 +124569,7 @@ async function startServer(port, project, options = {}) {
|
|
|
124450
124569
|
const mainServer = serve({ fetch: app.fetch, port });
|
|
124451
124570
|
return {
|
|
124452
124571
|
main: mainServer,
|
|
124572
|
+
db: db2,
|
|
124453
124573
|
gameId,
|
|
124454
124574
|
timebackMode: getTimebackDisplayMode(),
|
|
124455
124575
|
setRole: (role) => {
|
|
@@ -125201,6 +125321,7 @@ var init_achievements4 = __esm7(() => {
|
|
|
125201
125321
|
];
|
|
125202
125322
|
});
|
|
125203
125323
|
var AUTH_PROVIDER_IDS2;
|
|
125324
|
+
var DEMO_DISPLAY_NAME_PLACEHOLDER2 = "Demo Player";
|
|
125204
125325
|
var init_auth3 = __esm7(() => {
|
|
125205
125326
|
AUTH_PROVIDER_IDS2 = {
|
|
125206
125327
|
TIMEBACK: "timeback",
|
|
@@ -125285,7 +125406,8 @@ var init_overworld2 = __esm7(() => {
|
|
|
125285
125406
|
ERROR: 4000
|
|
125286
125407
|
};
|
|
125287
125408
|
CORE_GAME_UUIDS2 = {
|
|
125288
|
-
PLAYGROUND: "00000000-0000-0000-0000-000000000001"
|
|
125409
|
+
PLAYGROUND: "00000000-0000-0000-0000-000000000001",
|
|
125410
|
+
DEMO: "00000000-0000-0000-0000-000000000002"
|
|
125289
125411
|
};
|
|
125290
125412
|
});
|
|
125291
125413
|
var TIMEBACK_ROUTES2;
|
|
@@ -125359,13 +125481,15 @@ var DEMO_USER_IDS2;
|
|
|
125359
125481
|
var DEMO_USERS2;
|
|
125360
125482
|
var DEMO_USER2;
|
|
125361
125483
|
var init_demo_users2 = __esm7(() => {
|
|
125484
|
+
init_src5();
|
|
125362
125485
|
now2 = new Date;
|
|
125363
125486
|
DEMO_USER_IDS2 = {
|
|
125364
125487
|
player: "00000000-0000-0000-0000-000000000001",
|
|
125365
125488
|
developer: "00000000-0000-0000-0000-000000000002",
|
|
125366
125489
|
admin: "00000000-0000-0000-0000-000000000003",
|
|
125367
125490
|
pendingDeveloper: "00000000-0000-0000-0000-000000000004",
|
|
125368
|
-
unverifiedPlayer: "00000000-0000-0000-0000-000000000005"
|
|
125491
|
+
unverifiedPlayer: "00000000-0000-0000-0000-000000000005",
|
|
125492
|
+
anonymousPlayer: "00000000-0000-0000-0000-000000000006"
|
|
125369
125493
|
};
|
|
125370
125494
|
DEMO_USERS2 = {
|
|
125371
125495
|
admin: {
|
|
@@ -125427,6 +125551,19 @@ var init_demo_users2 = __esm7(() => {
|
|
|
125427
125551
|
developerStatus: "none",
|
|
125428
125552
|
createdAt: now2,
|
|
125429
125553
|
updatedAt: now2
|
|
125554
|
+
},
|
|
125555
|
+
anonymousPlayer: {
|
|
125556
|
+
id: DEMO_USER_IDS2.anonymousPlayer,
|
|
125557
|
+
name: DEMO_DISPLAY_NAME_PLACEHOLDER2,
|
|
125558
|
+
username: "anonymous_demo_player",
|
|
125559
|
+
email: "player@anon.demo.playcademy.gg",
|
|
125560
|
+
emailVerified: false,
|
|
125561
|
+
image: null,
|
|
125562
|
+
isAnonymous: true,
|
|
125563
|
+
role: "player",
|
|
125564
|
+
developerStatus: "none",
|
|
125565
|
+
createdAt: now2,
|
|
125566
|
+
updatedAt: now2
|
|
125430
125567
|
}
|
|
125431
125568
|
};
|
|
125432
125569
|
DEMO_USER2 = DEMO_USERS2.player;
|
|
@@ -125439,6 +125576,7 @@ var init_demo_tokens2 = __esm7(() => {
|
|
|
125439
125576
|
"sandbox-demo-token": DEMO_USERS2.player,
|
|
125440
125577
|
"sandbox-admin-token": DEMO_USERS2.admin,
|
|
125441
125578
|
"sandbox-player-token": DEMO_USERS2.player,
|
|
125579
|
+
"sandbox-anonymous-token": DEMO_USERS2.anonymousPlayer,
|
|
125442
125580
|
"sandbox-developer-token": DEMO_USERS2.developer,
|
|
125443
125581
|
"sandbox-pending-dev-token": DEMO_USERS2.pendingDeveloper,
|
|
125444
125582
|
"sandbox-unverified-token": DEMO_USERS2.unverifiedPlayer,
|
|
@@ -125447,6 +125585,7 @@ var init_demo_tokens2 = __esm7(() => {
|
|
|
125447
125585
|
};
|
|
125448
125586
|
SANDBOX_TOKENS2 = {
|
|
125449
125587
|
player: "sandbox-player-token",
|
|
125588
|
+
anonymous: "sandbox-anonymous-token",
|
|
125450
125589
|
developer: "sandbox-developer-token",
|
|
125451
125590
|
admin: "sandbox-admin-token",
|
|
125452
125591
|
pendingDeveloper: "sandbox-pending-dev-token",
|
|
@@ -125574,19 +125713,20 @@ var init_constants11 = __esm7(() => {
|
|
|
125574
125713
|
init_constants11();
|
|
125575
125714
|
|
|
125576
125715
|
// src/lib/sandbox/token.ts
|
|
125577
|
-
var
|
|
125716
|
+
var IDENTITY_TO_USER_ID = {
|
|
125578
125717
|
player: DEMO_USER_IDS2.player,
|
|
125579
125718
|
developer: DEMO_USER_IDS2.developer,
|
|
125580
|
-
admin: DEMO_USER_IDS2.admin
|
|
125719
|
+
admin: DEMO_USER_IDS2.admin,
|
|
125720
|
+
anonymous: DEMO_USER_IDS2.anonymousPlayer
|
|
125581
125721
|
};
|
|
125582
125722
|
function encode(obj) {
|
|
125583
125723
|
return btoa(JSON.stringify(obj));
|
|
125584
125724
|
}
|
|
125585
|
-
function createSandboxGameToken(gameSlug,
|
|
125725
|
+
function createSandboxGameToken(gameSlug, identity = "player") {
|
|
125586
125726
|
const header = { alg: "none", typ: "sandbox" };
|
|
125587
125727
|
const payload = {
|
|
125588
125728
|
sub: gameSlug,
|
|
125589
|
-
uid:
|
|
125729
|
+
uid: IDENTITY_TO_USER_ID[identity],
|
|
125590
125730
|
iat: Math.floor(Date.now() / 1000)
|
|
125591
125731
|
};
|
|
125592
125732
|
return `${encode(header)}.${encode(payload)}.sandbox`;
|
|
@@ -125658,6 +125798,7 @@ var shell_default = `<!doctype html>
|
|
|
125658
125798
|
gameId: '{{GAME_ID}}',
|
|
125659
125799
|
gameToken: '{{GAME_TOKEN}}',
|
|
125660
125800
|
gameUrl: '{{GAME_URL}}' || undefined,
|
|
125801
|
+
mode: '{{MODE}}',
|
|
125661
125802
|
timebackJson: '{{TIMEBACK_DATA}}',
|
|
125662
125803
|
hideBadge: '{{HIDE_BADGE}}' === 'true',
|
|
125663
125804
|
}
|
|
@@ -125680,10 +125821,13 @@ var shell_default = `<!doctype html>
|
|
|
125680
125821
|
const log = (...args) => window.PLAYCADEMY_DEBUG && console.log('[DevShell]', ...args)
|
|
125681
125822
|
|
|
125682
125823
|
async function checkSandbox() {
|
|
125824
|
+
// Use the public /health endpoint as a pure liveness probe.
|
|
125825
|
+
// We used to hit /api/users/me here, but that's \`requireNonAnonymous\`
|
|
125826
|
+
// and 403s in demo mode (anonymous cohort) even when the sandbox
|
|
125827
|
+
// is perfectly healthy. /health is auth-bypassed and is all we
|
|
125828
|
+
// actually need for a reachability check.
|
|
125683
125829
|
try {
|
|
125684
|
-
const res = await fetch(\`\${CONFIG.sandboxUrl}/
|
|
125685
|
-
headers: { Authorization: \`Bearer \${CONFIG.gameToken}\` },
|
|
125686
|
-
})
|
|
125830
|
+
const res = await fetch(\`\${CONFIG.sandboxUrl}/health\`)
|
|
125687
125831
|
if (!res.ok) throw new Error('Sandbox unavailable')
|
|
125688
125832
|
badge.classList.remove('offline')
|
|
125689
125833
|
log('Sandbox connected')
|
|
@@ -125702,6 +125846,7 @@ var shell_default = `<!doctype html>
|
|
|
125702
125846
|
gameUrl: CONFIG.gameUrl,
|
|
125703
125847
|
gameId: CONFIG.gameId,
|
|
125704
125848
|
token: CONFIG.gameToken,
|
|
125849
|
+
mode: CONFIG.mode,
|
|
125705
125850
|
timeback: timebackData,
|
|
125706
125851
|
}
|
|
125707
125852
|
|
|
@@ -125756,15 +125901,17 @@ var shell_default = `<!doctype html>
|
|
|
125756
125901
|
`;
|
|
125757
125902
|
|
|
125758
125903
|
// src/server/middleware.ts
|
|
125759
|
-
function generateLoaderHTML(sandboxUrl, gameSlug, options, gameUrl) {
|
|
125904
|
+
function generateLoaderHTML(sandboxUrl, gameSlug, gameId, options, gameUrl) {
|
|
125760
125905
|
const timebackJson = generateTimebackJson(options.timeback);
|
|
125761
|
-
const
|
|
125762
|
-
const
|
|
125763
|
-
|
|
125906
|
+
const mode = getCurrentMode();
|
|
125907
|
+
const tokenIdentity = mode === "demo" ? "anonymous" : getPlatformRoleOverride() ?? "player";
|
|
125908
|
+
const gameToken = createSandboxGameToken(gameSlug, tokenIdentity);
|
|
125909
|
+
const handshakeGameId = gameId || gameSlug;
|
|
125910
|
+
return shell_default.replace(/{{SANDBOX_URL}}/g, sandboxUrl).replace(/{{GAME_ID}}/g, handshakeGameId).replace(/{{GAME_TOKEN}}/g, gameToken).replace(/{{GAME_URL}}/g, gameUrl || "").replace(/{{MODE}}/g, isShellMode(mode) ? mode : "platform").replace(/{{TIMEBACK_DATA}}/g, timebackJson).replace(/{{HIDE_BADGE}}/g, String(options.hideBadge));
|
|
125764
125911
|
}
|
|
125765
125912
|
function devServerMiddleware(server, sandbox, gameUrl, options) {
|
|
125766
125913
|
server.middlewares.use("/", (req, res, next) => {
|
|
125767
|
-
if (getCurrentMode()
|
|
125914
|
+
if (!isShellMode(getCurrentMode())) {
|
|
125768
125915
|
next();
|
|
125769
125916
|
return;
|
|
125770
125917
|
}
|
|
@@ -125774,7 +125921,7 @@ function devServerMiddleware(server, sandbox, gameUrl, options) {
|
|
|
125774
125921
|
next();
|
|
125775
125922
|
} else {
|
|
125776
125923
|
res.setHeader("Content-Type", "text/html");
|
|
125777
|
-
res.end(generateLoaderHTML(sandbox.baseUrl, sandbox.project?.slug ?? "", options, gameUrl));
|
|
125924
|
+
res.end(generateLoaderHTML(sandbox.baseUrl, sandbox.project?.slug ?? "", sandbox.gameId ?? "", options, gameUrl));
|
|
125778
125925
|
}
|
|
125779
125926
|
return;
|
|
125780
125927
|
}
|
|
@@ -125792,9 +125939,9 @@ async function recreateSandbox(options) {
|
|
|
125792
125939
|
viteConfig.logger.error(`${prefix2} ${import_picocolors7.red("Cannot recreate sandbox database: no Vite server reference")}`);
|
|
125793
125940
|
return { success: false, error: "No Vite server reference" };
|
|
125794
125941
|
}
|
|
125795
|
-
if (currentMode
|
|
125796
|
-
viteConfig.logger.warn(`${prefix2} ${import_picocolors7.yellow("can only recreate sandbox database in platform
|
|
125797
|
-
return { success: false, error: "Not in
|
|
125942
|
+
if (!isShellMode(currentMode)) {
|
|
125943
|
+
viteConfig.logger.warn(`${prefix2} ${import_picocolors7.yellow("can only recreate sandbox database in platform or demo mode")}`);
|
|
125944
|
+
return { success: false, error: "Not in a shell-backed mode" };
|
|
125798
125945
|
}
|
|
125799
125946
|
viteConfig.logger.info(`${prefix2} recreating database...`);
|
|
125800
125947
|
if (serverState.sandbox) {
|
|
@@ -125843,7 +125990,7 @@ function createChangeHandler(server, viteConfig, platformModeOptions, watchedFil
|
|
|
125843
125990
|
if (!isWatchedFile) {
|
|
125844
125991
|
return;
|
|
125845
125992
|
}
|
|
125846
|
-
if (getCurrentMode()
|
|
125993
|
+
if (!isShellMode(getCurrentMode())) {
|
|
125847
125994
|
return;
|
|
125848
125995
|
}
|
|
125849
125996
|
if (debounceTimer) {
|
|
@@ -125949,7 +126096,7 @@ var import_picocolors12 = __toESM(require_picocolors(), 1);
|
|
|
125949
126096
|
// package.json
|
|
125950
126097
|
var package_default2 = {
|
|
125951
126098
|
name: "@playcademy/vite-plugin",
|
|
125952
|
-
version: "0.2.
|
|
126099
|
+
version: "0.2.25-beta.1",
|
|
125953
126100
|
type: "module",
|
|
125954
126101
|
exports: {
|
|
125955
126102
|
".": {
|
|
@@ -126191,7 +126338,7 @@ async function configureStandaloneMode(server, viteConfig, options) {
|
|
|
126191
126338
|
// src/server/hotkeys/toggle-mode.ts
|
|
126192
126339
|
async function toggleMode(options) {
|
|
126193
126340
|
const currentMode = getCurrentMode();
|
|
126194
|
-
const newMode = currentMode
|
|
126341
|
+
const newMode = getNextMode(currentMode);
|
|
126195
126342
|
const viteServer = getViteServerRef();
|
|
126196
126343
|
const prefix2 = createLogPrefix("playcademy");
|
|
126197
126344
|
if (!viteServer) {
|
|
@@ -126214,7 +126361,7 @@ async function toggleMode(options) {
|
|
|
126214
126361
|
function toggleModeHotkey(options) {
|
|
126215
126362
|
return {
|
|
126216
126363
|
key: "m",
|
|
126217
|
-
description: `${import_picocolors12.cyan(import_picocolors12.bold("[playcademy]"))}
|
|
126364
|
+
description: `${import_picocolors12.cyan(import_picocolors12.bold("[playcademy]"))} cycle platform/demo/standalone mode`,
|
|
126218
126365
|
action: () => toggleMode(options)
|
|
126219
126366
|
};
|
|
126220
126367
|
}
|
|
@@ -12,4 +12,14 @@
|
|
|
12
12
|
* - signature: "sandbox" (not cryptographically verified)
|
|
13
13
|
*/
|
|
14
14
|
import type { PlatformRoleOverride } from '../../types';
|
|
15
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Identities the dev shell can mint sandbox tokens for.
|
|
17
|
+
*
|
|
18
|
+
* Platform roles (player/developer/admin) are driven by the role-cycle
|
|
19
|
+
* hotkey and only make sense in `platform` mode. `anonymous` resolves to
|
|
20
|
+
* the seeded `DEMO_USERS.anonymousPlayer` and is what we mint in `demo`
|
|
21
|
+
* mode so demo-only APIs (`/users/demo-profile`, anonymous leaderboard
|
|
22
|
+
* reads, etc.) can authenticate against an actual anonymous cohort.
|
|
23
|
+
*/
|
|
24
|
+
export type SandboxTokenIdentity = PlatformRoleOverride | 'anonymous';
|
|
25
|
+
export declare function createSandboxGameToken(gameSlug: string, identity?: SandboxTokenIdentity): string;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { PlaycademyMode } from '../types/options';
|
|
2
|
+
export type ShellMode = Exclude<PlaycademyMode, 'standalone'>;
|
|
3
|
+
export declare function isShellMode(mode: PlaycademyMode): mode is ShellMode;
|
|
4
|
+
export declare function getNextMode(mode: PlaycademyMode): PlaycademyMode;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* Shell-backed mode server configuration
|
|
3
|
+
* Sandbox + backend + shell wrapper for platform and demo flows
|
|
4
4
|
*/
|
|
5
5
|
import type { ResolvedConfig, ViteDevServer } from 'vite';
|
|
6
6
|
import type { PlatformModeOptions } from '../types';
|
|
7
7
|
/**
|
|
8
|
-
* Configure server in
|
|
8
|
+
* Configure server in a shell-backed mode (sandbox + backend + shell)
|
|
9
9
|
*/
|
|
10
10
|
export declare function configurePlatformMode(server: ViteDevServer, viteConfig: ResolvedConfig, options: PlatformModeOptions): Promise<void>;
|
package/dist/types/internal.d.ts
CHANGED
|
@@ -118,7 +118,7 @@ export interface CliDevServerOptions {
|
|
|
118
118
|
gameId?: string;
|
|
119
119
|
}
|
|
120
120
|
/**
|
|
121
|
-
* Options for
|
|
121
|
+
* Options for shell-backed modes (sandbox + backend + shell)
|
|
122
122
|
*/
|
|
123
123
|
export interface PlatformModeOptions {
|
|
124
124
|
startSandbox: boolean;
|
|
@@ -155,7 +155,7 @@ export interface HotkeyOptions {
|
|
|
155
155
|
export interface BannerOptions {
|
|
156
156
|
/** Plugin version */
|
|
157
157
|
version: string;
|
|
158
|
-
/** Game/project name (
|
|
158
|
+
/** Game/project name (shell-backed modes only) */
|
|
159
159
|
gameName?: string;
|
|
160
160
|
/** Sandbox server info */
|
|
161
161
|
sandbox?: {
|
|
@@ -170,7 +170,7 @@ export interface BannerOptions {
|
|
|
170
170
|
/** Vite port for proxied URL display */
|
|
171
171
|
vitePort?: number;
|
|
172
172
|
};
|
|
173
|
-
/** Timeback info (
|
|
173
|
+
/** Timeback info (shell-backed modes only) */
|
|
174
174
|
timeback?: {
|
|
175
175
|
courseCount: number;
|
|
176
176
|
enrolledCount: number;
|
package/dist/types/options.d.ts
CHANGED
|
@@ -6,11 +6,12 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Controls how the Vite plugin operates during development:
|
|
8
8
|
* - `'platform'`: Full Playcademy platform experience with sandbox server, backend bundling, and shell wrapper (default)
|
|
9
|
+
* - `'demo'`: Shell-backed development mode that initializes the SDK with `mode: 'demo'`
|
|
9
10
|
* - `'standalone'`: Backend only, no sandbox or shell
|
|
10
11
|
*
|
|
11
12
|
* @default 'platform'
|
|
12
13
|
*/
|
|
13
|
-
export type PlaycademyMode = 'platform' | 'standalone';
|
|
14
|
+
export type PlaycademyMode = 'platform' | 'demo' | 'standalone';
|
|
14
15
|
/**
|
|
15
16
|
* Configuration options for exporting/building Playcademy games
|
|
16
17
|
*
|
|
@@ -254,7 +255,7 @@ export interface PlaycademyTimebackOptions {
|
|
|
254
255
|
* Configuration options for the development shell wrapper
|
|
255
256
|
*
|
|
256
257
|
* The shell provides the platform UI during development, including the
|
|
257
|
-
* Playcademy badge
|
|
258
|
+
* Playcademy badge and iframe wrapper used by `platform` and `demo` modes.
|
|
258
259
|
*/
|
|
259
260
|
export interface PlaycademyDisplayOptions {
|
|
260
261
|
/**
|
|
@@ -318,9 +319,11 @@ export interface PlaycademyPluginOptions {
|
|
|
318
319
|
* Plugin operation mode.
|
|
319
320
|
*
|
|
320
321
|
* - `'platform'`: Full development experience with sandbox server and shell (recommended)
|
|
322
|
+
* - `'demo'`: Sandbox + shell, but initializes the SDK with `mode: 'demo'`
|
|
321
323
|
* - `'standalone'`: Backend bundling only, no platform features
|
|
322
324
|
*
|
|
323
|
-
* Most games should use `'platform'` mode
|
|
325
|
+
* Most games should use `'platform'` mode; use `'demo'` to exercise
|
|
326
|
+
* anonymous/demo-specific SDK flows during local development.
|
|
324
327
|
*
|
|
325
328
|
* @default 'platform'
|
|
326
329
|
* @example
|