playcademy 0.14.14 → 0.14.16
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/index.d.ts +8 -1
- package/dist/index.js +77 -14
- package/dist/utils.js +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -690,7 +690,14 @@ interface DeployedGameInfo {
|
|
|
690
690
|
deployedSecrets?: string[];
|
|
691
691
|
}
|
|
692
692
|
interface GameStore {
|
|
693
|
-
|
|
693
|
+
/** Staging environment game deployments, keyed by absolute project path */
|
|
694
|
+
staging: {
|
|
695
|
+
[projectPath: string]: DeployedGameInfo;
|
|
696
|
+
};
|
|
697
|
+
/** Production environment game deployments, keyed by absolute project path */
|
|
698
|
+
production: {
|
|
699
|
+
[projectPath: string]: DeployedGameInfo;
|
|
700
|
+
};
|
|
694
701
|
}
|
|
695
702
|
/**
|
|
696
703
|
* Deployment context containing all information needed for deployment
|
package/dist/index.js
CHANGED
|
@@ -7222,7 +7222,7 @@ import { join as join18 } from "path";
|
|
|
7222
7222
|
// package.json
|
|
7223
7223
|
var package_default2 = {
|
|
7224
7224
|
name: "playcademy",
|
|
7225
|
-
version: "0.14.
|
|
7225
|
+
version: "0.14.15",
|
|
7226
7226
|
type: "module",
|
|
7227
7227
|
exports: {
|
|
7228
7228
|
".": {
|
|
@@ -8980,6 +8980,7 @@ init_context();
|
|
|
8980
8980
|
|
|
8981
8981
|
// src/lib/games/storage.ts
|
|
8982
8982
|
init_constants2();
|
|
8983
|
+
init_config2();
|
|
8983
8984
|
import { existsSync as existsSync19 } from "node:fs";
|
|
8984
8985
|
import { mkdir as mkdir3, readFile as readFile3, writeFile as writeFile3 } from "node:fs/promises";
|
|
8985
8986
|
import { homedir as homedir2 } from "node:os";
|
|
@@ -8997,33 +8998,82 @@ async function loadGameStore() {
|
|
|
8997
8998
|
const storePath = getGamesStorePath();
|
|
8998
8999
|
if (existsSync19(storePath)) {
|
|
8999
9000
|
const content = await readFile3(storePath, "utf-8");
|
|
9000
|
-
|
|
9001
|
+
const parsed = JSON.parse(content);
|
|
9002
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
9003
|
+
return { staging: {}, production: {} };
|
|
9004
|
+
}
|
|
9005
|
+
const parsedObj = parsed;
|
|
9006
|
+
if (!("staging" in parsedObj) && !("production" in parsedObj)) {
|
|
9007
|
+
const entries = Object.entries(parsedObj);
|
|
9008
|
+
const looksValidLegacy = entries.every(
|
|
9009
|
+
([, v]) => v !== null && typeof v === "object" && !Array.isArray(v)
|
|
9010
|
+
);
|
|
9011
|
+
if (!looksValidLegacy) {
|
|
9012
|
+
return { staging: {}, production: {} };
|
|
9013
|
+
}
|
|
9014
|
+
const migrated = { staging: {}, production: {} };
|
|
9015
|
+
for (const [key, value] of entries) {
|
|
9016
|
+
const info = value;
|
|
9017
|
+
if (typeof key === "string" && key.includes(":")) {
|
|
9018
|
+
const idx = key.lastIndexOf(":");
|
|
9019
|
+
const basePath = key.slice(0, idx);
|
|
9020
|
+
const envSuffix = key.slice(idx + 1);
|
|
9021
|
+
if (envSuffix === "staging") {
|
|
9022
|
+
migrated.staging[basePath] = info;
|
|
9023
|
+
continue;
|
|
9024
|
+
}
|
|
9025
|
+
if (envSuffix === "production") {
|
|
9026
|
+
migrated.production[basePath] = info;
|
|
9027
|
+
continue;
|
|
9028
|
+
}
|
|
9029
|
+
}
|
|
9030
|
+
migrated.staging[key] = info;
|
|
9031
|
+
}
|
|
9032
|
+
await saveGameStore(migrated);
|
|
9033
|
+
return migrated;
|
|
9034
|
+
}
|
|
9035
|
+
const store = parsedObj;
|
|
9036
|
+
return {
|
|
9037
|
+
staging: store.staging ?? {},
|
|
9038
|
+
production: store.production ?? {}
|
|
9039
|
+
};
|
|
9001
9040
|
}
|
|
9002
9041
|
} catch {
|
|
9003
9042
|
}
|
|
9004
|
-
return {
|
|
9043
|
+
return {
|
|
9044
|
+
staging: {},
|
|
9045
|
+
production: {}
|
|
9046
|
+
};
|
|
9005
9047
|
}
|
|
9006
9048
|
async function saveGameStore(store) {
|
|
9007
9049
|
await ensureConfigDir();
|
|
9008
9050
|
const storePath = getGamesStorePath();
|
|
9009
9051
|
await writeFile3(storePath, JSON.stringify(store, null, 2), "utf-8");
|
|
9010
9052
|
}
|
|
9011
|
-
async function getDeployedGame(projectPath) {
|
|
9053
|
+
async function getDeployedGame(projectPath, environment) {
|
|
9012
9054
|
const store = await loadGameStore();
|
|
9013
|
-
|
|
9055
|
+
const env = environment ?? getEnvironment();
|
|
9056
|
+
const bucket = env === "production" ? store.production : store.staging;
|
|
9057
|
+
return bucket[projectPath] || null;
|
|
9014
9058
|
}
|
|
9015
|
-
async function saveDeployedGame(projectPath, gameInfo) {
|
|
9059
|
+
async function saveDeployedGame(projectPath, gameInfo, environment) {
|
|
9016
9060
|
const store = await loadGameStore();
|
|
9017
|
-
|
|
9018
|
-
|
|
9061
|
+
const env = environment ?? getEnvironment();
|
|
9062
|
+
const bucket = env === "production" ? store.production : store.staging;
|
|
9063
|
+
bucket[projectPath] = {
|
|
9064
|
+
...bucket[projectPath],
|
|
9019
9065
|
...gameInfo
|
|
9020
9066
|
};
|
|
9021
9067
|
await saveGameStore(store);
|
|
9022
9068
|
}
|
|
9023
|
-
async function removeDeployedGame(projectPath) {
|
|
9069
|
+
async function removeDeployedGame(projectPath, environment) {
|
|
9024
9070
|
const store = await loadGameStore();
|
|
9025
|
-
|
|
9026
|
-
|
|
9071
|
+
const env = environment ?? getEnvironment();
|
|
9072
|
+
const bucket = env === "production" ? store.production : store.staging;
|
|
9073
|
+
if (bucket[projectPath]) {
|
|
9074
|
+
delete bucket[projectPath];
|
|
9075
|
+
await saveGameStore(store);
|
|
9076
|
+
}
|
|
9027
9077
|
}
|
|
9028
9078
|
async function saveDeploymentState(game, backendMetadata, context2) {
|
|
9029
9079
|
const { projectPath, buildHash, buildSize, config, fullConfig } = context2;
|
|
@@ -9083,6 +9133,7 @@ async function saveDeploymentState(game, backendMetadata, context2) {
|
|
|
9083
9133
|
|
|
9084
9134
|
// src/lib/deploy/secrets.ts
|
|
9085
9135
|
init_core();
|
|
9136
|
+
import { ApiError as ApiError2 } from "@playcademy/sdk";
|
|
9086
9137
|
function compareSecrets(current, previous) {
|
|
9087
9138
|
const currentKeys = Object.keys(current);
|
|
9088
9139
|
const changes = [];
|
|
@@ -9108,6 +9159,10 @@ async function fetchSecretsForDeployment(slug) {
|
|
|
9108
9159
|
const keys = Object.keys(secrets);
|
|
9109
9160
|
return { secrets, keys };
|
|
9110
9161
|
} catch (error) {
|
|
9162
|
+
if (error instanceof ApiError2 && error.status === 404) {
|
|
9163
|
+
logger.debug(`[Secrets] No secrets configured for game (404)`);
|
|
9164
|
+
return { secrets: {}, keys: [] };
|
|
9165
|
+
}
|
|
9111
9166
|
logger.warn(
|
|
9112
9167
|
`Could not fetch secrets: ${error instanceof Error ? error.message : String(error)}`
|
|
9113
9168
|
);
|
|
@@ -9153,13 +9208,21 @@ async function prepareDeploymentContext(options) {
|
|
|
9153
9208
|
const projectPath = getWorkspace();
|
|
9154
9209
|
const deployedGameInfo = await getDeployedGame(projectPath);
|
|
9155
9210
|
let existingGame;
|
|
9211
|
+
const existingGames = await client.games.list({ force: true });
|
|
9156
9212
|
if (deployedGameInfo) {
|
|
9157
|
-
const existingGames = await client.games.list({ force: true });
|
|
9158
9213
|
existingGame = existingGames.find((g) => g.id === deployedGameInfo.gameId);
|
|
9159
|
-
}
|
|
9160
|
-
|
|
9214
|
+
}
|
|
9215
|
+
if (!existingGame && finalConfig.slug) {
|
|
9161
9216
|
existingGame = existingGames.find((g) => g.slug === finalConfig.slug);
|
|
9162
9217
|
}
|
|
9218
|
+
if (existingGame) {
|
|
9219
|
+
const currentUser = await client.users.me();
|
|
9220
|
+
const isAdmin = currentUser.role === "admin";
|
|
9221
|
+
const isOwner = existingGame.developerId === currentUser.id;
|
|
9222
|
+
if (!isAdmin && !isOwner) {
|
|
9223
|
+
throw new Error(`Unable to deploy '${existingGame.slug}': You do not own this game`);
|
|
9224
|
+
}
|
|
9225
|
+
}
|
|
9163
9226
|
const gameIsDeployed = existingGame ? isGameDeployed(existingGame) : false;
|
|
9164
9227
|
if (existingGame && gameIsDeployed) {
|
|
9165
9228
|
finalConfig.slug = existingGame.slug;
|
package/dist/utils.js
CHANGED
package/dist/version.js
CHANGED