@playcademy/vite-plugin 0.2.20 → 0.2.21-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/README.md +2 -3
- package/dist/index.js +170 -96
- package/package.json +5 -6
package/README.md
CHANGED
|
@@ -375,11 +375,10 @@ cd packages/vite-plugin
|
|
|
375
375
|
|
|
376
376
|
# Build the plugin
|
|
377
377
|
bun run build
|
|
378
|
-
|
|
379
|
-
# Publish to npm (requires permissions)
|
|
380
|
-
bun run pub
|
|
381
378
|
```
|
|
382
379
|
|
|
380
|
+
Package releases are handled by the monorepo Changesets and CI release workflows rather than from this package directory.
|
|
381
|
+
|
|
383
382
|
## Dependencies
|
|
384
383
|
|
|
385
384
|
### Runtime Dependencies
|
package/dist/index.js
CHANGED
|
@@ -25334,7 +25334,7 @@ var package_default;
|
|
|
25334
25334
|
var init_package = __esm(() => {
|
|
25335
25335
|
package_default = {
|
|
25336
25336
|
name: "@playcademy/sandbox",
|
|
25337
|
-
version: "0.3.
|
|
25337
|
+
version: "0.3.15-beta.1",
|
|
25338
25338
|
description: "Local development server for Playcademy game development",
|
|
25339
25339
|
type: "module",
|
|
25340
25340
|
exports: {
|
|
@@ -25369,7 +25369,6 @@ var init_package = __esm(() => {
|
|
|
25369
25369
|
build: "bun run build.ts",
|
|
25370
25370
|
dev: "bun --watch src/cli",
|
|
25371
25371
|
docs: "typedoc",
|
|
25372
|
-
pub: "bun publish.ts",
|
|
25373
25372
|
start: "bun src/cli"
|
|
25374
25373
|
},
|
|
25375
25374
|
dependencies: {
|
|
@@ -45219,10 +45218,33 @@ class DeployJobService {
|
|
|
45219
45218
|
}
|
|
45220
45219
|
await this.deps.storage.deleteObject(bucketName, this.getCodeBundleObjectKey(jobId)).catch(() => {});
|
|
45221
45220
|
}
|
|
45221
|
+
assertValidCodeUploadToken(token, gameId) {
|
|
45222
|
+
const expectedPrefix = `uploads-temp/${gameId}/`;
|
|
45223
|
+
if (!token.startsWith(expectedPrefix) || !token.endsWith(".js")) {
|
|
45224
|
+
throw new ValidationError("Invalid backend code upload token");
|
|
45225
|
+
}
|
|
45226
|
+
}
|
|
45227
|
+
async loadUploadedCode(codeUploadToken, gameId) {
|
|
45228
|
+
this.assertValidCodeUploadToken(codeUploadToken, gameId);
|
|
45229
|
+
const bucketName = this.getUploadBucket();
|
|
45230
|
+
const bytes = await this.deps.storage.getObjectBytes(bucketName, codeUploadToken);
|
|
45231
|
+
if (!bytes) {
|
|
45232
|
+
throw new ValidationError("Backend code upload not found");
|
|
45233
|
+
}
|
|
45234
|
+
return new TextDecoder().decode(bytes);
|
|
45235
|
+
}
|
|
45236
|
+
deleteUploadedCode(codeUploadToken, gameId) {
|
|
45237
|
+
this.assertValidCodeUploadToken(codeUploadToken, gameId);
|
|
45238
|
+
const bucketName = this.getUploadBucket();
|
|
45239
|
+
this.deps.storage.deleteObject(bucketName, codeUploadToken).catch(() => {
|
|
45240
|
+
logger2.warn("Failed to delete temp code upload", { key: codeUploadToken });
|
|
45241
|
+
});
|
|
45242
|
+
}
|
|
45222
45243
|
sanitizeRequestForPersistence(request) {
|
|
45223
45244
|
const sanitized = { ...request };
|
|
45224
45245
|
delete sanitized._headers;
|
|
45225
45246
|
delete sanitized.code;
|
|
45247
|
+
delete sanitized.codeUploadToken;
|
|
45226
45248
|
return sanitized;
|
|
45227
45249
|
}
|
|
45228
45250
|
getLeaseExpiry() {
|
|
@@ -45260,6 +45282,16 @@ class DeployJobService {
|
|
|
45260
45282
|
async create(slug, request, user) {
|
|
45261
45283
|
const game = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
45262
45284
|
const jobId = crypto.randomUUID();
|
|
45285
|
+
let codeSource = "none";
|
|
45286
|
+
if (request.code) {
|
|
45287
|
+
codeSource = "inline";
|
|
45288
|
+
} else if (request.codeUploadToken) {
|
|
45289
|
+
codeSource = "presigned-upload";
|
|
45290
|
+
}
|
|
45291
|
+
logger2.info("Deploy job backend code source", { slug, codeSource });
|
|
45292
|
+
if (codeSource === "presigned-upload") {
|
|
45293
|
+
request.code = await this.loadUploadedCode(request.codeUploadToken, game.id);
|
|
45294
|
+
}
|
|
45263
45295
|
const sanitizedRequest = this.sanitizeRequestForPersistence(request);
|
|
45264
45296
|
if (request.code) {
|
|
45265
45297
|
await this.storeCodeBundle(jobId, request.code);
|
|
@@ -45288,6 +45320,9 @@ class DeployJobService {
|
|
|
45288
45320
|
throw new ValidationError("Failed to create deploy job");
|
|
45289
45321
|
}
|
|
45290
45322
|
logger2.info("Deploy job created", { jobId: job.id, gameId: game.id, slug, userId: user.id });
|
|
45323
|
+
if (codeSource === "presigned-upload") {
|
|
45324
|
+
this.deleteUploadedCode(request.codeUploadToken, game.id);
|
|
45325
|
+
}
|
|
45291
45326
|
return this.toResponse(job);
|
|
45292
45327
|
}
|
|
45293
45328
|
async get(jobId, slug, user) {
|
|
@@ -47645,7 +47680,7 @@ var init_provider2 = __esm(() => {
|
|
|
47645
47680
|
init_provider();
|
|
47646
47681
|
});
|
|
47647
47682
|
var require_main2 = __commonJS2((exports, module2) => {
|
|
47648
|
-
var __dirname2 = "/
|
|
47683
|
+
var __dirname2 = "/home/runner/work/playcademy/playcademy/node_modules/.bun/esbuild@0.25.10/node_modules/esbuild/lib", __filename2 = "/home/runner/work/playcademy/playcademy/node_modules/.bun/esbuild@0.25.10/node_modules/esbuild/lib/main.js";
|
|
47649
47684
|
var __defProp22 = Object.defineProperty;
|
|
47650
47685
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
47651
47686
|
var __getOwnPropNames22 = Object.getOwnPropertyNames;
|
|
@@ -54126,6 +54161,12 @@ class UploadService {
|
|
|
54126
54161
|
constructor(deps) {
|
|
54127
54162
|
this.deps = deps;
|
|
54128
54163
|
}
|
|
54164
|
+
static getContentType(fileName) {
|
|
54165
|
+
if (fileName.endsWith(".js")) {
|
|
54166
|
+
return "application/javascript";
|
|
54167
|
+
}
|
|
54168
|
+
return "application/zip";
|
|
54169
|
+
}
|
|
54129
54170
|
async initiate(request, user) {
|
|
54130
54171
|
const { fileName, gameId } = request;
|
|
54131
54172
|
const bucketName = this.deps.uploadBucket;
|
|
@@ -54137,7 +54178,7 @@ class UploadService {
|
|
|
54137
54178
|
const version2 = ulid();
|
|
54138
54179
|
const tempS3Key = `uploads-temp/${gameId}/${version2}/${fileName}`;
|
|
54139
54180
|
logger17.debug("Initiating upload", { userId: user.id, gameId, fileName, version: version2 });
|
|
54140
|
-
const presignedUrl = await this.deps.generatePresignedPutUrl(bucketName, tempS3Key,
|
|
54181
|
+
const presignedUrl = await this.deps.generatePresignedPutUrl(bucketName, tempS3Key, UploadService.getContentType(fileName));
|
|
54141
54182
|
logger17.info("Presigned URL generated", {
|
|
54142
54183
|
userId: user.id,
|
|
54143
54184
|
gameId,
|
|
@@ -117650,6 +117691,7 @@ var UpdateGameStateSchema;
|
|
|
117650
117691
|
var InsertGameDeploymentSchema;
|
|
117651
117692
|
var InsertGameDeployJobSchema;
|
|
117652
117693
|
var UpsertGameMetadataSchema;
|
|
117694
|
+
var ALLOWED_UPLOAD_EXTENSIONS;
|
|
117653
117695
|
var InitiateUploadSchema;
|
|
117654
117696
|
var AddCustomHostnameSchema;
|
|
117655
117697
|
var SetSecretsRequestSchema;
|
|
@@ -117750,9 +117792,10 @@ var init_schemas2 = __esm(() => {
|
|
|
117750
117792
|
message: "External games require an externalUrl",
|
|
117751
117793
|
path: ["externalUrl"]
|
|
117752
117794
|
});
|
|
117795
|
+
ALLOWED_UPLOAD_EXTENSIONS = [".zip", ".js"];
|
|
117753
117796
|
InitiateUploadSchema = exports_external.object({
|
|
117754
|
-
fileName: exports_external.string().min(1).refine((name4) => name4.endsWith(
|
|
117755
|
-
message:
|
|
117797
|
+
fileName: exports_external.string().min(1).refine((name4) => ALLOWED_UPLOAD_EXTENSIONS.some((ext2) => name4.endsWith(ext2)), {
|
|
117798
|
+
message: `File must be one of: ${ALLOWED_UPLOAD_EXTENSIONS.join(", ")}`
|
|
117756
117799
|
}),
|
|
117757
117800
|
gameId: exports_external.string().uuid()
|
|
117758
117801
|
});
|
|
@@ -117785,6 +117828,7 @@ var init_schemas2 = __esm(() => {
|
|
|
117785
117828
|
DeployRequestSchema = exports_external.object({
|
|
117786
117829
|
uploadToken: exports_external.string().optional(),
|
|
117787
117830
|
code: exports_external.string().optional(),
|
|
117831
|
+
codeUploadToken: exports_external.string().optional(),
|
|
117788
117832
|
config: exports_external.unknown().optional(),
|
|
117789
117833
|
bindings: exports_external.object({
|
|
117790
117834
|
database: exports_external.array(exports_external.string()).optional(),
|
|
@@ -117812,6 +117856,9 @@ var init_schemas2 = __esm(() => {
|
|
|
117812
117856
|
platform: exports_external.string().optional(),
|
|
117813
117857
|
metadata: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
|
|
117814
117858
|
}).optional()
|
|
117859
|
+
}).refine((data) => !(data.code && data.codeUploadToken), {
|
|
117860
|
+
message: "Specify either code or codeUploadToken, not both",
|
|
117861
|
+
path: ["codeUploadToken"]
|
|
117815
117862
|
});
|
|
117816
117863
|
});
|
|
117817
117864
|
function validateRelativePath(path22, fieldName) {
|
|
@@ -118084,8 +118131,8 @@ var init_schemas11 = __esm(() => {
|
|
|
118084
118131
|
activityData: exports_external.object({
|
|
118085
118132
|
activityId: exports_external.string().min(1),
|
|
118086
118133
|
activityName: exports_external.string().optional(),
|
|
118087
|
-
grade:
|
|
118088
|
-
subject:
|
|
118134
|
+
grade: TimebackGradeSchema,
|
|
118135
|
+
subject: TimebackSubjectSchema,
|
|
118089
118136
|
appName: exports_external.string().optional(),
|
|
118090
118137
|
sensorUrl: exports_external.string().url().optional(),
|
|
118091
118138
|
courseId: exports_external.string().optional(),
|
|
@@ -118977,7 +119024,7 @@ var init_game_controller = __esm(() => {
|
|
|
118977
119024
|
if (!isValidUUID(gameId)) {
|
|
118978
119025
|
throw ApiError.unprocessableEntity("gameId must be a valid UUID format");
|
|
118979
119026
|
}
|
|
118980
|
-
logger45.debug("Getting game by ID", { userId: ctx.user.id, gameId });
|
|
119027
|
+
logger45.debug("Getting game by ID", { userId: ctx.user.id, gameId, launchId: ctx.launchId });
|
|
118981
119028
|
return ctx.services.game.getById(gameId, ctx.user);
|
|
118982
119029
|
});
|
|
118983
119030
|
getBySlug = requireAuth(async (ctx) => {
|
|
@@ -118985,7 +119032,7 @@ var init_game_controller = __esm(() => {
|
|
|
118985
119032
|
if (!slug2) {
|
|
118986
119033
|
throw ApiError.badRequest("Missing game slug");
|
|
118987
119034
|
}
|
|
118988
|
-
logger45.debug("Getting game by slug", { userId: ctx.user.id, slug: slug2 });
|
|
119035
|
+
logger45.debug("Getting game by slug", { userId: ctx.user.id, slug: slug2, launchId: ctx.launchId });
|
|
118989
119036
|
return ctx.services.game.getBySlug(slug2, ctx.user);
|
|
118990
119037
|
});
|
|
118991
119038
|
upsertBySlug = requireAuth(async (ctx) => {
|
|
@@ -119880,7 +119927,8 @@ var init_realtime_controller = __esm(() => {
|
|
|
119880
119927
|
const gameIdOrSlug = ctx.params.gameId;
|
|
119881
119928
|
logger55.debug("Generating token", {
|
|
119882
119929
|
userId: ctx.user.id,
|
|
119883
|
-
gameId: gameIdOrSlug || "global"
|
|
119930
|
+
gameId: gameIdOrSlug || "global",
|
|
119931
|
+
launchId: ctx.launchId
|
|
119884
119932
|
});
|
|
119885
119933
|
return ctx.services.realtime.generateToken(ctx.user, gameIdOrSlug);
|
|
119886
119934
|
});
|
|
@@ -120003,7 +120051,7 @@ var init_session_controller = __esm(() => {
|
|
|
120003
120051
|
if (!gameIdOrSlug) {
|
|
120004
120052
|
throw ApiError.badRequest("Missing game ID or slug");
|
|
120005
120053
|
}
|
|
120006
|
-
logger58.debug("Starting session", { userId: ctx.user.id, gameIdOrSlug });
|
|
120054
|
+
logger58.debug("Starting session", { userId: ctx.user.id, gameIdOrSlug, launchId: ctx.launchId });
|
|
120007
120055
|
return ctx.services.session.start(gameIdOrSlug, ctx.user.id);
|
|
120008
120056
|
});
|
|
120009
120057
|
end = requireAuth(async (ctx) => {
|
|
@@ -120015,7 +120063,12 @@ var init_session_controller = __esm(() => {
|
|
|
120015
120063
|
if (!sessionId) {
|
|
120016
120064
|
throw ApiError.badRequest("Missing session ID");
|
|
120017
120065
|
}
|
|
120018
|
-
logger58.debug("Ending session", {
|
|
120066
|
+
logger58.debug("Ending session", {
|
|
120067
|
+
userId: ctx.user.id,
|
|
120068
|
+
gameIdOrSlug,
|
|
120069
|
+
sessionId,
|
|
120070
|
+
launchId: ctx.launchId
|
|
120071
|
+
});
|
|
120019
120072
|
return ctx.services.session.end(gameIdOrSlug, sessionId, ctx.user.id);
|
|
120020
120073
|
});
|
|
120021
120074
|
mintToken = requireAuth(async (ctx) => {
|
|
@@ -120023,7 +120076,7 @@ var init_session_controller = __esm(() => {
|
|
|
120023
120076
|
if (!gameIdOrSlug) {
|
|
120024
120077
|
throw ApiError.badRequest("Missing game ID or slug");
|
|
120025
120078
|
}
|
|
120026
|
-
logger58.debug("Minting token", { userId: ctx.user.id, gameIdOrSlug });
|
|
120079
|
+
logger58.debug("Minting token", { userId: ctx.user.id, gameIdOrSlug, launchId: ctx.launchId });
|
|
120027
120080
|
return ctx.services.session.mintToken(gameIdOrSlug, ctx.user.id);
|
|
120028
120081
|
});
|
|
120029
120082
|
sessions2 = {
|
|
@@ -120773,6 +120826,97 @@ var init_crud = __esm(() => {
|
|
|
120773
120826
|
gameCrudRouter.put("/:slug", handle2(games2.upsertBySlug));
|
|
120774
120827
|
gameCrudRouter.delete("/:gameId", handle2(games2.remove, { status: 204 }));
|
|
120775
120828
|
});
|
|
120829
|
+
async function initiateHandler(c2) {
|
|
120830
|
+
const user = c2.get("user");
|
|
120831
|
+
if (!user) {
|
|
120832
|
+
return c2.json({ error: { code: "UNAUTHORIZED", message: "Authentication required" } }, 401);
|
|
120833
|
+
}
|
|
120834
|
+
let body2;
|
|
120835
|
+
try {
|
|
120836
|
+
body2 = await c2.req.json();
|
|
120837
|
+
} catch {
|
|
120838
|
+
return c2.json({ error: { code: "BAD_REQUEST", message: "Invalid JSON body" } }, 400);
|
|
120839
|
+
}
|
|
120840
|
+
if (!body2.fileName || !body2.gameId) {
|
|
120841
|
+
return c2.json({
|
|
120842
|
+
error: {
|
|
120843
|
+
code: "VALIDATION_FAILED",
|
|
120844
|
+
message: "Validation failed: fileName and gameId are required"
|
|
120845
|
+
}
|
|
120846
|
+
}, 422);
|
|
120847
|
+
}
|
|
120848
|
+
const uploadToken = `sandbox-upload-${randomUUID3()}`;
|
|
120849
|
+
const version4 = `v${Date.now()}`;
|
|
120850
|
+
pendingUploads.set(uploadToken, {
|
|
120851
|
+
gameId: body2.gameId,
|
|
120852
|
+
fileName: body2.fileName
|
|
120853
|
+
});
|
|
120854
|
+
const host = c2.req.header("host") || "localhost:3000";
|
|
120855
|
+
const protocol = host.startsWith("localhost") || host.startsWith("127.0.0.1") ? "http" : "https";
|
|
120856
|
+
const presignedUrl = `${protocol}://${host}/api/games/uploads/sandbox/${uploadToken}`;
|
|
120857
|
+
return c2.json({
|
|
120858
|
+
uploadToken,
|
|
120859
|
+
presignedUrl,
|
|
120860
|
+
gameId: body2.gameId,
|
|
120861
|
+
version: version4
|
|
120862
|
+
});
|
|
120863
|
+
}
|
|
120864
|
+
function consumeUploadedCode(token) {
|
|
120865
|
+
const upload = pendingUploads.get(token);
|
|
120866
|
+
if (!upload?.data) {
|
|
120867
|
+
return;
|
|
120868
|
+
}
|
|
120869
|
+
const { data } = upload;
|
|
120870
|
+
pendingUploads.delete(token);
|
|
120871
|
+
return data;
|
|
120872
|
+
}
|
|
120873
|
+
async function finalizeHandler(c2) {
|
|
120874
|
+
const user = c2.get("user");
|
|
120875
|
+
if (!user) {
|
|
120876
|
+
return c2.json({ error: "Authentication required" }, 401);
|
|
120877
|
+
}
|
|
120878
|
+
let body2;
|
|
120879
|
+
try {
|
|
120880
|
+
body2 = await c2.req.json();
|
|
120881
|
+
} catch {
|
|
120882
|
+
return c2.json({ error: "Invalid JSON body" }, 400);
|
|
120883
|
+
}
|
|
120884
|
+
if (!body2.uploadToken) {
|
|
120885
|
+
return c2.json({ error: "uploadToken is required" }, 400);
|
|
120886
|
+
}
|
|
120887
|
+
const upload = pendingUploads.get(body2.uploadToken);
|
|
120888
|
+
if (!upload) {
|
|
120889
|
+
return c2.json({ error: "Invalid or expired upload token" }, 400);
|
|
120890
|
+
}
|
|
120891
|
+
pendingUploads.delete(body2.uploadToken);
|
|
120892
|
+
return c2.json({
|
|
120893
|
+
success: true,
|
|
120894
|
+
gameId: upload.gameId,
|
|
120895
|
+
fileName: upload.fileName
|
|
120896
|
+
});
|
|
120897
|
+
}
|
|
120898
|
+
var gameUploadsRouter;
|
|
120899
|
+
var pendingUploads;
|
|
120900
|
+
var init_uploads = __esm(() => {
|
|
120901
|
+
init_dist4();
|
|
120902
|
+
gameUploadsRouter = new Hono2;
|
|
120903
|
+
pendingUploads = new Map;
|
|
120904
|
+
gameUploadsRouter.post("/uploads/initiate", initiateHandler);
|
|
120905
|
+
gameUploadsRouter.post("/uploads/initiate/", initiateHandler);
|
|
120906
|
+
gameUploadsRouter.put("/uploads/sandbox/:token", async (c2) => {
|
|
120907
|
+
const token = c2.req.param("token");
|
|
120908
|
+
const upload = pendingUploads.get(token);
|
|
120909
|
+
if (!upload) {
|
|
120910
|
+
return c2.json({ error: "Invalid upload token" }, 400);
|
|
120911
|
+
}
|
|
120912
|
+
if (upload.fileName.endsWith(".js")) {
|
|
120913
|
+
upload.data = await c2.req.text();
|
|
120914
|
+
}
|
|
120915
|
+
return c2.text("", 200);
|
|
120916
|
+
});
|
|
120917
|
+
gameUploadsRouter.post("/uploads/finalize", finalizeHandler);
|
|
120918
|
+
gameUploadsRouter.post("/uploads/finalize/", finalizeHandler);
|
|
120919
|
+
});
|
|
120776
120920
|
var logger66;
|
|
120777
120921
|
var gameDeployRouter;
|
|
120778
120922
|
var init_deploy = __esm(() => {
|
|
@@ -120783,6 +120927,7 @@ var init_deploy = __esm(() => {
|
|
|
120783
120927
|
init_tables_index();
|
|
120784
120928
|
init_src2();
|
|
120785
120929
|
init_api();
|
|
120930
|
+
init_uploads();
|
|
120786
120931
|
logger66 = log.scope("SandboxDeploy");
|
|
120787
120932
|
gameDeployRouter = new Hono2;
|
|
120788
120933
|
gameDeployRouter.post("/:slug/deploy", async (c2) => {
|
|
@@ -120853,6 +120998,14 @@ var init_deploy = __esm(() => {
|
|
|
120853
120998
|
}).returning();
|
|
120854
120999
|
game = inserted[0];
|
|
120855
121000
|
}
|
|
121001
|
+
let backendCode = body2.code;
|
|
121002
|
+
if (!backendCode && body2.codeUploadToken) {
|
|
121003
|
+
backendCode = consumeUploadedCode(body2.codeUploadToken);
|
|
121004
|
+
if (!backendCode) {
|
|
121005
|
+
return c2.json({ error: { code: "BAD_REQUEST", message: "Backend code upload not found" } }, 400);
|
|
121006
|
+
}
|
|
121007
|
+
}
|
|
121008
|
+
const hasBackend = Boolean(backendCode);
|
|
120856
121009
|
const events = [
|
|
120857
121010
|
{ type: "status", message: "Deployment queued", createdAt: now2.toISOString() },
|
|
120858
121011
|
{ type: "status", message: "Deployment started", createdAt: now2.toISOString() },
|
|
@@ -120864,7 +121017,7 @@ var init_deploy = __esm(() => {
|
|
|
120864
121017
|
},
|
|
120865
121018
|
{ type: "status", message: "Extracting assets", createdAt: now2.toISOString() }
|
|
120866
121019
|
] : [],
|
|
120867
|
-
...
|
|
121020
|
+
...hasBackend ? [
|
|
120868
121021
|
{
|
|
120869
121022
|
type: "status",
|
|
120870
121023
|
message: "Deploying backend code",
|
|
@@ -121114,84 +121267,6 @@ var init_shop = __esm(() => {
|
|
|
121114
121267
|
gameShopRouter.patch("/:gameId/items/:itemId/shop-listing", handle2(shopListings2.updateForGameItem));
|
|
121115
121268
|
gameShopRouter.delete("/:gameId/items/:itemId/shop-listing", handle2(shopListings2.deleteForGameItem, { status: 204 }));
|
|
121116
121269
|
});
|
|
121117
|
-
async function initiateHandler(c2) {
|
|
121118
|
-
const user = c2.get("user");
|
|
121119
|
-
if (!user) {
|
|
121120
|
-
return c2.json({ error: { code: "UNAUTHORIZED", message: "Authentication required" } }, 401);
|
|
121121
|
-
}
|
|
121122
|
-
let body2;
|
|
121123
|
-
try {
|
|
121124
|
-
body2 = await c2.req.json();
|
|
121125
|
-
} catch {
|
|
121126
|
-
return c2.json({ error: { code: "BAD_REQUEST", message: "Invalid JSON body" } }, 400);
|
|
121127
|
-
}
|
|
121128
|
-
if (!body2.fileName || !body2.gameId) {
|
|
121129
|
-
return c2.json({
|
|
121130
|
-
error: {
|
|
121131
|
-
code: "VALIDATION_FAILED",
|
|
121132
|
-
message: "Validation failed: fileName and gameId are required"
|
|
121133
|
-
}
|
|
121134
|
-
}, 422);
|
|
121135
|
-
}
|
|
121136
|
-
const uploadToken = `sandbox-upload-${randomUUID3()}`;
|
|
121137
|
-
const version4 = `v${Date.now()}`;
|
|
121138
|
-
pendingUploads.set(uploadToken, {
|
|
121139
|
-
gameId: body2.gameId,
|
|
121140
|
-
fileName: body2.fileName
|
|
121141
|
-
});
|
|
121142
|
-
const host = c2.req.header("host") || "localhost:3000";
|
|
121143
|
-
const protocol = host.startsWith("localhost") || host.startsWith("127.0.0.1") ? "http" : "https";
|
|
121144
|
-
const presignedUrl = `${protocol}://${host}/api/games/uploads/sandbox/${uploadToken}`;
|
|
121145
|
-
return c2.json({
|
|
121146
|
-
uploadToken,
|
|
121147
|
-
presignedUrl,
|
|
121148
|
-
gameId: body2.gameId,
|
|
121149
|
-
version: version4
|
|
121150
|
-
});
|
|
121151
|
-
}
|
|
121152
|
-
async function finalizeHandler(c2) {
|
|
121153
|
-
const user = c2.get("user");
|
|
121154
|
-
if (!user) {
|
|
121155
|
-
return c2.json({ error: "Authentication required" }, 401);
|
|
121156
|
-
}
|
|
121157
|
-
let body2;
|
|
121158
|
-
try {
|
|
121159
|
-
body2 = await c2.req.json();
|
|
121160
|
-
} catch {
|
|
121161
|
-
return c2.json({ error: "Invalid JSON body" }, 400);
|
|
121162
|
-
}
|
|
121163
|
-
if (!body2.uploadToken) {
|
|
121164
|
-
return c2.json({ error: "uploadToken is required" }, 400);
|
|
121165
|
-
}
|
|
121166
|
-
const upload = pendingUploads.get(body2.uploadToken);
|
|
121167
|
-
if (!upload) {
|
|
121168
|
-
return c2.json({ error: "Invalid or expired upload token" }, 400);
|
|
121169
|
-
}
|
|
121170
|
-
pendingUploads.delete(body2.uploadToken);
|
|
121171
|
-
return c2.json({
|
|
121172
|
-
success: true,
|
|
121173
|
-
gameId: upload.gameId,
|
|
121174
|
-
fileName: upload.fileName
|
|
121175
|
-
});
|
|
121176
|
-
}
|
|
121177
|
-
var gameUploadsRouter;
|
|
121178
|
-
var pendingUploads;
|
|
121179
|
-
var init_uploads = __esm(() => {
|
|
121180
|
-
init_dist4();
|
|
121181
|
-
gameUploadsRouter = new Hono2;
|
|
121182
|
-
pendingUploads = new Map;
|
|
121183
|
-
gameUploadsRouter.post("/uploads/initiate", initiateHandler);
|
|
121184
|
-
gameUploadsRouter.post("/uploads/initiate/", initiateHandler);
|
|
121185
|
-
gameUploadsRouter.put("/uploads/sandbox/:token", async (c2) => {
|
|
121186
|
-
const token = c2.req.param("token");
|
|
121187
|
-
if (!pendingUploads.has(token)) {
|
|
121188
|
-
return c2.json({ error: "Invalid upload token" }, 400);
|
|
121189
|
-
}
|
|
121190
|
-
return c2.text("", 200);
|
|
121191
|
-
});
|
|
121192
|
-
gameUploadsRouter.post("/uploads/finalize", finalizeHandler);
|
|
121193
|
-
gameUploadsRouter.post("/uploads/finalize/", finalizeHandler);
|
|
121194
|
-
});
|
|
121195
121270
|
var gameVerifyRouter;
|
|
121196
121271
|
var init_verify2 = __esm(() => {
|
|
121197
121272
|
init_dist4();
|
|
@@ -123059,7 +123134,7 @@ var import_picocolors12 = __toESM(require_picocolors(), 1);
|
|
|
123059
123134
|
// package.json
|
|
123060
123135
|
var package_default2 = {
|
|
123061
123136
|
name: "@playcademy/vite-plugin",
|
|
123062
|
-
version: "0.2.
|
|
123137
|
+
version: "0.2.21-beta.1",
|
|
123063
123138
|
type: "module",
|
|
123064
123139
|
exports: {
|
|
123065
123140
|
".": {
|
|
@@ -123074,8 +123149,7 @@ var package_default2 = {
|
|
|
123074
123149
|
],
|
|
123075
123150
|
scripts: {
|
|
123076
123151
|
build: "bun build.ts",
|
|
123077
|
-
docs: "typedoc --skipErrorChecking"
|
|
123078
|
-
pub: "bun publish.ts"
|
|
123152
|
+
docs: "typedoc --skipErrorChecking"
|
|
123079
123153
|
},
|
|
123080
123154
|
dependencies: {
|
|
123081
123155
|
archiver: "^7.0.1",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@playcademy/vite-plugin",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.21-beta.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -15,20 +15,19 @@
|
|
|
15
15
|
],
|
|
16
16
|
"scripts": {
|
|
17
17
|
"build": "bun build.ts",
|
|
18
|
-
"docs": "typedoc --skipErrorChecking"
|
|
19
|
-
"pub": "bun publish.ts"
|
|
18
|
+
"docs": "typedoc --skipErrorChecking"
|
|
20
19
|
},
|
|
21
20
|
"dependencies": {
|
|
22
21
|
"archiver": "^7.0.1",
|
|
23
22
|
"picocolors": "^1.1.1",
|
|
24
|
-
"playcademy": "0.18.
|
|
23
|
+
"playcademy": "0.18.8"
|
|
25
24
|
},
|
|
26
25
|
"devDependencies": {
|
|
27
26
|
"@electric-sql/pglite": "^0.3.16",
|
|
28
27
|
"@inquirer/prompts": "^7.8.6",
|
|
29
28
|
"@playcademy/constants": "0.0.1",
|
|
30
|
-
"@playcademy/sandbox": "0.3.
|
|
31
|
-
"@playcademy/sdk": "0.3.
|
|
29
|
+
"@playcademy/sandbox": "0.3.15",
|
|
30
|
+
"@playcademy/sdk": "0.3.5",
|
|
32
31
|
"@playcademy/types": "0.0.1",
|
|
33
32
|
"@playcademy/utils": "0.0.1",
|
|
34
33
|
"@types/archiver": "^6.0.3",
|