playcademy 0.14.11 → 0.14.12-alpha.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.
@@ -155,6 +155,59 @@ declare const SCHEMA_INDEX_FILE = "index.ts";
155
155
  */
156
156
  declare const DEFAULT_SEED_FILE_NAME = "seed.ts";
157
157
 
158
+ /**
159
+ * Godot engine integration constants
160
+ *
161
+ * Constants for detecting Godot projects and running headless exports
162
+ */
163
+ /**
164
+ * Godot project file (presence indicates Godot project)
165
+ */
166
+ declare const GODOT_PROJECT_FILE = "project.godot";
167
+ /**
168
+ * Godot export presets configuration file
169
+ */
170
+ declare const GODOT_EXPORT_PRESETS_FILE = "export_presets.cfg";
171
+ /**
172
+ * Web platform identifier in export_presets.cfg
173
+ */
174
+ declare const GODOT_WEB_PLATFORM = "platform=\"Web\"";
175
+ /**
176
+ * Build output directories
177
+ */
178
+ declare const GODOT_BUILD_DIRECTORIES: {
179
+ /** Root build directory (cleared before each export) */
180
+ readonly ROOT: "build";
181
+ /** Web export subdirectory */
182
+ readonly WEB: "build/web";
183
+ };
184
+ /**
185
+ * Build output file paths
186
+ */
187
+ declare const GODOT_BUILD_OUTPUTS: {
188
+ /** Exported web build entry point */
189
+ readonly INDEX_HTML: "build/web/index.html";
190
+ /** Packaged zip file (created by Godot export) */
191
+ readonly ZIP: "build/web_playcademy.zip";
192
+ };
193
+ /**
194
+ * Platform-specific Godot executable discovery patterns
195
+ */
196
+ declare const GODOT_EXECUTABLE_PATTERNS: {
197
+ /** macOS app bundle suffix */
198
+ readonly MACOS_APP_SUFFIX: ".app/";
199
+ /** macOS executable path within .app bundle */
200
+ readonly MACOS_APP_EXECUTABLE: "Contents/MacOS/Godot";
201
+ /** Flatpak application ID */
202
+ readonly FLATPAK_ID: "org.godotengine.Godot";
203
+ /** Flatpak run command */
204
+ readonly FLATPAK_COMMAND: "flatpak run org.godotengine.Godot";
205
+ /** Snap package name */
206
+ readonly SNAP_NAME: "godot";
207
+ /** Snap run command */
208
+ readonly SNAP_COMMAND: "snap run godot";
209
+ };
210
+
158
211
  /**
159
212
  * HTTP server constants for CLI OAuth callback handling
160
213
  */
@@ -223,4 +276,4 @@ declare const DEFAULT_PORTS: {
223
276
  */
224
277
  declare const CONFIG_FILE_NAMES: string[];
225
278
 
226
- export { AUTH_API_SUBDIRECTORY, AUTH_CONFIG_FILE, AUTH_PROVIDER_NAMES, BETTER_AUTH_VERSION, BUCKET_ALWAYS_SKIP, CALLBACK_PATH, CALLBACK_PORT, CLI_DEFAULT_OUTPUTS, CLI_DIRECTORIES, CLI_FILES, CLI_USER_DIRECTORIES, CLOUDFLARE_BINDINGS, CLOUDFLARE_COMPATIBILITY_DATE, CONFIG_FILE_NAMES, DEFAULT_API_ROUTES_DIRECTORY, DEFAULT_DATABASE_DIRECTORY, DEFAULT_PORTS, DEFAULT_SEED_FILE_NAME, ENV_EXAMPLE_FILE, ENV_FILES, MINIFLARE_D1_DIRECTORY, OAUTH_CALLBACK_URL_PATTERN, PLACEHOLDER_GAME_URL, PLAYCADEMY_AUTH_VERSION, SAMPLE_API_SUBDIRECTORY, SAMPLE_BUCKET_FILENAME, SAMPLE_CUSTOM_FILENAME, SAMPLE_DATABASE_FILENAME, SAMPLE_KV_FILENAME, SCHEMA_INDEX_FILE, SCHEMA_SUBDIRECTORY, SERVER_LIB_DIRECTORY, SERVER_ROOT_DIRECTORY, SSO_AUTH_TIMEOUT_MS, TSCONFIG_FILES, WORKSPACE_NAME };
279
+ export { AUTH_API_SUBDIRECTORY, AUTH_CONFIG_FILE, AUTH_PROVIDER_NAMES, BETTER_AUTH_VERSION, BUCKET_ALWAYS_SKIP, CALLBACK_PATH, CALLBACK_PORT, CLI_DEFAULT_OUTPUTS, CLI_DIRECTORIES, CLI_FILES, CLI_USER_DIRECTORIES, CLOUDFLARE_BINDINGS, CLOUDFLARE_COMPATIBILITY_DATE, CONFIG_FILE_NAMES, DEFAULT_API_ROUTES_DIRECTORY, DEFAULT_DATABASE_DIRECTORY, DEFAULT_PORTS, DEFAULT_SEED_FILE_NAME, ENV_EXAMPLE_FILE, ENV_FILES, GODOT_BUILD_DIRECTORIES, GODOT_BUILD_OUTPUTS, GODOT_EXECUTABLE_PATTERNS, GODOT_EXPORT_PRESETS_FILE, GODOT_PROJECT_FILE, GODOT_WEB_PLATFORM, MINIFLARE_D1_DIRECTORY, OAUTH_CALLBACK_URL_PATTERN, PLACEHOLDER_GAME_URL, PLAYCADEMY_AUTH_VERSION, SAMPLE_API_SUBDIRECTORY, SAMPLE_BUCKET_FILENAME, SAMPLE_CUSTOM_FILENAME, SAMPLE_DATABASE_FILENAME, SAMPLE_KV_FILENAME, SCHEMA_INDEX_FILE, SCHEMA_SUBDIRECTORY, SERVER_LIB_DIRECTORY, SERVER_ROOT_DIRECTORY, SSO_AUTH_TIMEOUT_MS, TSCONFIG_FILES, WORKSPACE_NAME };
package/dist/constants.js CHANGED
@@ -171,6 +171,37 @@ var SCHEMA_SUBDIRECTORY = "schema";
171
171
  var SCHEMA_INDEX_FILE = "index.ts";
172
172
  var DEFAULT_SEED_FILE_NAME = "seed.ts";
173
173
 
174
+ // src/constants/godot.ts
175
+ var GODOT_PROJECT_FILE = "project.godot";
176
+ var GODOT_EXPORT_PRESETS_FILE = "export_presets.cfg";
177
+ var GODOT_WEB_PLATFORM = 'platform="Web"';
178
+ var GODOT_BUILD_DIRECTORIES = {
179
+ /** Root build directory (cleared before each export) */
180
+ ROOT: "build",
181
+ /** Web export subdirectory */
182
+ WEB: "build/web"
183
+ };
184
+ var GODOT_BUILD_OUTPUTS = {
185
+ /** Exported web build entry point */
186
+ INDEX_HTML: "build/web/index.html",
187
+ /** Packaged zip file (created by Godot export) */
188
+ ZIP: "build/web_playcademy.zip"
189
+ };
190
+ var GODOT_EXECUTABLE_PATTERNS = {
191
+ /** macOS app bundle suffix */
192
+ MACOS_APP_SUFFIX: ".app/",
193
+ /** macOS executable path within .app bundle */
194
+ MACOS_APP_EXECUTABLE: "Contents/MacOS/Godot",
195
+ /** Flatpak application ID */
196
+ FLATPAK_ID: "org.godotengine.Godot",
197
+ /** Flatpak run command */
198
+ FLATPAK_COMMAND: "flatpak run org.godotengine.Godot",
199
+ /** Snap package name */
200
+ SNAP_NAME: "godot",
201
+ /** Snap run command */
202
+ SNAP_COMMAND: "snap run godot"
203
+ };
204
+
174
205
  // src/constants/http-server.ts
175
206
  var CALLBACK_PORT = 6175;
176
207
  var CALLBACK_PATH = "/callback";
@@ -291,6 +322,12 @@ export {
291
322
  ENV_EXAMPLE_FILE,
292
323
  ENV_FILES,
293
324
  GAME_WORKER_DOMAINS,
325
+ GODOT_BUILD_DIRECTORIES,
326
+ GODOT_BUILD_OUTPUTS,
327
+ GODOT_EXECUTABLE_PATTERNS,
328
+ GODOT_EXPORT_PRESETS_FILE,
329
+ GODOT_PROJECT_FILE,
330
+ GODOT_WEB_PLATFORM,
294
331
  MINIFLARE_D1_DIRECTORY,
295
332
  OAUTH_CALLBACK_URL_PATTERN,
296
333
  PLACEHOLDER_GAME_URL,
package/dist/db.d.ts CHANGED
@@ -75,6 +75,17 @@ declare function resetDatabase(workspace: string, mf: Miniflare, options?: {
75
75
  debug?: boolean;
76
76
  }): Promise<void>;
77
77
 
78
+ /**
79
+ * Environment context passed to seed functions
80
+ */
81
+ interface SeedContext {
82
+ env: {
83
+ DB: unknown;
84
+ BUCKET?: unknown;
85
+ secrets?: Record<string, string>;
86
+ };
87
+ }
88
+
78
89
  /**
79
90
  * Database Seed Utilities
80
91
  *
@@ -87,19 +98,17 @@ declare function resetDatabase(workspace: string, mf: Miniflare, options?: {
87
98
  * Bundles all deps for portability.
88
99
  */
89
100
  declare function importSeedModule(seedPath: string): Promise<{
90
- seed?: (c: {
91
- env: {
92
- DB: unknown;
93
- };
94
- }) => Promise<void>;
101
+ seed?: (c: SeedContext) => Promise<void>;
95
102
  }>;
103
+ declare function getBucket(mf: Miniflare): Promise<unknown | null>;
96
104
  /**
97
- * Execute a seed file against a Miniflare D1 instance
105
+ * Execute a seed file against a Miniflare instance
98
106
  *
99
107
  * @param seedFilePath - Path to seed file
100
- * @param mf - Miniflare instance with D1 database
108
+ * @param mf - Miniflare instance with D1 database (and optionally bucket/secrets)
109
+ * @param envSecrets - Environment secrets from .env file
101
110
  */
102
- declare function executeSeedFile(seedFilePath: string, mf: Miniflare): Promise<void>;
111
+ declare function executeSeedFile(seedFilePath: string, mf: Miniflare, envSecrets?: Record<string, string>): Promise<void>;
103
112
 
104
- export { bundleSeedWorker, executeSeedFile, getDevDbPath as getPath, importSeedModule, resetDatabase };
113
+ export { bundleSeedWorker, executeSeedFile, getBucket, getDevDbPath as getPath, importSeedModule, resetDatabase };
105
114
  export type { SeedWorkerBundle };
package/dist/db.js CHANGED
@@ -2938,7 +2938,14 @@ async function resetDatabase(workspace, mf, options = { debug: false }) {
2938
2938
  async function importSeedModule(seedPath) {
2939
2939
  return await importTypescriptFile(seedPath);
2940
2940
  }
2941
- async function executeSeedFile(seedFilePath, mf) {
2941
+ async function getBucket(mf) {
2942
+ try {
2943
+ return await mf.getR2Bucket(CLOUDFLARE_BINDINGS.BUCKET);
2944
+ } catch {
2945
+ return null;
2946
+ }
2947
+ }
2948
+ async function executeSeedFile(seedFilePath, mf, envSecrets = {}) {
2942
2949
  const d1 = await mf.getD1Database(CLOUDFLARE_BINDINGS.DB);
2943
2950
  const seedModule = await importSeedModule(seedFilePath);
2944
2951
  if (typeof seedModule.seed !== "function") {
@@ -2951,9 +2958,16 @@ async function executeSeedFile(seedFilePath, mf) {
2951
2958
  logger.newLine();
2952
2959
  process.exit(1);
2953
2960
  }
2961
+ const bucket = await getBucket(mf);
2962
+ const hasSecrets = Object.keys(envSecrets).length > 0;
2954
2963
  await runStep(
2955
2964
  "Seeding database...",
2956
- async () => seedModule.seed?.({ env: { DB: d1 } }),
2965
+ async () => {
2966
+ const env = { DB: d1 };
2967
+ if (bucket) env.BUCKET = bucket;
2968
+ if (hasSecrets) env.secrets = envSecrets;
2969
+ return seedModule.seed?.({ env });
2970
+ },
2957
2971
  "Database seeded successfully!"
2958
2972
  );
2959
2973
  logger.newLine();
@@ -2961,6 +2975,7 @@ async function executeSeedFile(seedFilePath, mf) {
2961
2975
  export {
2962
2976
  bundleSeedWorker,
2963
2977
  executeSeedFile,
2978
+ getBucket,
2964
2979
  getDevDbPath as getPath,
2965
2980
  importSeedModule,
2966
2981
  resetDatabase
package/dist/index.js CHANGED
@@ -947,6 +947,43 @@ var init_database = __esm({
947
947
  }
948
948
  });
949
949
 
950
+ // src/constants/godot.ts
951
+ var GODOT_PROJECT_FILE, GODOT_EXPORT_PRESETS_FILE, GODOT_WEB_PLATFORM, GODOT_BUILD_DIRECTORIES, GODOT_BUILD_OUTPUTS, GODOT_EXECUTABLE_PATTERNS;
952
+ var init_godot = __esm({
953
+ "src/constants/godot.ts"() {
954
+ "use strict";
955
+ GODOT_PROJECT_FILE = "project.godot";
956
+ GODOT_EXPORT_PRESETS_FILE = "export_presets.cfg";
957
+ GODOT_WEB_PLATFORM = 'platform="Web"';
958
+ GODOT_BUILD_DIRECTORIES = {
959
+ /** Root build directory (cleared before each export) */
960
+ ROOT: "build",
961
+ /** Web export subdirectory */
962
+ WEB: "build/web"
963
+ };
964
+ GODOT_BUILD_OUTPUTS = {
965
+ /** Exported web build entry point */
966
+ INDEX_HTML: "build/web/index.html",
967
+ /** Packaged zip file (created by Godot export) */
968
+ ZIP: "build/web_playcademy.zip"
969
+ };
970
+ GODOT_EXECUTABLE_PATTERNS = {
971
+ /** macOS app bundle suffix */
972
+ MACOS_APP_SUFFIX: ".app/",
973
+ /** macOS executable path within .app bundle */
974
+ MACOS_APP_EXECUTABLE: "Contents/MacOS/Godot",
975
+ /** Flatpak application ID */
976
+ FLATPAK_ID: "org.godotengine.Godot",
977
+ /** Flatpak run command */
978
+ FLATPAK_COMMAND: "flatpak run org.godotengine.Godot",
979
+ /** Snap package name */
980
+ SNAP_NAME: "godot",
981
+ /** Snap run command */
982
+ SNAP_COMMAND: "snap run godot"
983
+ };
984
+ }
985
+ });
986
+
950
987
  // src/constants/http-server.ts
951
988
  var CALLBACK_PORT, CALLBACK_PATH, SSO_AUTH_TIMEOUT_MS;
952
989
  var init_http_server = __esm({
@@ -1156,6 +1193,7 @@ var init_constants = __esm({
1156
1193
  init_cloudflare();
1157
1194
  init_config();
1158
1195
  init_database();
1196
+ init_godot();
1159
1197
  init_http_server();
1160
1198
  init_paths();
1161
1199
  init_ports();
@@ -5732,7 +5770,14 @@ init_core();
5732
5770
  async function importSeedModule(seedPath) {
5733
5771
  return await importTypescriptFile(seedPath);
5734
5772
  }
5735
- async function executeSeedFile(seedFilePath, mf) {
5773
+ async function getBucket(mf) {
5774
+ try {
5775
+ return await mf.getR2Bucket(CLOUDFLARE_BINDINGS.BUCKET);
5776
+ } catch {
5777
+ return null;
5778
+ }
5779
+ }
5780
+ async function executeSeedFile(seedFilePath, mf, envSecrets = {}) {
5736
5781
  const d1 = await mf.getD1Database(CLOUDFLARE_BINDINGS.DB);
5737
5782
  const seedModule = await importSeedModule(seedFilePath);
5738
5783
  if (typeof seedModule.seed !== "function") {
@@ -5745,9 +5790,16 @@ async function executeSeedFile(seedFilePath, mf) {
5745
5790
  logger.newLine();
5746
5791
  process.exit(1);
5747
5792
  }
5793
+ const bucket = await getBucket(mf);
5794
+ const hasSecrets = Object.keys(envSecrets).length > 0;
5748
5795
  await runStep(
5749
5796
  "Seeding database...",
5750
- async () => seedModule.seed?.({ env: { DB: d1 } }),
5797
+ async () => {
5798
+ const env = { DB: d1 };
5799
+ if (bucket) env.BUCKET = bucket;
5800
+ if (hasSecrets) env.secrets = envSecrets;
5801
+ return seedModule.seed?.({ env });
5802
+ },
5751
5803
  "Database seeded successfully!"
5752
5804
  );
5753
5805
  logger.newLine();
@@ -6779,23 +6831,24 @@ function displayDeploymentDiff(options) {
6779
6831
 
6780
6832
  // src/lib/deploy/godot.ts
6781
6833
  init_src();
6834
+ init_constants2();
6782
6835
  init_core();
6783
6836
  import { execSync as execSync4 } from "child_process";
6784
- import { existsSync as existsSync10, mkdirSync as mkdirSync2, readFileSync as readFileSync5 } from "fs";
6837
+ import { existsSync as existsSync10, mkdirSync as mkdirSync2, readFileSync as readFileSync5, rmSync as rmSync3 } from "fs";
6785
6838
  import { join as join13 } from "path";
6786
6839
  import { confirm, select } from "@inquirer/prompts";
6787
6840
  function isGodotProject() {
6788
- return existsSync10(join13(getWorkspace(), "project.godot"));
6841
+ return existsSync10(join13(getWorkspace(), GODOT_PROJECT_FILE));
6789
6842
  }
6790
6843
  function hasWebExportPreset() {
6791
- const presetsPath = join13(getWorkspace(), "export_presets.cfg");
6844
+ const presetsPath = join13(getWorkspace(), GODOT_EXPORT_PRESETS_FILE);
6792
6845
  if (!existsSync10(presetsPath)) {
6793
6846
  return { configured: false };
6794
6847
  }
6795
6848
  try {
6796
6849
  const content = readFileSync5(presetsPath, "utf-8");
6797
6850
  const lines = content.split("\n");
6798
- const webPlatformIndex = lines.findIndex((line) => line.trim() === 'platform="Web"');
6851
+ const webPlatformIndex = lines.findIndex((line) => line.trim() === GODOT_WEB_PLATFORM);
6799
6852
  if (webPlatformIndex === -1) {
6800
6853
  return { configured: false };
6801
6854
  }
@@ -6824,8 +6877,8 @@ async function findGodotExecutable() {
6824
6877
  const result = execSync4(whichCmd, { stdio: "pipe", encoding: "utf-8" });
6825
6878
  const paths = result.trim().split("\n").filter(Boolean);
6826
6879
  for (const path4 of paths) {
6827
- if (platform === "darwin" && path4.includes(".app/")) {
6828
- const appPath = path4.split(".app/")[0] + ".app";
6880
+ if (platform === "darwin" && path4.includes(GODOT_EXECUTABLE_PATTERNS.MACOS_APP_SUFFIX)) {
6881
+ const appPath = path4.split(GODOT_EXECUTABLE_PATTERNS.MACOS_APP_SUFFIX)[0] + GODOT_EXECUTABLE_PATTERNS.MACOS_APP_SUFFIX.slice(0, -1);
6829
6882
  const appName = appPath.split("/").pop() || "Godot";
6830
6883
  foundExecutables.push({ path: path4, label: appName });
6831
6884
  seenAppBundles.add(appPath);
@@ -6844,7 +6897,7 @@ async function findGodotExecutable() {
6844
6897
  const apps = result.split("\n").filter(Boolean);
6845
6898
  for (const appPath of apps) {
6846
6899
  if (seenAppBundles.has(appPath)) continue;
6847
- const executable = join13(appPath, "Contents/MacOS/Godot");
6900
+ const executable = join13(appPath, GODOT_EXECUTABLE_PATTERNS.MACOS_APP_EXECUTABLE);
6848
6901
  const appName = appPath.split("/").pop() || "Godot";
6849
6902
  foundExecutables.push({ path: executable, label: appName });
6850
6903
  }
@@ -6853,16 +6906,23 @@ async function findGodotExecutable() {
6853
6906
  }
6854
6907
  if (platform === "linux") {
6855
6908
  try {
6856
- execSync4("flatpak list 2>/dev/null | grep org.godotengine.Godot", { stdio: "pipe" });
6909
+ execSync4(`flatpak list 2>/dev/null | grep ${GODOT_EXECUTABLE_PATTERNS.FLATPAK_ID}`, {
6910
+ stdio: "pipe"
6911
+ });
6857
6912
  foundExecutables.push({
6858
- path: "flatpak run org.godotengine.Godot",
6913
+ path: GODOT_EXECUTABLE_PATTERNS.FLATPAK_COMMAND,
6859
6914
  label: "Godot (flatpak)"
6860
6915
  });
6861
6916
  } catch {
6862
6917
  }
6863
6918
  try {
6864
- execSync4("snap list 2>/dev/null | grep godot", { stdio: "pipe" });
6865
- foundExecutables.push({ path: "snap run godot", label: "Godot (snap)" });
6919
+ execSync4(`snap list 2>/dev/null | grep ${GODOT_EXECUTABLE_PATTERNS.SNAP_NAME}`, {
6920
+ stdio: "pipe"
6921
+ });
6922
+ foundExecutables.push({
6923
+ path: GODOT_EXECUTABLE_PATTERNS.SNAP_COMMAND,
6924
+ label: "Godot (snap)"
6925
+ });
6866
6926
  } catch {
6867
6927
  }
6868
6928
  }
@@ -6899,7 +6959,11 @@ async function findGodotExecutable() {
6899
6959
  async function runGodotExport(godotPath, presetName, outputPath) {
6900
6960
  const root = getWorkspace();
6901
6961
  try {
6902
- mkdirSync2(join13(root, "build", "web"), { recursive: true });
6962
+ const buildDir = join13(root, GODOT_BUILD_DIRECTORIES.ROOT);
6963
+ if (existsSync10(buildDir)) {
6964
+ rmSync3(buildDir, { recursive: true, force: true });
6965
+ }
6966
+ mkdirSync2(join13(root, GODOT_BUILD_DIRECTORIES.WEB), { recursive: true });
6903
6967
  await runStep(
6904
6968
  `Exporting project using "${presetName}" preset`,
6905
6969
  async () => {
@@ -6945,19 +7009,22 @@ async function handleGodotBuildPrompt() {
6945
7009
  logger.newLine();
6946
7010
  return null;
6947
7011
  }
6948
- const success = await runGodotExport(godotPath, webExport.presetName, "build/web/index.html");
7012
+ const success = await runGodotExport(
7013
+ godotPath,
7014
+ webExport.presetName,
7015
+ GODOT_BUILD_OUTPUTS.INDEX_HTML
7016
+ );
6949
7017
  if (!success) {
6950
7018
  logger.error("Export failed. Please export manually or provide zip file.");
6951
7019
  logger.newLine();
6952
7020
  return null;
6953
7021
  }
6954
- const zipPath = "build/web_playcademy.zip";
6955
- if (existsSync10(join13(getWorkspace(), zipPath))) {
6956
- return zipPath;
7022
+ if (existsSync10(join13(getWorkspace(), GODOT_BUILD_OUTPUTS.ZIP))) {
7023
+ return GODOT_BUILD_OUTPUTS.ZIP;
6957
7024
  }
6958
7025
  logger.warn("Expected zip file not found, using build directory");
6959
7026
  logger.newLine();
6960
- return "build/web";
7027
+ return GODOT_BUILD_DIRECTORIES.WEB;
6961
7028
  }
6962
7029
 
6963
7030
  // src/lib/deploy/interaction.ts
@@ -7070,8 +7137,11 @@ function scaffoldProtectedExample(workspace) {
7070
7137
  writeFileSync3(join14(sampleDir, "protected.ts"), protectedRouteTemplate);
7071
7138
  }
7072
7139
  function updateEnvForAuth(workspace, strategies) {
7073
- if (strategies.length === 0) return;
7074
7140
  const envLines = [];
7141
+ envLines.push("# Better Auth (required)");
7142
+ envLines.push("# Generate with: openssl rand -base64 32");
7143
+ envLines.push("BETTER_AUTH_SECRET=your_secret_here");
7144
+ envLines.push("");
7075
7145
  if (strategies.includes("github")) {
7076
7146
  envLines.push("# GitHub OAuth (for standalone auth)");
7077
7147
  envLines.push("GITHUB_CLIENT_ID=your_github_client_id");
@@ -7084,9 +7154,7 @@ function updateEnvForAuth(workspace, strategies) {
7084
7154
  envLines.push("GOOGLE_CLIENT_SECRET=your_google_client_secret");
7085
7155
  envLines.push("");
7086
7156
  }
7087
- if (envLines.length > 0) {
7088
- updateEnvExample(workspace, envLines);
7089
- }
7157
+ updateEnvExample(workspace, envLines);
7090
7158
  }
7091
7159
  async function scaffoldAuthSetup(options = {}) {
7092
7160
  const workspace = getWorkspace();
@@ -7142,7 +7210,7 @@ import { join as join15 } from "path";
7142
7210
  // package.json
7143
7211
  var package_default2 = {
7144
7212
  name: "playcademy",
7145
- version: "0.14.10",
7213
+ version: "0.14.12",
7146
7214
  type: "module",
7147
7215
  exports: {
7148
7216
  ".": {
@@ -8383,6 +8451,7 @@ async function reportDryRun(plan, context2) {
8383
8451
  logger.data("Update Game", String(plan.shouldUpdateGame), 1);
8384
8452
  logger.data("Upload Build", String(plan.shouldUploadBuild), 1);
8385
8453
  logger.data("Deploy Backend", String(plan.shouldDeployBackend), 1);
8454
+ logger.newLine();
8386
8455
  const diff = plan.changes.config ? calculateConfigDiff(context2.existingGame, context2.config) : {};
8387
8456
  const currentIntegrationKeys = getIntegrationKeys(context2.fullConfig?.integrations);
8388
8457
  const schemaStatementCount = await getSchemaStatementCount(
@@ -8445,7 +8514,6 @@ async function reportDryRun(plan, context2) {
8445
8514
  } else {
8446
8515
  logger.remark("No changes detected");
8447
8516
  }
8448
- logger.newLine();
8449
8517
  logger.remark("Dry run complete");
8450
8518
  logger.newLine();
8451
8519
  }
@@ -11852,10 +11920,37 @@ async function runDbSeedRemote(seedFile, options) {
11852
11920
  async function runDbSeedLocal(seedFile, options) {
11853
11921
  const workspace = getWorkspace();
11854
11922
  const dbDir = join31(workspace, CLI_DIRECTORIES.DATABASE);
11923
+ const config = await loadConfig();
11924
+ const hasBucket = hasBucketSetup(config);
11925
+ const hasKV = hasKVSetup(config);
11926
+ const bucketDir = hasBucket ? join31(workspace, CLI_DIRECTORIES.BUCKET) : void 0;
11927
+ const kvDir = hasKV ? join31(workspace, CLI_DIRECTORIES.KV) : void 0;
11928
+ if (bucketDir) {
11929
+ const { mkdir: mkdir5 } = await import("fs/promises");
11930
+ await mkdir5(bucketDir, { recursive: true });
11931
+ }
11932
+ if (kvDir) {
11933
+ const { mkdir: mkdir5 } = await import("fs/promises");
11934
+ await mkdir5(kvDir, { recursive: true });
11935
+ }
11936
+ const envSecrets = await readEnvFile(workspace);
11937
+ const bindings = {};
11938
+ for (const [key, value] of Object.entries(envSecrets)) {
11939
+ bindings[`secrets_${key}`] = value;
11940
+ }
11855
11941
  const mf = new Miniflare3({
11856
11942
  modules: [{ type: "ESModule", path: "index.mjs", contents: "" }],
11943
+ bindings,
11857
11944
  d1Databases: [CLOUDFLARE_BINDINGS.DB],
11858
11945
  d1Persist: dbDir,
11946
+ ...hasBucket && {
11947
+ r2Buckets: [CLOUDFLARE_BINDINGS.BUCKET],
11948
+ r2Persist: bucketDir
11949
+ },
11950
+ ...hasKV && {
11951
+ kvNamespaces: [CLOUDFLARE_BINDINGS.KV],
11952
+ kvPersist: kvDir
11953
+ },
11859
11954
  compatibilityDate: CLOUDFLARE_COMPATIBILITY_DATE
11860
11955
  });
11861
11956
  logger.newLine();
@@ -11863,7 +11958,7 @@ async function runDbSeedLocal(seedFile, options) {
11863
11958
  await resetDatabase(workspace, mf, { debug: options.debug });
11864
11959
  }
11865
11960
  try {
11866
- await executeSeedFile(seedFile, mf);
11961
+ await executeSeedFile(seedFile, mf, envSecrets);
11867
11962
  } finally {
11868
11963
  await mf.dispose();
11869
11964
  }
@@ -14901,6 +14996,7 @@ export {
14901
14996
  getAuthenticatedEnvironments,
14902
14997
  getBaseUrl,
14903
14998
  getBestUnit,
14999
+ getBucket,
14904
15000
  getBucketKey,
14905
15001
  getCallbackUrl,
14906
15002
  getCliContext,
@@ -7,7 +7,7 @@
7
7
 
8
8
  import { desc } from 'drizzle-orm'
9
9
 
10
- import { getDb, schema } from '../../../db'
10
+ import { getDb, schema } from 'db'
11
11
 
12
12
  /**
13
13
  * GET /api/sample/database
@@ -11,10 +11,20 @@ import { playcademy } from '@playcademy/better-auth/server'
11
11
 
12
12
  import { getDb } from '../../db'
13
13
 
14
- import type { Context } from 'hono'
14
+ function getAuthSecret(c: Context): string {
15
+ const secret = c.env.secrets?.BETTER_AUTH_SECRET
16
+ if (!secret) {
17
+ throw new Error(
18
+ 'BETTER_AUTH_SECRET is required. ' +
19
+ 'Set it locally in .env or deploy with: playcademy secret set BETTER_AUTH_SECRET <value>'
20
+ )
21
+ }
22
+ return secret
23
+ }
15
24
 
16
25
  export function getAuth(c: Context) {
17
26
  const db = getDb(c.env.DB)
27
+ const secret = getAuthSecret(c)
18
28
 
19
29
  // CUSTOMIZABLE: Configure trusted origins for CORS
20
30
  // These origins are allowed to make cross-origin requests to your game's auth endpoints.
@@ -31,6 +41,8 @@ export function getAuth(c: Context) {
31
41
  usePlural: false,
32
42
  }),
33
43
 
44
+ secret,
45
+
34
46
  trustedOrigins,
35
47
  {{EMAIL_AND_PASSWORD}}{{SOCIAL_PROVIDERS}}
36
48
  // REQUIRED: Platform integration
package/dist/utils.js CHANGED
@@ -3829,7 +3829,7 @@ import { join as join8 } from "path";
3829
3829
  // package.json
3830
3830
  var package_default2 = {
3831
3831
  name: "playcademy",
3832
- version: "0.14.10",
3832
+ version: "0.14.12",
3833
3833
  type: "module",
3834
3834
  exports: {
3835
3835
  ".": {
package/dist/version.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // package.json
2
2
  var package_default = {
3
3
  name: "playcademy",
4
- version: "0.14.10",
4
+ version: "0.14.12",
5
5
  type: "module",
6
6
  exports: {
7
7
  ".": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playcademy",
3
- "version": "0.14.11",
3
+ "version": "0.14.12-alpha.1",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {