playcademy 0.12.2 → 0.12.4
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/edge-play/src/routes/root.html +96 -0
- package/dist/index.d.ts +65 -1
- package/dist/index.js +77 -39
- package/dist/utils.js +76 -38
- package/package.json +1 -1
- /package/dist/{vendor/constants → constants/src}/auth.ts +0 -0
- /package/dist/{vendor/constants → constants/src}/domains.ts +0 -0
- /package/dist/{vendor/constants → constants/src}/env-vars.ts +0 -0
- /package/dist/{vendor/constants → constants/src}/index.ts +0 -0
- /package/dist/{vendor/constants → constants/src}/overworld.ts +0 -0
- /package/dist/{vendor/constants → constants/src}/system.ts +0 -0
- /package/dist/{vendor/constants → constants/src}/timeback.ts +0 -0
- /package/dist/{vendor/constants → constants/src}/workers.ts +0 -0
|
@@ -47,6 +47,9 @@
|
|
|
47
47
|
</svg>
|
|
48
48
|
</button>
|
|
49
49
|
|
|
50
|
+
<!-- Pixel trail container -->
|
|
51
|
+
<div id="pixelTrail" class="absolute inset-0 z-0"></div>
|
|
52
|
+
|
|
50
53
|
<!-- Subtle background enhancements: vignette + grid (theme-aware) -->
|
|
51
54
|
<div class="pointer-events-none absolute inset-0 z-0">
|
|
52
55
|
<!-- Light mode vignette (white on black) -->
|
|
@@ -165,5 +168,98 @@
|
|
|
165
168
|
localStorage.setItem('theme', willBeDark ? 'dark' : 'light')
|
|
166
169
|
})
|
|
167
170
|
</script>
|
|
171
|
+
|
|
172
|
+
<script>
|
|
173
|
+
// Pixel Trail Effect
|
|
174
|
+
const pixelTrail = document.getElementById('pixelTrail')
|
|
175
|
+
const PIXEL_SIZE = 20 // px
|
|
176
|
+
const FADE_DURATION = 500 // ms
|
|
177
|
+
|
|
178
|
+
let pixelGrid = {}
|
|
179
|
+
let columns = 0
|
|
180
|
+
let rows = 0
|
|
181
|
+
|
|
182
|
+
function initPixelGrid() {
|
|
183
|
+
const width = window.innerWidth
|
|
184
|
+
const height = window.innerHeight
|
|
185
|
+
columns = Math.ceil(width / PIXEL_SIZE)
|
|
186
|
+
rows = Math.ceil(height / PIXEL_SIZE)
|
|
187
|
+
|
|
188
|
+
// Clear existing grid
|
|
189
|
+
pixelTrail.innerHTML = ''
|
|
190
|
+
pixelGrid = {}
|
|
191
|
+
|
|
192
|
+
// Create pixel grid
|
|
193
|
+
for (let row = 0; row < rows; row++) {
|
|
194
|
+
for (let col = 0; col < columns; col++) {
|
|
195
|
+
const pixel = document.createElement('div')
|
|
196
|
+
pixel.className = 'absolute pointer-events-none transition-opacity'
|
|
197
|
+
pixel.style.width = `${PIXEL_SIZE}px`
|
|
198
|
+
pixel.style.height = `${PIXEL_SIZE}px`
|
|
199
|
+
pixel.style.left = `${col * PIXEL_SIZE}px`
|
|
200
|
+
pixel.style.top = `${row * PIXEL_SIZE}px`
|
|
201
|
+
pixel.style.opacity = '0'
|
|
202
|
+
pixel.style.transitionDuration = `${FADE_DURATION}ms`
|
|
203
|
+
|
|
204
|
+
// Add a subtle background color based on theme
|
|
205
|
+
const isDark = html.classList.contains('dark')
|
|
206
|
+
pixel.style.backgroundColor = isDark
|
|
207
|
+
? 'rgba(0, 0, 0, 0.4)'
|
|
208
|
+
: 'rgba(255, 255, 255, 0.4)'
|
|
209
|
+
|
|
210
|
+
pixelTrail.appendChild(pixel)
|
|
211
|
+
pixelGrid[`${col}-${row}`] = pixel
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function animatePixel(col, row) {
|
|
217
|
+
const key = `${col}-${row}`
|
|
218
|
+
const pixel = pixelGrid[key]
|
|
219
|
+
if (!pixel) return
|
|
220
|
+
|
|
221
|
+
// Cancel any ongoing animation
|
|
222
|
+
clearTimeout(pixel.fadeTimeout)
|
|
223
|
+
|
|
224
|
+
// Show pixel
|
|
225
|
+
pixel.style.opacity = '1'
|
|
226
|
+
|
|
227
|
+
// Fade out after duration
|
|
228
|
+
pixel.fadeTimeout = setTimeout(() => {
|
|
229
|
+
pixel.style.opacity = '0'
|
|
230
|
+
}, FADE_DURATION)
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function handleMouseMove(e) {
|
|
234
|
+
const col = Math.floor(e.clientX / PIXEL_SIZE)
|
|
235
|
+
const row = Math.floor(e.clientY / PIXEL_SIZE)
|
|
236
|
+
animatePixel(col, row)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Initialize on load
|
|
240
|
+
initPixelGrid()
|
|
241
|
+
|
|
242
|
+
// Add event listeners
|
|
243
|
+
document.body.addEventListener('mousemove', handleMouseMove)
|
|
244
|
+
|
|
245
|
+
// Reinitialize on window resize
|
|
246
|
+
let resizeTimeout
|
|
247
|
+
window.addEventListener('resize', () => {
|
|
248
|
+
clearTimeout(resizeTimeout)
|
|
249
|
+
resizeTimeout = setTimeout(initPixelGrid, 200)
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
// Update pixel colors when theme changes
|
|
253
|
+
const originalSetTheme = setTheme
|
|
254
|
+
setTheme = function (isDark) {
|
|
255
|
+
originalSetTheme(isDark)
|
|
256
|
+
// Update all pixel colors
|
|
257
|
+
Object.values(pixelGrid).forEach(pixel => {
|
|
258
|
+
pixel.style.backgroundColor = isDark
|
|
259
|
+
? 'rgba(0, 0, 0, 0.4)'
|
|
260
|
+
: 'rgba(255, 255, 255, 0.4)'
|
|
261
|
+
})
|
|
262
|
+
}
|
|
263
|
+
</script>
|
|
168
264
|
</body>
|
|
169
265
|
</html>
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { UserInfo, ApiKey, BackendDeploymentResponse } from '@playcademy/data/types';
|
|
2
|
+
import { SchemaInfo } from '@playcademy/cloudflare';
|
|
2
3
|
import { OrganizationConfig, CourseConfig, ComponentConfig, ResourceConfig, ComponentResourceConfig } from '@playcademy/timeback/types';
|
|
3
4
|
export { ComponentConfig, ComponentResourceConfig, CourseConfig, DerivedComponentConfig, DerivedComponentResourceConfig, DerivedCourseConfig, DerivedOrganizationConfig, DerivedResourceConfig, DerivedTimebackConfig, OrganizationConfig, ResourceConfig, TimebackGrade, TimebackSourcedIds, TimebackSubject } from '@playcademy/timeback/types';
|
|
4
5
|
import { PlaycademyClient } from '@playcademy/sdk';
|
|
@@ -222,6 +223,32 @@ interface PlaycademyConfig {
|
|
|
222
223
|
integrations?: IntegrationsConfig;
|
|
223
224
|
}
|
|
224
225
|
|
|
226
|
+
/**
|
|
227
|
+
* Resource bindings for backend deployment
|
|
228
|
+
* Provider-agnostic abstraction for cloud resources
|
|
229
|
+
*/
|
|
230
|
+
interface BackendResourceBindings {
|
|
231
|
+
/** SQL database instances to create and bind (maps to D1 on Cloudflare) */
|
|
232
|
+
database?: string[];
|
|
233
|
+
/** Key-value store namespaces to create and bind (maps to KV on Cloudflare) */
|
|
234
|
+
keyValue?: string[];
|
|
235
|
+
/** Object storage buckets to bind (maps to R2 on Cloudflare) */
|
|
236
|
+
bucket?: string[];
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Backend deployment bundle for uploading to Playcademy platform
|
|
240
|
+
*/
|
|
241
|
+
interface BackendDeploymentBundle {
|
|
242
|
+
/** Bundled JavaScript code ready for deployment */
|
|
243
|
+
code: string;
|
|
244
|
+
/** Game configuration */
|
|
245
|
+
config: PlaycademyConfig;
|
|
246
|
+
/** Optional resource bindings (database, storage, etc.) */
|
|
247
|
+
bindings?: BackendResourceBindings;
|
|
248
|
+
/** Optional schema information for database setup */
|
|
249
|
+
schema?: SchemaInfo;
|
|
250
|
+
}
|
|
251
|
+
|
|
225
252
|
type GameMetadata = {
|
|
226
253
|
description?: string;
|
|
227
254
|
emoji?: string;
|
|
@@ -620,6 +647,43 @@ interface UpdateExistingGameOptions {
|
|
|
620
647
|
previousBackendSize?: number;
|
|
621
648
|
verbose?: boolean;
|
|
622
649
|
}
|
|
650
|
+
/**
|
|
651
|
+
* Backend bundle with CLI-specific metadata
|
|
652
|
+
* Extends SDK's BackendDeploymentBundle with route discovery metadata
|
|
653
|
+
*/
|
|
654
|
+
interface BackendBundle extends BackendDeploymentBundle {
|
|
655
|
+
/** Discovered custom routes (for CLI display and tracking) */
|
|
656
|
+
customRoutes: Array<{
|
|
657
|
+
path: string;
|
|
658
|
+
file: string;
|
|
659
|
+
methods?: string[];
|
|
660
|
+
}>;
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Bundle configuration options
|
|
664
|
+
*/
|
|
665
|
+
interface BundleOptions {
|
|
666
|
+
/** Include source map for debugging (default: false) */
|
|
667
|
+
sourcemap?: boolean;
|
|
668
|
+
/** Minify output (default: false) */
|
|
669
|
+
minify?: boolean;
|
|
670
|
+
}
|
|
671
|
+
/**
|
|
672
|
+
* Resolved paths for bundling embedded sources
|
|
673
|
+
* Used to support both monorepo development and published package scenarios
|
|
674
|
+
*/
|
|
675
|
+
interface EmbeddedSourcePaths {
|
|
676
|
+
/** Whether we're running from a published package (vs monorepo dev) */
|
|
677
|
+
isBuiltPackage: boolean;
|
|
678
|
+
/** Path to edge-play sources (embedded or monorepo) */
|
|
679
|
+
edgePlaySrc: string;
|
|
680
|
+
/** Path to constants entry point (embedded or monorepo) */
|
|
681
|
+
constantsEntry: string;
|
|
682
|
+
/** User's workspace node_modules */
|
|
683
|
+
workspaceNodeModules: string;
|
|
684
|
+
/** CLI's node_modules (monorepo root in dev, same as workspace in published) */
|
|
685
|
+
cliNodeModules: string;
|
|
686
|
+
}
|
|
623
687
|
|
|
624
688
|
/**
|
|
625
689
|
* Types for the CLI local HTTP server that handles OAuth callbacks
|
|
@@ -801,4 +865,4 @@ interface DeploymentDiffOptions {
|
|
|
801
865
|
integrations?: IntegrationsDiff;
|
|
802
866
|
}
|
|
803
867
|
|
|
804
|
-
export type { ApiConfig, ApiErrorResponse, ApiKeyListItem, ApiKeyWithSecret, ApiRequestOptions, AuthProfile, AuthStore, BackendDeploymentWithHash, BackendDiff, BuildDiff, CallbackServerResult, ConfigDiff, CreateApiKeyResponse, CustomRoutesIntegrationOptions, DatabaseIntegrationOptions, DeployConfig, DeployNewGameOptions, DeployedGameInfo, DeploymentChanges, DeploymentContext, DeploymentDiffOptions, DeploymentPlan, DeploymentResult, EnvironmentAuthProfiles, GameStore, IntegrationChangeDetector, IntegrationChangeDetectors, IntegrationConfigChange, IntegrationsConfig, IntegrationsDiff, LoginCredentials, LoginResponse, PlaycademyConfig, PreviewOptions, PreviewResponse, SignInResponse, SsoCallbackData, TimebackIntegrationConfig, TokenType, UpdateExistingGameOptions };
|
|
868
|
+
export type { ApiConfig, ApiErrorResponse, ApiKeyListItem, ApiKeyWithSecret, ApiRequestOptions, AuthProfile, AuthStore, BackendBundle, BackendDeploymentWithHash, BackendDiff, BuildDiff, BundleOptions, CallbackServerResult, ConfigDiff, CreateApiKeyResponse, CustomRoutesIntegrationOptions, DatabaseIntegrationOptions, DeployConfig, DeployNewGameOptions, DeployedGameInfo, DeploymentChanges, DeploymentContext, DeploymentDiffOptions, DeploymentPlan, DeploymentResult, EmbeddedSourcePaths, EnvironmentAuthProfiles, GameStore, IntegrationChangeDetector, IntegrationChangeDetectors, IntegrationConfigChange, IntegrationsConfig, IntegrationsDiff, LoginCredentials, LoginResponse, PlaycademyConfig, PreviewOptions, PreviewResponse, SignInResponse, SsoCallbackData, TimebackIntegrationConfig, TokenType, UpdateExistingGameOptions };
|
package/dist/index.js
CHANGED
|
@@ -5222,9 +5222,8 @@ async function registerCustomRoutes(app, routes) {
|
|
|
5222
5222
|
}
|
|
5223
5223
|
|
|
5224
5224
|
// src/lib/deploy/bundle.ts
|
|
5225
|
-
var entryTemplate = entry_default;
|
|
5226
|
-
async function
|
|
5227
|
-
const esbuild = await import("esbuild");
|
|
5225
|
+
var entryTemplate = entry_default.toString();
|
|
5226
|
+
async function discoverCustomRoutes(config) {
|
|
5228
5227
|
const workspace = getWorkspace();
|
|
5229
5228
|
const customRoutesConfig = config.integrations?.customRoutes;
|
|
5230
5229
|
const customRoutesDir = typeof customRoutesConfig === "object" && customRoutesConfig.directory || DEFAULT_API_ROUTES_DIRECTORY;
|
|
@@ -5235,76 +5234,115 @@ async function bundleBackend(config, options = {}) {
|
|
|
5235
5234
|
// Use relative path (e.g., 'server/api/test.ts'), not absolute
|
|
5236
5235
|
methods: r.methods
|
|
5237
5236
|
}));
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
const entryCode = generateEntryCode(customRouteData, customRoutesDir);
|
|
5237
|
+
return { customRouteData, customRoutesDir };
|
|
5238
|
+
}
|
|
5239
|
+
function resolveEmbeddedSourcePaths() {
|
|
5240
|
+
const workspace = getWorkspace();
|
|
5243
5241
|
const distDir = new URL(".", import.meta.url).pathname;
|
|
5244
5242
|
const embeddedEdgeSrc = join6(distDir, "edge-play", "src");
|
|
5243
|
+
const isBuiltPackage = existsSync7(embeddedEdgeSrc);
|
|
5245
5244
|
const monorepoRoot = getMonorepoRoot();
|
|
5246
5245
|
const monorepoEdgeSrc = join6(monorepoRoot, "packages/edge-play/src");
|
|
5247
|
-
const isBuiltPackage = existsSync7(embeddedEdgeSrc);
|
|
5248
5246
|
const edgePlaySrc = isBuiltPackage ? embeddedEdgeSrc : monorepoEdgeSrc;
|
|
5249
5247
|
const cliPackageRoot = isBuiltPackage ? join6(distDir, "../../..") : join6(monorepoRoot, "packages/cli");
|
|
5250
5248
|
const cliNodeModules = isBuiltPackage ? join6(cliPackageRoot, "node_modules") : monorepoRoot;
|
|
5251
5249
|
const workspaceNodeModules = join6(workspace, "node_modules");
|
|
5252
|
-
const constantsEntry = isBuiltPackage ? join6(
|
|
5253
|
-
|
|
5250
|
+
const constantsEntry = isBuiltPackage ? join6(embeddedEdgeSrc, "..", "..", "constants", "src", "index.ts") : join6(monorepoRoot, "packages", "constants", "src", "index.ts");
|
|
5251
|
+
return {
|
|
5252
|
+
isBuiltPackage,
|
|
5253
|
+
edgePlaySrc,
|
|
5254
|
+
constantsEntry,
|
|
5255
|
+
workspaceNodeModules,
|
|
5256
|
+
cliNodeModules
|
|
5257
|
+
};
|
|
5258
|
+
}
|
|
5259
|
+
function createEsbuildConfig(entryCode, paths, bundleConfig, customRoutesDir, options) {
|
|
5260
|
+
const workspace = getWorkspace();
|
|
5261
|
+
const { isBuiltPackage, edgePlaySrc, constantsEntry, workspaceNodeModules, cliNodeModules } = paths;
|
|
5262
|
+
return {
|
|
5263
|
+
// ──── Input Configuration ────
|
|
5254
5264
|
stdin: {
|
|
5255
5265
|
contents: entryCode,
|
|
5266
|
+
// Generated entry code with custom route imports
|
|
5256
5267
|
resolveDir: edgePlaySrc,
|
|
5257
|
-
//
|
|
5268
|
+
// Resolve relative imports from edge-play/src
|
|
5258
5269
|
loader: "ts"
|
|
5270
|
+
// Treat input as TypeScript
|
|
5259
5271
|
},
|
|
5272
|
+
// ──── Output Configuration ────
|
|
5260
5273
|
bundle: true,
|
|
5274
|
+
// Bundle all dependencies into single file
|
|
5261
5275
|
format: "esm",
|
|
5276
|
+
// Output ES modules (required for Cloudflare Workers)
|
|
5262
5277
|
platform: "browser",
|
|
5278
|
+
// Workers use browser APIs, not Node.js
|
|
5263
5279
|
target: "es2022",
|
|
5280
|
+
// Modern JavaScript for Workers runtime
|
|
5264
5281
|
write: false,
|
|
5282
|
+
// Return code as string (don't write to disk)
|
|
5265
5283
|
sourcemap: options.sourcemap ? "inline" : false,
|
|
5266
5284
|
minify: options.minify || false,
|
|
5267
5285
|
logLevel: "error",
|
|
5268
|
-
|
|
5269
|
-
//
|
|
5270
|
-
|
|
5271
|
-
|
|
5272
|
-
|
|
5286
|
+
// Only show errors (suppress warnings)
|
|
5287
|
+
// ──── Module Resolution ────
|
|
5288
|
+
// Tell esbuild where to find node_modules for bare imports
|
|
5289
|
+
// In dev: Need both workspace and monorepo root (hoisted deps)
|
|
5290
|
+
// In published: Both point to same location (/user-project/node_modules)
|
|
5291
|
+
nodePaths: isBuiltPackage ? [workspaceNodeModules] : [workspaceNodeModules, cliNodeModules],
|
|
5292
|
+
// ──── Build-time Constants ────
|
|
5293
|
+
// Inject the Playcademy config as a global constant
|
|
5294
|
+
// Code can access it via: const config = PLAYCADEMY_CONFIG
|
|
5273
5295
|
define: {
|
|
5274
5296
|
PLAYCADEMY_CONFIG: JSON.stringify(bundleConfig)
|
|
5275
5297
|
},
|
|
5298
|
+
// ──── Import Aliases ────
|
|
5276
5299
|
alias: {
|
|
5277
|
-
//
|
|
5300
|
+
// ┌─ Workspace-only package resolution ─────────────────────────────┐
|
|
5301
|
+
// │ @playcademy/constants is a workspace package that users don't │
|
|
5302
|
+
// │ install. We embed it in dist/ and alias imports to point there. │
|
|
5303
|
+
// └─────────────────────────────────────────────────────────────────┘
|
|
5278
5304
|
"@playcademy/constants": constantsEntry,
|
|
5279
|
-
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
*
|
|
5285
|
-
* The alias resolves to the absolute path of the custom routes directory in the
|
|
5286
|
-
* user's game project (configured via integrations.customRoutes.directory), enabling esbuild
|
|
5287
|
-
* to bundle custom routes into the worker.
|
|
5288
|
-
*/
|
|
5305
|
+
// ┌─ User's custom routes ──────────────────────────────────────────┐
|
|
5306
|
+
// │ @game-api is a virtual module that maps to the user's API dir. │
|
|
5307
|
+
// │ Example: import * as route from '@game-api/hello.ts' │
|
|
5308
|
+
// │ Resolves to: /user-project/server/api/hello.ts │
|
|
5309
|
+
// └─────────────────────────────────────────────────────────────────┘
|
|
5289
5310
|
"@game-api": join6(workspace, customRoutesDir),
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
|
|
5294
|
-
* These aliases redirect Node.js imports to a polyfill that throws helpful errors.
|
|
5295
|
-
*
|
|
5296
|
-
* This prevents bundling errors and provides clear runtime messages if
|
|
5297
|
-
* user code accidentally imports Node.js modules that won't work in Workers.
|
|
5298
|
-
*/
|
|
5311
|
+
// ┌─ Node.js polyfills for Cloudflare Workers ──────────────────────┐
|
|
5312
|
+
// │ Workers don't have fs, path, os, etc. Redirect to polyfills │
|
|
5313
|
+
// │ that throw helpful errors if user code tries to use them. │
|
|
5314
|
+
// └─────────────────────────────────────────────────────────────────┘
|
|
5299
5315
|
fs: join6(edgePlaySrc, "polyfills.js"),
|
|
5300
5316
|
"fs/promises": join6(edgePlaySrc, "polyfills.js"),
|
|
5301
5317
|
path: join6(edgePlaySrc, "polyfills.js"),
|
|
5302
5318
|
os: join6(edgePlaySrc, "polyfills.js"),
|
|
5303
5319
|
process: join6(edgePlaySrc, "polyfills.js")
|
|
5304
5320
|
},
|
|
5321
|
+
// ──── Build Plugins ────
|
|
5305
5322
|
plugins: [textLoaderPlugin()],
|
|
5323
|
+
// Support Bun's 'with { type: "text" }' imports
|
|
5324
|
+
// ──── External Dependencies ────
|
|
5306
5325
|
external: []
|
|
5307
|
-
|
|
5326
|
+
// Bundle everything (no externals for Workers)
|
|
5327
|
+
};
|
|
5328
|
+
}
|
|
5329
|
+
async function bundleBackend(config, options = {}) {
|
|
5330
|
+
const esbuild = await import("esbuild");
|
|
5331
|
+
const { customRouteData, customRoutesDir } = await discoverCustomRoutes(config);
|
|
5332
|
+
const bundleConfig = {
|
|
5333
|
+
...config,
|
|
5334
|
+
customRoutes: customRouteData
|
|
5335
|
+
};
|
|
5336
|
+
const entryCode = generateEntryCode(customRouteData, customRoutesDir);
|
|
5337
|
+
const paths = resolveEmbeddedSourcePaths();
|
|
5338
|
+
const buildConfig = createEsbuildConfig(
|
|
5339
|
+
entryCode,
|
|
5340
|
+
paths,
|
|
5341
|
+
bundleConfig,
|
|
5342
|
+
customRoutesDir,
|
|
5343
|
+
options
|
|
5344
|
+
);
|
|
5345
|
+
const result = await esbuild.build(buildConfig);
|
|
5308
5346
|
if (!result.outputFiles?.[0]) {
|
|
5309
5347
|
throw new Error("Backend bundling failed: no output");
|
|
5310
5348
|
}
|
|
@@ -5344,6 +5382,7 @@ function generateEntryCode(customRoutes, customRoutesDir) {
|
|
|
5344
5382
|
init_core();
|
|
5345
5383
|
import { existsSync as existsSync9 } from "fs";
|
|
5346
5384
|
import { join as join8 } from "path";
|
|
5385
|
+
import { generateSQLiteDrizzleJson, generateSQLiteMigration } from "drizzle-kit/api";
|
|
5347
5386
|
|
|
5348
5387
|
// src/lib/init/prompts.ts
|
|
5349
5388
|
init_constants3();
|
|
@@ -5603,7 +5642,6 @@ async function getSchemaInfo(previousSchemaSnapshot) {
|
|
|
5603
5642
|
return null;
|
|
5604
5643
|
}
|
|
5605
5644
|
try {
|
|
5606
|
-
const { generateSQLiteDrizzleJson, generateSQLiteMigration } = await import("drizzle-kit/api");
|
|
5607
5645
|
const schemaModule = await import(schemaPath);
|
|
5608
5646
|
const currentSchema = schemaModule.default || schemaModule;
|
|
5609
5647
|
const nextJson = await generateSQLiteDrizzleJson(currentSchema);
|
package/dist/utils.js
CHANGED
|
@@ -1162,9 +1162,8 @@ async function transpileRoute(filePath) {
|
|
|
1162
1162
|
}
|
|
1163
1163
|
|
|
1164
1164
|
// src/lib/deploy/bundle.ts
|
|
1165
|
-
var entryTemplate = entry_default;
|
|
1166
|
-
async function
|
|
1167
|
-
const esbuild = await import("esbuild");
|
|
1165
|
+
var entryTemplate = entry_default.toString();
|
|
1166
|
+
async function discoverCustomRoutes(config) {
|
|
1168
1167
|
const workspace = getWorkspace();
|
|
1169
1168
|
const customRoutesConfig = config.integrations?.customRoutes;
|
|
1170
1169
|
const customRoutesDir = typeof customRoutesConfig === "object" && customRoutesConfig.directory || DEFAULT_API_ROUTES_DIRECTORY;
|
|
@@ -1175,76 +1174,115 @@ async function bundleBackend(config, options = {}) {
|
|
|
1175
1174
|
// Use relative path (e.g., 'server/api/test.ts'), not absolute
|
|
1176
1175
|
methods: r.methods
|
|
1177
1176
|
}));
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
const entryCode = generateEntryCode(customRouteData, customRoutesDir);
|
|
1177
|
+
return { customRouteData, customRoutesDir };
|
|
1178
|
+
}
|
|
1179
|
+
function resolveEmbeddedSourcePaths() {
|
|
1180
|
+
const workspace = getWorkspace();
|
|
1183
1181
|
const distDir = new URL(".", import.meta.url).pathname;
|
|
1184
1182
|
const embeddedEdgeSrc = join2(distDir, "edge-play", "src");
|
|
1183
|
+
const isBuiltPackage = existsSync2(embeddedEdgeSrc);
|
|
1185
1184
|
const monorepoRoot = getMonorepoRoot();
|
|
1186
1185
|
const monorepoEdgeSrc = join2(monorepoRoot, "packages/edge-play/src");
|
|
1187
|
-
const isBuiltPackage = existsSync2(embeddedEdgeSrc);
|
|
1188
1186
|
const edgePlaySrc = isBuiltPackage ? embeddedEdgeSrc : monorepoEdgeSrc;
|
|
1189
1187
|
const cliPackageRoot = isBuiltPackage ? join2(distDir, "../../..") : join2(monorepoRoot, "packages/cli");
|
|
1190
1188
|
const cliNodeModules = isBuiltPackage ? join2(cliPackageRoot, "node_modules") : monorepoRoot;
|
|
1191
1189
|
const workspaceNodeModules = join2(workspace, "node_modules");
|
|
1192
|
-
const constantsEntry = isBuiltPackage ? join2(
|
|
1193
|
-
|
|
1190
|
+
const constantsEntry = isBuiltPackage ? join2(embeddedEdgeSrc, "..", "..", "constants", "src", "index.ts") : join2(monorepoRoot, "packages", "constants", "src", "index.ts");
|
|
1191
|
+
return {
|
|
1192
|
+
isBuiltPackage,
|
|
1193
|
+
edgePlaySrc,
|
|
1194
|
+
constantsEntry,
|
|
1195
|
+
workspaceNodeModules,
|
|
1196
|
+
cliNodeModules
|
|
1197
|
+
};
|
|
1198
|
+
}
|
|
1199
|
+
function createEsbuildConfig(entryCode, paths, bundleConfig, customRoutesDir, options) {
|
|
1200
|
+
const workspace = getWorkspace();
|
|
1201
|
+
const { isBuiltPackage, edgePlaySrc, constantsEntry, workspaceNodeModules, cliNodeModules } = paths;
|
|
1202
|
+
return {
|
|
1203
|
+
// ──── Input Configuration ────
|
|
1194
1204
|
stdin: {
|
|
1195
1205
|
contents: entryCode,
|
|
1206
|
+
// Generated entry code with custom route imports
|
|
1196
1207
|
resolveDir: edgePlaySrc,
|
|
1197
|
-
//
|
|
1208
|
+
// Resolve relative imports from edge-play/src
|
|
1198
1209
|
loader: "ts"
|
|
1210
|
+
// Treat input as TypeScript
|
|
1199
1211
|
},
|
|
1212
|
+
// ──── Output Configuration ────
|
|
1200
1213
|
bundle: true,
|
|
1214
|
+
// Bundle all dependencies into single file
|
|
1201
1215
|
format: "esm",
|
|
1216
|
+
// Output ES modules (required for Cloudflare Workers)
|
|
1202
1217
|
platform: "browser",
|
|
1218
|
+
// Workers use browser APIs, not Node.js
|
|
1203
1219
|
target: "es2022",
|
|
1220
|
+
// Modern JavaScript for Workers runtime
|
|
1204
1221
|
write: false,
|
|
1222
|
+
// Return code as string (don't write to disk)
|
|
1205
1223
|
sourcemap: options.sourcemap ? "inline" : false,
|
|
1206
1224
|
minify: options.minify || false,
|
|
1207
1225
|
logLevel: "error",
|
|
1208
|
-
|
|
1209
|
-
//
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1226
|
+
// Only show errors (suppress warnings)
|
|
1227
|
+
// ──── Module Resolution ────
|
|
1228
|
+
// Tell esbuild where to find node_modules for bare imports
|
|
1229
|
+
// In dev: Need both workspace and monorepo root (hoisted deps)
|
|
1230
|
+
// In published: Both point to same location (/user-project/node_modules)
|
|
1231
|
+
nodePaths: isBuiltPackage ? [workspaceNodeModules] : [workspaceNodeModules, cliNodeModules],
|
|
1232
|
+
// ──── Build-time Constants ────
|
|
1233
|
+
// Inject the Playcademy config as a global constant
|
|
1234
|
+
// Code can access it via: const config = PLAYCADEMY_CONFIG
|
|
1213
1235
|
define: {
|
|
1214
1236
|
PLAYCADEMY_CONFIG: JSON.stringify(bundleConfig)
|
|
1215
1237
|
},
|
|
1238
|
+
// ──── Import Aliases ────
|
|
1216
1239
|
alias: {
|
|
1217
|
-
//
|
|
1240
|
+
// ┌─ Workspace-only package resolution ─────────────────────────────┐
|
|
1241
|
+
// │ @playcademy/constants is a workspace package that users don't │
|
|
1242
|
+
// │ install. We embed it in dist/ and alias imports to point there. │
|
|
1243
|
+
// └─────────────────────────────────────────────────────────────────┘
|
|
1218
1244
|
"@playcademy/constants": constantsEntry,
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
*
|
|
1225
|
-
* The alias resolves to the absolute path of the custom routes directory in the
|
|
1226
|
-
* user's game project (configured via integrations.customRoutes.directory), enabling esbuild
|
|
1227
|
-
* to bundle custom routes into the worker.
|
|
1228
|
-
*/
|
|
1245
|
+
// ┌─ User's custom routes ──────────────────────────────────────────┐
|
|
1246
|
+
// │ @game-api is a virtual module that maps to the user's API dir. │
|
|
1247
|
+
// │ Example: import * as route from '@game-api/hello.ts' │
|
|
1248
|
+
// │ Resolves to: /user-project/server/api/hello.ts │
|
|
1249
|
+
// └─────────────────────────────────────────────────────────────────┘
|
|
1229
1250
|
"@game-api": join2(workspace, customRoutesDir),
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
* These aliases redirect Node.js imports to a polyfill that throws helpful errors.
|
|
1235
|
-
*
|
|
1236
|
-
* This prevents bundling errors and provides clear runtime messages if
|
|
1237
|
-
* user code accidentally imports Node.js modules that won't work in Workers.
|
|
1238
|
-
*/
|
|
1251
|
+
// ┌─ Node.js polyfills for Cloudflare Workers ──────────────────────┐
|
|
1252
|
+
// │ Workers don't have fs, path, os, etc. Redirect to polyfills │
|
|
1253
|
+
// │ that throw helpful errors if user code tries to use them. │
|
|
1254
|
+
// └─────────────────────────────────────────────────────────────────┘
|
|
1239
1255
|
fs: join2(edgePlaySrc, "polyfills.js"),
|
|
1240
1256
|
"fs/promises": join2(edgePlaySrc, "polyfills.js"),
|
|
1241
1257
|
path: join2(edgePlaySrc, "polyfills.js"),
|
|
1242
1258
|
os: join2(edgePlaySrc, "polyfills.js"),
|
|
1243
1259
|
process: join2(edgePlaySrc, "polyfills.js")
|
|
1244
1260
|
},
|
|
1261
|
+
// ──── Build Plugins ────
|
|
1245
1262
|
plugins: [textLoaderPlugin()],
|
|
1263
|
+
// Support Bun's 'with { type: "text" }' imports
|
|
1264
|
+
// ──── External Dependencies ────
|
|
1246
1265
|
external: []
|
|
1247
|
-
|
|
1266
|
+
// Bundle everything (no externals for Workers)
|
|
1267
|
+
};
|
|
1268
|
+
}
|
|
1269
|
+
async function bundleBackend(config, options = {}) {
|
|
1270
|
+
const esbuild = await import("esbuild");
|
|
1271
|
+
const { customRouteData, customRoutesDir } = await discoverCustomRoutes(config);
|
|
1272
|
+
const bundleConfig = {
|
|
1273
|
+
...config,
|
|
1274
|
+
customRoutes: customRouteData
|
|
1275
|
+
};
|
|
1276
|
+
const entryCode = generateEntryCode(customRouteData, customRoutesDir);
|
|
1277
|
+
const paths = resolveEmbeddedSourcePaths();
|
|
1278
|
+
const buildConfig = createEsbuildConfig(
|
|
1279
|
+
entryCode,
|
|
1280
|
+
paths,
|
|
1281
|
+
bundleConfig,
|
|
1282
|
+
customRoutesDir,
|
|
1283
|
+
options
|
|
1284
|
+
);
|
|
1285
|
+
const result = await esbuild.build(buildConfig);
|
|
1248
1286
|
if (!result.outputFiles?.[0]) {
|
|
1249
1287
|
throw new Error("Backend bundling failed: no output");
|
|
1250
1288
|
}
|
package/package.json
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|