playcademy 0.30.1 → 0.30.2-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/cli.js CHANGED
@@ -3045,7 +3045,7 @@ import { existsSync as existsSync11, mkdirSync as mkdirSync5, readFileSync as re
3045
3045
  import { join as join12 } from "node:path";
3046
3046
 
3047
3047
  // src/version.ts
3048
- var cliVersion = false ? "0.0.0-dev" : "0.30.1";
3048
+ var cliVersion = false ? "0.0.0-dev" : "0.30.2-beta.1";
3049
3049
 
3050
3050
  // src/lib/init/database.ts
3051
3051
  var drizzleConfigTemplate = loadTemplateString("database/drizzle-config.ts");
package/dist/index.js CHANGED
@@ -6486,7 +6486,7 @@ import { existsSync as existsSync11, mkdirSync as mkdirSync2, readFileSync as re
6486
6486
  import { join as join12 } from "node:path";
6487
6487
 
6488
6488
  // src/version.ts
6489
- var cliVersion = false ? "0.0.0-dev" : "0.30.1";
6489
+ var cliVersion = false ? "0.0.0-dev" : "0.30.2-beta.1";
6490
6490
 
6491
6491
  // src/lib/init/database.ts
6492
6492
  var drizzleConfigTemplate = loadTemplateString("database/drizzle-config.ts");
@@ -1,7 +1,7 @@
1
1
  {
2
- "cliVersion": "0.30.1",
3
- "sdkVersion": "0.19.0",
4
- "runtimeBuildId": "c6f2b41dfc45",
5
- "inputFingerprint": "c6f2b41dfc4596541e93b76f62d40676c3e5207958d63b331b31ca54fe3abb1b",
2
+ "cliVersion": "0.30.2-beta.1",
3
+ "sdkVersion": "0.19.1-beta.1",
4
+ "runtimeBuildId": "dd9e334c1651",
5
+ "inputFingerprint": "dd9e334c165146eb95c4bc04d26ef9c4feefadc649f711900e6487996e085dd7",
6
6
  "entry": "index.js"
7
7
  }
@@ -384,6 +384,15 @@ var init_constants2 = __esm({
384
384
  }
385
385
  });
386
386
 
387
+ // ../utils/src/fns.ts
388
+ function isRecord(value) {
389
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
390
+ }
391
+ var init_fns = __esm({
392
+ "../utils/src/fns.ts"() {
393
+ }
394
+ });
395
+
387
396
  // ../sdk/src/messaging.ts
388
397
  function isFromParentWindow(event) {
389
398
  return globalThis.window.parent !== globalThis.window && event.source === globalThis.window.parent;
@@ -1394,15 +1403,6 @@ var init_src3 = __esm({
1394
1403
  }
1395
1404
  });
1396
1405
 
1397
- // ../utils/src/fns.ts
1398
- function isRecord(value) {
1399
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
1400
- }
1401
- var init_fns = __esm({
1402
- "../utils/src/fns.ts"() {
1403
- }
1404
- });
1405
-
1406
1406
  // ../utils/src/timeback.ts
1407
1407
  function withinQtiCapacity(capacities, usage, identifier) {
1408
1408
  const used = (usage.get(identifier) ?? 0) + 1;
@@ -14202,9 +14202,9 @@ var init_list = __esm({
14202
14202
  // ../edge-play/src/game/lib/metadata.ts
14203
14203
  function getRuntimeMetadata() {
14204
14204
  return {
14205
- cliVersion: true ? "0.30.1" : "0.0.0-dev",
14206
- sdkVersion: true ? "0.19.0" : "0.0.0-dev",
14207
- buildId: true ? "c6f2b41dfc45" : "dev-source"
14205
+ cliVersion: true ? "0.30.2-beta.1" : "0.0.0-dev",
14206
+ sdkVersion: true ? "0.19.1-beta.1" : "0.0.0-dev",
14207
+ buildId: true ? "dd9e334c1651" : "dev-source"
14208
14208
  };
14209
14209
  }
14210
14210
  var init_metadata = __esm({
@@ -17180,6 +17180,99 @@ function setupProcessGlobal() {
17180
17180
  };
17181
17181
  }
17182
17182
 
17183
+ // ../edge-play/src/game/middleware/playcademy-user.ts
17184
+ init_fns();
17185
+ var MAX_VERIFIED_TOKENS = 256;
17186
+ var verifiedTokens = /* @__PURE__ */ new Map();
17187
+ function isUserInfo(user) {
17188
+ return isRecord(user) && typeof user.sub === "string" && user.sub.length > 0 && typeof user.email === "string" && (typeof user.name === "string" || user.name === null) && (user.email_verified === void 0 || typeof user.email_verified === "boolean") && ["given_name", "family_name", "issuer", "timeback_id"].every(
17189
+ (key) => user[key] === void 0 || typeof user[key] === "string"
17190
+ );
17191
+ }
17192
+ function isFiniteExpiry(exp) {
17193
+ return typeof exp === "number" && Number.isFinite(exp);
17194
+ }
17195
+ function isUnexpired(exp) {
17196
+ return isFiniteExpiry(exp) && exp > Date.now() / 1e3;
17197
+ }
17198
+ function readCachedToken(token) {
17199
+ const entry = verifiedTokens.get(token);
17200
+ if (!entry) {
17201
+ return void 0;
17202
+ }
17203
+ verifiedTokens.delete(token);
17204
+ if (!isUnexpired(entry.expiresAt)) {
17205
+ return void 0;
17206
+ }
17207
+ verifiedTokens.set(token, entry);
17208
+ return entry;
17209
+ }
17210
+ function cacheVerifiedToken(token, entry) {
17211
+ verifiedTokens.delete(token);
17212
+ verifiedTokens.set(token, entry);
17213
+ if (verifiedTokens.size > MAX_VERIFIED_TOKENS) {
17214
+ verifiedTokens.delete(verifiedTokens.keys().next().value);
17215
+ }
17216
+ }
17217
+ async function verifyWithHub(token, c) {
17218
+ let result;
17219
+ try {
17220
+ result = await verifyGameToken(token, {
17221
+ baseUrl: c.env.PLAYCADEMY_BASE_URL,
17222
+ gameOrigin: new URL(c.req.url).origin,
17223
+ launchId: c.req.header("x-playcademy-launch-id")
17224
+ });
17225
+ } catch {
17226
+ return { outcome: "verification_failed" };
17227
+ }
17228
+ if (!isRecord(result) || !isUserInfo(result.user) || !isRecord(result.claims)) {
17229
+ return { outcome: "invalid_response" };
17230
+ }
17231
+ const { exp } = result.claims;
17232
+ if (!isFiniteExpiry(exp)) {
17233
+ return { user: result.user, outcome: "uncacheable" };
17234
+ }
17235
+ if (!isUnexpired(exp)) {
17236
+ return { outcome: "expired" };
17237
+ }
17238
+ cacheVerifiedToken(token, { user: result.user, expiresAt: exp });
17239
+ return { user: result.user, outcome: "success" };
17240
+ }
17241
+ function registerPlaycademyUser(app) {
17242
+ app.use("/api/*", async (c, next) => {
17243
+ const authHeader = c.req.header("Authorization");
17244
+ if (!authHeader?.startsWith("Bearer ")) {
17245
+ await next();
17246
+ return;
17247
+ }
17248
+ const token = authHeader.slice(7);
17249
+ const startedAt = performance.now();
17250
+ const cached = readCachedToken(token);
17251
+ const { user, outcome } = cached ? { user: cached.user, outcome: "success" } : await verifyWithHub(token, c);
17252
+ if (user) {
17253
+ c.set("playcademyUser", structuredClone(user));
17254
+ }
17255
+ const verificationDurationMs = performance.now() - startedAt;
17256
+ try {
17257
+ await next();
17258
+ } finally {
17259
+ console.info(
17260
+ JSON.stringify({
17261
+ event: "game_token_verification",
17262
+ source: cached ? "cache" : "hub",
17263
+ outcome,
17264
+ game_id: c.env.GAME_ID,
17265
+ build_version: c.env.BUILD_VERSION,
17266
+ request_id: c.req.header("cf-ray"),
17267
+ status_code: c.res.status,
17268
+ verification_duration_ms: verificationDurationMs,
17269
+ middleware_duration_ms: performance.now() - startedAt
17270
+ })
17271
+ );
17272
+ }
17273
+ });
17274
+ }
17275
+
17183
17276
  // ../edge-play/src/game/middleware/index.ts
17184
17277
  function registerBodyDisposal(app) {
17185
17278
  app.use("*", async (c, next) => {
@@ -17233,24 +17326,6 @@ function registerSdkInit(app, config) {
17233
17326
  await next();
17234
17327
  });
17235
17328
  }
17236
- function registerPlaycademyUser(app) {
17237
- app.use("/api/*", async (c, next) => {
17238
- const authHeader = c.req.header("Authorization");
17239
- if (authHeader?.startsWith("Bearer ")) {
17240
- const token = authHeader.slice(7);
17241
- try {
17242
- const result = await verifyGameToken(token, {
17243
- baseUrl: c.env.PLAYCADEMY_BASE_URL,
17244
- gameOrigin: new URL(c.req.url).origin,
17245
- launchId: c.req.header("x-playcademy-launch-id")
17246
- });
17247
- c.set("playcademyUser", result.user);
17248
- } catch {
17249
- }
17250
- }
17251
- await next();
17252
- });
17253
- }
17254
17329
  function registerBuiltinAssetRoute(app) {
17255
17330
  app.get(GAME_ROUTES.ASSETS, GET);
17256
17331
  }
@@ -1,7 +1,7 @@
1
1
  {
2
- "cliVersion": "0.30.1",
3
- "sdkVersion": "0.19.0",
4
- "runtimeBuildId": "c6f2b41dfc45",
5
- "inputFingerprint": "c6f2b41dfc4596541e93b76f62d40676c3e5207958d63b331b31ca54fe3abb1b",
2
+ "cliVersion": "0.30.2-beta.1",
3
+ "sdkVersion": "0.19.1-beta.1",
4
+ "runtimeBuildId": "dd9e334c1651",
5
+ "inputFingerprint": "dd9e334c165146eb95c4bc04d26ef9c4feefadc649f711900e6487996e085dd7",
6
6
  "entry": "index.js"
7
7
  }
package/dist/utils.js CHANGED
@@ -2849,7 +2849,7 @@ import { existsSync as existsSync9, mkdirSync as mkdirSync2, writeFileSync as wr
2849
2849
  import { dirname as dirname4, join as join13 } from "node:path";
2850
2850
 
2851
2851
  // src/version.ts
2852
- var cliVersion = false ? "0.0.0-dev" : "0.30.1";
2852
+ var cliVersion = false ? "0.0.0-dev" : "0.30.2-beta.1";
2853
2853
 
2854
2854
  // src/lib/build/binary-resource.ts
2855
2855
  function writeFileTree(baseDir, files) {
package/dist/version.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { createRequire as __pcCreateRequire } from 'node:module'; const require = __pcCreateRequire(import.meta.url);
2
2
 
3
3
  // src/version.ts
4
- var cliVersion = false ? "0.0.0-dev" : "0.30.1";
4
+ var cliVersion = false ? "0.0.0-dev" : "0.30.2-beta.1";
5
5
  export {
6
6
  cliVersion
7
7
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playcademy",
3
- "version": "0.30.1",
3
+ "version": "0.30.2-beta.1",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -55,7 +55,7 @@
55
55
  },
56
56
  "dependencies": {
57
57
  "@inquirer/prompts": "^7.8.6",
58
- "@playcademy/sdk": "0.19.0",
58
+ "@playcademy/sdk": "0.19.1-beta.1",
59
59
  "chokidar": "^4.0.3",
60
60
  "colorette": "^2.0.20",
61
61
  "commander": "^14.0.1",