@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
package/dist/apps/upload.d.ts
CHANGED
|
@@ -17,8 +17,9 @@ export type AppUploadOptions = {
|
|
|
17
17
|
creatorUsername?: string;
|
|
18
18
|
token?: string | null;
|
|
19
19
|
user?: UserResponse | null;
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
runStagedUploadLoadCheck?: boolean;
|
|
21
|
+
loadCheckTimeoutMs?: number;
|
|
22
22
|
agentTaskId?: number;
|
|
23
|
+
mediaCaptureRequired?: boolean;
|
|
23
24
|
};
|
|
24
25
|
export declare function uploadApp(client: ApiClient, task: AppTask, artifacts: AppBuildArtifacts | null, options?: AppUploadOptions): Promise<AppUploadResult>;
|
package/dist/apps/upload.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.uploadApp = uploadApp;
|
|
4
|
-
const node_crypto_1 = require("node:crypto");
|
|
5
|
-
const types_1 = require("@playdrop/types");
|
|
6
4
|
const config_1 = require("@playdrop/config");
|
|
5
|
+
const types_1 = require("@playdrop/types");
|
|
6
|
+
const node_crypto_1 = require("node:crypto");
|
|
7
7
|
const node_fs_1 = require("node:fs");
|
|
8
8
|
const node_path_1 = require("node:path");
|
|
9
9
|
const http_1 = require("../http");
|
|
10
|
-
const
|
|
10
|
+
const loadCheck_1 = require("./loadCheck");
|
|
11
11
|
const EXTENSION_TO_MIME = {
|
|
12
12
|
'.png': 'image/png',
|
|
13
13
|
'.jpg': 'image/jpeg',
|
|
@@ -74,6 +74,97 @@ async function bufferFromFile(file) {
|
|
|
74
74
|
function computeSha256Hex(buffer) {
|
|
75
75
|
return (0, node_crypto_1.createHash)('sha256').update(buffer).digest('hex');
|
|
76
76
|
}
|
|
77
|
+
function isSha256Hex(value) {
|
|
78
|
+
return typeof value === 'string' && /^[a-f0-9]{64}$/i.test(value.trim());
|
|
79
|
+
}
|
|
80
|
+
function isCaptureMediaFileKey(fileKey) {
|
|
81
|
+
return fileKey.startsWith('screenshotsPortrait:')
|
|
82
|
+
|| fileKey.startsWith('screenshotsLandscape:')
|
|
83
|
+
|| fileKey.startsWith('videosPortrait:')
|
|
84
|
+
|| fileKey.startsWith('videosLandscape:');
|
|
85
|
+
}
|
|
86
|
+
function readMediaCaptureProof(input) {
|
|
87
|
+
const reportPath = input.task.listing?.captureReportPath;
|
|
88
|
+
if (!reportPath) {
|
|
89
|
+
throw new Error(`agent_task_media_capture_report_missing: ${input.task.name} must include listing.captureReport from "playdrop project capture".`);
|
|
90
|
+
}
|
|
91
|
+
let report;
|
|
92
|
+
try {
|
|
93
|
+
report = JSON.parse((0, node_fs_1.readFileSync)(reportPath, 'utf8'));
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
97
|
+
throw new Error(`agent_task_media_capture_report_invalid: ${reportPath} must be valid JSON. ${reason}`);
|
|
98
|
+
}
|
|
99
|
+
const binding = report?.binding;
|
|
100
|
+
if (!binding || typeof binding !== 'object' || Array.isArray(binding)) {
|
|
101
|
+
throw new Error(`agent_task_media_capture_report_invalid: ${reportPath} is missing binding.`);
|
|
102
|
+
}
|
|
103
|
+
const contentHash = typeof binding.contentHash === 'string' ? binding.contentHash.trim().toLowerCase() : '';
|
|
104
|
+
if (!isSha256Hex(contentHash)) {
|
|
105
|
+
throw new Error(`agent_task_media_capture_report_invalid: ${reportPath} binding.contentHash must be a SHA-256 hex string.`);
|
|
106
|
+
}
|
|
107
|
+
if (contentHash !== input.artifacts.bundleHash) {
|
|
108
|
+
throw new Error(`agent_task_media_capture_build_mismatch: capture report contentHash does not match the bundle being uploaded for ${input.task.name}. Rerun "playdrop project capture" after the final build changes.`);
|
|
109
|
+
}
|
|
110
|
+
const rawArtifactHashes = binding.artifactHashes;
|
|
111
|
+
if (!rawArtifactHashes || typeof rawArtifactHashes !== 'object' || Array.isArray(rawArtifactHashes)) {
|
|
112
|
+
throw new Error(`agent_task_media_capture_report_invalid: ${reportPath} binding.artifactHashes must be an object.`);
|
|
113
|
+
}
|
|
114
|
+
const captureArtifactHashEntries = Object.values(rawArtifactHashes)
|
|
115
|
+
.map((value) => typeof value === 'string' ? value.trim().toLowerCase() : '')
|
|
116
|
+
.filter((value) => isSha256Hex(value));
|
|
117
|
+
const captureArtifactHashes = new Set(captureArtifactHashEntries);
|
|
118
|
+
if (captureArtifactHashEntries.length === 0) {
|
|
119
|
+
throw new Error(`agent_task_media_capture_report_invalid: ${reportPath} binding.artifactHashes is empty.`);
|
|
120
|
+
}
|
|
121
|
+
const captureArtifactHashCounts = new Map();
|
|
122
|
+
for (const hash of captureArtifactHashEntries) {
|
|
123
|
+
captureArtifactHashCounts.set(hash, (captureArtifactHashCounts.get(hash) ?? 0) + 1);
|
|
124
|
+
}
|
|
125
|
+
const mediaFiles = input.preparedSessionFiles.filter((file) => isCaptureMediaFileKey(file.fileKey));
|
|
126
|
+
if (mediaFiles.length === 0) {
|
|
127
|
+
throw new Error(`agent_task_media_capture_artifacts_missing: ${input.task.name} must upload recorder stills and video in listing.screenshots* and listing.videos*.`);
|
|
128
|
+
}
|
|
129
|
+
const uploadedMediaHashCounts = new Map();
|
|
130
|
+
for (const file of mediaFiles) {
|
|
131
|
+
uploadedMediaHashCounts.set(file.sha256, (uploadedMediaHashCounts.get(file.sha256) ?? 0) + 1);
|
|
132
|
+
}
|
|
133
|
+
const missingUploadedCaptureArtifacts = [...captureArtifactHashCounts.entries()]
|
|
134
|
+
.filter(([hash, expectedCount]) => (uploadedMediaHashCounts.get(hash) ?? 0) < expectedCount);
|
|
135
|
+
if (missingUploadedCaptureArtifacts.length > 0) {
|
|
136
|
+
throw new Error(`agent_task_media_capture_artifact_missing_from_listing: ${input.task.name} must list every recorder poster and video from listing.captureReport in catalogue.json.`);
|
|
137
|
+
}
|
|
138
|
+
let hasStill = false;
|
|
139
|
+
let hasVideo = false;
|
|
140
|
+
const artifactHashes = {};
|
|
141
|
+
for (const file of mediaFiles) {
|
|
142
|
+
if (!captureArtifactHashes.has(file.sha256)) {
|
|
143
|
+
throw new Error(`agent_task_media_capture_artifact_mismatch: ${file.fileKey} was not produced by listing.captureReport for ${input.task.name}.`);
|
|
144
|
+
}
|
|
145
|
+
hasStill = hasStill || file.fileKey.startsWith('screenshots');
|
|
146
|
+
hasVideo = hasVideo || file.fileKey.startsWith('videos');
|
|
147
|
+
artifactHashes[file.fileKey] = file.sha256;
|
|
148
|
+
}
|
|
149
|
+
if (!hasStill || !hasVideo) {
|
|
150
|
+
throw new Error(`agent_task_media_capture_artifacts_missing: ${input.task.name} must upload at least one recorder still and one recorder video.`);
|
|
151
|
+
}
|
|
152
|
+
const capturedSurfaces = Array.isArray(binding.capturedSurfaces)
|
|
153
|
+
? Array.from(new Set(binding.capturedSurfaces
|
|
154
|
+
.map((surface) => typeof surface === 'string' ? surface.trim().toUpperCase() : '')
|
|
155
|
+
.filter((surface) => input.task.surfaceTargets.includes(surface))))
|
|
156
|
+
: [];
|
|
157
|
+
const capturedSurfaceSet = new Set(capturedSurfaces);
|
|
158
|
+
const missingSurfaces = input.task.surfaceTargets.filter((surface) => !capturedSurfaceSet.has(surface));
|
|
159
|
+
if (missingSurfaces.length > 0) {
|
|
160
|
+
throw new Error(`agent_task_media_capture_surface_missing: listing.captureReport did not capture ${missingSurfaces.join(', ')} for ${input.task.name}.`);
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
contentHash,
|
|
164
|
+
artifactHashes,
|
|
165
|
+
capturedSurfaces,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
77
168
|
function resolveMimeType(filename, fallback = 'application/octet-stream') {
|
|
78
169
|
const type = EXTENSION_TO_MIME[(0, node_path_1.extname)(filename).toLowerCase()];
|
|
79
170
|
return type ?? fallback;
|
|
@@ -159,7 +250,6 @@ async function uploadApp(client, task, artifacts, options) {
|
|
|
159
250
|
/**
|
|
160
251
|
* Upload an app version using the versioned API.
|
|
161
252
|
*/
|
|
162
|
-
// eslint-disable-next-line complexity -- Upload assembly mirrors the versioned multipart contract in one place.
|
|
163
253
|
async function uploadAppVersion(client, task, artifacts, options) {
|
|
164
254
|
const creatorUsername = typeof options?.creatorUsername === 'string' ? options.creatorUsername.trim() : '';
|
|
165
255
|
if (!creatorUsername) {
|
|
@@ -340,20 +430,33 @@ async function uploadAppVersion(client, task, artifacts, options) {
|
|
|
340
430
|
})),
|
|
341
431
|
});
|
|
342
432
|
}
|
|
433
|
+
if (options?.mediaCaptureRequired === true
|
|
434
|
+
&& task.hostingMode !== 'EXTERNAL'
|
|
435
|
+
&& !task.externalUrl) {
|
|
436
|
+
if (!artifacts) {
|
|
437
|
+
throw new Error(`agent_task_media_capture_build_missing: ${task.name} has no hosted build artifacts to bind capture media to.`);
|
|
438
|
+
}
|
|
439
|
+
const mediaCaptureProof = readMediaCaptureProof({
|
|
440
|
+
task,
|
|
441
|
+
artifacts,
|
|
442
|
+
preparedSessionFiles,
|
|
443
|
+
});
|
|
444
|
+
await client.recordAppUploadMediaCapture(creatorUsername, task.name, sessionId, mediaCaptureProof);
|
|
445
|
+
}
|
|
343
446
|
if (task.hostingMode !== 'EXTERNAL'
|
|
344
447
|
&& !task.externalUrl
|
|
345
|
-
&& options?.
|
|
346
|
-
const
|
|
448
|
+
&& options?.runStagedUploadLoadCheck) {
|
|
449
|
+
const loadCheck = await (0, loadCheck_1.runUploadedHostedLoadCheck)({
|
|
347
450
|
client,
|
|
348
451
|
creatorUsername,
|
|
349
452
|
task,
|
|
350
453
|
sessionId,
|
|
351
|
-
timeoutMs: options.
|
|
454
|
+
timeoutMs: options.loadCheckTimeoutMs,
|
|
352
455
|
token: options?.token ?? null,
|
|
353
456
|
currentUser: options?.user ?? null,
|
|
354
457
|
});
|
|
355
|
-
if (
|
|
356
|
-
throw new Error((0,
|
|
458
|
+
if (loadCheck.status !== 'PASSED') {
|
|
459
|
+
throw new Error((0, loadCheck_1.formatHostedLoadCheckFailure)(task.name, loadCheck, 'staged'));
|
|
357
460
|
}
|
|
358
461
|
}
|
|
359
462
|
}
|
package/dist/assetSpecs.js
CHANGED
|
@@ -9,11 +9,11 @@ exports.loadAndValidateAssetSpecContract = loadAndValidateAssetSpecContract;
|
|
|
9
9
|
exports.validateCustomAssetFilesAgainstContract = validateCustomAssetFilesAgainstContract;
|
|
10
10
|
exports.normalizeAssetSpecVersionRef = normalizeAssetSpecVersionRef;
|
|
11
11
|
exports.validateAssetSpecName = validateAssetSpecName;
|
|
12
|
+
const types_1 = require("@playdrop/types");
|
|
13
|
+
const ajv_1 = __importDefault(require("ajv"));
|
|
12
14
|
const node_fs_1 = require("node:fs");
|
|
13
15
|
const node_path_1 = require("node:path");
|
|
14
|
-
const ajv_1 = __importDefault(require("ajv"));
|
|
15
16
|
const semver_1 = require("semver");
|
|
16
|
-
const types_1 = require("@playdrop/types");
|
|
17
17
|
const LOCAL_EXTENSION_TO_MIME = {
|
|
18
18
|
'.png': 'image/png',
|
|
19
19
|
'.jpg': 'image/jpeg',
|
|
@@ -75,7 +75,6 @@ function resolveCustomAssetRoleContentType(filePath, roleContract) {
|
|
|
75
75
|
}
|
|
76
76
|
return resolvedContentType;
|
|
77
77
|
}
|
|
78
|
-
// eslint-disable-next-line complexity
|
|
79
78
|
function normalizeAssetSpecSupportEntries(raw, errors, context) {
|
|
80
79
|
if (raw === undefined || raw === null) {
|
|
81
80
|
return [];
|
|
@@ -130,7 +129,6 @@ function normalizeAssetSpecSupportEntries(raw, errors, context) {
|
|
|
130
129
|
}
|
|
131
130
|
return rows;
|
|
132
131
|
}
|
|
133
|
-
// eslint-disable-next-line complexity
|
|
134
132
|
function loadAndValidateAssetSpecContract(catalogueDir, relativeContractPath, errors, context) {
|
|
135
133
|
const contractPath = (0, node_path_1.resolve)(catalogueDir, relativeContractPath);
|
|
136
134
|
let rawText;
|
|
@@ -213,7 +211,6 @@ function loadAndValidateAssetSpecContract(catalogueDir, relativeContractPath, er
|
|
|
213
211
|
contractPath,
|
|
214
212
|
};
|
|
215
213
|
}
|
|
216
|
-
// eslint-disable-next-line complexity
|
|
217
214
|
function validateCustomAssetFilesAgainstContract(contract, filePaths, errors, context) {
|
|
218
215
|
const contractRoles = new Map(contract.roles.map((role) => [role.name.trim().toLowerCase(), role]));
|
|
219
216
|
const providedRoles = new Set();
|
package/dist/catalogue-utils.js
CHANGED
package/dist/catalogue.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type AppAchievementCatalogueDefinition, type AppAuthMode, type AppControllerMode, type AppHostingMode, type AppLeaderboardCatalogueDefinition, type AppMetadataAssetSpecSupport, type AppSurface, type AppType, type AppVersionDesign, type AppVersionVisibility, type AssetSpecContract, type AssetSpecStatus, type AssetSpecValidationKind, type CatalogueTagGroupDefinition, type ContentLicense, type PlayerMetaDefinitionStatus } from '@playdrop/types';
|
|
2
2
|
import { type AssetSpecSupportDeclaration } from './assetSpecs';
|
|
3
3
|
export type CatalogueJson = {
|
|
4
4
|
apps?: Array<Record<string, unknown>>;
|
|
@@ -19,6 +19,7 @@ export type AppListingConfig = {
|
|
|
19
19
|
screenshotsLandscape?: string[];
|
|
20
20
|
videosPortrait?: string[];
|
|
21
21
|
videosLandscape?: string[];
|
|
22
|
+
captureReport?: string;
|
|
22
23
|
};
|
|
23
24
|
export type ResolvedAppAchievementDefinition = Omit<AppAchievementCatalogueDefinition, 'status'> & {
|
|
24
25
|
iconPath: string;
|
|
@@ -152,6 +153,7 @@ export type ResolvedListingAssets = {
|
|
|
152
153
|
screenshotLandscapePaths: string[];
|
|
153
154
|
videoPortraitPaths: string[];
|
|
154
155
|
videoLandscapePaths: string[];
|
|
156
|
+
captureReportPath?: string;
|
|
155
157
|
};
|
|
156
158
|
export type AppDependencyAssetRef = {
|
|
157
159
|
ref: string;
|
package/dist/catalogue.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/* eslint-disable complexity, max-lines, max-lines-per-function */
|
|
3
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
3
|
exports.validateAppMetadata = validateAppMetadata;
|
|
5
4
|
exports.resolveCatalogueTagGroups = resolveCatalogueTagGroups;
|
|
@@ -8,11 +7,11 @@ exports.resolveWorkspaceApp = resolveWorkspaceApp;
|
|
|
8
7
|
exports.formatMetadataWarnings = formatMetadataWarnings;
|
|
9
8
|
exports.formatMissingMetadataWarnings = formatMissingMetadataWarnings;
|
|
10
9
|
exports.findAppTaskByFile = findAppTaskByFile;
|
|
10
|
+
const types_1 = require("@playdrop/types");
|
|
11
11
|
const node_fs_1 = require("node:fs");
|
|
12
12
|
const node_path_1 = require("node:path");
|
|
13
|
-
const types_1 = require("@playdrop/types");
|
|
14
|
-
const catalogue_utils_1 = require("./catalogue-utils");
|
|
15
13
|
const assetSpecs_1 = require("./assetSpecs");
|
|
14
|
+
const catalogue_utils_1 = require("./catalogue-utils");
|
|
16
15
|
const HEX_COLOR_REGEX = /^#?(?:[0-9a-fA-F]{6})$/;
|
|
17
16
|
const SEMVER_REGEX = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/;
|
|
18
17
|
const LEGACY_CATALOGUE_VERSION_KEY = ['schema', 'Version'].join('');
|
|
@@ -1250,6 +1249,23 @@ function buildAppTasks(rootDir, catalogues, options) {
|
|
|
1250
1249
|
}
|
|
1251
1250
|
}
|
|
1252
1251
|
}
|
|
1252
|
+
if (!listingValidationFailed && typeof rawListing.captureReport === 'string' && rawListing.captureReport.trim()) {
|
|
1253
|
+
const captureReportPath = rawListing.captureReport.trim();
|
|
1254
|
+
if ((0, node_path_1.extname)(captureReportPath).toLowerCase() !== '.json') {
|
|
1255
|
+
errors.push(`[${label}] Skipping ${rawName}: listing.captureReport must point to a JSON file.`);
|
|
1256
|
+
listingValidationFailed = true;
|
|
1257
|
+
}
|
|
1258
|
+
else {
|
|
1259
|
+
const validationError = validateListingAssetPath(file.directory, captureReportPath, 'listing.captureReport');
|
|
1260
|
+
if (validationError) {
|
|
1261
|
+
errors.push(`[${label}] Skipping ${rawName}: ${validationError}`);
|
|
1262
|
+
listingValidationFailed = true;
|
|
1263
|
+
}
|
|
1264
|
+
else {
|
|
1265
|
+
resolvedListing.captureReportPath = resolveListingAssetPath(file.directory, captureReportPath);
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1253
1269
|
if (listingValidationFailed) {
|
|
1254
1270
|
continue;
|
|
1255
1271
|
}
|
package/dist/commands/browse.js
CHANGED
|
@@ -380,7 +380,7 @@ function parseBrowseCommandOptions(options) {
|
|
|
380
380
|
};
|
|
381
381
|
}
|
|
382
382
|
async function loadMergedBrowseResults(input) {
|
|
383
|
-
const { client,
|
|
383
|
+
const { client, creatorUsername, appType, assetCategory, assetSubcategory, assetSpec, assetSpecOwner, assetSpecName, limit, offset, tags, } = input;
|
|
384
384
|
const appResultsPromise = creatorUsername
|
|
385
385
|
? collectPaginatedItems((pageLimit, pageOffset) => client.fetchAppsByCreator(creatorUsername, {
|
|
386
386
|
limit: pageLimit,
|
|
@@ -546,7 +546,7 @@ async function runAssetPackBrowseCommand(input) {
|
|
|
546
546
|
};
|
|
547
547
|
}
|
|
548
548
|
async function runBrowseCommand(input) {
|
|
549
|
-
const { client, kind,
|
|
549
|
+
const { client, kind, creatorUsername, appType, auth, controller, surface, sort, limit, offset, tags, } = input;
|
|
550
550
|
if (kind === 'app') {
|
|
551
551
|
if (creatorUsername) {
|
|
552
552
|
const response = await client.fetchAppsByCreator(creatorUsername, {
|
package/dist/commands/build.js
CHANGED
|
@@ -23,9 +23,11 @@ async function build(pathOrName) {
|
|
|
23
23
|
for (const task of (0, taskUtils_1.sortTasks)(tasks)) {
|
|
24
24
|
const entityId = task.name;
|
|
25
25
|
try {
|
|
26
|
+
let detail;
|
|
26
27
|
if (task.kind === 'app') {
|
|
27
28
|
await (0, apps_1.validateAppTask)(task);
|
|
28
|
-
await (0, apps_1.buildApp)(task);
|
|
29
|
+
const artifacts = await (0, apps_1.buildApp)(task);
|
|
30
|
+
detail = `bundleHash=${artifacts.bundleHash}`;
|
|
29
31
|
}
|
|
30
32
|
else if (task.kind === 'asset' || task.kind === 'owned-asset') {
|
|
31
33
|
const generated = await (0, model_artifacts_1.prepareModel3DAssetArtifacts)(task);
|
|
@@ -42,6 +44,7 @@ async function build(pathOrName) {
|
|
|
42
44
|
entityType: task.kind,
|
|
43
45
|
entityId,
|
|
44
46
|
catalogue: task.cataloguePath,
|
|
47
|
+
detail,
|
|
45
48
|
};
|
|
46
49
|
results.push(entry);
|
|
47
50
|
console.log((0, uploadLog_1.formatTaskLogLine)(entry));
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { type AppSurface } from '@playdrop/types';
|
|
2
|
+
import type { BrowserContextOptions } from 'playwright-core';
|
|
1
3
|
type CaptureListingOptions = {
|
|
2
4
|
app?: string;
|
|
3
5
|
duration?: string | number;
|
|
@@ -8,6 +10,7 @@ type CaptureListingOptions = {
|
|
|
8
10
|
audio?: boolean;
|
|
9
11
|
outputDir?: string;
|
|
10
12
|
keepRaw?: boolean;
|
|
13
|
+
contentHash?: string;
|
|
11
14
|
};
|
|
12
15
|
type ParsedCaptureListingOptions = {
|
|
13
16
|
targetArg?: string;
|
|
@@ -20,6 +23,8 @@ type ParsedCaptureListingOptions = {
|
|
|
20
23
|
audio: boolean;
|
|
21
24
|
outputDir: string | null;
|
|
22
25
|
keepRaw: boolean;
|
|
26
|
+
contentHash: string | null;
|
|
27
|
+
explicitDimensions: boolean;
|
|
23
28
|
};
|
|
24
29
|
type CaptureRect = {
|
|
25
30
|
x: number;
|
|
@@ -45,11 +50,35 @@ type CropRect = {
|
|
|
45
50
|
width: number;
|
|
46
51
|
height: number;
|
|
47
52
|
};
|
|
48
|
-
export declare function resolveListingCaptureRouteSegment(previewable: boolean): 'dev
|
|
53
|
+
export declare function resolveListingCaptureRouteSegment(previewable: boolean): 'dev-preview';
|
|
54
|
+
export declare function resolveCaptureListingDevRouterPort(env?: NodeJS.ProcessEnv): number;
|
|
55
|
+
export declare function resolveListingCaptureLocalDevPort(devRouterPort: number): number | null;
|
|
56
|
+
export declare function buildListingCaptureFrameUrl({ webBase, currentUsername, appTypeSlug, appName, routeSegment, localDevPort, }: {
|
|
57
|
+
webBase: string;
|
|
58
|
+
currentUsername: string;
|
|
59
|
+
appTypeSlug: string;
|
|
60
|
+
appName: string;
|
|
61
|
+
routeSegment: 'dev-preview';
|
|
62
|
+
localDevPort: number | null;
|
|
63
|
+
}): string;
|
|
49
64
|
export declare function resolveListingCaptureSceneId(width: number, height: number): 'listing-landscape' | 'listing-portrait';
|
|
50
65
|
export declare function parseCaptureListingOptions(targetArg: string | undefined, options?: CaptureListingOptions): ParsedCaptureListingOptions;
|
|
51
66
|
export declare function assertSupportedListingEnvironment(platform?: NodeJS.Platform, macosVersion?: string): void;
|
|
52
67
|
export declare function resolveListingRecorderPath(baseDir?: string): string;
|
|
68
|
+
export declare function buildSurfaceOutputPaths(outputDir: string, surface: AppSurface, useSurfacePrefix: boolean): {
|
|
69
|
+
rawVideoPath: string;
|
|
70
|
+
metadataPath: string;
|
|
71
|
+
posterPath: string;
|
|
72
|
+
finalVideoPath: string;
|
|
73
|
+
};
|
|
74
|
+
export declare function resolveCaptureDimensions(surface: AppSurface, parsedOptions: ParsedCaptureListingOptions): {
|
|
75
|
+
width: number;
|
|
76
|
+
height: number;
|
|
77
|
+
};
|
|
78
|
+
export declare function resolveListingCaptureBrowserContextOptions(surface: AppSurface, dimensions: {
|
|
79
|
+
width: number;
|
|
80
|
+
height: number;
|
|
81
|
+
}): BrowserContextOptions;
|
|
53
82
|
export declare function computeRecordedCrop(measurement: HostedGameMeasurement, rawWidth: number, rawHeight: number): CropRect;
|
|
54
83
|
export declare function captureListing(targetArg: string | undefined, options?: CaptureListingOptions): Promise<void>;
|
|
55
84
|
export {};
|