@puzzmo/cli 1.0.47 → 1.0.49
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.js +78 -36
- package/lib/commands/upload.js.map +1 -1
- package/lib/util/api.d.ts +1 -0
- package/lib/util/api.js +1 -2
- package/lib/util/api.js.map +1 -1
- package/package.json +1 -1
- package/schemas/puzzmo-file-schema.json +338 -0
- package/src/commands/upload.ts +88 -35
- package/src/util/api.ts +18 -4
- package/templates/minesweeper/puzzmo.json +1 -1
package/lib/commands/upload.js
CHANGED
|
@@ -4,7 +4,7 @@ import fs from "node:fs";
|
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import * as p from "@clack/prompts";
|
|
6
6
|
import { GameNotFoundError, uploadFiles } from "../util/api.js";
|
|
7
|
-
import { findTokensForTeam, getTokens, resolveServerForTeam, sourceToURL } from "../util/config.js";
|
|
7
|
+
import { defaultSource, findTokensForTeam, getTokens, normalizeSource, resolveServerForTeam, sourceToURL, } from "../util/config.js";
|
|
8
8
|
import { createUserGame } from "../util/createGame.js";
|
|
9
9
|
import { discoverGames } from "../util/discoverGames.js";
|
|
10
10
|
/** Uploads game build artifacts to Puzzmo by discovering puzzmo.json files in `dir` */
|
|
@@ -24,25 +24,26 @@ export const upload = async (dir, options = {}) => {
|
|
|
24
24
|
console.error(`No puzzmo.json files found under ${rootDir}`);
|
|
25
25
|
process.exit(1);
|
|
26
26
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
console.log(`
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
console.log(
|
|
35
|
-
for (const
|
|
36
|
-
console.log(`
|
|
27
|
+
const multi = games.length + discoveryErrors.length > 1;
|
|
28
|
+
if (multi) {
|
|
29
|
+
console.log(`Found ${plural(games.length, "game")} under ${rootDir}`);
|
|
30
|
+
for (const game of games) {
|
|
31
|
+
console.log(` - ${game.puzzmoFile.game.slug} (${path.relative(rootDir, game.distDir) || "."})`);
|
|
32
|
+
}
|
|
33
|
+
if (discoveryErrors.length) {
|
|
34
|
+
console.log(`\n${plural(discoveryErrors.length, "puzzmo.json file")} could not be loaded:`);
|
|
35
|
+
for (const err of discoveryErrors) {
|
|
36
|
+
console.log(` - ${err.slug ?? path.relative(rootDir, err.puzzmoJsonPath)}`);
|
|
37
|
+
for (const e of err.errors)
|
|
38
|
+
console.log(` ${e}`);
|
|
39
|
+
}
|
|
37
40
|
}
|
|
38
41
|
}
|
|
39
42
|
const sha = getGitSHA(rootDir) || hashGames(games);
|
|
40
43
|
const description = getGitMessage(rootDir);
|
|
41
44
|
const repoURL = getGitRepoURL(rootDir);
|
|
42
|
-
if (description)
|
|
45
|
+
if (description && multi)
|
|
43
46
|
console.log(`\nMessage: ${description}`);
|
|
44
|
-
if (repoURL)
|
|
45
|
-
console.log(`Repo: ${repoURL}`);
|
|
46
47
|
const results = [];
|
|
47
48
|
for (const err of discoveryErrors) {
|
|
48
49
|
results.push({ ok: false, slug: err.slug ?? path.relative(rootDir, err.puzzmoJsonPath), error: err.errors.join("; ") });
|
|
@@ -50,7 +51,8 @@ export const upload = async (dir, options = {}) => {
|
|
|
50
51
|
for (let i = 0; i < games.length; i++) {
|
|
51
52
|
const game = games[i];
|
|
52
53
|
const slug = game.puzzmoFile.game.slug;
|
|
53
|
-
|
|
54
|
+
const prefix = multi ? `[${i + 1}/${games.length}] ` : "";
|
|
55
|
+
const distLabel = path.relative(rootDir, game.distDir) || ".";
|
|
54
56
|
const teamID = game.puzzmoFile.game.teamID;
|
|
55
57
|
const credential = await resolveServerForTeam(teamID);
|
|
56
58
|
if (!credential) {
|
|
@@ -58,16 +60,20 @@ export const upload = async (dir, options = {}) => {
|
|
|
58
60
|
const message = matches.length === 0
|
|
59
61
|
? `No saved token for team ${teamID}. Run \`puzzmo login <token>\` (use \`--source\` if the token is for a non-default server).`
|
|
60
62
|
: `Token for team ${teamID} is registered against ${matches.map((m) => m.source).join(", ")} but none of those servers are reachable.`;
|
|
61
|
-
console.error(
|
|
63
|
+
console.error(`\n${prefix}Uploading ${slug} from ${distLabel}\n ${message}`);
|
|
62
64
|
results.push({ ok: false, slug, error: message });
|
|
63
65
|
continue;
|
|
64
66
|
}
|
|
65
67
|
const apiURL = sourceToURL(credential.source);
|
|
66
|
-
console.log(
|
|
68
|
+
console.log(`\n${prefix}Uploading ${slug} from ${distLabel}`);
|
|
69
|
+
if (!isDefaultServer(credential.source))
|
|
70
|
+
console.log(` Server: ${credential.source}`);
|
|
71
|
+
if (description && !multi)
|
|
72
|
+
console.log(` Message: ${description}`);
|
|
67
73
|
try {
|
|
68
74
|
let result;
|
|
69
75
|
try {
|
|
70
|
-
result = await uploadOneGame(game, { credential, apiURL, sha, description, repoURL, verbose
|
|
76
|
+
result = await uploadOneGame(game, { credential, apiURL, sha, description, repoURL, verbose });
|
|
71
77
|
}
|
|
72
78
|
catch (e) {
|
|
73
79
|
if (!(e instanceof GameNotFoundError))
|
|
@@ -75,7 +81,7 @@ export const upload = async (dir, options = {}) => {
|
|
|
75
81
|
const created = await maybeCreateMissingGame(e, game, { apiURL, teamAccessToken: credential.token });
|
|
76
82
|
if (!created)
|
|
77
83
|
throw e;
|
|
78
|
-
result = await uploadOneGame(game, { credential, apiURL, sha, description, repoURL, verbose
|
|
84
|
+
result = await uploadOneGame(game, { credential, apiURL, sha, description, repoURL, verbose });
|
|
79
85
|
}
|
|
80
86
|
results.push(result);
|
|
81
87
|
}
|
|
@@ -85,32 +91,37 @@ export const upload = async (dir, options = {}) => {
|
|
|
85
91
|
results.push({ ok: false, slug, error: message });
|
|
86
92
|
}
|
|
87
93
|
}
|
|
88
|
-
|
|
94
|
+
printSummary(results, multi);
|
|
89
95
|
const anyFailed = results.some((r) => !r.ok);
|
|
90
96
|
if (anyFailed)
|
|
91
97
|
process.exit(1);
|
|
92
98
|
};
|
|
93
99
|
/** Uploads a single discovered game; throws on failure */
|
|
94
100
|
const uploadOneGame = async (game, opts) => {
|
|
95
|
-
const { credential, apiURL, sha, description, repoURL, verbose
|
|
101
|
+
const { credential, apiURL, sha, description, repoURL, verbose } = opts;
|
|
96
102
|
const { puzzmoFile, distDir } = game;
|
|
97
103
|
const gameSlug = puzzmoFile.game.slug;
|
|
98
104
|
const files = collectFiles(distDir);
|
|
99
105
|
if (!files.length)
|
|
100
106
|
throw new Error(`Dist folder is empty: ${distDir}`);
|
|
101
|
-
console.log(` Directory: ${path.relative(rootDir, distDir) || distDir}`);
|
|
102
107
|
let totalBytes = 0;
|
|
103
108
|
for (const file of files)
|
|
104
109
|
totalBytes += fs.statSync(file).size;
|
|
105
|
-
console.log(` ${files.length
|
|
110
|
+
console.log(` ${plural(files.length, "file")}, ${formatBytes(totalBytes)} (sha ${sha.slice(0, 8)})`);
|
|
106
111
|
const result = await uploadFiles(apiURL, credential.token, gameSlug, sha, files, distDir, puzzmoFile, (batch, totalBatches, uploaded) => {
|
|
107
|
-
console.log(` Batch ${batch}/${totalBatches} done (${uploaded
|
|
112
|
+
console.log(` Batch ${batch}/${totalBatches} done (${plural(uploaded, "file")} uploaded)`);
|
|
108
113
|
}, { verbose, description, repoURL });
|
|
109
|
-
console.log(` Done - ${result.versionID}`);
|
|
110
114
|
if (result.integrationsChanged && result.versionsURL) {
|
|
111
|
-
console.log(` Integrations changed —
|
|
115
|
+
console.log(` Uploaded. Integrations changed — a new version has been staged for your team:`);
|
|
112
116
|
console.log(` ${result.versionsURL}`);
|
|
113
117
|
}
|
|
118
|
+
else if (result.gameURL) {
|
|
119
|
+
console.log(` Uploaded — live now for your team at:`);
|
|
120
|
+
console.log(` ${result.gameURL}`);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
console.log(` Uploaded.`);
|
|
124
|
+
}
|
|
114
125
|
return {
|
|
115
126
|
ok: true,
|
|
116
127
|
slug: gameSlug,
|
|
@@ -120,21 +131,52 @@ const uploadOneGame = async (game, opts) => {
|
|
|
120
131
|
versionID: result.versionID,
|
|
121
132
|
assetsBase: result.assetsBase,
|
|
122
133
|
integrationsChanged: result.integrationsChanged,
|
|
134
|
+
gameURL: result.gameURL,
|
|
123
135
|
versionsURL: result.versionsURL,
|
|
124
136
|
};
|
|
125
137
|
};
|
|
126
|
-
/** Prints
|
|
127
|
-
const
|
|
128
|
-
console.log(`\nUpload report (${results.length} game${results.length === 1 ? "" : "s"})`);
|
|
138
|
+
/** Prints the closing summary: failure count for all-fail, otherwise the puzzmonaut delivering the success line. */
|
|
139
|
+
const printSummary = (results, multi) => {
|
|
129
140
|
const successes = results.filter((r) => r.ok);
|
|
130
141
|
const failures = results.filter((r) => !r.ok);
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
console.log(` FAIL ${r.slug.padEnd(24)} ${r.error}`);
|
|
142
|
+
if (successes.length === 0) {
|
|
143
|
+
if (multi)
|
|
144
|
+
console.log(`\n${plural(failures.length, "game")} failed.`);
|
|
145
|
+
return;
|
|
136
146
|
}
|
|
137
|
-
|
|
147
|
+
const lines = [];
|
|
148
|
+
if (multi && failures.length === 0)
|
|
149
|
+
lines.push(`${plural(successes.length, "game")} uploaded!`);
|
|
150
|
+
else if (multi)
|
|
151
|
+
lines.push(`${successes.length} of ${results.length} uploaded, ${failures.length} failed.`);
|
|
152
|
+
else
|
|
153
|
+
lines.push("Uploaded!");
|
|
154
|
+
console.log("");
|
|
155
|
+
console.log(puzzmonautSays(lines));
|
|
156
|
+
};
|
|
157
|
+
const plural = (n, singular, pluralForm) => `${n} ${n === 1 ? singular : (pluralForm ?? `${singular}s`)}`;
|
|
158
|
+
const isDefaultServer = (source) => normalizeSource(source) === normalizeSource(defaultSource);
|
|
159
|
+
const yellow = (s) => (process.stdout.isTTY ? `\x1b[33m${s}\x1b[0m` : s);
|
|
160
|
+
const blackOnYellow = (s) => (process.stdout.isTTY ? `\x1b[30;43m${s}\x1b[0m` : s);
|
|
161
|
+
const puzzmonautLines = [
|
|
162
|
+
` ${yellow("▟████▙")}`,
|
|
163
|
+
` ${yellow("██")}${blackOnYellow("▝ ▘ ")} ${yellow("██")}`,
|
|
164
|
+
`${yellow(" ██")}${blackOnYellow(" ▄▖")}${yellow("██")}`,
|
|
165
|
+
` ${yellow("▝▀▀▀▀▘")}`,
|
|
166
|
+
];
|
|
167
|
+
// oxlint-disable-next-line no-control-regex
|
|
168
|
+
const visualWidth = (s) => s.replace(/\u001b\[[0-9;]*m/g, "").length;
|
|
169
|
+
/** Renders the puzzmonaut with message lines vertically centered to its right. */
|
|
170
|
+
const puzzmonautSays = (messages) => {
|
|
171
|
+
const iconWidth = Math.max(...puzzmonautLines.map(visualWidth));
|
|
172
|
+
const startRow = Math.max(0, Math.floor((puzzmonautLines.length - messages.length) / 2));
|
|
173
|
+
return puzzmonautLines
|
|
174
|
+
.map((line, i) => {
|
|
175
|
+
const pad = " ".repeat(iconWidth - visualWidth(line));
|
|
176
|
+
const msg = messages[i - startRow] ?? "";
|
|
177
|
+
return `${line}${pad} ${msg}`.trimEnd();
|
|
178
|
+
})
|
|
179
|
+
.join("\n");
|
|
138
180
|
};
|
|
139
181
|
/** Collects all files in a directory recursively */
|
|
140
182
|
const collectFiles = (dir) => {
|
|
@@ -224,7 +266,7 @@ const maybeCreateMissingGame = async (err, game, opts) => {
|
|
|
224
266
|
return false;
|
|
225
267
|
try {
|
|
226
268
|
const created = await createUserGame({ apiURL: opts.apiURL, displayName, teamAccessToken: opts.teamAccessToken });
|
|
227
|
-
console.log(` Created game ${created.slug}
|
|
269
|
+
console.log(` Created game ${created.slug}`);
|
|
228
270
|
if (created.slug !== slug) {
|
|
229
271
|
console.warn(` Server picked slug "${created.slug}" but your puzzmo.json uses "${slug}". Update puzzmo.json before re-uploading.`);
|
|
230
272
|
return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../src/commands/upload.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../src/commands/upload.ts"],"names":[],"mappings":"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"}
|
package/lib/util/api.d.ts
CHANGED
package/lib/util/api.js
CHANGED
|
@@ -101,8 +101,6 @@ export const uploadFiles = async (apiURL, token, gameSlug, sha, filePaths, baseD
|
|
|
101
101
|
throw new GameNotFoundError(gameSlug, e.message);
|
|
102
102
|
throw e;
|
|
103
103
|
}
|
|
104
|
-
if (verbose)
|
|
105
|
-
console.log(` session: ${init.sessionID}`);
|
|
106
104
|
// Step 2: Upload files in concurrent batches
|
|
107
105
|
const fileURL = `${apiURL}/cliUpload/${init.sessionID}/file`;
|
|
108
106
|
const totalBatches = Math.ceil(filePaths.length / batchSize);
|
|
@@ -119,6 +117,7 @@ export const uploadFiles = async (apiURL, token, gameSlug, sha, filePaths, baseD
|
|
|
119
117
|
return {
|
|
120
118
|
...complete,
|
|
121
119
|
integrationsChanged: !!init.integrationsChanged,
|
|
120
|
+
gameURL: init.gameURL ?? null,
|
|
122
121
|
versionsURL: init.versionsURL ?? null,
|
|
123
122
|
};
|
|
124
123
|
};
|
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;AAgB5B,MAAM,SAAS,GAAG,EAAE,CAAA;AAEpB,4FAA4F;AAC5F,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAExB,IAAI;IADtB,YACkB,IAAY,EAC5B,OAAe,EACf;QACA,KAAK,CAAC,OAAO,CAAC,CAAA;oBAHE,IAAI;QAIpB,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAA;IAAA,CAChC;CACF;
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/util/api.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$ref": "#/definitions/PuzzmoFile",
|
|
4
|
+
"definitions": {
|
|
5
|
+
"PuzzmoFile": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"game": {
|
|
9
|
+
"type": "object",
|
|
10
|
+
"properties": {
|
|
11
|
+
"displayName": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"description": "Display name shown in the UI, use | to indicate where a line break should go"
|
|
14
|
+
},
|
|
15
|
+
"slug": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"description": "URL-friendly identifier for the game"
|
|
18
|
+
},
|
|
19
|
+
"teamID": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"description": "The team ID that owns this game"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"required": ["displayName", "slug", "teamID"],
|
|
25
|
+
"additionalProperties": false,
|
|
26
|
+
"description": "Metadata about the game"
|
|
27
|
+
},
|
|
28
|
+
"integrations": {
|
|
29
|
+
"$ref": "#/definitions/Augmentations",
|
|
30
|
+
"description": "Game integrations with Puzzmo platform systems (leaderboards, stats, completion UI, etc.)"
|
|
31
|
+
},
|
|
32
|
+
"output": {
|
|
33
|
+
"type": "object",
|
|
34
|
+
"properties": {
|
|
35
|
+
"dir": {
|
|
36
|
+
"type": "string",
|
|
37
|
+
"description": "Path to the built artifacts. Resolved relative to the puzzmo.json's directory. Can be shared across games (e.g. `../../dist/<slug>`) or per-game (e.g. `./build`)."
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"required": ["dir"],
|
|
41
|
+
"additionalProperties": false,
|
|
42
|
+
"description": "Where the built game artifacts live for this game. Used by `puzzmo upload` and `puzzmo validate` to find the dist folder when running from a repo root. If omitted, the CLI looks for a `dist`, `build`, or `built` folder — first next to puzzmo.json, then walking up to the repo root, optionally with `<slug>` as a sub-folder for shared output dirs."
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"required": ["game"],
|
|
46
|
+
"additionalProperties": false,
|
|
47
|
+
"description": "The schema for a puzzmo.json file that lives alongside a game's build artifacts"
|
|
48
|
+
},
|
|
49
|
+
"Augmentations": {
|
|
50
|
+
"type": "object",
|
|
51
|
+
"properties": {
|
|
52
|
+
"leaderboards": {
|
|
53
|
+
"type": "array",
|
|
54
|
+
"items": {
|
|
55
|
+
"$ref": "#/definitions/LeaderboardExpressionSetup"
|
|
56
|
+
},
|
|
57
|
+
"description": "Dynamic leaderboards for this game"
|
|
58
|
+
},
|
|
59
|
+
"puzzleAggregateStats": {
|
|
60
|
+
"type": "array",
|
|
61
|
+
"items": {
|
|
62
|
+
"type": "object",
|
|
63
|
+
"properties": {
|
|
64
|
+
"deedID": {
|
|
65
|
+
"$ref": "#/definitions/DeedKeys",
|
|
66
|
+
"description": "Sometimes, instead of an expression, you may need to hook up to a deed"
|
|
67
|
+
},
|
|
68
|
+
"stableID": {
|
|
69
|
+
"type": ["string", "null"],
|
|
70
|
+
"description": "For a lot of augmentations, this acts as an \"id\" and should be unique and treated as a lower, kebab-case string.\n\nFor a leaderboard:\n- A stable ID has to be in the format of `game-[gameslug]:[your value name]` for a game-based leaderboard (value here likely can be your deedID). The formatting will get validated on puzzle creation, and in TypeScript."
|
|
71
|
+
},
|
|
72
|
+
"filterExp": {
|
|
73
|
+
"type": "string",
|
|
74
|
+
"description": "An expression string which can stop something from happening. A concrete example: Whether to post to a leaderboard or not. If the expression returns true or > 0 then the entry is considered allowed for the leaderboard."
|
|
75
|
+
},
|
|
76
|
+
"valueExp": {
|
|
77
|
+
"type": "string",
|
|
78
|
+
"description": "An expression string which can be used to generate the value for whatever your config is based on. The API will provide a set of appropriate variables for you to use in this JS-like expression string. They are based on \"AngularJS Expressions\" which you can read about here: https://docs.angularjs.org/guide/expression"
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"additionalProperties": false
|
|
82
|
+
},
|
|
83
|
+
"description": "Puzzle-specific aggregate stats that track data across all completions of a specific puzzle (e.g. \"how many perfect scores on this puzzle\"). Unlike `userAggregateStats` which are per-user, these accumulate data across all players for a single puzzle instance.\n\nEvaluated at game completion. Expression scope includes:\n\n- All deed values from the gameplay (camelCase keys, e.g. `excessMoves` from `excess-moves` deed)\n- `prior`: The previous value of this stat for the puzzle\n- `wallClockComplete`: Seconds since daily start when completed (if today's daily)\n\nTwo ways to define stats:\n\n1. Via `deedID`: Looks up the deed value and adds it to prior (simple accumulation) 2. Via `valueExp`: Full expression control, e.g. `prior + 1` to count occurrences\n\nUse `filterExp` to conditionally update, e.g. `excessMoves === 0` to only count perfect games. The `stableID` is required and used as the storage key for this stat.\n\nExample: Count perfect completions\n\n```json { \"stableID\": \"perfects\", \"filterExp\": \"excessMoves === 0\", \"valueExp\": \"prior + 1\" } ```"
|
|
84
|
+
},
|
|
85
|
+
"userAggregateStats": {
|
|
86
|
+
"type": "array",
|
|
87
|
+
"items": {
|
|
88
|
+
"type": "object",
|
|
89
|
+
"properties": {
|
|
90
|
+
"deedID": {
|
|
91
|
+
"$ref": "#/definitions/DeedKeys",
|
|
92
|
+
"description": "Sometimes, instead of an expression, you may need to hook up to a deed"
|
|
93
|
+
},
|
|
94
|
+
"stableID": {
|
|
95
|
+
"type": ["string", "null"],
|
|
96
|
+
"description": "For a lot of augmentations, this acts as an \"id\" and should be unique and treated as a lower, kebab-case string.\n\nFor a leaderboard:\n- A stable ID has to be in the format of `game-[gameslug]:[your value name]` for a game-based leaderboard (value here likely can be your deedID). The formatting will get validated on puzzle creation, and in TypeScript."
|
|
97
|
+
},
|
|
98
|
+
"filterExp": {
|
|
99
|
+
"type": "string",
|
|
100
|
+
"description": "An expression string which can stop something from happening. A concrete example: Whether to post to a leaderboard or not. If the expression returns true or > 0 then the entry is considered allowed for the leaderboard."
|
|
101
|
+
},
|
|
102
|
+
"valueExp": {
|
|
103
|
+
"type": "string",
|
|
104
|
+
"description": "An expression string which can be used to generate the value for whatever your config is based on. The API will provide a set of appropriate variables for you to use in this JS-like expression string. They are based on \"AngularJS Expressions\" which you can read about here: https://docs.angularjs.org/guide/expression"
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
"additionalProperties": false
|
|
108
|
+
},
|
|
109
|
+
"description": "User-specific aggregate stats stored per-user, tied to the game or remix. These track lifetime stats for individual players (e.g. \"total points earned\", \"best score\"). Stats are keyed by game symbol, or `{symbol}-{remixSlug}` if the remix has the uniqueStats flag.\n\nEvaluated at game completion. Expression scope includes:\n\n- `deeds`: All deed values from the gameplay (camelCase keys, e.g. `deeds.tilesCleared`)\n- `prior`: The previous value of this stat for the user (for running totals/max/min)\n- `uas`: The user's existing aggregate stats object\n- Game symbol keys containing prior deed stats\n\nTwo ways to define stats:\n\n1. Via `deedID`: Looks up the deed value and adds it to prior (simple accumulation) 2. Via `valueExp`: Full expression control, e.g. `prior > deeds.score ? prior : deeds.score` for max\n\nUse `filterExp` to conditionally update (e.g. only count completed games). The `stableID` is required and used as the storage key for this stat.\n\nExample: Track the user's best score\n\n```json { \"stableID\": \"best-score\", \"valueExp\": \"prior > deeds.score ? prior : deeds.score\" } ```"
|
|
110
|
+
},
|
|
111
|
+
"userStatDisplays": {
|
|
112
|
+
"type": "array",
|
|
113
|
+
"items": {
|
|
114
|
+
"type": "object",
|
|
115
|
+
"properties": {
|
|
116
|
+
"userAggregateStatStableID": {
|
|
117
|
+
"type": "string",
|
|
118
|
+
"description": "The stableID from userAggregateStats to display. Converted to camelCase for lookup (e.g. \"best-score\" -> \"bestScore\")."
|
|
119
|
+
},
|
|
120
|
+
"formatString": {
|
|
121
|
+
"type": "string",
|
|
122
|
+
"description": "Format string. Use `%@` as placeholder for the value (e.g., \"Best score: %@\" -> \"Best score: 1234\")."
|
|
123
|
+
},
|
|
124
|
+
"displayID": {
|
|
125
|
+
"type": "number",
|
|
126
|
+
"description": "Unique ID for this stat within the game section. Used for user selection persistence. Negative IDs are reserved for system stats."
|
|
127
|
+
},
|
|
128
|
+
"hideExp": {
|
|
129
|
+
"type": "string",
|
|
130
|
+
"description": "Optional expression to determine visibility. Receives `{ value }` in scope. Return truthy to hide."
|
|
131
|
+
},
|
|
132
|
+
"order": {
|
|
133
|
+
"type": "number",
|
|
134
|
+
"description": "Display order within section (default: 0). Negative numbers are reserved for system prefix stats."
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
"required": ["userAggregateStatStableID", "formatString", "displayID"],
|
|
138
|
+
"additionalProperties": false
|
|
139
|
+
},
|
|
140
|
+
"description": "Configuration for how user aggregate stats are displayed on user profiles. Maps stats from `userAggregateStats` to formatted display strings shown in the profile stats section.\n\nThe profile section automatically includes prefix stats (games played, hours played, best streak) before any custom stats defined here.\n\nThe `hideExp` expression receives `{ value }` in scope where `value` is the stat's current value. Common pattern: `\"!value\"` to hide when zero/undefined."
|
|
141
|
+
},
|
|
142
|
+
"persistedDeeds": {
|
|
143
|
+
"type": "array",
|
|
144
|
+
"items": {
|
|
145
|
+
"$ref": "#/definitions/ExpressionSetup"
|
|
146
|
+
},
|
|
147
|
+
"description": "Converts temporary (pipeline) deeds into persisted deeds at game completion time. Use this to persist computed values derived from temporary deed data.\n\nFor each config, the `valueExp` is evaluated against the deed scope, and the result is stored as a permanent deed using `stableID` (or `deedID`) as the storage key.\n\nExpression scope includes all deeds from the gameplay (camelCase keys, e.g. `points` from `points` deed). Values are floored to integers before storage.\n\nUse `filterExp` to conditionally persist (e.g. only persist if a threshold is met). Either `stableID` or `deedID` is required as the storage key.\n\nExample: Persist a computed score only when player achieves a threshold\n\n```json { \"stableID\": \"computed-bonus\", \"filterExp\": \"points > 100\", \"valueExp\": \"points * 2\" } ```\n\nCommon use case: Take a temporary deed and persist it for use in completion tables or sidebars."
|
|
148
|
+
},
|
|
149
|
+
"completionTable": {
|
|
150
|
+
"type": "array",
|
|
151
|
+
"items": {
|
|
152
|
+
"type": "object",
|
|
153
|
+
"properties": {
|
|
154
|
+
"title": {
|
|
155
|
+
"type": "string",
|
|
156
|
+
"description": "Label shown on the left side of the table row"
|
|
157
|
+
},
|
|
158
|
+
"persistedDeedID": {
|
|
159
|
+
"type": "string",
|
|
160
|
+
"description": "ID of the persisted deed to look up (must match a deed stored on the gameplay)"
|
|
161
|
+
},
|
|
162
|
+
"formatString": {
|
|
163
|
+
"type": "string",
|
|
164
|
+
"description": "Format string. Use `%@` as placeholder for the value."
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
"required": ["title", "persistedDeedID", "formatString"],
|
|
168
|
+
"additionalProperties": false
|
|
169
|
+
},
|
|
170
|
+
"description": "Additional rows to display in the Today page completion table for a completed game. Shows custom stats alongside the default game stats (time, score, hints, etc.).\n\nEach entry looks up a persisted deed by `persistedDeedID` and formats its value using `formatString`. Custom entries appear before the default game stats. The table is rendered as title/value pairs.\n\nNote: Only works with persisted deeds. Use `persistedDeeds` augmentation first if you need to convert temporary deeds into persisted ones for display here.\n\nExample: Show a custom \"Bonus Points\" stat\n\n```json { \"title\": \"Bonus Points\", \"persistedDeedID\": \"bonus-points\", \"formatString\": \"%@ pts\" } ```"
|
|
171
|
+
},
|
|
172
|
+
"completionSidebar": {
|
|
173
|
+
"type": "array",
|
|
174
|
+
"items": {
|
|
175
|
+
"$ref": "#/definitions/ExpressionSetup"
|
|
176
|
+
},
|
|
177
|
+
"description": "Additional stats to display in the game completion sidebar/popover on the Today page. Use this to show deed values that don't have an associated leaderboard.\n\nThese items are merged with leaderboard entries, sorted by `sortValue`, and displayed as a list of stats after game completion. Each entry looks up a deed by `deedID` and formats its value using `formatString`.\n\nItems can include:\n\n- `display` or `secondaryName`: Label shown for the stat\n- `deedID`: Which deed to look up for the value\n- `formatString`: How to format the value (e.g. \"%@ pts\")\n- `sortValue`: Order relative to other sidebar items (lower = earlier)\n- `order`: \"Lower=better\" or default (higher=better) for directional indicators\n\nExample: Show a custom \"Combos\" stat\n\n```json { \"completionSidebar\": [ { \"deedID\": \"combo-count\", \"displayName\": \"Combos\", \"formatString\": \"%@\", \"sortValue\": 10 } ] } ```"
|
|
178
|
+
},
|
|
179
|
+
"completionNotables": {
|
|
180
|
+
"type": "array",
|
|
181
|
+
"items": {
|
|
182
|
+
"type": "object",
|
|
183
|
+
"properties": {
|
|
184
|
+
"valueExp": {
|
|
185
|
+
"type": "string",
|
|
186
|
+
"description": "Expression evaluated against deed scope. If truthy, the notable is awarded."
|
|
187
|
+
},
|
|
188
|
+
"notableIndex": {
|
|
189
|
+
"type": "number",
|
|
190
|
+
"description": "For code-based notables: 0 for UserAwardsBitmapKeys, 1 for UserAwardsBitmap1Keys. Not needed for system notables."
|
|
191
|
+
},
|
|
192
|
+
"notableName": {
|
|
193
|
+
"type": "string",
|
|
194
|
+
"description": "Notable identifier. For code-based: the enum key name (Puzzmo team games only). For system notables: \"{index}-{bitmapValue}\" format."
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
"required": ["valueExp", "notableName"],
|
|
198
|
+
"additionalProperties": false
|
|
199
|
+
},
|
|
200
|
+
"description": "Awards notables (achievements/badges) to users when conditions are met at game completion. When a notable is awarded, it appears on the user's profile and creates a social news item.\n\nThe `valueExp` is evaluated against the game's deed scope. If it returns truthy, the notable is awarded. Expression scope includes all deed values from the gameplay (camelCase keys).\n\nTwo types of notables:\n\n1. **Code-based notables**: Use `notableName` (e.g. \"jokinAround\") with `notableIndex` (0 or 1). These reference predefined notables in UserAwardsBitmapKeys (index 0) or UserAwardsBitmap1Keys (index 1). **Restricted to games owned by the Puzzmo team.** 2. **System notables**: Use `notableName` as \"{index}-{bitmapValue}\" format (e.g. \"2-4\"). These reference dynamic notables stored in the SystemNotable database table. Available to all games.\n\nExample: Award a notable when player scores over 100 points\n\n```json { \"completionNotables\": [ { \"valueExp\": \"score > 100\", \"notableIndex\": 0, \"notableName\": \"jokinAround\" }, { \"valueExp\": \"perfect === true\", \"notableName\": \"2-4\" } ] } ```"
|
|
201
|
+
},
|
|
202
|
+
"forceGameSettings": {
|
|
203
|
+
"type": "object",
|
|
204
|
+
"description": "Forces specific game settings for this puzzle, overriding user preferences. Only applies when set via puzzle front-matter (not from game-level augmentations).\n\nWhen a puzzle has forced settings, those settings are locked in the UI and displayed as read-only with a note that the setting is specific to this puzzle. Users cannot change forced settings.\n\nThe settings object keys/values are game-specific. To find valid settings for a game, set the setting yourself in the game and check your user profile in the admin to see the stored format.\n\nExample: Force monochrome grid mode for a crossword puzzle\n\n```json { \"forceGameSettings\": { \"monoGrid\": true } } ```"
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
"additionalProperties": false,
|
|
208
|
+
"description": "Site-wide hooks which are sent at puzzle creation, (via front-matter), via the game, and gameplay completion messages.\n\nGames/Variants/FrontMatter: Supports All Fields. Game Completion: Just \"leaderboards\" and \"completionNotables\""
|
|
209
|
+
},
|
|
210
|
+
"LeaderboardExpressionSetup": {
|
|
211
|
+
"type": "object",
|
|
212
|
+
"additionalProperties": false,
|
|
213
|
+
"properties": {
|
|
214
|
+
"stableID": {
|
|
215
|
+
"type": ["string", "null"],
|
|
216
|
+
"description": "For a lot of augmentations, this acts as an \"id\" and should be unique and treated as a lower, kebab-case string.\n\nFor a leaderboard:\n- A stable ID has to be in the format of `game-[gameslug]:[your value name]` for a game-based leaderboard (value here likely can be your deedID). The formatting will get validated on puzzle creation, and in TypeScript."
|
|
217
|
+
},
|
|
218
|
+
"scoreTechnique": {
|
|
219
|
+
"type": ["string", "null"],
|
|
220
|
+
"enum": ["AggregateOfBest", "AggregateOfAll", null],
|
|
221
|
+
"description": "Provides a way to control how we handle different scoring algorithms, right now you have the default (overwrite on best) and \"AggregateOfBest\" which aggregates based on the"
|
|
222
|
+
},
|
|
223
|
+
"rotation": {
|
|
224
|
+
"type": "string",
|
|
225
|
+
"enum": ["Weekly", "Monthly"],
|
|
226
|
+
"description": "How often does this leaderboard rotate? Leaving empty is means daily"
|
|
227
|
+
},
|
|
228
|
+
"icons": {
|
|
229
|
+
"type": "array",
|
|
230
|
+
"items": {
|
|
231
|
+
"type": "string"
|
|
232
|
+
},
|
|
233
|
+
"description": "What icons should show above the leaderboard? These want to be game slugs"
|
|
234
|
+
},
|
|
235
|
+
"rules": {
|
|
236
|
+
"type": "string",
|
|
237
|
+
"description": "A \\n separated list of rules to put under a leaderboard"
|
|
238
|
+
},
|
|
239
|
+
"subscoreExp": {
|
|
240
|
+
"type": "string",
|
|
241
|
+
"description": "An expression to grab a subscore"
|
|
242
|
+
},
|
|
243
|
+
"championsLeague": {
|
|
244
|
+
"type": "boolean",
|
|
245
|
+
"const": true,
|
|
246
|
+
"description": "Support having a champion's league, where we extract the top players from the game and move them into a new league. Only available for use on the Game augmentations (and not at puzzles/variants/runtime etc) and on leaderboards with a rotation of null (daily.)"
|
|
247
|
+
},
|
|
248
|
+
"postCompletion": {
|
|
249
|
+
"type": "boolean",
|
|
250
|
+
"const": true,
|
|
251
|
+
"description": "This leaderboard is only submitted to via a post-completion checkpoint, not during the normal completion pipeline. We use this for games which have secret metagames which occur after the game has been completed."
|
|
252
|
+
},
|
|
253
|
+
"displayName": {
|
|
254
|
+
"type": "string",
|
|
255
|
+
"description": "What do we call this datum"
|
|
256
|
+
},
|
|
257
|
+
"secondaryName": {
|
|
258
|
+
"type": "string",
|
|
259
|
+
"description": "An optional secondary name for this config. For example, on a leaderboard this is used in the completion sidebar"
|
|
260
|
+
},
|
|
261
|
+
"order": {
|
|
262
|
+
"type": "string",
|
|
263
|
+
"enum": ["Higher=better", "Lower=better"],
|
|
264
|
+
"description": "Just saying it how it is, for some augmentations, this isn't necessary"
|
|
265
|
+
},
|
|
266
|
+
"deedID": {
|
|
267
|
+
"$ref": "#/definitions/DeedKeys",
|
|
268
|
+
"description": "Sometimes, instead of an expression, you may need to hook up to a deed"
|
|
269
|
+
},
|
|
270
|
+
"formatString": {
|
|
271
|
+
"type": "string",
|
|
272
|
+
"description": "A custom string formatter, slightly based on printf.\n\n- `%+`: Adds a plus sign _only_ to positive numbers\n- `%@`: Takes the value and replaces the token with the value. If a number it is 'toLocaleString(\"en-US\")'ed\n- `%TD`: Takes the text definition for a deed and replaces the token with the value\n- `\"[time]\"`: Converts a number of seconds to a colon-separated time string (must be exact match)"
|
|
273
|
+
},
|
|
274
|
+
"filterExp": {
|
|
275
|
+
"type": "string",
|
|
276
|
+
"description": "An expression string which can stop something from happening. A concrete example: Whether to post to a leaderboard or not. If the expression returns true or > 0 then the entry is considered allowed for the leaderboard."
|
|
277
|
+
},
|
|
278
|
+
"valueExp": {
|
|
279
|
+
"type": "string",
|
|
280
|
+
"description": "An expression string which can be used to generate the value for whatever your config is based on. The API will provide a set of appropriate variables for you to use in this JS-like expression string. They are based on \"AngularJS Expressions\" which you can read about here: https://docs.angularjs.org/guide/expression"
|
|
281
|
+
},
|
|
282
|
+
"sortValue": {
|
|
283
|
+
"type": "number",
|
|
284
|
+
"description": "Different augmentations would do different things with this sort value. Leaderboards for example use this when displaying on a page."
|
|
285
|
+
}
|
|
286
|
+
},
|
|
287
|
+
"required": ["displayName", "formatString", "stableID"]
|
|
288
|
+
},
|
|
289
|
+
"DeedKeys": {
|
|
290
|
+
"type": "string"
|
|
291
|
+
},
|
|
292
|
+
"ExpressionSetup": {
|
|
293
|
+
"type": "object",
|
|
294
|
+
"properties": {
|
|
295
|
+
"displayName": {
|
|
296
|
+
"type": "string",
|
|
297
|
+
"description": "What do we call this datum"
|
|
298
|
+
},
|
|
299
|
+
"secondaryName": {
|
|
300
|
+
"type": "string",
|
|
301
|
+
"description": "An optional secondary name for this config. For example, on a leaderboard this is used in the completion sidebar"
|
|
302
|
+
},
|
|
303
|
+
"stableID": {
|
|
304
|
+
"type": ["string", "null"],
|
|
305
|
+
"description": "For a lot of augmentations, this acts as an \"id\" and should be unique and treated as a lower, kebab-case string.\n\nFor a leaderboard:\n- A stable ID has to be in the format of `game-[gameslug]:[your value name]` for a game-based leaderboard (value here likely can be your deedID). The formatting will get validated on puzzle creation, and in TypeScript."
|
|
306
|
+
},
|
|
307
|
+
"order": {
|
|
308
|
+
"type": "string",
|
|
309
|
+
"enum": ["Higher=better", "Lower=better"],
|
|
310
|
+
"description": "Just saying it how it is, for some augmentations, this isn't necessary"
|
|
311
|
+
},
|
|
312
|
+
"deedID": {
|
|
313
|
+
"$ref": "#/definitions/DeedKeys",
|
|
314
|
+
"description": "Sometimes, instead of an expression, you may need to hook up to a deed"
|
|
315
|
+
},
|
|
316
|
+
"formatString": {
|
|
317
|
+
"type": "string",
|
|
318
|
+
"description": "A custom string formatter, slightly based on printf.\n\n- `%+`: Adds a plus sign _only_ to positive numbers\n- `%@`: Takes the value and replaces the token with the value. If a number it is 'toLocaleString(\"en-US\")'ed\n- `%TD`: Takes the text definition for a deed and replaces the token with the value\n- `\"[time]\"`: Converts a number of seconds to a colon-separated time string (must be exact match)"
|
|
319
|
+
},
|
|
320
|
+
"filterExp": {
|
|
321
|
+
"type": "string",
|
|
322
|
+
"description": "An expression string which can stop something from happening. A concrete example: Whether to post to a leaderboard or not. If the expression returns true or > 0 then the entry is considered allowed for the leaderboard."
|
|
323
|
+
},
|
|
324
|
+
"valueExp": {
|
|
325
|
+
"type": "string",
|
|
326
|
+
"description": "An expression string which can be used to generate the value for whatever your config is based on. The API will provide a set of appropriate variables for you to use in this JS-like expression string. They are based on \"AngularJS Expressions\" which you can read about here: https://docs.angularjs.org/guide/expression"
|
|
327
|
+
},
|
|
328
|
+
"sortValue": {
|
|
329
|
+
"type": "number",
|
|
330
|
+
"description": "Different augmentations would do different things with this sort value. Leaderboards for example use this when displaying on a page."
|
|
331
|
+
}
|
|
332
|
+
},
|
|
333
|
+
"required": ["displayName", "formatString"],
|
|
334
|
+
"additionalProperties": false,
|
|
335
|
+
"description": "Data given by either via a puzzle in front-matter, or a game in completion. A general unit of data which can be used to represent a lot of configuration points from the game to the API."
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
package/src/commands/upload.ts
CHANGED
|
@@ -5,7 +5,15 @@ import path from "node:path"
|
|
|
5
5
|
import * as p from "@clack/prompts"
|
|
6
6
|
|
|
7
7
|
import { GameNotFoundError, uploadFiles } from "../util/api.js"
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
defaultSource,
|
|
10
|
+
findTokensForTeam,
|
|
11
|
+
getTokens,
|
|
12
|
+
normalizeSource,
|
|
13
|
+
resolveServerForTeam,
|
|
14
|
+
sourceToURL,
|
|
15
|
+
type TokenEntry,
|
|
16
|
+
} from "../util/config.js"
|
|
9
17
|
import { createUserGame } from "../util/createGame.js"
|
|
10
18
|
import { discoverGames, type DiscoveredGame } from "../util/discoverGames.js"
|
|
11
19
|
|
|
@@ -22,6 +30,7 @@ type GameSuccess = {
|
|
|
22
30
|
versionID: string
|
|
23
31
|
assetsBase: string
|
|
24
32
|
integrationsChanged: boolean
|
|
33
|
+
gameURL: string | null
|
|
25
34
|
versionsURL: string | null
|
|
26
35
|
}
|
|
27
36
|
|
|
@@ -55,23 +64,26 @@ export const upload = async (dir: string, options: UploadOptions = {}) => {
|
|
|
55
64
|
process.exit(1)
|
|
56
65
|
}
|
|
57
66
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
const multi = games.length + discoveryErrors.length > 1
|
|
68
|
+
|
|
69
|
+
if (multi) {
|
|
70
|
+
console.log(`Found ${plural(games.length, "game")} under ${rootDir}`)
|
|
71
|
+
for (const game of games) {
|
|
72
|
+
console.log(` - ${game.puzzmoFile.game.slug} (${path.relative(rootDir, game.distDir) || "."})`)
|
|
73
|
+
}
|
|
74
|
+
if (discoveryErrors.length) {
|
|
75
|
+
console.log(`\n${plural(discoveryErrors.length, "puzzmo.json file")} could not be loaded:`)
|
|
76
|
+
for (const err of discoveryErrors) {
|
|
77
|
+
console.log(` - ${err.slug ?? path.relative(rootDir, err.puzzmoJsonPath)}`)
|
|
78
|
+
for (const e of err.errors) console.log(` ${e}`)
|
|
79
|
+
}
|
|
67
80
|
}
|
|
68
81
|
}
|
|
69
82
|
|
|
70
83
|
const sha = getGitSHA(rootDir) || hashGames(games)
|
|
71
84
|
const description = getGitMessage(rootDir)
|
|
72
85
|
const repoURL = getGitRepoURL(rootDir)
|
|
73
|
-
if (description) console.log(`\nMessage: ${description}`)
|
|
74
|
-
if (repoURL) console.log(`Repo: ${repoURL}`)
|
|
86
|
+
if (description && multi) console.log(`\nMessage: ${description}`)
|
|
75
87
|
|
|
76
88
|
const results: GameResult[] = []
|
|
77
89
|
for (const err of discoveryErrors) {
|
|
@@ -81,7 +93,8 @@ export const upload = async (dir: string, options: UploadOptions = {}) => {
|
|
|
81
93
|
for (let i = 0; i < games.length; i++) {
|
|
82
94
|
const game = games[i]
|
|
83
95
|
const slug = game.puzzmoFile.game.slug
|
|
84
|
-
|
|
96
|
+
const prefix = multi ? `[${i + 1}/${games.length}] ` : ""
|
|
97
|
+
const distLabel = path.relative(rootDir, game.distDir) || "."
|
|
85
98
|
|
|
86
99
|
const teamID = game.puzzmoFile.game.teamID
|
|
87
100
|
const credential = await resolveServerForTeam(teamID)
|
|
@@ -91,23 +104,25 @@ export const upload = async (dir: string, options: UploadOptions = {}) => {
|
|
|
91
104
|
matches.length === 0
|
|
92
105
|
? `No saved token for team ${teamID}. Run \`puzzmo login <token>\` (use \`--source\` if the token is for a non-default server).`
|
|
93
106
|
: `Token for team ${teamID} is registered against ${matches.map((m) => m.source).join(", ")} but none of those servers are reachable.`
|
|
94
|
-
console.error(
|
|
107
|
+
console.error(`\n${prefix}Uploading ${slug} from ${distLabel}\n ${message}`)
|
|
95
108
|
results.push({ ok: false, slug, error: message })
|
|
96
109
|
continue
|
|
97
110
|
}
|
|
98
111
|
|
|
99
112
|
const apiURL = sourceToURL(credential.source)
|
|
100
|
-
console.log(
|
|
113
|
+
console.log(`\n${prefix}Uploading ${slug} from ${distLabel}`)
|
|
114
|
+
if (!isDefaultServer(credential.source)) console.log(` Server: ${credential.source}`)
|
|
115
|
+
if (description && !multi) console.log(` Message: ${description}`)
|
|
101
116
|
|
|
102
117
|
try {
|
|
103
118
|
let result: GameSuccess
|
|
104
119
|
try {
|
|
105
|
-
result = await uploadOneGame(game, { credential, apiURL, sha, description, repoURL, verbose
|
|
120
|
+
result = await uploadOneGame(game, { credential, apiURL, sha, description, repoURL, verbose })
|
|
106
121
|
} catch (e) {
|
|
107
122
|
if (!(e instanceof GameNotFoundError)) throw e
|
|
108
123
|
const created = await maybeCreateMissingGame(e, game, { apiURL, teamAccessToken: credential.token })
|
|
109
124
|
if (!created) throw e
|
|
110
|
-
result = await uploadOneGame(game, { credential, apiURL, sha, description, repoURL, verbose
|
|
125
|
+
result = await uploadOneGame(game, { credential, apiURL, sha, description, repoURL, verbose })
|
|
111
126
|
}
|
|
112
127
|
results.push(result)
|
|
113
128
|
} catch (e) {
|
|
@@ -117,7 +132,7 @@ export const upload = async (dir: string, options: UploadOptions = {}) => {
|
|
|
117
132
|
}
|
|
118
133
|
}
|
|
119
134
|
|
|
120
|
-
|
|
135
|
+
printSummary(results, multi)
|
|
121
136
|
|
|
122
137
|
const anyFailed = results.some((r) => !r.ok)
|
|
123
138
|
if (anyFailed) process.exit(1)
|
|
@@ -130,22 +145,20 @@ type UploadOneOptions = {
|
|
|
130
145
|
description: string | null
|
|
131
146
|
repoURL: string | null
|
|
132
147
|
verbose: boolean
|
|
133
|
-
rootDir: string
|
|
134
148
|
}
|
|
135
149
|
|
|
136
150
|
/** Uploads a single discovered game; throws on failure */
|
|
137
151
|
const uploadOneGame = async (game: DiscoveredGame, opts: UploadOneOptions): Promise<GameSuccess> => {
|
|
138
|
-
const { credential, apiURL, sha, description, repoURL, verbose
|
|
152
|
+
const { credential, apiURL, sha, description, repoURL, verbose } = opts
|
|
139
153
|
const { puzzmoFile, distDir } = game
|
|
140
154
|
const gameSlug = puzzmoFile.game.slug
|
|
141
155
|
|
|
142
156
|
const files = collectFiles(distDir)
|
|
143
157
|
if (!files.length) throw new Error(`Dist folder is empty: ${distDir}`)
|
|
144
158
|
|
|
145
|
-
console.log(` Directory: ${path.relative(rootDir, distDir) || distDir}`)
|
|
146
159
|
let totalBytes = 0
|
|
147
160
|
for (const file of files) totalBytes += fs.statSync(file).size
|
|
148
|
-
console.log(` ${files.length
|
|
161
|
+
console.log(` ${plural(files.length, "file")}, ${formatBytes(totalBytes)} (sha ${sha.slice(0, 8)})`)
|
|
149
162
|
|
|
150
163
|
const result = await uploadFiles(
|
|
151
164
|
apiURL,
|
|
@@ -156,15 +169,19 @@ const uploadOneGame = async (game: DiscoveredGame, opts: UploadOneOptions): Prom
|
|
|
156
169
|
distDir,
|
|
157
170
|
puzzmoFile,
|
|
158
171
|
(batch, totalBatches, uploaded) => {
|
|
159
|
-
console.log(` Batch ${batch}/${totalBatches} done (${uploaded
|
|
172
|
+
console.log(` Batch ${batch}/${totalBatches} done (${plural(uploaded, "file")} uploaded)`)
|
|
160
173
|
},
|
|
161
174
|
{ verbose, description, repoURL },
|
|
162
175
|
)
|
|
163
176
|
|
|
164
|
-
console.log(` Done - ${result.versionID}`)
|
|
165
177
|
if (result.integrationsChanged && result.versionsURL) {
|
|
166
|
-
console.log(` Integrations changed —
|
|
178
|
+
console.log(` Uploaded. Integrations changed — a new version has been staged for your team:`)
|
|
167
179
|
console.log(` ${result.versionsURL}`)
|
|
180
|
+
} else if (result.gameURL) {
|
|
181
|
+
console.log(` Uploaded — live now for your team at:`)
|
|
182
|
+
console.log(` ${result.gameURL}`)
|
|
183
|
+
} else {
|
|
184
|
+
console.log(` Uploaded.`)
|
|
168
185
|
}
|
|
169
186
|
return {
|
|
170
187
|
ok: true,
|
|
@@ -175,22 +192,58 @@ const uploadOneGame = async (game: DiscoveredGame, opts: UploadOneOptions): Prom
|
|
|
175
192
|
versionID: result.versionID,
|
|
176
193
|
assetsBase: result.assetsBase,
|
|
177
194
|
integrationsChanged: result.integrationsChanged,
|
|
195
|
+
gameURL: result.gameURL,
|
|
178
196
|
versionsURL: result.versionsURL,
|
|
179
197
|
}
|
|
180
198
|
}
|
|
181
199
|
|
|
182
|
-
/** Prints
|
|
183
|
-
const
|
|
184
|
-
console.log(`\nUpload report (${results.length} game${results.length === 1 ? "" : "s"})`)
|
|
200
|
+
/** Prints the closing summary: failure count for all-fail, otherwise the puzzmonaut delivering the success line. */
|
|
201
|
+
const printSummary = (results: GameResult[], multi: boolean) => {
|
|
185
202
|
const successes = results.filter((r): r is GameSuccess => r.ok)
|
|
186
203
|
const failures = results.filter((r): r is GameFailure => !r.ok)
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
console.log(` FAIL ${r.slug.padEnd(24)} ${r.error}`)
|
|
204
|
+
|
|
205
|
+
if (successes.length === 0) {
|
|
206
|
+
if (multi) console.log(`\n${plural(failures.length, "game")} failed.`)
|
|
207
|
+
return
|
|
192
208
|
}
|
|
193
|
-
|
|
209
|
+
|
|
210
|
+
const lines: string[] = []
|
|
211
|
+
if (multi && failures.length === 0) lines.push(`${plural(successes.length, "game")} uploaded!`)
|
|
212
|
+
else if (multi) lines.push(`${successes.length} of ${results.length} uploaded, ${failures.length} failed.`)
|
|
213
|
+
else lines.push("Uploaded!")
|
|
214
|
+
|
|
215
|
+
console.log("")
|
|
216
|
+
console.log(puzzmonautSays(lines))
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const plural = (n: number, singular: string, pluralForm?: string): string => `${n} ${n === 1 ? singular : (pluralForm ?? `${singular}s`)}`
|
|
220
|
+
|
|
221
|
+
const isDefaultServer = (source: string): boolean => normalizeSource(source) === normalizeSource(defaultSource)
|
|
222
|
+
|
|
223
|
+
const yellow = (s: string): string => (process.stdout.isTTY ? `\x1b[33m${s}\x1b[0m` : s)
|
|
224
|
+
const blackOnYellow = (s: string): string => (process.stdout.isTTY ? `\x1b[30;43m${s}\x1b[0m` : s)
|
|
225
|
+
|
|
226
|
+
const puzzmonautLines = [
|
|
227
|
+
` ${yellow("▟████▙")}`,
|
|
228
|
+
` ${yellow("██")}${blackOnYellow("▝ ▘ ")} ${yellow("██")}`,
|
|
229
|
+
`${yellow(" ██")}${blackOnYellow(" ▄▖")}${yellow("██")}`,
|
|
230
|
+
` ${yellow("▝▀▀▀▀▘")}`,
|
|
231
|
+
]
|
|
232
|
+
|
|
233
|
+
// oxlint-disable-next-line no-control-regex
|
|
234
|
+
const visualWidth = (s: string): number => s.replace(/\u001b\[[0-9;]*m/g, "").length
|
|
235
|
+
|
|
236
|
+
/** Renders the puzzmonaut with message lines vertically centered to its right. */
|
|
237
|
+
const puzzmonautSays = (messages: string[]): string => {
|
|
238
|
+
const iconWidth = Math.max(...puzzmonautLines.map(visualWidth))
|
|
239
|
+
const startRow = Math.max(0, Math.floor((puzzmonautLines.length - messages.length) / 2))
|
|
240
|
+
return puzzmonautLines
|
|
241
|
+
.map((line, i) => {
|
|
242
|
+
const pad = " ".repeat(iconWidth - visualWidth(line))
|
|
243
|
+
const msg = messages[i - startRow] ?? ""
|
|
244
|
+
return `${line}${pad} ${msg}`.trimEnd()
|
|
245
|
+
})
|
|
246
|
+
.join("\n")
|
|
194
247
|
}
|
|
195
248
|
|
|
196
249
|
/** Collects all files in a directory recursively */
|
|
@@ -285,7 +338,7 @@ const maybeCreateMissingGame = async (
|
|
|
285
338
|
|
|
286
339
|
try {
|
|
287
340
|
const created = await createUserGame({ apiURL: opts.apiURL, displayName, teamAccessToken: opts.teamAccessToken })
|
|
288
|
-
console.log(` Created game ${created.slug}
|
|
341
|
+
console.log(` Created game ${created.slug}`)
|
|
289
342
|
if (created.slug !== slug) {
|
|
290
343
|
console.warn(` Server picked slug "${created.slug}" but your puzzmo.json uses "${slug}". Update puzzmo.json before re-uploading.`)
|
|
291
344
|
return false
|
package/src/util/api.ts
CHANGED
|
@@ -28,9 +28,23 @@ export class GameNotFoundError extends Error {
|
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
type InitResponse = {
|
|
31
|
+
type InitResponse = {
|
|
32
|
+
sessionID: string
|
|
33
|
+
basePath: string
|
|
34
|
+
integrationsChanged?: boolean
|
|
35
|
+
gameURL?: string
|
|
36
|
+
versionsURL?: string
|
|
37
|
+
error?: string
|
|
38
|
+
}
|
|
32
39
|
type FileResponse = { path: string; error?: string }
|
|
33
|
-
type CompleteResponse = {
|
|
40
|
+
type CompleteResponse = {
|
|
41
|
+
assetsBase: string
|
|
42
|
+
versionID: string
|
|
43
|
+
integrationsChanged: boolean
|
|
44
|
+
gameURL: string | null
|
|
45
|
+
versionsURL: string | null
|
|
46
|
+
error?: string
|
|
47
|
+
}
|
|
34
48
|
|
|
35
49
|
/** Callback for reporting batch upload progress */
|
|
36
50
|
export type UploadProgress = (batch: number, totalBatches: number, uploaded: number) => void
|
|
@@ -157,7 +171,6 @@ export const uploadFiles = async (
|
|
|
157
171
|
if (e instanceof Error && e.message.includes("Game not found:")) throw new GameNotFoundError(gameSlug, e.message)
|
|
158
172
|
throw e
|
|
159
173
|
}
|
|
160
|
-
if (verbose) console.log(` session: ${init.sessionID}`)
|
|
161
174
|
|
|
162
175
|
// Step 2: Upload files in concurrent batches
|
|
163
176
|
const fileURL = `${apiURL}/cliUpload/${init.sessionID}/file`
|
|
@@ -175,11 +188,12 @@ export const uploadFiles = async (
|
|
|
175
188
|
// Step 3: Complete
|
|
176
189
|
const complete = (await jsonPost(`${apiURL}/cliUpload/${init.sessionID}/complete`, token, {}, "upload complete", verbose)) as Omit<
|
|
177
190
|
CompleteResponse,
|
|
178
|
-
"integrationsChanged" | "versionsURL"
|
|
191
|
+
"integrationsChanged" | "gameURL" | "versionsURL"
|
|
179
192
|
>
|
|
180
193
|
return {
|
|
181
194
|
...complete,
|
|
182
195
|
integrationsChanged: !!init.integrationsChanged,
|
|
196
|
+
gameURL: init.gameURL ?? null,
|
|
183
197
|
versionsURL: init.versionsURL ?? null,
|
|
184
198
|
}
|
|
185
199
|
}
|