@playcademy/vite-plugin 1.0.1-beta.5 → 1.1.0-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/hooks/transform-index-html.d.ts +22 -18
- package/dist/index.js +319 -218
- package/dist/lib/assets/index.d.ts +40 -0
- package/package.json +4 -4
|
@@ -1,30 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Vite transformIndexHtml() hook
|
|
3
3
|
*
|
|
4
|
-
* Injects
|
|
5
|
-
* This enables cross-origin iframe recording: the game iframe's PostHog
|
|
6
|
-
* instance posts its recording data (DOM snapshots, console logs, network
|
|
7
|
-
* requests) to the parent platform's PostHog instance, producing a single
|
|
8
|
-
* unified session replay.
|
|
4
|
+
* Injects two independent snippets into game HTML `<head>`:
|
|
9
5
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
6
|
+
* 1. **Dev only** — the asset manifest (`self.__PLAYCADEMY_ASSET_MANIFEST`),
|
|
7
|
+
* read from the local bucket, so the SDK's `asset()` resolver works in
|
|
8
|
+
* `vite dev` as it does on the platform. In production the edge worker
|
|
9
|
+
* injects this itself, so we don't bake it into the build.
|
|
13
10
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
11
|
+
* 2. **Build only** — a PostHog session-replay snippet enabling cross-origin
|
|
12
|
+
* iframe recording: the game iframe's PostHog instance posts its recording
|
|
13
|
+
* data to the parent platform's instance for a single unified replay. It
|
|
14
|
+
* loads before any game JS (capturing the full boot sequence) and uses a
|
|
15
|
+
* named instance to avoid conflicting with the game's own `window.posthog`.
|
|
18
16
|
*/
|
|
19
17
|
import type { HtmlTagDescriptor } from 'vite';
|
|
20
18
|
import type { PluginContext } from '../types';
|
|
21
19
|
/**
|
|
22
|
-
* Transform index.html
|
|
20
|
+
* Transform index.html. Returns HTML tags Vite injects into `<head>`, before
|
|
21
|
+
* any game scripts in `<body>`.
|
|
22
|
+
*
|
|
23
|
+
* Two independent, build-only-vs-dev-only injections:
|
|
23
24
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
25
|
+
* - **Asset manifest (dev only).** Mirrors the SDK's `asset()` resolver against
|
|
26
|
+
* the local bucket so it works in `vite dev` the same as on the platform. We
|
|
27
|
+
* do NOT inject at build time: in production the edge worker injects the
|
|
28
|
+
* manifest into every HTML response itself, sourced from the deployed bucket.
|
|
29
|
+
* Baking a tag at build time would embed the developer's *local* bucket
|
|
30
|
+
* manifest into the deployed HTML — stale and competing with the worker's.
|
|
27
31
|
*
|
|
28
|
-
*
|
|
32
|
+
* - **PostHog cross-origin iframe recorder (build only).**
|
|
29
33
|
*/
|
|
30
|
-
export declare function transformIndexHtmlHook(context: PluginContext): HtmlTagDescriptor[]
|
|
34
|
+
export declare function transformIndexHtmlHook(context: PluginContext): Promise<HtmlTagDescriptor[]>;
|
package/dist/index.js
CHANGED
|
@@ -23746,7 +23746,7 @@ import path from "node:path";
|
|
|
23746
23746
|
// package.json
|
|
23747
23747
|
var package_default = {
|
|
23748
23748
|
name: "@playcademy/vite-plugin",
|
|
23749
|
-
version: "1.0
|
|
23749
|
+
version: "1.1.0-beta.1",
|
|
23750
23750
|
type: "module",
|
|
23751
23751
|
exports: {
|
|
23752
23752
|
".": {
|
|
@@ -23974,6 +23974,172 @@ function configResolvedHook(resolvedConfig, context) {
|
|
|
23974
23974
|
// src/hooks/configure-server.ts
|
|
23975
23975
|
import { DEFAULT_PORTS as DEFAULT_PORTS3 } from "playcademy/constants";
|
|
23976
23976
|
|
|
23977
|
+
// src/lib/assets/index.ts
|
|
23978
|
+
var import_picocolors4 = __toESM(require_picocolors(), 1);
|
|
23979
|
+
import {
|
|
23980
|
+
ASSET_DEV_ROUTE_PREFIX,
|
|
23981
|
+
hasCustomAssetsRoute,
|
|
23982
|
+
openLocalAssetBucket,
|
|
23983
|
+
readLocalAsset,
|
|
23984
|
+
readLocalManifestScript
|
|
23985
|
+
} from "playcademy/bucket";
|
|
23986
|
+
import { loadPlaycademyConfig } from "playcademy/utils";
|
|
23987
|
+
|
|
23988
|
+
// ../utils/src/vite-logger.ts
|
|
23989
|
+
var import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
23990
|
+
var { bold, cyan, dim } = import_picocolors2.default;
|
|
23991
|
+
function formatTimestamp() {
|
|
23992
|
+
const now = new Date;
|
|
23993
|
+
const hours = now.getHours();
|
|
23994
|
+
const minutes = now.getMinutes().toString().padStart(2, "0");
|
|
23995
|
+
const seconds = now.getSeconds().toString().padStart(2, "0");
|
|
23996
|
+
const ampm = hours >= 12 ? "PM" : "AM";
|
|
23997
|
+
const displayHours = hours % 12 || 12;
|
|
23998
|
+
return dim(`${displayHours}:${minutes}:${seconds} ${ampm}`);
|
|
23999
|
+
}
|
|
24000
|
+
function createLogPrefix(entity, domain) {
|
|
24001
|
+
const timestamp = formatTimestamp();
|
|
24002
|
+
const label = bold(cyan(`[${entity}]`));
|
|
24003
|
+
if (domain) {
|
|
24004
|
+
return `${timestamp} ${label} ${dim(`(${domain})`)}`;
|
|
24005
|
+
}
|
|
24006
|
+
return `${timestamp} ${label}`;
|
|
24007
|
+
}
|
|
24008
|
+
|
|
24009
|
+
// src/lib/logging/adapter.ts
|
|
24010
|
+
function createLoggerAdapter(domain) {
|
|
24011
|
+
return {
|
|
24012
|
+
info: (msg) => console.log(`${createLogPrefix("playcademy", domain)} ${msg}`),
|
|
24013
|
+
warn: (msg) => console.warn(`${createLogPrefix("playcademy", domain)} ${msg}`),
|
|
24014
|
+
error: (msg) => console.error(`${createLogPrefix("playcademy", domain)} ${msg}`)
|
|
24015
|
+
};
|
|
24016
|
+
}
|
|
24017
|
+
// src/lib/logging/utils.ts
|
|
24018
|
+
var import_picocolors3 = __toESM(require_picocolors(), 1);
|
|
24019
|
+
|
|
24020
|
+
// ../utils/src/string.ts
|
|
24021
|
+
function pluralize(count, singular, pluralForm) {
|
|
24022
|
+
return count === 1 ? singular : pluralForm || `${singular}s`;
|
|
24023
|
+
}
|
|
24024
|
+
|
|
24025
|
+
// src/lib/logging/utils.ts
|
|
24026
|
+
function createBackendBannerOptions(backendPort, vitePort) {
|
|
24027
|
+
if (!backendPort) {
|
|
24028
|
+
return;
|
|
24029
|
+
}
|
|
24030
|
+
return { port: backendPort, vitePort };
|
|
24031
|
+
}
|
|
24032
|
+
function createTimebackBannerOptions(timebackMode, courseCount, enrolledCount) {
|
|
24033
|
+
if (!timebackMode || !courseCount) {
|
|
24034
|
+
return;
|
|
24035
|
+
}
|
|
24036
|
+
return {
|
|
24037
|
+
courseCount,
|
|
24038
|
+
enrolledCount: enrolledCount ?? courseCount,
|
|
24039
|
+
mode: timebackMode
|
|
24040
|
+
};
|
|
24041
|
+
}
|
|
24042
|
+
function printBanner(viteConfig, options) {
|
|
24043
|
+
const INDENT = " ".repeat(2);
|
|
24044
|
+
const { version, gameName, sandbox, backend, timeback } = options;
|
|
24045
|
+
viteConfig.logger.info("");
|
|
24046
|
+
viteConfig.logger.info(`${INDENT}${import_picocolors3.green(import_picocolors3.bold("PLAYCADEMY"))} ${import_picocolors3.green(`v${version}`)}`);
|
|
24047
|
+
viteConfig.logger.info("");
|
|
24048
|
+
if (gameName) {
|
|
24049
|
+
viteConfig.logger.info(`${INDENT}${import_picocolors3.green("➜")} ${import_picocolors3.bold("Project:")} ${import_picocolors3.cyan(gameName)}`);
|
|
24050
|
+
}
|
|
24051
|
+
if (sandbox?.enabled) {
|
|
24052
|
+
viteConfig.logger.info(`${INDENT}${import_picocolors3.green("➜")} ${import_picocolors3.bold("Sandbox:")} ${import_picocolors3.cyan(`http://localhost:${import_picocolors3.bold(sandbox.port.toString())}/api`)}`);
|
|
24053
|
+
} else if (sandbox) {
|
|
24054
|
+
viteConfig.logger.info(`${INDENT}${import_picocolors3.green("➜")} ${import_picocolors3.bold("Sandbox:")} ${import_picocolors3.cyan("Disabled")}`);
|
|
24055
|
+
}
|
|
24056
|
+
if (backend) {
|
|
24057
|
+
const backendUrl = backend.vitePort ? `http://localhost:${import_picocolors3.bold(backend.vitePort.toString())}/api ${import_picocolors3.dim(`(via ${backend.port})`)}` : `http://localhost:${import_picocolors3.bold(backend.port.toString())}/api`;
|
|
24058
|
+
viteConfig.logger.info(`${INDENT}${import_picocolors3.green("➜")} ${import_picocolors3.bold("Backend:")} ${import_picocolors3.cyan(backendUrl)}`);
|
|
24059
|
+
}
|
|
24060
|
+
if (timeback && timeback.courseCount > 0) {
|
|
24061
|
+
const enrollmentInfo = timeback.enrolledCount !== timeback.courseCount ? ` / ${timeback.enrolledCount} enrolled` : "";
|
|
24062
|
+
const label = `${timeback.courseCount} ${pluralize(timeback.courseCount, "course")}${enrollmentInfo} ${import_picocolors3.dim(`(${timeback.mode})`)}`;
|
|
24063
|
+
viteConfig.logger.info(`${INDENT}${import_picocolors3.green("➜")} ${import_picocolors3.bold("Timeback:")} ${import_picocolors3.cyan(label)}`);
|
|
24064
|
+
}
|
|
24065
|
+
viteConfig.logger.info("");
|
|
24066
|
+
}
|
|
24067
|
+
// src/lib/assets/index.ts
|
|
24068
|
+
var logger = createLoggerAdapter("assets");
|
|
24069
|
+
async function loadConfigSafely(configPath) {
|
|
24070
|
+
try {
|
|
24071
|
+
return await loadPlaycademyConfig(configPath);
|
|
24072
|
+
} catch {
|
|
24073
|
+
return null;
|
|
24074
|
+
}
|
|
24075
|
+
}
|
|
24076
|
+
var session = null;
|
|
24077
|
+
var hasWarnedNoManifest = false;
|
|
24078
|
+
async function getBucket() {
|
|
24079
|
+
if (!session) {
|
|
24080
|
+
session = await openLocalAssetBucket();
|
|
24081
|
+
}
|
|
24082
|
+
return session.bucket;
|
|
24083
|
+
}
|
|
24084
|
+
async function disposeAssetBucket() {
|
|
24085
|
+
if (session) {
|
|
24086
|
+
await session.dispose();
|
|
24087
|
+
session = null;
|
|
24088
|
+
}
|
|
24089
|
+
hasWarnedNoManifest = false;
|
|
24090
|
+
}
|
|
24091
|
+
async function getDevManifestScript(configPath) {
|
|
24092
|
+
const config = await loadConfigSafely(configPath);
|
|
24093
|
+
if (!config?.integrations?.bucket) {
|
|
24094
|
+
return null;
|
|
24095
|
+
}
|
|
24096
|
+
const script = await readLocalManifestScript(await getBucket());
|
|
24097
|
+
if (!script) {
|
|
24098
|
+
if (!hasWarnedNoManifest) {
|
|
24099
|
+
hasWarnedNoManifest = true;
|
|
24100
|
+
logger.warn(`No local asset manifest found (run ${import_picocolors4.greenBright("playcademy bucket sync")} to serve bucket assets in local dev)`);
|
|
24101
|
+
}
|
|
24102
|
+
return null;
|
|
24103
|
+
}
|
|
24104
|
+
return script;
|
|
24105
|
+
}
|
|
24106
|
+
async function registerAssetMiddleware(server, projectRoot, configPath) {
|
|
24107
|
+
const config = await loadConfigSafely(configPath);
|
|
24108
|
+
if (!config?.integrations?.bucket) {
|
|
24109
|
+
return;
|
|
24110
|
+
}
|
|
24111
|
+
if (hasCustomAssetsRoute(projectRoot, config)) {
|
|
24112
|
+
return;
|
|
24113
|
+
}
|
|
24114
|
+
server.middlewares.use(ASSET_DEV_ROUTE_PREFIX, (req, res, next) => {
|
|
24115
|
+
serveAsset(req, res, next);
|
|
24116
|
+
});
|
|
24117
|
+
}
|
|
24118
|
+
async function serveAsset(req, res, next) {
|
|
24119
|
+
const raw = (req.url ?? "").split("?")[0].replace(/^\/+/, "");
|
|
24120
|
+
let servingKey;
|
|
24121
|
+
try {
|
|
24122
|
+
servingKey = decodeURIComponent(raw);
|
|
24123
|
+
} catch {
|
|
24124
|
+
res.statusCode = 400;
|
|
24125
|
+
res.end("Malformed asset path");
|
|
24126
|
+
return;
|
|
24127
|
+
}
|
|
24128
|
+
if (!servingKey) {
|
|
24129
|
+
next();
|
|
24130
|
+
return;
|
|
24131
|
+
}
|
|
24132
|
+
const asset = await readLocalAsset(await getBucket(), servingKey);
|
|
24133
|
+
if (!asset) {
|
|
24134
|
+
next();
|
|
24135
|
+
return;
|
|
24136
|
+
}
|
|
24137
|
+
res.statusCode = 200;
|
|
24138
|
+
res.setHeader("Content-Type", asset.contentType);
|
|
24139
|
+
res.setHeader("Cache-Control", "no-store");
|
|
24140
|
+
res.end(Buffer.from(asset.body));
|
|
24141
|
+
}
|
|
24142
|
+
|
|
23977
24143
|
// src/server/state.ts
|
|
23978
24144
|
var serverState = {
|
|
23979
24145
|
sandbox: null,
|
|
@@ -24016,6 +24182,9 @@ function setPlatformRoleOverride(role) {
|
|
|
24016
24182
|
|
|
24017
24183
|
// src/server/cleanup.ts
|
|
24018
24184
|
async function cleanupServers() {
|
|
24185
|
+
try {
|
|
24186
|
+
await disposeAssetBucket();
|
|
24187
|
+
} catch {}
|
|
24019
24188
|
if (serverState.backend) {
|
|
24020
24189
|
try {
|
|
24021
24190
|
await serverState.backend.server.dispose();
|
|
@@ -24053,31 +24222,10 @@ function getNextMode(mode) {
|
|
|
24053
24222
|
}
|
|
24054
24223
|
|
|
24055
24224
|
// src/server/recreate-sandbox.ts
|
|
24056
|
-
var
|
|
24057
|
-
|
|
24058
|
-
// ../utils/src/vite-logger.ts
|
|
24059
|
-
var import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
24060
|
-
var { bold, cyan, dim } = import_picocolors2.default;
|
|
24061
|
-
function formatTimestamp() {
|
|
24062
|
-
const now = new Date;
|
|
24063
|
-
const hours = now.getHours();
|
|
24064
|
-
const minutes = now.getMinutes().toString().padStart(2, "0");
|
|
24065
|
-
const seconds = now.getSeconds().toString().padStart(2, "0");
|
|
24066
|
-
const ampm = hours >= 12 ? "PM" : "AM";
|
|
24067
|
-
const displayHours = hours % 12 || 12;
|
|
24068
|
-
return dim(`${displayHours}:${minutes}:${seconds} ${ampm}`);
|
|
24069
|
-
}
|
|
24070
|
-
function createLogPrefix(entity, domain) {
|
|
24071
|
-
const timestamp = formatTimestamp();
|
|
24072
|
-
const label = bold(cyan(`[${entity}]`));
|
|
24073
|
-
if (domain) {
|
|
24074
|
-
return `${timestamp} ${label} ${dim(`(${domain})`)}`;
|
|
24075
|
-
}
|
|
24076
|
-
return `${timestamp} ${label}`;
|
|
24077
|
-
}
|
|
24225
|
+
var import_picocolors8 = __toESM(require_picocolors(), 1);
|
|
24078
24226
|
|
|
24079
24227
|
// src/lib/sandbox/server.ts
|
|
24080
|
-
var
|
|
24228
|
+
var import_picocolors7 = __toESM(require_picocolors(), 1);
|
|
24081
24229
|
import { DEFAULT_PORTS as DEFAULT_PORTS2 } from "playcademy/constants";
|
|
24082
24230
|
|
|
24083
24231
|
// ../sandbox/dist/server.js
|
|
@@ -24089,7 +24237,7 @@ import { Readable } from "stream";
|
|
|
24089
24237
|
import crypto2 from "crypto";
|
|
24090
24238
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
24091
24239
|
import { createServer } from "node:net";
|
|
24092
|
-
import
|
|
24240
|
+
import * as os from "node:os";
|
|
24093
24241
|
import { join } from "node:path";
|
|
24094
24242
|
import { mkdir, writeFile } from "fs/promises";
|
|
24095
24243
|
import { join as join2 } from "path";
|
|
@@ -24103,7 +24251,7 @@ import * as o3 from "path";
|
|
|
24103
24251
|
import fs22 from "node:fs";
|
|
24104
24252
|
import { dirname, isAbsolute, join as join4 } from "node:path";
|
|
24105
24253
|
import process2 from "process";
|
|
24106
|
-
import
|
|
24254
|
+
import os2 from "os";
|
|
24107
24255
|
import tty from "tty";
|
|
24108
24256
|
import { randomUUID } from "crypto";
|
|
24109
24257
|
import fs3 from "node:fs";
|
|
@@ -25100,7 +25248,7 @@ var init_dist = __esm(() => {
|
|
|
25100
25248
|
outgoingEnded = Symbol("outgoingEnded");
|
|
25101
25249
|
});
|
|
25102
25250
|
function getRegistryPath() {
|
|
25103
|
-
const home =
|
|
25251
|
+
const home = os.homedir();
|
|
25104
25252
|
const dir = join(home, ".playcademy");
|
|
25105
25253
|
if (!existsSync(dir)) {
|
|
25106
25254
|
mkdirSync(dir, { recursive: true });
|
|
@@ -25194,7 +25342,7 @@ var package_default2;
|
|
|
25194
25342
|
var init_package = __esm(() => {
|
|
25195
25343
|
package_default2 = {
|
|
25196
25344
|
name: "@playcademy/sandbox",
|
|
25197
|
-
version: "0.5.
|
|
25345
|
+
version: "0.5.1-beta.5",
|
|
25198
25346
|
description: "Local development server for Playcademy game development",
|
|
25199
25347
|
type: "module",
|
|
25200
25348
|
exports: {
|
|
@@ -25646,7 +25794,7 @@ function createLogger(scopeName) {
|
|
|
25646
25794
|
var colors;
|
|
25647
25795
|
var levelPriority;
|
|
25648
25796
|
var customHandler;
|
|
25649
|
-
var
|
|
25797
|
+
var log2;
|
|
25650
25798
|
var init_src2 = __esm(() => {
|
|
25651
25799
|
colors = {
|
|
25652
25800
|
reset: "\x1B[0m",
|
|
@@ -25664,7 +25812,7 @@ var init_src2 = __esm(() => {
|
|
|
25664
25812
|
warn: 2,
|
|
25665
25813
|
error: 3
|
|
25666
25814
|
};
|
|
25667
|
-
|
|
25815
|
+
log2 = createLogger();
|
|
25668
25816
|
});
|
|
25669
25817
|
function formatSSE(eventType, data) {
|
|
25670
25818
|
const payload = `event: ${eventType}
|
|
@@ -25701,7 +25849,7 @@ function toApiError(err2) {
|
|
|
25701
25849
|
return ApiError.fromDomain(err2);
|
|
25702
25850
|
}
|
|
25703
25851
|
const message = err2 instanceof Error ? err2.message : "Unknown error";
|
|
25704
|
-
|
|
25852
|
+
log2.error("[api-hono] Unexpected error", { error: err2 });
|
|
25705
25853
|
return ApiError.internal(message);
|
|
25706
25854
|
}
|
|
25707
25855
|
function errorResponse(c, err2) {
|
|
@@ -25742,7 +25890,7 @@ function createStreamHandle(buildContext) {
|
|
|
25742
25890
|
} catch (error) {
|
|
25743
25891
|
const apiError = toApiError(error);
|
|
25744
25892
|
const logLevel = apiError.status >= 500 ? "error" : "warn";
|
|
25745
|
-
|
|
25893
|
+
log2[logLevel]("[api-hono] Stream error", {
|
|
25746
25894
|
status: apiError.status,
|
|
25747
25895
|
code: apiError.code,
|
|
25748
25896
|
message: apiError.message,
|
|
@@ -33225,9 +33373,9 @@ var init_delete = __esm(() => {
|
|
|
33225
33373
|
init_tracing();
|
|
33226
33374
|
init_utils();
|
|
33227
33375
|
PgDeleteBase = class PgDeleteBase2 extends QueryPromise {
|
|
33228
|
-
constructor(table2,
|
|
33376
|
+
constructor(table2, session2, dialect, withList) {
|
|
33229
33377
|
super();
|
|
33230
|
-
this.session =
|
|
33378
|
+
this.session = session2;
|
|
33231
33379
|
this.dialect = dialect;
|
|
33232
33380
|
this.config = { table: table2, withList };
|
|
33233
33381
|
}
|
|
@@ -33365,7 +33513,7 @@ var init_dialect = __esm(() => {
|
|
|
33365
33513
|
constructor(config2) {
|
|
33366
33514
|
this.casing = new CasingCache(config2?.casing);
|
|
33367
33515
|
}
|
|
33368
|
-
async migrate(migrations,
|
|
33516
|
+
async migrate(migrations, session2, config2) {
|
|
33369
33517
|
const migrationsTable = typeof config2 === "string" ? "__drizzle_migrations" : config2.migrationsTable ?? "__drizzle_migrations";
|
|
33370
33518
|
const migrationsSchema = typeof config2 === "string" ? "drizzle" : config2.migrationsSchema ?? "drizzle";
|
|
33371
33519
|
const migrationTableCreate = sql`
|
|
@@ -33375,11 +33523,11 @@ var init_dialect = __esm(() => {
|
|
|
33375
33523
|
created_at bigint
|
|
33376
33524
|
)
|
|
33377
33525
|
`;
|
|
33378
|
-
await
|
|
33379
|
-
await
|
|
33380
|
-
const dbMigrations = await
|
|
33526
|
+
await session2.execute(sql`CREATE SCHEMA IF NOT EXISTS ${sql.identifier(migrationsSchema)}`);
|
|
33527
|
+
await session2.execute(migrationTableCreate);
|
|
33528
|
+
const dbMigrations = await session2.all(sql`select id, hash, created_at from ${sql.identifier(migrationsSchema)}.${sql.identifier(migrationsTable)} order by created_at desc limit 1`);
|
|
33381
33529
|
const lastDbMigration = dbMigrations[0];
|
|
33382
|
-
await
|
|
33530
|
+
await session2.transaction(async (tx) => {
|
|
33383
33531
|
for await (const migration of migrations) {
|
|
33384
33532
|
if (!lastDbMigration || Number(lastDbMigration.created_at) < migration.folderMillis) {
|
|
33385
33533
|
for (const stmt of migration.sql) {
|
|
@@ -34026,7 +34174,7 @@ var init_select2 = __esm(() => {
|
|
|
34026
34174
|
isPartialSelect;
|
|
34027
34175
|
session;
|
|
34028
34176
|
dialect;
|
|
34029
|
-
constructor({ table: table2, fields, isPartialSelect, session, dialect, withList, distinct }) {
|
|
34177
|
+
constructor({ table: table2, fields, isPartialSelect, session: session2, dialect, withList, distinct }) {
|
|
34030
34178
|
super();
|
|
34031
34179
|
this.config = {
|
|
34032
34180
|
withList,
|
|
@@ -34036,7 +34184,7 @@ var init_select2 = __esm(() => {
|
|
|
34036
34184
|
setOperators: []
|
|
34037
34185
|
};
|
|
34038
34186
|
this.isPartialSelect = isPartialSelect;
|
|
34039
|
-
this.session =
|
|
34187
|
+
this.session = session2;
|
|
34040
34188
|
this.dialect = dialect;
|
|
34041
34189
|
this._ = {
|
|
34042
34190
|
selectedFields: fields
|
|
@@ -34200,13 +34348,13 @@ var init_select2 = __esm(() => {
|
|
|
34200
34348
|
PgSelectBase = class PgSelectBase2 extends PgSelectQueryBuilderBase {
|
|
34201
34349
|
static [entityKind] = "PgSelect";
|
|
34202
34350
|
_prepare(name2) {
|
|
34203
|
-
const { session, config: config2, dialect, joinsNotNullableMap, authToken } = this;
|
|
34204
|
-
if (!
|
|
34351
|
+
const { session: session2, config: config2, dialect, joinsNotNullableMap, authToken } = this;
|
|
34352
|
+
if (!session2) {
|
|
34205
34353
|
throw new Error("Cannot execute a query on a query builder. Please use a database instance instead.");
|
|
34206
34354
|
}
|
|
34207
34355
|
return tracer.startActiveSpan("drizzle.prepareQuery", () => {
|
|
34208
34356
|
const fieldsList = orderSelectedFields(config2.fields);
|
|
34209
|
-
const query =
|
|
34357
|
+
const query = session2.prepareQuery(dialect.sqlToQuery(this.getSQL()), fieldsList, name2, true);
|
|
34210
34358
|
query.joinsNotNullableMap = joinsNotNullableMap;
|
|
34211
34359
|
return query.setToken(authToken);
|
|
34212
34360
|
});
|
|
@@ -34329,9 +34477,9 @@ var init_insert = __esm(() => {
|
|
|
34329
34477
|
init_utils();
|
|
34330
34478
|
init_query_builder2();
|
|
34331
34479
|
PgInsertBuilder = class PgInsertBuilder2 {
|
|
34332
|
-
constructor(table2,
|
|
34480
|
+
constructor(table2, session2, dialect, withList, overridingSystemValue_) {
|
|
34333
34481
|
this.table = table2;
|
|
34334
|
-
this.session =
|
|
34482
|
+
this.session = session2;
|
|
34335
34483
|
this.dialect = dialect;
|
|
34336
34484
|
this.withList = withList;
|
|
34337
34485
|
this.overridingSystemValue_ = overridingSystemValue_;
|
|
@@ -34371,9 +34519,9 @@ var init_insert = __esm(() => {
|
|
|
34371
34519
|
}
|
|
34372
34520
|
};
|
|
34373
34521
|
PgInsertBase = class PgInsertBase2 extends QueryPromise {
|
|
34374
|
-
constructor(table2, values,
|
|
34522
|
+
constructor(table2, values, session2, dialect, withList, select2, overridingSystemValue_) {
|
|
34375
34523
|
super();
|
|
34376
|
-
this.session =
|
|
34524
|
+
this.session = session2;
|
|
34377
34525
|
this.dialect = dialect;
|
|
34378
34526
|
this.config = { table: table2, values, withList, select: select2, overridingSystemValue_ };
|
|
34379
34527
|
}
|
|
@@ -34451,9 +34599,9 @@ var init_refresh_materialized_view = __esm(() => {
|
|
|
34451
34599
|
init_query_promise();
|
|
34452
34600
|
init_tracing();
|
|
34453
34601
|
PgRefreshMaterializedView = class PgRefreshMaterializedView2 extends QueryPromise {
|
|
34454
|
-
constructor(view,
|
|
34602
|
+
constructor(view, session2, dialect) {
|
|
34455
34603
|
super();
|
|
34456
|
-
this.session =
|
|
34604
|
+
this.session = session2;
|
|
34457
34605
|
this.dialect = dialect;
|
|
34458
34606
|
this.config = { view };
|
|
34459
34607
|
}
|
|
@@ -34513,9 +34661,9 @@ var init_update = __esm(() => {
|
|
|
34513
34661
|
init_utils();
|
|
34514
34662
|
init_view_common();
|
|
34515
34663
|
PgUpdateBuilder = class PgUpdateBuilder2 {
|
|
34516
|
-
constructor(table2,
|
|
34664
|
+
constructor(table2, session2, dialect, withList) {
|
|
34517
34665
|
this.table = table2;
|
|
34518
|
-
this.session =
|
|
34666
|
+
this.session = session2;
|
|
34519
34667
|
this.dialect = dialect;
|
|
34520
34668
|
this.withList = withList;
|
|
34521
34669
|
}
|
|
@@ -34530,9 +34678,9 @@ var init_update = __esm(() => {
|
|
|
34530
34678
|
}
|
|
34531
34679
|
};
|
|
34532
34680
|
PgUpdateBase = class PgUpdateBase2 extends QueryPromise {
|
|
34533
|
-
constructor(table2, set,
|
|
34681
|
+
constructor(table2, set, session2, dialect, withList) {
|
|
34534
34682
|
super();
|
|
34535
|
-
this.session =
|
|
34683
|
+
this.session = session2;
|
|
34536
34684
|
this.dialect = dialect;
|
|
34537
34685
|
this.config = { set, table: table2, withList, joins: [] };
|
|
34538
34686
|
this.tableName = getTableLikeName(table2);
|
|
@@ -34720,14 +34868,14 @@ var init_query = __esm(() => {
|
|
|
34720
34868
|
init_relations();
|
|
34721
34869
|
init_tracing();
|
|
34722
34870
|
RelationalQueryBuilder = class RelationalQueryBuilder2 {
|
|
34723
|
-
constructor(fullSchema, schema, tableNamesMap, table2, tableConfig, dialect,
|
|
34871
|
+
constructor(fullSchema, schema, tableNamesMap, table2, tableConfig, dialect, session2) {
|
|
34724
34872
|
this.fullSchema = fullSchema;
|
|
34725
34873
|
this.schema = schema;
|
|
34726
34874
|
this.tableNamesMap = tableNamesMap;
|
|
34727
34875
|
this.table = table2;
|
|
34728
34876
|
this.tableConfig = tableConfig;
|
|
34729
34877
|
this.dialect = dialect;
|
|
34730
|
-
this.session =
|
|
34878
|
+
this.session = session2;
|
|
34731
34879
|
}
|
|
34732
34880
|
static [entityKind] = "PgRelationalQueryBuilder";
|
|
34733
34881
|
findMany(config2) {
|
|
@@ -34738,7 +34886,7 @@ var init_query = __esm(() => {
|
|
|
34738
34886
|
}
|
|
34739
34887
|
};
|
|
34740
34888
|
PgRelationalQuery = class PgRelationalQuery2 extends QueryPromise {
|
|
34741
|
-
constructor(fullSchema, schema, tableNamesMap, table2, tableConfig, dialect,
|
|
34889
|
+
constructor(fullSchema, schema, tableNamesMap, table2, tableConfig, dialect, session2, config2, mode) {
|
|
34742
34890
|
super();
|
|
34743
34891
|
this.fullSchema = fullSchema;
|
|
34744
34892
|
this.schema = schema;
|
|
@@ -34746,7 +34894,7 @@ var init_query = __esm(() => {
|
|
|
34746
34894
|
this.table = table2;
|
|
34747
34895
|
this.tableConfig = tableConfig;
|
|
34748
34896
|
this.dialect = dialect;
|
|
34749
|
-
this.session =
|
|
34897
|
+
this.session = session2;
|
|
34750
34898
|
this.config = config2;
|
|
34751
34899
|
this.mode = mode;
|
|
34752
34900
|
}
|
|
@@ -34842,24 +34990,24 @@ var init_db = __esm(() => {
|
|
|
34842
34990
|
init_raw();
|
|
34843
34991
|
init_refresh_materialized_view();
|
|
34844
34992
|
PgDatabase = class PgDatabase2 {
|
|
34845
|
-
constructor(dialect,
|
|
34993
|
+
constructor(dialect, session2, schema) {
|
|
34846
34994
|
this.dialect = dialect;
|
|
34847
|
-
this.session =
|
|
34995
|
+
this.session = session2;
|
|
34848
34996
|
this._ = schema ? {
|
|
34849
34997
|
schema: schema.schema,
|
|
34850
34998
|
fullSchema: schema.fullSchema,
|
|
34851
34999
|
tableNamesMap: schema.tableNamesMap,
|
|
34852
|
-
session
|
|
35000
|
+
session: session2
|
|
34853
35001
|
} : {
|
|
34854
35002
|
schema: undefined,
|
|
34855
35003
|
fullSchema: {},
|
|
34856
35004
|
tableNamesMap: {},
|
|
34857
|
-
session
|
|
35005
|
+
session: session2
|
|
34858
35006
|
};
|
|
34859
35007
|
this.query = {};
|
|
34860
35008
|
if (this._.schema) {
|
|
34861
35009
|
for (const [tableName, columns] of Object.entries(this._.schema)) {
|
|
34862
|
-
this.query[tableName] = new RelationalQueryBuilder(schema.fullSchema, this._.schema, this._.tableNamesMap, schema.fullSchema[tableName], columns, dialect,
|
|
35010
|
+
this.query[tableName] = new RelationalQueryBuilder(schema.fullSchema, this._.schema, this._.tableNamesMap, schema.fullSchema[tableName], columns, dialect, session2);
|
|
34863
35011
|
}
|
|
34864
35012
|
}
|
|
34865
35013
|
}
|
|
@@ -35114,8 +35262,8 @@ var init_session = __esm(() => {
|
|
|
35114
35262
|
}
|
|
35115
35263
|
};
|
|
35116
35264
|
PgTransaction = class PgTransaction2 extends PgDatabase {
|
|
35117
|
-
constructor(dialect,
|
|
35118
|
-
super(dialect,
|
|
35265
|
+
constructor(dialect, session2, schema, nestedIndex = 0) {
|
|
35266
|
+
super(dialect, session2, schema);
|
|
35119
35267
|
this.schema = schema;
|
|
35120
35268
|
this.nestedIndex = nestedIndex;
|
|
35121
35269
|
}
|
|
@@ -45982,13 +46130,13 @@ async function extractZipToDirectory(zipBuffer, targetDir) {
|
|
|
45982
46130
|
}
|
|
45983
46131
|
});
|
|
45984
46132
|
await Promise.all(extractPromises);
|
|
45985
|
-
|
|
46133
|
+
log2.debug("[utils/zip] Extracted ZIP to directory", {
|
|
45986
46134
|
targetDir,
|
|
45987
46135
|
fileCount: Object.keys(zip.files).length
|
|
45988
46136
|
});
|
|
45989
46137
|
} catch (error) {
|
|
45990
46138
|
const errorMessage2 = error instanceof Error ? error.message : String(error);
|
|
45991
|
-
|
|
46139
|
+
log2.error("[utils/zip] Failed to extract ZIP", { targetDir, error });
|
|
45992
46140
|
throw new Error(`Failed to extract ZIP to ${targetDir}: ${errorMessage2}`, { cause: error });
|
|
45993
46141
|
}
|
|
45994
46142
|
}
|
|
@@ -50275,7 +50423,7 @@ ${file}:${line3}:${column2}: ERROR: ${pluginText}${e.text}`;
|
|
|
50275
50423
|
return result;
|
|
50276
50424
|
}
|
|
50277
50425
|
var fs23 = __require2("fs");
|
|
50278
|
-
var
|
|
50426
|
+
var os22 = __require2("os");
|
|
50279
50427
|
var path2 = __require2("path");
|
|
50280
50428
|
var ESBUILD_BINARY_PATH = process.env.ESBUILD_BINARY_PATH || ESBUILD_BINARY_PATH;
|
|
50281
50429
|
var isValidBinaryPath = (x) => !!x && x !== "/usr/bin/esbuild";
|
|
@@ -50317,7 +50465,7 @@ ${file}:${line3}:${column2}: ERROR: ${pluginText}${e.text}`;
|
|
|
50317
50465
|
let pkg;
|
|
50318
50466
|
let subpath;
|
|
50319
50467
|
let isWASM = false;
|
|
50320
|
-
let platformKey = `${process.platform} ${
|
|
50468
|
+
let platformKey = `${process.platform} ${os22.arch()} ${os22.endianness()}`;
|
|
50321
50469
|
if (platformKey in knownWindowsPackages) {
|
|
50322
50470
|
pkg = knownWindowsPackages[platformKey];
|
|
50323
50471
|
subpath = "esbuild.exe";
|
|
@@ -50462,7 +50610,7 @@ for your current platform.`);
|
|
|
50462
50610
|
var crypto32 = __require2("crypto");
|
|
50463
50611
|
var path22 = __require2("path");
|
|
50464
50612
|
var fs222 = __require2("fs");
|
|
50465
|
-
var
|
|
50613
|
+
var os222 = __require2("os");
|
|
50466
50614
|
var tty2 = __require2("tty");
|
|
50467
50615
|
var worker_threads;
|
|
50468
50616
|
if (process.env.ESBUILD_WORKER_THREADS !== "0") {
|
|
@@ -50773,7 +50921,7 @@ More information: The file containing the code for esbuild's JavaScript API (${_
|
|
|
50773
50921
|
afterClose(null);
|
|
50774
50922
|
};
|
|
50775
50923
|
var randomFileName = () => {
|
|
50776
|
-
return path22.join(
|
|
50924
|
+
return path22.join(os222.tmpdir(), `esbuild-${crypto32.randomBytes(32).toString("hex")}`);
|
|
50777
50925
|
};
|
|
50778
50926
|
var workerThreadService = null;
|
|
50779
50927
|
var startWorkerThreadService = (worker_threads2) => {
|
|
@@ -51014,7 +51162,8 @@ class DeployService {
|
|
|
51014
51162
|
expiresIn: null,
|
|
51015
51163
|
permissions: {
|
|
51016
51164
|
games: [`read:${slug}`, `write:${slug}`]
|
|
51017
|
-
}
|
|
51165
|
+
},
|
|
51166
|
+
rateLimitEnabled: false
|
|
51018
51167
|
});
|
|
51019
51168
|
setAttribute("app.deploy.api_key_outcome", "created");
|
|
51020
51169
|
return apiKey;
|
|
@@ -51075,9 +51224,9 @@ class DeployService {
|
|
|
51075
51224
|
throw new ValidationError("Uploaded file is empty or not found");
|
|
51076
51225
|
}
|
|
51077
51226
|
setAttribute("app.deploy.asset_upload_size", frontendZip.length);
|
|
51078
|
-
const
|
|
51227
|
+
const os22 = await import("os");
|
|
51079
51228
|
const path2 = await import("path");
|
|
51080
|
-
const tempDir = path2.join(
|
|
51229
|
+
const tempDir = path2.join(os22.tmpdir(), `playcademy-deploy-${gameId}-${Date.now()}`);
|
|
51081
51230
|
const assetsPath = path2.join(tempDir, "dist");
|
|
51082
51231
|
await withSpan("deploy.extract_assets", () => extractZip(frontendZip, assetsPath));
|
|
51083
51232
|
uploadDeps.deleteObject(uploadToken).catch(catchAttrs("deploy.temp_cleanup"));
|
|
@@ -53551,12 +53700,14 @@ var init_secrets_service = __esm(() => {
|
|
|
53551
53700
|
init_deployment_util();
|
|
53552
53701
|
INTERNAL_SECRET_KEYS = ["PLAYCADEMY_API_KEY", "GAME_ID", "PLAYCADEMY_BASE_URL"];
|
|
53553
53702
|
});
|
|
53703
|
+
var ASSET_ROUTE_PREFIX = "/api/assets/";
|
|
53554
53704
|
var ROUTES;
|
|
53555
53705
|
var init_constants3 = __esm(() => {
|
|
53556
53706
|
init_src();
|
|
53557
53707
|
ROUTES = {
|
|
53558
53708
|
INDEX: "/api",
|
|
53559
53709
|
HEALTH: "/api/health",
|
|
53710
|
+
ASSETS: `${ASSET_ROUTE_PREFIX}*`,
|
|
53560
53711
|
TIMEBACK: {
|
|
53561
53712
|
END_ACTIVITY: `/api${TIMEBACK_ROUTES.END_ACTIVITY}`,
|
|
53562
53713
|
GET_XP: `/api${TIMEBACK_ROUTES.GET_XP}`,
|
|
@@ -63923,14 +64074,14 @@ function buildTimebackClient() {
|
|
|
63923
64074
|
}
|
|
63924
64075
|
const { mode, onerosterApiUrl, caliperApiUrl, clientId, clientSecret, authUrl } = config.timeback;
|
|
63925
64076
|
if (mode === "local") {
|
|
63926
|
-
|
|
64077
|
+
log2.debug("[Sandbox] Initializing TimeBack client (local mode)", { onerosterApiUrl });
|
|
63927
64078
|
return new TimebackClient({
|
|
63928
64079
|
baseUrl: onerosterApiUrl,
|
|
63929
64080
|
caliperUrl: caliperApiUrl
|
|
63930
64081
|
});
|
|
63931
64082
|
}
|
|
63932
64083
|
if (mode === "remote" && clientId && clientSecret && authUrl) {
|
|
63933
|
-
|
|
64084
|
+
log2.debug("[Sandbox] Initializing TimeBack client (remote mode)", { onerosterApiUrl });
|
|
63934
64085
|
return new TimebackClient({
|
|
63935
64086
|
baseUrl: onerosterApiUrl,
|
|
63936
64087
|
caliperUrl: caliperApiUrl,
|
|
@@ -63965,7 +64116,7 @@ function createSandboxAuthProvider() {
|
|
|
63965
64116
|
expiresAt: params.expiresIn ? new Date(Date.now() + params.expiresIn * 1000) : null
|
|
63966
64117
|
};
|
|
63967
64118
|
sandboxApiKeys.set(id, apiKey);
|
|
63968
|
-
|
|
64119
|
+
log2.debug("[SandboxAuthProvider] Created API key", { id, name: params.name });
|
|
63969
64120
|
return { id, key };
|
|
63970
64121
|
},
|
|
63971
64122
|
async listApiKeys(_headers) {
|
|
@@ -63973,13 +64124,13 @@ function createSandboxAuthProvider() {
|
|
|
63973
64124
|
},
|
|
63974
64125
|
async deleteApiKey(keyId) {
|
|
63975
64126
|
sandboxApiKeys.delete(keyId);
|
|
63976
|
-
|
|
64127
|
+
log2.debug("[SandboxAuthProvider] Deleted API key", { keyId });
|
|
63977
64128
|
},
|
|
63978
64129
|
async deleteApiKeyByName(name3, userId) {
|
|
63979
64130
|
for (const [id, key] of sandboxApiKeys.entries()) {
|
|
63980
64131
|
if (key.name === name3 && key.userId === userId) {
|
|
63981
64132
|
sandboxApiKeys.delete(id);
|
|
63982
|
-
|
|
64133
|
+
log2.debug("[SandboxAuthProvider] Deleted API key by name", { id, name: name3 });
|
|
63983
64134
|
return id;
|
|
63984
64135
|
}
|
|
63985
64136
|
}
|
|
@@ -64002,7 +64153,7 @@ function createSandboxAuthProvider() {
|
|
|
64002
64153
|
const payload2 = JSON.parse(atob(parts2[1]));
|
|
64003
64154
|
if (payload2.sub && payload2.uid) {
|
|
64004
64155
|
if (payload2.exp && payload2.exp < Date.now()) {
|
|
64005
|
-
|
|
64156
|
+
log2.debug("[SandboxAuthProvider] Token expired");
|
|
64006
64157
|
return null;
|
|
64007
64158
|
}
|
|
64008
64159
|
return payload2;
|
|
@@ -64053,7 +64204,7 @@ function createSandboxAuthProvider() {
|
|
|
64053
64204
|
const payload = JSON.parse(atob(parts2[1]));
|
|
64054
64205
|
if (payload.jti && payload.sub && payload.game) {
|
|
64055
64206
|
if (payload.exp && payload.exp < Date.now()) {
|
|
64056
|
-
|
|
64207
|
+
log2.debug("[SandboxAuthProvider] Log stream token expired");
|
|
64057
64208
|
return null;
|
|
64058
64209
|
}
|
|
64059
64210
|
return { jti: payload.jti, sub: payload.sub, game: payload.game };
|
|
@@ -64103,7 +64254,7 @@ var cache;
|
|
|
64103
64254
|
var init_cache_provider = __esm(() => {
|
|
64104
64255
|
cache = new Map;
|
|
64105
64256
|
});
|
|
64106
|
-
function
|
|
64257
|
+
function getBucket2(bucketName) {
|
|
64107
64258
|
let bucket = storage2.get(bucketName);
|
|
64108
64259
|
if (!bucket) {
|
|
64109
64260
|
bucket = new Map;
|
|
@@ -64114,7 +64265,7 @@ function getBucket(bucketName) {
|
|
|
64114
64265
|
function createSandboxStorageProvider() {
|
|
64115
64266
|
return {
|
|
64116
64267
|
async listObjects(bucketName, prefix) {
|
|
64117
|
-
const bucket =
|
|
64268
|
+
const bucket = getBucket2(bucketName);
|
|
64118
64269
|
const files = [];
|
|
64119
64270
|
for (const [key, data] of bucket.entries()) {
|
|
64120
64271
|
if (!prefix || key.startsWith(prefix)) {
|
|
@@ -64129,7 +64280,7 @@ function createSandboxStorageProvider() {
|
|
|
64129
64280
|
return files;
|
|
64130
64281
|
},
|
|
64131
64282
|
async getObject(bucketName, key) {
|
|
64132
|
-
const bucket =
|
|
64283
|
+
const bucket = getBucket2(bucketName);
|
|
64133
64284
|
const data = bucket.get(key);
|
|
64134
64285
|
if (!data) {
|
|
64135
64286
|
return null;
|
|
@@ -64141,18 +64292,18 @@ function createSandboxStorageProvider() {
|
|
|
64141
64292
|
};
|
|
64142
64293
|
},
|
|
64143
64294
|
async putObject(bucketName, key, body2, options) {
|
|
64144
|
-
const bucket =
|
|
64295
|
+
const bucket = getBucket2(bucketName);
|
|
64145
64296
|
bucket.set(key, { body: body2, contentType: options?.contentType });
|
|
64146
|
-
|
|
64297
|
+
log2.debug("[SandboxStorageProvider] Stored object", {
|
|
64147
64298
|
bucket: bucketName,
|
|
64148
64299
|
key,
|
|
64149
64300
|
size: body2.length
|
|
64150
64301
|
});
|
|
64151
64302
|
},
|
|
64152
64303
|
async deleteObject(bucketName, key) {
|
|
64153
|
-
const bucket =
|
|
64304
|
+
const bucket = getBucket2(bucketName);
|
|
64154
64305
|
bucket.delete(key);
|
|
64155
|
-
|
|
64306
|
+
log2.debug("[SandboxStorageProvider] Deleted object", { bucket: bucketName, key });
|
|
64156
64307
|
},
|
|
64157
64308
|
async generatePresignedPutUrl(bucketName, key, _contentType, _expiresIn) {
|
|
64158
64309
|
const baseUrl = "http://localhost:3000";
|
|
@@ -64218,7 +64369,7 @@ function createSandboxContext(options) {
|
|
|
64218
64369
|
};
|
|
64219
64370
|
Object.assign(services, createServices(ctx));
|
|
64220
64371
|
cachedServiceContext = ctx;
|
|
64221
|
-
|
|
64372
|
+
log2.debug("[Sandbox] ServiceContext initialized", {
|
|
64222
64373
|
sstStage: config2.sstStage,
|
|
64223
64374
|
baseUrl: config2.baseUrl,
|
|
64224
64375
|
hasTimeback: Boolean(timeback2)
|
|
@@ -73538,7 +73689,7 @@ var require_has_flag = __commonJS2((exports, module2) => {
|
|
|
73538
73689
|
};
|
|
73539
73690
|
});
|
|
73540
73691
|
var require_supports_color = __commonJS2((exports, module2) => {
|
|
73541
|
-
var
|
|
73692
|
+
var os22 = __require2("os");
|
|
73542
73693
|
var tty2 = __require2("tty");
|
|
73543
73694
|
var hasFlag = require_has_flag();
|
|
73544
73695
|
var { env } = process;
|
|
@@ -73586,7 +73737,7 @@ var require_supports_color = __commonJS2((exports, module2) => {
|
|
|
73586
73737
|
return min;
|
|
73587
73738
|
}
|
|
73588
73739
|
if (process.platform === "win32") {
|
|
73589
|
-
const osRelease =
|
|
73740
|
+
const osRelease = os22.release().split(".");
|
|
73590
73741
|
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
73591
73742
|
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
73592
73743
|
}
|
|
@@ -78700,8 +78851,8 @@ function assembleStyles() {
|
|
|
78700
78851
|
styles2.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
|
|
78701
78852
|
Object.defineProperties(styles2, {
|
|
78702
78853
|
rgbToAnsi256: {
|
|
78703
|
-
value(red,
|
|
78704
|
-
if (red ===
|
|
78854
|
+
value(red, green2, blue2) {
|
|
78855
|
+
if (red === green2 && green2 === blue2) {
|
|
78705
78856
|
if (red < 8) {
|
|
78706
78857
|
return 16;
|
|
78707
78858
|
}
|
|
@@ -78710,7 +78861,7 @@ function assembleStyles() {
|
|
|
78710
78861
|
}
|
|
78711
78862
|
return Math.round((red - 8) / 247 * 24) + 232;
|
|
78712
78863
|
}
|
|
78713
|
-
return 16 + 36 * Math.round(red / 255 * 5) + 6 * Math.round(
|
|
78864
|
+
return 16 + 36 * Math.round(red / 255 * 5) + 6 * Math.round(green2 / 255 * 5) + Math.round(blue2 / 255 * 5);
|
|
78714
78865
|
},
|
|
78715
78866
|
enumerable: false
|
|
78716
78867
|
},
|
|
@@ -78746,24 +78897,24 @@ function assembleStyles() {
|
|
|
78746
78897
|
return 90 + (code - 8);
|
|
78747
78898
|
}
|
|
78748
78899
|
let red;
|
|
78749
|
-
let
|
|
78750
|
-
let
|
|
78900
|
+
let green2;
|
|
78901
|
+
let blue2;
|
|
78751
78902
|
if (code >= 232) {
|
|
78752
78903
|
red = ((code - 232) * 10 + 8) / 255;
|
|
78753
|
-
|
|
78754
|
-
|
|
78904
|
+
green2 = red;
|
|
78905
|
+
blue2 = red;
|
|
78755
78906
|
} else {
|
|
78756
78907
|
code -= 16;
|
|
78757
78908
|
const remainder = code % 36;
|
|
78758
78909
|
red = Math.floor(code / 36) / 5;
|
|
78759
|
-
|
|
78760
|
-
|
|
78910
|
+
green2 = Math.floor(remainder / 6) / 5;
|
|
78911
|
+
blue2 = remainder % 6 / 5;
|
|
78761
78912
|
}
|
|
78762
|
-
const value = Math.max(red,
|
|
78913
|
+
const value = Math.max(red, green2, blue2) * 2;
|
|
78763
78914
|
if (value === 0) {
|
|
78764
78915
|
return 30;
|
|
78765
78916
|
}
|
|
78766
|
-
let result = 30 + (Math.round(
|
|
78917
|
+
let result = 30 + (Math.round(blue2) << 2 | Math.round(green2) << 1 | Math.round(red));
|
|
78767
78918
|
if (value === 2) {
|
|
78768
78919
|
result += 60;
|
|
78769
78920
|
}
|
|
@@ -78772,7 +78923,7 @@ function assembleStyles() {
|
|
|
78772
78923
|
enumerable: false
|
|
78773
78924
|
},
|
|
78774
78925
|
rgbToAnsi: {
|
|
78775
|
-
value: (red,
|
|
78926
|
+
value: (red, green2, blue2) => styles2.ansi256ToAnsi(styles2.rgbToAnsi256(red, green2, blue2)),
|
|
78776
78927
|
enumerable: false
|
|
78777
78928
|
},
|
|
78778
78929
|
hexToAnsi: {
|
|
@@ -78838,7 +78989,7 @@ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
|
|
|
78838
78989
|
return min2;
|
|
78839
78990
|
}
|
|
78840
78991
|
if (process2.platform === "win32") {
|
|
78841
|
-
const osRelease =
|
|
78992
|
+
const osRelease = os2.release().split(".");
|
|
78842
78993
|
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
78843
78994
|
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
78844
78995
|
}
|
|
@@ -84239,7 +84390,7 @@ var init_api2 = __esm(() => {
|
|
|
84239
84390
|
ANSI_BACKGROUND_OFFSET = 10;
|
|
84240
84391
|
wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`;
|
|
84241
84392
|
wrapAnsi256 = (offset = 0) => (code) => `\x1B[${38 + offset};5;${code}m`;
|
|
84242
|
-
wrapAnsi16m = (offset = 0) => (red,
|
|
84393
|
+
wrapAnsi16m = (offset = 0) => (red, green2, blue2) => `\x1B[${38 + offset};2;${red};${green2};${blue2}m`;
|
|
84243
84394
|
styles2 = {
|
|
84244
84395
|
modifier: {
|
|
84245
84396
|
reset: [0, 0],
|
|
@@ -94105,7 +94256,7 @@ Is ${source_default.bold.blue(this.base.name)} schema created or renamed from an
|
|
|
94105
94256
|
});
|
|
94106
94257
|
require_supports_colors = __commonJS22({
|
|
94107
94258
|
"../node_modules/.pnpm/colors@1.4.0/node_modules/colors/lib/system/supports-colors.js"(exports, module2) {
|
|
94108
|
-
var
|
|
94259
|
+
var os22 = __require22("os");
|
|
94109
94260
|
var hasFlag2 = require_has_flag2();
|
|
94110
94261
|
var env2 = process.env;
|
|
94111
94262
|
var forceColor = undefined;
|
|
@@ -94143,7 +94294,7 @@ Is ${source_default.bold.blue(this.base.name)} schema created or renamed from an
|
|
|
94143
94294
|
}
|
|
94144
94295
|
var min2 = forceColor ? 1 : 0;
|
|
94145
94296
|
if (process.platform === "win32") {
|
|
94146
|
-
var osRelease =
|
|
94297
|
+
var osRelease = os22.release().split(".");
|
|
94147
94298
|
if (Number(process.versions.node.split(".")[0]) >= 8 && Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
94148
94299
|
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
94149
94300
|
}
|
|
@@ -121921,8 +122072,8 @@ var require_colorette = __commonJS2((exports) => {
|
|
|
121921
122072
|
var createColors = ({ useColor = isColorSupported } = {}) => useColor ? colors3 : Object.keys(colors3).reduce((colors4, key) => ({ ...colors4, [key]: String }), {});
|
|
121922
122073
|
var {
|
|
121923
122074
|
reset,
|
|
121924
|
-
bold:
|
|
121925
|
-
dim:
|
|
122075
|
+
bold: bold22,
|
|
122076
|
+
dim: dim22,
|
|
121926
122077
|
italic,
|
|
121927
122078
|
underline,
|
|
121928
122079
|
inverse,
|
|
@@ -121930,11 +122081,11 @@ var require_colorette = __commonJS2((exports) => {
|
|
|
121930
122081
|
strikethrough,
|
|
121931
122082
|
black,
|
|
121932
122083
|
red,
|
|
121933
|
-
green,
|
|
122084
|
+
green: green2,
|
|
121934
122085
|
yellow,
|
|
121935
|
-
blue,
|
|
122086
|
+
blue: blue2,
|
|
121936
122087
|
magenta,
|
|
121937
|
-
cyan:
|
|
122088
|
+
cyan: cyan3,
|
|
121938
122089
|
white,
|
|
121939
122090
|
gray,
|
|
121940
122091
|
bgBlack,
|
|
@@ -121947,7 +122098,7 @@ var require_colorette = __commonJS2((exports) => {
|
|
|
121947
122098
|
bgWhite,
|
|
121948
122099
|
blackBright,
|
|
121949
122100
|
redBright,
|
|
121950
|
-
greenBright,
|
|
122101
|
+
greenBright: greenBright2,
|
|
121951
122102
|
yellowBright,
|
|
121952
122103
|
blueBright,
|
|
121953
122104
|
magentaBright,
|
|
@@ -121980,16 +122131,16 @@ var require_colorette = __commonJS2((exports) => {
|
|
|
121980
122131
|
exports.bgYellowBright = bgYellowBright;
|
|
121981
122132
|
exports.black = black;
|
|
121982
122133
|
exports.blackBright = blackBright;
|
|
121983
|
-
exports.blue =
|
|
122134
|
+
exports.blue = blue2;
|
|
121984
122135
|
exports.blueBright = blueBright;
|
|
121985
|
-
exports.bold =
|
|
122136
|
+
exports.bold = bold22;
|
|
121986
122137
|
exports.createColors = createColors;
|
|
121987
|
-
exports.cyan =
|
|
122138
|
+
exports.cyan = cyan3;
|
|
121988
122139
|
exports.cyanBright = cyanBright;
|
|
121989
|
-
exports.dim =
|
|
122140
|
+
exports.dim = dim22;
|
|
121990
122141
|
exports.gray = gray;
|
|
121991
|
-
exports.green =
|
|
121992
|
-
exports.greenBright =
|
|
122142
|
+
exports.green = green2;
|
|
122143
|
+
exports.greenBright = greenBright2;
|
|
121993
122144
|
exports.hidden = hidden;
|
|
121994
122145
|
exports.inverse = inverse;
|
|
121995
122146
|
exports.isColorSupported = isColorSupported;
|
|
@@ -122168,7 +122319,7 @@ function processServerOptions(_port, options) {
|
|
|
122168
122319
|
if (customLogger2) {
|
|
122169
122320
|
setLogger(customLogger2);
|
|
122170
122321
|
setCustomLogHandler((level, message, context2, scope) => {
|
|
122171
|
-
const scopePrefix = scope ? `${
|
|
122322
|
+
const scopePrefix = scope ? `${import_picocolors5.default.bold(`[${scope}]`)} ` : "";
|
|
122172
122323
|
let formattedMessage = `${scopePrefix}${message}`;
|
|
122173
122324
|
if (context2) {
|
|
122174
122325
|
const colorized = import_json_colorizer.colorize(context2);
|
|
@@ -122192,13 +122343,13 @@ ${stripped}`;
|
|
|
122192
122343
|
};
|
|
122193
122344
|
}
|
|
122194
122345
|
var import_json_colorizer;
|
|
122195
|
-
var
|
|
122346
|
+
var import_picocolors5;
|
|
122196
122347
|
var init_options = __esm(() => {
|
|
122197
122348
|
init_src2();
|
|
122198
122349
|
init_config();
|
|
122199
122350
|
init_logging();
|
|
122200
122351
|
import_json_colorizer = __toESM2(require_dist2(), 1);
|
|
122201
|
-
|
|
122352
|
+
import_picocolors5 = __toESM2(require_picocolors2(), 1);
|
|
122202
122353
|
});
|
|
122203
122354
|
var healthRouter;
|
|
122204
122355
|
var init_health = __esm(() => {
|
|
@@ -124104,7 +124255,7 @@ async function getMockTimebackData(db2, timebackId, gameId) {
|
|
|
124104
124255
|
const { role, organizations } = getMockStudentProfile();
|
|
124105
124256
|
const allEnrollments = await getMockEnrollments(db2);
|
|
124106
124257
|
const enrollments = gameId ? filterEnrollmentsByGame(allEnrollments, gameId) : allEnrollments;
|
|
124107
|
-
|
|
124258
|
+
log2.debug("[Timeback] Sandbox is using mock data", {
|
|
124108
124259
|
timebackId,
|
|
124109
124260
|
role,
|
|
124110
124261
|
enrollments: enrollments.map((e) => `${e.subject}:${e.grade}`),
|
|
@@ -124309,7 +124460,7 @@ var init_deploy = __esm(() => {
|
|
|
124309
124460
|
init_src2();
|
|
124310
124461
|
init_api();
|
|
124311
124462
|
init_uploads();
|
|
124312
|
-
logger4 =
|
|
124463
|
+
logger4 = log2.scope("SandboxDeploy");
|
|
124313
124464
|
gameDeployRouter = new Hono2;
|
|
124314
124465
|
gameDeployRouter.post("/:slug/deploy", async (c2) => {
|
|
124315
124466
|
const user = c2.get("user");
|
|
@@ -125007,7 +125158,7 @@ var init_lti = __esm(() => {
|
|
|
125007
125158
|
init_src2();
|
|
125008
125159
|
init_constants();
|
|
125009
125160
|
init_api();
|
|
125010
|
-
logger5 =
|
|
125161
|
+
logger5 = log2.scope("SandboxLti");
|
|
125011
125162
|
ltiRouter = new Hono2;
|
|
125012
125163
|
ltiRouter.post("/launch", async (c2) => {
|
|
125013
125164
|
const db2 = c2.get("db");
|
|
@@ -125194,68 +125345,10 @@ var init_server = __esm(() => {
|
|
|
125194
125345
|
});
|
|
125195
125346
|
init_server();
|
|
125196
125347
|
|
|
125197
|
-
// src/lib/logging/adapter.ts
|
|
125198
|
-
function createLoggerAdapter(domain) {
|
|
125199
|
-
return {
|
|
125200
|
-
info: (msg) => console.log(`${createLogPrefix("playcademy", domain)} ${msg}`),
|
|
125201
|
-
warn: (msg) => console.warn(`${createLogPrefix("playcademy", domain)} ${msg}`),
|
|
125202
|
-
error: (msg) => console.error(`${createLogPrefix("playcademy", domain)} ${msg}`)
|
|
125203
|
-
};
|
|
125204
|
-
}
|
|
125205
|
-
// src/lib/logging/utils.ts
|
|
125206
|
-
var import_picocolors4 = __toESM(require_picocolors(), 1);
|
|
125207
|
-
|
|
125208
|
-
// ../utils/src/string.ts
|
|
125209
|
-
function pluralize(count2, singular, plural) {
|
|
125210
|
-
return count2 === 1 ? singular : plural || `${singular}s`;
|
|
125211
|
-
}
|
|
125212
|
-
|
|
125213
|
-
// src/lib/logging/utils.ts
|
|
125214
|
-
function createBackendBannerOptions(backendPort, vitePort) {
|
|
125215
|
-
if (!backendPort) {
|
|
125216
|
-
return;
|
|
125217
|
-
}
|
|
125218
|
-
return { port: backendPort, vitePort };
|
|
125219
|
-
}
|
|
125220
|
-
function createTimebackBannerOptions(timebackMode, courseCount, enrolledCount) {
|
|
125221
|
-
if (!timebackMode || !courseCount) {
|
|
125222
|
-
return;
|
|
125223
|
-
}
|
|
125224
|
-
return {
|
|
125225
|
-
courseCount,
|
|
125226
|
-
enrolledCount: enrolledCount ?? courseCount,
|
|
125227
|
-
mode: timebackMode
|
|
125228
|
-
};
|
|
125229
|
-
}
|
|
125230
|
-
function printBanner(viteConfig, options) {
|
|
125231
|
-
const INDENT = " ".repeat(2);
|
|
125232
|
-
const { version: version4, gameName, sandbox, backend, timeback } = options;
|
|
125233
|
-
viteConfig.logger.info("");
|
|
125234
|
-
viteConfig.logger.info(`${INDENT}${import_picocolors4.green(import_picocolors4.bold("PLAYCADEMY"))} ${import_picocolors4.green(`v${version4}`)}`);
|
|
125235
|
-
viteConfig.logger.info("");
|
|
125236
|
-
if (gameName) {
|
|
125237
|
-
viteConfig.logger.info(`${INDENT}${import_picocolors4.green("➜")} ${import_picocolors4.bold("Project:")} ${import_picocolors4.cyan(gameName)}`);
|
|
125238
|
-
}
|
|
125239
|
-
if (sandbox?.enabled) {
|
|
125240
|
-
viteConfig.logger.info(`${INDENT}${import_picocolors4.green("➜")} ${import_picocolors4.bold("Sandbox:")} ${import_picocolors4.cyan(`http://localhost:${import_picocolors4.bold(sandbox.port.toString())}/api`)}`);
|
|
125241
|
-
} else if (sandbox) {
|
|
125242
|
-
viteConfig.logger.info(`${INDENT}${import_picocolors4.green("➜")} ${import_picocolors4.bold("Sandbox:")} ${import_picocolors4.cyan("Disabled")}`);
|
|
125243
|
-
}
|
|
125244
|
-
if (backend) {
|
|
125245
|
-
const backendUrl = backend.vitePort ? `http://localhost:${import_picocolors4.bold(backend.vitePort.toString())}/api ${import_picocolors4.dim(`(via ${backend.port})`)}` : `http://localhost:${import_picocolors4.bold(backend.port.toString())}/api`;
|
|
125246
|
-
viteConfig.logger.info(`${INDENT}${import_picocolors4.green("➜")} ${import_picocolors4.bold("Backend:")} ${import_picocolors4.cyan(backendUrl)}`);
|
|
125247
|
-
}
|
|
125248
|
-
if (timeback && timeback.courseCount > 0) {
|
|
125249
|
-
const enrollmentInfo = timeback.enrolledCount !== timeback.courseCount ? ` / ${timeback.enrolledCount} enrolled` : "";
|
|
125250
|
-
const label = `${timeback.courseCount} ${pluralize(timeback.courseCount, "course")}${enrollmentInfo} ${import_picocolors4.dim(`(${timeback.mode})`)}`;
|
|
125251
|
-
viteConfig.logger.info(`${INDENT}${import_picocolors4.green("➜")} ${import_picocolors4.bold("Timeback:")} ${import_picocolors4.cyan(label)}`);
|
|
125252
|
-
}
|
|
125253
|
-
viteConfig.logger.info("");
|
|
125254
|
-
}
|
|
125255
125348
|
// src/lib/sandbox/project-info.ts
|
|
125256
125349
|
import fs5 from "node:fs";
|
|
125257
125350
|
import path3 from "node:path";
|
|
125258
|
-
import { loadPlaycademyConfig } from "playcademy/utils";
|
|
125351
|
+
import { loadPlaycademyConfig as loadPlaycademyConfig2 } from "playcademy/utils";
|
|
125259
125352
|
|
|
125260
125353
|
// ../utils/src/uuid.ts
|
|
125261
125354
|
var UUID_REGEX2 = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
|
|
@@ -125476,7 +125569,7 @@ async function extractProjectInfo(viteConfig, timebackOptions) {
|
|
|
125476
125569
|
const directoryName = path3.basename(projectRoot);
|
|
125477
125570
|
let config2 = null;
|
|
125478
125571
|
try {
|
|
125479
|
-
config2 = await
|
|
125572
|
+
config2 = await loadPlaycademyConfig2();
|
|
125480
125573
|
} catch {}
|
|
125481
125574
|
let packageJson = {};
|
|
125482
125575
|
try {
|
|
@@ -125508,7 +125601,7 @@ async function extractProjectInfo(viteConfig, timebackOptions) {
|
|
|
125508
125601
|
}
|
|
125509
125602
|
|
|
125510
125603
|
// src/lib/sandbox/timeback.ts
|
|
125511
|
-
var
|
|
125604
|
+
var import_picocolors6 = __toESM(require_picocolors(), 1);
|
|
125512
125605
|
// ../constants/src/domains.ts
|
|
125513
125606
|
var POSTHOG_CONFIG = {
|
|
125514
125607
|
apiKey: "phc_z7aVQnB4P9FHm91g0BSfJTlIU6lISCBVhIJEFdfnYfX",
|
|
@@ -125573,9 +125666,9 @@ function validateTimebackConfig(viteConfig, timeback3) {
|
|
|
125573
125666
|
if (realCourses.length > 0 && !hasTimebackCredentials2()) {
|
|
125574
125667
|
const courseList = realCourses.map(([key]) => key).join(", ");
|
|
125575
125668
|
viteConfig.logger.warn("");
|
|
125576
|
-
viteConfig.logger.warn(
|
|
125577
|
-
viteConfig.logger.warn(
|
|
125578
|
-
viteConfig.logger.warn(
|
|
125669
|
+
viteConfig.logger.warn(import_picocolors6.default.yellow(`⚠️ TimeBack: Real course IDs for ${import_picocolors6.default.bold(courseList)} but credentials missing.`));
|
|
125670
|
+
viteConfig.logger.warn(import_picocolors6.default.dim(` Required: TIMEBACK_API_CLIENT_ID, TIMEBACK_API_CLIENT_SECRET, TIMEBACK_API_AUTH_URL, TIMEBACK_ONEROSTER_API_URL`));
|
|
125671
|
+
viteConfig.logger.warn(import_picocolors6.default.dim(` Or use 'mock' for local testing.`));
|
|
125579
125672
|
viteConfig.logger.warn("");
|
|
125580
125673
|
}
|
|
125581
125674
|
}
|
|
@@ -125694,7 +125787,7 @@ async function startSandbox(viteConfig, autoStart = true, options = {}) {
|
|
|
125694
125787
|
}
|
|
125695
125788
|
};
|
|
125696
125789
|
} catch (error2) {
|
|
125697
|
-
viteConfig.logger.error(
|
|
125790
|
+
viteConfig.logger.error(import_picocolors7.default.red(`[Playcademy] Failed to start sandbox: ${error2}`));
|
|
125698
125791
|
return {
|
|
125699
125792
|
baseUrl: `http://localhost:${DEFAULT_PORTS2.SANDBOX}`,
|
|
125700
125793
|
port: DEFAULT_PORTS2.SANDBOX,
|
|
@@ -126167,11 +126260,11 @@ async function recreateSandbox(options) {
|
|
|
126167
126260
|
const viteServer = getViteServerRef();
|
|
126168
126261
|
const prefix2 = createLogPrefix("playcademy", "sandbox");
|
|
126169
126262
|
if (!viteServer) {
|
|
126170
|
-
viteConfig.logger.error(`${prefix2} ${
|
|
126263
|
+
viteConfig.logger.error(`${prefix2} ${import_picocolors8.red("Cannot recreate sandbox database: no Vite server reference")}`);
|
|
126171
126264
|
return { success: false, error: "No Vite server reference" };
|
|
126172
126265
|
}
|
|
126173
126266
|
if (!isShellMode(currentMode)) {
|
|
126174
|
-
viteConfig.logger.warn(`${prefix2} ${
|
|
126267
|
+
viteConfig.logger.warn(`${prefix2} ${import_picocolors8.yellow("can only recreate sandbox database in platform or demo mode")}`);
|
|
126175
126268
|
return { success: false, error: "Not in a shell-backed mode" };
|
|
126176
126269
|
}
|
|
126177
126270
|
viteConfig.logger.info(`${prefix2} recreating database...`);
|
|
@@ -126204,7 +126297,7 @@ async function recreateSandbox(options) {
|
|
|
126204
126297
|
}
|
|
126205
126298
|
});
|
|
126206
126299
|
}
|
|
126207
|
-
viteConfig.logger.info(`${prefix2} ${
|
|
126300
|
+
viteConfig.logger.info(`${prefix2} ${import_picocolors8.green("database recreated")}`);
|
|
126208
126301
|
return { success: true };
|
|
126209
126302
|
}
|
|
126210
126303
|
|
|
@@ -126251,38 +126344,38 @@ function setupConfigWatcher(server, viteConfig, platformModeOptions) {
|
|
|
126251
126344
|
}
|
|
126252
126345
|
|
|
126253
126346
|
// src/server/hotkeys/cycle-platform-role.ts
|
|
126254
|
-
var
|
|
126347
|
+
var import_picocolors9 = __toESM(require_picocolors(), 1);
|
|
126255
126348
|
|
|
126256
126349
|
// src/types/internal.ts
|
|
126257
126350
|
var TIMEBACK_ROLES = ["student", "parent", "teacher", "administrator"];
|
|
126258
126351
|
var PLATFORM_ROLES = ["player", "developer", "admin"];
|
|
126259
126352
|
// src/server/hotkeys/cycle-platform-role.ts
|
|
126260
|
-
function cyclePlatformRole(
|
|
126353
|
+
function cyclePlatformRole(logger6) {
|
|
126261
126354
|
const currentRole = getPlatformRoleOverride() ?? "player";
|
|
126262
126355
|
const currentIndex = PLATFORM_ROLES.indexOf(currentRole);
|
|
126263
126356
|
const nextIndex = (currentIndex + 1) % PLATFORM_ROLES.length;
|
|
126264
126357
|
const nextRole = PLATFORM_ROLES[nextIndex];
|
|
126265
126358
|
const prefix2 = createLogPrefix("playcademy", "user");
|
|
126266
126359
|
setPlatformRoleOverride(nextRole);
|
|
126267
|
-
|
|
126360
|
+
logger6.info(`${prefix2} ${import_picocolors9.red(currentRole)} → ${import_picocolors9.green(nextRole)}`);
|
|
126268
126361
|
if (getViteServerRef()) {
|
|
126269
126362
|
getViteServerRef()?.ws.send({ type: "full-reload", path: "*" });
|
|
126270
126363
|
} else {
|
|
126271
|
-
|
|
126364
|
+
logger6.warn(`${prefix2} ${import_picocolors9.yellow("Cannot cycle platform role: no Vite server reference")}`);
|
|
126272
126365
|
}
|
|
126273
126366
|
}
|
|
126274
126367
|
function cyclePlatformRoleHotkey(options) {
|
|
126275
126368
|
return {
|
|
126276
126369
|
key: "p",
|
|
126277
|
-
description: `${
|
|
126370
|
+
description: `${import_picocolors9.cyan(import_picocolors9.bold("[playcademy]"))} cycle platform role`,
|
|
126278
126371
|
action: () => cyclePlatformRole(options.viteConfig.logger)
|
|
126279
126372
|
};
|
|
126280
126373
|
}
|
|
126281
126374
|
|
|
126282
126375
|
// src/server/hotkeys/cycle-timeback-role.ts
|
|
126283
|
-
var
|
|
126284
|
-
var { bold: bold5, cyan: cyan4, green: green4, red: red3, yellow: yellow3 } =
|
|
126285
|
-
function cycleTimebackRole(
|
|
126376
|
+
var import_picocolors10 = __toESM(require_picocolors(), 1);
|
|
126377
|
+
var { bold: bold5, cyan: cyan4, green: green4, red: red3, yellow: yellow3 } = import_picocolors10.default;
|
|
126378
|
+
function cycleTimebackRole(logger6) {
|
|
126286
126379
|
const currentRole = getTimebackRoleOverride() ?? "student";
|
|
126287
126380
|
const currentIndex = TIMEBACK_ROLES.indexOf(currentRole);
|
|
126288
126381
|
const nextIndex = (currentIndex + 1) % TIMEBACK_ROLES.length;
|
|
@@ -126290,11 +126383,11 @@ function cycleTimebackRole(logger) {
|
|
|
126290
126383
|
setTimebackRoleOverride(nextRole);
|
|
126291
126384
|
getSandboxRef()?.setRole?.(nextRole);
|
|
126292
126385
|
const prefix2 = createLogPrefix("playcademy", "timeback");
|
|
126293
|
-
|
|
126386
|
+
logger6.info(`${prefix2} ${red3(currentRole)} → ${green4(nextRole)}`);
|
|
126294
126387
|
if (getViteServerRef()) {
|
|
126295
126388
|
getViteServerRef()?.ws.send({ type: "full-reload", path: "*" });
|
|
126296
126389
|
} else {
|
|
126297
|
-
|
|
126390
|
+
logger6.warn(`${prefix2} ${yellow3("Cannot cycle TimeBack role: no Vite server reference")}`);
|
|
126298
126391
|
}
|
|
126299
126392
|
}
|
|
126300
126393
|
function cycleTimebackRoleHotkey(options) {
|
|
@@ -126306,8 +126399,8 @@ function cycleTimebackRoleHotkey(options) {
|
|
|
126306
126399
|
}
|
|
126307
126400
|
|
|
126308
126401
|
// src/server/hotkeys/recreate-database.ts
|
|
126309
|
-
var
|
|
126310
|
-
var { bold: bold6, cyan: cyan5 } =
|
|
126402
|
+
var import_picocolors11 = __toESM(require_picocolors(), 1);
|
|
126403
|
+
var { bold: bold6, cyan: cyan5 } = import_picocolors11.default;
|
|
126311
126404
|
async function recreateSandboxDatabase(options) {
|
|
126312
126405
|
await recreateSandbox({
|
|
126313
126406
|
viteConfig: options.viteConfig,
|
|
@@ -126323,7 +126416,7 @@ function recreateDatabaseHotkey(options) {
|
|
|
126323
126416
|
}
|
|
126324
126417
|
|
|
126325
126418
|
// src/server/hotkeys/toggle-mode.ts
|
|
126326
|
-
var
|
|
126419
|
+
var import_picocolors13 = __toESM(require_picocolors(), 1);
|
|
126327
126420
|
|
|
126328
126421
|
// src/lib/backend/server.ts
|
|
126329
126422
|
import {
|
|
@@ -126333,7 +126426,7 @@ import {
|
|
|
126333
126426
|
} from "playcademy/utils";
|
|
126334
126427
|
|
|
126335
126428
|
// src/lib/backend/hot-reload.ts
|
|
126336
|
-
var
|
|
126429
|
+
var import_picocolors12 = __toESM(require_picocolors(), 1);
|
|
126337
126430
|
import path5 from "node:path";
|
|
126338
126431
|
function createHotReloadCallbacks(viteConfig) {
|
|
126339
126432
|
function formatPath(changedPath) {
|
|
@@ -126350,7 +126443,7 @@ function createHotReloadCallbacks(viteConfig) {
|
|
|
126350
126443
|
onSuccess: (changedPath) => {
|
|
126351
126444
|
const relativePath = formatPath(changedPath);
|
|
126352
126445
|
if (relativePath) {
|
|
126353
|
-
viteConfig.logger.info(`${prefix2} ${
|
|
126446
|
+
viteConfig.logger.info(`${prefix2} ${import_picocolors12.green("hmr update")} ${import_picocolors12.dim(relativePath)}`);
|
|
126354
126447
|
} else {
|
|
126355
126448
|
viteConfig.logger.info(`${prefix2} reloaded`);
|
|
126356
126449
|
}
|
|
@@ -126532,7 +126625,7 @@ async function toggleMode(options) {
|
|
|
126532
126625
|
const viteServer = getViteServerRef();
|
|
126533
126626
|
const prefix2 = createLogPrefix("playcademy");
|
|
126534
126627
|
if (!viteServer) {
|
|
126535
|
-
options.viteConfig.logger.error(`${prefix2} ${
|
|
126628
|
+
options.viteConfig.logger.error(`${prefix2} ${import_picocolors13.red("Cannot toggle mode: no Vite server reference")}`);
|
|
126536
126629
|
return;
|
|
126537
126630
|
}
|
|
126538
126631
|
await cleanupServers();
|
|
@@ -126546,12 +126639,12 @@ async function toggleMode(options) {
|
|
|
126546
126639
|
} else {
|
|
126547
126640
|
await configurePlatformMode(viteServer, options.viteConfig, options.platformModeOptions);
|
|
126548
126641
|
}
|
|
126549
|
-
options.viteConfig.logger.info(`${prefix2} ${
|
|
126642
|
+
options.viteConfig.logger.info(`${prefix2} ${import_picocolors13.green("switched to")} ${import_picocolors13.green(import_picocolors13.bold(newMode))} ${import_picocolors13.green("mode")}`);
|
|
126550
126643
|
}
|
|
126551
126644
|
function toggleModeHotkey(options) {
|
|
126552
126645
|
return {
|
|
126553
126646
|
key: "m",
|
|
126554
|
-
description: `${
|
|
126647
|
+
description: `${import_picocolors13.cyan(import_picocolors13.bold("[playcademy]"))} cycle platform/demo/standalone mode`,
|
|
126555
126648
|
action: () => toggleMode(options)
|
|
126556
126649
|
};
|
|
126557
126650
|
}
|
|
@@ -126594,6 +126687,7 @@ async function configureServerHook(server, context) {
|
|
|
126594
126687
|
setViteServerRef(server);
|
|
126595
126688
|
setCurrentMode(context.options.mode);
|
|
126596
126689
|
setupProcessShutdownHandlers();
|
|
126690
|
+
await registerAssetMiddleware(server, context.viteConfig.root, context.options.configPath);
|
|
126597
126691
|
if (hasActiveServers()) {
|
|
126598
126692
|
await cleanupServers();
|
|
126599
126693
|
}
|
|
@@ -126672,17 +126766,24 @@ function buildInitCall() {
|
|
|
126672
126766
|
].join(",");
|
|
126673
126767
|
return `posthog.init('${POSTHOG_CONFIG.apiKey}',{${config2}},'${POSTHOG_INSTANCE_NAME}');`;
|
|
126674
126768
|
}
|
|
126675
|
-
function transformIndexHtmlHook(context) {
|
|
126676
|
-
|
|
126677
|
-
|
|
126769
|
+
async function transformIndexHtmlHook(context) {
|
|
126770
|
+
const isBuild = context.viteConfig?.command === "build";
|
|
126771
|
+
const tags = [];
|
|
126772
|
+
if (!isBuild) {
|
|
126773
|
+
const manifestScript = await getDevManifestScript(context.options.configPath);
|
|
126774
|
+
if (manifestScript) {
|
|
126775
|
+
const body2 = manifestScript.replace(/^<script>/, "").replace(/<\/script>$/, "");
|
|
126776
|
+
tags.push({ tag: "script", children: body2, injectTo: "head" });
|
|
126777
|
+
}
|
|
126678
126778
|
}
|
|
126679
|
-
|
|
126680
|
-
{
|
|
126779
|
+
if (isBuild) {
|
|
126780
|
+
tags.push({
|
|
126681
126781
|
tag: "script",
|
|
126682
126782
|
children: SERVER_TIMING_PATCH + POSTHOG_LOADER + buildInitCall(),
|
|
126683
126783
|
injectTo: "head"
|
|
126684
|
-
}
|
|
126685
|
-
|
|
126784
|
+
});
|
|
126785
|
+
}
|
|
126786
|
+
return tags;
|
|
126686
126787
|
}
|
|
126687
126788
|
|
|
126688
126789
|
// src/hooks/write-bundle.ts
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local asset dev support.
|
|
3
|
+
*
|
|
4
|
+
* In production the edge worker injects the asset manifest into the page and
|
|
5
|
+
* serves `/api/assets/*` from R2. There is no edge worker in `vite dev`, so the
|
|
6
|
+
* plugin reproduces both against the local Miniflare bucket that
|
|
7
|
+
* `playcademy bucket sync` writes to — making the SDK's `asset()` resolver work
|
|
8
|
+
* locally exactly as it does on the platform.
|
|
9
|
+
*
|
|
10
|
+
* A single Miniflare instance is opened for the dev server's lifetime (not one
|
|
11
|
+
* per request) and reused for the manifest read and every asset read. It still
|
|
12
|
+
* observes `bucket sync` writes to the same persist dir, so it stays fresh
|
|
13
|
+
* across syncs without reopening.
|
|
14
|
+
*
|
|
15
|
+
* The local-bucket reads go through `playcademy/bucket` (Node-only, build-time
|
|
16
|
+
* tooling). This never reaches a game's browser bundle — frontends use the
|
|
17
|
+
* dependency-free `@playcademy/sdk/assets` `asset()` resolver instead.
|
|
18
|
+
*/
|
|
19
|
+
import type { ViteDevServer } from 'vite';
|
|
20
|
+
/** Dispose the persistent local-bucket session (call on dev-server shutdown). */
|
|
21
|
+
export declare function disposeAssetBucket(): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Build the `<script>` injecting `self.__PLAYCADEMY_ASSET_MANIFEST` for dev,
|
|
24
|
+
* read from the local bucket. Returns `null` when bucket storage isn't enabled
|
|
25
|
+
* or no `bucket sync` has populated the local bucket yet — in the latter case,
|
|
26
|
+
* warns once so the dev knows why `asset()` paths 404 (re-syncing then reloading
|
|
27
|
+
* picks up the manifest without restarting the dev server).
|
|
28
|
+
*/
|
|
29
|
+
export declare function getDevManifestScript(configPath?: string): Promise<string | null>;
|
|
30
|
+
/**
|
|
31
|
+
* Register the dev middleware that serves `/api/assets/*` from the local bucket,
|
|
32
|
+
* mirroring the edge asset route (the request path after the route prefix maps
|
|
33
|
+
* to the stored object).
|
|
34
|
+
*
|
|
35
|
+
* No-op when bucket storage isn't enabled, or when the game defines its own
|
|
36
|
+
* `server/api/assets` route — in that case `/api/assets/*` proxies to the
|
|
37
|
+
* backend so the custom route runs, matching production where a custom route
|
|
38
|
+
* supersedes the built-in one.
|
|
39
|
+
*/
|
|
40
|
+
export declare function registerAssetMiddleware(server: ViteDevServer, projectRoot: string, configPath?: string): Promise<void>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@playcademy/vite-plugin",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0-beta.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -19,14 +19,14 @@
|
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"archiver": "^7.0.1",
|
|
21
21
|
"picocolors": "^1.1.1",
|
|
22
|
-
"playcademy": "0.
|
|
22
|
+
"playcademy": "0.25.0"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@electric-sql/pglite": "^0.3.16",
|
|
26
26
|
"@inquirer/prompts": "^7.8.6",
|
|
27
27
|
"@playcademy/constants": "0.0.1",
|
|
28
|
-
"@playcademy/sandbox": "0.5.
|
|
29
|
-
"@playcademy/sdk": "0.
|
|
28
|
+
"@playcademy/sandbox": "0.5.1",
|
|
29
|
+
"@playcademy/sdk": "0.13.0",
|
|
30
30
|
"@playcademy/types": "0.0.1",
|
|
31
31
|
"@playcademy/utils": "0.0.1",
|
|
32
32
|
"@types/archiver": "^6.0.3",
|