playcademy 0.22.0 → 0.22.1-beta.2
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/cli.js +2 -2
- package/dist/constants.js +1 -1
- package/dist/db.d.ts +8 -0
- package/dist/db.js +1 -1
- package/dist/index.d.ts +9 -0
- package/dist/index.js +611 -46
- package/dist/runtime/backend-runtime/index.js +11 -3
- package/dist/runtime/backend-runtime/manifest.json +4 -4
- package/dist/utils.js +2 -2
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1065,7 +1065,7 @@ var SAMPLE_BUCKET_FILENAME = "bucket.ts";
|
|
|
1065
1065
|
// ../better-auth/package.json
|
|
1066
1066
|
var package_default = {
|
|
1067
1067
|
name: "@playcademy/better-auth",
|
|
1068
|
-
version: "0.0.
|
|
1068
|
+
version: "0.0.14-beta.2",
|
|
1069
1069
|
type: "module",
|
|
1070
1070
|
exports: {
|
|
1071
1071
|
"./server": {
|
|
@@ -3045,7 +3045,7 @@ import { existsSync as existsSync11, mkdirSync as mkdirSync5, readFileSync as re
|
|
|
3045
3045
|
import { join as join13 } from "node:path";
|
|
3046
3046
|
|
|
3047
3047
|
// src/version.ts
|
|
3048
|
-
var cliVersion = false ? "0.0.0-dev" : "0.22.
|
|
3048
|
+
var cliVersion = false ? "0.0.0-dev" : "0.22.1-beta.2";
|
|
3049
3049
|
|
|
3050
3050
|
// src/lib/init/database.ts
|
|
3051
3051
|
var drizzleConfigTemplate = loadTemplateString("database/drizzle-config.ts");
|
package/dist/constants.js
CHANGED
package/dist/db.d.ts
CHANGED
|
@@ -134,6 +134,14 @@ declare function getBucket(mf: Miniflare): Promise<unknown | null>;
|
|
|
134
134
|
*/
|
|
135
135
|
declare function executeSeedFile(seedFilePath: string, mf: Miniflare, envSecrets?: Record<string, string>): Promise<void>;
|
|
136
136
|
|
|
137
|
+
/**
|
|
138
|
+
* Game Types
|
|
139
|
+
*
|
|
140
|
+
* Literal types and API DTOs. Database row types are in @playcademy/data/types.
|
|
141
|
+
*
|
|
142
|
+
* @module types/game
|
|
143
|
+
*/
|
|
144
|
+
|
|
137
145
|
/** Log entry captured from seed worker console output */
|
|
138
146
|
interface SeedLogEntry {
|
|
139
147
|
/** Log level (log, warn, error, info) */
|
package/dist/db.js
CHANGED
|
@@ -36,7 +36,7 @@ var DEFAULT_API_ROUTES_DIRECTORY = join2(SERVER_ROOT_DIRECTORY, "api");
|
|
|
36
36
|
// ../better-auth/package.json
|
|
37
37
|
var package_default = {
|
|
38
38
|
name: "@playcademy/better-auth",
|
|
39
|
-
version: "0.0.
|
|
39
|
+
version: "0.0.14-beta.2",
|
|
40
40
|
type: "module",
|
|
41
41
|
exports: {
|
|
42
42
|
"./server": {
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,14 @@ import { SchemaInfo } from '@playcademy/cloudflare';
|
|
|
3
3
|
import { PlaycademyClient } from '@playcademy/sdk/internal';
|
|
4
4
|
import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* User Types
|
|
8
|
+
*
|
|
9
|
+
* Enums, DTOs and API response types. Database row types are in @playcademy/data/types.
|
|
10
|
+
*
|
|
11
|
+
* @module types/user
|
|
12
|
+
*/
|
|
13
|
+
|
|
6
14
|
/**
|
|
7
15
|
* OpenID Connect UserInfo claims (NOT a database row).
|
|
8
16
|
*/
|
|
@@ -1317,6 +1325,7 @@ interface DeploymentDiffOptions {
|
|
|
1317
1325
|
backend?: BackendDiff;
|
|
1318
1326
|
integrations?: IntegrationsDiff;
|
|
1319
1327
|
secrets?: SecretsDiff;
|
|
1328
|
+
driftLabels?: Set<string>;
|
|
1320
1329
|
}
|
|
1321
1330
|
|
|
1322
1331
|
/**
|
package/dist/index.js
CHANGED
|
@@ -326,7 +326,7 @@ var SAMPLE_BUCKET_FILENAME = "bucket.ts";
|
|
|
326
326
|
// ../better-auth/package.json
|
|
327
327
|
var package_default = {
|
|
328
328
|
name: "@playcademy/better-auth",
|
|
329
|
-
version: "0.0.
|
|
329
|
+
version: "0.0.14-beta.2",
|
|
330
330
|
type: "module",
|
|
331
331
|
exports: {
|
|
332
332
|
"./server": {
|
|
@@ -635,6 +635,12 @@ var PLAYCADEMY_BASE_URLS = {
|
|
|
635
635
|
};
|
|
636
636
|
var LOG_COLLECTOR_URL = "https://logs.playcademy.gg";
|
|
637
637
|
|
|
638
|
+
// ../constants/src/game.ts
|
|
639
|
+
var GAME_MEMBER_ROLES = {
|
|
640
|
+
OWNER: "owner",
|
|
641
|
+
COLLABORATOR: "collaborator"
|
|
642
|
+
};
|
|
643
|
+
|
|
638
644
|
// ../constants/src/overworld.ts
|
|
639
645
|
var ITEM_SLUGS = {
|
|
640
646
|
/** Primary platform currency */
|
|
@@ -3465,6 +3471,243 @@ async function updateConfigFile(configPath, updates, options = {}) {
|
|
|
3465
3471
|
await formatConfigWithPrettier(configPath);
|
|
3466
3472
|
}
|
|
3467
3473
|
}
|
|
3474
|
+
async function updateConfigScalars(configPath, updates, options = {}) {
|
|
3475
|
+
const entries = Object.entries(updates);
|
|
3476
|
+
const provided = entries.filter(([, value]) => value !== void 0);
|
|
3477
|
+
if (provided.length === 0) {
|
|
3478
|
+
return { written: [], skipped: [] };
|
|
3479
|
+
}
|
|
3480
|
+
const configContent = readFileSync2(configPath, "utf8");
|
|
3481
|
+
const isJson = configPath.endsWith(".json");
|
|
3482
|
+
let result;
|
|
3483
|
+
if (isJson) {
|
|
3484
|
+
result = updateJsonScalars(configContent, configPath, provided);
|
|
3485
|
+
} else {
|
|
3486
|
+
result = updateJsScalars(configContent, configPath, provided);
|
|
3487
|
+
}
|
|
3488
|
+
if (result.written.length > 0 && options.format !== false) {
|
|
3489
|
+
await formatConfigWithPrettier(configPath);
|
|
3490
|
+
}
|
|
3491
|
+
return result;
|
|
3492
|
+
}
|
|
3493
|
+
function updateJsonScalars(content, configPath, updates) {
|
|
3494
|
+
const parsed = JSON.parse(content);
|
|
3495
|
+
const written = [];
|
|
3496
|
+
for (const [field, value] of updates) {
|
|
3497
|
+
if (value === null) {
|
|
3498
|
+
if (field in parsed) {
|
|
3499
|
+
delete parsed[field];
|
|
3500
|
+
written.push(field);
|
|
3501
|
+
}
|
|
3502
|
+
} else {
|
|
3503
|
+
parsed[field] = value;
|
|
3504
|
+
written.push(field);
|
|
3505
|
+
}
|
|
3506
|
+
}
|
|
3507
|
+
if (written.length > 0) {
|
|
3508
|
+
writeFileSync2(configPath, JSON.stringify(parsed, null, 4), "utf8");
|
|
3509
|
+
}
|
|
3510
|
+
return { written, skipped: [] };
|
|
3511
|
+
}
|
|
3512
|
+
function buildScalarPropertyRegex(field) {
|
|
3513
|
+
return new RegExp(
|
|
3514
|
+
`(^|[\\s,{])(${field})(\\s*:\\s*)(['"\`])((?:(?!\\4)[^\\\\\\n\\r])*)\\4`,
|
|
3515
|
+
"gm"
|
|
3516
|
+
);
|
|
3517
|
+
}
|
|
3518
|
+
function fieldKeyPresent(content, field) {
|
|
3519
|
+
const objectRange = findExportDefaultObjectRange(content);
|
|
3520
|
+
if (!objectRange) {
|
|
3521
|
+
return false;
|
|
3522
|
+
}
|
|
3523
|
+
const presenceRegex = new RegExp(`(^|[\\s,{])${field}\\s*:`, "gm");
|
|
3524
|
+
const objectContent = content.slice(objectRange.openBrace + 1, objectRange.closeBrace);
|
|
3525
|
+
for (const match of objectContent.matchAll(presenceRegex)) {
|
|
3526
|
+
const prefix = match[1] ?? "";
|
|
3527
|
+
const keyStart = objectRange.openBrace + 1 + match.index + prefix.length;
|
|
3528
|
+
if (isTopLevelObjectProperty(content, objectRange.openBrace, keyStart)) {
|
|
3529
|
+
return true;
|
|
3530
|
+
}
|
|
3531
|
+
}
|
|
3532
|
+
return false;
|
|
3533
|
+
}
|
|
3534
|
+
function stringifyJsStringLiteral(value) {
|
|
3535
|
+
return JSON.stringify(value);
|
|
3536
|
+
}
|
|
3537
|
+
function updateJsScalars(content, configPath, updates) {
|
|
3538
|
+
const written = [];
|
|
3539
|
+
const skipped = [];
|
|
3540
|
+
let working = content;
|
|
3541
|
+
for (const [field, value] of updates) {
|
|
3542
|
+
const outcome = tryRewriteJsScalar(working, field, value);
|
|
3543
|
+
if (outcome.kind === "written") {
|
|
3544
|
+
working = outcome.content;
|
|
3545
|
+
written.push(field);
|
|
3546
|
+
} else {
|
|
3547
|
+
skipped.push(outcome.skipped);
|
|
3548
|
+
}
|
|
3549
|
+
}
|
|
3550
|
+
if (written.length > 0) {
|
|
3551
|
+
writeFileSync2(configPath, working, "utf8");
|
|
3552
|
+
}
|
|
3553
|
+
return { written, skipped };
|
|
3554
|
+
}
|
|
3555
|
+
function tryRewriteJsScalar(content, field, value) {
|
|
3556
|
+
if (value === null) {
|
|
3557
|
+
return {
|
|
3558
|
+
kind: "skipped",
|
|
3559
|
+
skipped: {
|
|
3560
|
+
field,
|
|
3561
|
+
intendedValue: null,
|
|
3562
|
+
reason: fieldKeyPresent(content, field) ? "removal-unsupported" : "missing"
|
|
3563
|
+
}
|
|
3564
|
+
};
|
|
3565
|
+
}
|
|
3566
|
+
const match = findTopLevelLiteralScalar(content, field);
|
|
3567
|
+
if (match) {
|
|
3568
|
+
const replacement = `${match.prefix}${match.key}${match.separator}${stringifyJsStringLiteral(value)}`;
|
|
3569
|
+
const nextContent = `${content.slice(0, match.start)}${replacement}${content.slice(match.end)}`;
|
|
3570
|
+
return { kind: "written", content: nextContent };
|
|
3571
|
+
}
|
|
3572
|
+
return {
|
|
3573
|
+
kind: "skipped",
|
|
3574
|
+
skipped: {
|
|
3575
|
+
field,
|
|
3576
|
+
intendedValue: value,
|
|
3577
|
+
reason: fieldKeyPresent(content, field) ? "non-literal" : "missing"
|
|
3578
|
+
}
|
|
3579
|
+
};
|
|
3580
|
+
}
|
|
3581
|
+
function findExportDefaultObjectRange(content) {
|
|
3582
|
+
const exportDefaultIndex = content.indexOf("export default");
|
|
3583
|
+
if (exportDefaultIndex === -1) {
|
|
3584
|
+
return null;
|
|
3585
|
+
}
|
|
3586
|
+
const openBrace = content.indexOf("{", exportDefaultIndex);
|
|
3587
|
+
if (openBrace === -1) {
|
|
3588
|
+
return null;
|
|
3589
|
+
}
|
|
3590
|
+
const closeBrace = findMatchingBrace(content, openBrace);
|
|
3591
|
+
return closeBrace === null ? null : { openBrace, closeBrace };
|
|
3592
|
+
}
|
|
3593
|
+
function findTopLevelLiteralScalar(content, field) {
|
|
3594
|
+
const objectRange = findExportDefaultObjectRange(content);
|
|
3595
|
+
if (!objectRange) {
|
|
3596
|
+
return null;
|
|
3597
|
+
}
|
|
3598
|
+
const literalRegex = buildScalarPropertyRegex(field);
|
|
3599
|
+
const objectContent = content.slice(objectRange.openBrace + 1, objectRange.closeBrace);
|
|
3600
|
+
for (const match of objectContent.matchAll(literalRegex)) {
|
|
3601
|
+
const [matchedText, prefix = "", key = "", separator = "", quote = "", literal = ""] = match;
|
|
3602
|
+
const start = objectRange.openBrace + 1 + match.index;
|
|
3603
|
+
const keyStart = start + prefix.length;
|
|
3604
|
+
const isInterpolatedTemplate = quote === "`" && literal.includes("${");
|
|
3605
|
+
if (!isInterpolatedTemplate && isTopLevelObjectProperty(content, objectRange.openBrace, keyStart)) {
|
|
3606
|
+
return {
|
|
3607
|
+
start,
|
|
3608
|
+
end: start + matchedText.length,
|
|
3609
|
+
prefix,
|
|
3610
|
+
key,
|
|
3611
|
+
separator
|
|
3612
|
+
};
|
|
3613
|
+
}
|
|
3614
|
+
}
|
|
3615
|
+
return null;
|
|
3616
|
+
}
|
|
3617
|
+
function findMatchingBrace(content, openBrace) {
|
|
3618
|
+
let depth = 0;
|
|
3619
|
+
let quote = null;
|
|
3620
|
+
let inLineComment = false;
|
|
3621
|
+
let inBlockComment = false;
|
|
3622
|
+
for (let index2 = openBrace; index2 < content.length; index2 += 1) {
|
|
3623
|
+
const char = content[index2];
|
|
3624
|
+
const next = content[index2 + 1];
|
|
3625
|
+
if (inLineComment) {
|
|
3626
|
+
if (char === "\n") {
|
|
3627
|
+
inLineComment = false;
|
|
3628
|
+
}
|
|
3629
|
+
} else if (inBlockComment) {
|
|
3630
|
+
if (char === "*" && next === "/") {
|
|
3631
|
+
inBlockComment = false;
|
|
3632
|
+
index2 += 1;
|
|
3633
|
+
}
|
|
3634
|
+
} else if (quote) {
|
|
3635
|
+
if (char === quote && !isEscapedCharacter(content, index2)) {
|
|
3636
|
+
quote = null;
|
|
3637
|
+
}
|
|
3638
|
+
} else if (char === "/" && next === "/") {
|
|
3639
|
+
inLineComment = true;
|
|
3640
|
+
index2 += 1;
|
|
3641
|
+
} else if (char === "/" && next === "*") {
|
|
3642
|
+
inBlockComment = true;
|
|
3643
|
+
index2 += 1;
|
|
3644
|
+
} else if (char === "'" || char === '"' || char === "`") {
|
|
3645
|
+
quote = char;
|
|
3646
|
+
} else if (char === "{") {
|
|
3647
|
+
depth += 1;
|
|
3648
|
+
} else if (char === "}") {
|
|
3649
|
+
depth -= 1;
|
|
3650
|
+
if (depth === 0) {
|
|
3651
|
+
return index2;
|
|
3652
|
+
}
|
|
3653
|
+
}
|
|
3654
|
+
}
|
|
3655
|
+
return null;
|
|
3656
|
+
}
|
|
3657
|
+
function isTopLevelObjectProperty(content, openBrace, keyStart) {
|
|
3658
|
+
let objectDepth = 0;
|
|
3659
|
+
let bracketDepth = 0;
|
|
3660
|
+
let parenDepth = 0;
|
|
3661
|
+
let quote = null;
|
|
3662
|
+
let inLineComment = false;
|
|
3663
|
+
let inBlockComment = false;
|
|
3664
|
+
for (let index2 = openBrace + 1; index2 < keyStart; index2 += 1) {
|
|
3665
|
+
const char = content[index2];
|
|
3666
|
+
const next = content[index2 + 1];
|
|
3667
|
+
if (inLineComment) {
|
|
3668
|
+
if (char === "\n") {
|
|
3669
|
+
inLineComment = false;
|
|
3670
|
+
}
|
|
3671
|
+
} else if (inBlockComment) {
|
|
3672
|
+
if (char === "*" && next === "/") {
|
|
3673
|
+
inBlockComment = false;
|
|
3674
|
+
index2 += 1;
|
|
3675
|
+
}
|
|
3676
|
+
} else if (quote) {
|
|
3677
|
+
if (char === quote && !isEscapedCharacter(content, index2)) {
|
|
3678
|
+
quote = null;
|
|
3679
|
+
}
|
|
3680
|
+
} else if (char === "/" && next === "/") {
|
|
3681
|
+
inLineComment = true;
|
|
3682
|
+
index2 += 1;
|
|
3683
|
+
} else if (char === "/" && next === "*") {
|
|
3684
|
+
inBlockComment = true;
|
|
3685
|
+
index2 += 1;
|
|
3686
|
+
} else if (char === "'" || char === '"' || char === "`") {
|
|
3687
|
+
quote = char;
|
|
3688
|
+
} else if (char === "{") {
|
|
3689
|
+
objectDepth += 1;
|
|
3690
|
+
} else if (char === "}") {
|
|
3691
|
+
objectDepth -= 1;
|
|
3692
|
+
} else if (char === "[") {
|
|
3693
|
+
bracketDepth += 1;
|
|
3694
|
+
} else if (char === "]") {
|
|
3695
|
+
bracketDepth -= 1;
|
|
3696
|
+
} else if (char === "(") {
|
|
3697
|
+
parenDepth += 1;
|
|
3698
|
+
} else if (char === ")") {
|
|
3699
|
+
parenDepth -= 1;
|
|
3700
|
+
}
|
|
3701
|
+
}
|
|
3702
|
+
return !inLineComment && !inBlockComment && !quote && objectDepth === 0 && bracketDepth === 0 && parenDepth === 0;
|
|
3703
|
+
}
|
|
3704
|
+
function isEscapedCharacter(content, index2) {
|
|
3705
|
+
let backslashCount = 0;
|
|
3706
|
+
for (let cursor2 = index2 - 1; cursor2 >= 0 && content[cursor2] === "\\"; cursor2 -= 1) {
|
|
3707
|
+
backslashCount += 1;
|
|
3708
|
+
}
|
|
3709
|
+
return backslashCount % 2 === 1;
|
|
3710
|
+
}
|
|
3468
3711
|
function deepMerge(target, source) {
|
|
3469
3712
|
const result = { ...target };
|
|
3470
3713
|
for (const key of Object.keys(source)) {
|
|
@@ -3659,6 +3902,19 @@ ${indent(level)}integrations: {`];
|
|
|
3659
3902
|
return lines.join("\n");
|
|
3660
3903
|
}
|
|
3661
3904
|
|
|
3905
|
+
// src/lib/deploy/metadata-payload.ts
|
|
3906
|
+
function buildDeployGameMetadataPayload(config) {
|
|
3907
|
+
return {
|
|
3908
|
+
displayName: config.displayName,
|
|
3909
|
+
platform: config.platform || "web",
|
|
3910
|
+
gameType: "hosted",
|
|
3911
|
+
metadata: {
|
|
3912
|
+
...config.description !== void 0 && { description: config.description },
|
|
3913
|
+
...config.emoji !== void 0 && { emoji: config.emoji }
|
|
3914
|
+
}
|
|
3915
|
+
};
|
|
3916
|
+
}
|
|
3917
|
+
|
|
3662
3918
|
// src/lib/core/game.ts
|
|
3663
3919
|
function getSlugFromConfig(config) {
|
|
3664
3920
|
return generateSlug(config.name);
|
|
@@ -3678,15 +3934,15 @@ async function ensureGameExists(client, config) {
|
|
|
3678
3934
|
logger.newLine();
|
|
3679
3935
|
game = await runStep(
|
|
3680
3936
|
`Creating app metadata for "${slug}"`,
|
|
3681
|
-
() => client.dev.games.upsert(
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
}
|
|
3689
|
-
|
|
3937
|
+
() => client.dev.games.upsert(
|
|
3938
|
+
slug,
|
|
3939
|
+
buildDeployGameMetadataPayload({
|
|
3940
|
+
displayName: config.name,
|
|
3941
|
+
description: config.description,
|
|
3942
|
+
emoji: config.emoji,
|
|
3943
|
+
platform: config.platform
|
|
3944
|
+
})
|
|
3945
|
+
),
|
|
3690
3946
|
"App metadata created"
|
|
3691
3947
|
);
|
|
3692
3948
|
}
|
|
@@ -4057,7 +4313,7 @@ import { existsSync as existsSync9, mkdirSync as mkdirSync2, readFileSync as rea
|
|
|
4057
4313
|
import { join as join13 } from "node:path";
|
|
4058
4314
|
|
|
4059
4315
|
// src/version.ts
|
|
4060
|
-
var cliVersion = false ? "0.0.0-dev" : "0.22.
|
|
4316
|
+
var cliVersion = false ? "0.0.0-dev" : "0.22.1-beta.2";
|
|
4061
4317
|
|
|
4062
4318
|
// src/lib/init/database.ts
|
|
4063
4319
|
var drizzleConfigTemplate = loadTemplateString("database/drizzle-config.ts");
|
|
@@ -10030,6 +10286,75 @@ async function loadDeployConfig(configPath) {
|
|
|
10030
10286
|
throw new Error(`Unsupported config file type: ${ext}`);
|
|
10031
10287
|
}
|
|
10032
10288
|
|
|
10289
|
+
// src/lib/deploy/dashboard-drift.ts
|
|
10290
|
+
var DASHBOARD_DRIFT_LABELS = {
|
|
10291
|
+
displayName: "Display name",
|
|
10292
|
+
platform: "Platform",
|
|
10293
|
+
metadataPrefix: "metadata."
|
|
10294
|
+
};
|
|
10295
|
+
function metadataValuesEqual(a, b) {
|
|
10296
|
+
if (Object.is(a, b)) {
|
|
10297
|
+
return true;
|
|
10298
|
+
}
|
|
10299
|
+
if (typeof a === "object" && a !== null && typeof b === "object" && b !== null) {
|
|
10300
|
+
return JSON.stringify(sortJsonKeys(a)) === JSON.stringify(sortJsonKeys(b));
|
|
10301
|
+
}
|
|
10302
|
+
return false;
|
|
10303
|
+
}
|
|
10304
|
+
function sortJsonKeys(value) {
|
|
10305
|
+
if (value === null || typeof value !== "object") {
|
|
10306
|
+
return value;
|
|
10307
|
+
}
|
|
10308
|
+
if (Array.isArray(value)) {
|
|
10309
|
+
return value.map(sortJsonKeys);
|
|
10310
|
+
}
|
|
10311
|
+
const sorted = {};
|
|
10312
|
+
for (const key of Object.keys(value).toSorted()) {
|
|
10313
|
+
sorted[key] = sortJsonKeys(value[key]);
|
|
10314
|
+
}
|
|
10315
|
+
return sorted;
|
|
10316
|
+
}
|
|
10317
|
+
function getDashboardMetadataDriftRows(remoteGame, localPayload) {
|
|
10318
|
+
const rows = [];
|
|
10319
|
+
if (remoteGame.displayName !== localPayload.displayName) {
|
|
10320
|
+
rows.push({
|
|
10321
|
+
label: DASHBOARD_DRIFT_LABELS.displayName,
|
|
10322
|
+
dashboard: remoteGame.displayName,
|
|
10323
|
+
afterDeploy: localPayload.displayName
|
|
10324
|
+
});
|
|
10325
|
+
}
|
|
10326
|
+
if (remoteGame.platform !== localPayload.platform) {
|
|
10327
|
+
rows.push({
|
|
10328
|
+
label: DASHBOARD_DRIFT_LABELS.platform,
|
|
10329
|
+
dashboard: remoteGame.platform,
|
|
10330
|
+
afterDeploy: localPayload.platform
|
|
10331
|
+
});
|
|
10332
|
+
}
|
|
10333
|
+
const remoteMeta = { ...remoteGame.metadata };
|
|
10334
|
+
const localMeta = { ...localPayload.metadata };
|
|
10335
|
+
const keys = /* @__PURE__ */ new Set([...Object.keys(remoteMeta), ...Object.keys(localMeta)]);
|
|
10336
|
+
for (const key of [...keys].toSorted()) {
|
|
10337
|
+
const rv = remoteMeta[key];
|
|
10338
|
+
const lv = localMeta[key];
|
|
10339
|
+
if (!metadataValuesEqual(rv, lv)) {
|
|
10340
|
+
rows.push({
|
|
10341
|
+
label: `${DASHBOARD_DRIFT_LABELS.metadataPrefix}${key}`,
|
|
10342
|
+
dashboard: rv,
|
|
10343
|
+
afterDeploy: lv
|
|
10344
|
+
});
|
|
10345
|
+
}
|
|
10346
|
+
}
|
|
10347
|
+
return rows;
|
|
10348
|
+
}
|
|
10349
|
+
function skipsDeployGameDueToSecretsOnly(context2, plan) {
|
|
10350
|
+
const changes = plan.changes;
|
|
10351
|
+
if (!changes) {
|
|
10352
|
+
return false;
|
|
10353
|
+
}
|
|
10354
|
+
const isSecretsOnly = !plan.shouldUpdateGame && !plan.shouldUploadBuild && !plan.shouldDeployBackend && changes.secrets !== void 0 && hasChanges(changes.secrets);
|
|
10355
|
+
return Boolean(isSecretsOnly && context2.existingGame && context2.localSecrets);
|
|
10356
|
+
}
|
|
10357
|
+
|
|
10033
10358
|
// src/lib/deploy/diff.ts
|
|
10034
10359
|
import { dim as dim6, green as green6, red as red4, yellow as yellow5 } from "colorette";
|
|
10035
10360
|
function calculateConfigDiff(existingGame, newConfig) {
|
|
@@ -10261,7 +10586,7 @@ function displayIntegrationAndSecretsChanges(integrations, secrets, secretsChang
|
|
|
10261
10586
|
}
|
|
10262
10587
|
}
|
|
10263
10588
|
function displayDeploymentDiff(options) {
|
|
10264
|
-
const { diff, noChanges, build: build3, backend, integrations, secrets } = options;
|
|
10589
|
+
const { diff, noChanges, build: build3, backend, integrations, secrets, driftLabels } = options;
|
|
10265
10590
|
if (noChanges) {
|
|
10266
10591
|
logger.remark("No changes detected");
|
|
10267
10592
|
logger.newLine();
|
|
@@ -10280,21 +10605,29 @@ function displayDeploymentDiff(options) {
|
|
|
10280
10605
|
logger.highlight("Changes detected:");
|
|
10281
10606
|
logger.newLine();
|
|
10282
10607
|
if (hasConfigChanges) {
|
|
10608
|
+
let driftHint2 = function(label) {
|
|
10609
|
+
return driftLabels?.has(label) ? ` ${red4("[differs from platform]")}` : "";
|
|
10610
|
+
};
|
|
10611
|
+
var driftHint = driftHint2;
|
|
10283
10612
|
logger.bold("Config", 1);
|
|
10284
10613
|
if (diff.displayName) {
|
|
10285
|
-
logger.data(
|
|
10614
|
+
logger.data(
|
|
10615
|
+
"Name",
|
|
10616
|
+
`${red4(diff.displayName.old)} \u2192 ${green6(diff.displayName.new)}${driftHint2(DASHBOARD_DRIFT_LABELS.displayName)}`,
|
|
10617
|
+
2
|
|
10618
|
+
);
|
|
10286
10619
|
}
|
|
10287
10620
|
if (diff.emoji) {
|
|
10288
10621
|
logger.data(
|
|
10289
10622
|
"Emoji",
|
|
10290
|
-
`${red4(diff.emoji.old || "(none)")} \u2192 ${green6(diff.emoji.new || "(none)")}`,
|
|
10623
|
+
`${red4(diff.emoji.old || "(none)")} \u2192 ${green6(diff.emoji.new || "(none)")}${driftHint2(`${DASHBOARD_DRIFT_LABELS.metadataPrefix}emoji`)}`,
|
|
10291
10624
|
2
|
|
10292
10625
|
);
|
|
10293
10626
|
}
|
|
10294
10627
|
if (diff.description) {
|
|
10295
10628
|
logger.data(
|
|
10296
10629
|
"Description",
|
|
10297
|
-
`${red4(diff.description.old || "(none)")} \u2192 ${green6(diff.description.new || "(none)")}`,
|
|
10630
|
+
`${red4(diff.description.old || "(none)")} \u2192 ${green6(diff.description.new || "(none)")}${driftHint2(`${DASHBOARD_DRIFT_LABELS.metadataPrefix}description`)}`,
|
|
10298
10631
|
2
|
|
10299
10632
|
);
|
|
10300
10633
|
}
|
|
@@ -10325,6 +10658,7 @@ function displayDeploymentDiff(options) {
|
|
|
10325
10658
|
}
|
|
10326
10659
|
|
|
10327
10660
|
// src/lib/deploy/interaction.ts
|
|
10661
|
+
import { join as join38 } from "path";
|
|
10328
10662
|
import { confirm as confirm6, input as input3, select as select5 } from "@inquirer/prompts";
|
|
10329
10663
|
|
|
10330
10664
|
// src/lib/deploy/schema.ts
|
|
@@ -10809,6 +11143,8 @@ async function confirmDeploymentPlan(plan, context2) {
|
|
|
10809
11143
|
const previousResources = context2.previousResources || [];
|
|
10810
11144
|
const addedResources = currentResources.filter((r) => !previousResources.includes(r));
|
|
10811
11145
|
const removedResources = previousResources.filter((r) => !currentResources.includes(r));
|
|
11146
|
+
const drift = await detectDashboardDrift(context2, plan);
|
|
11147
|
+
const driftLabels = drift ? new Set(drift.rows.map((r) => r.label)) : void 0;
|
|
10812
11148
|
displayDeploymentDiff({
|
|
10813
11149
|
diff: plan.changes.config ? calculateConfigDiff(context2.existingGame, config) : {},
|
|
10814
11150
|
noChanges: false,
|
|
@@ -10837,12 +11173,23 @@ async function confirmDeploymentPlan(plan, context2) {
|
|
|
10837
11173
|
currentKeys: currentIntegrationKeys,
|
|
10838
11174
|
metadata: plan.changes.integrationsMetadata
|
|
10839
11175
|
},
|
|
10840
|
-
secrets: plan.changes.secrets
|
|
11176
|
+
secrets: plan.changes.secrets,
|
|
11177
|
+
driftLabels
|
|
10841
11178
|
});
|
|
10842
11179
|
if (isNonInteractive()) {
|
|
10843
11180
|
logger.remark("Updating project (CI auto-confirm)", 1);
|
|
11181
|
+
if (drift) {
|
|
11182
|
+
logger.remark("Dashboard edits will be overwritten by local config", 1);
|
|
11183
|
+
}
|
|
10844
11184
|
return true;
|
|
10845
11185
|
}
|
|
11186
|
+
if (drift) {
|
|
11187
|
+
return await promptDashboardDriftResolution({
|
|
11188
|
+
context: context2,
|
|
11189
|
+
rows: drift.rows,
|
|
11190
|
+
remoteGame: drift.remoteGame
|
|
11191
|
+
});
|
|
11192
|
+
}
|
|
10846
11193
|
const shouldDeploy = await confirm6({
|
|
10847
11194
|
message: `Update ${config.displayName}?`,
|
|
10848
11195
|
default: true
|
|
@@ -10851,6 +11198,227 @@ async function confirmDeploymentPlan(plan, context2) {
|
|
|
10851
11198
|
}
|
|
10852
11199
|
return false;
|
|
10853
11200
|
}
|
|
11201
|
+
async function detectDashboardDrift(context2, plan) {
|
|
11202
|
+
if (!context2.config.slug || skipsDeployGameDueToSecretsOnly(context2, plan)) {
|
|
11203
|
+
return null;
|
|
11204
|
+
}
|
|
11205
|
+
try {
|
|
11206
|
+
const remoteGame = await context2.client.games.fetch(context2.config.slug, {
|
|
11207
|
+
force: true
|
|
11208
|
+
});
|
|
11209
|
+
const localPayload = buildDeployGameMetadataPayload(context2.config);
|
|
11210
|
+
const rows = getDashboardMetadataDriftRows(remoteGame, localPayload);
|
|
11211
|
+
if (rows.length === 0) {
|
|
11212
|
+
return null;
|
|
11213
|
+
}
|
|
11214
|
+
return { rows, remoteGame };
|
|
11215
|
+
} catch {
|
|
11216
|
+
return null;
|
|
11217
|
+
}
|
|
11218
|
+
}
|
|
11219
|
+
async function promptDashboardDriftResolution(args) {
|
|
11220
|
+
const { context: context2, rows, remoteGame } = args;
|
|
11221
|
+
logger.admonition("warning", "Config drift detected", [
|
|
11222
|
+
"Your local config is out of sync with the platform"
|
|
11223
|
+
]);
|
|
11224
|
+
logger.newLine();
|
|
11225
|
+
const canWriteConfig = Boolean(context2.configFileName);
|
|
11226
|
+
const choices = [
|
|
11227
|
+
{
|
|
11228
|
+
name: "Keep local values",
|
|
11229
|
+
value: "config-wins"
|
|
11230
|
+
}
|
|
11231
|
+
];
|
|
11232
|
+
if (canWriteConfig) {
|
|
11233
|
+
choices.push({
|
|
11234
|
+
name: "Keep platform values",
|
|
11235
|
+
value: "platform-wins"
|
|
11236
|
+
});
|
|
11237
|
+
}
|
|
11238
|
+
choices.push({ name: "Cancel", value: "cancel" });
|
|
11239
|
+
const decision = await select5({
|
|
11240
|
+
message: "How do you want to proceed?",
|
|
11241
|
+
choices,
|
|
11242
|
+
default: "config-wins"
|
|
11243
|
+
});
|
|
11244
|
+
if (decision === "cancel") {
|
|
11245
|
+
return false;
|
|
11246
|
+
}
|
|
11247
|
+
if (decision === "config-wins") {
|
|
11248
|
+
return true;
|
|
11249
|
+
}
|
|
11250
|
+
return await applyPlatformValuesToLocalConfig({ context: context2, rows, remoteGame });
|
|
11251
|
+
}
|
|
11252
|
+
var AUTO_RESOLVABLE_METADATA_KEYS = /* @__PURE__ */ new Set(["description", "emoji"]);
|
|
11253
|
+
async function applyPlatformValuesToLocalConfig(args) {
|
|
11254
|
+
const { context: context2, rows, remoteGame } = args;
|
|
11255
|
+
if (!context2.configFileName) {
|
|
11256
|
+
logger.admonition("warning", "Cannot rewrite config", [
|
|
11257
|
+
"No `playcademy.config.{js,json}` file was found for this project; falling back to deploying with your local values."
|
|
11258
|
+
]);
|
|
11259
|
+
return true;
|
|
11260
|
+
}
|
|
11261
|
+
let writeDisplayName = rows.some((r) => r.label === DASHBOARD_DRIFT_LABELS.displayName);
|
|
11262
|
+
if (writeDisplayName) {
|
|
11263
|
+
const acknowledgedSlugChange = await confirmDisplayNameSlugChange(context2, remoteGame);
|
|
11264
|
+
if (!acknowledgedSlugChange) {
|
|
11265
|
+
writeDisplayName = false;
|
|
11266
|
+
}
|
|
11267
|
+
}
|
|
11268
|
+
const { updates, unresolvableLabels } = buildScalarUpdatesFromDrift({
|
|
11269
|
+
rows,
|
|
11270
|
+
remoteGame,
|
|
11271
|
+
writeDisplayName
|
|
11272
|
+
});
|
|
11273
|
+
applyUpdatesToContext(context2, updates, writeDisplayName);
|
|
11274
|
+
const configPath = join38(context2.projectPath, context2.configFileName);
|
|
11275
|
+
const result = await updateConfigScalars(configPath, updates);
|
|
11276
|
+
reportConfigUpdate(result, unresolvableLabels, context2.configFileName);
|
|
11277
|
+
return true;
|
|
11278
|
+
}
|
|
11279
|
+
function buildScalarUpdatesFromDrift(args) {
|
|
11280
|
+
const { rows, remoteGame, writeDisplayName } = args;
|
|
11281
|
+
const updates = {};
|
|
11282
|
+
const unresolvableLabels = [];
|
|
11283
|
+
for (const row of rows) {
|
|
11284
|
+
const decision = classifyDriftRow(row, remoteGame, writeDisplayName);
|
|
11285
|
+
if (decision.kind === "write") {
|
|
11286
|
+
applyDecisionToUpdates(updates, decision);
|
|
11287
|
+
} else if (decision.kind === "unresolvable") {
|
|
11288
|
+
unresolvableLabels.push(row.label);
|
|
11289
|
+
}
|
|
11290
|
+
}
|
|
11291
|
+
return { updates, unresolvableLabels };
|
|
11292
|
+
}
|
|
11293
|
+
function classifyDriftRow(row, remoteGame, writeDisplayName) {
|
|
11294
|
+
if (row.label === DASHBOARD_DRIFT_LABELS.displayName) {
|
|
11295
|
+
if (!writeDisplayName) {
|
|
11296
|
+
return { kind: "skip" };
|
|
11297
|
+
}
|
|
11298
|
+
if (typeof remoteGame.displayName !== "string") {
|
|
11299
|
+
return { kind: "unresolvable" };
|
|
11300
|
+
}
|
|
11301
|
+
return { kind: "write", field: "name", value: remoteGame.displayName };
|
|
11302
|
+
}
|
|
11303
|
+
if (row.label === DASHBOARD_DRIFT_LABELS.platform) {
|
|
11304
|
+
if (typeof remoteGame.platform !== "string") {
|
|
11305
|
+
return { kind: "unresolvable" };
|
|
11306
|
+
}
|
|
11307
|
+
return { kind: "write", field: "platform", value: remoteGame.platform };
|
|
11308
|
+
}
|
|
11309
|
+
if (!row.label.startsWith(DASHBOARD_DRIFT_LABELS.metadataPrefix)) {
|
|
11310
|
+
return { kind: "skip" };
|
|
11311
|
+
}
|
|
11312
|
+
const key = row.label.slice(DASHBOARD_DRIFT_LABELS.metadataPrefix.length);
|
|
11313
|
+
if (!AUTO_RESOLVABLE_METADATA_KEYS.has(key)) {
|
|
11314
|
+
return { kind: "unresolvable" };
|
|
11315
|
+
}
|
|
11316
|
+
const remoteValue = remoteGame.metadata?.[key];
|
|
11317
|
+
if (typeof remoteValue !== "string" && remoteValue !== void 0) {
|
|
11318
|
+
return { kind: "unresolvable" };
|
|
11319
|
+
}
|
|
11320
|
+
const value = remoteValue ?? null;
|
|
11321
|
+
if (key === "description") {
|
|
11322
|
+
return { kind: "write", field: "description", value };
|
|
11323
|
+
}
|
|
11324
|
+
if (key === "emoji") {
|
|
11325
|
+
return { kind: "write", field: "emoji", value };
|
|
11326
|
+
}
|
|
11327
|
+
return { kind: "unresolvable" };
|
|
11328
|
+
}
|
|
11329
|
+
function applyDecisionToUpdates(updates, decision) {
|
|
11330
|
+
if (decision.field === "name" && decision.value !== null) {
|
|
11331
|
+
updates.name = decision.value;
|
|
11332
|
+
} else if (decision.field === "platform" && decision.value !== null) {
|
|
11333
|
+
updates.platform = decision.value;
|
|
11334
|
+
} else if (decision.field === "description") {
|
|
11335
|
+
updates.description = decision.value;
|
|
11336
|
+
} else if (decision.field === "emoji") {
|
|
11337
|
+
updates.emoji = decision.value;
|
|
11338
|
+
}
|
|
11339
|
+
}
|
|
11340
|
+
async function confirmDisplayNameSlugChange(context2, remoteGame) {
|
|
11341
|
+
const currentSlug = context2.config.slug ?? "(unknown)";
|
|
11342
|
+
const dashboardName = remoteGame.displayName ?? "(unset)";
|
|
11343
|
+
logger.newLine();
|
|
11344
|
+
logger.admonition("warning", "Updating `name` changes your deployment slug", [
|
|
11345
|
+
`If we rewrite \`name\` in your config to "${dashboardName}", your next deploy will derive a different slug from it.`,
|
|
11346
|
+
"",
|
|
11347
|
+
`This deploy will still target the current slug "${currentSlug}", but the next \`playcademy deploy\` will create a new game at the new slug unless you keep them aligned.`,
|
|
11348
|
+
"",
|
|
11349
|
+
"Choose No to leave `name` alone and only sync the other drifted fields."
|
|
11350
|
+
]);
|
|
11351
|
+
logger.newLine();
|
|
11352
|
+
return await confirm6({
|
|
11353
|
+
message: `Rewrite \`name\` to "${dashboardName}" and accept the slug change on the next deploy?`,
|
|
11354
|
+
default: false
|
|
11355
|
+
});
|
|
11356
|
+
}
|
|
11357
|
+
function applyUpdatesToContext(context2, updates, writeDisplayName) {
|
|
11358
|
+
if (writeDisplayName && typeof updates.name === "string") {
|
|
11359
|
+
context2.config.displayName = updates.name;
|
|
11360
|
+
if (context2.fullConfig) {
|
|
11361
|
+
context2.fullConfig.name = updates.name;
|
|
11362
|
+
}
|
|
11363
|
+
}
|
|
11364
|
+
if ("description" in updates) {
|
|
11365
|
+
context2.config.description = updates.description ?? void 0;
|
|
11366
|
+
if (context2.fullConfig) {
|
|
11367
|
+
context2.fullConfig.description = updates.description ?? void 0;
|
|
11368
|
+
}
|
|
11369
|
+
}
|
|
11370
|
+
if ("emoji" in updates) {
|
|
11371
|
+
context2.config.emoji = updates.emoji ?? void 0;
|
|
11372
|
+
if (context2.fullConfig) {
|
|
11373
|
+
context2.fullConfig.emoji = updates.emoji ?? void 0;
|
|
11374
|
+
}
|
|
11375
|
+
}
|
|
11376
|
+
if (typeof updates.platform === "string") {
|
|
11377
|
+
const narrowed = narrowToPlaycademyPlatform(updates.platform);
|
|
11378
|
+
if (narrowed) {
|
|
11379
|
+
context2.config.platform = narrowed;
|
|
11380
|
+
if (context2.fullConfig) {
|
|
11381
|
+
context2.fullConfig.platform = narrowed;
|
|
11382
|
+
}
|
|
11383
|
+
}
|
|
11384
|
+
}
|
|
11385
|
+
}
|
|
11386
|
+
var PLAYCADEMY_PLATFORM_VALUES = ["web", "unity", "godot"];
|
|
11387
|
+
function narrowToPlaycademyPlatform(value) {
|
|
11388
|
+
return PLAYCADEMY_PLATFORM_VALUES.includes(value) ? value : null;
|
|
11389
|
+
}
|
|
11390
|
+
function reportConfigUpdate(result, unresolvableLabels, configFileName) {
|
|
11391
|
+
logger.newLine();
|
|
11392
|
+
if (result.written.length > 0) {
|
|
11393
|
+
const fieldList = result.written.join(", ");
|
|
11394
|
+
logger.success(`Updated ${fieldList} in ${configFileName} to match the dashboard`);
|
|
11395
|
+
} else {
|
|
11396
|
+
logger.remark(`No fields were rewritten in ${configFileName}`, 1);
|
|
11397
|
+
}
|
|
11398
|
+
const manualLines = [];
|
|
11399
|
+
for (const skipped of result.skipped) {
|
|
11400
|
+
const target = skipped.intendedValue === null ? "(remove this field)" : `"${skipped.intendedValue}"`;
|
|
11401
|
+
if (skipped.reason === "non-literal") {
|
|
11402
|
+
manualLines.push(`\`${skipped.field}\` in ${configFileName} \u2192 set to ${target}`);
|
|
11403
|
+
} else if (skipped.reason === "removal-unsupported") {
|
|
11404
|
+
manualLines.push(`\`${skipped.field}\` in ${configFileName} \u2192 remove this field`);
|
|
11405
|
+
} else {
|
|
11406
|
+
manualLines.push(`\`${skipped.field}\` missing from ${configFileName} \u2192 add ${target}`);
|
|
11407
|
+
}
|
|
11408
|
+
}
|
|
11409
|
+
for (const label of unresolvableLabels) {
|
|
11410
|
+
manualLines.push(`${label}: not editable from the General tab; reconcile manually`);
|
|
11411
|
+
}
|
|
11412
|
+
if (manualLines.length > 0) {
|
|
11413
|
+
logger.newLine();
|
|
11414
|
+
logger.admonition("note", "Some fields need a manual update", [
|
|
11415
|
+
"These could not be rewritten automatically (dynamic expression, missing key, unsupported JS field removal, or not a user-editable field):",
|
|
11416
|
+
"",
|
|
11417
|
+
...manualLines
|
|
11418
|
+
]);
|
|
11419
|
+
}
|
|
11420
|
+
logger.newLine();
|
|
11421
|
+
}
|
|
10854
11422
|
|
|
10855
11423
|
// src/lib/deploy/output.ts
|
|
10856
11424
|
import { underline as underline2 } from "colorette";
|
|
@@ -11050,7 +11618,7 @@ function logDeploymentPlanDebug(plan, context2) {
|
|
|
11050
11618
|
|
|
11051
11619
|
// src/lib/deploy/preparation.ts
|
|
11052
11620
|
import { stat } from "node:fs/promises";
|
|
11053
|
-
import { join as
|
|
11621
|
+
import { join as join39 } from "node:path";
|
|
11054
11622
|
|
|
11055
11623
|
// ../data/src/domains/game/helpers.ts
|
|
11056
11624
|
function isHostedGame(game) {
|
|
@@ -11223,14 +11791,17 @@ var games = pgTable2("games", {
|
|
|
11223
11791
|
createdAt: timestamp2("created_at", { withTimezone: true }).defaultNow(),
|
|
11224
11792
|
updatedAt: timestamp2("updated_at", { withTimezone: true }).defaultNow()
|
|
11225
11793
|
});
|
|
11226
|
-
var gameMemberRoleEnum = pgEnum2("game_member_role", [
|
|
11794
|
+
var gameMemberRoleEnum = pgEnum2("game_member_role", [
|
|
11795
|
+
GAME_MEMBER_ROLES.OWNER,
|
|
11796
|
+
GAME_MEMBER_ROLES.COLLABORATOR
|
|
11797
|
+
]);
|
|
11227
11798
|
var gameMembers = pgTable2(
|
|
11228
11799
|
"game_members",
|
|
11229
11800
|
{
|
|
11230
11801
|
id: uuid("id").primaryKey().defaultRandom(),
|
|
11231
11802
|
gameId: uuid("game_id").notNull().references(() => games.id, { onDelete: "cascade" }),
|
|
11232
11803
|
userId: text2("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
|
|
11233
|
-
role: gameMemberRoleEnum("role").notNull().default(
|
|
11804
|
+
role: gameMemberRoleEnum("role").notNull().default(GAME_MEMBER_ROLES.COLLABORATOR),
|
|
11234
11805
|
createdAt: timestamp2("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
11235
11806
|
},
|
|
11236
11807
|
(table) => [uniqueIndex2("game_members_game_user_idx").on(table.gameId, table.userId)]
|
|
@@ -11681,8 +12252,8 @@ async function bundleAndHash(context2) {
|
|
|
11681
12252
|
});
|
|
11682
12253
|
const bundleHash = hashContent(bundle.code);
|
|
11683
12254
|
const [serverSize, dbSize] = await Promise.all([
|
|
11684
|
-
getDirectorySize(
|
|
11685
|
-
getDirectorySize(
|
|
12255
|
+
getDirectorySize(join39(context2.projectPath, SERVER_ROOT_DIRECTORY)),
|
|
12256
|
+
getDirectorySize(join39(context2.projectPath, DEFAULT_DATABASE_DIRECTORY))
|
|
11686
12257
|
]);
|
|
11687
12258
|
context2.currentBackendBundle = bundle;
|
|
11688
12259
|
context2.currentBackendBundleHash = bundleHash;
|
|
@@ -11859,18 +12430,7 @@ function hasOptionalFieldsMissing(missing) {
|
|
|
11859
12430
|
// src/lib/deploy/steps.ts
|
|
11860
12431
|
import { existsSync as existsSync28 } from "fs";
|
|
11861
12432
|
import { readFile as readFile6 } from "fs/promises";
|
|
11862
|
-
import { basename as basename3, join as
|
|
11863
|
-
function prepareGameMetadata(config) {
|
|
11864
|
-
return {
|
|
11865
|
-
displayName: config.displayName,
|
|
11866
|
-
platform: config.platform || "web",
|
|
11867
|
-
gameType: "hosted",
|
|
11868
|
-
metadata: {
|
|
11869
|
-
...config.description && { description: config.description },
|
|
11870
|
-
...config.emoji && { emoji: config.emoji }
|
|
11871
|
-
}
|
|
11872
|
-
};
|
|
11873
|
-
}
|
|
12433
|
+
import { basename as basename3, join as join40, resolve as resolve13 } from "path";
|
|
11874
12434
|
async function prepareBuildFile(buildPath) {
|
|
11875
12435
|
const resolvedPath = resolve13(buildPath);
|
|
11876
12436
|
if (resolvedPath.endsWith(".zip") && existsSync28(resolvedPath)) {
|
|
@@ -11984,7 +12544,7 @@ async function handleIntegrationConfigChanges(game, context2) {
|
|
|
11984
12544
|
}
|
|
11985
12545
|
async function deployGame(context2, shouldUploadBuild, shouldDeployBackend) {
|
|
11986
12546
|
const { client, config, fullConfig } = context2;
|
|
11987
|
-
const metadata =
|
|
12547
|
+
const metadata = buildDeployGameMetadataPayload(config);
|
|
11988
12548
|
if (!shouldUploadBuild && !shouldDeployBackend) {
|
|
11989
12549
|
const game2 = await runStep(
|
|
11990
12550
|
"Updating app metadata",
|
|
@@ -12054,8 +12614,8 @@ async function deployGame(context2, shouldUploadBuild, shouldDeployBackend) {
|
|
|
12054
12614
|
compatibilityFlags: [...BACKEND_COMPATIBILITY_FLAGS]
|
|
12055
12615
|
};
|
|
12056
12616
|
const [serverSize, dbSize] = await Promise.all([
|
|
12057
|
-
getDirectorySize(
|
|
12058
|
-
getDirectorySize(
|
|
12617
|
+
getDirectorySize(join40(context2.projectPath, SERVER_ROOT_DIRECTORY)),
|
|
12618
|
+
getDirectorySize(join40(context2.projectPath, DEFAULT_DATABASE_DIRECTORY))
|
|
12059
12619
|
]);
|
|
12060
12620
|
const isMigrateMode = Boolean(deploymentPrep.schemaInfo?.migrationTag);
|
|
12061
12621
|
backendMetadata = {
|
|
@@ -12118,7 +12678,7 @@ async function deployGame(context2, shouldUploadBuild, shouldDeployBackend) {
|
|
|
12118
12678
|
|
|
12119
12679
|
// src/lib/db/path.ts
|
|
12120
12680
|
import { copyFileSync, existsSync as existsSync29, mkdirSync as mkdirSync9, readdirSync as readdirSync4, unlinkSync } from "fs";
|
|
12121
|
-
import { join as
|
|
12681
|
+
import { join as join41 } from "path";
|
|
12122
12682
|
var DB_DIRECTORY = CLI_DIRECTORIES.DATABASE;
|
|
12123
12683
|
var INITIAL_DB_NAME = CLI_FILES.INITIAL_DATABASE;
|
|
12124
12684
|
function ensureDirectoryExists(dir) {
|
|
@@ -12127,7 +12687,7 @@ function ensureDirectoryExists(dir) {
|
|
|
12127
12687
|
}
|
|
12128
12688
|
}
|
|
12129
12689
|
function findMiniflareDatabase(dbDir) {
|
|
12130
|
-
const miniflareDir =
|
|
12690
|
+
const miniflareDir = join41(dbDir, MINIFLARE_D1_DIRECTORY);
|
|
12131
12691
|
if (!existsSync29(miniflareDir)) {
|
|
12132
12692
|
return null;
|
|
12133
12693
|
}
|
|
@@ -12135,7 +12695,7 @@ function findMiniflareDatabase(dbDir) {
|
|
|
12135
12695
|
if (sqliteFiles.length === 0) {
|
|
12136
12696
|
return null;
|
|
12137
12697
|
}
|
|
12138
|
-
return
|
|
12698
|
+
return join41(miniflareDir, sqliteFiles[0]);
|
|
12139
12699
|
}
|
|
12140
12700
|
function migrateInitialDbToTarget(initialPath, targetPath) {
|
|
12141
12701
|
if (!existsSync29(initialPath)) {
|
|
@@ -12145,7 +12705,7 @@ function migrateInitialDbToTarget(initialPath, targetPath) {
|
|
|
12145
12705
|
unlinkSync(initialPath);
|
|
12146
12706
|
}
|
|
12147
12707
|
function getDevDbPath() {
|
|
12148
|
-
const initialDbPath =
|
|
12708
|
+
const initialDbPath = join41(DB_DIRECTORY, INITIAL_DB_NAME);
|
|
12149
12709
|
ensureDirectoryExists(DB_DIRECTORY);
|
|
12150
12710
|
const miniflareDbPath = findMiniflareDatabase(DB_DIRECTORY);
|
|
12151
12711
|
if (miniflareDbPath) {
|
|
@@ -12286,10 +12846,10 @@ async function bundleSeedWorker(seedFilePath, projectPath) {
|
|
|
12286
12846
|
// src/lib/db/reset.ts
|
|
12287
12847
|
import { execSync as execSync7 } from "child_process";
|
|
12288
12848
|
import { rmSync as rmSync3 } from "fs";
|
|
12289
|
-
import { join as
|
|
12849
|
+
import { join as join42 } from "path";
|
|
12290
12850
|
async function resetDatabase(workspace, mf, options = { debug: false }) {
|
|
12291
12851
|
const { debug } = options;
|
|
12292
|
-
const dbDir =
|
|
12852
|
+
const dbDir = join42(workspace, CLI_DIRECTORIES.DATABASE);
|
|
12293
12853
|
await runStep(
|
|
12294
12854
|
"Resetting database...",
|
|
12295
12855
|
async () => {
|
|
@@ -12737,7 +13297,7 @@ import { dim as dim9 } from "colorette";
|
|
|
12737
13297
|
|
|
12738
13298
|
// src/lib/bucket/collect.ts
|
|
12739
13299
|
import { readdirSync as readdirSync5, statSync as statSync4 } from "fs";
|
|
12740
|
-
import { join as
|
|
13300
|
+
import { join as join43, relative as relative6, sep as sep3 } from "path";
|
|
12741
13301
|
function shouldSkipFile(filePath, baseDir, gitignorePatterns) {
|
|
12742
13302
|
const relativePath = relative6(baseDir, filePath);
|
|
12743
13303
|
const pathParts = relativePath.split(sep3);
|
|
@@ -12754,7 +13314,7 @@ function collectFiles(directory, baseDir, gitignorePatterns) {
|
|
|
12754
13314
|
try {
|
|
12755
13315
|
const entries = readdirSync5(directory, { withFileTypes: true });
|
|
12756
13316
|
for (const entry of entries) {
|
|
12757
|
-
const fullPath =
|
|
13317
|
+
const fullPath = join43(directory, entry.name);
|
|
12758
13318
|
if (!shouldSkipFile(fullPath, baseDir, gitignorePatterns)) {
|
|
12759
13319
|
if (entry.isDirectory()) {
|
|
12760
13320
|
files.push(...collectFiles(fullPath, baseDir, gitignorePatterns));
|
|
@@ -13727,7 +14287,7 @@ ${error.suggestion}` : error.message;
|
|
|
13727
14287
|
|
|
13728
14288
|
// src/lib/upgrade/channel.ts
|
|
13729
14289
|
import { mkdir as mkdir6, readFile as readFile7, writeFile as writeFile5 } from "node:fs/promises";
|
|
13730
|
-
import { join as
|
|
14290
|
+
import { join as join44 } from "node:path";
|
|
13731
14291
|
var RELEASE_CHANNELS = ["stable", "beta"];
|
|
13732
14292
|
var CDN_BASE_URLS = {
|
|
13733
14293
|
stable: "https://cdn.playcademy.net/cli",
|
|
@@ -13741,7 +14301,7 @@ function getLatestVersionUrl(channel) {
|
|
|
13741
14301
|
}
|
|
13742
14302
|
var CHANNEL_FILE = "channel";
|
|
13743
14303
|
function getChannelFilePath() {
|
|
13744
|
-
return
|
|
14304
|
+
return join44(CLI_USER_DIRECTORIES.CONFIG, CHANNEL_FILE);
|
|
13745
14305
|
}
|
|
13746
14306
|
function channelFromVersion(version3) {
|
|
13747
14307
|
return version3.includes("-beta") ? "beta" : "stable";
|
|
@@ -14040,6 +14600,7 @@ async function fetchLatestVersion(channel) {
|
|
|
14040
14600
|
}
|
|
14041
14601
|
export {
|
|
14042
14602
|
ConfigError,
|
|
14603
|
+
DASHBOARD_DRIFT_LABELS,
|
|
14043
14604
|
INSTALL_SCRIPT_URL,
|
|
14044
14605
|
METRICS_RESOLVER_EXTENSIONS,
|
|
14045
14606
|
METRICS_RESOLVER_PATH,
|
|
@@ -14054,6 +14615,7 @@ export {
|
|
|
14054
14615
|
applySecretsChanges,
|
|
14055
14616
|
assertVersionExists,
|
|
14056
14617
|
buildCustomRouteImportStatements,
|
|
14618
|
+
buildDeployGameMetadataPayload,
|
|
14057
14619
|
buildLogStreamUrl,
|
|
14058
14620
|
buildMetricsResolverCode,
|
|
14059
14621
|
buildMetricsResolverImportStatement,
|
|
@@ -14145,6 +14707,7 @@ export {
|
|
|
14145
14707
|
getContentType,
|
|
14146
14708
|
getCurrentProfile,
|
|
14147
14709
|
getCustomRoutesDirectory,
|
|
14710
|
+
getDashboardMetadataDriftRows,
|
|
14148
14711
|
getDatabaseDirectory,
|
|
14149
14712
|
getDeployedGame,
|
|
14150
14713
|
getDirectorySize,
|
|
@@ -14288,6 +14851,7 @@ export {
|
|
|
14288
14851
|
setCliContext,
|
|
14289
14852
|
setupGlobalErrorHandlers,
|
|
14290
14853
|
shouldSkipFile,
|
|
14854
|
+
skipsDeployGameDueToSecretsOnly,
|
|
14291
14855
|
startCallbackServer,
|
|
14292
14856
|
startDevServer,
|
|
14293
14857
|
startHotReload,
|
|
@@ -14295,6 +14859,7 @@ export {
|
|
|
14295
14859
|
transpileTypeScript,
|
|
14296
14860
|
updateBuildMetadata,
|
|
14297
14861
|
updateConfigFile,
|
|
14862
|
+
updateConfigScalars,
|
|
14298
14863
|
updateEnvExample,
|
|
14299
14864
|
updateExistingCourses,
|
|
14300
14865
|
updateViteConfig,
|
|
@@ -162,6 +162,13 @@ var init_env_vars = __esm({
|
|
|
162
162
|
}
|
|
163
163
|
});
|
|
164
164
|
|
|
165
|
+
// ../constants/src/game.ts
|
|
166
|
+
var init_game = __esm({
|
|
167
|
+
"../constants/src/game.ts"() {
|
|
168
|
+
"use strict";
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
|
|
165
172
|
// ../constants/src/overworld.ts
|
|
166
173
|
var ITEM_SLUGS, CURRENCIES, BADGES;
|
|
167
174
|
var init_overworld = __esm({
|
|
@@ -239,6 +246,7 @@ var init_src = __esm({
|
|
|
239
246
|
init_character();
|
|
240
247
|
init_domains();
|
|
241
248
|
init_env_vars();
|
|
249
|
+
init_game();
|
|
242
250
|
init_overworld();
|
|
243
251
|
init_system();
|
|
244
252
|
init_timeback();
|
|
@@ -353,9 +361,9 @@ var init_routes = __esm({
|
|
|
353
361
|
// ../edge-play/src/entry/metadata.ts
|
|
354
362
|
function getRuntimeMetadata() {
|
|
355
363
|
return {
|
|
356
|
-
cliVersion: true ? "0.22.
|
|
357
|
-
sdkVersion: true ? "0.9.
|
|
358
|
-
buildId: true ? "
|
|
364
|
+
cliVersion: true ? "0.22.1-beta.2" : "0.0.0-dev",
|
|
365
|
+
sdkVersion: true ? "0.9.1-beta.2" : "0.0.0-dev",
|
|
366
|
+
buildId: true ? "6f65f92e5aa2" : "dev-source"
|
|
359
367
|
};
|
|
360
368
|
}
|
|
361
369
|
var init_metadata = __esm({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"cliVersion": "0.22.
|
|
3
|
-
"sdkVersion": "0.9.
|
|
4
|
-
"runtimeBuildId": "
|
|
5
|
-
"inputFingerprint": "
|
|
2
|
+
"cliVersion": "0.22.1-beta.2",
|
|
3
|
+
"sdkVersion": "0.9.1-beta.2",
|
|
4
|
+
"runtimeBuildId": "6f65f92e5aa2",
|
|
5
|
+
"inputFingerprint": "6f65f92e5aa2b74c213221c4c1c80e7019bc3c6fd498df2e5ffe6d4a61d5abd6",
|
|
6
6
|
"entry": "index.js"
|
|
7
7
|
}
|
package/dist/utils.js
CHANGED
|
@@ -481,7 +481,7 @@ var DEFAULT_API_ROUTES_DIRECTORY = join2(SERVER_ROOT_DIRECTORY, "api");
|
|
|
481
481
|
// ../better-auth/package.json
|
|
482
482
|
var package_default = {
|
|
483
483
|
name: "@playcademy/better-auth",
|
|
484
|
-
version: "0.0.
|
|
484
|
+
version: "0.0.14-beta.2",
|
|
485
485
|
type: "module",
|
|
486
486
|
exports: {
|
|
487
487
|
"./server": {
|
|
@@ -2591,7 +2591,7 @@ import { existsSync as existsSync9, mkdirSync as mkdirSync2, writeFileSync as wr
|
|
|
2591
2591
|
import { dirname as dirname4, join as join14 } from "node:path";
|
|
2592
2592
|
|
|
2593
2593
|
// src/version.ts
|
|
2594
|
-
var cliVersion = false ? "0.0.0-dev" : "0.22.
|
|
2594
|
+
var cliVersion = false ? "0.0.0-dev" : "0.22.1-beta.2";
|
|
2595
2595
|
|
|
2596
2596
|
// src/lib/build/binary-resource.ts
|
|
2597
2597
|
function writeFileTree(baseDir, files) {
|
package/dist/version.js
CHANGED