@playdrop/playdrop-cli 0.5.2 → 0.5.3
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 +4 -4
- package/dist/apps/build.js +49 -6
- package/dist/apps/index.d.ts +2 -0
- package/dist/apps/index.js +2 -0
- package/dist/apps/upload.d.ts +2 -0
- package/dist/apps/upload.js +126 -28
- package/dist/assetSpecs.d.ts +16 -0
- package/dist/assetSpecs.js +263 -0
- package/dist/assets/model-artifacts.js +3 -0
- package/dist/catalogue.d.ts +57 -3
- package/dist/catalogue.js +342 -16
- package/dist/commands/ads.d.ts +8 -0
- package/dist/commands/ads.js +124 -0
- package/dist/commands/boosts.d.ts +25 -0
- package/dist/commands/boosts.js +209 -0
- package/dist/commands/browse.d.ts +6 -1
- package/dist/commands/browse.js +365 -124
- package/dist/commands/captureListing.d.ts +53 -0
- package/dist/commands/captureListing.js +804 -0
- package/dist/commands/create.d.ts +1 -0
- package/dist/commands/create.js +183 -3
- package/dist/commands/credits.d.ts +6 -0
- package/dist/commands/credits.js +47 -1
- package/dist/commands/detail.js +38 -4
- package/dist/commands/devServer.js +10 -5
- package/dist/commands/search.d.ts +5 -0
- package/dist/commands/search.js +139 -17
- package/dist/commands/tags.d.ts +7 -0
- package/dist/commands/tags.js +63 -0
- package/dist/commands/upload-content.d.ts +13 -3
- package/dist/commands/upload-content.js +86 -20
- package/dist/commands/upload.d.ts +2 -0
- package/dist/commands/upload.js +187 -11
- package/dist/commands/validate.js +163 -2
- package/dist/commands/versionsBrowse.js +128 -91
- package/dist/index.js +145 -3
- package/dist/refs.d.ts +2 -2
- package/dist/refs.js +13 -1
- package/dist/taskSelection.js +6 -3
- package/dist/taskUtils.d.ts +2 -2
- package/dist/taskUtils.js +1 -0
- package/dist/uploadLog.d.ts +1 -1
- package/dist/uploadLog.js +2 -2
- package/node_modules/@playdrop/ai-client/package.json +1 -1
- package/node_modules/@playdrop/api-client/dist/client.d.ts +131 -10
- package/node_modules/@playdrop/api-client/dist/client.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/client.js +6 -0
- package/node_modules/@playdrop/api-client/dist/domains/admin.d.ts +9 -1
- package/node_modules/@playdrop/api-client/dist/domains/admin.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/admin.js +45 -0
- package/node_modules/@playdrop/api-client/dist/domains/apps.d.ts +3 -0
- package/node_modules/@playdrop/api-client/dist/domains/apps.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/apps.js +27 -0
- package/node_modules/@playdrop/api-client/dist/domains/asset-packs.d.ts +2 -0
- package/node_modules/@playdrop/api-client/dist/domains/asset-packs.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/asset-packs.js +16 -0
- package/node_modules/@playdrop/api-client/dist/domains/assets.d.ts +44 -2
- package/node_modules/@playdrop/api-client/dist/domains/assets.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/assets.js +260 -3
- package/node_modules/@playdrop/api-client/dist/domains/payments.d.ts +17 -1
- package/node_modules/@playdrop/api-client/dist/domains/payments.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/payments.js +173 -0
- package/node_modules/@playdrop/api-client/dist/domains/search.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/search.js +39 -11
- package/node_modules/@playdrop/api-client/dist/domains/tags.d.ts +34 -0
- package/node_modules/@playdrop/api-client/dist/domains/tags.d.ts.map +1 -0
- package/node_modules/@playdrop/api-client/dist/domains/tags.js +111 -0
- package/node_modules/@playdrop/api-client/dist/index.d.ts +61 -1
- package/node_modules/@playdrop/api-client/dist/index.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/index.js +50 -0
- package/node_modules/@playdrop/api-client/package.json +1 -1
- package/node_modules/@playdrop/boxel-core/package.json +1 -1
- package/node_modules/@playdrop/boxel-three/package.json +1 -1
- package/node_modules/@playdrop/config/client-meta.json +4 -4
- package/node_modules/@playdrop/config/dist/src/constants.d.ts +11 -0
- package/node_modules/@playdrop/config/dist/src/constants.d.ts.map +1 -1
- package/node_modules/@playdrop/config/dist/src/constants.js +12 -1
- package/node_modules/@playdrop/config/dist/tsconfig.tsbuildinfo +1 -1
- package/node_modules/@playdrop/config/package.json +1 -1
- package/node_modules/@playdrop/types/dist/api.d.ts +346 -6
- package/node_modules/@playdrop/types/dist/api.d.ts.map +1 -1
- package/node_modules/@playdrop/types/dist/api.js +52 -1
- package/node_modules/@playdrop/types/dist/asset-pack.d.ts +7 -1
- package/node_modules/@playdrop/types/dist/asset-pack.d.ts.map +1 -1
- package/node_modules/@playdrop/types/dist/asset-spec-contract-meta-schema.json +86 -0
- package/node_modules/@playdrop/types/dist/asset-spec.d.ts +163 -0
- package/node_modules/@playdrop/types/dist/asset-spec.d.ts.map +1 -0
- package/node_modules/@playdrop/types/dist/asset-spec.js +101 -0
- package/node_modules/@playdrop/types/dist/asset.d.ts +23 -6
- package/node_modules/@playdrop/types/dist/asset.d.ts.map +1 -1
- package/node_modules/@playdrop/types/dist/asset.js +4 -1
- package/node_modules/@playdrop/types/dist/graph.d.ts +4 -2
- package/node_modules/@playdrop/types/dist/graph.d.ts.map +1 -1
- package/node_modules/@playdrop/types/dist/graph.js +9 -2
- package/node_modules/@playdrop/types/dist/index.d.ts +1 -0
- package/node_modules/@playdrop/types/dist/index.d.ts.map +1 -1
- package/node_modules/@playdrop/types/dist/index.js +1 -0
- package/node_modules/@playdrop/types/dist/version.d.ts +13 -0
- package/node_modules/@playdrop/types/dist/version.d.ts.map +1 -1
- package/node_modules/@playdrop/types/dist/version.js +21 -0
- package/node_modules/@playdrop/types/package.json +6 -1
- package/node_modules/@playdrop/vox-three/package.json +1 -1
- package/package.json +3 -1
|
@@ -57,18 +57,144 @@ function printEntry(entry) {
|
|
|
57
57
|
}
|
|
58
58
|
return;
|
|
59
59
|
}
|
|
60
|
+
if (entry.kind === 'asset-spec') {
|
|
61
|
+
const currentLabel = entry.isCurrent ? ' | current' : '';
|
|
62
|
+
console.log(`${entry.version} | ${entry.visibility.toLowerCase()} | ${entry.status.toLowerCase()}${currentLabel} | ${(0, output_1.formatTimestamp)(entry.createdAt)}`);
|
|
63
|
+
console.log(` Documentation URL: ${(0, output_1.formatOptionalValue)(entry.documentationUrl)}`);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
60
66
|
const currentLabel = entry.isCurrent ? ' | current' : '';
|
|
61
67
|
console.log(`${entry.version} | ${entry.visibility.toLowerCase()}${currentLabel} | ${(0, output_1.formatTimestamp)(entry.createdAt)}`);
|
|
62
68
|
console.log(` Download URL: ${(0, output_1.formatOptionalValue)(entry.urls.download)}`);
|
|
63
69
|
console.log(` Source URL: ${entry.urls.source}`);
|
|
64
70
|
}
|
|
71
|
+
async function loadVersionEntries(input) {
|
|
72
|
+
const { client, envConfig, ref, limit, offset } = input;
|
|
73
|
+
if (ref.kind === 'app') {
|
|
74
|
+
const [appDetail, response] = await Promise.all([
|
|
75
|
+
client.fetchAppBySlug(ref.creator, ref.name),
|
|
76
|
+
client.listAppVersions(ref.creator, ref.name),
|
|
77
|
+
]);
|
|
78
|
+
const listed = response.versions ?? [];
|
|
79
|
+
const selected = listed.slice(offset, offset + limit);
|
|
80
|
+
const entries = await Promise.all(selected.map(async (version) => {
|
|
81
|
+
const detail = await client.getAppVersion(ref.creator, ref.name, version.version);
|
|
82
|
+
return {
|
|
83
|
+
kind: 'app',
|
|
84
|
+
version: version.version,
|
|
85
|
+
visibility: version.visibility,
|
|
86
|
+
createdAt: version.createdAt,
|
|
87
|
+
updatedAt: detail.version.updatedAt,
|
|
88
|
+
releaseNotes: version.releaseNotes ?? null,
|
|
89
|
+
isCurrent: Boolean(version.isCurrent),
|
|
90
|
+
urls: {
|
|
91
|
+
play: (0, appUrls_1.buildPlatformPlayUrl)(envConfig.webBase, {
|
|
92
|
+
creatorUsername: ref.creator,
|
|
93
|
+
appName: ref.name,
|
|
94
|
+
appType: appDetail.app.type,
|
|
95
|
+
}),
|
|
96
|
+
source: typeof detail.version.sourceUrl === 'string' ? detail.version.sourceUrl : null,
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
}));
|
|
100
|
+
return {
|
|
101
|
+
entries,
|
|
102
|
+
pagination: {
|
|
103
|
+
limit,
|
|
104
|
+
offset,
|
|
105
|
+
count: entries.length,
|
|
106
|
+
hasMore: listed.length > offset + limit,
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
if (ref.kind === 'asset') {
|
|
111
|
+
const [detail, response] = await Promise.all([
|
|
112
|
+
client.fetchAssetBySlug(ref.creator, ref.name),
|
|
113
|
+
client.listAssetVersions(ref.creator, ref.name, { limit, offset }),
|
|
114
|
+
]);
|
|
115
|
+
const currentRevision = detail.asset.currentVersion?.revision ?? null;
|
|
116
|
+
return {
|
|
117
|
+
entries: (response.versions ?? []).map((version) => ({
|
|
118
|
+
kind: 'asset',
|
|
119
|
+
revision: version.revision,
|
|
120
|
+
revisionLabel: version.revisionLabel,
|
|
121
|
+
visibility: version.visibility,
|
|
122
|
+
createdAt: version.createdAt,
|
|
123
|
+
updatedAt: version.updatedAt,
|
|
124
|
+
subcategory: version.subcategory,
|
|
125
|
+
format: version.format,
|
|
126
|
+
isCurrent: currentRevision === version.revision,
|
|
127
|
+
urls: {
|
|
128
|
+
source: buildAssetSourceUrl(envConfig.apiBase, ref, version.revision),
|
|
129
|
+
files: assetFileUrls(version),
|
|
130
|
+
},
|
|
131
|
+
})),
|
|
132
|
+
pagination: response.pagination ?? {
|
|
133
|
+
limit,
|
|
134
|
+
offset,
|
|
135
|
+
count: (response.versions ?? []).length,
|
|
136
|
+
hasMore: false,
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
if (ref.kind === 'asset-pack') {
|
|
141
|
+
const [detail, response] = await Promise.all([
|
|
142
|
+
client.fetchAssetPackBySlug(ref.creator, ref.name),
|
|
143
|
+
client.listAssetPackVersions(ref.creator, ref.name, { limit, offset }),
|
|
144
|
+
]);
|
|
145
|
+
const currentVersion = detail.pack.currentVersion?.version ?? null;
|
|
146
|
+
return {
|
|
147
|
+
entries: (response.versions ?? []).map((version) => ({
|
|
148
|
+
kind: 'asset-pack',
|
|
149
|
+
version: version.version,
|
|
150
|
+
visibility: version.visibility,
|
|
151
|
+
createdAt: version.createdAt,
|
|
152
|
+
updatedAt: version.updatedAt,
|
|
153
|
+
isCurrent: currentVersion === version.version,
|
|
154
|
+
urls: {
|
|
155
|
+
download: buildAssetPackDownloadUrl(envConfig.apiBase, ref, version.version),
|
|
156
|
+
source: buildAssetPackSourceUrl(envConfig.apiBase, ref, version.version),
|
|
157
|
+
},
|
|
158
|
+
})),
|
|
159
|
+
pagination: response.pagination ?? {
|
|
160
|
+
limit,
|
|
161
|
+
offset,
|
|
162
|
+
count: (response.versions ?? []).length,
|
|
163
|
+
hasMore: false,
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
const [detail, response] = await Promise.all([
|
|
168
|
+
client.fetchAssetSpecBySlug(ref.creator, ref.name),
|
|
169
|
+
client.listAssetSpecVersions(ref.creator, ref.name, { limit, offset }),
|
|
170
|
+
]);
|
|
171
|
+
const currentVersion = detail.assetSpec.currentVersion?.version ?? null;
|
|
172
|
+
return {
|
|
173
|
+
entries: (response.versions ?? []).map((version) => ({
|
|
174
|
+
kind: 'asset-spec',
|
|
175
|
+
version: version.version,
|
|
176
|
+
visibility: version.visibility,
|
|
177
|
+
status: version.status,
|
|
178
|
+
createdAt: version.createdAt,
|
|
179
|
+
updatedAt: version.updatedAt,
|
|
180
|
+
isCurrent: currentVersion === version.version,
|
|
181
|
+
documentationUrl: version.documentationUrl ?? null,
|
|
182
|
+
})),
|
|
183
|
+
pagination: response.pagination ?? {
|
|
184
|
+
limit,
|
|
185
|
+
offset,
|
|
186
|
+
count: (response.versions ?? []).length,
|
|
187
|
+
hasMore: false,
|
|
188
|
+
},
|
|
189
|
+
};
|
|
190
|
+
}
|
|
65
191
|
async function browseVersions(rawRef, options = {}) {
|
|
66
192
|
let ref;
|
|
67
193
|
try {
|
|
68
194
|
ref = (0, refs_1.parseContentRef)(rawRef ?? '');
|
|
69
195
|
}
|
|
70
196
|
catch {
|
|
71
|
-
(0, messages_1.printErrorWithHelp)('A canonical ref is required.', ['Use the format <creator>/<kind>/<name>.', 'Example: playdrop versions browse playdrop/app/hangingout'], { command: 'versions browse' });
|
|
197
|
+
(0, messages_1.printErrorWithHelp)('A canonical ref is required.', ['Use the format <creator>/<kind>/<name>.', 'Example: playdrop versions browse playdrop/app/hangingout', 'Example: playdrop versions browse playdrop/asset-spec/platformer-level'], { command: 'versions browse' });
|
|
72
198
|
process.exitCode = 1;
|
|
73
199
|
return;
|
|
74
200
|
}
|
|
@@ -86,96 +212,7 @@ async function browseVersions(rawRef, options = {}) {
|
|
|
86
212
|
}
|
|
87
213
|
await (0, commandContext_1.withPublicEnvironment)('versions browse', async ({ client, envConfig }) => {
|
|
88
214
|
try {
|
|
89
|
-
|
|
90
|
-
let pagination;
|
|
91
|
-
if (ref.kind === 'app') {
|
|
92
|
-
const [appDetail, response] = await Promise.all([
|
|
93
|
-
client.fetchAppBySlug(ref.creator, ref.name),
|
|
94
|
-
client.listAppVersions(ref.creator, ref.name),
|
|
95
|
-
]);
|
|
96
|
-
const listed = response.versions ?? [];
|
|
97
|
-
const selected = listed.slice(offset, offset + limit);
|
|
98
|
-
const details = await Promise.all(selected.map(async (version) => {
|
|
99
|
-
const detail = await client.getAppVersion(ref.creator, ref.name, version.version);
|
|
100
|
-
return {
|
|
101
|
-
kind: 'app',
|
|
102
|
-
version: version.version,
|
|
103
|
-
visibility: version.visibility,
|
|
104
|
-
createdAt: version.createdAt,
|
|
105
|
-
updatedAt: detail.version.updatedAt,
|
|
106
|
-
releaseNotes: version.releaseNotes ?? null,
|
|
107
|
-
isCurrent: Boolean(version.isCurrent),
|
|
108
|
-
urls: {
|
|
109
|
-
play: (0, appUrls_1.buildPlatformPlayUrl)(envConfig.webBase, {
|
|
110
|
-
creatorUsername: ref.creator,
|
|
111
|
-
appName: ref.name,
|
|
112
|
-
appType: appDetail.app.type,
|
|
113
|
-
}),
|
|
114
|
-
source: typeof detail.version.sourceUrl === 'string' ? detail.version.sourceUrl : null,
|
|
115
|
-
},
|
|
116
|
-
};
|
|
117
|
-
}));
|
|
118
|
-
entries = details;
|
|
119
|
-
pagination = {
|
|
120
|
-
limit,
|
|
121
|
-
offset,
|
|
122
|
-
count: entries.length,
|
|
123
|
-
hasMore: listed.length > offset + limit,
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
else if (ref.kind === 'asset') {
|
|
127
|
-
const [detail, response] = await Promise.all([
|
|
128
|
-
client.fetchAssetBySlug(ref.creator, ref.name),
|
|
129
|
-
client.listAssetVersions(ref.creator, ref.name, { limit, offset }),
|
|
130
|
-
]);
|
|
131
|
-
const currentRevision = detail.asset.currentVersion?.revision ?? null;
|
|
132
|
-
entries = (response.versions ?? []).map((version) => ({
|
|
133
|
-
kind: 'asset',
|
|
134
|
-
revision: version.revision,
|
|
135
|
-
revisionLabel: version.revisionLabel,
|
|
136
|
-
visibility: version.visibility,
|
|
137
|
-
createdAt: version.createdAt,
|
|
138
|
-
updatedAt: version.updatedAt,
|
|
139
|
-
subcategory: version.subcategory,
|
|
140
|
-
format: version.format,
|
|
141
|
-
isCurrent: currentRevision === version.revision,
|
|
142
|
-
urls: {
|
|
143
|
-
source: buildAssetSourceUrl(envConfig.apiBase, ref, version.revision),
|
|
144
|
-
files: assetFileUrls(version),
|
|
145
|
-
},
|
|
146
|
-
}));
|
|
147
|
-
pagination = response.pagination ?? {
|
|
148
|
-
limit,
|
|
149
|
-
offset,
|
|
150
|
-
count: entries.length,
|
|
151
|
-
hasMore: false,
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
else {
|
|
155
|
-
const [detail, response] = await Promise.all([
|
|
156
|
-
client.fetchAssetPackBySlug(ref.creator, ref.name),
|
|
157
|
-
client.listAssetPackVersions(ref.creator, ref.name, { limit, offset }),
|
|
158
|
-
]);
|
|
159
|
-
const currentVersion = detail.pack.currentVersion?.version ?? null;
|
|
160
|
-
entries = (response.versions ?? []).map((version) => ({
|
|
161
|
-
kind: 'asset-pack',
|
|
162
|
-
version: version.version,
|
|
163
|
-
visibility: version.visibility,
|
|
164
|
-
createdAt: version.createdAt,
|
|
165
|
-
updatedAt: version.updatedAt,
|
|
166
|
-
isCurrent: currentVersion === version.version,
|
|
167
|
-
urls: {
|
|
168
|
-
download: buildAssetPackDownloadUrl(envConfig.apiBase, ref, version.version),
|
|
169
|
-
source: buildAssetPackSourceUrl(envConfig.apiBase, ref, version.version),
|
|
170
|
-
},
|
|
171
|
-
}));
|
|
172
|
-
pagination = response.pagination ?? {
|
|
173
|
-
limit,
|
|
174
|
-
offset,
|
|
175
|
-
count: entries.length,
|
|
176
|
-
hasMore: false,
|
|
177
|
-
};
|
|
178
|
-
}
|
|
215
|
+
const { entries, pagination } = await loadVersionEntries({ client, envConfig, ref, limit, offset });
|
|
179
216
|
if (options.json) {
|
|
180
217
|
(0, output_1.printJson)({ kind: ref.kind, ref: ref.ref, entries, pagination });
|
|
181
218
|
return;
|
package/dist/index.js
CHANGED
|
@@ -10,11 +10,14 @@ const whoami_1 = require("./commands/whoami");
|
|
|
10
10
|
const logout_1 = require("./commands/logout");
|
|
11
11
|
const browse_1 = require("./commands/browse");
|
|
12
12
|
const search_1 = require("./commands/search");
|
|
13
|
+
const tags_1 = require("./commands/tags");
|
|
13
14
|
const detail_1 = require("./commands/detail");
|
|
14
15
|
const play_1 = require("./commands/play");
|
|
16
|
+
const ads_1 = require("./commands/ads");
|
|
15
17
|
const comments_1 = require("./commands/comments");
|
|
16
18
|
const versionsBrowse_1 = require("./commands/versionsBrowse");
|
|
17
19
|
const credits_1 = require("./commands/credits");
|
|
20
|
+
const boosts_1 = require("./commands/boosts");
|
|
18
21
|
const notifications_1 = require("./commands/notifications");
|
|
19
22
|
const creations_1 = require("./commands/creations");
|
|
20
23
|
const generation_1 = require("./commands/generation");
|
|
@@ -23,6 +26,7 @@ const create_1 = require("./commands/create");
|
|
|
23
26
|
const createRemixContent_1 = require("./commands/createRemixContent");
|
|
24
27
|
const dev_1 = require("./commands/dev");
|
|
25
28
|
const capture_1 = require("./commands/capture");
|
|
29
|
+
const captureListing_1 = require("./commands/captureListing");
|
|
26
30
|
const captureRemote_1 = require("./commands/captureRemote");
|
|
27
31
|
const validate_1 = require("./commands/validate");
|
|
28
32
|
const build_1 = require("./commands/build");
|
|
@@ -95,6 +99,9 @@ program.on('command:*', (unknownCommands) => {
|
|
|
95
99
|
function createEnvOption() {
|
|
96
100
|
return new commander_1.Option('--env <env>', 'Environment (dev|local|prod)').default('prod');
|
|
97
101
|
}
|
|
102
|
+
function collectRepeatedOption(value, previous = []) {
|
|
103
|
+
return [...previous, value];
|
|
104
|
+
}
|
|
98
105
|
function registerLoginCommand(parent) {
|
|
99
106
|
parent
|
|
100
107
|
.command('login')
|
|
@@ -136,13 +143,18 @@ registerLogoutCommand(auth);
|
|
|
136
143
|
registerWhoamiCommand(auth);
|
|
137
144
|
const browseCommand = program.command('browse').description('Browse public content');
|
|
138
145
|
browseCommand
|
|
139
|
-
.option('--kind <kind>', 'app, asset, asset-pack, or all')
|
|
146
|
+
.option('--kind <kind>', 'app, asset, asset-pack, asset-spec, or all')
|
|
140
147
|
.option('--creator <creator>', 'all, me, or a creator slug')
|
|
141
148
|
.option('--app-type <type>', 'game, demo, tool, or template')
|
|
142
149
|
.option('--asset-category <category>', 'Asset category filter')
|
|
143
150
|
.option('--asset-subcategory <subcategory>', 'Asset subcategory filter')
|
|
151
|
+
.option('--asset-spec <ref>', 'Asset spec family or version filter for assets')
|
|
152
|
+
.option('--asset-spec-owner <creator>', 'Asset spec owner filter for assets')
|
|
153
|
+
.option('--asset-spec-name <name>', 'Asset spec name filter for assets')
|
|
154
|
+
.option('--sort <sort>', 'Sort asset or asset-spec browse results')
|
|
144
155
|
.option('--limit <number>', 'Maximum number of results to return')
|
|
145
156
|
.option('--offset <number>', 'Result offset')
|
|
157
|
+
.option('--tag <ref>', 'Filter by canonical tag ref', collectRepeatedOption, [])
|
|
146
158
|
.option('--json', 'Output JSON')
|
|
147
159
|
.action(async (opts) => {
|
|
148
160
|
await (0, browse_1.browse)(opts);
|
|
@@ -157,18 +169,33 @@ browseCommand
|
|
|
157
169
|
program
|
|
158
170
|
.command('search <query>')
|
|
159
171
|
.description('Search public content')
|
|
160
|
-
.option('--kind <kind>', 'app, asset, asset-pack, or all')
|
|
172
|
+
.option('--kind <kind>', 'app, asset, asset-pack, asset-spec, or all')
|
|
161
173
|
.option('--app-type <type>', 'game, demo, tool, or template')
|
|
162
174
|
.option('--asset-category <category>', 'Asset category filter')
|
|
163
175
|
.option('--asset-subcategory <subcategory>', 'Asset subcategory filter')
|
|
176
|
+
.option('--asset-spec <ref>', 'Asset spec family or version filter for assets')
|
|
177
|
+
.option('--asset-spec-owner <creator>', 'Asset spec owner filter for assets')
|
|
178
|
+
.option('--asset-spec-name <name>', 'Asset spec name filter for assets')
|
|
179
|
+
.option('--sort <sort>', 'Sort search results')
|
|
164
180
|
.option('--pack-contains-category <category>', 'Asset pack category filter')
|
|
165
181
|
.option('--pack-contains-subcategory <subcategory>', 'Asset pack subcategory filter')
|
|
166
182
|
.option('--limit <number>', 'Maximum number of results to return')
|
|
167
183
|
.option('--offset <number>', 'Result offset')
|
|
184
|
+
.option('--tag <ref>', 'Filter by canonical tag ref', collectRepeatedOption, [])
|
|
168
185
|
.option('--json', 'Output JSON')
|
|
169
186
|
.action(async (query, opts) => {
|
|
170
187
|
await (0, search_1.search)(query, opts);
|
|
171
188
|
});
|
|
189
|
+
const tags = program.command('tags').description('Browse and inspect tags');
|
|
190
|
+
tags
|
|
191
|
+
.command('browse')
|
|
192
|
+
.description('Browse public tags')
|
|
193
|
+
.option('--group <slug>', 'Filter to one tag group')
|
|
194
|
+
.option('--kind <kind>', 'Filter to one target kind')
|
|
195
|
+
.option('--json', 'Output JSON')
|
|
196
|
+
.action(async (opts) => {
|
|
197
|
+
await (0, tags_1.browseTags)(opts);
|
|
198
|
+
});
|
|
172
199
|
program
|
|
173
200
|
.command('detail <ref>')
|
|
174
201
|
.description('Show one app, asset, or asset pack')
|
|
@@ -234,6 +261,88 @@ credits
|
|
|
234
261
|
.action(async (opts) => {
|
|
235
262
|
await (0, credits_1.browseCreditTransactions)(opts);
|
|
236
263
|
});
|
|
264
|
+
credits
|
|
265
|
+
.command('earnings')
|
|
266
|
+
.description('Show creator ad earnings and boost spend summary')
|
|
267
|
+
.option('--days <number>', 'Number of days to include')
|
|
268
|
+
.option('--app-id <number>', 'Filter to one app id')
|
|
269
|
+
.option('--json', 'Output JSON')
|
|
270
|
+
.action(async (opts) => {
|
|
271
|
+
await (0, credits_1.showCreatorEarnings)(opts);
|
|
272
|
+
});
|
|
273
|
+
const ads = program.command('ads').description('Creator ad earnings and reporting');
|
|
274
|
+
ads
|
|
275
|
+
.command('earnings')
|
|
276
|
+
.description('Show ad earnings grouped by app and format')
|
|
277
|
+
.option('--app <ref>', 'Filter to one app ref')
|
|
278
|
+
.option('--days <number>', 'Number of days to include')
|
|
279
|
+
.option('--json', 'Output JSON')
|
|
280
|
+
.action(async (opts) => {
|
|
281
|
+
await (0, ads_1.showAdsEarnings)(opts);
|
|
282
|
+
});
|
|
283
|
+
ads
|
|
284
|
+
.command('report')
|
|
285
|
+
.description('Show daily ad reporting buckets')
|
|
286
|
+
.option('--app <ref>', 'Filter to one app ref')
|
|
287
|
+
.option('--days <number>', 'Number of days to include')
|
|
288
|
+
.option('--json', 'Output JSON')
|
|
289
|
+
.action(async (opts) => {
|
|
290
|
+
await (0, ads_1.showAdsReport)(opts);
|
|
291
|
+
});
|
|
292
|
+
const boosts = program.command('boosts').description('Buy, activate, and inspect game boosts');
|
|
293
|
+
boosts
|
|
294
|
+
.command('balance')
|
|
295
|
+
.description('Show your available boost inventory')
|
|
296
|
+
.option('--json', 'Output JSON')
|
|
297
|
+
.action(async (opts) => {
|
|
298
|
+
await (0, boosts_1.showBoostBalance)(opts);
|
|
299
|
+
});
|
|
300
|
+
boosts
|
|
301
|
+
.command('offers')
|
|
302
|
+
.description('List available boost packs')
|
|
303
|
+
.option('--json', 'Output JSON')
|
|
304
|
+
.action(async (opts) => {
|
|
305
|
+
await (0, boosts_1.browseBoostOffers)(opts);
|
|
306
|
+
});
|
|
307
|
+
boosts
|
|
308
|
+
.command('buy <sku>')
|
|
309
|
+
.description('Buy one boost pack')
|
|
310
|
+
.option('--quantity <number>', 'Number of packs to buy')
|
|
311
|
+
.option('--json', 'Output JSON')
|
|
312
|
+
.action(async (sku, opts) => {
|
|
313
|
+
await (0, boosts_1.buyBoostPack)(sku, opts);
|
|
314
|
+
});
|
|
315
|
+
boosts
|
|
316
|
+
.command('activate <ref>')
|
|
317
|
+
.description('Activate one or more boosts for an app')
|
|
318
|
+
.option('--units <number>', 'Number of boosts to consume')
|
|
319
|
+
.option('--json', 'Output JSON')
|
|
320
|
+
.action(async (ref, opts) => {
|
|
321
|
+
await (0, boosts_1.activateBoost)(ref, opts);
|
|
322
|
+
});
|
|
323
|
+
boosts
|
|
324
|
+
.command('status <ref>')
|
|
325
|
+
.description('Show the current boost status for an app')
|
|
326
|
+
.option('--json', 'Output JSON')
|
|
327
|
+
.action(async (ref, opts) => {
|
|
328
|
+
await (0, boosts_1.showBoostStatus)(ref, opts);
|
|
329
|
+
});
|
|
330
|
+
boosts
|
|
331
|
+
.command('history <ref>')
|
|
332
|
+
.description('Show past boost runs for an app')
|
|
333
|
+
.option('--limit <number>', 'Maximum number of boost runs to include')
|
|
334
|
+
.option('--json', 'Output JSON')
|
|
335
|
+
.action(async (ref, opts) => {
|
|
336
|
+
await (0, boosts_1.showBoostHistory)(ref, opts);
|
|
337
|
+
});
|
|
338
|
+
boosts
|
|
339
|
+
.command('report <ref>')
|
|
340
|
+
.description('Show daily boost performance for an app')
|
|
341
|
+
.option('--days <number>', 'Number of days to include')
|
|
342
|
+
.option('--json', 'Output JSON')
|
|
343
|
+
.action(async (ref, opts) => {
|
|
344
|
+
await (0, boosts_1.showBoostReport)(ref, opts);
|
|
345
|
+
});
|
|
237
346
|
const notifications = program.command('notifications').description('Notification inbox');
|
|
238
347
|
notifications
|
|
239
348
|
.command('browse')
|
|
@@ -519,6 +628,12 @@ projectCreate
|
|
|
519
628
|
.action(async (name, opts) => {
|
|
520
629
|
await (0, create_1.create)(name, opts);
|
|
521
630
|
});
|
|
631
|
+
projectCreate
|
|
632
|
+
.command('asset-spec <name>')
|
|
633
|
+
.description('Create a new custom asset spec scaffold')
|
|
634
|
+
.action(async (name) => {
|
|
635
|
+
await (0, create_1.createAssetSpecProject)(name);
|
|
636
|
+
});
|
|
522
637
|
projectCreate
|
|
523
638
|
.command('asset <name>')
|
|
524
639
|
.description('Create a new asset remix from an exact asset version')
|
|
@@ -562,6 +677,31 @@ projectCapture
|
|
|
562
677
|
password: opts.password,
|
|
563
678
|
});
|
|
564
679
|
});
|
|
680
|
+
projectCapture
|
|
681
|
+
.command('listing [target]', { hidden: true })
|
|
682
|
+
.description('Record private listing video for a hosted app')
|
|
683
|
+
.option('--app <name>', 'App name when the target is a workspace')
|
|
684
|
+
.option('--duration <seconds>', 'Recording duration in seconds')
|
|
685
|
+
.option('--width <pixels>', 'Final gameplay width in pixels')
|
|
686
|
+
.option('--height <pixels>', 'Final gameplay height in pixels')
|
|
687
|
+
.option('--fps <number>', 'Final output frame rate')
|
|
688
|
+
.option('--poster-at <seconds>', 'Poster frame offset in seconds')
|
|
689
|
+
.option('--audio', 'Capture gameplay audio')
|
|
690
|
+
.option('--output-dir <path>', 'Output directory for the capture artifacts')
|
|
691
|
+
.option('--keep-raw', 'Keep the raw intermediate recording')
|
|
692
|
+
.action(async (target, opts) => {
|
|
693
|
+
await (0, captureListing_1.captureListing)(target, {
|
|
694
|
+
app: opts.app,
|
|
695
|
+
duration: opts.duration,
|
|
696
|
+
width: opts.width,
|
|
697
|
+
height: opts.height,
|
|
698
|
+
fps: opts.fps,
|
|
699
|
+
posterAt: opts.posterAt,
|
|
700
|
+
audio: opts.audio,
|
|
701
|
+
outputDir: opts.outputDir,
|
|
702
|
+
keepRaw: opts.keepRaw,
|
|
703
|
+
});
|
|
704
|
+
});
|
|
565
705
|
projectCapture
|
|
566
706
|
.command('remote <url>')
|
|
567
707
|
.description('Run a Playwright capture against a published URL')
|
|
@@ -600,8 +740,10 @@ project
|
|
|
600
740
|
.command('publish [target]')
|
|
601
741
|
.description('Publish local content to Playdrop')
|
|
602
742
|
.option('--skip-ecs', 'Skip ecs.json and server.js during publish')
|
|
743
|
+
.option('--clear-tags', 'Confirm clearing existing live tags when this publish removes them')
|
|
744
|
+
.addOption(new commander_1.Option('--skip-review', 'Mark uploaded app versions as NOT_REQUIRED review. Admin-only.').hideHelp())
|
|
603
745
|
.action(async (target, opts) => {
|
|
604
|
-
await (0, upload_1.upload)(target ?? '.', { skipEcs: opts.skipEcs });
|
|
746
|
+
await (0, upload_1.upload)(target ?? '.', { skipEcs: opts.skipEcs, skipReview: opts.skipReview, clearTags: opts.clearTags });
|
|
605
747
|
});
|
|
606
748
|
const documentation = program.command('documentation').description('Public Playdrop documentation');
|
|
607
749
|
documentation
|
package/dist/refs.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ApiClient } from '@playdrop/api-client';
|
|
2
2
|
import type { SavedItemKind } from '@playdrop/types';
|
|
3
|
-
export type ContentKind = 'app' | 'asset' | 'asset-pack';
|
|
3
|
+
export type ContentKind = 'app' | 'asset' | 'asset-pack' | 'asset-spec';
|
|
4
4
|
export type ContentRef = {
|
|
5
5
|
creator: string;
|
|
6
6
|
kind: ContentKind;
|
|
@@ -13,6 +13,6 @@ export declare function parseCreatorOption(raw: string | undefined): string | 'm
|
|
|
13
13
|
export declare function resolveCreatorOption(client: ApiClient, raw: string | undefined): Promise<string>;
|
|
14
14
|
export declare function buildScopedRef(creator: string, kind: ContentKind, name: string): ContentRef;
|
|
15
15
|
export declare function contentKindToSavedItemKind(kind: ContentKind): SavedItemKind;
|
|
16
|
-
export declare function contentKindToSearchKind(kind: ContentKind | 'all'): 'all' | 'app' | 'asset' | 'pack';
|
|
16
|
+
export declare function contentKindToSearchKind(kind: ContentKind | 'all'): 'all' | 'app' | 'asset' | 'asset-spec' | 'pack';
|
|
17
17
|
export declare function contentKindLabel(kind: ContentKind): string;
|
|
18
18
|
export declare function contentKindPluralLabel(kind: ContentKind): string;
|
package/dist/refs.js
CHANGED
|
@@ -31,7 +31,7 @@ function parseContentRef(raw) {
|
|
|
31
31
|
const creator = sanitizeSegment(segments[0], 'creator');
|
|
32
32
|
const kind = sanitizeSegment(segments[1], 'kind');
|
|
33
33
|
const name = sanitizeSegment(segments[2], 'name');
|
|
34
|
-
if (kind !== 'app' && kind !== 'asset' && kind !== 'asset-pack') {
|
|
34
|
+
if (kind !== 'app' && kind !== 'asset' && kind !== 'asset-pack' && kind !== 'asset-spec') {
|
|
35
35
|
throw new Error('invalid_kind');
|
|
36
36
|
}
|
|
37
37
|
return {
|
|
@@ -83,9 +83,15 @@ function contentKindToSavedItemKind(kind) {
|
|
|
83
83
|
if (kind === 'asset') {
|
|
84
84
|
return 'ASSET';
|
|
85
85
|
}
|
|
86
|
+
if (kind === 'asset-spec') {
|
|
87
|
+
throw new Error('asset_specs_not_saveable');
|
|
88
|
+
}
|
|
86
89
|
return 'PACK';
|
|
87
90
|
}
|
|
88
91
|
function contentKindToSearchKind(kind) {
|
|
92
|
+
if (kind === 'asset-spec') {
|
|
93
|
+
return 'asset-spec';
|
|
94
|
+
}
|
|
89
95
|
if (kind === 'asset-pack') {
|
|
90
96
|
return 'pack';
|
|
91
97
|
}
|
|
@@ -95,11 +101,17 @@ function contentKindLabel(kind) {
|
|
|
95
101
|
if (kind === 'asset-pack') {
|
|
96
102
|
return 'asset pack';
|
|
97
103
|
}
|
|
104
|
+
if (kind === 'asset-spec') {
|
|
105
|
+
return 'asset spec';
|
|
106
|
+
}
|
|
98
107
|
return kind;
|
|
99
108
|
}
|
|
100
109
|
function contentKindPluralLabel(kind) {
|
|
101
110
|
if (kind === 'asset-pack') {
|
|
102
111
|
return 'asset packs';
|
|
103
112
|
}
|
|
113
|
+
if (kind === 'asset-spec') {
|
|
114
|
+
return 'asset specs';
|
|
115
|
+
}
|
|
104
116
|
return `${kind}s`;
|
|
105
117
|
}
|
package/dist/taskSelection.js
CHANGED
|
@@ -29,6 +29,8 @@ function createDirectAppTask(htmlPath) {
|
|
|
29
29
|
emoji: undefined,
|
|
30
30
|
color: undefined,
|
|
31
31
|
surfaceTargets: [],
|
|
32
|
+
assetSpecSupport: [],
|
|
33
|
+
tags: [],
|
|
32
34
|
missingMetadata: [],
|
|
33
35
|
achievements: [],
|
|
34
36
|
leaderboards: [],
|
|
@@ -53,7 +55,7 @@ function selectTasks(pathOrName) {
|
|
|
53
55
|
});
|
|
54
56
|
return { tasks: [], warnings, errors, resolution: 'directory' };
|
|
55
57
|
}
|
|
56
|
-
const { apps, assets, embeddedAssets, assetPacks, warnings: rawWarnings, errors: catalogueErrors } = (0, catalogue_1.resolveCatalogueEntries)(absolute);
|
|
58
|
+
const { apps, assetSpecs, assets, embeddedAssets, assetPacks, warnings: rawWarnings, errors: catalogueErrors } = (0, catalogue_1.resolveCatalogueEntries)(absolute);
|
|
57
59
|
if (catalogueErrors.length > 0) {
|
|
58
60
|
catalogueErrors.forEach(message => {
|
|
59
61
|
errors.push({
|
|
@@ -64,12 +66,12 @@ function selectTasks(pathOrName) {
|
|
|
64
66
|
});
|
|
65
67
|
return { tasks: [], warnings, errors, resolution: 'directory' };
|
|
66
68
|
}
|
|
67
|
-
const taskList = [...assets, ...apps, ...embeddedAssets, ...assetPacks];
|
|
69
|
+
const taskList = [...assetSpecs, ...assets, ...apps, ...embeddedAssets, ...assetPacks];
|
|
68
70
|
if (taskList.length === 0) {
|
|
69
71
|
errors.push({
|
|
70
72
|
type: 'no-tasks',
|
|
71
73
|
message: `No publishable entries were found under ${absolute}.`,
|
|
72
|
-
help: ['Add child catalogue.json files or add apps, assets, or assetPacks to the root catalogue.json, then rerun the command.'],
|
|
74
|
+
help: ['Add child catalogue.json files or add apps, assetSpecs, assets, or assetPacks to the root catalogue.json, then rerun the command.'],
|
|
73
75
|
directory: absolute,
|
|
74
76
|
});
|
|
75
77
|
return { tasks: [], warnings, errors, resolution: 'directory' };
|
|
@@ -126,6 +128,7 @@ function selectTasks(pathOrName) {
|
|
|
126
128
|
}
|
|
127
129
|
const candidates = [
|
|
128
130
|
...lookup.apps.filter(task => task.name === pathOrName),
|
|
131
|
+
...lookup.assetSpecs.filter(task => task.name === pathOrName),
|
|
129
132
|
...lookup.assets.filter(task => task.name === pathOrName),
|
|
130
133
|
...lookup.assetPacks.filter(task => task.name === pathOrName),
|
|
131
134
|
];
|
package/dist/taskUtils.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AppTask, AssetTask, EmbeddedAssetTask, AssetPackTask } from './catalogue';
|
|
2
|
-
export type CliTask = AppTask | AssetTask | EmbeddedAssetTask | AssetPackTask;
|
|
1
|
+
import type { AppTask, AssetSpecTask, AssetTask, EmbeddedAssetTask, AssetPackTask } from './catalogue';
|
|
2
|
+
export type CliTask = AppTask | AssetSpecTask | AssetTask | EmbeddedAssetTask | AssetPackTask;
|
|
3
3
|
export declare function sortTasks(tasks: CliTask[]): CliTask[];
|
|
4
4
|
export declare function addTaskWarnings(warnings: Set<string>, tasks: CliTask[]): void;
|
package/dist/taskUtils.js
CHANGED
package/dist/uploadLog.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export type TaskStatus = 'success' | 'skipped' | 'error';
|
|
|
3
3
|
export type TaskLogEntry = {
|
|
4
4
|
action: TaskAction;
|
|
5
5
|
status: TaskStatus;
|
|
6
|
-
entityType: 'app' | 'asset' | 'embedded-asset' | 'asset-pack';
|
|
6
|
+
entityType: 'app' | 'asset-spec' | 'asset' | 'embedded-asset' | 'asset-pack' | 'tag-group' | 'tag';
|
|
7
7
|
entityId: string;
|
|
8
8
|
catalogue: string;
|
|
9
9
|
detail?: string;
|
package/dist/uploadLog.js
CHANGED
|
@@ -39,7 +39,7 @@ function formatLabel(entry) {
|
|
|
39
39
|
function formatTaskLogLine(entry) {
|
|
40
40
|
const prefix = `${STATUS_EMOJI[entry.status]} ${formatLabel(entry)}`;
|
|
41
41
|
if (entry.detail) {
|
|
42
|
-
return `${prefix}
|
|
42
|
+
return `${prefix} - ${entry.detail}`;
|
|
43
43
|
}
|
|
44
44
|
return prefix;
|
|
45
45
|
}
|
|
@@ -108,7 +108,7 @@ function printTaskSummary(entries, warnings, options) {
|
|
|
108
108
|
summaryText = labels.complete;
|
|
109
109
|
}
|
|
110
110
|
const parts = [
|
|
111
|
-
`${summaryEmoji} ${summaryText}
|
|
111
|
+
`${summaryEmoji} ${summaryText} - ${success} ${labels.unit}`,
|
|
112
112
|
`${skipped} skipped`,
|
|
113
113
|
`${failed} failed`,
|
|
114
114
|
];
|