@playcademy/sandbox 0.5.1-beta.3 → 0.5.1-beta.5
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 +94 -119
- package/dist/infrastructure/api/providers/cache.provider.d.ts +0 -15
- package/dist/server.js +94 -119
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -979,10 +979,10 @@ var init_dist = __esm(() => {
|
|
|
979
979
|
// ../utils/src/port.ts
|
|
980
980
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
981
981
|
import { createServer } from "node:net";
|
|
982
|
-
import
|
|
982
|
+
import * as os from "node:os";
|
|
983
983
|
import { join } from "node:path";
|
|
984
984
|
function getRegistryPath() {
|
|
985
|
-
const home = homedir();
|
|
985
|
+
const home = os.homedir();
|
|
986
986
|
const dir = join(home, ".playcademy");
|
|
987
987
|
if (!existsSync(dir)) {
|
|
988
988
|
mkdirSync(dir, { recursive: true });
|
|
@@ -1078,7 +1078,7 @@ var package_default;
|
|
|
1078
1078
|
var init_package = __esm(() => {
|
|
1079
1079
|
package_default = {
|
|
1080
1080
|
name: "@playcademy/sandbox",
|
|
1081
|
-
version: "0.5.1-beta.
|
|
1081
|
+
version: "0.5.1-beta.5",
|
|
1082
1082
|
description: "Local development server for Playcademy game development",
|
|
1083
1083
|
type: "module",
|
|
1084
1084
|
exports: {
|
|
@@ -22505,7 +22505,6 @@ class DeployJobService {
|
|
|
22505
22505
|
"app.deploy_job.outcome": "succeeded",
|
|
22506
22506
|
"app.deploy_job.run_duration_ms": DeployJobService.elapsedMsSince(new Date(runStartedAt))
|
|
22507
22507
|
});
|
|
22508
|
-
await this.deps.cache.refreshGameOrigins().catch(catchAttrs("deploy_job.cache_refresh"));
|
|
22509
22508
|
await this.deleteCodeBundle(jobId);
|
|
22510
22509
|
} catch (error) {
|
|
22511
22510
|
clearInterval(heartbeat);
|
|
@@ -26423,7 +26422,7 @@ ${file}:${line3}:${column2}: ERROR: ${pluginText}${e.text}`;
|
|
|
26423
26422
|
return result;
|
|
26424
26423
|
}
|
|
26425
26424
|
var fs2 = __require("fs");
|
|
26426
|
-
var
|
|
26425
|
+
var os2 = __require("os");
|
|
26427
26426
|
var path = __require("path");
|
|
26428
26427
|
var ESBUILD_BINARY_PATH = process.env.ESBUILD_BINARY_PATH || ESBUILD_BINARY_PATH;
|
|
26429
26428
|
var isValidBinaryPath = (x) => !!x && x !== "/usr/bin/esbuild";
|
|
@@ -26465,7 +26464,7 @@ ${file}:${line3}:${column2}: ERROR: ${pluginText}${e.text}`;
|
|
|
26465
26464
|
let pkg;
|
|
26466
26465
|
let subpath;
|
|
26467
26466
|
let isWASM = false;
|
|
26468
|
-
let platformKey = `${process.platform} ${
|
|
26467
|
+
let platformKey = `${process.platform} ${os2.arch()} ${os2.endianness()}`;
|
|
26469
26468
|
if (platformKey in knownWindowsPackages) {
|
|
26470
26469
|
pkg = knownWindowsPackages[platformKey];
|
|
26471
26470
|
subpath = "esbuild.exe";
|
|
@@ -26608,7 +26607,7 @@ for your current platform.`);
|
|
|
26608
26607
|
var crypto3 = __require("crypto");
|
|
26609
26608
|
var path2 = __require("path");
|
|
26610
26609
|
var fs22 = __require("fs");
|
|
26611
|
-
var
|
|
26610
|
+
var os22 = __require("os");
|
|
26612
26611
|
var tty = __require("tty");
|
|
26613
26612
|
var worker_threads;
|
|
26614
26613
|
if (process.env.ESBUILD_WORKER_THREADS !== "0") {
|
|
@@ -26919,7 +26918,7 @@ More information: The file containing the code for esbuild's JavaScript API (${_
|
|
|
26919
26918
|
afterClose(null);
|
|
26920
26919
|
};
|
|
26921
26920
|
var randomFileName = () => {
|
|
26922
|
-
return path2.join(
|
|
26921
|
+
return path2.join(os22.tmpdir(), `esbuild-${crypto3.randomBytes(32).toString("hex")}`);
|
|
26923
26922
|
};
|
|
26924
26923
|
var workerThreadService = null;
|
|
26925
26924
|
var startWorkerThreadService = (worker_threads2) => {
|
|
@@ -27181,7 +27180,8 @@ class DeployService {
|
|
|
27181
27180
|
expiresIn: null,
|
|
27182
27181
|
permissions: {
|
|
27183
27182
|
games: [`read:${slug}`, `write:${slug}`]
|
|
27184
|
-
}
|
|
27183
|
+
},
|
|
27184
|
+
rateLimitEnabled: false
|
|
27185
27185
|
});
|
|
27186
27186
|
setAttribute("app.deploy.api_key_outcome", "created");
|
|
27187
27187
|
return apiKey;
|
|
@@ -27242,9 +27242,9 @@ class DeployService {
|
|
|
27242
27242
|
throw new ValidationError("Uploaded file is empty or not found");
|
|
27243
27243
|
}
|
|
27244
27244
|
setAttribute("app.deploy.asset_upload_size", frontendZip.length);
|
|
27245
|
-
const
|
|
27245
|
+
const os2 = await import("os");
|
|
27246
27246
|
const path = await import("path");
|
|
27247
|
-
const tempDir = path.join(
|
|
27247
|
+
const tempDir = path.join(os2.tmpdir(), `playcademy-deploy-${gameId}-${Date.now()}`);
|
|
27248
27248
|
const assetsPath = path.join(tempDir, "dist");
|
|
27249
27249
|
await withSpan("deploy.extract_assets", () => extractZip(frontendZip, assetsPath));
|
|
27250
27250
|
uploadDeps.deleteObject(uploadToken).catch(catchAttrs("deploy.temp_cleanup"));
|
|
@@ -27857,6 +27857,31 @@ var init_game_service = __esm(() => {
|
|
|
27857
27857
|
static changedFields(data) {
|
|
27858
27858
|
return Object.entries(data).filter(([, value]) => value !== undefined).map(([key]) => key).toSorted().join(",");
|
|
27859
27859
|
}
|
|
27860
|
+
static safeOrigin(game2) {
|
|
27861
|
+
if (!game2 || game2.gameType !== "external" || !game2.externalUrl) {
|
|
27862
|
+
return;
|
|
27863
|
+
}
|
|
27864
|
+
try {
|
|
27865
|
+
return new URL(game2.externalUrl).origin;
|
|
27866
|
+
} catch {
|
|
27867
|
+
return;
|
|
27868
|
+
}
|
|
27869
|
+
}
|
|
27870
|
+
cleanupStaleOrigin(origin, excludeGameId) {
|
|
27871
|
+
if (!this.deps.corsKvs) {
|
|
27872
|
+
return;
|
|
27873
|
+
}
|
|
27874
|
+
const corsKvs = this.deps.corsKvs;
|
|
27875
|
+
const db2 = this.deps.db;
|
|
27876
|
+
(async () => {
|
|
27877
|
+
const sharesOrigin = await db2.select({ id: games.id }).from(games).where(and(ne(games.id, excludeGameId), eq(games.gameType, "external"), or(eq(games.externalUrl, origin), like(games.externalUrl, `${origin}/%`)))).limit(1);
|
|
27878
|
+
if (sharesOrigin.length === 0) {
|
|
27879
|
+
await corsKvs.deleteOrigin(origin);
|
|
27880
|
+
} else {
|
|
27881
|
+
setAttribute("app.cors_kvs.delete_skipped", true);
|
|
27882
|
+
}
|
|
27883
|
+
})().catch(catchAttrs("cors_kvs.delete_origin", {}));
|
|
27884
|
+
}
|
|
27860
27885
|
async list(caller) {
|
|
27861
27886
|
const db2 = this.deps.db;
|
|
27862
27887
|
const isAdmin = caller?.role === "admin";
|
|
@@ -28159,6 +28184,18 @@ var init_game_service = __esm(() => {
|
|
|
28159
28184
|
"app.game.next_visibility": data.visibility !== undefined ? gameResponse.visibility : undefined
|
|
28160
28185
|
});
|
|
28161
28186
|
GameService.recordGameShape(gameResponse);
|
|
28187
|
+
if (this.deps.corsKvs) {
|
|
28188
|
+
const prevOrigin = GameService.safeOrigin(existingGame);
|
|
28189
|
+
const nextOrigin = GameService.safeOrigin(gameResponse);
|
|
28190
|
+
if (nextOrigin) {
|
|
28191
|
+
setAttribute("app.cors_kvs.origin", nextOrigin);
|
|
28192
|
+
this.deps.corsKvs.putOrigin(nextOrigin).catch(catchAttrs("cors_kvs.put_origin", {}));
|
|
28193
|
+
}
|
|
28194
|
+
if (prevOrigin && prevOrigin !== nextOrigin) {
|
|
28195
|
+
setAttribute("app.cors_kvs.prev_origin", prevOrigin);
|
|
28196
|
+
this.cleanupStaleOrigin(prevOrigin, gameResponse.id);
|
|
28197
|
+
}
|
|
28198
|
+
}
|
|
28162
28199
|
return gameResponse;
|
|
28163
28200
|
}
|
|
28164
28201
|
async updateMetadata(gameId, data, user) {
|
|
@@ -28277,6 +28314,11 @@ var init_game_service = __esm(() => {
|
|
|
28277
28314
|
setAttribute("app.game.api_key_cleanup_error", errorMessage(error));
|
|
28278
28315
|
}
|
|
28279
28316
|
}
|
|
28317
|
+
const corsOrigin = GameService.safeOrigin(gameToDelete);
|
|
28318
|
+
if (this.deps.corsKvs && corsOrigin) {
|
|
28319
|
+
setAttribute("app.cors_kvs.origin", corsOrigin);
|
|
28320
|
+
this.cleanupStaleOrigin(corsOrigin, gameId);
|
|
28321
|
+
}
|
|
28280
28322
|
return {
|
|
28281
28323
|
slug: gameToDelete.slug,
|
|
28282
28324
|
displayName: gameToDelete.displayName
|
|
@@ -28408,12 +28450,13 @@ var init_logs_service = __esm(() => {
|
|
|
28408
28450
|
|
|
28409
28451
|
// ../api-core/src/services/factory/game.ts
|
|
28410
28452
|
function createGameServices(deps) {
|
|
28411
|
-
const { db: db2, config: config2, cloudflare: cloudflare2, auth: auth2, storage, cache, alerts } = deps;
|
|
28453
|
+
const { db: db2, config: config2, cloudflare: cloudflare2, corsKvs, auth: auth2, storage, cache, alerts } = deps;
|
|
28412
28454
|
const game2 = new GameService({
|
|
28413
28455
|
db: db2,
|
|
28414
28456
|
alerts,
|
|
28415
28457
|
cache,
|
|
28416
28458
|
cloudflare: cloudflare2,
|
|
28459
|
+
corsKvs,
|
|
28417
28460
|
deleteApiKeyByName: auth2.deleteApiKeyByName.bind(auth2)
|
|
28418
28461
|
});
|
|
28419
28462
|
const gameMember = new GameMemberService({
|
|
@@ -28434,7 +28477,6 @@ function createGameServices(deps) {
|
|
|
28434
28477
|
db: db2,
|
|
28435
28478
|
uploadBucket: config2.uploadBucket,
|
|
28436
28479
|
storage,
|
|
28437
|
-
cache,
|
|
28438
28480
|
validateDeveloperAccessBySlug: (user, slug) => game2.validateDeveloperAccessBySlug(user, slug),
|
|
28439
28481
|
runDeploy: (slug, request, user, uploadDeps, extractZip) => deploy.deploy(slug, request, user, uploadDeps, extractZip),
|
|
28440
28482
|
notifyDeploymentFailure: (slug, displayName, error, developerInfo) => deploy.notifyDeploymentFailure(slug, displayName, error, developerInfo)
|
|
@@ -29319,6 +29361,9 @@ class DomainService {
|
|
|
29319
29361
|
addEvent("domain.cloudflare_hostname_created", {
|
|
29320
29362
|
"app.domain.cloudflare_id": cfHostname.id
|
|
29321
29363
|
});
|
|
29364
|
+
const corsOrigin = `https://${hostname}`;
|
|
29365
|
+
setAttribute("app.cors_kvs.origin", corsOrigin);
|
|
29366
|
+
this.deps.corsKvs?.putOrigin(corsOrigin).catch(catchAttrs("cors_kvs.put_origin", {}));
|
|
29322
29367
|
return customHostname;
|
|
29323
29368
|
}
|
|
29324
29369
|
async list(slug, environment, user) {
|
|
@@ -29402,6 +29447,9 @@ class DomainService {
|
|
|
29402
29447
|
"app.domain.status": dbHostname.status,
|
|
29403
29448
|
"app.domain.ssl_status": dbHostname.sslStatus
|
|
29404
29449
|
});
|
|
29450
|
+
const corsOrigin = `https://${hostname}`;
|
|
29451
|
+
setAttribute("app.cors_kvs.origin", corsOrigin);
|
|
29452
|
+
this.deps.corsKvs?.deleteOrigin(corsOrigin).catch(catchAttrs("cors_kvs.delete_origin", {}));
|
|
29405
29453
|
}
|
|
29406
29454
|
}
|
|
29407
29455
|
var init_domain_service = __esm(() => {
|
|
@@ -29696,12 +29744,13 @@ var init_secrets_service = __esm(() => {
|
|
|
29696
29744
|
});
|
|
29697
29745
|
|
|
29698
29746
|
// ../edge-play/src/constants.ts
|
|
29699
|
-
var ROUTES;
|
|
29747
|
+
var ASSET_ROUTE_PREFIX = "/api/assets/", ROUTES;
|
|
29700
29748
|
var init_constants3 = __esm(() => {
|
|
29701
29749
|
init_src();
|
|
29702
29750
|
ROUTES = {
|
|
29703
29751
|
INDEX: "/api",
|
|
29704
29752
|
HEALTH: "/api/health",
|
|
29753
|
+
ASSETS: `${ASSET_ROUTE_PREFIX}*`,
|
|
29705
29754
|
TIMEBACK: {
|
|
29706
29755
|
END_ACTIVITY: `/api${TIMEBACK_ROUTES.END_ACTIVITY}`,
|
|
29707
29756
|
GET_XP: `/api${TIMEBACK_ROUTES.GET_XP}`,
|
|
@@ -29858,7 +29907,8 @@ class SeedService {
|
|
|
29858
29907
|
}, {
|
|
29859
29908
|
bindings: { d1: [deploymentId], r2: [], kv: [] },
|
|
29860
29909
|
keepAssets: false,
|
|
29861
|
-
compatibilityDate: CLOUDFLARE_COMPATIBILITY_DATE
|
|
29910
|
+
compatibilityDate: CLOUDFLARE_COMPATIBILITY_DATE,
|
|
29911
|
+
observability: false
|
|
29862
29912
|
});
|
|
29863
29913
|
if (secrets && Object.keys(secrets).length > 0) {
|
|
29864
29914
|
await cf.setSecrets(seedDeploymentId, prefixSecrets(secrets));
|
|
@@ -32125,44 +32175,6 @@ function validateSessionData(sessionData) {
|
|
|
32125
32175
|
throw new ConfigurationError("sensorUrl", 'Sensor URL is required for Caliper events. Provide it in sessionData.sensorUrl (e.g., "https://hub.playcademy.net/p/your-game")');
|
|
32126
32176
|
}
|
|
32127
32177
|
}
|
|
32128
|
-
function getAttemptMultiplier(attemptNumber) {
|
|
32129
|
-
switch (attemptNumber) {
|
|
32130
|
-
case 1: {
|
|
32131
|
-
return 1;
|
|
32132
|
-
}
|
|
32133
|
-
case 2: {
|
|
32134
|
-
return 0.5;
|
|
32135
|
-
}
|
|
32136
|
-
case 3: {
|
|
32137
|
-
return 0.25;
|
|
32138
|
-
}
|
|
32139
|
-
default: {
|
|
32140
|
-
return 0;
|
|
32141
|
-
}
|
|
32142
|
-
}
|
|
32143
|
-
}
|
|
32144
|
-
function getAccuracyMultiplier(accuracy) {
|
|
32145
|
-
if (!Number.isFinite(accuracy) || accuracy < 0) {
|
|
32146
|
-
return 0;
|
|
32147
|
-
}
|
|
32148
|
-
if (accuracy >= PERFECT_ACCURACY_THRESHOLD) {
|
|
32149
|
-
return 1.25;
|
|
32150
|
-
} else if (accuracy >= 0.8) {
|
|
32151
|
-
return 1;
|
|
32152
|
-
} else {
|
|
32153
|
-
return 0;
|
|
32154
|
-
}
|
|
32155
|
-
}
|
|
32156
|
-
function calculateXp(durationSeconds, accuracy, attemptNumber) {
|
|
32157
|
-
if (!Number.isFinite(durationSeconds) || durationSeconds <= 0) {
|
|
32158
|
-
return 0;
|
|
32159
|
-
}
|
|
32160
|
-
const durationMinutes = durationSeconds / 60;
|
|
32161
|
-
const baseXp = Number(durationMinutes);
|
|
32162
|
-
const accuracyMultiplier = getAccuracyMultiplier(accuracy);
|
|
32163
|
-
const attemptMultiplier = getAttemptMultiplier(attemptNumber);
|
|
32164
|
-
return Math.round(baseXp * accuracyMultiplier * attemptMultiplier * 10) / 10;
|
|
32165
|
-
}
|
|
32166
32178
|
|
|
32167
32179
|
class ProgressRecorder {
|
|
32168
32180
|
studentResolver;
|
|
@@ -32181,10 +32193,15 @@ class ProgressRecorder {
|
|
|
32181
32193
|
validateProgressData(progressData);
|
|
32182
32194
|
const { ids, activityId, activityName, courseName, student } = await this.resolveContext(courseId, studentIdentifier, progressData);
|
|
32183
32195
|
const { id: studentId, email: studentEmail } = student;
|
|
32184
|
-
const {
|
|
32196
|
+
const {
|
|
32197
|
+
score,
|
|
32198
|
+
totalQuestions,
|
|
32199
|
+
correctQuestions,
|
|
32200
|
+
xpEarned = 0,
|
|
32201
|
+
attemptNumber
|
|
32202
|
+
} = progressData;
|
|
32185
32203
|
const actualLineItemId = await this.resolveAssessmentLineItem(activityId, activityName, progressData.classId, ids);
|
|
32186
32204
|
const currentAttemptNumber = await this.resolveAttemptNumber(attemptNumber, score, studentId, actualLineItemId);
|
|
32187
|
-
const calculatedXp = this.calculateXpForProgress(progressData, totalQuestions, correctQuestions, xpEarned, currentAttemptNumber);
|
|
32188
32205
|
let extensions = progressData.extensions;
|
|
32189
32206
|
const masteryProgress = await this.masteryTracker.checkProgress({
|
|
32190
32207
|
studentId,
|
|
@@ -32215,7 +32232,7 @@ class ProgressRecorder {
|
|
|
32215
32232
|
studentId,
|
|
32216
32233
|
attemptNumber: currentAttemptNumber,
|
|
32217
32234
|
score,
|
|
32218
|
-
xp:
|
|
32235
|
+
xp: xpEarned,
|
|
32219
32236
|
scoreStatus,
|
|
32220
32237
|
inProgress,
|
|
32221
32238
|
appName: progressData.appName,
|
|
@@ -32254,7 +32271,7 @@ class ProgressRecorder {
|
|
|
32254
32271
|
courseName,
|
|
32255
32272
|
totalQuestions,
|
|
32256
32273
|
correctQuestions,
|
|
32257
|
-
xpEarned
|
|
32274
|
+
xpEarned,
|
|
32258
32275
|
masteredUnits: effectiveMasteredUnits || undefined,
|
|
32259
32276
|
attemptNumber: currentAttemptNumber,
|
|
32260
32277
|
progressData,
|
|
@@ -32262,7 +32279,7 @@ class ProgressRecorder {
|
|
|
32262
32279
|
runId: progressData.runId
|
|
32263
32280
|
});
|
|
32264
32281
|
return {
|
|
32265
|
-
xpAwarded:
|
|
32282
|
+
xpAwarded: xpEarned,
|
|
32266
32283
|
attemptNumber: currentAttemptNumber,
|
|
32267
32284
|
masteredUnitsApplied: effectiveMasteredUnits,
|
|
32268
32285
|
pctCompleteApp,
|
|
@@ -32296,16 +32313,6 @@ class ProgressRecorder {
|
|
|
32296
32313
|
}
|
|
32297
32314
|
return 1;
|
|
32298
32315
|
}
|
|
32299
|
-
calculateXpForProgress(progressData, totalQuestions, correctQuestions, xpEarned, attemptNumber) {
|
|
32300
|
-
if (xpEarned !== undefined) {
|
|
32301
|
-
return xpEarned;
|
|
32302
|
-
}
|
|
32303
|
-
if (progressData.durationSeconds && totalQuestions && correctQuestions) {
|
|
32304
|
-
const accuracy = correctQuestions / totalQuestions;
|
|
32305
|
-
return calculateXp(progressData.durationSeconds, accuracy, attemptNumber);
|
|
32306
|
-
}
|
|
32307
|
-
return 0;
|
|
32308
|
-
}
|
|
32309
32316
|
async getOrCreateLineItem(lineItemId, activityName, classId, ids) {
|
|
32310
32317
|
try {
|
|
32311
32318
|
const lineItem = await this.onerosterNamespace.assessmentLineItems.findOrCreate(lineItemId, {
|
|
@@ -32963,7 +32970,7 @@ var __defProp2, __export2 = (target, all) => {
|
|
|
32963
32970
|
configurable: true,
|
|
32964
32971
|
set: (newValue) => all[name3] = () => newValue
|
|
32965
32972
|
});
|
|
32966
|
-
}, __esm2 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), TIMEBACK_API_URLS, QTI_API_URL = "https://qti.alpha-1edtech.ai/api", TIMEBACK_AUTH_URLS, CALIPER_API_URLS, ONEROSTER_ENDPOINTS, QTI_ENDPOINTS, CALIPER_ENDPOINTS, CALIPER_CONSTANTS, TIMEBACK_EVENT_TYPES, TIMEBACK_ACTIONS, TIMEBACK_TYPES, ACTIVITY_METRIC_TYPES, TIME_METRIC_TYPES, TIMEBACK_SUBJECTS, TIMEBACK_GRADE_LEVELS, TIMEBACK_GRADE_LEVEL_LABELS, CALIPER_SUBJECTS, ONEROSTER_STATUS, SCORE_STATUS, ENV_VARS, HTTP_DEFAULTS, AUTH_DEFAULTS, CACHE_DEFAULTS, CONFIG_DEFAULTS, PLAYCADEMY_DEFAULTS, RESOURCE_DEFAULTS, HTTP_STATUS, ERROR_NAMES, init_constants4, exports_verify, init_verify, TimebackError, TimebackApiError, TimebackAuthenticationError, StudentNotFoundError, ConfigurationError, ResourceNotFoundError, SUBJECT_VALUES, GRADE_VALUES, TimebackAuthError, UUID_PATTERN, storage,
|
|
32973
|
+
}, __esm2 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), TIMEBACK_API_URLS, QTI_API_URL = "https://qti.alpha-1edtech.ai/api", TIMEBACK_AUTH_URLS, CALIPER_API_URLS, ONEROSTER_ENDPOINTS, QTI_ENDPOINTS, CALIPER_ENDPOINTS, CALIPER_CONSTANTS, TIMEBACK_EVENT_TYPES, TIMEBACK_ACTIONS, TIMEBACK_TYPES, ACTIVITY_METRIC_TYPES, TIME_METRIC_TYPES, TIMEBACK_SUBJECTS, TIMEBACK_GRADE_LEVELS, TIMEBACK_GRADE_LEVEL_LABELS, CALIPER_SUBJECTS, ONEROSTER_STATUS, SCORE_STATUS, ENV_VARS, HTTP_DEFAULTS, AUTH_DEFAULTS, CACHE_DEFAULTS, CONFIG_DEFAULTS, PLAYCADEMY_DEFAULTS, RESOURCE_DEFAULTS, HTTP_STATUS, ERROR_NAMES, init_constants4, exports_verify, init_verify, TimebackError, TimebackApiError, TimebackAuthenticationError, StudentNotFoundError, ConfigurationError, ResourceNotFoundError, SUBJECT_VALUES, GRADE_VALUES, TimebackAuthError, UUID_PATTERN, storage, EmailSchema, StudentSourcedIdSchema, StudentIdentifierSchema;
|
|
32967
32974
|
var init_dist2 = __esm(() => {
|
|
32968
32975
|
init_src();
|
|
32969
32976
|
init_src();
|
|
@@ -34211,13 +34218,14 @@ var init_emoji = __esm(() => {
|
|
|
34211
34218
|
});
|
|
34212
34219
|
|
|
34213
34220
|
// ../data/src/domains/game/schemas.ts
|
|
34214
|
-
var GameEmojiSchema, GameMetadataRecordSchema, InsertGameSchema, UpdateGameSchema, InsertGameDeploymentSchema, InsertGameDeployJobSchema, UpsertGameMetadataSchema, PatchGameMetadataSchema, AddGameMemberSchema, UpdateGameMemberRoleSchema, ALLOWED_UPLOAD_EXTENSIONS, InitiateUploadSchema, AddCustomHostnameSchema, SetSecretsRequestSchema, SeedRequestSchema, SchemaInfoSchema, DatabaseResetRequestSchema, VerifyTokenSchema, KVSeedRequestSchema, DeployRequestSchema;
|
|
34221
|
+
var HttpUrlSchema, GameEmojiSchema, GameMetadataRecordSchema, InsertGameSchema, UpdateGameSchema, InsertGameDeploymentSchema, InsertGameDeployJobSchema, UpsertGameMetadataSchema, PatchGameMetadataSchema, AddGameMemberSchema, UpdateGameMemberRoleSchema, ALLOWED_UPLOAD_EXTENSIONS, InitiateUploadSchema, AddCustomHostnameSchema, SetSecretsRequestSchema, SeedRequestSchema, SchemaInfoSchema, DatabaseResetRequestSchema, VerifyTokenSchema, KVSeedRequestSchema, DeployRequestSchema;
|
|
34215
34222
|
var init_schemas2 = __esm(() => {
|
|
34216
34223
|
init_drizzle_zod();
|
|
34217
34224
|
init_esm();
|
|
34218
34225
|
init_src();
|
|
34219
34226
|
init_emoji();
|
|
34220
34227
|
init_table5();
|
|
34228
|
+
HttpUrlSchema = exports_external.string().url().refine((url2) => /^https?:\/\//i.test(url2), { message: "URL must use http or https" });
|
|
34221
34229
|
GameEmojiSchema = exports_external.string().max(16).refine((value) => value.length === 0 || isSingleEmoji(value), {
|
|
34222
34230
|
message: "Emoji must be a single emoji."
|
|
34223
34231
|
});
|
|
@@ -34242,7 +34250,7 @@ var init_schemas2 = __esm(() => {
|
|
|
34242
34250
|
gameType: exports_external.enum(gameTypeEnum.enumValues).default("hosted"),
|
|
34243
34251
|
visibility: exports_external.enum(gameVisibilityEnum.enumValues).default("visible"),
|
|
34244
34252
|
deploymentUrl: exports_external.string().nullable().optional(),
|
|
34245
|
-
externalUrl:
|
|
34253
|
+
externalUrl: HttpUrlSchema.nullable().optional()
|
|
34246
34254
|
}).omit({
|
|
34247
34255
|
slug: true,
|
|
34248
34256
|
version: true
|
|
@@ -34265,7 +34273,7 @@ var init_schemas2 = __esm(() => {
|
|
|
34265
34273
|
gameType: exports_external.enum(gameTypeEnum.enumValues).optional(),
|
|
34266
34274
|
visibility: exports_external.enum(gameVisibilityEnum.enumValues).optional(),
|
|
34267
34275
|
deploymentUrl: exports_external.string().nullable().optional(),
|
|
34268
|
-
externalUrl:
|
|
34276
|
+
externalUrl: HttpUrlSchema.nullable().optional()
|
|
34269
34277
|
}).omit({
|
|
34270
34278
|
id: true,
|
|
34271
34279
|
slug: true,
|
|
@@ -34295,7 +34303,7 @@ var init_schemas2 = __esm(() => {
|
|
|
34295
34303
|
metadata: GameMetadataRecordSchema.optional().default({}),
|
|
34296
34304
|
gameType: exports_external.enum(gameTypeEnum.enumValues).optional().default("hosted"),
|
|
34297
34305
|
visibility: exports_external.enum(gameVisibilityEnum.enumValues).optional(),
|
|
34298
|
-
externalUrl:
|
|
34306
|
+
externalUrl: HttpUrlSchema.optional()
|
|
34299
34307
|
}).refine((data) => {
|
|
34300
34308
|
if (data.gameType === "external" && !data.externalUrl) {
|
|
34301
34309
|
return false;
|
|
@@ -34494,7 +34502,7 @@ var init_schemas4 = __esm(() => {
|
|
|
34494
34502
|
activeSeconds: exports_external.number().nonnegative(),
|
|
34495
34503
|
inactiveSeconds: exports_external.number().nonnegative().optional()
|
|
34496
34504
|
}).optional(),
|
|
34497
|
-
xpEarned: exports_external.number()
|
|
34505
|
+
xpEarned: exports_external.number(),
|
|
34498
34506
|
masteredUnits: exports_external.number().optional(),
|
|
34499
34507
|
masteredUnitsAbsolute: exports_external.number().int().nonnegative().optional(),
|
|
34500
34508
|
extensions: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
|
|
@@ -39206,6 +39214,7 @@ function createPlatformServices(deps) {
|
|
|
39206
39214
|
db: db2,
|
|
39207
39215
|
config: config2,
|
|
39208
39216
|
cloudflare: cloudflare2,
|
|
39217
|
+
corsKvs,
|
|
39209
39218
|
storage: storage2,
|
|
39210
39219
|
r2Storage,
|
|
39211
39220
|
timebackClient,
|
|
@@ -39227,7 +39236,7 @@ function createPlatformServices(deps) {
|
|
|
39227
39236
|
});
|
|
39228
39237
|
const kv = new KVService({ db: db2, cloudflare: cloudflare2, validateDeveloperAccessBySlug });
|
|
39229
39238
|
const secrets = new SecretsService({ config: config2, cloudflare: cloudflare2, validateDeveloperAccessBySlug });
|
|
39230
|
-
const domain = new DomainService({ db: db2, cloudflare: cloudflare2, validateDeveloperAccessBySlug });
|
|
39239
|
+
const domain = new DomainService({ db: db2, cloudflare: cloudflare2, corsKvs, validateDeveloperAccessBySlug });
|
|
39231
39240
|
const database = new DatabaseService({
|
|
39232
39241
|
db: db2,
|
|
39233
39242
|
config: config2,
|
|
@@ -39905,7 +39914,7 @@ var init_standalone = __esm(() => {
|
|
|
39905
39914
|
|
|
39906
39915
|
// ../api-core/src/services/factory/index.ts
|
|
39907
39916
|
function createServices(ctx) {
|
|
39908
|
-
const { db: db2, config: config2, providers, cloudflare: cloudflare2, timeback: timeback2, discord } = ctx;
|
|
39917
|
+
const { db: db2, config: config2, providers, cloudflare: cloudflare2, timeback: timeback2, discord, corsKvs } = ctx;
|
|
39909
39918
|
const { auth: auth2, storage: storage2, r2Storage, cache } = providers;
|
|
39910
39919
|
const infra2 = createInfraServices({
|
|
39911
39920
|
db: db2,
|
|
@@ -39919,6 +39928,7 @@ function createServices(ctx) {
|
|
|
39919
39928
|
db: db2,
|
|
39920
39929
|
config: config2,
|
|
39921
39930
|
cloudflare: cloudflare2,
|
|
39931
|
+
corsKvs,
|
|
39922
39932
|
auth: auth2,
|
|
39923
39933
|
storage: storage2,
|
|
39924
39934
|
cache,
|
|
@@ -39928,6 +39938,7 @@ function createServices(ctx) {
|
|
|
39928
39938
|
db: db2,
|
|
39929
39939
|
config: config2,
|
|
39930
39940
|
cloudflare: cloudflare2,
|
|
39941
|
+
corsKvs,
|
|
39931
39942
|
storage: storage2,
|
|
39932
39943
|
r2Storage,
|
|
39933
39944
|
timebackClient: timeback2,
|
|
@@ -40116,16 +40127,6 @@ var init_auth_provider = __esm(() => {
|
|
|
40116
40127
|
// src/infrastructure/api/providers/cache.provider.ts
|
|
40117
40128
|
function createSandboxCacheProvider() {
|
|
40118
40129
|
return {
|
|
40119
|
-
async refreshGameOrigins() {
|
|
40120
|
-
gameOrigins = ["http://localhost:3000", "http://localhost:5173"];
|
|
40121
|
-
lastRefreshTime = Date.now();
|
|
40122
|
-
},
|
|
40123
|
-
getGameOriginState() {
|
|
40124
|
-
return {
|
|
40125
|
-
origins: gameOrigins,
|
|
40126
|
-
lastRefreshTime
|
|
40127
|
-
};
|
|
40128
|
-
},
|
|
40129
40130
|
async get(key) {
|
|
40130
40131
|
const entry = cache.get(key);
|
|
40131
40132
|
if (!entry) {
|
|
@@ -40150,13 +40151,10 @@ function createSandboxCacheProvider() {
|
|
|
40150
40151
|
}
|
|
40151
40152
|
function clearSandboxCache() {
|
|
40152
40153
|
cache.clear();
|
|
40153
|
-
gameOrigins = [];
|
|
40154
|
-
lastRefreshTime = 0;
|
|
40155
40154
|
}
|
|
40156
|
-
var cache
|
|
40155
|
+
var cache;
|
|
40157
40156
|
var init_cache_provider = __esm(() => {
|
|
40158
40157
|
cache = new Map;
|
|
40159
|
-
gameOrigins = [];
|
|
40160
40158
|
});
|
|
40161
40159
|
|
|
40162
40160
|
// src/infrastructure/api/providers/storage.provider.ts
|
|
@@ -49365,7 +49363,7 @@ var require_has_flag = __commonJS((exports, module2) => {
|
|
|
49365
49363
|
|
|
49366
49364
|
// ../../node_modules/.bun/supports-color@7.2.0/node_modules/supports-color/index.js
|
|
49367
49365
|
var require_supports_color = __commonJS((exports, module2) => {
|
|
49368
|
-
var
|
|
49366
|
+
var os2 = __require("os");
|
|
49369
49367
|
var tty = __require("tty");
|
|
49370
49368
|
var hasFlag = require_has_flag();
|
|
49371
49369
|
var { env } = process;
|
|
@@ -49413,7 +49411,7 @@ var require_supports_color = __commonJS((exports, module2) => {
|
|
|
49413
49411
|
return min;
|
|
49414
49412
|
}
|
|
49415
49413
|
if (process.platform === "win32") {
|
|
49416
|
-
const osRelease =
|
|
49414
|
+
const osRelease = os2.release().split(".");
|
|
49417
49415
|
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
49418
49416
|
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
49419
49417
|
}
|
|
@@ -54506,7 +54504,7 @@ __export(exports_api, {
|
|
|
54506
54504
|
generateDrizzleJson: () => generateDrizzleJson
|
|
54507
54505
|
});
|
|
54508
54506
|
import process2 from "process";
|
|
54509
|
-
import
|
|
54507
|
+
import os2 from "os";
|
|
54510
54508
|
import tty from "tty";
|
|
54511
54509
|
import { randomUUID } from "crypto";
|
|
54512
54510
|
function assembleStyles() {
|
|
@@ -54677,7 +54675,7 @@ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
|
|
|
54677
54675
|
return min2;
|
|
54678
54676
|
}
|
|
54679
54677
|
if (process2.platform === "win32") {
|
|
54680
|
-
const osRelease =
|
|
54678
|
+
const osRelease = os2.release().split(".");
|
|
54681
54679
|
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
54682
54680
|
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
54683
54681
|
}
|
|
@@ -67517,7 +67515,7 @@ Is ${source_default.bold.blue(this.base.name)} schema created or renamed from an
|
|
|
67517
67515
|
});
|
|
67518
67516
|
require_supports_colors = __commonJS2({
|
|
67519
67517
|
"../node_modules/.pnpm/colors@1.4.0/node_modules/colors/lib/system/supports-colors.js"(exports, module2) {
|
|
67520
|
-
var
|
|
67518
|
+
var os22 = __require2("os");
|
|
67521
67519
|
var hasFlag2 = require_has_flag2();
|
|
67522
67520
|
var env2 = process.env;
|
|
67523
67521
|
var forceColor = undefined;
|
|
@@ -67555,7 +67553,7 @@ Is ${source_default.bold.blue(this.base.name)} schema created or renamed from an
|
|
|
67555
67553
|
}
|
|
67556
67554
|
var min2 = forceColor ? 1 : 0;
|
|
67557
67555
|
if (process.platform === "win32") {
|
|
67558
|
-
var osRelease =
|
|
67556
|
+
var osRelease = os22.release().split(".");
|
|
67559
67557
|
if (Number(process.versions.node.split(".")[0]) >= 8 && Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
67560
67558
|
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
67561
67559
|
}
|
|
@@ -95977,28 +95975,6 @@ var init_utils11 = __esm(() => {
|
|
|
95977
95975
|
init_validation_util();
|
|
95978
95976
|
});
|
|
95979
95977
|
|
|
95980
|
-
// ../api-core/src/controllers/admin.controller.ts
|
|
95981
|
-
var getAllowedOrigins, admin;
|
|
95982
|
-
var init_admin_controller = __esm(() => {
|
|
95983
|
-
init_utils11();
|
|
95984
|
-
getAllowedOrigins = requireAdmin(async (ctx) => {
|
|
95985
|
-
const shouldRefresh = ctx.url.searchParams.get("refresh") === "true";
|
|
95986
|
-
if (shouldRefresh) {
|
|
95987
|
-
await ctx.providers.cache.refreshGameOrigins();
|
|
95988
|
-
}
|
|
95989
|
-
const { origins, lastRefreshTime: lastRefreshTime2 } = ctx.providers.cache.getGameOriginState();
|
|
95990
|
-
return {
|
|
95991
|
-
origins,
|
|
95992
|
-
count: origins.length,
|
|
95993
|
-
lastRefresh: lastRefreshTime2 > 0 ? new Date(lastRefreshTime2).toISOString() : null,
|
|
95994
|
-
cacheAge: lastRefreshTime2 > 0 ? Date.now() - lastRefreshTime2 : null
|
|
95995
|
-
};
|
|
95996
|
-
});
|
|
95997
|
-
admin = defineControllerNames("admin", {
|
|
95998
|
-
getAllowedOrigins
|
|
95999
|
-
});
|
|
96000
|
-
});
|
|
96001
|
-
|
|
96002
95978
|
// ../api-core/src/controllers/bucket.controller.ts
|
|
96003
95979
|
var listFiles, getFile, putFile, deleteFile, initiateUpload, bucket;
|
|
96004
95980
|
var init_bucket_controller = __esm(() => {
|
|
@@ -97430,7 +97406,6 @@ var init_verify_controller = __esm(() => {
|
|
|
97430
97406
|
|
|
97431
97407
|
// ../api-core/src/controllers/index.ts
|
|
97432
97408
|
var init_controllers = __esm(() => {
|
|
97433
|
-
init_admin_controller();
|
|
97434
97409
|
init_bucket_controller();
|
|
97435
97410
|
init_database_controller();
|
|
97436
97411
|
init_deploy_controller();
|
|
@@ -1,18 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sandbox Cache Provider
|
|
3
|
-
*
|
|
4
|
-
* In-memory cache for local development. Simple TTL-based expiration.
|
|
5
|
-
*
|
|
6
|
-
* @module infrastructure/api/providers/cache
|
|
7
|
-
*/
|
|
8
1
|
import type { CacheProvider } from '@playcademy/api-core/providers';
|
|
9
|
-
/**
|
|
10
|
-
* Create a sandbox cache provider.
|
|
11
|
-
*
|
|
12
|
-
* Uses in-memory storage with TTL support.
|
|
13
|
-
*/
|
|
14
2
|
export declare function createSandboxCacheProvider(): CacheProvider;
|
|
15
|
-
/**
|
|
16
|
-
* Clear all sandbox cache (useful for testing).
|
|
17
|
-
*/
|
|
18
3
|
export declare function clearSandboxCache(): void;
|
package/dist/server.js
CHANGED
|
@@ -978,10 +978,10 @@ var init_dist = __esm(() => {
|
|
|
978
978
|
// ../utils/src/port.ts
|
|
979
979
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
980
980
|
import { createServer } from "node:net";
|
|
981
|
-
import
|
|
981
|
+
import * as os from "node:os";
|
|
982
982
|
import { join } from "node:path";
|
|
983
983
|
function getRegistryPath() {
|
|
984
|
-
const home = homedir();
|
|
984
|
+
const home = os.homedir();
|
|
985
985
|
const dir = join(home, ".playcademy");
|
|
986
986
|
if (!existsSync(dir)) {
|
|
987
987
|
mkdirSync(dir, { recursive: true });
|
|
@@ -1077,7 +1077,7 @@ var package_default;
|
|
|
1077
1077
|
var init_package = __esm(() => {
|
|
1078
1078
|
package_default = {
|
|
1079
1079
|
name: "@playcademy/sandbox",
|
|
1080
|
-
version: "0.5.1-beta.
|
|
1080
|
+
version: "0.5.1-beta.5",
|
|
1081
1081
|
description: "Local development server for Playcademy game development",
|
|
1082
1082
|
type: "module",
|
|
1083
1083
|
exports: {
|
|
@@ -22504,7 +22504,6 @@ class DeployJobService {
|
|
|
22504
22504
|
"app.deploy_job.outcome": "succeeded",
|
|
22505
22505
|
"app.deploy_job.run_duration_ms": DeployJobService.elapsedMsSince(new Date(runStartedAt))
|
|
22506
22506
|
});
|
|
22507
|
-
await this.deps.cache.refreshGameOrigins().catch(catchAttrs("deploy_job.cache_refresh"));
|
|
22508
22507
|
await this.deleteCodeBundle(jobId);
|
|
22509
22508
|
} catch (error) {
|
|
22510
22509
|
clearInterval(heartbeat);
|
|
@@ -26422,7 +26421,7 @@ ${file}:${line3}:${column2}: ERROR: ${pluginText}${e.text}`;
|
|
|
26422
26421
|
return result;
|
|
26423
26422
|
}
|
|
26424
26423
|
var fs2 = __require("fs");
|
|
26425
|
-
var
|
|
26424
|
+
var os2 = __require("os");
|
|
26426
26425
|
var path = __require("path");
|
|
26427
26426
|
var ESBUILD_BINARY_PATH = process.env.ESBUILD_BINARY_PATH || ESBUILD_BINARY_PATH;
|
|
26428
26427
|
var isValidBinaryPath = (x) => !!x && x !== "/usr/bin/esbuild";
|
|
@@ -26464,7 +26463,7 @@ ${file}:${line3}:${column2}: ERROR: ${pluginText}${e.text}`;
|
|
|
26464
26463
|
let pkg;
|
|
26465
26464
|
let subpath;
|
|
26466
26465
|
let isWASM = false;
|
|
26467
|
-
let platformKey = `${process.platform} ${
|
|
26466
|
+
let platformKey = `${process.platform} ${os2.arch()} ${os2.endianness()}`;
|
|
26468
26467
|
if (platformKey in knownWindowsPackages) {
|
|
26469
26468
|
pkg = knownWindowsPackages[platformKey];
|
|
26470
26469
|
subpath = "esbuild.exe";
|
|
@@ -26607,7 +26606,7 @@ for your current platform.`);
|
|
|
26607
26606
|
var crypto3 = __require("crypto");
|
|
26608
26607
|
var path2 = __require("path");
|
|
26609
26608
|
var fs22 = __require("fs");
|
|
26610
|
-
var
|
|
26609
|
+
var os22 = __require("os");
|
|
26611
26610
|
var tty = __require("tty");
|
|
26612
26611
|
var worker_threads;
|
|
26613
26612
|
if (process.env.ESBUILD_WORKER_THREADS !== "0") {
|
|
@@ -26918,7 +26917,7 @@ More information: The file containing the code for esbuild's JavaScript API (${_
|
|
|
26918
26917
|
afterClose(null);
|
|
26919
26918
|
};
|
|
26920
26919
|
var randomFileName = () => {
|
|
26921
|
-
return path2.join(
|
|
26920
|
+
return path2.join(os22.tmpdir(), `esbuild-${crypto3.randomBytes(32).toString("hex")}`);
|
|
26922
26921
|
};
|
|
26923
26922
|
var workerThreadService = null;
|
|
26924
26923
|
var startWorkerThreadService = (worker_threads2) => {
|
|
@@ -27180,7 +27179,8 @@ class DeployService {
|
|
|
27180
27179
|
expiresIn: null,
|
|
27181
27180
|
permissions: {
|
|
27182
27181
|
games: [`read:${slug}`, `write:${slug}`]
|
|
27183
|
-
}
|
|
27182
|
+
},
|
|
27183
|
+
rateLimitEnabled: false
|
|
27184
27184
|
});
|
|
27185
27185
|
setAttribute("app.deploy.api_key_outcome", "created");
|
|
27186
27186
|
return apiKey;
|
|
@@ -27241,9 +27241,9 @@ class DeployService {
|
|
|
27241
27241
|
throw new ValidationError("Uploaded file is empty or not found");
|
|
27242
27242
|
}
|
|
27243
27243
|
setAttribute("app.deploy.asset_upload_size", frontendZip.length);
|
|
27244
|
-
const
|
|
27244
|
+
const os2 = await import("os");
|
|
27245
27245
|
const path = await import("path");
|
|
27246
|
-
const tempDir = path.join(
|
|
27246
|
+
const tempDir = path.join(os2.tmpdir(), `playcademy-deploy-${gameId}-${Date.now()}`);
|
|
27247
27247
|
const assetsPath = path.join(tempDir, "dist");
|
|
27248
27248
|
await withSpan("deploy.extract_assets", () => extractZip(frontendZip, assetsPath));
|
|
27249
27249
|
uploadDeps.deleteObject(uploadToken).catch(catchAttrs("deploy.temp_cleanup"));
|
|
@@ -27856,6 +27856,31 @@ var init_game_service = __esm(() => {
|
|
|
27856
27856
|
static changedFields(data) {
|
|
27857
27857
|
return Object.entries(data).filter(([, value]) => value !== undefined).map(([key]) => key).toSorted().join(",");
|
|
27858
27858
|
}
|
|
27859
|
+
static safeOrigin(game2) {
|
|
27860
|
+
if (!game2 || game2.gameType !== "external" || !game2.externalUrl) {
|
|
27861
|
+
return;
|
|
27862
|
+
}
|
|
27863
|
+
try {
|
|
27864
|
+
return new URL(game2.externalUrl).origin;
|
|
27865
|
+
} catch {
|
|
27866
|
+
return;
|
|
27867
|
+
}
|
|
27868
|
+
}
|
|
27869
|
+
cleanupStaleOrigin(origin, excludeGameId) {
|
|
27870
|
+
if (!this.deps.corsKvs) {
|
|
27871
|
+
return;
|
|
27872
|
+
}
|
|
27873
|
+
const corsKvs = this.deps.corsKvs;
|
|
27874
|
+
const db2 = this.deps.db;
|
|
27875
|
+
(async () => {
|
|
27876
|
+
const sharesOrigin = await db2.select({ id: games.id }).from(games).where(and(ne(games.id, excludeGameId), eq(games.gameType, "external"), or(eq(games.externalUrl, origin), like(games.externalUrl, `${origin}/%`)))).limit(1);
|
|
27877
|
+
if (sharesOrigin.length === 0) {
|
|
27878
|
+
await corsKvs.deleteOrigin(origin);
|
|
27879
|
+
} else {
|
|
27880
|
+
setAttribute("app.cors_kvs.delete_skipped", true);
|
|
27881
|
+
}
|
|
27882
|
+
})().catch(catchAttrs("cors_kvs.delete_origin", {}));
|
|
27883
|
+
}
|
|
27859
27884
|
async list(caller) {
|
|
27860
27885
|
const db2 = this.deps.db;
|
|
27861
27886
|
const isAdmin = caller?.role === "admin";
|
|
@@ -28158,6 +28183,18 @@ var init_game_service = __esm(() => {
|
|
|
28158
28183
|
"app.game.next_visibility": data.visibility !== undefined ? gameResponse.visibility : undefined
|
|
28159
28184
|
});
|
|
28160
28185
|
GameService.recordGameShape(gameResponse);
|
|
28186
|
+
if (this.deps.corsKvs) {
|
|
28187
|
+
const prevOrigin = GameService.safeOrigin(existingGame);
|
|
28188
|
+
const nextOrigin = GameService.safeOrigin(gameResponse);
|
|
28189
|
+
if (nextOrigin) {
|
|
28190
|
+
setAttribute("app.cors_kvs.origin", nextOrigin);
|
|
28191
|
+
this.deps.corsKvs.putOrigin(nextOrigin).catch(catchAttrs("cors_kvs.put_origin", {}));
|
|
28192
|
+
}
|
|
28193
|
+
if (prevOrigin && prevOrigin !== nextOrigin) {
|
|
28194
|
+
setAttribute("app.cors_kvs.prev_origin", prevOrigin);
|
|
28195
|
+
this.cleanupStaleOrigin(prevOrigin, gameResponse.id);
|
|
28196
|
+
}
|
|
28197
|
+
}
|
|
28161
28198
|
return gameResponse;
|
|
28162
28199
|
}
|
|
28163
28200
|
async updateMetadata(gameId, data, user) {
|
|
@@ -28276,6 +28313,11 @@ var init_game_service = __esm(() => {
|
|
|
28276
28313
|
setAttribute("app.game.api_key_cleanup_error", errorMessage(error));
|
|
28277
28314
|
}
|
|
28278
28315
|
}
|
|
28316
|
+
const corsOrigin = GameService.safeOrigin(gameToDelete);
|
|
28317
|
+
if (this.deps.corsKvs && corsOrigin) {
|
|
28318
|
+
setAttribute("app.cors_kvs.origin", corsOrigin);
|
|
28319
|
+
this.cleanupStaleOrigin(corsOrigin, gameId);
|
|
28320
|
+
}
|
|
28279
28321
|
return {
|
|
28280
28322
|
slug: gameToDelete.slug,
|
|
28281
28323
|
displayName: gameToDelete.displayName
|
|
@@ -28407,12 +28449,13 @@ var init_logs_service = __esm(() => {
|
|
|
28407
28449
|
|
|
28408
28450
|
// ../api-core/src/services/factory/game.ts
|
|
28409
28451
|
function createGameServices(deps) {
|
|
28410
|
-
const { db: db2, config: config2, cloudflare: cloudflare2, auth: auth2, storage, cache, alerts } = deps;
|
|
28452
|
+
const { db: db2, config: config2, cloudflare: cloudflare2, corsKvs, auth: auth2, storage, cache, alerts } = deps;
|
|
28411
28453
|
const game2 = new GameService({
|
|
28412
28454
|
db: db2,
|
|
28413
28455
|
alerts,
|
|
28414
28456
|
cache,
|
|
28415
28457
|
cloudflare: cloudflare2,
|
|
28458
|
+
corsKvs,
|
|
28416
28459
|
deleteApiKeyByName: auth2.deleteApiKeyByName.bind(auth2)
|
|
28417
28460
|
});
|
|
28418
28461
|
const gameMember = new GameMemberService({
|
|
@@ -28433,7 +28476,6 @@ function createGameServices(deps) {
|
|
|
28433
28476
|
db: db2,
|
|
28434
28477
|
uploadBucket: config2.uploadBucket,
|
|
28435
28478
|
storage,
|
|
28436
|
-
cache,
|
|
28437
28479
|
validateDeveloperAccessBySlug: (user, slug) => game2.validateDeveloperAccessBySlug(user, slug),
|
|
28438
28480
|
runDeploy: (slug, request, user, uploadDeps, extractZip) => deploy.deploy(slug, request, user, uploadDeps, extractZip),
|
|
28439
28481
|
notifyDeploymentFailure: (slug, displayName, error, developerInfo) => deploy.notifyDeploymentFailure(slug, displayName, error, developerInfo)
|
|
@@ -29318,6 +29360,9 @@ class DomainService {
|
|
|
29318
29360
|
addEvent("domain.cloudflare_hostname_created", {
|
|
29319
29361
|
"app.domain.cloudflare_id": cfHostname.id
|
|
29320
29362
|
});
|
|
29363
|
+
const corsOrigin = `https://${hostname}`;
|
|
29364
|
+
setAttribute("app.cors_kvs.origin", corsOrigin);
|
|
29365
|
+
this.deps.corsKvs?.putOrigin(corsOrigin).catch(catchAttrs("cors_kvs.put_origin", {}));
|
|
29321
29366
|
return customHostname;
|
|
29322
29367
|
}
|
|
29323
29368
|
async list(slug, environment, user) {
|
|
@@ -29401,6 +29446,9 @@ class DomainService {
|
|
|
29401
29446
|
"app.domain.status": dbHostname.status,
|
|
29402
29447
|
"app.domain.ssl_status": dbHostname.sslStatus
|
|
29403
29448
|
});
|
|
29449
|
+
const corsOrigin = `https://${hostname}`;
|
|
29450
|
+
setAttribute("app.cors_kvs.origin", corsOrigin);
|
|
29451
|
+
this.deps.corsKvs?.deleteOrigin(corsOrigin).catch(catchAttrs("cors_kvs.delete_origin", {}));
|
|
29404
29452
|
}
|
|
29405
29453
|
}
|
|
29406
29454
|
var init_domain_service = __esm(() => {
|
|
@@ -29695,12 +29743,13 @@ var init_secrets_service = __esm(() => {
|
|
|
29695
29743
|
});
|
|
29696
29744
|
|
|
29697
29745
|
// ../edge-play/src/constants.ts
|
|
29698
|
-
var ROUTES;
|
|
29746
|
+
var ASSET_ROUTE_PREFIX = "/api/assets/", ROUTES;
|
|
29699
29747
|
var init_constants3 = __esm(() => {
|
|
29700
29748
|
init_src();
|
|
29701
29749
|
ROUTES = {
|
|
29702
29750
|
INDEX: "/api",
|
|
29703
29751
|
HEALTH: "/api/health",
|
|
29752
|
+
ASSETS: `${ASSET_ROUTE_PREFIX}*`,
|
|
29704
29753
|
TIMEBACK: {
|
|
29705
29754
|
END_ACTIVITY: `/api${TIMEBACK_ROUTES.END_ACTIVITY}`,
|
|
29706
29755
|
GET_XP: `/api${TIMEBACK_ROUTES.GET_XP}`,
|
|
@@ -29857,7 +29906,8 @@ class SeedService {
|
|
|
29857
29906
|
}, {
|
|
29858
29907
|
bindings: { d1: [deploymentId], r2: [], kv: [] },
|
|
29859
29908
|
keepAssets: false,
|
|
29860
|
-
compatibilityDate: CLOUDFLARE_COMPATIBILITY_DATE
|
|
29909
|
+
compatibilityDate: CLOUDFLARE_COMPATIBILITY_DATE,
|
|
29910
|
+
observability: false
|
|
29861
29911
|
});
|
|
29862
29912
|
if (secrets && Object.keys(secrets).length > 0) {
|
|
29863
29913
|
await cf.setSecrets(seedDeploymentId, prefixSecrets(secrets));
|
|
@@ -32124,44 +32174,6 @@ function validateSessionData(sessionData) {
|
|
|
32124
32174
|
throw new ConfigurationError("sensorUrl", 'Sensor URL is required for Caliper events. Provide it in sessionData.sensorUrl (e.g., "https://hub.playcademy.net/p/your-game")');
|
|
32125
32175
|
}
|
|
32126
32176
|
}
|
|
32127
|
-
function getAttemptMultiplier(attemptNumber) {
|
|
32128
|
-
switch (attemptNumber) {
|
|
32129
|
-
case 1: {
|
|
32130
|
-
return 1;
|
|
32131
|
-
}
|
|
32132
|
-
case 2: {
|
|
32133
|
-
return 0.5;
|
|
32134
|
-
}
|
|
32135
|
-
case 3: {
|
|
32136
|
-
return 0.25;
|
|
32137
|
-
}
|
|
32138
|
-
default: {
|
|
32139
|
-
return 0;
|
|
32140
|
-
}
|
|
32141
|
-
}
|
|
32142
|
-
}
|
|
32143
|
-
function getAccuracyMultiplier(accuracy) {
|
|
32144
|
-
if (!Number.isFinite(accuracy) || accuracy < 0) {
|
|
32145
|
-
return 0;
|
|
32146
|
-
}
|
|
32147
|
-
if (accuracy >= PERFECT_ACCURACY_THRESHOLD) {
|
|
32148
|
-
return 1.25;
|
|
32149
|
-
} else if (accuracy >= 0.8) {
|
|
32150
|
-
return 1;
|
|
32151
|
-
} else {
|
|
32152
|
-
return 0;
|
|
32153
|
-
}
|
|
32154
|
-
}
|
|
32155
|
-
function calculateXp(durationSeconds, accuracy, attemptNumber) {
|
|
32156
|
-
if (!Number.isFinite(durationSeconds) || durationSeconds <= 0) {
|
|
32157
|
-
return 0;
|
|
32158
|
-
}
|
|
32159
|
-
const durationMinutes = durationSeconds / 60;
|
|
32160
|
-
const baseXp = Number(durationMinutes);
|
|
32161
|
-
const accuracyMultiplier = getAccuracyMultiplier(accuracy);
|
|
32162
|
-
const attemptMultiplier = getAttemptMultiplier(attemptNumber);
|
|
32163
|
-
return Math.round(baseXp * accuracyMultiplier * attemptMultiplier * 10) / 10;
|
|
32164
|
-
}
|
|
32165
32177
|
|
|
32166
32178
|
class ProgressRecorder {
|
|
32167
32179
|
studentResolver;
|
|
@@ -32180,10 +32192,15 @@ class ProgressRecorder {
|
|
|
32180
32192
|
validateProgressData(progressData);
|
|
32181
32193
|
const { ids, activityId, activityName, courseName, student } = await this.resolveContext(courseId, studentIdentifier, progressData);
|
|
32182
32194
|
const { id: studentId, email: studentEmail } = student;
|
|
32183
|
-
const {
|
|
32195
|
+
const {
|
|
32196
|
+
score,
|
|
32197
|
+
totalQuestions,
|
|
32198
|
+
correctQuestions,
|
|
32199
|
+
xpEarned = 0,
|
|
32200
|
+
attemptNumber
|
|
32201
|
+
} = progressData;
|
|
32184
32202
|
const actualLineItemId = await this.resolveAssessmentLineItem(activityId, activityName, progressData.classId, ids);
|
|
32185
32203
|
const currentAttemptNumber = await this.resolveAttemptNumber(attemptNumber, score, studentId, actualLineItemId);
|
|
32186
|
-
const calculatedXp = this.calculateXpForProgress(progressData, totalQuestions, correctQuestions, xpEarned, currentAttemptNumber);
|
|
32187
32204
|
let extensions = progressData.extensions;
|
|
32188
32205
|
const masteryProgress = await this.masteryTracker.checkProgress({
|
|
32189
32206
|
studentId,
|
|
@@ -32214,7 +32231,7 @@ class ProgressRecorder {
|
|
|
32214
32231
|
studentId,
|
|
32215
32232
|
attemptNumber: currentAttemptNumber,
|
|
32216
32233
|
score,
|
|
32217
|
-
xp:
|
|
32234
|
+
xp: xpEarned,
|
|
32218
32235
|
scoreStatus,
|
|
32219
32236
|
inProgress,
|
|
32220
32237
|
appName: progressData.appName,
|
|
@@ -32253,7 +32270,7 @@ class ProgressRecorder {
|
|
|
32253
32270
|
courseName,
|
|
32254
32271
|
totalQuestions,
|
|
32255
32272
|
correctQuestions,
|
|
32256
|
-
xpEarned
|
|
32273
|
+
xpEarned,
|
|
32257
32274
|
masteredUnits: effectiveMasteredUnits || undefined,
|
|
32258
32275
|
attemptNumber: currentAttemptNumber,
|
|
32259
32276
|
progressData,
|
|
@@ -32261,7 +32278,7 @@ class ProgressRecorder {
|
|
|
32261
32278
|
runId: progressData.runId
|
|
32262
32279
|
});
|
|
32263
32280
|
return {
|
|
32264
|
-
xpAwarded:
|
|
32281
|
+
xpAwarded: xpEarned,
|
|
32265
32282
|
attemptNumber: currentAttemptNumber,
|
|
32266
32283
|
masteredUnitsApplied: effectiveMasteredUnits,
|
|
32267
32284
|
pctCompleteApp,
|
|
@@ -32295,16 +32312,6 @@ class ProgressRecorder {
|
|
|
32295
32312
|
}
|
|
32296
32313
|
return 1;
|
|
32297
32314
|
}
|
|
32298
|
-
calculateXpForProgress(progressData, totalQuestions, correctQuestions, xpEarned, attemptNumber) {
|
|
32299
|
-
if (xpEarned !== undefined) {
|
|
32300
|
-
return xpEarned;
|
|
32301
|
-
}
|
|
32302
|
-
if (progressData.durationSeconds && totalQuestions && correctQuestions) {
|
|
32303
|
-
const accuracy = correctQuestions / totalQuestions;
|
|
32304
|
-
return calculateXp(progressData.durationSeconds, accuracy, attemptNumber);
|
|
32305
|
-
}
|
|
32306
|
-
return 0;
|
|
32307
|
-
}
|
|
32308
32315
|
async getOrCreateLineItem(lineItemId, activityName, classId, ids) {
|
|
32309
32316
|
try {
|
|
32310
32317
|
const lineItem = await this.onerosterNamespace.assessmentLineItems.findOrCreate(lineItemId, {
|
|
@@ -32962,7 +32969,7 @@ var __defProp2, __export2 = (target, all) => {
|
|
|
32962
32969
|
configurable: true,
|
|
32963
32970
|
set: (newValue) => all[name3] = () => newValue
|
|
32964
32971
|
});
|
|
32965
|
-
}, __esm2 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), TIMEBACK_API_URLS, QTI_API_URL = "https://qti.alpha-1edtech.ai/api", TIMEBACK_AUTH_URLS, CALIPER_API_URLS, ONEROSTER_ENDPOINTS, QTI_ENDPOINTS, CALIPER_ENDPOINTS, CALIPER_CONSTANTS, TIMEBACK_EVENT_TYPES, TIMEBACK_ACTIONS, TIMEBACK_TYPES, ACTIVITY_METRIC_TYPES, TIME_METRIC_TYPES, TIMEBACK_SUBJECTS, TIMEBACK_GRADE_LEVELS, TIMEBACK_GRADE_LEVEL_LABELS, CALIPER_SUBJECTS, ONEROSTER_STATUS, SCORE_STATUS, ENV_VARS, HTTP_DEFAULTS, AUTH_DEFAULTS, CACHE_DEFAULTS, CONFIG_DEFAULTS, PLAYCADEMY_DEFAULTS, RESOURCE_DEFAULTS, HTTP_STATUS, ERROR_NAMES, init_constants4, exports_verify, init_verify, TimebackError, TimebackApiError, TimebackAuthenticationError, StudentNotFoundError, ConfigurationError, ResourceNotFoundError, SUBJECT_VALUES, GRADE_VALUES, TimebackAuthError, UUID_PATTERN, storage,
|
|
32972
|
+
}, __esm2 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), TIMEBACK_API_URLS, QTI_API_URL = "https://qti.alpha-1edtech.ai/api", TIMEBACK_AUTH_URLS, CALIPER_API_URLS, ONEROSTER_ENDPOINTS, QTI_ENDPOINTS, CALIPER_ENDPOINTS, CALIPER_CONSTANTS, TIMEBACK_EVENT_TYPES, TIMEBACK_ACTIONS, TIMEBACK_TYPES, ACTIVITY_METRIC_TYPES, TIME_METRIC_TYPES, TIMEBACK_SUBJECTS, TIMEBACK_GRADE_LEVELS, TIMEBACK_GRADE_LEVEL_LABELS, CALIPER_SUBJECTS, ONEROSTER_STATUS, SCORE_STATUS, ENV_VARS, HTTP_DEFAULTS, AUTH_DEFAULTS, CACHE_DEFAULTS, CONFIG_DEFAULTS, PLAYCADEMY_DEFAULTS, RESOURCE_DEFAULTS, HTTP_STATUS, ERROR_NAMES, init_constants4, exports_verify, init_verify, TimebackError, TimebackApiError, TimebackAuthenticationError, StudentNotFoundError, ConfigurationError, ResourceNotFoundError, SUBJECT_VALUES, GRADE_VALUES, TimebackAuthError, UUID_PATTERN, storage, EmailSchema, StudentSourcedIdSchema, StudentIdentifierSchema;
|
|
32966
32973
|
var init_dist2 = __esm(() => {
|
|
32967
32974
|
init_src();
|
|
32968
32975
|
init_src();
|
|
@@ -34210,13 +34217,14 @@ var init_emoji = __esm(() => {
|
|
|
34210
34217
|
});
|
|
34211
34218
|
|
|
34212
34219
|
// ../data/src/domains/game/schemas.ts
|
|
34213
|
-
var GameEmojiSchema, GameMetadataRecordSchema, InsertGameSchema, UpdateGameSchema, InsertGameDeploymentSchema, InsertGameDeployJobSchema, UpsertGameMetadataSchema, PatchGameMetadataSchema, AddGameMemberSchema, UpdateGameMemberRoleSchema, ALLOWED_UPLOAD_EXTENSIONS, InitiateUploadSchema, AddCustomHostnameSchema, SetSecretsRequestSchema, SeedRequestSchema, SchemaInfoSchema, DatabaseResetRequestSchema, VerifyTokenSchema, KVSeedRequestSchema, DeployRequestSchema;
|
|
34220
|
+
var HttpUrlSchema, GameEmojiSchema, GameMetadataRecordSchema, InsertGameSchema, UpdateGameSchema, InsertGameDeploymentSchema, InsertGameDeployJobSchema, UpsertGameMetadataSchema, PatchGameMetadataSchema, AddGameMemberSchema, UpdateGameMemberRoleSchema, ALLOWED_UPLOAD_EXTENSIONS, InitiateUploadSchema, AddCustomHostnameSchema, SetSecretsRequestSchema, SeedRequestSchema, SchemaInfoSchema, DatabaseResetRequestSchema, VerifyTokenSchema, KVSeedRequestSchema, DeployRequestSchema;
|
|
34214
34221
|
var init_schemas2 = __esm(() => {
|
|
34215
34222
|
init_drizzle_zod();
|
|
34216
34223
|
init_esm();
|
|
34217
34224
|
init_src();
|
|
34218
34225
|
init_emoji();
|
|
34219
34226
|
init_table5();
|
|
34227
|
+
HttpUrlSchema = exports_external.string().url().refine((url2) => /^https?:\/\//i.test(url2), { message: "URL must use http or https" });
|
|
34220
34228
|
GameEmojiSchema = exports_external.string().max(16).refine((value) => value.length === 0 || isSingleEmoji(value), {
|
|
34221
34229
|
message: "Emoji must be a single emoji."
|
|
34222
34230
|
});
|
|
@@ -34241,7 +34249,7 @@ var init_schemas2 = __esm(() => {
|
|
|
34241
34249
|
gameType: exports_external.enum(gameTypeEnum.enumValues).default("hosted"),
|
|
34242
34250
|
visibility: exports_external.enum(gameVisibilityEnum.enumValues).default("visible"),
|
|
34243
34251
|
deploymentUrl: exports_external.string().nullable().optional(),
|
|
34244
|
-
externalUrl:
|
|
34252
|
+
externalUrl: HttpUrlSchema.nullable().optional()
|
|
34245
34253
|
}).omit({
|
|
34246
34254
|
slug: true,
|
|
34247
34255
|
version: true
|
|
@@ -34264,7 +34272,7 @@ var init_schemas2 = __esm(() => {
|
|
|
34264
34272
|
gameType: exports_external.enum(gameTypeEnum.enumValues).optional(),
|
|
34265
34273
|
visibility: exports_external.enum(gameVisibilityEnum.enumValues).optional(),
|
|
34266
34274
|
deploymentUrl: exports_external.string().nullable().optional(),
|
|
34267
|
-
externalUrl:
|
|
34275
|
+
externalUrl: HttpUrlSchema.nullable().optional()
|
|
34268
34276
|
}).omit({
|
|
34269
34277
|
id: true,
|
|
34270
34278
|
slug: true,
|
|
@@ -34294,7 +34302,7 @@ var init_schemas2 = __esm(() => {
|
|
|
34294
34302
|
metadata: GameMetadataRecordSchema.optional().default({}),
|
|
34295
34303
|
gameType: exports_external.enum(gameTypeEnum.enumValues).optional().default("hosted"),
|
|
34296
34304
|
visibility: exports_external.enum(gameVisibilityEnum.enumValues).optional(),
|
|
34297
|
-
externalUrl:
|
|
34305
|
+
externalUrl: HttpUrlSchema.optional()
|
|
34298
34306
|
}).refine((data) => {
|
|
34299
34307
|
if (data.gameType === "external" && !data.externalUrl) {
|
|
34300
34308
|
return false;
|
|
@@ -34493,7 +34501,7 @@ var init_schemas4 = __esm(() => {
|
|
|
34493
34501
|
activeSeconds: exports_external.number().nonnegative(),
|
|
34494
34502
|
inactiveSeconds: exports_external.number().nonnegative().optional()
|
|
34495
34503
|
}).optional(),
|
|
34496
|
-
xpEarned: exports_external.number()
|
|
34504
|
+
xpEarned: exports_external.number(),
|
|
34497
34505
|
masteredUnits: exports_external.number().optional(),
|
|
34498
34506
|
masteredUnitsAbsolute: exports_external.number().int().nonnegative().optional(),
|
|
34499
34507
|
extensions: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
|
|
@@ -39205,6 +39213,7 @@ function createPlatformServices(deps) {
|
|
|
39205
39213
|
db: db2,
|
|
39206
39214
|
config: config2,
|
|
39207
39215
|
cloudflare: cloudflare2,
|
|
39216
|
+
corsKvs,
|
|
39208
39217
|
storage: storage2,
|
|
39209
39218
|
r2Storage,
|
|
39210
39219
|
timebackClient,
|
|
@@ -39226,7 +39235,7 @@ function createPlatformServices(deps) {
|
|
|
39226
39235
|
});
|
|
39227
39236
|
const kv = new KVService({ db: db2, cloudflare: cloudflare2, validateDeveloperAccessBySlug });
|
|
39228
39237
|
const secrets = new SecretsService({ config: config2, cloudflare: cloudflare2, validateDeveloperAccessBySlug });
|
|
39229
|
-
const domain = new DomainService({ db: db2, cloudflare: cloudflare2, validateDeveloperAccessBySlug });
|
|
39238
|
+
const domain = new DomainService({ db: db2, cloudflare: cloudflare2, corsKvs, validateDeveloperAccessBySlug });
|
|
39230
39239
|
const database = new DatabaseService({
|
|
39231
39240
|
db: db2,
|
|
39232
39241
|
config: config2,
|
|
@@ -39904,7 +39913,7 @@ var init_standalone = __esm(() => {
|
|
|
39904
39913
|
|
|
39905
39914
|
// ../api-core/src/services/factory/index.ts
|
|
39906
39915
|
function createServices(ctx) {
|
|
39907
|
-
const { db: db2, config: config2, providers, cloudflare: cloudflare2, timeback: timeback2, discord } = ctx;
|
|
39916
|
+
const { db: db2, config: config2, providers, cloudflare: cloudflare2, timeback: timeback2, discord, corsKvs } = ctx;
|
|
39908
39917
|
const { auth: auth2, storage: storage2, r2Storage, cache } = providers;
|
|
39909
39918
|
const infra2 = createInfraServices({
|
|
39910
39919
|
db: db2,
|
|
@@ -39918,6 +39927,7 @@ function createServices(ctx) {
|
|
|
39918
39927
|
db: db2,
|
|
39919
39928
|
config: config2,
|
|
39920
39929
|
cloudflare: cloudflare2,
|
|
39930
|
+
corsKvs,
|
|
39921
39931
|
auth: auth2,
|
|
39922
39932
|
storage: storage2,
|
|
39923
39933
|
cache,
|
|
@@ -39927,6 +39937,7 @@ function createServices(ctx) {
|
|
|
39927
39937
|
db: db2,
|
|
39928
39938
|
config: config2,
|
|
39929
39939
|
cloudflare: cloudflare2,
|
|
39940
|
+
corsKvs,
|
|
39930
39941
|
storage: storage2,
|
|
39931
39942
|
r2Storage,
|
|
39932
39943
|
timebackClient: timeback2,
|
|
@@ -40115,16 +40126,6 @@ var init_auth_provider = __esm(() => {
|
|
|
40115
40126
|
// src/infrastructure/api/providers/cache.provider.ts
|
|
40116
40127
|
function createSandboxCacheProvider() {
|
|
40117
40128
|
return {
|
|
40118
|
-
async refreshGameOrigins() {
|
|
40119
|
-
gameOrigins = ["http://localhost:3000", "http://localhost:5173"];
|
|
40120
|
-
lastRefreshTime = Date.now();
|
|
40121
|
-
},
|
|
40122
|
-
getGameOriginState() {
|
|
40123
|
-
return {
|
|
40124
|
-
origins: gameOrigins,
|
|
40125
|
-
lastRefreshTime
|
|
40126
|
-
};
|
|
40127
|
-
},
|
|
40128
40129
|
async get(key) {
|
|
40129
40130
|
const entry = cache.get(key);
|
|
40130
40131
|
if (!entry) {
|
|
@@ -40149,13 +40150,10 @@ function createSandboxCacheProvider() {
|
|
|
40149
40150
|
}
|
|
40150
40151
|
function clearSandboxCache() {
|
|
40151
40152
|
cache.clear();
|
|
40152
|
-
gameOrigins = [];
|
|
40153
|
-
lastRefreshTime = 0;
|
|
40154
40153
|
}
|
|
40155
|
-
var cache
|
|
40154
|
+
var cache;
|
|
40156
40155
|
var init_cache_provider = __esm(() => {
|
|
40157
40156
|
cache = new Map;
|
|
40158
|
-
gameOrigins = [];
|
|
40159
40157
|
});
|
|
40160
40158
|
|
|
40161
40159
|
// src/infrastructure/api/providers/storage.provider.ts
|
|
@@ -49364,7 +49362,7 @@ var require_has_flag = __commonJS((exports, module2) => {
|
|
|
49364
49362
|
|
|
49365
49363
|
// ../../node_modules/.bun/supports-color@7.2.0/node_modules/supports-color/index.js
|
|
49366
49364
|
var require_supports_color = __commonJS((exports, module2) => {
|
|
49367
|
-
var
|
|
49365
|
+
var os2 = __require("os");
|
|
49368
49366
|
var tty = __require("tty");
|
|
49369
49367
|
var hasFlag = require_has_flag();
|
|
49370
49368
|
var { env } = process;
|
|
@@ -49412,7 +49410,7 @@ var require_supports_color = __commonJS((exports, module2) => {
|
|
|
49412
49410
|
return min;
|
|
49413
49411
|
}
|
|
49414
49412
|
if (process.platform === "win32") {
|
|
49415
|
-
const osRelease =
|
|
49413
|
+
const osRelease = os2.release().split(".");
|
|
49416
49414
|
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
49417
49415
|
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
49418
49416
|
}
|
|
@@ -54505,7 +54503,7 @@ __export(exports_api, {
|
|
|
54505
54503
|
generateDrizzleJson: () => generateDrizzleJson
|
|
54506
54504
|
});
|
|
54507
54505
|
import process2 from "process";
|
|
54508
|
-
import
|
|
54506
|
+
import os2 from "os";
|
|
54509
54507
|
import tty from "tty";
|
|
54510
54508
|
import { randomUUID } from "crypto";
|
|
54511
54509
|
function assembleStyles() {
|
|
@@ -54676,7 +54674,7 @@ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
|
|
|
54676
54674
|
return min2;
|
|
54677
54675
|
}
|
|
54678
54676
|
if (process2.platform === "win32") {
|
|
54679
|
-
const osRelease =
|
|
54677
|
+
const osRelease = os2.release().split(".");
|
|
54680
54678
|
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
54681
54679
|
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
54682
54680
|
}
|
|
@@ -67516,7 +67514,7 @@ Is ${source_default.bold.blue(this.base.name)} schema created or renamed from an
|
|
|
67516
67514
|
});
|
|
67517
67515
|
require_supports_colors = __commonJS2({
|
|
67518
67516
|
"../node_modules/.pnpm/colors@1.4.0/node_modules/colors/lib/system/supports-colors.js"(exports, module2) {
|
|
67519
|
-
var
|
|
67517
|
+
var os22 = __require2("os");
|
|
67520
67518
|
var hasFlag2 = require_has_flag2();
|
|
67521
67519
|
var env2 = process.env;
|
|
67522
67520
|
var forceColor = undefined;
|
|
@@ -67554,7 +67552,7 @@ Is ${source_default.bold.blue(this.base.name)} schema created or renamed from an
|
|
|
67554
67552
|
}
|
|
67555
67553
|
var min2 = forceColor ? 1 : 0;
|
|
67556
67554
|
if (process.platform === "win32") {
|
|
67557
|
-
var osRelease =
|
|
67555
|
+
var osRelease = os22.release().split(".");
|
|
67558
67556
|
if (Number(process.versions.node.split(".")[0]) >= 8 && Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
67559
67557
|
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
67560
67558
|
}
|
|
@@ -95976,28 +95974,6 @@ var init_utils11 = __esm(() => {
|
|
|
95976
95974
|
init_validation_util();
|
|
95977
95975
|
});
|
|
95978
95976
|
|
|
95979
|
-
// ../api-core/src/controllers/admin.controller.ts
|
|
95980
|
-
var getAllowedOrigins, admin;
|
|
95981
|
-
var init_admin_controller = __esm(() => {
|
|
95982
|
-
init_utils11();
|
|
95983
|
-
getAllowedOrigins = requireAdmin(async (ctx) => {
|
|
95984
|
-
const shouldRefresh = ctx.url.searchParams.get("refresh") === "true";
|
|
95985
|
-
if (shouldRefresh) {
|
|
95986
|
-
await ctx.providers.cache.refreshGameOrigins();
|
|
95987
|
-
}
|
|
95988
|
-
const { origins, lastRefreshTime: lastRefreshTime2 } = ctx.providers.cache.getGameOriginState();
|
|
95989
|
-
return {
|
|
95990
|
-
origins,
|
|
95991
|
-
count: origins.length,
|
|
95992
|
-
lastRefresh: lastRefreshTime2 > 0 ? new Date(lastRefreshTime2).toISOString() : null,
|
|
95993
|
-
cacheAge: lastRefreshTime2 > 0 ? Date.now() - lastRefreshTime2 : null
|
|
95994
|
-
};
|
|
95995
|
-
});
|
|
95996
|
-
admin = defineControllerNames("admin", {
|
|
95997
|
-
getAllowedOrigins
|
|
95998
|
-
});
|
|
95999
|
-
});
|
|
96000
|
-
|
|
96001
95977
|
// ../api-core/src/controllers/bucket.controller.ts
|
|
96002
95978
|
var listFiles, getFile, putFile, deleteFile, initiateUpload, bucket;
|
|
96003
95979
|
var init_bucket_controller = __esm(() => {
|
|
@@ -97429,7 +97405,6 @@ var init_verify_controller = __esm(() => {
|
|
|
97429
97405
|
|
|
97430
97406
|
// ../api-core/src/controllers/index.ts
|
|
97431
97407
|
var init_controllers = __esm(() => {
|
|
97432
|
-
init_admin_controller();
|
|
97433
97408
|
init_bucket_controller();
|
|
97434
97409
|
init_database_controller();
|
|
97435
97410
|
init_deploy_controller();
|