@playdrop/playdrop-cli 0.11.8 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/client-meta.json +2 -2
- package/dist/apps/build.d.ts +1 -1
- package/dist/apps/build.js +4 -6
- package/dist/apps/index.d.ts +4 -5
- package/dist/apps/index.js +14 -16
- package/dist/apps/loadCheck.d.ts +76 -0
- package/dist/apps/loadCheck.js +874 -0
- package/dist/apps/upload.d.ts +3 -2
- package/dist/apps/upload.js +112 -9
- package/dist/assetSpecs.js +2 -5
- package/dist/catalogue-utils.d.ts +1 -0
- package/dist/catalogue-utils.js +1 -0
- package/dist/catalogue.d.ts +3 -1
- package/dist/catalogue.js +19 -3
- package/dist/commands/browse.js +2 -2
- package/dist/commands/build.js +4 -1
- package/dist/commands/captureListing.d.ts +30 -1
- package/dist/commands/captureListing.js +308 -125
- package/dist/commands/check.d.ts +8 -0
- package/dist/commands/check.js +188 -0
- package/dist/commands/create.js +17 -15
- package/dist/commands/createRemixContent.js +2 -2
- package/dist/commands/detail.js +2 -2
- package/dist/commands/dev.js +9 -12
- package/dist/commands/devServer.d.ts +2 -2
- package/dist/commands/devServer.js +3 -4
- package/dist/commands/marketing.js +10 -11
- package/dist/commands/play.js +2 -2
- package/dist/commands/review.d.ts +20 -0
- package/dist/commands/review.js +112 -0
- package/dist/commands/upload-content.d.ts +1 -1
- package/dist/commands/upload-content.js +1 -1
- package/dist/commands/upload.d.ts +2 -1
- package/dist/commands/upload.js +9 -52
- package/dist/commands/validate.js +4 -161
- package/dist/commands/worker/runtime.d.ts +1 -0
- package/dist/commands/worker/runtime.js +48 -5
- package/dist/commands/worker.d.ts +5 -6
- package/dist/commands/worker.js +42 -92
- package/dist/config.js +1 -2
- package/dist/index.js +33 -49
- package/dist/playwright.d.ts +5 -0
- package/dist/playwright.js +60 -1
- package/node_modules/@playdrop/api-client/dist/client.d.ts +5 -3
- package/node_modules/@playdrop/api-client/dist/client.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/client.js +10 -27
- package/node_modules/@playdrop/api-client/dist/domains/admin.d.ts +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/admin.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/apps.d.ts +2 -1
- package/node_modules/@playdrop/api-client/dist/domains/apps.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/apps.js +11 -0
- package/node_modules/@playdrop/api-client/dist/domains/assets.d.ts +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/assets.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/auth.d.ts +3 -1
- package/node_modules/@playdrop/api-client/dist/domains/auth.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/auth.js +22 -0
- package/node_modules/@playdrop/api-client/dist/domains/payments.d.ts +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/payments.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/index.d.ts +7 -6
- package/node_modules/@playdrop/api-client/dist/index.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/index.js +11 -6
- package/node_modules/@playdrop/boxel-core/dist/src/entity-cleaner.js +0 -7
- package/node_modules/@playdrop/boxel-core/dist/src/entity-cleaner.js.map +1 -1
- package/node_modules/@playdrop/boxel-core/dist/src/humanoid/r15/textured-builder.js +2 -46
- package/node_modules/@playdrop/boxel-core/dist/src/humanoid/r15/textured-builder.js.map +1 -1
- package/node_modules/@playdrop/boxel-core/dist/src/humanoid/r15/voxel-builder.js +2 -22
- package/node_modules/@playdrop/boxel-core/dist/src/humanoid/r15/voxel-builder.js.map +1 -1
- package/node_modules/@playdrop/boxel-core/dist/src/palette_tools.js.map +1 -1
- package/node_modules/@playdrop/boxel-core/dist/src/serialization.js +1 -1
- package/node_modules/@playdrop/boxel-core/dist/src/serialization.js.map +1 -1
- package/node_modules/@playdrop/boxel-core/dist/src/transforms/textured-boxes/infer-face.js.map +1 -1
- package/node_modules/@playdrop/boxel-core/dist/src/transforms/textured-boxes/layer-mode.js +2 -2
- package/node_modules/@playdrop/boxel-core/dist/src/transforms/textured-boxes/layer-mode.js.map +1 -1
- package/node_modules/@playdrop/boxel-core/dist/src/transforms/textured-boxes/slice.js +0 -11
- package/node_modules/@playdrop/boxel-core/dist/src/transforms/textured-boxes/slice.js.map +1 -1
- package/node_modules/@playdrop/boxel-core/dist/src/transforms/upscale.js.map +1 -1
- package/node_modules/@playdrop/boxel-core/dist/src/validation.d.ts +1 -1
- package/node_modules/@playdrop/boxel-core/dist/src/validation.js +0 -20
- package/node_modules/@playdrop/boxel-core/dist/src/validation.js.map +1 -1
- package/node_modules/@playdrop/boxel-three/dist/src/exporters/glb.d.ts +2 -2
- package/node_modules/@playdrop/boxel-three/dist/src/exporters/glb.js +2 -12
- package/node_modules/@playdrop/boxel-three/dist/src/voxels/faces.js +1 -125
- package/node_modules/@playdrop/config/client-meta.json +2 -2
- package/node_modules/@playdrop/config/dist/src/client-meta.d.ts +8 -0
- package/node_modules/@playdrop/config/dist/src/client-meta.d.ts.map +1 -0
- package/node_modules/@playdrop/config/dist/src/client-meta.js +51 -0
- package/node_modules/@playdrop/config/dist/src/deployment.d.ts.map +1 -1
- package/node_modules/@playdrop/config/dist/src/deployment.js +2 -32
- package/node_modules/@playdrop/config/dist/src/index.d.ts +2 -2
- package/node_modules/@playdrop/config/dist/src/index.d.ts.map +1 -1
- package/node_modules/@playdrop/config/dist/src/index.js +3 -29
- package/node_modules/@playdrop/config/dist/src/runtime-service-origins.d.ts +0 -1
- package/node_modules/@playdrop/config/dist/src/runtime-service-origins.d.ts.map +1 -1
- package/node_modules/@playdrop/config/dist/src/runtime-service-origins.js +21 -5
- package/node_modules/@playdrop/config/dist/src/server/fastify.d.ts +2 -2
- package/node_modules/@playdrop/config/dist/src/server/fastify.d.ts.map +1 -1
- package/node_modules/@playdrop/config/dist/src/server/fastify.js +0 -1
- package/node_modules/@playdrop/config/dist/test/runtime-service-origins.test.js +8 -0
- package/node_modules/@playdrop/config/dist/tsconfig.tsbuildinfo +1 -1
- package/node_modules/@playdrop/types/dist/api.d.ts +25 -24
- package/node_modules/@playdrop/types/dist/api.d.ts.map +1 -1
- package/node_modules/@playdrop/types/dist/api.js +5 -10
- package/node_modules/@playdrop/types/dist/version.d.ts +14 -0
- package/node_modules/@playdrop/types/dist/version.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/apps/launchCheck.d.ts +0 -39
- package/dist/apps/launchCheck.js +0 -414
- package/dist/captureRuntime.d.ts +0 -73
- package/dist/captureRuntime.js +0 -1021
- package/dist/commands/capture.d.ts +0 -14
- package/dist/commands/capture.js +0 -550
- package/dist/commands/captureRemote.d.ts +0 -17
- package/dist/commands/captureRemote.js +0 -394
- package/node_modules/@playdrop/types/dist/entity.d.ts +0 -31
- package/node_modules/@playdrop/types/dist/entity.d.ts.map +0 -1
- package/node_modules/@playdrop/types/dist/entity.js +0 -67
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.check = check;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const types_1 = require("@playdrop/types");
|
|
7
|
+
const commandContext_1 = require("../commandContext");
|
|
8
|
+
const catalogue_1 = require("../catalogue");
|
|
9
|
+
const catalogue_utils_1 = require("../catalogue-utils");
|
|
10
|
+
const http_1 = require("../http");
|
|
11
|
+
const messages_1 = require("../messages");
|
|
12
|
+
const loadCheck_1 = require("../apps/loadCheck");
|
|
13
|
+
const devShared_1 = require("./devShared");
|
|
14
|
+
function resolveProjectCheckTarget(targetArg, appOption) {
|
|
15
|
+
try {
|
|
16
|
+
return (0, devShared_1.resolveDevTarget)(targetArg, appOption);
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
const code = error?.code;
|
|
20
|
+
const message = error?.message || 'Unable to resolve project check target.';
|
|
21
|
+
const suggestions = code === 'app_required'
|
|
22
|
+
? ['Use "--app <name>" to choose which app to check.']
|
|
23
|
+
: code === 'catalogue_missing'
|
|
24
|
+
? ['Run the command inside a Playdrop workspace with catalogue.json.']
|
|
25
|
+
: ['Provide a valid catalogue-backed app target.'];
|
|
26
|
+
(0, messages_1.printErrorWithHelp)(message, suggestions, { command: 'project check' });
|
|
27
|
+
process.exitCode = 1;
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function parseProjectCheckTimeoutMs(value) {
|
|
32
|
+
if (value === undefined || value === null || value === '') {
|
|
33
|
+
return 15000;
|
|
34
|
+
}
|
|
35
|
+
const numeric = typeof value === 'number' ? value : Number(value);
|
|
36
|
+
if (!Number.isFinite(numeric) || numeric <= 0) {
|
|
37
|
+
throw new Error('Timeout must be a positive number of seconds.');
|
|
38
|
+
}
|
|
39
|
+
if (numeric > 600) {
|
|
40
|
+
throw new Error('Timeout cannot exceed 600 seconds.');
|
|
41
|
+
}
|
|
42
|
+
return Math.round(numeric * 1000);
|
|
43
|
+
}
|
|
44
|
+
function readProjectCheckActions(actionsPath) {
|
|
45
|
+
const normalizedPath = actionsPath?.trim() ?? '';
|
|
46
|
+
if (!normalizedPath) {
|
|
47
|
+
return [];
|
|
48
|
+
}
|
|
49
|
+
const raw = (0, node_fs_1.readFileSync)(normalizedPath, 'utf8');
|
|
50
|
+
return (0, loadCheck_1.normalizeProjectCheckActions)(JSON.parse(raw));
|
|
51
|
+
}
|
|
52
|
+
function defaultProjectCheckScreenshotPath(appName) {
|
|
53
|
+
return (0, node_path_1.join)('assets', 'marketing', 'playdrop', 'check', `${appName}.png`);
|
|
54
|
+
}
|
|
55
|
+
async function check(targetArg, options = {}) {
|
|
56
|
+
let timeoutMs;
|
|
57
|
+
let actions;
|
|
58
|
+
try {
|
|
59
|
+
timeoutMs = parseProjectCheckTimeoutMs(options.timeout);
|
|
60
|
+
actions = readProjectCheckActions(options.actions);
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
(0, messages_1.printErrorWithHelp)(error?.message || 'Invalid project check options.', ['Use --actions with a JSON array of click, press, and wait actions.'], { command: 'project check' });
|
|
64
|
+
process.exitCode = 1;
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const resolvedTarget = resolveProjectCheckTarget(targetArg, options.app);
|
|
68
|
+
if (!resolvedTarget) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const filePath = resolvedTarget.htmlPath;
|
|
72
|
+
if (!(0, node_fs_1.existsSync)(filePath) || !(0, node_fs_1.statSync)(filePath).isFile()) {
|
|
73
|
+
(0, messages_1.printErrorWithHelp)(`App HTML was not found at ${filePath}.`, ['Run the app build first or fix the catalogue file path.'], { command: 'project check' });
|
|
74
|
+
process.exitCode = 1;
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const taskLookup = (0, catalogue_1.findAppTaskByFile)(filePath);
|
|
78
|
+
if (taskLookup.errors.length > 0) {
|
|
79
|
+
(0, messages_1.printErrorWithHelp)(taskLookup.errors[0] || 'Failed to resolve the app task from catalogue.json.', taskLookup.errors.slice(1), { command: 'project check' });
|
|
80
|
+
process.exitCode = 1;
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (!taskLookup.task) {
|
|
84
|
+
(0, messages_1.printErrorWithHelp)('project check requires a catalogue-backed app target.', ['Add this app to catalogue.json, then rerun "playdrop project check".'], { command: 'project check' });
|
|
85
|
+
process.exitCode = 1;
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
let appName = resolvedTarget.appName;
|
|
89
|
+
try {
|
|
90
|
+
const match = (0, catalogue_utils_1.findAppDefinition)(filePath);
|
|
91
|
+
appName = match.name;
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
if (resolvedTarget.cataloguePath) {
|
|
95
|
+
(0, messages_1.printErrorWithHelp)(error?.message || 'Catalogue lookup failed.', ['Ensure the HTML file is listed exactly once in catalogue.json with a valid type.'], { command: 'project check' });
|
|
96
|
+
process.exitCode = 1;
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
const screenshotPath = options.screenshot?.trim() || defaultProjectCheckScreenshotPath(appName);
|
|
101
|
+
const workspacePath = resolvedTarget.cataloguePath ?? (0, node_path_1.dirname)(filePath);
|
|
102
|
+
await (0, commandContext_1.withEnvironment)('project check', 'Checking the Playdrop hosted game shell', async ({ client, env, envConfig, account, token }) => {
|
|
103
|
+
let currentUsername = account?.username?.trim() ?? '';
|
|
104
|
+
if (!currentUsername) {
|
|
105
|
+
try {
|
|
106
|
+
currentUsername = await (0, devShared_1.fetchDevUsername)(client);
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
if (error instanceof http_1.CLIUnsupportedClientError) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (error instanceof types_1.UnsupportedClientError) {
|
|
113
|
+
(0, http_1.handleUnsupportedError)(error, 'Authentication');
|
|
114
|
+
process.exitCode = 1;
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (error instanceof types_1.ApiError) {
|
|
118
|
+
(0, messages_1.printErrorWithHelp)(`Could not fetch your account (status ${error.status}).`, ['Run "playdrop auth login" to refresh your session.'], { command: 'project check' });
|
|
119
|
+
process.exitCode = 1;
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
if ((0, devShared_1.isNetworkError)(error)) {
|
|
123
|
+
(0, messages_1.printNetworkIssue)('Could not reach the Playdrop API to resolve your account.', 'project check');
|
|
124
|
+
process.exitCode = 1;
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
throw error;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
await (0, devShared_1.assertAppRegistered)(client, currentUsername, appName);
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
if (error instanceof http_1.CLIUnsupportedClientError) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (error instanceof types_1.UnsupportedClientError) {
|
|
138
|
+
(0, http_1.handleUnsupportedError)(error, 'Project check');
|
|
139
|
+
process.exitCode = 1;
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
if (error instanceof types_1.ApiError && error.status === 404) {
|
|
143
|
+
(0, messages_1.printErrorWithHelp)(`App ${currentUsername}/${appName} is not registered on ${env}.`, [`Run "playdrop project create app ${appName}" before using project check.`], { command: 'project check' });
|
|
144
|
+
process.exitCode = 1;
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
if ((0, devShared_1.isNetworkError)(error)) {
|
|
148
|
+
(0, messages_1.printNetworkIssue)('Could not reach the Playdrop API to verify the app registration.', 'project check');
|
|
149
|
+
process.exitCode = 1;
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
throw error;
|
|
153
|
+
}
|
|
154
|
+
const projectInfo = (0, devShared_1.findProjectInfo)(filePath);
|
|
155
|
+
const devScriptAvailable = Boolean(projectInfo.projectDir
|
|
156
|
+
&& projectInfo.packageJson
|
|
157
|
+
&& typeof projectInfo.packageJson.scripts?.dev === 'string');
|
|
158
|
+
const entryLabel = (0, node_path_1.relative)(process.cwd(), filePath) || filePath;
|
|
159
|
+
console.log(`[check] Preparing ${entryLabel}.`);
|
|
160
|
+
if (projectInfo.projectDir && !devScriptAvailable && projectInfo.packageJsonPath) {
|
|
161
|
+
const projectLabel = (0, devShared_1.formatProjectLabel)(projectInfo);
|
|
162
|
+
if (projectLabel) {
|
|
163
|
+
console.log(`[check] package.json detected at ${projectLabel}, but no "dev" script was found. Run your app build manually if needed.`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
const result = await (0, loadCheck_1.runLocalHostedLoadCheck)({
|
|
167
|
+
client,
|
|
168
|
+
apiBase: envConfig.apiBase,
|
|
169
|
+
webBase: envConfig.webBase,
|
|
170
|
+
creatorUsername: currentUsername,
|
|
171
|
+
task: taskLookup.task,
|
|
172
|
+
timeoutMs,
|
|
173
|
+
token,
|
|
174
|
+
currentUser: null,
|
|
175
|
+
screenshotPath,
|
|
176
|
+
actions,
|
|
177
|
+
});
|
|
178
|
+
if (result.status !== 'PASSED') {
|
|
179
|
+
(0, messages_1.printErrorWithHelp)((0, loadCheck_1.formatHostedLoadCheckFailure)(appName, result, 'local'), result.screenshotPath ? [`Screenshot: ${result.screenshotPath}`] : [], { command: 'project check' });
|
|
180
|
+
process.exitCode = 1;
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
console.log(`[check] Passed ${currentUsername}/${appName}.`);
|
|
184
|
+
if (result.webglRenderer) {
|
|
185
|
+
console.log(`[check] Hardware renderer: ${result.webglRenderer}`);
|
|
186
|
+
}
|
|
187
|
+
}, { workspacePath });
|
|
188
|
+
}
|
package/dist/commands/create.js
CHANGED
|
@@ -1,26 +1,25 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/* eslint-disable complexity, max-lines, max-lines-per-function */
|
|
3
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
4
|
};
|
|
6
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
6
|
exports.createAssetSpecProject = createAssetSpecProject;
|
|
8
7
|
exports.create = create;
|
|
9
|
-
const
|
|
10
|
-
const
|
|
8
|
+
const types_1 = require("@playdrop/types");
|
|
9
|
+
const app_1 = require("@playdrop/types/app");
|
|
10
|
+
const fflate_1 = require("fflate");
|
|
11
|
+
const node_child_process_1 = require("node:child_process");
|
|
11
12
|
const node_fs_1 = require("node:fs");
|
|
12
13
|
const node_path_1 = require("node:path");
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
14
|
+
const node_process_1 = require("node:process");
|
|
15
|
+
const promises_1 = __importDefault(require("node:readline/promises"));
|
|
16
|
+
const catalogue_1 = require("../catalogue");
|
|
17
|
+
const catalogue_utils_1 = require("../catalogue-utils");
|
|
18
|
+
const clientInfo_1 = require("../clientInfo");
|
|
16
19
|
const commandContext_1 = require("../commandContext");
|
|
17
20
|
const http_1 = require("../http");
|
|
18
21
|
const messages_1 = require("../messages");
|
|
19
22
|
const init_1 = require("./init");
|
|
20
|
-
const app_1 = require("@playdrop/types/app");
|
|
21
|
-
const catalogue_utils_1 = require("../catalogue-utils");
|
|
22
|
-
const catalogue_1 = require("../catalogue");
|
|
23
|
-
const clientInfo_1 = require("../clientInfo");
|
|
24
23
|
const CATALOGUE_FILENAME = 'catalogue.json';
|
|
25
24
|
const LEGACY_CATALOGUE_VERSION_KEY = ['schema', 'Version'].join('');
|
|
26
25
|
const ALLOWED_CATALOGUE_TOP_LEVEL_KEYS = new Set(['apps', 'assetSpecs', 'assets', 'assetPacks']);
|
|
@@ -306,7 +305,10 @@ function buildCatalogueEntry(name, metadata, sourceInfo, relativeFilePath) {
|
|
|
306
305
|
entry.surfaceTargets = { ...parsed.map };
|
|
307
306
|
}
|
|
308
307
|
catch (error) {
|
|
309
|
-
|
|
308
|
+
const message = error instanceof Error && error.message.trim()
|
|
309
|
+
? error.message.trim()
|
|
310
|
+
: String(error);
|
|
311
|
+
throw new Error(`Invalid surfaceTargets for ${name}: ${message}`);
|
|
310
312
|
}
|
|
311
313
|
}
|
|
312
314
|
if (Object.prototype.hasOwnProperty.call(metadata, 'templateSource')) {
|
|
@@ -1048,8 +1050,8 @@ function describeInitSummary(summary) {
|
|
|
1048
1050
|
async function create(name, options = {}) {
|
|
1049
1051
|
const file = (0, node_path_1.resolve)(`${name}.html`);
|
|
1050
1052
|
const projectDirCandidate = (0, node_path_1.resolve)(name);
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
+
const templateOptionRaw = options.template?.trim();
|
|
1054
|
+
const remixOptionRaw = options.remix?.trim();
|
|
1053
1055
|
let parsedTemplate = null;
|
|
1054
1056
|
let parsedRemix = null;
|
|
1055
1057
|
const existingLookup = (0, catalogue_1.resolveCatalogueEntries)(process.cwd(), { filterName: name });
|
|
@@ -1149,7 +1151,7 @@ async function create(name, options = {}) {
|
|
|
1149
1151
|
process.exitCode = 1;
|
|
1150
1152
|
return;
|
|
1151
1153
|
}
|
|
1152
|
-
const detailMessage =
|
|
1154
|
+
const detailMessage = error instanceof Error && error.message.trim()
|
|
1153
1155
|
? error.message.trim()
|
|
1154
1156
|
: '';
|
|
1155
1157
|
const problem = detailMessage
|
|
@@ -1222,7 +1224,7 @@ async function create(name, options = {}) {
|
|
|
1222
1224
|
try {
|
|
1223
1225
|
(0, node_fs_1.mkdirSync)(projectDir);
|
|
1224
1226
|
}
|
|
1225
|
-
catch
|
|
1227
|
+
catch {
|
|
1226
1228
|
(0, messages_1.printErrorWithHelp)(`Cannot create ${projectDir} because it already exists.`, [
|
|
1227
1229
|
'Remove or rename the existing directory before running "playdrop project create app" again.'
|
|
1228
1230
|
], { command: 'project create app' });
|
|
@@ -3,9 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.createAssetRemix = createAssetRemix;
|
|
4
4
|
exports.createPackRemix = createPackRemix;
|
|
5
5
|
exports.createRemixContent = createRemixContent;
|
|
6
|
+
const types_1 = require("@playdrop/types");
|
|
6
7
|
const node_fs_1 = require("node:fs");
|
|
7
8
|
const node_path_1 = require("node:path");
|
|
8
|
-
const types_1 = require("@playdrop/types");
|
|
9
9
|
const commandContext_1 = require("../commandContext");
|
|
10
10
|
const http_1 = require("../http");
|
|
11
11
|
const messages_1 = require("../messages");
|
|
@@ -232,7 +232,7 @@ async function createPackRemix(name, remixRef) {
|
|
|
232
232
|
const catalogue = readWorkspaceCatalogue(cataloguePath);
|
|
233
233
|
assertWorkspaceRootCanOwnEntries(cataloguePath);
|
|
234
234
|
ensureUniqueEntryName(catalogue, 'pack', name);
|
|
235
|
-
|
|
235
|
+
await client.fetchAssetPackBySlug(parsedRef.creatorUsername, parsedRef.name);
|
|
236
236
|
const versions = await client.listAssetPackVersions(parsedRef.creatorUsername, parsedRef.name, { limit: 200, offset: 0 });
|
|
237
237
|
const version = versions.versions.find((entry) => entry.version === parsedRef.version);
|
|
238
238
|
if (!version) {
|
package/dist/commands/detail.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.detail = detail;
|
|
4
|
+
const appUrls_1 = require("../appUrls");
|
|
4
5
|
const commandContext_1 = require("../commandContext");
|
|
5
6
|
const errors_1 = require("../errors");
|
|
6
7
|
const messages_1 = require("../messages");
|
|
7
8
|
const output_1 = require("../output");
|
|
8
9
|
const refs_1 = require("../refs");
|
|
9
|
-
|
|
10
|
-
function printRefValidationError(raw) {
|
|
10
|
+
function printRefValidationError(_raw) {
|
|
11
11
|
(0, messages_1.printErrorWithHelp)('A canonical ref is required.', [
|
|
12
12
|
'Use the format <creator>/<kind>/<name>.',
|
|
13
13
|
'Kinds must be exactly app, asset, asset-spec, or asset-pack.',
|
package/dist/commands/dev.js
CHANGED
|
@@ -4,19 +4,19 @@ exports.formatDevRuntimeAssetManifestFailure = formatDevRuntimeAssetManifestFail
|
|
|
4
4
|
exports.dev = dev;
|
|
5
5
|
exports.resolveDevRouterPort = resolveDevRouterPort;
|
|
6
6
|
exports.resolveCliDevRouterPort = resolveCliDevRouterPort;
|
|
7
|
+
const types_1 = require("@playdrop/types");
|
|
7
8
|
const node_fs_1 = require("node:fs");
|
|
8
9
|
const node_path_1 = require("node:path");
|
|
9
|
-
const
|
|
10
|
+
const appUrls_1 = require("../appUrls");
|
|
11
|
+
const catalogue_1 = require("../catalogue");
|
|
12
|
+
const catalogue_utils_1 = require("../catalogue-utils");
|
|
10
13
|
const commandContext_1 = require("../commandContext");
|
|
14
|
+
const devAuth_1 = require("../devAuth");
|
|
11
15
|
const http_1 = require("../http");
|
|
12
16
|
const messages_1 = require("../messages");
|
|
13
|
-
const catalogue_1 = require("../catalogue");
|
|
14
|
-
const catalogue_utils_1 = require("../catalogue-utils");
|
|
15
|
-
const devShared_1 = require("./devShared");
|
|
16
|
-
const appUrls_1 = require("../appUrls");
|
|
17
|
-
const devServer_1 = require("./devServer");
|
|
18
17
|
const devRuntimeAssets_1 = require("./devRuntimeAssets");
|
|
19
|
-
const
|
|
18
|
+
const devServer_1 = require("./devServer");
|
|
19
|
+
const devShared_1 = require("./devShared");
|
|
20
20
|
function formatDevRuntimeAssetManifestFailure(error) {
|
|
21
21
|
const rawMessage = error instanceof Error ? error.message : String(error ?? 'unknown_error');
|
|
22
22
|
if (rawMessage.startsWith('dev_runtime_asset_ref_invalid:')) {
|
|
@@ -217,9 +217,7 @@ async function dev(targetArg, appOption, devOptions = {}) {
|
|
|
217
217
|
return;
|
|
218
218
|
}
|
|
219
219
|
const workspacePath = resolvedTarget.cataloguePath ?? (0, node_path_1.dirname)(filePath);
|
|
220
|
-
await (0, commandContext_1.withEnvironment)('project dev', 'Starting the dev server',
|
|
221
|
-
// eslint-disable-next-line complexity
|
|
222
|
-
async ({ client, env, envConfig, account }) => {
|
|
220
|
+
await (0, commandContext_1.withEnvironment)('project dev', 'Starting the dev server', async ({ client, env, envConfig, account }) => {
|
|
223
221
|
let currentUsername = account?.username?.trim() ?? '';
|
|
224
222
|
if (!currentUsername) {
|
|
225
223
|
try {
|
|
@@ -250,10 +248,9 @@ async function dev(targetArg, appOption, devOptions = {}) {
|
|
|
250
248
|
throw error;
|
|
251
249
|
}
|
|
252
250
|
}
|
|
253
|
-
let appResponse = null;
|
|
254
251
|
if (resolvedTarget.cataloguePath) {
|
|
255
252
|
try {
|
|
256
|
-
|
|
253
|
+
await (0, devShared_1.assertAppRegistered)(client, currentUsername, appName);
|
|
257
254
|
}
|
|
258
255
|
catch (error) {
|
|
259
256
|
if (error instanceof http_1.CLIUnsupportedClientError) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import http from 'node:http';
|
|
2
1
|
import { type ChildProcess } from 'node:child_process';
|
|
3
|
-
import
|
|
2
|
+
import http from 'node:http';
|
|
4
3
|
import type { DevRuntimeAssetManifestRegistration } from './devRuntimeAssets';
|
|
4
|
+
import type { ProjectInfo } from './devShared';
|
|
5
5
|
export interface StartDevServerOptions {
|
|
6
6
|
appName: string;
|
|
7
7
|
appType: string;
|
|
@@ -14,11 +14,11 @@ exports.isDevServerAvailable = isDevServerAvailable;
|
|
|
14
14
|
exports.createDevRouterServer = createDevRouterServer;
|
|
15
15
|
exports.listenDevRouterServer = listenDevRouterServer;
|
|
16
16
|
exports.runDevRouterServer = runDevRouterServer;
|
|
17
|
-
const node_http_1 = __importDefault(require("node:http"));
|
|
18
|
-
const node_fs_1 = require("node:fs");
|
|
19
|
-
const node_path_1 = require("node:path");
|
|
20
17
|
const node_child_process_1 = require("node:child_process");
|
|
21
18
|
const node_crypto_1 = require("node:crypto");
|
|
19
|
+
const node_fs_1 = require("node:fs");
|
|
20
|
+
const node_http_1 = __importDefault(require("node:http"));
|
|
21
|
+
const node_path_1 = require("node:path");
|
|
22
22
|
exports.DEV_ROUTER_PORT = 8888;
|
|
23
23
|
const DEV_ROUTER_HOST = '127.0.0.1';
|
|
24
24
|
const CONTROL_PREFIX = '/_playdrop';
|
|
@@ -581,7 +581,6 @@ async function isDevServerAvailable(input, timeoutMs = 1000) {
|
|
|
581
581
|
}
|
|
582
582
|
function createDevRouterServer(initialPort = exports.DEV_ROUTER_PORT) {
|
|
583
583
|
let activePort = initialPort;
|
|
584
|
-
// eslint-disable-next-line complexity
|
|
585
584
|
const handleRequest = async (req, res) => {
|
|
586
585
|
const method = req.method || 'GET';
|
|
587
586
|
const allowedOrigin = resolveApprovedDevRouterOrigin(typeof req.headers.origin === 'string' ? req.headers.origin : undefined);
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/* eslint-disable max-lines */
|
|
3
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
3
|
exports.MARKETING_AUDIO_POLICIES = exports.MARKETING_SURFACES = void 0;
|
|
5
4
|
exports.parseMarketingCaptureOptions = parseMarketingCaptureOptions;
|
|
@@ -11,22 +10,22 @@ exports.buildMarketingCaptureManifest = buildMarketingCaptureManifest;
|
|
|
11
10
|
exports.createMarketingReport = createMarketingReport;
|
|
12
11
|
exports.marketingDoctor = marketingDoctor;
|
|
13
12
|
exports.marketingCapture = marketingCapture;
|
|
13
|
+
const types_1 = require("@playdrop/types");
|
|
14
14
|
const node_child_process_1 = require("node:child_process");
|
|
15
|
-
const promises_1 = require("node:fs/promises");
|
|
16
15
|
const node_fs_1 = require("node:fs");
|
|
17
|
-
const
|
|
16
|
+
const promises_1 = require("node:fs/promises");
|
|
18
17
|
const node_os_1 = require("node:os");
|
|
19
|
-
const
|
|
20
|
-
const
|
|
18
|
+
const node_path_1 = require("node:path");
|
|
19
|
+
const appUrls_1 = require("../appUrls");
|
|
21
20
|
const catalogue_1 = require("../catalogue");
|
|
21
|
+
const catalogue_utils_1 = require("../catalogue-utils");
|
|
22
22
|
const commandContext_1 = require("../commandContext");
|
|
23
23
|
const http_1 = require("../http");
|
|
24
|
-
const appUrls_1 = require("../appUrls");
|
|
25
24
|
const messages_1 = require("../messages");
|
|
26
25
|
const playwright_1 = require("../playwright");
|
|
27
|
-
const devServer_1 = require("./devServer");
|
|
28
|
-
const devRuntimeAssets_1 = require("./devRuntimeAssets");
|
|
29
26
|
const dev_1 = require("./dev");
|
|
27
|
+
const devRuntimeAssets_1 = require("./devRuntimeAssets");
|
|
28
|
+
const devServer_1 = require("./devServer");
|
|
30
29
|
const devShared_1 = require("./devShared");
|
|
31
30
|
exports.MARKETING_SURFACES = ['desktop', 'mobile-landscape', 'mobile-portrait'];
|
|
32
31
|
exports.MARKETING_AUDIO_POLICIES = ['music-and-sfx', 'sfx-only', 'silent'];
|
|
@@ -329,7 +328,7 @@ function loadCatalogueApp(cataloguePath, appName) {
|
|
|
329
328
|
if (!cataloguePath || !(0, node_fs_1.existsSync)(cataloguePath)) {
|
|
330
329
|
return null;
|
|
331
330
|
}
|
|
332
|
-
const raw = JSON.parse(
|
|
331
|
+
const raw = JSON.parse((0, node_fs_1.readFileSync)(cataloguePath, 'utf8'));
|
|
333
332
|
const apps = raw && typeof raw === 'object' && Array.isArray(raw.apps)
|
|
334
333
|
? raw.apps
|
|
335
334
|
: Array.isArray(raw)
|
|
@@ -661,7 +660,7 @@ function muxMarketingAudio(videoPath, audioPath) {
|
|
|
661
660
|
'-shortest',
|
|
662
661
|
muxedPath,
|
|
663
662
|
], 'ffmpeg_failed');
|
|
664
|
-
|
|
663
|
+
(0, node_fs_1.renameSync)(muxedPath, videoPath);
|
|
665
664
|
}
|
|
666
665
|
function extractPoster(videoPath, posterPath) {
|
|
667
666
|
runTool('ffmpeg', [
|
|
@@ -861,7 +860,7 @@ async function marketingCapture(targetArg, options = {}) {
|
|
|
861
860
|
const outputPaths = resolveMarketingOutputPaths(projectRoot, appName, parsedOptions.outputDir);
|
|
862
861
|
const projectInfo = (0, devShared_1.findProjectInfo)(resolvedTarget.htmlPath);
|
|
863
862
|
const devScriptAvailable = Boolean(projectInfo.projectDir && projectInfo.packageJson && typeof projectInfo.packageJson.scripts?.dev === 'string');
|
|
864
|
-
await (0, commandContext_1.withEnvironment)('project marketing capture', 'Capturing marketing media', async ({ client, env, envConfig }) => {
|
|
863
|
+
await (0, commandContext_1.withEnvironment)('project marketing capture', 'Capturing marketing media', async ({ client, env: _env, envConfig }) => {
|
|
865
864
|
let currentUsername = '';
|
|
866
865
|
try {
|
|
867
866
|
const currentUser = await (0, devShared_1.fetchDevUser)(client);
|
package/dist/commands/play.js
CHANGED
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.play = play;
|
|
4
4
|
const types_1 = require("@playdrop/types");
|
|
5
|
-
const commandContext_1 = require("../commandContext");
|
|
6
5
|
const appUrls_1 = require("../appUrls");
|
|
7
6
|
const browser_1 = require("../browser");
|
|
7
|
+
const commandContext_1 = require("../commandContext");
|
|
8
8
|
const http_1 = require("../http");
|
|
9
9
|
const messages_1 = require("../messages");
|
|
10
10
|
const output_1 = require("../output");
|
|
11
11
|
const refs_1 = require("../refs");
|
|
12
12
|
const devShared_1 = require("./devShared");
|
|
13
|
-
function printPlayRefValidationError(
|
|
13
|
+
function printPlayRefValidationError(_rawRef) {
|
|
14
14
|
(0, messages_1.printErrorWithHelp)('A canonical app ref is required.', [
|
|
15
15
|
'Use the format <creator>/app/<name>.',
|
|
16
16
|
'Example: playdrop play playdrop/app/hangingout',
|
|
@@ -33,6 +33,26 @@ export type ReviewRatingCardOptions = {
|
|
|
33
33
|
punchline?: string;
|
|
34
34
|
title?: string;
|
|
35
35
|
};
|
|
36
|
+
export type ReviewListWindowsOptions = {
|
|
37
|
+
pid: string;
|
|
38
|
+
};
|
|
39
|
+
export type ReviewScreenshotOptions = {
|
|
40
|
+
metadata?: string;
|
|
41
|
+
out: string;
|
|
42
|
+
pid: string;
|
|
43
|
+
windowId?: string;
|
|
44
|
+
};
|
|
45
|
+
export declare function buildReviewListWindowsRecorderArgs(options: ReviewListWindowsOptions): string[];
|
|
46
|
+
export declare function buildReviewScreenshotRecorderArgs(options: ReviewScreenshotOptions): {
|
|
47
|
+
args: string[];
|
|
48
|
+
metadataPath: string;
|
|
49
|
+
outputPath: string;
|
|
50
|
+
};
|
|
51
|
+
export declare function listReviewCaptureWindows(options: ReviewListWindowsOptions): Promise<void>;
|
|
52
|
+
export declare function captureReviewScreenshot(options: ReviewScreenshotOptions): Promise<{
|
|
53
|
+
metadataPath: string;
|
|
54
|
+
outputPath: string;
|
|
55
|
+
}>;
|
|
36
56
|
export declare function validateGameReviewResult(input: ValidateGameReviewResultInput): Promise<ReviewValidationResult>;
|
|
37
57
|
export declare function validateReviewResultCommand(options: ReviewValidateResultOptions): Promise<void>;
|
|
38
58
|
export declare function composeReviewEvidence(options: ReviewComposeEvidenceOptions): Promise<{
|
package/dist/commands/review.js
CHANGED
|
@@ -4,14 +4,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.REQUIRED_REVIEW_EVIDENCE_FILES = exports.REVIEW_CRITERIA = void 0;
|
|
7
|
+
exports.buildReviewListWindowsRecorderArgs = buildReviewListWindowsRecorderArgs;
|
|
8
|
+
exports.buildReviewScreenshotRecorderArgs = buildReviewScreenshotRecorderArgs;
|
|
9
|
+
exports.listReviewCaptureWindows = listReviewCaptureWindows;
|
|
10
|
+
exports.captureReviewScreenshot = captureReviewScreenshot;
|
|
7
11
|
exports.validateGameReviewResult = validateGameReviewResult;
|
|
8
12
|
exports.validateReviewResultCommand = validateReviewResultCommand;
|
|
9
13
|
exports.composeReviewEvidence = composeReviewEvidence;
|
|
10
14
|
exports.createReviewRatingCard = createReviewRatingCard;
|
|
11
15
|
const node_path_1 = __importDefault(require("node:path"));
|
|
16
|
+
const node_child_process_1 = require("node:child_process");
|
|
12
17
|
const node_fs_1 = require("node:fs");
|
|
13
18
|
const sharp_1 = __importDefault(require("sharp"));
|
|
14
19
|
const output_1 = require("../output");
|
|
20
|
+
const captureListing_1 = require("./captureListing");
|
|
15
21
|
exports.REVIEW_CRITERIA = [
|
|
16
22
|
'Gameplay / Core Loop',
|
|
17
23
|
'Depth / Replayability',
|
|
@@ -46,6 +52,7 @@ exports.REQUIRED_REVIEW_EVIDENCE_FILES = [
|
|
|
46
52
|
'rating-card.png',
|
|
47
53
|
];
|
|
48
54
|
const REVIEW_EVIDENCE_MAX_BYTES = 10 * 1024 * 1024;
|
|
55
|
+
const REVIEW_RECORDER_TIMEOUT_MS = 15000;
|
|
49
56
|
function resolveFilePath(filePath, code) {
|
|
50
57
|
const normalized = typeof filePath === 'string' ? filePath.trim() : '';
|
|
51
58
|
if (!normalized) {
|
|
@@ -167,6 +174,111 @@ async function assertPngFile(filePath) {
|
|
|
167
174
|
}
|
|
168
175
|
}
|
|
169
176
|
}
|
|
177
|
+
async function assertNonBlankPngFile(filePath) {
|
|
178
|
+
await assertPngFile(filePath);
|
|
179
|
+
const image = (0, sharp_1.default)(filePath);
|
|
180
|
+
const metadata = await image.metadata();
|
|
181
|
+
if (!metadata.width || !metadata.height) {
|
|
182
|
+
throw new Error(`review_screenshot_invalid_image:${filePath}`);
|
|
183
|
+
}
|
|
184
|
+
const stats = await image.stats();
|
|
185
|
+
const colorChannels = stats.channels.slice(0, 3);
|
|
186
|
+
const brightest = Math.max(...colorChannels.map((channel) => channel.max));
|
|
187
|
+
if (brightest <= 5) {
|
|
188
|
+
throw new Error(`review_screenshot_blank:${filePath}`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
function parsePositiveInteger(value, code) {
|
|
192
|
+
const normalized = typeof value === 'string' ? value.trim() : '';
|
|
193
|
+
const parsed = Number.parseInt(normalized, 10);
|
|
194
|
+
if (!Number.isSafeInteger(parsed) || parsed <= 0 || String(parsed) !== normalized) {
|
|
195
|
+
throw new Error(code);
|
|
196
|
+
}
|
|
197
|
+
return parsed;
|
|
198
|
+
}
|
|
199
|
+
function buildReviewListWindowsRecorderArgs(options) {
|
|
200
|
+
const pid = parsePositiveInteger(options.pid, 'invalid_review_window_pid');
|
|
201
|
+
return ['--list-windows', '--pid', String(pid)];
|
|
202
|
+
}
|
|
203
|
+
function buildReviewScreenshotRecorderArgs(options) {
|
|
204
|
+
const pid = parsePositiveInteger(options.pid, 'invalid_review_window_pid');
|
|
205
|
+
const outputPath = resolveFilePath(options.out, 'missing_out');
|
|
206
|
+
const metadataPath = options.metadata
|
|
207
|
+
? resolveFilePath(options.metadata, 'invalid_review_screenshot_metadata')
|
|
208
|
+
: outputPath.replace(/\.png$/i, '') + '.metadata.json';
|
|
209
|
+
const args = [
|
|
210
|
+
'--pid',
|
|
211
|
+
String(pid),
|
|
212
|
+
'--screenshot',
|
|
213
|
+
outputPath,
|
|
214
|
+
'--metadata',
|
|
215
|
+
metadataPath,
|
|
216
|
+
];
|
|
217
|
+
if (options.windowId !== undefined && options.windowId !== '') {
|
|
218
|
+
const windowId = parsePositiveInteger(options.windowId, 'invalid_review_window_id');
|
|
219
|
+
args.push('--window-id', String(windowId));
|
|
220
|
+
}
|
|
221
|
+
return { args, metadataPath, outputPath };
|
|
222
|
+
}
|
|
223
|
+
function runRecorder(args) {
|
|
224
|
+
return new Promise((resolve, reject) => {
|
|
225
|
+
const recorderPath = (0, captureListing_1.resolveListingRecorderPath)();
|
|
226
|
+
const child = (0, node_child_process_1.spawn)(recorderPath, args, {
|
|
227
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
228
|
+
});
|
|
229
|
+
let stdout = '';
|
|
230
|
+
let stderr = '';
|
|
231
|
+
let settled = false;
|
|
232
|
+
const timer = setTimeout(() => {
|
|
233
|
+
if (settled) {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
settled = true;
|
|
237
|
+
child.kill('SIGKILL');
|
|
238
|
+
reject(new Error(`review_recorder_timeout:${REVIEW_RECORDER_TIMEOUT_MS}`));
|
|
239
|
+
}, REVIEW_RECORDER_TIMEOUT_MS);
|
|
240
|
+
child.stdout.on('data', (chunk) => {
|
|
241
|
+
stdout += chunk.toString();
|
|
242
|
+
});
|
|
243
|
+
child.stderr.on('data', (chunk) => {
|
|
244
|
+
stderr += chunk.toString();
|
|
245
|
+
});
|
|
246
|
+
child.on('error', (error) => {
|
|
247
|
+
if (settled) {
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
settled = true;
|
|
251
|
+
clearTimeout(timer);
|
|
252
|
+
reject(new Error(`review_recorder_unavailable:${recorderPath}:${error.message}`));
|
|
253
|
+
});
|
|
254
|
+
child.on('close', (code) => {
|
|
255
|
+
if (settled) {
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
settled = true;
|
|
259
|
+
clearTimeout(timer);
|
|
260
|
+
if (code === 0) {
|
|
261
|
+
resolve(stdout);
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
const detail = (stderr || stdout || `exit ${code}`).trim();
|
|
265
|
+
reject(new Error(`review_recorder_failed:${detail}`));
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
async function listReviewCaptureWindows(options) {
|
|
270
|
+
const output = await runRecorder(buildReviewListWindowsRecorderArgs(options));
|
|
271
|
+
process.stdout.write(output);
|
|
272
|
+
}
|
|
273
|
+
async function captureReviewScreenshot(options) {
|
|
274
|
+
const { args, metadataPath, outputPath } = buildReviewScreenshotRecorderArgs(options);
|
|
275
|
+
await node_fs_1.promises.mkdir(node_path_1.default.dirname(outputPath), { recursive: true });
|
|
276
|
+
await node_fs_1.promises.mkdir(node_path_1.default.dirname(metadataPath), { recursive: true });
|
|
277
|
+
await runRecorder(args);
|
|
278
|
+
await assertNonBlankPngFile(outputPath);
|
|
279
|
+
(0, output_1.printSuccess)(`Review screenshot written to ${outputPath}`);
|
|
280
|
+
return { metadataPath, outputPath };
|
|
281
|
+
}
|
|
170
282
|
async function validateGameReviewResult(input) {
|
|
171
283
|
const normalizedState = String(input.reviewState || '').trim().toUpperCase();
|
|
172
284
|
if (!TERMINAL_REVIEW_STATES.has(normalizedState)) {
|
|
@@ -2,7 +2,7 @@ import type { ApiClient } from '@playdrop/api-client';
|
|
|
2
2
|
import { type AssetPackUploadedLocalAsset } from '@playdrop/types';
|
|
3
3
|
import type { AssetPackTask, AssetSpecTask, AssetTask, OwnedAssetTask, PackOwnedAssetTask } from '../catalogue';
|
|
4
4
|
import type { CliTask } from '../taskUtils';
|
|
5
|
-
export type CurrentUserRole = '
|
|
5
|
+
export type CurrentUserRole = 'CREATOR' | 'ADMIN' | null;
|
|
6
6
|
export type UploadedAssetInfo = {
|
|
7
7
|
creatorUsername: string;
|
|
8
8
|
name: string;
|