@puzzmo/cli 1.0.36 → 1.0.38
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/lib/commands/upload.d.ts +1 -1
- package/lib/commands/upload.js +126 -54
- package/lib/commands/upload.js.map +1 -1
- package/lib/commands/validate.d.ts +1 -1
- package/lib/commands/validate.js +24 -31
- package/lib/commands/validate.js.map +1 -1
- package/lib/index.js +3 -7
- package/lib/index.js.map +1 -1
- package/lib/util/api.d.ts +7 -0
- package/lib/util/api.js +6 -4
- package/lib/util/api.js.map +1 -1
- package/lib/util/discoverGames.d.ts +25 -0
- package/lib/util/discoverGames.js +181 -0
- package/lib/util/discoverGames.js.map +1 -0
- package/lib/util/validatePuzzmoFile.d.ts +1 -1
- package/lib/util/validatePuzzmoFile.js +2 -2
- package/lib/util/validatePuzzmoFile.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/upload.ts +149 -53
- package/src/commands/validate.ts +23 -30
- package/src/index.ts +3 -7
- package/src/util/api.ts +20 -4
- package/src/util/discoverGames.ts +203 -0
- package/src/util/validatePuzzmoFile.ts +2 -2
package/lib/commands/upload.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
type UploadOptions = {
|
|
2
2
|
verbose?: boolean;
|
|
3
3
|
};
|
|
4
|
-
/** Uploads game build artifacts to Puzzmo */
|
|
4
|
+
/** Uploads game build artifacts to Puzzmo by discovering puzzmo.json files in `dir` */
|
|
5
5
|
export declare const upload: (dir: string, options?: UploadOptions) => Promise<void>;
|
|
6
6
|
export {};
|
package/lib/commands/upload.js
CHANGED
|
@@ -4,8 +4,8 @@ import fs from "node:fs";
|
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { uploadFiles } from "../util/api.js";
|
|
6
6
|
import { getAPIURL, getToken } from "../util/config.js";
|
|
7
|
-
import {
|
|
8
|
-
/** Uploads game build artifacts to Puzzmo */
|
|
7
|
+
import { discoverGames } from "../util/discoverGames.js";
|
|
8
|
+
/** Uploads game build artifacts to Puzzmo by discovering puzzmo.json files in `dir` */
|
|
9
9
|
export const upload = async (dir, options = {}) => {
|
|
10
10
|
const { verbose = false } = options;
|
|
11
11
|
const token = getToken();
|
|
@@ -13,64 +13,99 @@ export const upload = async (dir, options = {}) => {
|
|
|
13
13
|
console.error("Not logged in. Run `puzzmo login <token>` or set PUZZMO_TOKEN.");
|
|
14
14
|
process.exit(1);
|
|
15
15
|
}
|
|
16
|
-
const
|
|
17
|
-
if (!fs.existsSync(
|
|
16
|
+
const rootDir = path.resolve(dir);
|
|
17
|
+
if (!fs.existsSync(rootDir)) {
|
|
18
18
|
console.error(`Directory not found: ${dir}`);
|
|
19
19
|
process.exit(1);
|
|
20
20
|
}
|
|
21
|
-
const
|
|
22
|
-
if (!
|
|
23
|
-
console.error(`
|
|
21
|
+
const { games, errors: discoveryErrors } = await discoverGames(rootDir);
|
|
22
|
+
if (!games.length && !discoveryErrors.length) {
|
|
23
|
+
console.error(`No puzzmo.json files found under ${rootDir}`);
|
|
24
24
|
process.exit(1);
|
|
25
25
|
}
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
console.error(`Missing puzzmo.json in ${dir}`);
|
|
30
|
-
console.error("Every game upload must include a puzzmo.json file.");
|
|
31
|
-
process.exit(1);
|
|
26
|
+
console.log(`Found ${games.length} game(s) under ${rootDir}`);
|
|
27
|
+
for (const game of games) {
|
|
28
|
+
console.log(` - ${game.puzzmoFile.game.slug} (${path.relative(rootDir, game.distDir) || "."})`);
|
|
32
29
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
30
|
+
if (discoveryErrors.length) {
|
|
31
|
+
console.log(`\n${discoveryErrors.length} puzzmo.json file(s) could not be loaded:`);
|
|
32
|
+
for (const err of discoveryErrors) {
|
|
33
|
+
console.log(` - ${err.slug ?? path.relative(rootDir, err.puzzmoJsonPath)}`);
|
|
34
|
+
for (const e of err.errors)
|
|
35
|
+
console.log(` ${e}`);
|
|
36
|
+
}
|
|
36
37
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
const sha = getGitSHA(rootDir) || hashGames(games);
|
|
39
|
+
const description = getGitMessage(rootDir);
|
|
40
|
+
const repoURL = getGitRepoURL(rootDir);
|
|
41
|
+
if (description)
|
|
42
|
+
console.log(`\nMessage: ${description}`);
|
|
43
|
+
if (repoURL)
|
|
44
|
+
console.log(`Repo: ${repoURL}`);
|
|
45
|
+
const apiURL = getAPIURL();
|
|
46
|
+
const defaultURL = "https://api.puzzmo.com";
|
|
47
|
+
if (apiURL !== defaultURL)
|
|
48
|
+
console.log(`API: ${apiURL}`);
|
|
49
|
+
const results = [];
|
|
50
|
+
for (const err of discoveryErrors) {
|
|
51
|
+
results.push({ ok: false, slug: err.slug ?? path.relative(rootDir, err.puzzmoJsonPath), error: err.errors.join("; ") });
|
|
40
52
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
console.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
53
|
+
for (let i = 0; i < games.length; i++) {
|
|
54
|
+
const game = games[i];
|
|
55
|
+
console.log(`\n[${i + 1}/${games.length}] Uploading ${game.puzzmoFile.game.slug}`);
|
|
56
|
+
try {
|
|
57
|
+
const result = await uploadOneGame(game, { token, sha, description, repoURL, verbose, rootDir });
|
|
58
|
+
results.push(result);
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
62
|
+
console.error(` Failed: ${message}`);
|
|
63
|
+
results.push({ ok: false, slug: game.puzzmoFile.game.slug, error: message });
|
|
64
|
+
}
|
|
47
65
|
}
|
|
48
|
-
|
|
66
|
+
printReport(results);
|
|
67
|
+
const anyFailed = results.some((r) => !r.ok);
|
|
68
|
+
if (anyFailed)
|
|
69
|
+
process.exit(1);
|
|
70
|
+
};
|
|
71
|
+
/** Uploads a single discovered game; throws on failure */
|
|
72
|
+
const uploadOneGame = async (game, opts) => {
|
|
73
|
+
const { token, sha, description, repoURL, verbose, rootDir } = opts;
|
|
74
|
+
const { puzzmoFile, distDir } = game;
|
|
49
75
|
const gameSlug = puzzmoFile.game.slug;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
console.log(`Directory: ${distDir}`);
|
|
54
|
-
console.log("");
|
|
76
|
+
const files = collectFiles(distDir);
|
|
77
|
+
if (!files.length)
|
|
78
|
+
throw new Error(`Dist folder is empty: ${distDir}`);
|
|
79
|
+
console.log(` Directory: ${path.relative(rootDir, distDir) || distDir}`);
|
|
55
80
|
let totalBytes = 0;
|
|
56
|
-
for (const file of files)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const rel = path.relative(distDir, file);
|
|
60
|
-
console.log(` ${rel} (${formatBytes(size)})`);
|
|
61
|
-
}
|
|
62
|
-
const apiURL = getAPIURL();
|
|
63
|
-
const defaultURL = "https://api.puzzmo.com";
|
|
64
|
-
console.log(`\n${files.length} file(s), ${formatBytes(totalBytes)} total`);
|
|
65
|
-
if (apiURL !== defaultURL)
|
|
66
|
-
console.log(`Uploading to ${apiURL}...`);
|
|
67
|
-
else
|
|
68
|
-
console.log("Uploading...");
|
|
81
|
+
for (const file of files)
|
|
82
|
+
totalBytes += fs.statSync(file).size;
|
|
83
|
+
console.log(` ${files.length} file(s), ${formatBytes(totalBytes)} total (sha ${sha.slice(0, 8)})`);
|
|
69
84
|
const result = await uploadFiles(token, gameSlug, sha, files, distDir, puzzmoFile, (batch, totalBatches, uploaded) => {
|
|
70
|
-
console.log(`
|
|
71
|
-
}, { verbose });
|
|
72
|
-
console.log(
|
|
73
|
-
|
|
85
|
+
console.log(` Batch ${batch}/${totalBatches} done (${uploaded} file(s) uploaded)`);
|
|
86
|
+
}, { verbose, description, repoURL });
|
|
87
|
+
console.log(` Done - ${result.versionID}`);
|
|
88
|
+
return {
|
|
89
|
+
ok: true,
|
|
90
|
+
slug: gameSlug,
|
|
91
|
+
fileCount: files.length,
|
|
92
|
+
totalBytes,
|
|
93
|
+
versionID: result.versionID,
|
|
94
|
+
assetsBase: result.assetsBase,
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
/** Prints a final summary of every game's outcome */
|
|
98
|
+
const printReport = (results) => {
|
|
99
|
+
console.log(`\nUpload report (${results.length} game${results.length === 1 ? "" : "s"})`);
|
|
100
|
+
const successes = results.filter((r) => r.ok);
|
|
101
|
+
const failures = results.filter((r) => !r.ok);
|
|
102
|
+
for (const r of successes) {
|
|
103
|
+
console.log(` OK ${r.slug.padEnd(24)} ${formatBytes(r.totalBytes).padStart(8)} ${r.versionID}`);
|
|
104
|
+
}
|
|
105
|
+
for (const r of failures) {
|
|
106
|
+
console.log(` FAIL ${r.slug.padEnd(24)} ${r.error}`);
|
|
107
|
+
}
|
|
108
|
+
console.log(`\n${successes.length} succeeded, ${failures.length} failed`);
|
|
74
109
|
};
|
|
75
110
|
/** Collects all files in a directory recursively */
|
|
76
111
|
const collectFiles = (dir) => {
|
|
@@ -86,19 +121,56 @@ const collectFiles = (dir) => {
|
|
|
86
121
|
return files;
|
|
87
122
|
};
|
|
88
123
|
/** Tries to get the shortest unique git SHA, returns null if not in a git repo */
|
|
89
|
-
const getGitSHA = () => {
|
|
124
|
+
const getGitSHA = (cwd) => {
|
|
125
|
+
try {
|
|
126
|
+
return execSync("git rev-parse --short HEAD", { encoding: "utf-8", cwd }).trim();
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
/** Gets the subject line of the latest commit, or null if not in a git repo */
|
|
133
|
+
const getGitMessage = (cwd) => {
|
|
90
134
|
try {
|
|
91
|
-
return execSync("git
|
|
135
|
+
return execSync("git log -1 --pretty=%s", { encoding: "utf-8", cwd }).trim() || null;
|
|
92
136
|
}
|
|
93
137
|
catch {
|
|
94
138
|
return null;
|
|
95
139
|
}
|
|
96
140
|
};
|
|
97
|
-
/**
|
|
98
|
-
const
|
|
141
|
+
/** Gets the origin remote URL normalized to https, or null if unavailable */
|
|
142
|
+
const getGitRepoURL = (cwd) => {
|
|
143
|
+
try {
|
|
144
|
+
const raw = execSync("git config --get remote.origin.url", { encoding: "utf-8", cwd }).trim();
|
|
145
|
+
return raw ? normalizeRepoURL(raw) : null;
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
/** Converts SSH-style git URLs to https; strips trailing .git */
|
|
152
|
+
const normalizeRepoURL = (url) => {
|
|
153
|
+
let normalized = url;
|
|
154
|
+
// git@host:owner/repo(.git) -> https://host/owner/repo
|
|
155
|
+
const sshMatch = normalized.match(/^git@([^:]+):(.+)$/);
|
|
156
|
+
if (sshMatch)
|
|
157
|
+
normalized = `https://${sshMatch[1]}/${sshMatch[2]}`;
|
|
158
|
+
// ssh://git@host/owner/repo(.git) -> https://host/owner/repo
|
|
159
|
+
else if (normalized.startsWith("ssh://"))
|
|
160
|
+
normalized = normalized.replace(/^ssh:\/\/(?:[^@]+@)?/, "https://");
|
|
161
|
+
// git://host/owner/repo(.git) -> https://host/owner/repo
|
|
162
|
+
else if (normalized.startsWith("git://"))
|
|
163
|
+
normalized = normalized.replace(/^git:\/\//, "https://");
|
|
164
|
+
return normalized.replace(/\.git$/, "");
|
|
165
|
+
};
|
|
166
|
+
/** Hashes the dist contents of every game to produce a deterministic SHA across all uploads */
|
|
167
|
+
const hashGames = (games) => {
|
|
99
168
|
const hash = crypto.createHash("sha256");
|
|
100
|
-
for (const
|
|
101
|
-
|
|
169
|
+
for (const game of games) {
|
|
170
|
+
for (const file of collectFiles(game.distDir).sort()) {
|
|
171
|
+
hash.update(file);
|
|
172
|
+
hash.update(fs.readFileSync(file));
|
|
173
|
+
}
|
|
102
174
|
}
|
|
103
175
|
return hash.digest("hex").slice(0, 12);
|
|
104
176
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../src/commands/upload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC7C,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../src/commands/upload.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/** CLI command: puzzmo validate [dir] */
|
|
1
|
+
/** CLI command: puzzmo validate [dir] — discovers every puzzmo.json under dir and validates each */
|
|
2
2
|
export declare const validate: (dir: string) => Promise<void>;
|
package/lib/commands/validate.js
CHANGED
|
@@ -1,43 +1,36 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import {
|
|
4
|
-
/** CLI command: puzzmo validate [dir] */
|
|
3
|
+
import { discoverGames } from "../util/discoverGames.js";
|
|
4
|
+
/** CLI command: puzzmo validate [dir] — discovers every puzzmo.json under dir and validates each */
|
|
5
5
|
export const validate = async (dir) => {
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
console.error(`No puzzmo.json found in ${dir}`);
|
|
6
|
+
const rootDir = path.resolve(dir);
|
|
7
|
+
if (!fs.existsSync(rootDir)) {
|
|
8
|
+
console.error(`Directory not found: ${dir}`);
|
|
10
9
|
process.exit(1);
|
|
11
10
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
catch (e) {
|
|
17
|
-
console.error(`Could not read puzzmo.json: ${e instanceof Error ? e.message : e}`);
|
|
11
|
+
const { games, errors } = await discoverGames(rootDir);
|
|
12
|
+
if (!games.length && !errors.length) {
|
|
13
|
+
console.error(`No puzzmo.json files found under ${rootDir}`);
|
|
18
14
|
process.exit(1);
|
|
19
15
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
for (const game of games) {
|
|
17
|
+
const rel = path.relative(rootDir, game.puzzmoJsonPath) || game.puzzmoJsonPath;
|
|
18
|
+
const integrations = game.puzzmoFile.integrations ? Object.keys(game.puzzmoFile.integrations) : [];
|
|
19
|
+
const distRel = path.relative(rootDir, game.distDir) || game.distDir;
|
|
20
|
+
console.log(`OK ${game.puzzmoFile.game.slug.padEnd(24)} (${rel})`);
|
|
21
|
+
console.log(` dist: ${distRel}`);
|
|
22
|
+
if (integrations.length)
|
|
23
|
+
console.log(` integrations: ${integrations.join(", ")}`);
|
|
23
24
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
for (const err of errors) {
|
|
26
|
+
const rel = path.relative(rootDir, err.puzzmoJsonPath) || err.puzzmoJsonPath;
|
|
27
|
+
const label = err.slug ?? rel;
|
|
28
|
+
console.error(`FAIL ${label.padEnd(24)} (${rel})`);
|
|
29
|
+
for (const e of err.errors)
|
|
30
|
+
console.error(` ${e}`);
|
|
27
31
|
}
|
|
28
|
-
|
|
29
|
-
if (
|
|
30
|
-
console.error(`puzzmo.json has ${result.errors.length} error(s):\n`);
|
|
31
|
-
for (const err of result.errors)
|
|
32
|
-
console.error(` ${err}`);
|
|
32
|
+
console.log(`\n${games.length} valid, ${errors.length} invalid`);
|
|
33
|
+
if (errors.length)
|
|
33
34
|
process.exit(1);
|
|
34
|
-
}
|
|
35
|
-
const { data: puzzmoFile } = result;
|
|
36
|
-
console.log(`Valid puzzmo.json for "${puzzmoFile.game.displayName}" (${puzzmoFile.game.slug})`);
|
|
37
|
-
if (puzzmoFile.integrations) {
|
|
38
|
-
const keys = Object.keys(puzzmoFile.integrations);
|
|
39
|
-
if (keys.length)
|
|
40
|
-
console.log(`Integrations: ${keys.join(", ")}`);
|
|
41
|
-
}
|
|
42
35
|
};
|
|
43
36
|
//# sourceMappingURL=validate.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAExD,sGAAoG;AACpG,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,EAAE,GAAW,EAAE,EAAE,CAAC;IAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IACjC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,KAAK,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAA;QAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC,CAAA;IAEtD,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACpC,OAAO,CAAC,KAAK,CAAC,oCAAoC,OAAO,EAAE,CAAC,CAAA;QAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,IAAI,CAAC,cAAc,CAAA;QAC9E,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QAClG,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAA;QACpE,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,CAAA;QACpE,OAAO,CAAC,GAAG,CAAC,cAAc,OAAO,EAAE,CAAC,CAAA;QACpC,IAAI,YAAY,CAAC,MAAM;YAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACvF,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,cAAc,CAAC,IAAI,GAAG,CAAC,cAAc,CAAA;QAC5E,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,IAAI,GAAG,CAAA;QAC7B,OAAO,CAAC,KAAK,CAAC,QAAQ,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,CAAA;QAClD,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM;YAAE,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;IACxD,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,MAAM,WAAW,MAAM,CAAC,MAAM,UAAU,CAAC,CAAA;IAChE,IAAI,MAAM,CAAC,MAAM;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AAAA,CACnC,CAAA"}
|
package/lib/index.js
CHANGED
|
@@ -11,8 +11,8 @@ const printUsage = () => {
|
|
|
11
11
|
puzzmo login <token> Save a CLI auth token
|
|
12
12
|
puzzmo game create [token] Create a new Puzzmo game project
|
|
13
13
|
|
|
14
|
-
puzzmo upload
|
|
15
|
-
puzzmo validate [dir]
|
|
14
|
+
puzzmo upload [dir] [-v] Discover puzzmo.json files in [dir] (default: .) and upload each game's build. -v/--verbose prints request URLs and full error bodies.
|
|
15
|
+
puzzmo validate [dir] Discover and validate every puzzmo.json under [dir] (default: .)
|
|
16
16
|
puzzmo migrate List and select migration skills from dev.puzzmo.com`);
|
|
17
17
|
};
|
|
18
18
|
const run = async () => {
|
|
@@ -28,11 +28,7 @@ const run = async () => {
|
|
|
28
28
|
}
|
|
29
29
|
case "upload": {
|
|
30
30
|
const verbose = args.includes("--verbose") || args.includes("-v");
|
|
31
|
-
const dir = args.find((a) => !a.startsWith("-"));
|
|
32
|
-
if (!dir) {
|
|
33
|
-
console.error("Usage: puzzmo upload <dir> [-v|--verbose]");
|
|
34
|
-
process.exit(1);
|
|
35
|
-
}
|
|
31
|
+
const dir = args.find((a) => !a.startsWith("-")) ?? ".";
|
|
36
32
|
await upload(dir, { verbose });
|
|
37
33
|
break;
|
|
38
34
|
}
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAE/C,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;AAEhD,MAAM,UAAU,GAAG,GAAG,EAAE,CAAC;IACvB,OAAO,CAAC,GAAG,CAAC;;;;;;uFAMyE,CAAC,CAAA;AAAA,CACvF,CAAA;AAED,MAAM,GAAG,GAAG,KAAK,IAAI,EAAE,CAAC;IACtB,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,OAAO,EAAE,CAAC;YACb,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;YACrB,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAA;gBAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACjB,CAAC;YACD,KAAK,CAAC,KAAK,CAAC,CAAA;YACZ,MAAK;QACP,CAAC;QACD,KAAK,QAAQ,EAAE,CAAC;YACd,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;YACjE,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/lib/util/api.d.ts
CHANGED
|
@@ -6,6 +6,9 @@ export type PuzzmoFile = {
|
|
|
6
6
|
teamID: string;
|
|
7
7
|
};
|
|
8
8
|
integrations?: Record<string, unknown>;
|
|
9
|
+
output?: {
|
|
10
|
+
dir: string;
|
|
11
|
+
};
|
|
9
12
|
};
|
|
10
13
|
type CompleteResponse = {
|
|
11
14
|
assetsBase: string;
|
|
@@ -17,6 +20,10 @@ export type UploadProgress = (batch: number, totalBatches: number, uploaded: num
|
|
|
17
20
|
/** Options for uploadFiles */
|
|
18
21
|
export type UploadFilesOptions = {
|
|
19
22
|
verbose?: boolean;
|
|
23
|
+
/** Commit message subject for the new GameRuntimeVersion */
|
|
24
|
+
description?: string | null;
|
|
25
|
+
/** HTTPS repo URL to set on the GameRuntime */
|
|
26
|
+
repoURL?: string | null;
|
|
20
27
|
};
|
|
21
28
|
/** Multi-step upload: init -> batched file uploads -> complete */
|
|
22
29
|
export declare const uploadFiles: (token: string, gameSlug: string, sha: string, filePaths: string[], baseDir: string, puzzmoFile: PuzzmoFile, onProgress?: UploadProgress | undefined, options?: UploadFilesOptions) => Promise<CompleteResponse>;
|
package/lib/util/api.js
CHANGED
|
@@ -35,9 +35,11 @@ const readResponse = async (res, url, step, verbose) => {
|
|
|
35
35
|
throw new Error(`Invalid JSON response during ${step} (${url}): ${verbose ? text : text.slice(0, 200)}`);
|
|
36
36
|
}
|
|
37
37
|
if (!res.ok) {
|
|
38
|
-
const
|
|
38
|
+
const body = json;
|
|
39
|
+
const serverMsg = body.error || res.statusText || "Unknown error";
|
|
40
|
+
const validation = body.validationErrors?.length ? `\n - ${body.validationErrors.join("\n - ")}` : "";
|
|
39
41
|
const detail = verbose ? `\n${JSON.stringify(json, null, 2)}` : "";
|
|
40
|
-
throw new Error(`Server error during ${step} (${res.status} from ${url}): ${serverMsg}${detail}`);
|
|
42
|
+
throw new Error(`Server error during ${step} (${res.status} from ${url}): ${serverMsg}${validation}${detail}`);
|
|
41
43
|
}
|
|
42
44
|
return json;
|
|
43
45
|
};
|
|
@@ -68,12 +70,12 @@ const uploadFile = async (url, token, filePath, baseDir, verbose) => {
|
|
|
68
70
|
};
|
|
69
71
|
/** Multi-step upload: init -> batched file uploads -> complete */
|
|
70
72
|
export const uploadFiles = async (token, gameSlug, sha, filePaths, baseDir, puzzmoFile, onProgress, options = {}) => {
|
|
71
|
-
const { verbose = false } = options;
|
|
73
|
+
const { verbose = false, description, repoURL } = options;
|
|
72
74
|
const apiURL = getAPIURL();
|
|
73
75
|
if (verbose)
|
|
74
76
|
console.log(` API URL: ${apiURL}`);
|
|
75
77
|
// Step 1: Init session (includes puzzmo.json metadata)
|
|
76
|
-
const init = (await jsonPost(`${apiURL}/cliUpload`, token, { gameSlug, sha, puzzmoFile }, "upload init", verbose));
|
|
78
|
+
const init = (await jsonPost(`${apiURL}/cliUpload`, token, { gameSlug, sha, puzzmoFile, description, repoURL }, "upload init", verbose));
|
|
77
79
|
if (verbose)
|
|
78
80
|
console.log(` session: ${init.sessionID}`);
|
|
79
81
|
// Step 2: Upload files in concurrent batches
|
package/lib/util/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/util/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/util/api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { PuzzmoFile } from "./api.js";
|
|
2
|
+
/** A game discovered in the repo, with its parsed puzzmo.json and resolved dist directory */
|
|
3
|
+
export type DiscoveredGame = {
|
|
4
|
+
/** Absolute path to the puzzmo.json file */
|
|
5
|
+
puzzmoJsonPath: string;
|
|
6
|
+
/** Directory containing the puzzmo.json file */
|
|
7
|
+
puzzmoJsonDir: string;
|
|
8
|
+
/** Validated puzzmo.json contents */
|
|
9
|
+
puzzmoFile: PuzzmoFile;
|
|
10
|
+
/** Absolute path to the dist directory containing the build artifacts */
|
|
11
|
+
distDir: string;
|
|
12
|
+
};
|
|
13
|
+
/** A puzzmo.json that was found but could not be used (invalid JSON, schema errors, missing dist) */
|
|
14
|
+
export type DiscoveryError = {
|
|
15
|
+
puzzmoJsonPath: string;
|
|
16
|
+
/** Slug pulled from the file when available, used for reporting */
|
|
17
|
+
slug?: string;
|
|
18
|
+
errors: string[];
|
|
19
|
+
};
|
|
20
|
+
export type DiscoveryResult = {
|
|
21
|
+
games: DiscoveredGame[];
|
|
22
|
+
errors: DiscoveryError[];
|
|
23
|
+
};
|
|
24
|
+
/** Walks `rootDir` looking for puzzmo.json files, validates each, and resolves their dist directory */
|
|
25
|
+
export declare const discoverGames: (rootDir: string) => Promise<DiscoveryResult>;
|