playcademy 0.7.0 → 0.9.0
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.js +411 -200
- package/dist/types.d.ts +19 -6
- package/dist/utils.js +56 -20
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2513,6 +2513,16 @@ var CONFIG_FILE_NAMES = [
|
|
|
2513
2513
|
"playcademy.config.mjs"
|
|
2514
2514
|
];
|
|
2515
2515
|
|
|
2516
|
+
// src/constants/urls.ts
|
|
2517
|
+
var PLAYCADEMY_BASE_URLS = {
|
|
2518
|
+
staging: "https://hub.dev.playcademy.net",
|
|
2519
|
+
production: "https://hub.playcademy.com"
|
|
2520
|
+
};
|
|
2521
|
+
var GAME_BACKEND_DOMAINS = {
|
|
2522
|
+
staging: "staging.playcademy.gg",
|
|
2523
|
+
production: "playcademy.gg"
|
|
2524
|
+
};
|
|
2525
|
+
|
|
2516
2526
|
// src/lib/auth/storage.ts
|
|
2517
2527
|
import { access, mkdir, readFile as readFile2, writeFile } from "node:fs/promises";
|
|
2518
2528
|
import { homedir } from "node:os";
|
|
@@ -2521,7 +2531,7 @@ import { join } from "node:path";
|
|
|
2521
2531
|
// src/lib/core/context.ts
|
|
2522
2532
|
var context = {};
|
|
2523
2533
|
function setCliContext(ctx) {
|
|
2524
|
-
context = ctx;
|
|
2534
|
+
context = { ...context, ...ctx };
|
|
2525
2535
|
}
|
|
2526
2536
|
function getCliContext() {
|
|
2527
2537
|
return context;
|
|
@@ -2531,26 +2541,47 @@ function getWorkspace() {
|
|
|
2531
2541
|
}
|
|
2532
2542
|
|
|
2533
2543
|
// src/lib/core/config.ts
|
|
2544
|
+
function normalizeEnvironment(env) {
|
|
2545
|
+
if (!env) return null;
|
|
2546
|
+
const normalized = env.toLowerCase().trim();
|
|
2547
|
+
if (normalized === "staging" || normalized === "stage") {
|
|
2548
|
+
return "staging";
|
|
2549
|
+
}
|
|
2550
|
+
if (normalized === "production" || normalized === "prod") {
|
|
2551
|
+
return "production";
|
|
2552
|
+
}
|
|
2553
|
+
return null;
|
|
2554
|
+
}
|
|
2555
|
+
function ensureEnvironment(env, logger2) {
|
|
2556
|
+
if (env) {
|
|
2557
|
+
const normalized = normalizeEnvironment(env);
|
|
2558
|
+
if (!normalized) {
|
|
2559
|
+
logger2.newLine();
|
|
2560
|
+
logger2.error(`Invalid environment: "${env}"`);
|
|
2561
|
+
logger2.newLine();
|
|
2562
|
+
logger2.info("Valid environments: staging, production");
|
|
2563
|
+
logger2.newLine();
|
|
2564
|
+
process.exit(1);
|
|
2565
|
+
}
|
|
2566
|
+
setCliContext({ environment: normalized });
|
|
2567
|
+
}
|
|
2568
|
+
return getEnvironment();
|
|
2569
|
+
}
|
|
2534
2570
|
function getEnvironment() {
|
|
2535
2571
|
const context2 = getCliContext();
|
|
2536
2572
|
if (context2.environment) {
|
|
2537
2573
|
return context2.environment;
|
|
2538
2574
|
}
|
|
2539
2575
|
const env = process.env.PLAYCADEMY_ENV?.toLowerCase();
|
|
2540
|
-
if (env === "staging") {
|
|
2541
|
-
return
|
|
2576
|
+
if (env === "staging" || env === "production") {
|
|
2577
|
+
return env;
|
|
2542
2578
|
}
|
|
2543
|
-
return "
|
|
2579
|
+
return "staging";
|
|
2544
2580
|
}
|
|
2545
2581
|
function getBaseUrl() {
|
|
2546
2582
|
const explicitUrl = process.env.PLAYCADEMY_BASE_URL;
|
|
2547
|
-
if (explicitUrl)
|
|
2548
|
-
|
|
2549
|
-
}
|
|
2550
|
-
if (getEnvironment() === "staging") {
|
|
2551
|
-
return "https://hub.dev.playcademy.net";
|
|
2552
|
-
}
|
|
2553
|
-
return "https://hub.playcademy.com";
|
|
2583
|
+
if (explicitUrl) return explicitUrl;
|
|
2584
|
+
return PLAYCADEMY_BASE_URLS[getEnvironment()];
|
|
2554
2585
|
}
|
|
2555
2586
|
function getApiUrl(path) {
|
|
2556
2587
|
const baseUrl = getBaseUrl();
|
|
@@ -2573,6 +2604,12 @@ async function ensureAuthDir() {
|
|
|
2573
2604
|
const authDir = join(homedir(), ".playcademy");
|
|
2574
2605
|
await mkdir(authDir, { recursive: true });
|
|
2575
2606
|
}
|
|
2607
|
+
function createEmptyEnvironmentProfiles() {
|
|
2608
|
+
return {
|
|
2609
|
+
default: null,
|
|
2610
|
+
profiles: {}
|
|
2611
|
+
};
|
|
2612
|
+
}
|
|
2576
2613
|
async function loadAuthStore() {
|
|
2577
2614
|
try {
|
|
2578
2615
|
await ensureAuthDir();
|
|
@@ -2583,8 +2620,8 @@ async function loadAuthStore() {
|
|
|
2583
2620
|
} catch {
|
|
2584
2621
|
}
|
|
2585
2622
|
return {
|
|
2586
|
-
|
|
2587
|
-
|
|
2623
|
+
staging: createEmptyEnvironmentProfiles(),
|
|
2624
|
+
production: createEmptyEnvironmentProfiles()
|
|
2588
2625
|
};
|
|
2589
2626
|
}
|
|
2590
2627
|
async function saveAuthStore(store) {
|
|
@@ -2601,45 +2638,79 @@ async function getCurrentProfile() {
|
|
|
2601
2638
|
};
|
|
2602
2639
|
}
|
|
2603
2640
|
const store = await loadAuthStore();
|
|
2641
|
+
const environment = getEnvironment();
|
|
2604
2642
|
const profileName = getProfileName();
|
|
2643
|
+
const envProfiles = store[environment];
|
|
2644
|
+
if (!envProfiles) {
|
|
2645
|
+
return null;
|
|
2646
|
+
}
|
|
2605
2647
|
if (profileName === "default") {
|
|
2606
|
-
return
|
|
2648
|
+
return envProfiles.default;
|
|
2607
2649
|
}
|
|
2608
|
-
return
|
|
2650
|
+
return envProfiles.profiles[profileName] || null;
|
|
2609
2651
|
}
|
|
2610
|
-
async function saveProfile(profileName, profile) {
|
|
2652
|
+
async function saveProfile(environment, profileName, profile) {
|
|
2611
2653
|
const store = await loadAuthStore();
|
|
2654
|
+
if (!store[environment]) {
|
|
2655
|
+
store[environment] = createEmptyEnvironmentProfiles();
|
|
2656
|
+
}
|
|
2657
|
+
const envProfiles = store[environment];
|
|
2612
2658
|
if (profileName === "default") {
|
|
2613
|
-
|
|
2659
|
+
envProfiles.default = profile;
|
|
2614
2660
|
} else {
|
|
2615
|
-
|
|
2661
|
+
envProfiles.profiles[profileName] = profile;
|
|
2616
2662
|
}
|
|
2617
2663
|
await saveAuthStore(store);
|
|
2618
2664
|
}
|
|
2619
|
-
async function removeProfile(profileName) {
|
|
2665
|
+
async function removeProfile(environment, profileName) {
|
|
2620
2666
|
const store = await loadAuthStore();
|
|
2667
|
+
if (!store[environment]) {
|
|
2668
|
+
return;
|
|
2669
|
+
}
|
|
2670
|
+
const envProfiles = store[environment];
|
|
2621
2671
|
if (profileName === "default") {
|
|
2622
|
-
|
|
2672
|
+
envProfiles.default = null;
|
|
2623
2673
|
} else {
|
|
2624
|
-
delete
|
|
2674
|
+
delete envProfiles.profiles[profileName];
|
|
2625
2675
|
}
|
|
2626
2676
|
await saveAuthStore(store);
|
|
2627
2677
|
}
|
|
2628
|
-
async function getProfile(profileName) {
|
|
2678
|
+
async function getProfile(environment, profileName) {
|
|
2629
2679
|
const store = await loadAuthStore();
|
|
2680
|
+
const envProfiles = store[environment];
|
|
2681
|
+
if (!envProfiles) {
|
|
2682
|
+
return null;
|
|
2683
|
+
}
|
|
2630
2684
|
if (profileName === "default") {
|
|
2631
|
-
return
|
|
2685
|
+
return envProfiles.default;
|
|
2632
2686
|
}
|
|
2633
|
-
return
|
|
2687
|
+
return envProfiles.profiles[profileName] || null;
|
|
2634
2688
|
}
|
|
2635
2689
|
async function listProfiles() {
|
|
2636
2690
|
const store = await loadAuthStore();
|
|
2637
|
-
const
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2691
|
+
const profileMap = /* @__PURE__ */ new Map();
|
|
2692
|
+
const stagingProfiles = [];
|
|
2693
|
+
if (store.staging.default) {
|
|
2694
|
+
stagingProfiles.push("default");
|
|
2695
|
+
}
|
|
2696
|
+
stagingProfiles.push(...Object.keys(store.staging.profiles));
|
|
2697
|
+
profileMap.set("staging", stagingProfiles);
|
|
2698
|
+
const productionProfiles = [];
|
|
2699
|
+
if (store.production.default) {
|
|
2700
|
+
productionProfiles.push("default");
|
|
2701
|
+
}
|
|
2702
|
+
productionProfiles.push(...Object.keys(store.production.profiles));
|
|
2703
|
+
profileMap.set("production", productionProfiles);
|
|
2704
|
+
return profileMap;
|
|
2705
|
+
}
|
|
2706
|
+
async function getAuthenticatedEnvironments() {
|
|
2707
|
+
const store = await loadAuthStore();
|
|
2708
|
+
const environments = [];
|
|
2709
|
+
const hasStaging = store.staging.default !== null || Object.keys(store.staging.profiles).length > 0;
|
|
2710
|
+
const hasProduction = store.production.default !== null || Object.keys(store.production.profiles).length > 0;
|
|
2711
|
+
if (hasStaging) environments.push("staging");
|
|
2712
|
+
if (hasProduction) environments.push("production");
|
|
2713
|
+
return environments;
|
|
2643
2714
|
}
|
|
2644
2715
|
|
|
2645
2716
|
// src/lib/auth/http-server/server.ts
|
|
@@ -7260,15 +7331,7 @@ function createDevNamespace(client) {
|
|
|
7260
7331
|
throw new Error(`File upload failed: ${uploadResponse.status} ${uploadResponse.statusText}`);
|
|
7261
7332
|
}
|
|
7262
7333
|
}
|
|
7263
|
-
const
|
|
7264
|
-
const anyClient = client;
|
|
7265
|
-
try {
|
|
7266
|
-
return typeof anyClient.getBaseUrl === "function" ? anyClient.getBaseUrl() : "/api";
|
|
7267
|
-
} catch {
|
|
7268
|
-
return "/api";
|
|
7269
|
-
}
|
|
7270
|
-
})();
|
|
7271
|
-
const finalizeUrl = baseUrl.replace(/\/$/, "") + "/games/uploads/finalize/";
|
|
7334
|
+
const finalizeUrl = `${client.baseUrl}/games/uploads/finalize/`;
|
|
7272
7335
|
const authToken = client.getToken();
|
|
7273
7336
|
const tokenType = client.getTokenType();
|
|
7274
7337
|
const headers = {
|
|
@@ -8746,13 +8809,13 @@ var init_achievements = () => {
|
|
|
8746
8809
|
function createTimebackNamespace(client) {
|
|
8747
8810
|
return {
|
|
8748
8811
|
recordProgress: (progressData) => {
|
|
8749
|
-
return client["
|
|
8812
|
+
return client["requestGameBackend"]("/api/integrations/timeback/progress", "POST", { progressData });
|
|
8750
8813
|
},
|
|
8751
8814
|
recordSessionEnd: (sessionData) => {
|
|
8752
|
-
return client["
|
|
8815
|
+
return client["requestGameBackend"]("/api/integrations/timeback/session-end", "POST", { sessionData });
|
|
8753
8816
|
},
|
|
8754
8817
|
awardXP: (xpAmount, metadata) => {
|
|
8755
|
-
return client["
|
|
8818
|
+
return client["requestGameBackend"]("/api/integrations/timeback/award-xp", "POST", { xpAmount, metadata });
|
|
8756
8819
|
},
|
|
8757
8820
|
management: {
|
|
8758
8821
|
setup: (request2) => {
|
|
@@ -9061,7 +9124,7 @@ var init_client = __esm2(() => {
|
|
|
9061
9124
|
authContext;
|
|
9062
9125
|
initPayload;
|
|
9063
9126
|
constructor(config) {
|
|
9064
|
-
this.baseUrl = config?.baseUrl
|
|
9127
|
+
this.baseUrl = config?.baseUrl?.endsWith("/api") ? config.baseUrl : `${config?.baseUrl}/api`;
|
|
9065
9128
|
this.gameUrl = config?.gameUrl;
|
|
9066
9129
|
this.gameId = config?.gameId;
|
|
9067
9130
|
this.config = config || {};
|
|
@@ -9077,8 +9140,9 @@ var init_client = __esm2(() => {
|
|
|
9077
9140
|
return `${effectiveBaseUrl}/api`;
|
|
9078
9141
|
}
|
|
9079
9142
|
getGameBackendUrl() {
|
|
9080
|
-
if (!this.gameUrl)
|
|
9081
|
-
|
|
9143
|
+
if (!this.gameUrl) {
|
|
9144
|
+
throw new PlaycademyError("Game backend URL not configured. gameUrl must be set to use game backend features.");
|
|
9145
|
+
}
|
|
9082
9146
|
const isRelative = this.gameUrl.startsWith("/");
|
|
9083
9147
|
const isBrowser2 = typeof window !== "undefined";
|
|
9084
9148
|
const effectiveGameUrl = isRelative && isBrowser2 ? `${window.location.origin}${this.gameUrl}` : this.gameUrl;
|
|
@@ -9115,17 +9179,29 @@ var init_client = __esm2(() => {
|
|
|
9115
9179
|
listener(payload);
|
|
9116
9180
|
});
|
|
9117
9181
|
}
|
|
9118
|
-
async request(path, method, body, headers
|
|
9182
|
+
async request(path, method, body, headers) {
|
|
9183
|
+
const effectiveHeaders = {
|
|
9184
|
+
...headers,
|
|
9185
|
+
...this.authStrategy.getHeaders()
|
|
9186
|
+
};
|
|
9187
|
+
return request({
|
|
9188
|
+
path,
|
|
9189
|
+
method,
|
|
9190
|
+
body,
|
|
9191
|
+
baseUrl: this.baseUrl,
|
|
9192
|
+
extraHeaders: effectiveHeaders
|
|
9193
|
+
});
|
|
9194
|
+
}
|
|
9195
|
+
async requestGameBackend(path, method, body, headers) {
|
|
9119
9196
|
const effectiveHeaders = {
|
|
9120
9197
|
...headers,
|
|
9121
9198
|
...this.authStrategy.getHeaders()
|
|
9122
9199
|
};
|
|
9123
|
-
const targetBaseUrl = useGameBackend ? this.getGameBackendUrl() : this.baseUrl;
|
|
9124
9200
|
return request({
|
|
9125
9201
|
path,
|
|
9126
9202
|
method,
|
|
9127
9203
|
body,
|
|
9128
|
-
baseUrl:
|
|
9204
|
+
baseUrl: this.getGameBackendUrl(),
|
|
9129
9205
|
extraHeaders: effectiveHeaders
|
|
9130
9206
|
});
|
|
9131
9207
|
}
|
|
@@ -9204,9 +9280,40 @@ function customTransform(text2) {
|
|
|
9204
9280
|
const highlightCode = (text3) => text3.replace(/`([^`]+)`/g, (_, code) => greenBright(code));
|
|
9205
9281
|
return highlightCode(text2);
|
|
9206
9282
|
}
|
|
9283
|
+
function formatTable(data, title) {
|
|
9284
|
+
if (data.length === 0) return;
|
|
9285
|
+
const keys = Object.keys(data[0]);
|
|
9286
|
+
const rows = data.map((item) => keys.map((key) => String(item[key] ?? "")));
|
|
9287
|
+
const widths = keys.map((key, i) => {
|
|
9288
|
+
const headerWidth = key.length;
|
|
9289
|
+
const dataWidth = Math.max(...rows.map((row) => row[i].length));
|
|
9290
|
+
return Math.max(headerWidth, dataWidth);
|
|
9291
|
+
});
|
|
9292
|
+
const totalWidth = widths.reduce((sum, w) => sum + w + 3, -1);
|
|
9293
|
+
const separator = "\u251C" + widths.map((w) => "\u2500".repeat(w + 2)).join("\u253C") + "\u2524";
|
|
9294
|
+
const topBorder = "\u250C" + "\u2500".repeat(totalWidth) + "\u2510";
|
|
9295
|
+
const titleSeparator = "\u251C" + widths.map((w) => "\u2500".repeat(w + 2)).join("\u252C") + "\u2524";
|
|
9296
|
+
const bottomBorder = "\u2514" + widths.map((w) => "\u2500".repeat(w + 2)).join("\u2534") + "\u2518";
|
|
9297
|
+
console.log(topBorder);
|
|
9298
|
+
if (title) {
|
|
9299
|
+
const titleText = bold(title);
|
|
9300
|
+
const titlePadding = totalWidth - title.length - 1;
|
|
9301
|
+
const titleRow = "\u2502 " + titleText + " ".repeat(titlePadding) + "\u2502";
|
|
9302
|
+
console.log(titleRow);
|
|
9303
|
+
console.log(titleSeparator);
|
|
9304
|
+
}
|
|
9305
|
+
const header = "\u2502 " + keys.map((key, i) => key.padEnd(widths[i])).join(" \u2502 ") + " \u2502";
|
|
9306
|
+
console.log(header);
|
|
9307
|
+
console.log(separator);
|
|
9308
|
+
rows.forEach((row) => {
|
|
9309
|
+
const dataRow = "\u2502 " + row.map((cell, i) => cell.padEnd(widths[i])).join(" \u2502 ") + " \u2502";
|
|
9310
|
+
console.log(dataRow);
|
|
9311
|
+
});
|
|
9312
|
+
console.log(bottomBorder);
|
|
9313
|
+
}
|
|
9207
9314
|
var logger = {
|
|
9208
|
-
table: (data) => {
|
|
9209
|
-
|
|
9315
|
+
table: (data, title) => {
|
|
9316
|
+
formatTable(data, title);
|
|
9210
9317
|
},
|
|
9211
9318
|
/**
|
|
9212
9319
|
* Info message - general information
|
|
@@ -9362,9 +9469,8 @@ var logger = {
|
|
|
9362
9469
|
async function createClient() {
|
|
9363
9470
|
const profile = await getCurrentProfile();
|
|
9364
9471
|
const baseUrl = getBaseUrl();
|
|
9365
|
-
const apiBaseUrl = `${baseUrl}/api`;
|
|
9366
9472
|
const client = new PlaycademyClient({
|
|
9367
|
-
baseUrl
|
|
9473
|
+
baseUrl,
|
|
9368
9474
|
token: profile?.token
|
|
9369
9475
|
});
|
|
9370
9476
|
if (profile?.token && profile?.tokenType) {
|
|
@@ -9374,11 +9480,12 @@ async function createClient() {
|
|
|
9374
9480
|
}
|
|
9375
9481
|
async function requireAuthenticatedClient() {
|
|
9376
9482
|
const profile = await getCurrentProfile();
|
|
9483
|
+
const environment = getEnvironment();
|
|
9377
9484
|
if (!profile) {
|
|
9378
9485
|
logger.newLine();
|
|
9379
9486
|
logger.admonition("warning", "Login Required", [
|
|
9380
|
-
|
|
9381
|
-
"Run `playcademy login` to authenticate."
|
|
9487
|
+
`You are not logged into ${environment}.`,
|
|
9488
|
+
environment === "production" ? `Run \`playcademy login --env ${environment}\` to authenticate.` : "Run `playcademy login` to authenticate."
|
|
9382
9489
|
]);
|
|
9383
9490
|
logger.newLine();
|
|
9384
9491
|
process.exit(1);
|
|
@@ -10238,16 +10345,25 @@ async function validateDeployConfig(config) {
|
|
|
10238
10345
|
// src/lib/deploy/interaction.ts
|
|
10239
10346
|
async function selectEnvironment(options) {
|
|
10240
10347
|
let environment = options.env;
|
|
10241
|
-
|
|
10242
|
-
|
|
10348
|
+
if (environment || process.env.PLAYCADEMY_ENV || process.env.PLAYCADEMY_BASE_URL) {
|
|
10349
|
+
if (environment) {
|
|
10350
|
+
setCliContext({ environment });
|
|
10351
|
+
}
|
|
10352
|
+
return;
|
|
10353
|
+
}
|
|
10354
|
+
const authenticatedEnvs = await getAuthenticatedEnvironments();
|
|
10355
|
+
if (authenticatedEnvs.length === 1) {
|
|
10356
|
+
environment = authenticatedEnvs[0];
|
|
10357
|
+
logger.info(`Deploying to ${environment}`, 1);
|
|
10358
|
+
} else if (authenticatedEnvs.length === 2 && !options.dryRun) {
|
|
10243
10359
|
logger.newLine();
|
|
10244
10360
|
environment = await select({
|
|
10245
10361
|
message: "Select deployment environment:",
|
|
10246
10362
|
choices: [
|
|
10247
|
-
{ value: "
|
|
10248
|
-
{ value: "
|
|
10363
|
+
{ value: "staging", name: "Staging (hub.dev.playcademy.net)" },
|
|
10364
|
+
{ value: "production", name: "Production (hub.playcademy.com)" }
|
|
10249
10365
|
],
|
|
10250
|
-
default: "
|
|
10366
|
+
default: "staging"
|
|
10251
10367
|
});
|
|
10252
10368
|
}
|
|
10253
10369
|
if (environment) {
|
|
@@ -10395,10 +10511,12 @@ function displayCurrentConfiguration(context2) {
|
|
|
10395
10511
|
} else if (config.externalUrl) {
|
|
10396
10512
|
logger.data("URL", config.externalUrl, 1);
|
|
10397
10513
|
}
|
|
10398
|
-
if (
|
|
10514
|
+
if (context2.isGameDeployed) {
|
|
10399
10515
|
logger.data("Status", "Deployed", 1);
|
|
10400
|
-
} else {
|
|
10516
|
+
} else if (existingGame) {
|
|
10401
10517
|
logger.data("Status", "Not deployed", 1);
|
|
10518
|
+
} else {
|
|
10519
|
+
logger.data("Status", "New deployment", 1);
|
|
10402
10520
|
}
|
|
10403
10521
|
logger.newLine();
|
|
10404
10522
|
}
|
|
@@ -10427,14 +10545,15 @@ async function reportNoChanges(context2) {
|
|
|
10427
10545
|
function reportDeploymentSuccess(result, context2) {
|
|
10428
10546
|
const { game, backendDeployment } = result;
|
|
10429
10547
|
const { client, previousBackendHash } = context2;
|
|
10430
|
-
const action = context2.
|
|
10548
|
+
const action = context2.isGameDeployed ? "updated" : "deployed";
|
|
10431
10549
|
logger.newLine();
|
|
10432
10550
|
logger.success(`${game.displayName} ${action} successfully!`);
|
|
10433
10551
|
logger.newLine();
|
|
10434
10552
|
const baseUrl = getWebBaseUrl(client.getBaseUrl());
|
|
10435
10553
|
logger.data("Game URL", underline(blueBright(`${baseUrl}/g/${game.slug}`)), 1);
|
|
10436
10554
|
if (backendDeployment || previousBackendHash) {
|
|
10437
|
-
const
|
|
10555
|
+
const gameDomain = GAME_BACKEND_DOMAINS[getEnvironment()];
|
|
10556
|
+
const backendUrl = `https://${game.slug}.${gameDomain}/api`;
|
|
10438
10557
|
logger.data("Backend API", underline(blueBright(backendUrl)), 1);
|
|
10439
10558
|
}
|
|
10440
10559
|
if (game.version !== "external") {
|
|
@@ -10458,10 +10577,10 @@ import { stat as stat2 } from "node:fs/promises";
|
|
|
10458
10577
|
|
|
10459
10578
|
// ../data/src/domains/game/helpers.ts
|
|
10460
10579
|
var isHostedGame = (game) => {
|
|
10461
|
-
return game.gameType === "hosted" && game.assetBundleBase
|
|
10580
|
+
return game.gameType === "hosted" && !!game.assetBundleBase;
|
|
10462
10581
|
};
|
|
10463
10582
|
var isExternalGame = (game) => {
|
|
10464
|
-
return game.gameType === "external" && game.externalUrl
|
|
10583
|
+
return game.gameType === "external" && !!game.externalUrl;
|
|
10465
10584
|
};
|
|
10466
10585
|
function isGameDeployed(game) {
|
|
10467
10586
|
return isHostedGame(game) || isExternalGame(game);
|
|
@@ -10527,9 +10646,9 @@ async function prepareDeploymentContext(options) {
|
|
|
10527
10646
|
configFileName,
|
|
10528
10647
|
client,
|
|
10529
10648
|
projectPath,
|
|
10530
|
-
existingGame
|
|
10649
|
+
existingGame,
|
|
10531
10650
|
deployedGameInfo: deployedGameInfo ?? void 0,
|
|
10532
|
-
|
|
10651
|
+
isGameDeployed: gameIsDeployed,
|
|
10533
10652
|
buildHash,
|
|
10534
10653
|
buildSize,
|
|
10535
10654
|
previousBuildHash: deployedGameInfo?.buildHash,
|
|
@@ -10579,8 +10698,8 @@ async function analyzeChanges(context2) {
|
|
|
10579
10698
|
};
|
|
10580
10699
|
}
|
|
10581
10700
|
async function calculateDeploymentPlan(context2, changes) {
|
|
10582
|
-
const { config,
|
|
10583
|
-
if (
|
|
10701
|
+
const { config, isGameDeployed: isGameDeployed2, projectPath, deployBackend } = context2;
|
|
10702
|
+
if (!isGameDeployed2) {
|
|
10584
10703
|
const needsBackend3 = hasLocalBackend(projectPath) || !!context2.fullConfig?.integrations;
|
|
10585
10704
|
const shouldDeployBackend2 = deployBackend && needsBackend3;
|
|
10586
10705
|
return {
|
|
@@ -11435,19 +11554,28 @@ initCommand.addCommand(configCommand);
|
|
|
11435
11554
|
|
|
11436
11555
|
// src/commands/login.ts
|
|
11437
11556
|
import { input as input4, password, select as select3 } from "@inquirer/prompts";
|
|
11557
|
+
import { bold as bold4, dim as dim6, whiteBright } from "colorette";
|
|
11438
11558
|
import { Command as Command4 } from "commander";
|
|
11439
11559
|
import open from "open";
|
|
11440
11560
|
init_file_loader();
|
|
11441
|
-
var loginCommand = new Command4("login").description("Authenticate with Playcademy").option("-e, --email <email>", "Email address (for email/password auth)").option("-p, --password <password>", "Password (for email/password auth)").option("--sso", "Use Timeback SSO authentication").action(async (options) => {
|
|
11442
|
-
const { email, password: password2, sso } = options;
|
|
11443
|
-
logger
|
|
11561
|
+
var loginCommand = new Command4("login").description("Authenticate with Playcademy").option("-e, --email <email>", "Email address (for email/password auth)").option("-p, --password <password>", "Password (for email/password auth)").option("--sso", "Use Timeback SSO authentication").option("--env <environment>", "Environment to login to (staging or production)").action(async (options) => {
|
|
11562
|
+
const { email, password: password2, sso, env } = options;
|
|
11563
|
+
const environment = ensureEnvironment(env, logger);
|
|
11444
11564
|
const profileName = getProfileName();
|
|
11445
|
-
|
|
11565
|
+
logger.newLine();
|
|
11566
|
+
const existingProfile = await getProfile(environment, profileName);
|
|
11446
11567
|
if (existingProfile) {
|
|
11447
|
-
const email2 = existingProfile.email;
|
|
11448
|
-
|
|
11449
|
-
|
|
11450
|
-
|
|
11568
|
+
const email2 = existingProfile.email || "unknown user";
|
|
11569
|
+
const otherEnv = environment === "staging" ? "production" : "staging";
|
|
11570
|
+
const otherProfile = await getProfile(otherEnv, profileName);
|
|
11571
|
+
logger.admonition("note", "Hello again", [
|
|
11572
|
+
bold4("You're already logged in"),
|
|
11573
|
+
"",
|
|
11574
|
+
dim6("Email: ") + bold4(email2),
|
|
11575
|
+
dim6("Environment: ") + bold4(environment),
|
|
11576
|
+
dim6("Profile: ") + bold4(profileName),
|
|
11577
|
+
...otherProfile ? [dim6("Other Profile: ") + bold4(otherEnv)] : []
|
|
11578
|
+
]);
|
|
11451
11579
|
logger.newLine();
|
|
11452
11580
|
return;
|
|
11453
11581
|
}
|
|
@@ -11462,7 +11590,7 @@ var loginCommand = new Command4("login").description("Authenticate with Playcade
|
|
|
11462
11590
|
});
|
|
11463
11591
|
logger.newLine();
|
|
11464
11592
|
if (authMethod === "sso") {
|
|
11465
|
-
await handleSsoLogin(profileName);
|
|
11593
|
+
await handleSsoLogin(environment, profileName);
|
|
11466
11594
|
return;
|
|
11467
11595
|
}
|
|
11468
11596
|
const finalEmail = email || await promptForEmail();
|
|
@@ -11515,14 +11643,17 @@ var loginCommand = new Command4("login").description("Authenticate with Playcade
|
|
|
11515
11643
|
logger.newLine();
|
|
11516
11644
|
await runStep(
|
|
11517
11645
|
`Saving credentials to profile "${profileName}"`,
|
|
11518
|
-
() => saveProfile(profileName, authProfile),
|
|
11646
|
+
() => saveProfile(environment, profileName, authProfile),
|
|
11519
11647
|
"Credentials saved successfully"
|
|
11520
11648
|
);
|
|
11521
|
-
logger.
|
|
11522
|
-
|
|
11523
|
-
|
|
11524
|
-
|
|
11525
|
-
|
|
11649
|
+
logger.newLine();
|
|
11650
|
+
logger.admonition("tip", "Logged In Successfully!", [
|
|
11651
|
+
`Email: ${authProfile.email}`,
|
|
11652
|
+
`Environment: ${environment}`,
|
|
11653
|
+
...profileName !== "default" ? [`Profile: ${profileName}`] : [],
|
|
11654
|
+
"",
|
|
11655
|
+
...profileName !== "default" ? [`Use \`--profile ${profileName}\` with commands to use this profile`] : []
|
|
11656
|
+
]);
|
|
11526
11657
|
logger.newLine();
|
|
11527
11658
|
} catch (error) {
|
|
11528
11659
|
logger.newLine();
|
|
@@ -11533,7 +11664,7 @@ var loginCommand = new Command4("login").description("Authenticate with Playcade
|
|
|
11533
11664
|
process.exit(1);
|
|
11534
11665
|
}
|
|
11535
11666
|
});
|
|
11536
|
-
async function handleSsoLogin(profileName) {
|
|
11667
|
+
async function handleSsoLogin(environment, profileName) {
|
|
11537
11668
|
try {
|
|
11538
11669
|
const serverPromise = startCallbackServer(SSO_AUTH_TIMEOUT_MS);
|
|
11539
11670
|
const baseUrl = getBaseUrl();
|
|
@@ -11578,21 +11709,20 @@ async function handleSsoLogin(profileName) {
|
|
|
11578
11709
|
email: result.data.email
|
|
11579
11710
|
};
|
|
11580
11711
|
logger.newLine();
|
|
11581
|
-
logger.admonition("warning", "Your API Key", [
|
|
11582
|
-
|
|
11712
|
+
logger.admonition("warning", "Your API Key", [
|
|
11713
|
+
"",
|
|
11714
|
+
whiteBright(bold4(apiKeyResult.apiKey)),
|
|
11715
|
+
"",
|
|
11716
|
+
"Save this key securely - it will not be shown again!"
|
|
11717
|
+
]);
|
|
11583
11718
|
logger.newLine();
|
|
11584
11719
|
await runStep(
|
|
11585
11720
|
`Saving credentials to profile "${profileName}"`,
|
|
11586
|
-
() => saveProfile(profileName, authProfile),
|
|
11587
|
-
"Credentials saved successfully"
|
|
11721
|
+
() => saveProfile(environment, profileName, authProfile),
|
|
11722
|
+
"Credentials saved successfully",
|
|
11723
|
+
{ silent: true }
|
|
11588
11724
|
);
|
|
11589
|
-
logger.success(`Logged in as ${authProfile.email}`);
|
|
11590
|
-
if (profileName !== "default") {
|
|
11591
|
-
logger.newLine();
|
|
11592
|
-
logger.info(`Profile saved as "${profileName}"`);
|
|
11593
|
-
logger.newLine();
|
|
11594
|
-
logger.aside(`Use \`--profile ${profileName}\` with commands to use this profile`, 1);
|
|
11595
|
-
}
|
|
11725
|
+
logger.success(`Logged in to ${environment} as ${authProfile.email}`);
|
|
11596
11726
|
logger.newLine();
|
|
11597
11727
|
} catch (error) {
|
|
11598
11728
|
logger.newLine();
|
|
@@ -11631,27 +11761,23 @@ async function promptForPassword() {
|
|
|
11631
11761
|
|
|
11632
11762
|
// src/commands/logout.ts
|
|
11633
11763
|
import { Command as Command5 } from "commander";
|
|
11634
|
-
var logoutCommand = new Command5("logout").description("Log out from Playcademy").
|
|
11635
|
-
const {
|
|
11764
|
+
var logoutCommand = new Command5("logout").description("Log out from Playcademy").argument("[profile]", "Profile name to logout from", "default").option("--env <environment>", "Environment to logout from (staging or production)").action(async (profileName, options) => {
|
|
11765
|
+
const { env } = options;
|
|
11766
|
+
const environment = ensureEnvironment(env, logger);
|
|
11636
11767
|
try {
|
|
11637
11768
|
logger.newLine();
|
|
11638
|
-
const profile = await getProfile(profileName);
|
|
11769
|
+
const profile = await getProfile(environment, profileName);
|
|
11639
11770
|
if (!profile) {
|
|
11640
|
-
logger.error(`Profile "${profileName}" not found`);
|
|
11771
|
+
logger.error(`Profile "${profileName}" not found in ${environment}`);
|
|
11772
|
+
logger.newLine();
|
|
11641
11773
|
logger.info("Use `playcademy profiles list` to see available profiles");
|
|
11642
11774
|
logger.newLine();
|
|
11643
11775
|
process.exit(1);
|
|
11644
11776
|
}
|
|
11645
|
-
await removeProfile(profileName);
|
|
11646
|
-
logger.success(
|
|
11647
|
-
|
|
11648
|
-
|
|
11649
|
-
}
|
|
11650
|
-
if (profileName === "default") {
|
|
11651
|
-
logger.info("To log in again: playcademy login");
|
|
11652
|
-
} else {
|
|
11653
|
-
logger.info(`To log in again: playcademy login --profile ${profileName}`);
|
|
11654
|
-
}
|
|
11777
|
+
await removeProfile(environment, profileName);
|
|
11778
|
+
logger.success(
|
|
11779
|
+
`Logged out from ${environment} profile "${profileName}" (${profile.email})`
|
|
11780
|
+
);
|
|
11655
11781
|
logger.newLine();
|
|
11656
11782
|
} catch (error) {
|
|
11657
11783
|
logger.newLine();
|
|
@@ -11665,18 +11791,24 @@ var logoutCommand = new Command5("logout").description("Log out from Playcademy"
|
|
|
11665
11791
|
|
|
11666
11792
|
// src/commands/me.ts
|
|
11667
11793
|
import { Command as Command6 } from "commander";
|
|
11668
|
-
var meCommand = new Command6("me").description("Display current user information").
|
|
11794
|
+
var meCommand = new Command6("me").description("Display current user information").option(
|
|
11795
|
+
"--env <environment>",
|
|
11796
|
+
"Environment to check user information from (staging or production)"
|
|
11797
|
+
).action(async (options) => {
|
|
11798
|
+
const { env } = options;
|
|
11669
11799
|
try {
|
|
11800
|
+
const environment = ensureEnvironment(env, logger);
|
|
11670
11801
|
const client = await requireAuthenticatedClient();
|
|
11671
11802
|
logger.newLine();
|
|
11672
11803
|
const user = await runStep(
|
|
11673
|
-
|
|
11804
|
+
`Fetching user information from ${environment}`,
|
|
11674
11805
|
client.users.me,
|
|
11675
11806
|
"User information retrieved"
|
|
11676
11807
|
);
|
|
11677
11808
|
logger.newLine();
|
|
11678
11809
|
logger.data("ID", user.id, 1);
|
|
11679
11810
|
logger.data("Email", user.email, 1);
|
|
11811
|
+
logger.data("Environment", environment, 1);
|
|
11680
11812
|
if (user.username) {
|
|
11681
11813
|
logger.data("Username", user.username, 1);
|
|
11682
11814
|
}
|
|
@@ -11724,7 +11856,8 @@ async function executeDeployment(plan, context2) {
|
|
|
11724
11856
|
return { game, backendDeployment };
|
|
11725
11857
|
}
|
|
11726
11858
|
async function runDeployment(options) {
|
|
11727
|
-
|
|
11859
|
+
const environment = ensureEnvironment(options.env, logger);
|
|
11860
|
+
await selectEnvironment({ env: environment, dryRun: options.dryRun });
|
|
11728
11861
|
const context2 = await prepareDeploymentContext(options);
|
|
11729
11862
|
displayCurrentConfiguration(context2);
|
|
11730
11863
|
const didPrompt = await promptForMissingConfig(context2);
|
|
@@ -11789,17 +11922,19 @@ import { Command as Command10 } from "commander";
|
|
|
11789
11922
|
// src/commands/games/delete.ts
|
|
11790
11923
|
import { confirm as confirm5, input as input5, select as select4 } from "@inquirer/prompts";
|
|
11791
11924
|
import { Command as Command8 } from "commander";
|
|
11792
|
-
var deleteCommand = new Command8("delete").alias("rm").alias("remove").description("Delete a game").argument("[slug]", "Game slug to delete").option("-f, --force", "Skip confirmation prompt").action(async (slug, options) => {
|
|
11925
|
+
var deleteCommand = new Command8("delete").alias("rm").alias("remove").description("Delete a game").argument("[slug]", "Game slug to delete").option("-f, --force", "Skip confirmation prompt").option("--env <environment>", "Environment to delete game from (staging or production)").action(async (slug, options) => {
|
|
11926
|
+
const { env } = options;
|
|
11793
11927
|
try {
|
|
11794
|
-
logger
|
|
11928
|
+
const environment = ensureEnvironment(env, logger);
|
|
11795
11929
|
const client = await requireAuthenticatedClient();
|
|
11930
|
+
logger.newLine();
|
|
11796
11931
|
const games2 = await runStep(
|
|
11797
|
-
|
|
11932
|
+
`Fetching games from ${environment}`,
|
|
11798
11933
|
client.games.list,
|
|
11799
|
-
(games3) => `Found ${games3.length} game${games3.length === 1 ? "" : "s"}`
|
|
11934
|
+
(games3) => `Found ${games3.length} game${games3.length === 1 ? "" : "s"} in ${environment}`
|
|
11800
11935
|
);
|
|
11801
11936
|
if (games2.length === 0) {
|
|
11802
|
-
logger.info(
|
|
11937
|
+
logger.info(`No games found in ${environment}`);
|
|
11803
11938
|
return;
|
|
11804
11939
|
}
|
|
11805
11940
|
logger.newLine();
|
|
@@ -11847,11 +11982,11 @@ var deleteCommand = new Command8("delete").alias("rm").alias("remove").descripti
|
|
|
11847
11982
|
logger.newLine();
|
|
11848
11983
|
}
|
|
11849
11984
|
await runStep(
|
|
11850
|
-
|
|
11985
|
+
`Deleting game from ${environment}`,
|
|
11851
11986
|
async () => {
|
|
11852
11987
|
await client.dev.games.delete(game.id);
|
|
11853
11988
|
},
|
|
11854
|
-
|
|
11989
|
+
`Game deleted successfully from ${environment}`
|
|
11855
11990
|
);
|
|
11856
11991
|
const deployedGame = await getDeployedGame(getWorkspace());
|
|
11857
11992
|
if (deployedGame && deployedGame.gameId === game.id) {
|
|
@@ -11870,14 +12005,16 @@ var deleteCommand = new Command8("delete").alias("rm").alias("remove").descripti
|
|
|
11870
12005
|
|
|
11871
12006
|
// src/commands/games/list.ts
|
|
11872
12007
|
import { Command as Command9 } from "commander";
|
|
11873
|
-
var listCommand = new Command9("list").alias("ls").description("List all games").action(async () => {
|
|
12008
|
+
var listCommand = new Command9("list").alias("ls").description("List all games").option("--env <environment>", "Environment to list games from (staging or production)").action(async (options) => {
|
|
12009
|
+
const { env } = options;
|
|
11874
12010
|
try {
|
|
12011
|
+
const environment = ensureEnvironment(env, logger);
|
|
11875
12012
|
const client = await requireAuthenticatedClient();
|
|
11876
12013
|
logger.newLine();
|
|
11877
12014
|
const games2 = await runStep(
|
|
11878
|
-
|
|
12015
|
+
`Fetching games from ${environment}`,
|
|
11879
12016
|
client.games.list,
|
|
11880
|
-
(games3) => `Found ${games3.length} game${games3.length === 1 ? "" : "s"}`
|
|
12017
|
+
(games3) => `Found ${games3.length} game${games3.length === 1 ? "" : "s"} in ${environment}`
|
|
11881
12018
|
);
|
|
11882
12019
|
if (games2.length === 0) {
|
|
11883
12020
|
logger.info("No games found");
|
|
@@ -11916,22 +12053,30 @@ import { Command as Command13 } from "commander";
|
|
|
11916
12053
|
|
|
11917
12054
|
// src/commands/dev/apply.ts
|
|
11918
12055
|
import { Command as Command11 } from "commander";
|
|
11919
|
-
var applyCommand = new Command11("apply").description("Apply for developer status").
|
|
12056
|
+
var applyCommand = new Command11("apply").description("Apply for developer status").option(
|
|
12057
|
+
"--env <environment>",
|
|
12058
|
+
"Environment to apply for developer status in (staging or production)"
|
|
12059
|
+
).action(async (options) => {
|
|
12060
|
+
const { env } = options;
|
|
11920
12061
|
try {
|
|
11921
|
-
logger
|
|
12062
|
+
const environment = ensureEnvironment(env, logger);
|
|
11922
12063
|
const client = await requireAuthenticatedClient();
|
|
12064
|
+
logger.newLine();
|
|
11923
12065
|
const currentStatus = await runStep(
|
|
11924
|
-
|
|
12066
|
+
`Checking current developer status in ${environment}`,
|
|
11925
12067
|
client.dev.status.get,
|
|
11926
|
-
|
|
12068
|
+
`Current status retrieved from ${environment}`
|
|
11927
12069
|
);
|
|
12070
|
+
logger.newLine();
|
|
11928
12071
|
if (currentStatus === "approved") {
|
|
11929
|
-
logger.
|
|
12072
|
+
logger.admonition("note", "Approved!", ["You are already an approved developer!"]);
|
|
11930
12073
|
logger.newLine();
|
|
11931
12074
|
return;
|
|
11932
12075
|
}
|
|
11933
12076
|
if (currentStatus === "pending") {
|
|
11934
|
-
logger.
|
|
12077
|
+
logger.admonition("warning", "Developer Status", [
|
|
12078
|
+
"Your developer application is pending review"
|
|
12079
|
+
]);
|
|
11935
12080
|
logger.newLine();
|
|
11936
12081
|
return;
|
|
11937
12082
|
}
|
|
@@ -11941,14 +12086,15 @@ var applyCommand = new Command11("apply").description("Apply for developer statu
|
|
|
11941
12086
|
"Developer application submitted successfully"
|
|
11942
12087
|
);
|
|
11943
12088
|
logger.newLine();
|
|
11944
|
-
logger.
|
|
11945
|
-
|
|
11946
|
-
|
|
11947
|
-
|
|
11948
|
-
|
|
12089
|
+
logger.admonition("tip", "Application Submitted!", [
|
|
12090
|
+
"Your developer application has been submitted.",
|
|
12091
|
+
"",
|
|
12092
|
+
"What happens next:",
|
|
12093
|
+
" \u2022 We will review your application shortly",
|
|
12094
|
+
" \u2022 Once approved, you can create and deploy games"
|
|
12095
|
+
]);
|
|
11949
12096
|
logger.newLine();
|
|
11950
12097
|
} catch (error) {
|
|
11951
|
-
logger.newLine();
|
|
11952
12098
|
logger.error(
|
|
11953
12099
|
`Failed to apply for developer status: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
11954
12100
|
);
|
|
@@ -11959,31 +12105,37 @@ var applyCommand = new Command11("apply").description("Apply for developer statu
|
|
|
11959
12105
|
|
|
11960
12106
|
// src/commands/dev/get-status.ts
|
|
11961
12107
|
import { Command as Command12 } from "commander";
|
|
11962
|
-
var getStatusCommand = new Command12("status").description("Check your developer status").
|
|
12108
|
+
var getStatusCommand = new Command12("status").description("Check your developer status").option(
|
|
12109
|
+
"--env <environment>",
|
|
12110
|
+
"Environment to check developer status from (staging or production)"
|
|
12111
|
+
).action(async (options) => {
|
|
12112
|
+
const { env } = options;
|
|
11963
12113
|
try {
|
|
11964
|
-
logger
|
|
12114
|
+
const environment = ensureEnvironment(env, logger);
|
|
11965
12115
|
const client = await requireAuthenticatedClient();
|
|
12116
|
+
logger.newLine();
|
|
11966
12117
|
const status = await runStep(
|
|
11967
|
-
|
|
12118
|
+
`Fetching developer status from ${environment}`,
|
|
11968
12119
|
() => client.dev.status.get(),
|
|
11969
|
-
|
|
12120
|
+
`Developer status retrieved from ${environment}`
|
|
11970
12121
|
);
|
|
11971
|
-
logger.newLine();
|
|
11972
|
-
logger.highlight("Developer Status");
|
|
11973
|
-
logger.data("Status", status, 1);
|
|
11974
12122
|
switch (status) {
|
|
11975
12123
|
case "none":
|
|
11976
12124
|
logger.newLine();
|
|
11977
|
-
logger.
|
|
11978
|
-
|
|
12125
|
+
logger.admonition("warning", "Become a Developer", [
|
|
12126
|
+
"Want to create and deploy games?",
|
|
12127
|
+
"Run `playcademy dev apply` to apply for developer status"
|
|
12128
|
+
]);
|
|
11979
12129
|
break;
|
|
11980
12130
|
case "pending":
|
|
11981
12131
|
logger.newLine();
|
|
11982
|
-
logger.
|
|
12132
|
+
logger.admonition("warning", "Developer Status", [
|
|
12133
|
+
"Your application is pending review."
|
|
12134
|
+
]);
|
|
11983
12135
|
break;
|
|
11984
12136
|
case "approved":
|
|
11985
12137
|
logger.newLine();
|
|
11986
|
-
logger.
|
|
12138
|
+
logger.admonition("note", "Approved!", ["You are an approved developer!"]);
|
|
11987
12139
|
break;
|
|
11988
12140
|
default:
|
|
11989
12141
|
logger.newLine();
|
|
@@ -12069,26 +12221,39 @@ import { Command as Command17 } from "commander";
|
|
|
12069
12221
|
import { Command as Command14 } from "commander";
|
|
12070
12222
|
async function listProfilesAction() {
|
|
12071
12223
|
try {
|
|
12072
|
-
const
|
|
12224
|
+
const profilesMap = await listProfiles();
|
|
12073
12225
|
logger.newLine();
|
|
12074
|
-
|
|
12226
|
+
let hasAnyProfiles = false;
|
|
12227
|
+
for (const [, profiles] of profilesMap.entries()) {
|
|
12228
|
+
if (profiles.length > 0) {
|
|
12229
|
+
hasAnyProfiles = true;
|
|
12230
|
+
break;
|
|
12231
|
+
}
|
|
12232
|
+
}
|
|
12233
|
+
if (!hasAnyProfiles) {
|
|
12075
12234
|
logger.warn("No authentication profiles found");
|
|
12076
12235
|
logger.newLine();
|
|
12077
12236
|
logger.admonition("tip", "Getting Started", [
|
|
12078
12237
|
"Run `playcademy login` to create your first profile"
|
|
12079
12238
|
]);
|
|
12239
|
+
logger.newLine();
|
|
12080
12240
|
return;
|
|
12081
12241
|
}
|
|
12082
|
-
const
|
|
12083
|
-
|
|
12084
|
-
const
|
|
12085
|
-
|
|
12086
|
-
|
|
12087
|
-
|
|
12088
|
-
|
|
12089
|
-
|
|
12090
|
-
|
|
12091
|
-
|
|
12242
|
+
for (const [environment, profiles] of profilesMap.entries()) {
|
|
12243
|
+
if (profiles.length === 0) continue;
|
|
12244
|
+
const tableData = [];
|
|
12245
|
+
for (const profileName of profiles) {
|
|
12246
|
+
const profile = await getProfile(environment, profileName);
|
|
12247
|
+
tableData.push({
|
|
12248
|
+
Profile: profileName,
|
|
12249
|
+
Email: profile?.email ?? ""
|
|
12250
|
+
});
|
|
12251
|
+
}
|
|
12252
|
+
if (tableData.length > 0) {
|
|
12253
|
+
const envTitle = environment.charAt(0).toUpperCase() + environment.slice(1);
|
|
12254
|
+
logger.table(tableData, envTitle);
|
|
12255
|
+
logger.newLine();
|
|
12256
|
+
}
|
|
12092
12257
|
}
|
|
12093
12258
|
} catch (error) {
|
|
12094
12259
|
logger.error(
|
|
@@ -12096,28 +12261,29 @@ async function listProfilesAction() {
|
|
|
12096
12261
|
);
|
|
12097
12262
|
process.exit(1);
|
|
12098
12263
|
}
|
|
12099
|
-
logger.newLine();
|
|
12100
12264
|
}
|
|
12101
12265
|
var listCommand2 = new Command14("list").alias("ls").description("List all stored authentication profiles").action(listProfilesAction);
|
|
12102
12266
|
|
|
12103
12267
|
// src/commands/profiles/remove.ts
|
|
12268
|
+
import { bold as bold5 } from "colorette";
|
|
12104
12269
|
import { Command as Command15 } from "commander";
|
|
12105
|
-
var removeCommand = new Command15("remove
|
|
12270
|
+
var removeCommand = new Command15("remove").alias("rm").description('Remove an authentication profile (defaults to "default")').argument("[name]", "Profile name to remove", "default").option("--env <environment>", "Environment to remove profile from (staging or production)").action(async (name, options) => {
|
|
12271
|
+
const { env } = options;
|
|
12272
|
+
const environment = ensureEnvironment(env, logger);
|
|
12106
12273
|
try {
|
|
12107
12274
|
logger.newLine();
|
|
12108
|
-
const
|
|
12109
|
-
|
|
12110
|
-
|
|
12275
|
+
const profilesMap = await listProfiles();
|
|
12276
|
+
const envProfiles = profilesMap.get(environment) || [];
|
|
12277
|
+
if (!envProfiles.includes(name)) {
|
|
12278
|
+
logger.error(`Profile "${name}" not found in ${environment}`);
|
|
12111
12279
|
logger.newLine();
|
|
12112
12280
|
process.exit(1);
|
|
12113
12281
|
}
|
|
12114
|
-
await removeProfile(name);
|
|
12115
|
-
logger.
|
|
12116
|
-
|
|
12117
|
-
|
|
12118
|
-
|
|
12119
|
-
logger.info("To re-authenticate: playcademy login");
|
|
12120
|
-
}
|
|
12282
|
+
await removeProfile(environment, name);
|
|
12283
|
+
logger.admonition("note", "Removed!", [
|
|
12284
|
+
`Profile ${bold5(name)} removed from ${environment}`,
|
|
12285
|
+
environment === "production" ? `To re-authenticate run \`playcademy login --env ${environment}\`` : "To re-authenticate run `playcademy login`"
|
|
12286
|
+
]);
|
|
12121
12287
|
logger.newLine();
|
|
12122
12288
|
} catch (error) {
|
|
12123
12289
|
logger.newLine();
|
|
@@ -12132,10 +12298,16 @@ var removeCommand = new Command15("remove <name>").alias("rm").description("Remo
|
|
|
12132
12298
|
// src/commands/profiles/reset.ts
|
|
12133
12299
|
import { confirm as confirm6 } from "@inquirer/prompts";
|
|
12134
12300
|
import { Command as Command16 } from "commander";
|
|
12135
|
-
var resetCommand = new Command16("reset").description(
|
|
12301
|
+
var resetCommand = new Command16("reset").description(
|
|
12302
|
+
"Remove all authentication profiles across all environments (requires confirmation)"
|
|
12303
|
+
).alias("clear").action(async () => {
|
|
12136
12304
|
try {
|
|
12137
|
-
const
|
|
12138
|
-
|
|
12305
|
+
const profilesMap = await listProfiles();
|
|
12306
|
+
let totalProfiles = 0;
|
|
12307
|
+
for (const profiles of profilesMap.values()) {
|
|
12308
|
+
totalProfiles += profiles.length;
|
|
12309
|
+
}
|
|
12310
|
+
if (totalProfiles === 0) {
|
|
12139
12311
|
logger.newLine();
|
|
12140
12312
|
logger.warn("No authentication profiles found");
|
|
12141
12313
|
logger.newLine();
|
|
@@ -12143,14 +12315,25 @@ var resetCommand = new Command16("reset").description("Remove all authentication
|
|
|
12143
12315
|
}
|
|
12144
12316
|
logger.newLine();
|
|
12145
12317
|
logger.warn(
|
|
12146
|
-
`This will remove ${
|
|
12318
|
+
`This will remove ${totalProfiles} authentication profile${totalProfiles > 1 ? "s" : ""} across all environments:`
|
|
12147
12319
|
);
|
|
12148
12320
|
logger.newLine();
|
|
12149
|
-
for (const
|
|
12150
|
-
|
|
12151
|
-
|
|
12321
|
+
for (const [environment, profiles] of profilesMap.entries()) {
|
|
12322
|
+
if (profiles.length === 0) continue;
|
|
12323
|
+
const tableData = [];
|
|
12324
|
+
for (const profileName of profiles) {
|
|
12325
|
+
const profile = await getProfile(environment, profileName);
|
|
12326
|
+
tableData.push({
|
|
12327
|
+
Profile: profileName,
|
|
12328
|
+
Email: profile?.email ?? ""
|
|
12329
|
+
});
|
|
12330
|
+
}
|
|
12331
|
+
if (tableData.length > 0) {
|
|
12332
|
+
const envTitle = environment.charAt(0).toUpperCase() + environment.slice(1);
|
|
12333
|
+
logger.table(tableData, envTitle);
|
|
12334
|
+
logger.newLine();
|
|
12335
|
+
}
|
|
12152
12336
|
}
|
|
12153
|
-
logger.newLine();
|
|
12154
12337
|
const confirmed = await confirm6({
|
|
12155
12338
|
message: "Are you sure you want to remove all profiles?",
|
|
12156
12339
|
default: false
|
|
@@ -12160,23 +12343,27 @@ var resetCommand = new Command16("reset").description("Remove all authentication
|
|
|
12160
12343
|
return;
|
|
12161
12344
|
}
|
|
12162
12345
|
let removedCount = 0;
|
|
12163
|
-
for (const
|
|
12164
|
-
|
|
12165
|
-
|
|
12166
|
-
|
|
12167
|
-
|
|
12168
|
-
|
|
12169
|
-
|
|
12170
|
-
|
|
12171
|
-
|
|
12346
|
+
for (const [environment, profiles] of profilesMap.entries()) {
|
|
12347
|
+
for (const profileName of profiles) {
|
|
12348
|
+
try {
|
|
12349
|
+
await removeProfile(environment, profileName);
|
|
12350
|
+
removedCount++;
|
|
12351
|
+
} catch (error) {
|
|
12352
|
+
logger.newLine();
|
|
12353
|
+
logger.error(
|
|
12354
|
+
`Failed to remove profile "${profileName}" from ${environment}`
|
|
12355
|
+
);
|
|
12356
|
+
logger.error(error instanceof Error ? error.message : "Unknown error");
|
|
12357
|
+
logger.newLine();
|
|
12358
|
+
}
|
|
12172
12359
|
}
|
|
12173
12360
|
}
|
|
12174
|
-
if (removedCount ===
|
|
12361
|
+
if (removedCount === totalProfiles) {
|
|
12175
12362
|
logger.success(
|
|
12176
12363
|
`${removedCount > 1 ? "All " : ""}${removedCount} profile${removedCount > 1 ? "s" : ""} removed successfully`
|
|
12177
12364
|
);
|
|
12178
12365
|
} else {
|
|
12179
|
-
logger.warn(`Removed ${removedCount} of ${
|
|
12366
|
+
logger.warn(`Removed ${removedCount} of ${totalProfiles} profiles`);
|
|
12180
12367
|
}
|
|
12181
12368
|
logger.newLine();
|
|
12182
12369
|
} catch (error) {
|
|
@@ -12201,13 +12388,18 @@ import { Command as Command22 } from "commander";
|
|
|
12201
12388
|
// src/commands/timeback/cleanup.ts
|
|
12202
12389
|
import { confirm as confirm7 } from "@inquirer/prompts";
|
|
12203
12390
|
import { Command as Command18 } from "commander";
|
|
12204
|
-
var cleanupCommand = new Command18("cleanup").description("Remove TimeBack integration for your game").
|
|
12391
|
+
var cleanupCommand = new Command18("cleanup").description("Remove TimeBack integration for your game").option(
|
|
12392
|
+
"--env <environment>",
|
|
12393
|
+
"Environment to remove TimeBack integration from (staging or production)"
|
|
12394
|
+
).action(async (options) => {
|
|
12395
|
+
const { env } = options;
|
|
12205
12396
|
try {
|
|
12206
|
-
logger
|
|
12397
|
+
const environment = ensureEnvironment(env, logger);
|
|
12207
12398
|
const client = await requireAuthenticatedClient();
|
|
12399
|
+
logger.newLine();
|
|
12208
12400
|
const { game } = await getGameFromConfig(client);
|
|
12209
12401
|
const integration = await runStep(
|
|
12210
|
-
|
|
12402
|
+
`Checking for TimeBack integration in ${environment}`,
|
|
12211
12403
|
() => client.timeback.management.get(game.id),
|
|
12212
12404
|
"Integration status checked"
|
|
12213
12405
|
);
|
|
@@ -12230,9 +12422,9 @@ var cleanupCommand = new Command18("cleanup").description("Remove TimeBack integ
|
|
|
12230
12422
|
}
|
|
12231
12423
|
logger.newLine();
|
|
12232
12424
|
await runStep(
|
|
12233
|
-
|
|
12425
|
+
`Removing TimeBack integration from ${environment}`,
|
|
12234
12426
|
() => client.timeback.management.cleanup(game.id),
|
|
12235
|
-
|
|
12427
|
+
`TimeBack integration removed from ${environment}`
|
|
12236
12428
|
);
|
|
12237
12429
|
logger.newLine();
|
|
12238
12430
|
logger.admonition("note", "Note", [
|
|
@@ -12251,8 +12443,13 @@ var cleanupCommand = new Command18("cleanup").description("Remove TimeBack integ
|
|
|
12251
12443
|
// src/commands/timeback/setup.ts
|
|
12252
12444
|
import { Command as Command19 } from "commander";
|
|
12253
12445
|
import dedent from "dedent";
|
|
12254
|
-
var setupCommand = new Command19("setup").description("Set up TimeBack integration for your game").option("--dry-run", "Validate configuration without creating resources").option("--verbose, -v", "Output detailed information").
|
|
12446
|
+
var setupCommand = new Command19("setup").description("Set up TimeBack integration for your game").option("--dry-run", "Validate configuration without creating resources").option("--verbose, -v", "Output detailed information").option(
|
|
12447
|
+
"--env <environment>",
|
|
12448
|
+
"Environment to set up TimeBack integration in (staging or production)"
|
|
12449
|
+
).action(async (options) => {
|
|
12450
|
+
const { env } = options;
|
|
12255
12451
|
try {
|
|
12452
|
+
ensureEnvironment(env, logger);
|
|
12256
12453
|
logger.newLine();
|
|
12257
12454
|
const config = await runStep(
|
|
12258
12455
|
"Loading configuration",
|
|
@@ -12354,8 +12551,13 @@ var setupCommand = new Command19("setup").description("Set up TimeBack integrati
|
|
|
12354
12551
|
import { confirm as confirm8 } from "@inquirer/prompts";
|
|
12355
12552
|
import { green as green3, red as red3 } from "colorette";
|
|
12356
12553
|
import { Command as Command20 } from "commander";
|
|
12357
|
-
var updateCommand = new Command20("update").description("Update TimeBack integration configuration for your game").option("--verbose, -v", "Output detailed information").
|
|
12554
|
+
var updateCommand = new Command20("update").description("Update TimeBack integration configuration for your game").option("--verbose, -v", "Output detailed information").option(
|
|
12555
|
+
"--env <environment>",
|
|
12556
|
+
"Environment to update TimeBack integration in (staging or production)"
|
|
12557
|
+
).action(async (options) => {
|
|
12558
|
+
const { env } = options;
|
|
12358
12559
|
try {
|
|
12560
|
+
ensureEnvironment(env, logger);
|
|
12359
12561
|
logger.newLine();
|
|
12360
12562
|
const config = await runStep(
|
|
12361
12563
|
"Loading configuration",
|
|
@@ -12461,13 +12663,18 @@ var updateCommand = new Command20("update").description("Update TimeBack integra
|
|
|
12461
12663
|
|
|
12462
12664
|
// src/commands/timeback/verify.ts
|
|
12463
12665
|
import { Command as Command21 } from "commander";
|
|
12464
|
-
var verifyCommand = new Command21("verify").description("Verify TimeBack integration for your game").option("--verbose, -v", "Output detailed resource information").
|
|
12666
|
+
var verifyCommand = new Command21("verify").description("Verify TimeBack integration for your game").option("--verbose, -v", "Output detailed resource information").option(
|
|
12667
|
+
"--env <environment>",
|
|
12668
|
+
"Environment to verify TimeBack integration in (staging or production)"
|
|
12669
|
+
).action(async (options) => {
|
|
12670
|
+
const { env } = options;
|
|
12465
12671
|
try {
|
|
12466
|
-
logger
|
|
12672
|
+
const environment = ensureEnvironment(env, logger);
|
|
12467
12673
|
const client = await requireAuthenticatedClient();
|
|
12674
|
+
logger.newLine();
|
|
12468
12675
|
const { game } = await getGameFromConfig(client);
|
|
12469
12676
|
const result = await runStep(
|
|
12470
|
-
|
|
12677
|
+
`Verifying TimeBack integration in ${environment}`,
|
|
12471
12678
|
() => client.timeback.management.verify(game.id),
|
|
12472
12679
|
"Verification complete"
|
|
12473
12680
|
);
|
|
@@ -12508,11 +12715,12 @@ timebackCommand.addCommand(cleanupCommand);
|
|
|
12508
12715
|
var __dirname = dirname4(fileURLToPath2(import.meta.url));
|
|
12509
12716
|
var packageJson = await loadPackageJson({ cwd: __dirname, searchUp: true, required: true });
|
|
12510
12717
|
program.name("playcademy").description("CLI for deploying and managing Playcademy games").version(packageJson?.version || "0.0.0").option("--profile <name>", "Use a specific authentication profile", "default").hook("preAction", (thisCommand) => {
|
|
12511
|
-
const options = thisCommand.
|
|
12718
|
+
const options = thisCommand.optsWithGlobals();
|
|
12512
12719
|
setCliContext({ profile: options.profile, workspace: process.cwd() });
|
|
12513
12720
|
});
|
|
12514
12721
|
program.addCommand(initCommand);
|
|
12515
12722
|
program.addCommand(loginCommand);
|
|
12723
|
+
program.addCommand(logoutCommand);
|
|
12516
12724
|
program.addCommand(profilesCommand);
|
|
12517
12725
|
program.addCommand(meCommand);
|
|
12518
12726
|
program.addCommand(devCommand);
|
|
@@ -12550,6 +12758,7 @@ export {
|
|
|
12550
12758
|
displayRegisteredRoutes,
|
|
12551
12759
|
displayResourcesStatus,
|
|
12552
12760
|
displaySuccessMessage,
|
|
12761
|
+
ensureEnvironment,
|
|
12553
12762
|
ensureGameExists,
|
|
12554
12763
|
findConfigPath,
|
|
12555
12764
|
generateEntryCode,
|
|
@@ -12557,6 +12766,7 @@ export {
|
|
|
12557
12766
|
generateJsonConfig,
|
|
12558
12767
|
getApiUrl,
|
|
12559
12768
|
getAuthPath,
|
|
12769
|
+
getAuthenticatedEnvironments,
|
|
12560
12770
|
getBackendHash,
|
|
12561
12771
|
getBackendSize,
|
|
12562
12772
|
getBaseUrl,
|
|
@@ -12588,6 +12798,7 @@ export {
|
|
|
12588
12798
|
loadGameStore,
|
|
12589
12799
|
logger,
|
|
12590
12800
|
needsBackend,
|
|
12801
|
+
normalizeEnvironment,
|
|
12591
12802
|
prepareDeploymentContext,
|
|
12592
12803
|
processConfigVariables,
|
|
12593
12804
|
promptForApiRoutes,
|
package/dist/types.d.ts
CHANGED
|
@@ -23,15 +23,28 @@ interface AuthProfile {
|
|
|
23
23
|
/** ISO 8601 date string - when the token expires (if applicable) */
|
|
24
24
|
expiresAt?: string;
|
|
25
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Environment-specific auth profiles
|
|
28
|
+
* Each environment (staging, production) has its own set of profiles
|
|
29
|
+
*/
|
|
30
|
+
interface EnvironmentAuthProfiles {
|
|
31
|
+
/** Default authentication profile for this environment */
|
|
32
|
+
default: AuthProfile | null;
|
|
33
|
+
/** Named authentication profiles for this environment */
|
|
34
|
+
profiles: Record<string, AuthProfile>;
|
|
35
|
+
}
|
|
26
36
|
/**
|
|
27
37
|
* The complete auth store structure
|
|
28
38
|
* CLI-specific type for ~/.playcademy/auth.json
|
|
39
|
+
*
|
|
40
|
+
* Profiles are scoped per environment to ensure staging and production
|
|
41
|
+
* credentials are kept separate for security.
|
|
29
42
|
*/
|
|
30
43
|
interface AuthStore {
|
|
31
|
-
/**
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
|
|
44
|
+
/** Staging environment profiles */
|
|
45
|
+
staging: EnvironmentAuthProfiles;
|
|
46
|
+
/** Production environment profiles */
|
|
47
|
+
production: EnvironmentAuthProfiles;
|
|
35
48
|
}
|
|
36
49
|
/**
|
|
37
50
|
* Login credentials for email/password authentication
|
|
@@ -486,7 +499,7 @@ interface DeploymentContext {
|
|
|
486
499
|
projectPath: string;
|
|
487
500
|
existingGame?: Game;
|
|
488
501
|
deployedGameInfo?: DeployedGameInfo;
|
|
489
|
-
|
|
502
|
+
isGameDeployed: boolean;
|
|
490
503
|
buildHash?: string;
|
|
491
504
|
buildSize?: number;
|
|
492
505
|
previousBuildHash?: string;
|
|
@@ -625,4 +638,4 @@ interface PreviewResponse {
|
|
|
625
638
|
qrCode?: string;
|
|
626
639
|
}
|
|
627
640
|
|
|
628
|
-
export type { ApiConfig, ApiErrorResponse, ApiKeyListItem, ApiKeyWithSecret, ApiRequestOptions, AuthProfile, AuthStore, BackendDeploymentWithHash, CallbackServerResult, CreateApiKeyResponse, DeployConfig, DeployNewGameOptions, DeployedGameInfo, DeploymentChanges, DeploymentContext, DeploymentPlan, DeploymentResult, GameStore, IntegrationsConfig, LoginCredentials, LoginResponse, PlaycademyConfig, PreviewOptions, PreviewResponse, SignInResponse, SsoCallbackData, TimebackIntegrationConfig, TokenType, UpdateExistingGameOptions };
|
|
641
|
+
export type { ApiConfig, ApiErrorResponse, ApiKeyListItem, ApiKeyWithSecret, ApiRequestOptions, AuthProfile, AuthStore, BackendDeploymentWithHash, CallbackServerResult, CreateApiKeyResponse, DeployConfig, DeployNewGameOptions, DeployedGameInfo, DeploymentChanges, DeploymentContext, DeploymentPlan, DeploymentResult, EnvironmentAuthProfiles, GameStore, IntegrationsConfig, LoginCredentials, LoginResponse, PlaycademyConfig, PreviewOptions, PreviewResponse, SignInResponse, SsoCallbackData, TimebackIntegrationConfig, TokenType, UpdateExistingGameOptions };
|
package/dist/utils.js
CHANGED
|
@@ -4548,15 +4548,7 @@ function createDevNamespace(client) {
|
|
|
4548
4548
|
throw new Error(`File upload failed: ${uploadResponse.status} ${uploadResponse.statusText}`);
|
|
4549
4549
|
}
|
|
4550
4550
|
}
|
|
4551
|
-
const
|
|
4552
|
-
const anyClient = client;
|
|
4553
|
-
try {
|
|
4554
|
-
return typeof anyClient.getBaseUrl === "function" ? anyClient.getBaseUrl() : "/api";
|
|
4555
|
-
} catch {
|
|
4556
|
-
return "/api";
|
|
4557
|
-
}
|
|
4558
|
-
})();
|
|
4559
|
-
const finalizeUrl = baseUrl.replace(/\/$/, "") + "/games/uploads/finalize/";
|
|
4551
|
+
const finalizeUrl = `${client.baseUrl}/games/uploads/finalize/`;
|
|
4560
4552
|
const authToken = client.getToken();
|
|
4561
4553
|
const tokenType = client.getTokenType();
|
|
4562
4554
|
const headers = {
|
|
@@ -6034,13 +6026,13 @@ var init_achievements = () => {
|
|
|
6034
6026
|
function createTimebackNamespace(client) {
|
|
6035
6027
|
return {
|
|
6036
6028
|
recordProgress: (progressData) => {
|
|
6037
|
-
return client["
|
|
6029
|
+
return client["requestGameBackend"]("/api/integrations/timeback/progress", "POST", { progressData });
|
|
6038
6030
|
},
|
|
6039
6031
|
recordSessionEnd: (sessionData) => {
|
|
6040
|
-
return client["
|
|
6032
|
+
return client["requestGameBackend"]("/api/integrations/timeback/session-end", "POST", { sessionData });
|
|
6041
6033
|
},
|
|
6042
6034
|
awardXP: (xpAmount, metadata) => {
|
|
6043
|
-
return client["
|
|
6035
|
+
return client["requestGameBackend"]("/api/integrations/timeback/award-xp", "POST", { xpAmount, metadata });
|
|
6044
6036
|
},
|
|
6045
6037
|
management: {
|
|
6046
6038
|
setup: (request2) => {
|
|
@@ -6349,7 +6341,7 @@ var init_client = __esm2(() => {
|
|
|
6349
6341
|
authContext;
|
|
6350
6342
|
initPayload;
|
|
6351
6343
|
constructor(config) {
|
|
6352
|
-
this.baseUrl = config?.baseUrl
|
|
6344
|
+
this.baseUrl = config?.baseUrl?.endsWith("/api") ? config.baseUrl : `${config?.baseUrl}/api`;
|
|
6353
6345
|
this.gameUrl = config?.gameUrl;
|
|
6354
6346
|
this.gameId = config?.gameId;
|
|
6355
6347
|
this.config = config || {};
|
|
@@ -6365,8 +6357,9 @@ var init_client = __esm2(() => {
|
|
|
6365
6357
|
return `${effectiveBaseUrl}/api`;
|
|
6366
6358
|
}
|
|
6367
6359
|
getGameBackendUrl() {
|
|
6368
|
-
if (!this.gameUrl)
|
|
6369
|
-
|
|
6360
|
+
if (!this.gameUrl) {
|
|
6361
|
+
throw new PlaycademyError("Game backend URL not configured. gameUrl must be set to use game backend features.");
|
|
6362
|
+
}
|
|
6370
6363
|
const isRelative = this.gameUrl.startsWith("/");
|
|
6371
6364
|
const isBrowser2 = typeof window !== "undefined";
|
|
6372
6365
|
const effectiveGameUrl = isRelative && isBrowser2 ? `${window.location.origin}${this.gameUrl}` : this.gameUrl;
|
|
@@ -6403,17 +6396,29 @@ var init_client = __esm2(() => {
|
|
|
6403
6396
|
listener(payload);
|
|
6404
6397
|
});
|
|
6405
6398
|
}
|
|
6406
|
-
async request(path, method, body, headers
|
|
6399
|
+
async request(path, method, body, headers) {
|
|
6400
|
+
const effectiveHeaders = {
|
|
6401
|
+
...headers,
|
|
6402
|
+
...this.authStrategy.getHeaders()
|
|
6403
|
+
};
|
|
6404
|
+
return request({
|
|
6405
|
+
path,
|
|
6406
|
+
method,
|
|
6407
|
+
body,
|
|
6408
|
+
baseUrl: this.baseUrl,
|
|
6409
|
+
extraHeaders: effectiveHeaders
|
|
6410
|
+
});
|
|
6411
|
+
}
|
|
6412
|
+
async requestGameBackend(path, method, body, headers) {
|
|
6407
6413
|
const effectiveHeaders = {
|
|
6408
6414
|
...headers,
|
|
6409
6415
|
...this.authStrategy.getHeaders()
|
|
6410
6416
|
};
|
|
6411
|
-
const targetBaseUrl = useGameBackend ? this.getGameBackendUrl() : this.baseUrl;
|
|
6412
6417
|
return request({
|
|
6413
6418
|
path,
|
|
6414
6419
|
method,
|
|
6415
6420
|
body,
|
|
6416
|
-
baseUrl:
|
|
6421
|
+
baseUrl: this.getGameBackendUrl(),
|
|
6417
6422
|
extraHeaders: effectiveHeaders
|
|
6418
6423
|
});
|
|
6419
6424
|
}
|
|
@@ -6498,9 +6503,40 @@ function customTransform(text2) {
|
|
|
6498
6503
|
const highlightCode = (text3) => text3.replace(/`([^`]+)`/g, (_, code) => greenBright(code));
|
|
6499
6504
|
return highlightCode(text2);
|
|
6500
6505
|
}
|
|
6506
|
+
function formatTable(data, title) {
|
|
6507
|
+
if (data.length === 0) return;
|
|
6508
|
+
const keys = Object.keys(data[0]);
|
|
6509
|
+
const rows = data.map((item) => keys.map((key) => String(item[key] ?? "")));
|
|
6510
|
+
const widths = keys.map((key, i) => {
|
|
6511
|
+
const headerWidth = key.length;
|
|
6512
|
+
const dataWidth = Math.max(...rows.map((row) => row[i].length));
|
|
6513
|
+
return Math.max(headerWidth, dataWidth);
|
|
6514
|
+
});
|
|
6515
|
+
const totalWidth = widths.reduce((sum, w) => sum + w + 3, -1);
|
|
6516
|
+
const separator = "\u251C" + widths.map((w) => "\u2500".repeat(w + 2)).join("\u253C") + "\u2524";
|
|
6517
|
+
const topBorder = "\u250C" + "\u2500".repeat(totalWidth) + "\u2510";
|
|
6518
|
+
const titleSeparator = "\u251C" + widths.map((w) => "\u2500".repeat(w + 2)).join("\u252C") + "\u2524";
|
|
6519
|
+
const bottomBorder = "\u2514" + widths.map((w) => "\u2500".repeat(w + 2)).join("\u2534") + "\u2518";
|
|
6520
|
+
console.log(topBorder);
|
|
6521
|
+
if (title) {
|
|
6522
|
+
const titleText = bold(title);
|
|
6523
|
+
const titlePadding = totalWidth - title.length - 1;
|
|
6524
|
+
const titleRow = "\u2502 " + titleText + " ".repeat(titlePadding) + "\u2502";
|
|
6525
|
+
console.log(titleRow);
|
|
6526
|
+
console.log(titleSeparator);
|
|
6527
|
+
}
|
|
6528
|
+
const header = "\u2502 " + keys.map((key, i) => key.padEnd(widths[i])).join(" \u2502 ") + " \u2502";
|
|
6529
|
+
console.log(header);
|
|
6530
|
+
console.log(separator);
|
|
6531
|
+
rows.forEach((row) => {
|
|
6532
|
+
const dataRow = "\u2502 " + row.map((cell, i) => cell.padEnd(widths[i])).join(" \u2502 ") + " \u2502";
|
|
6533
|
+
console.log(dataRow);
|
|
6534
|
+
});
|
|
6535
|
+
console.log(bottomBorder);
|
|
6536
|
+
}
|
|
6501
6537
|
var logger = {
|
|
6502
|
-
table: (data) => {
|
|
6503
|
-
|
|
6538
|
+
table: (data, title) => {
|
|
6539
|
+
formatTable(data, title);
|
|
6504
6540
|
},
|
|
6505
6541
|
/**
|
|
6506
6542
|
* Info message - general information
|