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.
- package/dist/constants.d.ts +54 -1
- package/dist/constants.js +37 -0
- package/dist/db.d.ts +18 -9
- package/dist/db.js +17 -2
- package/dist/index.js +122 -26
- package/dist/templates/api/sample-database.ts.template +1 -1
- package/dist/templates/auth/auth.ts.template +13 -1
- package/dist/utils.js +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/constants.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
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 () =>
|
|
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
|
|
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 () =>
|
|
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(),
|
|
6841
|
+
return existsSync10(join13(getWorkspace(), GODOT_PROJECT_FILE));
|
|
6789
6842
|
}
|
|
6790
6843
|
function hasWebExportPreset() {
|
|
6791
|
-
const presetsPath = join13(getWorkspace(),
|
|
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() ===
|
|
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(
|
|
6828
|
-
const appPath = path4.split(
|
|
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,
|
|
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(
|
|
6909
|
+
execSync4(`flatpak list 2>/dev/null | grep ${GODOT_EXECUTABLE_PATTERNS.FLATPAK_ID}`, {
|
|
6910
|
+
stdio: "pipe"
|
|
6911
|
+
});
|
|
6857
6912
|
foundExecutables.push({
|
|
6858
|
-
path:
|
|
6913
|
+
path: GODOT_EXECUTABLE_PATTERNS.FLATPAK_COMMAND,
|
|
6859
6914
|
label: "Godot (flatpak)"
|
|
6860
6915
|
});
|
|
6861
6916
|
} catch {
|
|
6862
6917
|
}
|
|
6863
6918
|
try {
|
|
6864
|
-
execSync4(
|
|
6865
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
6955
|
-
|
|
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
|
|
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
|
-
|
|
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.
|
|
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,
|
|
@@ -11,10 +11,20 @@ import { playcademy } from '@playcademy/better-auth/server'
|
|
|
11
11
|
|
|
12
12
|
import { getDb } from '../../db'
|
|
13
13
|
|
|
14
|
-
|
|
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
package/dist/version.js
CHANGED