@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
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
type CaptureOptions = {
|
|
2
|
-
timeoutSeconds?: number;
|
|
3
|
-
appName?: string;
|
|
4
|
-
logLevel?: string;
|
|
5
|
-
screenshotPath?: string;
|
|
6
|
-
surfaceTarget?: string;
|
|
7
|
-
devAuth?: string;
|
|
8
|
-
player?: string | number;
|
|
9
|
-
resetDevPlayer?: string;
|
|
10
|
-
username?: string;
|
|
11
|
-
password?: string;
|
|
12
|
-
};
|
|
13
|
-
export declare function capture(targetArg: string | undefined, options?: CaptureOptions): Promise<void>;
|
|
14
|
-
export {};
|
package/dist/commands/capture.js
DELETED
|
@@ -1,550 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.capture = capture;
|
|
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 http_1 = require("../http");
|
|
8
|
-
const messages_1 = require("../messages");
|
|
9
|
-
const catalogue_utils_1 = require("../catalogue-utils");
|
|
10
|
-
const catalogue_1 = require("../catalogue");
|
|
11
|
-
const devShared_1 = require("./devShared");
|
|
12
|
-
const devServer_1 = require("./devServer");
|
|
13
|
-
const commandContext_1 = require("../commandContext");
|
|
14
|
-
const appUrls_1 = require("../appUrls");
|
|
15
|
-
const captureRuntime_1 = require("../captureRuntime");
|
|
16
|
-
const devAuth_1 = require("../devAuth");
|
|
17
|
-
const devRuntimeAssets_1 = require("./devRuntimeAssets");
|
|
18
|
-
const dev_1 = require("./dev");
|
|
19
|
-
const dev_2 = require("./dev");
|
|
20
|
-
const MOBILE_USER_AGENT = 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1';
|
|
21
|
-
const SURFACE_PRESETS = {
|
|
22
|
-
desktop: {
|
|
23
|
-
label: 'desktop',
|
|
24
|
-
contextOptions: {
|
|
25
|
-
viewport: { width: 1280, height: 720 },
|
|
26
|
-
deviceScaleFactor: 1,
|
|
27
|
-
isMobile: false,
|
|
28
|
-
hasTouch: false,
|
|
29
|
-
},
|
|
30
|
-
},
|
|
31
|
-
mobileLandscape: {
|
|
32
|
-
label: 'mobile-landscape',
|
|
33
|
-
contextOptions: {
|
|
34
|
-
viewport: { width: 896, height: 414 },
|
|
35
|
-
deviceScaleFactor: 2,
|
|
36
|
-
isMobile: true,
|
|
37
|
-
hasTouch: true,
|
|
38
|
-
userAgent: MOBILE_USER_AGENT,
|
|
39
|
-
},
|
|
40
|
-
},
|
|
41
|
-
mobilePortrait: {
|
|
42
|
-
label: 'mobile-portrait',
|
|
43
|
-
contextOptions: {
|
|
44
|
-
viewport: { width: 414, height: 896 },
|
|
45
|
-
deviceScaleFactor: 2,
|
|
46
|
-
isMobile: true,
|
|
47
|
-
hasTouch: true,
|
|
48
|
-
userAgent: MOBILE_USER_AGENT,
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
};
|
|
52
|
-
const SURFACE_ORDER = ['desktop', 'mobileLandscape', 'mobilePortrait'];
|
|
53
|
-
function normalizeSurfaceOverride(value) {
|
|
54
|
-
if (!value)
|
|
55
|
-
return null;
|
|
56
|
-
const normalized = value.trim().toLowerCase().replace(/[-_\s]/g, '');
|
|
57
|
-
if (normalized === 'desktop')
|
|
58
|
-
return 'desktop';
|
|
59
|
-
if (normalized === 'mobilelandscape')
|
|
60
|
-
return 'mobileLandscape';
|
|
61
|
-
if (normalized === 'mobileportrait')
|
|
62
|
-
return 'mobilePortrait';
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
65
|
-
function appSurfaceToId(surface) {
|
|
66
|
-
if (surface === 'DESKTOP')
|
|
67
|
-
return 'desktop';
|
|
68
|
-
if (surface === 'MOBILE_LANDSCAPE')
|
|
69
|
-
return 'mobileLandscape';
|
|
70
|
-
if (surface === 'MOBILE_PORTRAIT')
|
|
71
|
-
return 'mobilePortrait';
|
|
72
|
-
return null;
|
|
73
|
-
}
|
|
74
|
-
function determineDefaultSurface(targets) {
|
|
75
|
-
for (const entry of targets.list) {
|
|
76
|
-
const id = appSurfaceToId(entry);
|
|
77
|
-
if (id)
|
|
78
|
-
return id;
|
|
79
|
-
}
|
|
80
|
-
for (const id of SURFACE_ORDER) {
|
|
81
|
-
if (targets.map[id])
|
|
82
|
-
return id;
|
|
83
|
-
}
|
|
84
|
-
return 'desktop';
|
|
85
|
-
}
|
|
86
|
-
function formatSurfaceList(targets) {
|
|
87
|
-
const enabled = SURFACE_ORDER.filter(id => targets.map[id]).map(id => SURFACE_PRESETS[id].label);
|
|
88
|
-
if (enabled.length === 0) {
|
|
89
|
-
return SURFACE_PRESETS.desktop.label;
|
|
90
|
-
}
|
|
91
|
-
return enabled.join(', ');
|
|
92
|
-
}
|
|
93
|
-
function resolveCaptureLoginOverride(options) {
|
|
94
|
-
const username = options.username?.trim() || '';
|
|
95
|
-
const password = options.password || '';
|
|
96
|
-
if ((username && !password) || (!username && password)) {
|
|
97
|
-
throw new Error('invalid_credentials_pair');
|
|
98
|
-
}
|
|
99
|
-
if (!username) {
|
|
100
|
-
return null;
|
|
101
|
-
}
|
|
102
|
-
return { username, password };
|
|
103
|
-
}
|
|
104
|
-
function resolveCaptureDevOptions(options) {
|
|
105
|
-
const selection = (0, devAuth_1.parseHostedDevAuthSelection)({
|
|
106
|
-
devAuth: options.devAuth,
|
|
107
|
-
player: options.player,
|
|
108
|
-
defaultMode: 'anonymous',
|
|
109
|
-
allowPrompt: false,
|
|
110
|
-
});
|
|
111
|
-
const resetMode = (0, devAuth_1.parseResetDevPlayerMode)(options.resetDevPlayer);
|
|
112
|
-
if (selection.devAuth !== 'player' && resetMode !== 'never') {
|
|
113
|
-
throw new Error('reset_dev_player_requires_player_auth');
|
|
114
|
-
}
|
|
115
|
-
return {
|
|
116
|
-
selection,
|
|
117
|
-
resetMode,
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
// eslint-disable-next-line max-lines-per-function
|
|
121
|
-
async function capture(targetArg, options = {}) {
|
|
122
|
-
const timeoutSeconds = (0, captureRuntime_1.validateCaptureTimeout)(options.timeoutSeconds);
|
|
123
|
-
const timeoutMs = Math.round(timeoutSeconds * 1000);
|
|
124
|
-
const devRouterPort = (0, dev_2.resolveCliDevRouterPort)();
|
|
125
|
-
let minimumLogLevel;
|
|
126
|
-
let loginOverride;
|
|
127
|
-
let devOptions;
|
|
128
|
-
try {
|
|
129
|
-
minimumLogLevel = (0, captureRuntime_1.resolveCaptureLogLevel)(options.logLevel);
|
|
130
|
-
loginOverride = resolveCaptureLoginOverride(options);
|
|
131
|
-
devOptions = resolveCaptureDevOptions(options);
|
|
132
|
-
}
|
|
133
|
-
catch (error) {
|
|
134
|
-
if (error instanceof Error && error.message === 'invalid_credentials_pair') {
|
|
135
|
-
(0, messages_1.printErrorWithHelp)('Use --username and --password together.', [], { command: 'project capture' });
|
|
136
|
-
}
|
|
137
|
-
else if (error instanceof Error && error.message === 'dev_auth_prompt_not_supported') {
|
|
138
|
-
(0, messages_1.printErrorWithHelp)('Use --dev-auth anonymous, viewer, or player for deterministic capture.', [], { command: 'project capture' });
|
|
139
|
-
}
|
|
140
|
-
else if (error instanceof Error && error.message === 'dev_auth_player_slot_required') {
|
|
141
|
-
(0, messages_1.printErrorWithHelp)('Use --player 1, 2, 3, or 4 when --dev-auth player is selected.', [], { command: 'project capture' });
|
|
142
|
-
}
|
|
143
|
-
else if (error instanceof Error && error.message === 'reset_dev_player_requires_player_auth') {
|
|
144
|
-
(0, messages_1.printErrorWithHelp)('Use --reset-dev-player only with --dev-auth player.', [], { command: 'project capture' });
|
|
145
|
-
}
|
|
146
|
-
else if (error instanceof Error && error.message === 'reset_dev_player_invalid') {
|
|
147
|
-
(0, messages_1.printErrorWithHelp)('Use --reset-dev-player before, after, before-and-after, or never.', [], { command: 'project capture' });
|
|
148
|
-
}
|
|
149
|
-
else {
|
|
150
|
-
(0, messages_1.printErrorWithHelp)(error?.message || 'Invalid capture options.', [
|
|
151
|
-
'Valid log levels: debug, info, warn, error',
|
|
152
|
-
'Valid --dev-auth values: anonymous, viewer, player',
|
|
153
|
-
], { command: 'project capture' });
|
|
154
|
-
}
|
|
155
|
-
process.exitCode = 1;
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
const screenshotPath = options.screenshotPath ? (0, node_path_1.resolve)(process.cwd(), options.screenshotPath) : null;
|
|
159
|
-
let resolvedTarget;
|
|
160
|
-
try {
|
|
161
|
-
resolvedTarget = (0, devShared_1.resolveDevTarget)(targetArg, options.appName);
|
|
162
|
-
}
|
|
163
|
-
catch (error) {
|
|
164
|
-
const code = error?.code;
|
|
165
|
-
const message = error?.message || 'Unable to resolve capture target.';
|
|
166
|
-
let suggestions = [];
|
|
167
|
-
switch (code) {
|
|
168
|
-
case 'app_required':
|
|
169
|
-
suggestions = ['Use "--app <name>" to select which app to capture or provide the HTML file path directly.'];
|
|
170
|
-
break;
|
|
171
|
-
case 'app_not_found':
|
|
172
|
-
suggestions = ['Confirm the app exists in catalogue.json, use "--app <name>", or pass the direct HTML file path.'];
|
|
173
|
-
break;
|
|
174
|
-
case 'catalogue_missing':
|
|
175
|
-
suggestions = ['Run "playdrop project capture" from a workspace with catalogue.json or provide the HTML file path.'];
|
|
176
|
-
break;
|
|
177
|
-
case 'invalid_target':
|
|
178
|
-
suggestions = ['Provide a valid HTML file path or app name.'];
|
|
179
|
-
break;
|
|
180
|
-
case 'empty_catalogue':
|
|
181
|
-
suggestions = ['Add at least one app entry to catalogue.json before running capture.'];
|
|
182
|
-
break;
|
|
183
|
-
case 'invalid_catalogue':
|
|
184
|
-
suggestions = ['Fix the catalogue.json file and rerun "playdrop project capture".'];
|
|
185
|
-
break;
|
|
186
|
-
default:
|
|
187
|
-
suggestions = ['Provide an app name, HTML file path, or run inside a Playdrop workspace.'];
|
|
188
|
-
break;
|
|
189
|
-
}
|
|
190
|
-
(0, messages_1.printErrorWithHelp)(message, suggestions, { command: 'project capture' });
|
|
191
|
-
process.exitCode = 1;
|
|
192
|
-
return;
|
|
193
|
-
}
|
|
194
|
-
let appName = resolvedTarget.appName;
|
|
195
|
-
const filePath = resolvedTarget.htmlPath;
|
|
196
|
-
if (!(0, node_fs_1.existsSync)(filePath) || !(0, node_fs_1.statSync)(filePath).isFile()) {
|
|
197
|
-
(0, messages_1.printErrorWithHelp)(`App HTML was not found at ${filePath}.`, [
|
|
198
|
-
'Ensure the catalogue entry points to a compiled HTML file or provide the correct file path.'
|
|
199
|
-
], { command: 'project capture' });
|
|
200
|
-
process.exitCode = 1;
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
const availableSurfaces = resolvedTarget.surfaceTargets;
|
|
204
|
-
const overrideSurface = normalizeSurfaceOverride(options.surfaceTarget);
|
|
205
|
-
if (options.surfaceTarget && !overrideSurface) {
|
|
206
|
-
(0, messages_1.printErrorWithHelp)(`Unsupported surface target "${options.surfaceTarget}".`, ['Valid values: desktop, mobile-landscape, mobile-portrait'], { command: 'project capture' });
|
|
207
|
-
process.exitCode = 1;
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
if (overrideSurface && !availableSurfaces.map[overrideSurface]) {
|
|
211
|
-
(0, messages_1.printErrorWithHelp)(`Surface target "${options.surfaceTarget}" is not enabled for this app.`, [`Catalogue surfaces: ${formatSurfaceList(availableSurfaces)}`], { command: 'project capture' });
|
|
212
|
-
process.exitCode = 1;
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
const selectedSurface = overrideSurface ?? determineDefaultSurface(availableSurfaces);
|
|
216
|
-
const surfacePreset = SURFACE_PRESETS[selectedSurface];
|
|
217
|
-
const surfaceContextOptions = {
|
|
218
|
-
...surfacePreset.contextOptions,
|
|
219
|
-
viewport: surfacePreset.contextOptions.viewport
|
|
220
|
-
? { ...surfacePreset.contextOptions.viewport }
|
|
221
|
-
: undefined,
|
|
222
|
-
};
|
|
223
|
-
const viewportLabel = surfaceContextOptions.viewport
|
|
224
|
-
? ` (${surfaceContextOptions.viewport.width}x${surfaceContextOptions.viewport.height})`
|
|
225
|
-
: '';
|
|
226
|
-
console.log(`[capture] Surface: ${surfacePreset.label}${viewportLabel}`);
|
|
227
|
-
let appType = null;
|
|
228
|
-
let appTypeSlug = (0, appUrls_1.getAppTypeSlug)(appType);
|
|
229
|
-
try {
|
|
230
|
-
const match = (0, catalogue_utils_1.findAppDefinition)(filePath);
|
|
231
|
-
appName = match.name;
|
|
232
|
-
appType = match.type;
|
|
233
|
-
appTypeSlug = (0, appUrls_1.getAppTypeSlug)(appType);
|
|
234
|
-
}
|
|
235
|
-
catch (error) {
|
|
236
|
-
if (resolvedTarget.cataloguePath) {
|
|
237
|
-
(0, messages_1.printErrorWithHelp)(error?.message || 'Catalogue lookup failed.', [
|
|
238
|
-
'Ensure the HTML file is listed exactly once in catalogue.json with a valid type.',
|
|
239
|
-
'Run "playdrop project create app <name>" to scaffold a new entry if needed.',
|
|
240
|
-
], { command: 'project capture' });
|
|
241
|
-
process.exitCode = 1;
|
|
242
|
-
return;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
const projectInfo = (0, devShared_1.findProjectInfo)(filePath);
|
|
246
|
-
const devScriptAvailable = Boolean(projectInfo.projectDir && projectInfo.packageJson && typeof projectInfo.packageJson.scripts?.dev === 'string');
|
|
247
|
-
await (0, commandContext_1.withEnvironment)('project capture', 'Capturing app logs', async ({ client, env, envConfig, token, workspaceAuth }) => {
|
|
248
|
-
let currentUsername = '';
|
|
249
|
-
let currentUser = null;
|
|
250
|
-
try {
|
|
251
|
-
const fetchedCurrentUser = await (0, devShared_1.fetchDevUser)(client);
|
|
252
|
-
currentUser = fetchedCurrentUser;
|
|
253
|
-
currentUsername = fetchedCurrentUser.username.trim();
|
|
254
|
-
}
|
|
255
|
-
catch (error) {
|
|
256
|
-
if (error instanceof http_1.CLIUnsupportedClientError) {
|
|
257
|
-
return;
|
|
258
|
-
}
|
|
259
|
-
if (error instanceof types_1.UnsupportedClientError) {
|
|
260
|
-
(0, http_1.handleUnsupportedError)(error, 'Authentication');
|
|
261
|
-
process.exitCode = 1;
|
|
262
|
-
return;
|
|
263
|
-
}
|
|
264
|
-
if (error instanceof types_1.ApiError) {
|
|
265
|
-
(0, messages_1.printErrorWithHelp)(`Could not fetch your account (status ${error.status}).`, [
|
|
266
|
-
'Run "playdrop auth login" to refresh your session and ensure the API is reachable.',
|
|
267
|
-
'Use "playdrop auth whoami" afterwards to confirm your status.',
|
|
268
|
-
], { command: 'project capture' });
|
|
269
|
-
process.exitCode = 1;
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
if ((0, devShared_1.isNetworkError)(error)) {
|
|
273
|
-
(0, messages_1.printNetworkIssue)('Could not reach the Playdrop API to resolve your account.', 'project capture');
|
|
274
|
-
process.exitCode = 1;
|
|
275
|
-
return;
|
|
276
|
-
}
|
|
277
|
-
if (error instanceof Error && error.message === 'DEV_USERNAME_EMPTY') {
|
|
278
|
-
(0, messages_1.printErrorWithHelp)('Could not determine your Playdrop creator username.', [
|
|
279
|
-
'Retry "playdrop project capture" in a moment.',
|
|
280
|
-
'If the problem persists, contact the Playdrop team.',
|
|
281
|
-
], { command: 'project capture' });
|
|
282
|
-
process.exitCode = 1;
|
|
283
|
-
return;
|
|
284
|
-
}
|
|
285
|
-
throw error;
|
|
286
|
-
}
|
|
287
|
-
const taskScoped = Boolean(workspaceAuth?.config.taskToken);
|
|
288
|
-
if (devOptions.selection.devAuth === 'viewer' && !loginOverride && !taskScoped) {
|
|
289
|
-
(0, messages_1.printErrorWithHelp)('Use --username and --password to establish a browser session before running --dev-auth viewer.', [], { command: 'project capture' });
|
|
290
|
-
process.exitCode = 1;
|
|
291
|
-
return;
|
|
292
|
-
}
|
|
293
|
-
if (devOptions.selection.devAuth === 'player' && !loginOverride) {
|
|
294
|
-
(0, messages_1.printErrorWithHelp)('Use --username and --password to establish a browser session before running --dev-auth player.', [], { command: 'project capture' });
|
|
295
|
-
process.exitCode = 1;
|
|
296
|
-
return;
|
|
297
|
-
}
|
|
298
|
-
const entryLabel = (0, node_path_1.relative)(process.cwd(), filePath) || filePath;
|
|
299
|
-
console.log(`[capture] Preparing ${entryLabel} for ${env} (${appTypeSlug}).`);
|
|
300
|
-
const serverAlreadyRunning = await (0, devServer_1.isDevServerAvailable)({
|
|
301
|
-
creatorUsername: currentUsername,
|
|
302
|
-
appType: appTypeSlug,
|
|
303
|
-
appName,
|
|
304
|
-
port: devRouterPort,
|
|
305
|
-
}, 750);
|
|
306
|
-
const devServerStartedByCapture = !serverAlreadyRunning;
|
|
307
|
-
let serverHandle = null;
|
|
308
|
-
let signalHandler = null;
|
|
309
|
-
let cleanupRequested = false;
|
|
310
|
-
const cleanup = async () => {
|
|
311
|
-
if (cleanupRequested)
|
|
312
|
-
return;
|
|
313
|
-
cleanupRequested = true;
|
|
314
|
-
if (serverHandle) {
|
|
315
|
-
try {
|
|
316
|
-
await serverHandle.close();
|
|
317
|
-
}
|
|
318
|
-
catch (error) {
|
|
319
|
-
console.error(error instanceof Error ? error.message : String(error));
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
};
|
|
323
|
-
let runtimeAssetManifest = (0, devRuntimeAssets_1.createEmptyDevRuntimeAssetManifest)();
|
|
324
|
-
const taskLookup = (0, catalogue_1.findAppTaskByFile)(filePath);
|
|
325
|
-
if (taskLookup.errors.length > 0) {
|
|
326
|
-
(0, messages_1.printErrorWithHelp)(taskLookup.errors[0] || 'Failed to resolve the app task from catalogue.json.', taskLookup.errors.slice(1), { command: 'project capture' });
|
|
327
|
-
process.exitCode = 1;
|
|
328
|
-
return;
|
|
329
|
-
}
|
|
330
|
-
if (taskLookup.task) {
|
|
331
|
-
try {
|
|
332
|
-
runtimeAssetManifest = await (0, devRuntimeAssets_1.buildDevRuntimeAssetManifest)({
|
|
333
|
-
client,
|
|
334
|
-
apiBase: envConfig.apiBase,
|
|
335
|
-
task: taskLookup.task,
|
|
336
|
-
creatorUsername: currentUsername,
|
|
337
|
-
appBaseUrl: new URL('.', (0, devServer_1.buildLocalDevAppUrl)({
|
|
338
|
-
creatorUsername: currentUsername,
|
|
339
|
-
appType: appTypeSlug,
|
|
340
|
-
appName,
|
|
341
|
-
port: devRouterPort,
|
|
342
|
-
})).toString(),
|
|
343
|
-
});
|
|
344
|
-
}
|
|
345
|
-
catch (error) {
|
|
346
|
-
const formatted = (0, dev_1.formatDevRuntimeAssetManifestFailure)(error);
|
|
347
|
-
(0, messages_1.printErrorWithHelp)(formatted.message, formatted.suggestions, { command: 'project capture' });
|
|
348
|
-
process.exitCode = 1;
|
|
349
|
-
return;
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
if (serverAlreadyRunning) {
|
|
353
|
-
console.log(`[capture] Reusing dev server at ${(0, devServer_1.buildLocalDevAppUrl)({
|
|
354
|
-
creatorUsername: currentUsername,
|
|
355
|
-
appType: appTypeSlug,
|
|
356
|
-
appName,
|
|
357
|
-
port: devRouterPort,
|
|
358
|
-
})}`);
|
|
359
|
-
try {
|
|
360
|
-
await (0, devServer_1.updateMountedDevRuntimeAssetManifest)({
|
|
361
|
-
creatorUsername: currentUsername,
|
|
362
|
-
appName,
|
|
363
|
-
runtimeAssetManifest,
|
|
364
|
-
port: devRouterPort,
|
|
365
|
-
});
|
|
366
|
-
}
|
|
367
|
-
catch (error) {
|
|
368
|
-
(0, messages_1.printErrorWithHelp)(error?.message || 'Failed to refresh the local runtime asset manifest on the shared dev router.', [
|
|
369
|
-
'Restart "playdrop project dev" for this app and try capture again.',
|
|
370
|
-
], { command: 'project capture' });
|
|
371
|
-
process.exitCode = 1;
|
|
372
|
-
return;
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
else {
|
|
376
|
-
try {
|
|
377
|
-
serverHandle = await (0, devServer_1.startDevServer)({
|
|
378
|
-
appName,
|
|
379
|
-
appType: appTypeSlug,
|
|
380
|
-
creatorUsername: currentUsername,
|
|
381
|
-
htmlPath: filePath,
|
|
382
|
-
port: devRouterPort,
|
|
383
|
-
projectInfo,
|
|
384
|
-
runtimeAssetManifest,
|
|
385
|
-
});
|
|
386
|
-
signalHandler = () => {
|
|
387
|
-
void cleanup().finally(() => process.exit(130));
|
|
388
|
-
};
|
|
389
|
-
process.on('SIGINT', signalHandler);
|
|
390
|
-
process.on('SIGTERM', signalHandler);
|
|
391
|
-
}
|
|
392
|
-
catch (error) {
|
|
393
|
-
const mountConflict = (0, devServer_1.parseMountConflictError)(typeof error?.message === 'string' ? error.message : '');
|
|
394
|
-
if (mountConflict) {
|
|
395
|
-
(0, messages_1.printErrorWithHelp)(`A different dev session already owns ${mountConflict.ref}.`, [
|
|
396
|
-
`Active owner pid: ${mountConflict.ownerPid}.`,
|
|
397
|
-
`Mounted repo root: ${mountConflict.repoRoot}.`,
|
|
398
|
-
`Mounted HTML path: ${mountConflict.htmlPath}.`,
|
|
399
|
-
], { command: 'project capture' });
|
|
400
|
-
}
|
|
401
|
-
else {
|
|
402
|
-
(0, messages_1.printErrorWithHelp)(error?.message || `Failed to start the shared dev router on port ${devRouterPort}.`, [
|
|
403
|
-
'Close the conflicting process or wait for the stale mount to exit.',
|
|
404
|
-
'Ensure the HTML file exists and is readable.',
|
|
405
|
-
], { command: 'project capture' });
|
|
406
|
-
}
|
|
407
|
-
process.exitCode = 1;
|
|
408
|
-
return;
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
if (!serverAlreadyRunning && projectInfo.projectDir && !devScriptAvailable && projectInfo.packageJsonPath) {
|
|
412
|
-
const projectLabel = (0, devShared_1.formatProjectLabel)(projectInfo);
|
|
413
|
-
if (projectLabel) {
|
|
414
|
-
console.log(`[capture] package.json detected at ${projectLabel}, but no "dev" script was found. Run your build/watch scripts manually if needed.`);
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
if (devServerStartedByCapture) {
|
|
418
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
419
|
-
}
|
|
420
|
-
const webBase = envConfig.webBase ?? 'https://www.playdrop.ai';
|
|
421
|
-
const shouldResetBefore = devOptions.selection.devAuth === 'player'
|
|
422
|
-
&& (devOptions.resetMode === 'before' || devOptions.resetMode === 'before-and-after');
|
|
423
|
-
const shouldResetAfter = devOptions.selection.devAuth === 'player'
|
|
424
|
-
&& (devOptions.resetMode === 'after' || devOptions.resetMode === 'before-and-after');
|
|
425
|
-
const savedSessionViewerCapture = devOptions.selection.devAuth === 'viewer' && !loginOverride && taskScoped;
|
|
426
|
-
const requiresRegisteredApp = devOptions.selection.devAuth === 'player'
|
|
427
|
-
|| shouldResetBefore
|
|
428
|
-
|| shouldResetAfter
|
|
429
|
-
|| (devOptions.selection.devAuth === 'viewer' && !savedSessionViewerCapture);
|
|
430
|
-
let registeredApp = null;
|
|
431
|
-
if (requiresRegisteredApp) {
|
|
432
|
-
try {
|
|
433
|
-
registeredApp = await (0, devShared_1.assertAppRegistered)(client, currentUsername, appName);
|
|
434
|
-
}
|
|
435
|
-
catch (error) {
|
|
436
|
-
if (error instanceof http_1.CLIUnsupportedClientError) {
|
|
437
|
-
return;
|
|
438
|
-
}
|
|
439
|
-
if (error instanceof types_1.UnsupportedClientError) {
|
|
440
|
-
(0, http_1.handleUnsupportedError)(error, 'Capture');
|
|
441
|
-
process.exitCode = 1;
|
|
442
|
-
return;
|
|
443
|
-
}
|
|
444
|
-
if (error instanceof types_1.ApiError) {
|
|
445
|
-
if (error.status === 404) {
|
|
446
|
-
(0, messages_1.printErrorWithHelp)(`App ${currentUsername}/${appName} is not registered on ${env}.`, [
|
|
447
|
-
`Run "playdrop project create app ${appName}" to register the app before using viewer or player capture.`,
|
|
448
|
-
'Use anonymous capture for local launch validation before upload.',
|
|
449
|
-
], { command: 'project capture' });
|
|
450
|
-
}
|
|
451
|
-
else {
|
|
452
|
-
(0, messages_1.printErrorWithHelp)(`Failed to verify app registration (status ${error.status}).`, [
|
|
453
|
-
'Retry in a moment.',
|
|
454
|
-
'If the issue persists, contact the Playdrop team.',
|
|
455
|
-
], { command: 'project capture' });
|
|
456
|
-
}
|
|
457
|
-
process.exitCode = 1;
|
|
458
|
-
return;
|
|
459
|
-
}
|
|
460
|
-
if ((0, devShared_1.isNetworkError)(error)) {
|
|
461
|
-
(0, messages_1.printNetworkIssue)('Could not reach the Playdrop API to verify the app registration.', 'project capture');
|
|
462
|
-
process.exitCode = 1;
|
|
463
|
-
return;
|
|
464
|
-
}
|
|
465
|
-
throw error;
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
const captureBaseUrl = (0, appUrls_1.buildPlatformDevUrl)(webBase, {
|
|
469
|
-
creatorUsername: currentUsername,
|
|
470
|
-
appName,
|
|
471
|
-
appType,
|
|
472
|
-
devAuth: devOptions.selection.devAuth,
|
|
473
|
-
player: devOptions.selection.player ? String(devOptions.selection.player) : null,
|
|
474
|
-
launchCheck: true,
|
|
475
|
-
localDevPort: devRouterPort === devServer_1.DEV_ROUTER_PORT ? null : devRouterPort,
|
|
476
|
-
});
|
|
477
|
-
const frameUrl = (0, devAuth_1.applyHostedDevAuthSelectionToUrl)(captureBaseUrl, devOptions.selection);
|
|
478
|
-
console.log(`[capture] Launching Playwright against ${frameUrl}`);
|
|
479
|
-
const selectedPlayerSlot = devOptions.selection.player;
|
|
480
|
-
const registeredAppId = typeof registeredApp?.id === 'number' ? registeredApp.id : null;
|
|
481
|
-
if ((shouldResetBefore || shouldResetAfter) && registeredAppId === null) {
|
|
482
|
-
(0, messages_1.printErrorWithHelp)('The registered app is missing a numeric id, so test-player reset is unavailable.', [], { command: 'project capture' });
|
|
483
|
-
process.exitCode = 1;
|
|
484
|
-
return;
|
|
485
|
-
}
|
|
486
|
-
if (shouldResetBefore && selectedPlayerSlot !== null) {
|
|
487
|
-
await client.resetDevPlayer(registeredAppId, selectedPlayerSlot);
|
|
488
|
-
}
|
|
489
|
-
try {
|
|
490
|
-
const result = await (0, captureRuntime_1.runCapture)({
|
|
491
|
-
targetUrl: frameUrl,
|
|
492
|
-
expectedUrl: frameUrl,
|
|
493
|
-
timeoutMs,
|
|
494
|
-
settleAfterReadyMs: timeoutMs,
|
|
495
|
-
minimumLogLevel,
|
|
496
|
-
screenshotPath,
|
|
497
|
-
contextOptions: surfaceContextOptions,
|
|
498
|
-
login: loginOverride ? {
|
|
499
|
-
username: loginOverride.username,
|
|
500
|
-
password: loginOverride.password,
|
|
501
|
-
} : undefined,
|
|
502
|
-
token: savedSessionViewerCapture ? token : undefined,
|
|
503
|
-
user: savedSessionViewerCapture ? currentUser : undefined,
|
|
504
|
-
savedSessionBootstrap: savedSessionViewerCapture,
|
|
505
|
-
enableCaptureBridge: true,
|
|
506
|
-
requireHostedLaunchReady: true,
|
|
507
|
-
});
|
|
508
|
-
if (result.errorCount > 0) {
|
|
509
|
-
console.error(`[capture] Completed with ${result.errorCount} error(s) after ${timeoutSeconds} seconds.`);
|
|
510
|
-
process.exitCode = 1;
|
|
511
|
-
}
|
|
512
|
-
else {
|
|
513
|
-
console.log(`[capture] Completed without console errors after ${timeoutSeconds} seconds.`);
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
catch (error) {
|
|
517
|
-
if (error instanceof http_1.CLIUnsupportedClientError) {
|
|
518
|
-
return;
|
|
519
|
-
}
|
|
520
|
-
if (error instanceof types_1.UnsupportedClientError) {
|
|
521
|
-
(0, http_1.handleUnsupportedError)(error, 'Capture');
|
|
522
|
-
process.exitCode = 1;
|
|
523
|
-
return;
|
|
524
|
-
}
|
|
525
|
-
if (error instanceof Error && error.stack) {
|
|
526
|
-
console.error(error.stack);
|
|
527
|
-
}
|
|
528
|
-
else {
|
|
529
|
-
console.error(`[capture] ${error instanceof Error ? error.message : String(error)}`);
|
|
530
|
-
}
|
|
531
|
-
process.exitCode = 1;
|
|
532
|
-
}
|
|
533
|
-
finally {
|
|
534
|
-
if (shouldResetAfter && selectedPlayerSlot !== null) {
|
|
535
|
-
try {
|
|
536
|
-
await client.resetDevPlayer(registeredAppId, selectedPlayerSlot);
|
|
537
|
-
}
|
|
538
|
-
catch (error) {
|
|
539
|
-
console.error(error instanceof Error ? error.message : String(error));
|
|
540
|
-
process.exitCode = 1;
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
if (signalHandler) {
|
|
544
|
-
process.off('SIGINT', signalHandler);
|
|
545
|
-
process.off('SIGTERM', signalHandler);
|
|
546
|
-
}
|
|
547
|
-
await cleanup();
|
|
548
|
-
}
|
|
549
|
-
}, { workspacePath: resolvedTarget.cataloguePath ?? (0, node_path_1.dirname)(filePath) });
|
|
550
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
type CaptureRemoteOptions = {
|
|
2
|
-
timeout?: string | number;
|
|
3
|
-
settle?: string | number;
|
|
4
|
-
screenshot?: string;
|
|
5
|
-
log?: string;
|
|
6
|
-
expectedUrl?: string;
|
|
7
|
-
username?: string;
|
|
8
|
-
password?: string;
|
|
9
|
-
loginUrl?: string;
|
|
10
|
-
actions?: string;
|
|
11
|
-
viewport?: string;
|
|
12
|
-
surface?: string;
|
|
13
|
-
fpsSampleMs?: string | number;
|
|
14
|
-
};
|
|
15
|
-
export declare function buildCaptureRemoteCommandArgs(url: string | undefined, options?: CaptureRemoteOptions): string[] | null;
|
|
16
|
-
export declare function captureRemote(url: string | undefined, options?: CaptureRemoteOptions): Promise<void>;
|
|
17
|
-
export {};
|