@playcademy/vite-plugin 0.0.1-beta.13 → 0.0.1-beta.14
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 +116 -11
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -94353,7 +94353,7 @@ var logger = (fn = console.log) => {
|
|
|
94353
94353
|
};
|
|
94354
94354
|
var package_default = {
|
|
94355
94355
|
name: "@playcademy/sandbox",
|
|
94356
|
-
version: "0.1.0-beta.
|
|
94356
|
+
version: "0.1.0-beta.10",
|
|
94357
94357
|
description: "Local development server for Playcademy game development",
|
|
94358
94358
|
type: "module",
|
|
94359
94359
|
exports: {
|
|
@@ -114581,7 +114581,10 @@ var SAMPLE_INVENTORY = [
|
|
|
114581
114581
|
];
|
|
114582
114582
|
async function seedDemoData(db) {
|
|
114583
114583
|
try {
|
|
114584
|
-
|
|
114584
|
+
const allDemoUsers = Object.values(DEMO_USERS);
|
|
114585
|
+
for (const user of allDemoUsers) {
|
|
114586
|
+
await db.insert(users).values(user).onConflictDoNothing();
|
|
114587
|
+
}
|
|
114585
114588
|
for (const item of SAMPLE_ITEMS) {
|
|
114586
114589
|
await db.insert(items).values(item);
|
|
114587
114590
|
}
|
|
@@ -114740,19 +114743,65 @@ async function seedCurrentProjectGame(db, project) {
|
|
|
114740
114743
|
throw error2;
|
|
114741
114744
|
}
|
|
114742
114745
|
}
|
|
114746
|
+
function extractTokenFromHeader(authHeader) {
|
|
114747
|
+
if (!authHeader?.startsWith("Bearer ")) {
|
|
114748
|
+
return null;
|
|
114749
|
+
}
|
|
114750
|
+
return authHeader.substring(7);
|
|
114751
|
+
}
|
|
114752
|
+
function parseJwtToken(token) {
|
|
114753
|
+
try {
|
|
114754
|
+
const parts2 = token.split(".");
|
|
114755
|
+
if (parts2.length === 3 && parts2[1]) {
|
|
114756
|
+
const payload = JSON.parse(atob(parts2[1]));
|
|
114757
|
+
return payload.uid || null;
|
|
114758
|
+
}
|
|
114759
|
+
} catch (error2) {
|
|
114760
|
+
console.warn("Failed to decode JWT token:", error2);
|
|
114761
|
+
}
|
|
114762
|
+
return null;
|
|
114763
|
+
}
|
|
114764
|
+
function resolveUserId(token) {
|
|
114765
|
+
const demoUser = DEMO_TOKENS[token];
|
|
114766
|
+
if (demoUser) {
|
|
114767
|
+
return demoUser.id;
|
|
114768
|
+
}
|
|
114769
|
+
if (token.includes(".")) {
|
|
114770
|
+
return parseJwtToken(token);
|
|
114771
|
+
}
|
|
114772
|
+
return null;
|
|
114773
|
+
}
|
|
114774
|
+
async function fetchUserFromDatabase(db, userId) {
|
|
114775
|
+
try {
|
|
114776
|
+
const user = await db.query.users.findFirst({
|
|
114777
|
+
where: eq(users.id, userId)
|
|
114778
|
+
});
|
|
114779
|
+
return user || null;
|
|
114780
|
+
} catch (error2) {
|
|
114781
|
+
console.error("Error fetching user from database:", error2);
|
|
114782
|
+
throw error2;
|
|
114783
|
+
}
|
|
114784
|
+
}
|
|
114743
114785
|
function setupAuth() {
|
|
114744
114786
|
return async (c2, next) => {
|
|
114745
114787
|
const authHeader = c2.req.header("Authorization");
|
|
114746
|
-
|
|
114747
|
-
|
|
114748
|
-
|
|
114749
|
-
|
|
114750
|
-
|
|
114751
|
-
|
|
114752
|
-
|
|
114753
|
-
|
|
114788
|
+
const token = extractTokenFromHeader(authHeader);
|
|
114789
|
+
if (!token) {
|
|
114790
|
+
throw new Error("No authorization token provided");
|
|
114791
|
+
}
|
|
114792
|
+
const targetUserId = resolveUserId(token);
|
|
114793
|
+
if (!targetUserId) {
|
|
114794
|
+
throw new Error("No user found for provided token");
|
|
114795
|
+
}
|
|
114796
|
+
const db = c2.get("db");
|
|
114797
|
+
if (!db) {
|
|
114798
|
+
throw new Error("Database not available in context");
|
|
114754
114799
|
}
|
|
114755
|
-
|
|
114800
|
+
const user = await fetchUserFromDatabase(db, targetUserId);
|
|
114801
|
+
if (!user) {
|
|
114802
|
+
throw new Error(`User not found: ${targetUserId}`);
|
|
114803
|
+
}
|
|
114804
|
+
c2.set("user", user);
|
|
114756
114805
|
await next();
|
|
114757
114806
|
};
|
|
114758
114807
|
}
|
|
@@ -114777,6 +114826,9 @@ class ApiError extends Error {
|
|
|
114777
114826
|
static notFound(message = "Not found") {
|
|
114778
114827
|
return new ApiError(404, "NOT_FOUND", message);
|
|
114779
114828
|
}
|
|
114829
|
+
static methodNotAllowed(message = "Method not allowed") {
|
|
114830
|
+
return new ApiError(405, "METHOD_NOT_ALLOWED", message);
|
|
114831
|
+
}
|
|
114780
114832
|
static badRequest(message = "Bad request", details) {
|
|
114781
114833
|
return new ApiError(400, "BAD_REQUEST", message, details);
|
|
114782
114834
|
}
|
|
@@ -119723,6 +119775,10 @@ usersRouter.post("/xp/add", async (c2) => {
|
|
|
119723
119775
|
return c2.json(createUnknownErrorResponse(error2), 500);
|
|
119724
119776
|
}
|
|
119725
119777
|
});
|
|
119778
|
+
usersRouter.all("/", async (c2) => {
|
|
119779
|
+
const error2 = ApiError.methodNotAllowed("Method not allowed");
|
|
119780
|
+
return c2.json(createErrorResponse(error2), 405);
|
|
119781
|
+
});
|
|
119726
119782
|
var healthRouter = new Hono2;
|
|
119727
119783
|
healthRouter.get("/", (c2) => c2.json({ status: "ok", timestamp: new Date().toISOString() }));
|
|
119728
119784
|
async function getUserInventory(ctx) {
|
|
@@ -119926,6 +119982,10 @@ inventoryRouter.post("/remove", async (c2) => {
|
|
|
119926
119982
|
return c2.json(createUnknownErrorResponse(error2), 500);
|
|
119927
119983
|
}
|
|
119928
119984
|
});
|
|
119985
|
+
inventoryRouter.all("/", async (c2) => {
|
|
119986
|
+
const error2 = ApiError.methodNotAllowed("Method not allowed");
|
|
119987
|
+
return c2.json(createErrorResponse(error2), 405);
|
|
119988
|
+
});
|
|
119929
119989
|
function assertError(err2) {
|
|
119930
119990
|
if (!isError(err2)) {
|
|
119931
119991
|
throw new Error("Parameter was not an error");
|
|
@@ -123614,6 +123674,10 @@ gamesRouter.delete("/:gameId/items/:itemId/shop-listing", async (c2) => {
|
|
|
123614
123674
|
return c2.json(createUnknownErrorResponse(error2), 500);
|
|
123615
123675
|
}
|
|
123616
123676
|
});
|
|
123677
|
+
gamesRouter.all("/", async (c2) => {
|
|
123678
|
+
const error2 = ApiError.methodNotAllowed("Method not allowed");
|
|
123679
|
+
return c2.json(createErrorResponse(error2), 405);
|
|
123680
|
+
});
|
|
123617
123681
|
var manifestRouter = new Hono2;
|
|
123618
123682
|
manifestRouter.get("/", async (c2) => {
|
|
123619
123683
|
const baseUrl = new URL(c2.req.url).origin;
|
|
@@ -123740,6 +123804,10 @@ shopRouter.get("/view", async (c2) => {
|
|
|
123740
123804
|
return c2.json(createUnknownErrorResponse(error2), 500);
|
|
123741
123805
|
}
|
|
123742
123806
|
});
|
|
123807
|
+
shopRouter.all("/view", async (c2) => {
|
|
123808
|
+
const error2 = ApiError.methodNotAllowed("Method not allowed");
|
|
123809
|
+
return c2.json(createErrorResponse(error2), 405);
|
|
123810
|
+
});
|
|
123743
123811
|
var itemsRouter = new Hono2;
|
|
123744
123812
|
itemsRouter.get("/resolve", async (c2) => {
|
|
123745
123813
|
const ctx = {
|
|
@@ -123852,6 +123920,10 @@ itemsRouter.delete("/:itemId", async (c2) => {
|
|
|
123852
123920
|
return c2.json(createUnknownErrorResponse(error2), 500);
|
|
123853
123921
|
}
|
|
123854
123922
|
});
|
|
123923
|
+
itemsRouter.all("/", async (c2) => {
|
|
123924
|
+
const error2 = ApiError.methodNotAllowed("Method not allowed");
|
|
123925
|
+
return c2.json(createErrorResponse(error2), 405);
|
|
123926
|
+
});
|
|
123855
123927
|
async function listCurrencies(ctx) {
|
|
123856
123928
|
const user = ctx.user;
|
|
123857
123929
|
log2.debug("[API] listing currencies", { userId: user?.id || "anonymous" });
|
|
@@ -123882,6 +123954,9 @@ async function getCurrencyById(ctx) {
|
|
|
123882
123954
|
if (!currencyId) {
|
|
123883
123955
|
throw ApiError.badRequest("Missing currency ID");
|
|
123884
123956
|
}
|
|
123957
|
+
if (!isValidUUID(currencyId)) {
|
|
123958
|
+
throw ApiError.unprocessableEntity("Invalid UUID format for currency ID");
|
|
123959
|
+
}
|
|
123885
123960
|
try {
|
|
123886
123961
|
const db = getDatabase();
|
|
123887
123962
|
const currency = await db.query.currencies.findFirst({
|
|
@@ -123953,6 +124028,9 @@ async function updateCurrency(ctx) {
|
|
|
123953
124028
|
if (!currencyId) {
|
|
123954
124029
|
throw ApiError.badRequest("Missing currency ID");
|
|
123955
124030
|
}
|
|
124031
|
+
if (!isValidUUID(currencyId)) {
|
|
124032
|
+
throw ApiError.unprocessableEntity("Invalid UUID format for currency ID");
|
|
124033
|
+
}
|
|
123956
124034
|
let requestBody;
|
|
123957
124035
|
try {
|
|
123958
124036
|
requestBody = await ctx.request.json();
|
|
@@ -124003,6 +124081,9 @@ async function deleteCurrency(ctx) {
|
|
|
124003
124081
|
if (!currencyId) {
|
|
124004
124082
|
throw ApiError.badRequest("Missing currency ID");
|
|
124005
124083
|
}
|
|
124084
|
+
if (!isValidUUID(currencyId)) {
|
|
124085
|
+
throw ApiError.unprocessableEntity("Invalid UUID format for currency ID");
|
|
124086
|
+
}
|
|
124006
124087
|
try {
|
|
124007
124088
|
const db = getDatabase();
|
|
124008
124089
|
const result = await db.delete(currencies).where(eq(currencies.id, currencyId)).returning({ id: currencies.id });
|
|
@@ -124110,6 +124191,10 @@ currenciesRouter.delete("/:currencyId", async (c2) => {
|
|
|
124110
124191
|
return c2.json(createUnknownErrorResponse(error2), 500);
|
|
124111
124192
|
}
|
|
124112
124193
|
});
|
|
124194
|
+
currenciesRouter.all("/", async (c2) => {
|
|
124195
|
+
const error2 = ApiError.methodNotAllowed("Method not allowed");
|
|
124196
|
+
return c2.json(createErrorResponse(error2), 405);
|
|
124197
|
+
});
|
|
124113
124198
|
async function getMapElements(ctx) {
|
|
124114
124199
|
const user = ctx.user;
|
|
124115
124200
|
if (!user) {
|
|
@@ -124215,6 +124300,10 @@ mapsRouter.get("/:identifier", async (c2) => {
|
|
|
124215
124300
|
return c2.json(createUnknownErrorResponse(error2), 500);
|
|
124216
124301
|
}
|
|
124217
124302
|
});
|
|
124303
|
+
mapsRouter.all("/", async (c2) => {
|
|
124304
|
+
const error2 = ApiError.methodNotAllowed("Method not allowed");
|
|
124305
|
+
return c2.json(createErrorResponse(error2), 405);
|
|
124306
|
+
});
|
|
124218
124307
|
async function createShopListing(ctx) {
|
|
124219
124308
|
const user = ctx.user;
|
|
124220
124309
|
if (!user || user.role !== "admin") {
|
|
@@ -124509,6 +124598,10 @@ shopListingsRouter.delete("/:listingId", async (c2) => {
|
|
|
124509
124598
|
return c2.json(createUnknownErrorResponse(error2), 500);
|
|
124510
124599
|
}
|
|
124511
124600
|
});
|
|
124601
|
+
shopListingsRouter.all("/", async (c2) => {
|
|
124602
|
+
const error2 = ApiError.methodNotAllowed("Method not allowed");
|
|
124603
|
+
return c2.json(createErrorResponse(error2), 405);
|
|
124604
|
+
});
|
|
124512
124605
|
async function applyForDeveloperStatus(ctx) {
|
|
124513
124606
|
const user = ctx.user;
|
|
124514
124607
|
log2.debug("[API] applying for developer status", {
|
|
@@ -124765,6 +124858,10 @@ devRouter.delete("/keys/:keyId", async (c2) => {
|
|
|
124765
124858
|
return c2.json(createUnknownErrorResponse(error2), 500);
|
|
124766
124859
|
}
|
|
124767
124860
|
});
|
|
124861
|
+
devRouter.all("/", async (c2) => {
|
|
124862
|
+
const error2 = ApiError.methodNotAllowed("Method not allowed");
|
|
124863
|
+
return c2.json(createErrorResponse(error2), 405);
|
|
124864
|
+
});
|
|
124768
124865
|
var levelsRouter = new Hono2;
|
|
124769
124866
|
levelsRouter.get("/config", async (c2) => {
|
|
124770
124867
|
const ctx = {
|
|
@@ -124802,6 +124899,10 @@ levelsRouter.get("/config/:level", async (c2) => {
|
|
|
124802
124899
|
return c2.json(createUnknownErrorResponse(error2), 500);
|
|
124803
124900
|
}
|
|
124804
124901
|
});
|
|
124902
|
+
levelsRouter.all("/", async (c2) => {
|
|
124903
|
+
const error2 = ApiError.methodNotAllowed("Method not allowed");
|
|
124904
|
+
return c2.json(createErrorResponse(error2), 405);
|
|
124905
|
+
});
|
|
124805
124906
|
async function startServer(options) {
|
|
124806
124907
|
const { port, verbose = false, project, memoryOnly = false, seed = true } = options;
|
|
124807
124908
|
const db = await setupDatabase(memoryOnly ? ":memory:" : undefined);
|
|
@@ -124815,6 +124916,10 @@ async function startServer(options) {
|
|
|
124815
124916
|
app.use("*", cors({ origin: "*", credentials: true }));
|
|
124816
124917
|
if (verbose)
|
|
124817
124918
|
app.use("*", logger());
|
|
124919
|
+
app.use("/api/*", async (c2, next) => {
|
|
124920
|
+
c2.set("db", db);
|
|
124921
|
+
await next();
|
|
124922
|
+
});
|
|
124818
124923
|
app.route("/health", healthRouter);
|
|
124819
124924
|
app.route("/api", manifestRouter);
|
|
124820
124925
|
app.use("/api/*", setupAuth());
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@playcademy/vite-plugin",
|
|
3
|
-
"version": "0.0.1-beta.
|
|
3
|
+
"version": "0.0.1-beta.14",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"picocolors": "^1.1.1"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@playcademy/sandbox": "0.1.0-beta.
|
|
30
|
+
"@playcademy/sandbox": "0.1.0-beta.10",
|
|
31
31
|
"@types/archiver": "^6.0.3",
|
|
32
32
|
"@types/bun": "latest",
|
|
33
33
|
"yocto-spinner": "^0.2.2"
|