@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.
Files changed (3) hide show
  1. package/README.md +2 -3
  2. package/dist/index.js +170 -96
  3. 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.14",
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 = "/Users/hbauer/work/projects/playcademy/node_modules/.bun/esbuild@0.25.10/node_modules/esbuild/lib", __filename2 = "/Users/hbauer/work/projects/playcademy/node_modules/.bun/esbuild@0.25.10/node_modules/esbuild/lib/main.js";
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, "application/zip");
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(".zip"), {
117755
- message: "File must be a .zip file"
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: exports_external.number().int(),
118088
- subject: exports_external.string().min(1),
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", { userId: ctx.user.id, gameIdOrSlug, sessionId });
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
- ...body2.code ? [
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.20",
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.20",
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.0"
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.14",
31
- "@playcademy/sdk": "0.3.1",
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",