@playcademy/sdk 0.1.10 → 0.1.12

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.d.ts CHANGED
@@ -3412,6 +3412,15 @@ interface BetterAuthApiKey {
3412
3412
  lastRequest: string | null;
3413
3413
  requestCount: number;
3414
3414
  }
3415
+ /**
3416
+ * Bucket file metadata
3417
+ */
3418
+ interface BucketFile {
3419
+ key: string;
3420
+ size: number;
3421
+ uploaded: string;
3422
+ contentType?: string;
3423
+ }
3415
3424
 
3416
3425
  /**
3417
3426
  * OAuth 2.0 implementation for the Playcademy SDK
@@ -3706,11 +3715,17 @@ declare class PlaycademyClient {
3706
3715
  *
3707
3716
  * @param path - API endpoint path
3708
3717
  * @param method - HTTP method
3709
- * @param body - Request body (optional)
3710
- * @param headers - Additional headers (optional)
3711
- * @returns Promise resolving to the response data
3718
+ * @param options - Optional request configuration
3719
+ * @param options.body - Request body
3720
+ * @param options.headers - Additional headers
3721
+ * @param options.raw - If true, returns raw Response instead of parsing
3722
+ * @returns Promise resolving to the response data or raw Response
3712
3723
  */
3713
- protected request<T>(path: string, method: Method, body?: unknown, headers?: Record<string, string>): Promise<T>;
3724
+ protected request<T>(path: string, method: Method, options?: {
3725
+ body?: unknown;
3726
+ headers?: Record<string, string>;
3727
+ raw?: boolean;
3728
+ }): Promise<T>;
3714
3729
  /**
3715
3730
  * Makes an authenticated HTTP request to the game's backend Worker.
3716
3731
  * Uses gameUrl if set, otherwise falls back to platform API.
@@ -3853,6 +3868,11 @@ declare class PlaycademyClient {
3853
3868
  deploy: {
3854
3869
  frontend: (slug: string, metadata: UpsertGameMetadataInput, file: File | Blob | null, hooks?: DevUploadHooks) => Promise<Game>;
3855
3870
  backend: (slug: string, bundle: BackendDeploymentBundle) => Promise<BackendDeploymentResponse>;
3871
+ seed: (slug: string, code: string, environment?: "staging" | "production") => Promise<{
3872
+ success: boolean;
3873
+ deploymentId: string;
3874
+ executedAt: string;
3875
+ }>;
3856
3876
  };
3857
3877
  upsert: (slug: string, metadata: UpsertGameMetadataInput) => Promise<Game>;
3858
3878
  delete: (gameId: string) => Promise<void>;
@@ -3862,6 +3882,23 @@ declare class PlaycademyClient {
3862
3882
  get: (slug: string) => Promise<Record<string, string>>;
3863
3883
  delete: (slug: string, key: string) => Promise<void>;
3864
3884
  };
3885
+ database: {
3886
+ reset: (slug: string, schema?: {
3887
+ sql: string;
3888
+ hash: string;
3889
+ }) => Promise<{
3890
+ success: boolean;
3891
+ deploymentId: string;
3892
+ resetAt: string;
3893
+ schemaPushed: boolean;
3894
+ }>;
3895
+ };
3896
+ bucket: {
3897
+ list: (slug: string, prefix?: string) => Promise<BucketFile[]>;
3898
+ get: (slug: string, key: string) => Promise<ArrayBuffer>;
3899
+ put: (slug: string, key: string, content: Blob | ArrayBuffer | Uint8Array, contentType?: string) => Promise<void>;
3900
+ delete: (slug: string, key: string) => Promise<void>;
3901
+ };
3865
3902
  };
3866
3903
  items: {
3867
3904
  create: (gameId: string, slug: string, itemData: Omit<InsertItemInput, "slug" | "gameId">) => Promise<Item>;
@@ -4076,7 +4113,9 @@ declare class PlaycademyClient {
4076
4113
  }) => Promise<TodayXpResponse>;
4077
4114
  total: () => Promise<TotalXpResponse>;
4078
4115
  history: (options?: {
4079
- startDate?: string;
4116
+ startDate
4117
+ /** Auto-initializes a PlaycademyClient with context from the environment */
4118
+ ?: string;
4080
4119
  endDate?: string;
4081
4120
  }) => Promise<XpHistoryResponse>;
4082
4121
  summary: (options?: {
package/dist/index.js CHANGED
@@ -20,6 +20,8 @@ var isBrowser = () => {
20
20
  return typeof process !== "undefined" && true;
21
21
  }, isInteractiveTTY = () => {
22
22
  return typeof process !== "undefined" && Boolean(process.stdout && process.stdout.isTTY);
23
+ }, isSilent = () => {
24
+ return typeof process !== "undefined" && process.env.LOG_SILENT === "true";
23
25
  }, detectOutputFormat = () => {
24
26
  if (isBrowser()) {
25
27
  return "browser";
@@ -117,6 +119,8 @@ var isBrowser = () => {
117
119
  }
118
120
  return isProduction() ? "info" : "debug";
119
121
  }, shouldLog = (level) => {
122
+ if (isSilent())
123
+ return false;
120
124
  const minLevel = getMinimumLogLevel();
121
125
  return levelPriority[level] >= levelPriority[minLevel];
122
126
  }, performLog = (level, message, context) => {
@@ -299,7 +303,7 @@ function createAuthNamespace(client) {
299
303
  return {
300
304
  login: async (credentials) => {
301
305
  try {
302
- const response = await client["request"]("/auth/sign-in/email", "POST", credentials);
306
+ const response = await client["request"]("/auth/sign-in/email", "POST", { body: credentials });
303
307
  client.setToken(response.token, "session");
304
308
  return {
305
309
  success: true,
@@ -323,12 +327,14 @@ function createAuthNamespace(client) {
323
327
  apiKeys: {
324
328
  create: async (options) => {
325
329
  return client["request"]("/dev/api-keys", "POST", {
326
- name: options?.name || `SDK Key - ${new Date().toISOString()}`,
327
- expiresIn: options?.expiresIn !== undefined ? options.expiresIn : null,
328
- permissions: options?.permissions || {
329
- games: ["read", "write", "delete"],
330
- users: ["read:self", "write:self"],
331
- dev: ["read", "write"]
330
+ body: {
331
+ name: options?.name || `SDK Key - ${new Date().toISOString()}`,
332
+ expiresIn: options?.expiresIn !== undefined ? options.expiresIn : null,
333
+ permissions: options?.permissions || {
334
+ games: ["read", "write", "delete"],
335
+ users: ["read:self", "write:self"],
336
+ dev: ["read", "write"]
337
+ }
332
338
  }
333
339
  });
334
340
  },
@@ -336,7 +342,9 @@ function createAuthNamespace(client) {
336
342
  return client["request"]("/auth/api-key/list", "GET");
337
343
  },
338
344
  revoke: async (keyId) => {
339
- await client["request"]("/auth/api-key/revoke", "POST", { id: keyId });
345
+ await client["request"]("/auth/api-key/revoke", "POST", {
346
+ body: { id: keyId }
347
+ });
340
348
  }
341
349
  }
342
350
  };
@@ -1046,7 +1054,7 @@ function createGamesNamespace(client) {
1046
1054
  },
1047
1055
  saveState: async (state) => {
1048
1056
  const gameId = client["_ensureGameId"]();
1049
- await client["request"](`/games/${gameId}/state`, "POST", state);
1057
+ await client["request"](`/games/${gameId}/state`, "POST", { body: state });
1050
1058
  },
1051
1059
  loadState: async () => {
1052
1060
  const gameId = client["_ensureGameId"]();
@@ -1156,7 +1164,7 @@ function createUsersNamespace(client) {
1156
1164
  get: async () => client["request"](`/inventory`, "GET"),
1157
1165
  add: async (identifier, qty) => {
1158
1166
  const itemId = await resolveItemId(identifier);
1159
- const res = await client["request"](`/inventory/add`, "POST", { itemId, qty });
1167
+ const res = await client["request"](`/inventory/add`, "POST", { body: { itemId, qty } });
1160
1168
  client["emit"]("inventoryChange", {
1161
1169
  itemId,
1162
1170
  delta: qty,
@@ -1166,7 +1174,7 @@ function createUsersNamespace(client) {
1166
1174
  },
1167
1175
  remove: async (identifier, qty) => {
1168
1176
  const itemId = await resolveItemId(identifier);
1169
- const res = await client["request"](`/inventory/remove`, "POST", { itemId, qty });
1177
+ const res = await client["request"](`/inventory/remove`, "POST", { body: { itemId, qty } });
1170
1178
  client["emit"]("inventoryChange", {
1171
1179
  itemId,
1172
1180
  delta: -qty,
@@ -1227,14 +1235,18 @@ function createDevNamespace(client) {
1227
1235
  deploy: {
1228
1236
  frontend: async (slug, metadata, file, hooks) => {
1229
1237
  hooks?.onEvent?.({ type: "init" });
1230
- const game = await client["request"](`/games/${slug}`, "PUT", metadata);
1238
+ const game = await client["request"](`/games/${slug}`, "PUT", {
1239
+ body: metadata
1240
+ });
1231
1241
  if (metadata.gameType === "external" || file === null) {
1232
1242
  return game;
1233
1243
  }
1234
1244
  const fileName = file instanceof File ? file.name : "game.zip";
1235
1245
  const initiateResponse = await client["request"]("/games/uploads/initiate/", "POST", {
1236
- fileName,
1237
- gameId: game.id
1246
+ body: {
1247
+ fileName,
1248
+ gameId: game.id
1249
+ }
1238
1250
  });
1239
1251
  if (hooks?.onEvent && typeof XMLHttpRequest !== "undefined") {
1240
1252
  await new Promise((resolve, reject) => {
@@ -1365,7 +1377,12 @@ function createDevNamespace(client) {
1365
1377
  throw new Error("Upload completed but no final game data received");
1366
1378
  },
1367
1379
  backend: async (slug, bundle) => {
1368
- return client["request"](`/games/${slug}/backend/deploy`, "POST", bundle);
1380
+ return client["request"](`/games/${slug}/backend/deploy`, "POST", { body: bundle });
1381
+ },
1382
+ seed: async (slug, code, environment) => {
1383
+ return client["request"](`/games/${slug}/seed`, "POST", {
1384
+ body: { code, environment }
1385
+ });
1369
1386
  }
1370
1387
  },
1371
1388
  upsert: async (slug, metadata) => {
@@ -1374,7 +1391,7 @@ function createDevNamespace(client) {
1374
1391
  delete: (gameId) => client["request"](`/games/${gameId}`, "DELETE"),
1375
1392
  secrets: {
1376
1393
  set: async (slug, secrets) => {
1377
- const result = await client["request"](`/games/${slug}/secrets`, "POST", secrets);
1394
+ const result = await client["request"](`/games/${slug}/secrets`, "POST", { body: secrets });
1378
1395
  return result.keys;
1379
1396
  },
1380
1397
  list: async (slug) => {
@@ -1388,14 +1405,57 @@ function createDevNamespace(client) {
1388
1405
  delete: async (slug, key) => {
1389
1406
  await client["request"](`/games/${slug}/secrets/${key}`, "DELETE");
1390
1407
  }
1408
+ },
1409
+ database: {
1410
+ reset: async (slug, schema) => {
1411
+ return client["request"](`/games/${slug}/database/reset`, "POST", {
1412
+ body: { schema }
1413
+ });
1414
+ }
1415
+ },
1416
+ bucket: {
1417
+ list: async (slug, prefix) => {
1418
+ const params = prefix ? `?prefix=${encodeURIComponent(prefix)}` : "";
1419
+ const result = await client["request"](`/games/${slug}/bucket${params}`, "GET");
1420
+ return result.files;
1421
+ },
1422
+ get: async (slug, key) => {
1423
+ const res = await client["request"](`/games/${slug}/bucket/${encodeURIComponent(key)}`, "GET", { raw: true });
1424
+ if (!res.ok) {
1425
+ let errorMessage = res.statusText;
1426
+ try {
1427
+ const errorData = await res.json();
1428
+ if (errorData.error) {
1429
+ errorMessage = errorData.error;
1430
+ } else if (errorData.message) {
1431
+ errorMessage = errorData.message;
1432
+ }
1433
+ } catch {}
1434
+ throw new Error(errorMessage);
1435
+ }
1436
+ return res.arrayBuffer();
1437
+ },
1438
+ put: async (slug, key, content, contentType) => {
1439
+ await client["request"](`/games/${slug}/bucket/${encodeURIComponent(key)}`, "PUT", {
1440
+ body: content,
1441
+ headers: contentType ? { "Content-Type": contentType } : undefined
1442
+ });
1443
+ },
1444
+ delete: async (slug, key) => {
1445
+ await client["request"](`/games/${slug}/bucket/${encodeURIComponent(key)}`, "DELETE");
1446
+ }
1391
1447
  }
1392
1448
  },
1393
1449
  items: {
1394
1450
  create: (gameId, slug, itemData) => client["request"](`/games/${gameId}/items`, "POST", {
1395
- slug,
1396
- ...itemData
1451
+ body: {
1452
+ slug,
1453
+ ...itemData
1454
+ }
1455
+ }),
1456
+ update: (gameId, itemId, updates) => client["request"](`/games/${gameId}/items/${itemId}`, "PATCH", {
1457
+ body: updates
1397
1458
  }),
1398
- update: (gameId, itemId, updates) => client["request"](`/games/${gameId}/items/${itemId}`, "PATCH", updates),
1399
1459
  list: (gameId) => client["request"](`/games/${gameId}/items`, "GET"),
1400
1460
  get: (gameId, slug) => {
1401
1461
  const queryParams = new URLSearchParams({ slug, gameId });
@@ -1404,13 +1464,13 @@ function createDevNamespace(client) {
1404
1464
  delete: (gameId, itemId) => client["request"](`/games/${gameId}/items/${itemId}`, "DELETE"),
1405
1465
  shop: {
1406
1466
  create: (gameId, itemId, listingData) => {
1407
- return client["request"](`/games/${gameId}/items/${itemId}/shop-listing`, "POST", listingData);
1467
+ return client["request"](`/games/${gameId}/items/${itemId}/shop-listing`, "POST", { body: listingData });
1408
1468
  },
1409
1469
  get: (gameId, itemId) => {
1410
1470
  return client["request"](`/games/${gameId}/items/${itemId}/shop-listing`, "GET");
1411
1471
  },
1412
1472
  update: (gameId, itemId, updates) => {
1413
- return client["request"](`/games/${gameId}/items/${itemId}/shop-listing`, "PATCH", updates);
1473
+ return client["request"](`/games/${gameId}/items/${itemId}/shop-listing`, "PATCH", { body: updates });
1414
1474
  },
1415
1475
  delete: (gameId, itemId) => {
1416
1476
  return client["request"](`/games/${gameId}/items/${itemId}/shop-listing`, "DELETE");
@@ -1438,7 +1498,9 @@ function createMapsNamespace(client) {
1438
1498
  elements: (mapId, options) => mapElementsCache.get(mapId, () => client["request"](`/map/elements?mapId=${mapId}`, "GET"), options),
1439
1499
  objects: {
1440
1500
  list: (mapId) => client["request"](`/maps/${mapId}/objects`, "GET"),
1441
- create: (mapId, objectData) => client["request"](`/maps/${mapId}/objects`, "POST", objectData),
1501
+ create: (mapId, objectData) => client["request"](`/maps/${mapId}/objects`, "POST", {
1502
+ body: objectData
1503
+ }),
1442
1504
  delete: (mapId, objectId) => client["request"](`/maps/${mapId}/objects/${objectId}`, "DELETE")
1443
1505
  }
1444
1506
  };
@@ -1453,24 +1515,26 @@ function createAdminNamespace(client) {
1453
1515
  resumeGame: (gameId) => client["request"](`/admin/games/${gameId}/resume`, "POST")
1454
1516
  },
1455
1517
  items: {
1456
- create: (props) => client["request"]("/items", "POST", props),
1518
+ create: (props) => client["request"]("/items", "POST", { body: props }),
1457
1519
  get: (itemId) => client["request"](`/items/${itemId}`, "GET"),
1458
1520
  list: () => client["request"]("/items", "GET"),
1459
- update: (itemId, props) => client["request"](`/items/${itemId}`, "PATCH", props),
1521
+ update: (itemId, props) => client["request"](`/items/${itemId}`, "PATCH", { body: props }),
1460
1522
  delete: (itemId) => client["request"](`/items/${itemId}`, "DELETE")
1461
1523
  },
1462
1524
  currencies: {
1463
- create: (props) => client["request"]("/currencies", "POST", props),
1525
+ create: (props) => client["request"]("/currencies", "POST", { body: props }),
1464
1526
  get: (currencyId) => client["request"](`/currencies/${currencyId}`, "GET"),
1465
1527
  list: () => client["request"]("/currencies", "GET"),
1466
- update: (currencyId, props) => client["request"](`/currencies/${currencyId}`, "PATCH", props),
1528
+ update: (currencyId, props) => client["request"](`/currencies/${currencyId}`, "PATCH", { body: props }),
1467
1529
  delete: (currencyId) => client["request"](`/currencies/${currencyId}`, "DELETE")
1468
1530
  },
1469
1531
  shopListings: {
1470
- create: (props) => client["request"]("/shop-listings", "POST", props),
1532
+ create: (props) => client["request"]("/shop-listings", "POST", { body: props }),
1471
1533
  get: (listingId) => client["request"](`/shop-listings/${listingId}`, "GET"),
1472
1534
  list: () => client["request"]("/shop-listings", "GET"),
1473
- update: (listingId, props) => client["request"](`/shop-listings/${listingId}`, "PATCH", props),
1535
+ update: (listingId, props) => client["request"](`/shop-listings/${listingId}`, "PATCH", {
1536
+ body: props
1537
+ }),
1474
1538
  delete: (listingId) => client["request"](`/shop-listings/${listingId}`, "DELETE")
1475
1539
  }
1476
1540
  };
@@ -1488,7 +1552,7 @@ function createShopNamespace(client) {
1488
1552
  // src/core/namespaces/telemetry.ts
1489
1553
  function createTelemetryNamespace(client) {
1490
1554
  return {
1491
- pushMetrics: (metrics) => client["request"](`/telemetry/metrics`, "POST", metrics)
1555
+ pushMetrics: (metrics) => client["request"](`/telemetry/metrics`, "POST", { body: metrics })
1492
1556
  };
1493
1557
  }
1494
1558
 
@@ -1665,8 +1729,10 @@ function createCreditsNamespace(client) {
1665
1729
  }
1666
1730
  const creditsItemId = await getCreditsItemId();
1667
1731
  const result = await client["request"]("/inventory/add", "POST", {
1668
- itemId: creditsItemId,
1669
- qty: amount
1732
+ body: {
1733
+ itemId: creditsItemId,
1734
+ qty: amount
1735
+ }
1670
1736
  });
1671
1737
  client["emit"]("inventoryChange", {
1672
1738
  itemId: creditsItemId,
@@ -1681,8 +1747,10 @@ function createCreditsNamespace(client) {
1681
1747
  }
1682
1748
  const creditsItemId = await getCreditsItemId();
1683
1749
  const result = await client["request"]("/inventory/remove", "POST", {
1684
- itemId: creditsItemId,
1685
- qty: amount
1750
+ body: {
1751
+ itemId: creditsItemId,
1752
+ qty: amount
1753
+ }
1686
1754
  });
1687
1755
  client["emit"]("inventoryChange", {
1688
1756
  itemId: creditsItemId,
@@ -1722,8 +1790,10 @@ function createScoresNamespace(client) {
1722
1790
  return {
1723
1791
  submit: async (gameId, score, metadata) => {
1724
1792
  return client["request"](`/games/${gameId}/scores`, "POST", {
1725
- score,
1726
- metadata
1793
+ body: {
1794
+ score,
1795
+ metadata
1796
+ }
1727
1797
  });
1728
1798
  },
1729
1799
  getByUser: async (gameId, userId, options) => {
@@ -1759,10 +1829,10 @@ function createCharacterNamespace(client) {
1759
1829
  }
1760
1830
  },
1761
1831
  create: async (characterData) => {
1762
- return client["request"]("/character", "POST", characterData);
1832
+ return client["request"]("/character", "POST", { body: characterData });
1763
1833
  },
1764
1834
  update: async (updates) => {
1765
- return client["request"]("/character", "PATCH", updates);
1835
+ return client["request"]("/character", "PATCH", { body: updates });
1766
1836
  },
1767
1837
  components: {
1768
1838
  list: async (options) => {
@@ -1778,7 +1848,7 @@ function createCharacterNamespace(client) {
1778
1848
  },
1779
1849
  accessories: {
1780
1850
  equip: async (slot, componentId) => {
1781
- return client["request"]("/character/accessories/equip", "POST", { slot, accessoryComponentId: componentId });
1851
+ return client["request"]("/character/accessories/equip", "POST", { body: { slot, accessoryComponentId: componentId } });
1782
1852
  },
1783
1853
  remove: async (slot) => {
1784
1854
  return client["request"](`/character/accessories/${slot}`, "DELETE");
@@ -2080,7 +2150,7 @@ function createAchievementsNamespace(client) {
2080
2150
  },
2081
2151
  progress: {
2082
2152
  submit: async (achievementId) => client["request"]("/achievements/progress", "POST", {
2083
- achievementId
2153
+ body: { achievementId }
2084
2154
  })
2085
2155
  }
2086
2156
  };
@@ -2155,7 +2225,9 @@ function createTimebackNamespace(client) {
2155
2225
  },
2156
2226
  management: {
2157
2227
  setup: (request2) => {
2158
- return client["request"]("/timeback/setup", "POST", request2);
2228
+ return client["request"]("/timeback/setup", "POST", {
2229
+ body: request2
2230
+ });
2159
2231
  },
2160
2232
  verify: (gameId) => {
2161
2233
  return client["request"](`/timeback/verify/${gameId}`, "GET");
@@ -2244,24 +2316,30 @@ function createNotificationsNamespace(client) {
2244
2316
  },
2245
2317
  markAsSeen: async (notificationId) => {
2246
2318
  const result = await client["request"](`/notifications/${notificationId}/status`, "PATCH", {
2247
- id: notificationId,
2248
- status: "seen"
2319
+ body: {
2320
+ id: notificationId,
2321
+ status: "seen"
2322
+ }
2249
2323
  });
2250
2324
  notificationsListCache.clear();
2251
2325
  return result;
2252
2326
  },
2253
2327
  markAsClicked: async (notificationId) => {
2254
2328
  const result = await client["request"](`/notifications/${notificationId}/status`, "PATCH", {
2255
- id: notificationId,
2256
- status: "clicked"
2329
+ body: {
2330
+ id: notificationId,
2331
+ status: "clicked"
2332
+ }
2257
2333
  });
2258
2334
  notificationsListCache.clear();
2259
2335
  return result;
2260
2336
  },
2261
2337
  dismiss: async (notificationId) => {
2262
2338
  const result = await client["request"](`/notifications/${notificationId}/status`, "PATCH", {
2263
- id: notificationId,
2264
- status: "dismissed"
2339
+ body: {
2340
+ id: notificationId,
2341
+ status: "dismissed"
2342
+ }
2265
2343
  });
2266
2344
  notificationsListCache.clear();
2267
2345
  return result;
@@ -2574,17 +2652,18 @@ var init_client = __esm(() => {
2574
2652
  listener(payload);
2575
2653
  });
2576
2654
  }
2577
- async request(path, method, body, headers) {
2655
+ async request(path, method, options) {
2578
2656
  const effectiveHeaders = {
2579
- ...headers,
2657
+ ...options?.headers,
2580
2658
  ...this.authStrategy.getHeaders()
2581
2659
  };
2582
2660
  return request({
2583
2661
  path,
2584
2662
  method,
2585
- body,
2663
+ body: options?.body,
2586
2664
  baseUrl: this.baseUrl,
2587
- extraHeaders: effectiveHeaders
2665
+ extraHeaders: effectiveHeaders,
2666
+ raw: options?.raw
2588
2667
  });
2589
2668
  }
2590
2669
  async requestGameBackend(path, method, body, headers, raw) {
package/dist/types.d.ts CHANGED
@@ -4394,11 +4394,17 @@ declare class PlaycademyClient {
4394
4394
  *
4395
4395
  * @param path - API endpoint path
4396
4396
  * @param method - HTTP method
4397
- * @param body - Request body (optional)
4398
- * @param headers - Additional headers (optional)
4399
- * @returns Promise resolving to the response data
4397
+ * @param options - Optional request configuration
4398
+ * @param options.body - Request body
4399
+ * @param options.headers - Additional headers
4400
+ * @param options.raw - If true, returns raw Response instead of parsing
4401
+ * @returns Promise resolving to the response data or raw Response
4400
4402
  */
4401
- protected request<T>(path: string, method: Method, body?: unknown, headers?: Record<string, string>): Promise<T>;
4403
+ protected request<T>(path: string, method: Method, options?: {
4404
+ body?: unknown;
4405
+ headers?: Record<string, string>;
4406
+ raw?: boolean;
4407
+ }): Promise<T>;
4402
4408
  /**
4403
4409
  * Makes an authenticated HTTP request to the game's backend Worker.
4404
4410
  * Uses gameUrl if set, otherwise falls back to platform API.
@@ -4541,6 +4547,11 @@ declare class PlaycademyClient {
4541
4547
  deploy: {
4542
4548
  frontend: (slug: string, metadata: UpsertGameMetadataInput, file: File | Blob | null, hooks?: DevUploadHooks) => Promise<Game>;
4543
4549
  backend: (slug: string, bundle: BackendDeploymentBundle) => Promise<BackendDeploymentResponse>;
4550
+ seed: (slug: string, code: string, environment?: "staging" | "production") => Promise<{
4551
+ success: boolean;
4552
+ deploymentId: string;
4553
+ executedAt: string;
4554
+ }>;
4544
4555
  };
4545
4556
  upsert: (slug: string, metadata: UpsertGameMetadataInput) => Promise<Game>;
4546
4557
  delete: (gameId: string) => Promise<void>;
@@ -4550,6 +4561,23 @@ declare class PlaycademyClient {
4550
4561
  get: (slug: string) => Promise<Record<string, string>>;
4551
4562
  delete: (slug: string, key: string) => Promise<void>;
4552
4563
  };
4564
+ database: {
4565
+ reset: (slug: string, schema?: {
4566
+ sql: string;
4567
+ hash: string;
4568
+ }) => Promise<{
4569
+ success: boolean;
4570
+ deploymentId: string;
4571
+ resetAt: string;
4572
+ schemaPushed: boolean;
4573
+ }>;
4574
+ };
4575
+ bucket: {
4576
+ list: (slug: string, prefix?: string) => Promise<BucketFile[]>;
4577
+ get: (slug: string, key: string) => Promise<ArrayBuffer>;
4578
+ put: (slug: string, key: string, content: Blob | ArrayBuffer | Uint8Array, contentType?: string) => Promise<void>;
4579
+ delete: (slug: string, key: string) => Promise<void>;
4580
+ };
4553
4581
  };
4554
4582
  items: {
4555
4583
  create: (gameId: string, slug: string, itemData: Omit<InsertItemInput, "slug" | "gameId">) => Promise<Item>;
@@ -4764,7 +4792,9 @@ declare class PlaycademyClient {
4764
4792
  }) => Promise<TodayXpResponse>;
4765
4793
  total: () => Promise<TotalXpResponse>;
4766
4794
  history: (options?: {
4767
- startDate?: string;
4795
+ startDate
4796
+ /** Auto-initializes a PlaycademyClient with context from the environment */
4797
+ ?: string;
4768
4798
  endDate?: string;
4769
4799
  }) => Promise<XpHistoryResponse>;
4770
4800
  summary: (options?: {
@@ -5128,6 +5158,15 @@ interface BetterAuthApiKey {
5128
5158
  lastRequest: string | null;
5129
5159
  requestCount: number;
5130
5160
  }
5161
+ /**
5162
+ * Bucket file metadata
5163
+ */
5164
+ interface BucketFile {
5165
+ key: string;
5166
+ size: number;
5167
+ uploaded: string;
5168
+ contentType?: string;
5169
+ }
5131
5170
 
5132
5171
  export { PlaycademyClient };
5133
- export type { Achievement, AchievementCurrent, AchievementProgressResponse, AuthCallbackPayload, AuthOptions, AuthProviderType, AuthResult, AuthServerMessage, AuthStateChangePayload, AuthStateUpdate, AuthenticatedUser, BetterAuthApiKey, BetterAuthApiKeyResponse, BetterAuthSignInResponse, CharacterComponent, CharacterComponentWithSpriteUrl, ClientConfig, ClientEvents, Currency, DevUploadEvent, DevUploadHooks, DeveloperStatusResponse, EventListeners, ExternalGame, Game, GameContextPayload, GameLeaderboardEntry, GameSession, GameStateData, GameTokenResponse, GameUser, HostedGame, HostedGameWithManifest, InitPayload, InventoryItem, InventoryItemWithItem, InventoryMutationResponse, Item, KeyEventPayload, LeaderboardEntry, LevelConfig, LoginResponse, ManifestV1, Map, MapElement, MapElementWithGame, MapObject, MapObjectWithItem, PlaycademyServerClientConfig, PlaycademyServerClientState, PlayerCharacter, ShopCurrency, ShopDisplayItem, ShopViewResponse, SpriteTemplate, SpriteTemplateData, StartSessionResponse, TelemetryPayload, TodayXpResponse, TokenRefreshPayload, TokenType, TotalXpResponse, User, UserInfo, UserLevel, UserLevelWithConfig, UserRank, UserRankResponse, UserRoleEnumType, UserScore$1 as UserScore, XpHistoryResponse };
5172
+ export type { Achievement, AchievementCurrent, AchievementProgressResponse, AuthCallbackPayload, AuthOptions, AuthProviderType, AuthResult, AuthServerMessage, AuthStateChangePayload, AuthStateUpdate, AuthenticatedUser, BetterAuthApiKey, BetterAuthApiKeyResponse, BetterAuthSignInResponse, BucketFile, CharacterComponent, CharacterComponentWithSpriteUrl, ClientConfig, ClientEvents, Currency, DevUploadEvent, DevUploadHooks, DeveloperStatusResponse, EventListeners, ExternalGame, Game, GameContextPayload, GameLeaderboardEntry, GameSession, GameStateData, GameTokenResponse, GameUser, HostedGame, HostedGameWithManifest, InitPayload, InventoryItem, InventoryItemWithItem, InventoryMutationResponse, Item, KeyEventPayload, LeaderboardEntry, LevelConfig, LoginResponse, ManifestV1, Map, MapElement, MapElementWithGame, MapObject, MapObjectWithItem, PlaycademyServerClientConfig, PlaycademyServerClientState, PlayerCharacter, ShopCurrency, ShopDisplayItem, ShopViewResponse, SpriteTemplate, SpriteTemplateData, StartSessionResponse, TelemetryPayload, TodayXpResponse, TokenRefreshPayload, TokenType, TotalXpResponse, User, UserInfo, UserLevel, UserLevelWithConfig, UserRank, UserRankResponse, UserRoleEnumType, UserScore$1 as UserScore, XpHistoryResponse };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playcademy/sdk",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -37,12 +37,12 @@
37
37
  "@playcademy/constants": "0.0.1",
38
38
  "@playcademy/data": "0.0.1",
39
39
  "@playcademy/logger": "0.0.1",
40
- "@playcademy/sandbox": "0.1.7",
40
+ "@playcademy/sandbox": "0.1.8",
41
41
  "@playcademy/test": "0.0.1",
42
42
  "@playcademy/timeback": "0.0.1",
43
43
  "@playcademy/utils": "0.0.1",
44
44
  "@types/bun": "latest",
45
- "playcademy": "0.13.21",
45
+ "playcademy": "0.13.23",
46
46
  "rollup": "^4.50.2",
47
47
  "rollup-plugin-dts": "^6.2.3",
48
48
  "typescript": "^5.7.2",