@playdrop/playdrop-cli 0.5.1 → 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 +7 -7
- 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 +132 -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/clientInfo.js +19 -3
- 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/captureRemote.js +33 -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/generation.d.ts +2 -0
- package/dist/commands/generation.js +1 -0
- 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/dist/test/entity-utils.test.d.ts +1 -0
- package/node_modules/@playdrop/boxel-core/dist/test/entity-utils.test.js +92 -0
- package/node_modules/@playdrop/boxel-core/dist/test/entity-utils.test.js.map +1 -0
- package/node_modules/@playdrop/boxel-core/dist/test/greedy-mesher.test.d.ts +1 -0
- package/node_modules/@playdrop/boxel-core/dist/test/greedy-mesher.test.js +48 -0
- package/node_modules/@playdrop/boxel-core/dist/test/greedy-mesher.test.js.map +1 -0
- package/node_modules/@playdrop/boxel-core/dist/test/humanoid/humanoid-builders.test.d.ts +1 -0
- package/node_modules/@playdrop/boxel-core/dist/test/humanoid/humanoid-builders.test.js +270 -0
- package/node_modules/@playdrop/boxel-core/dist/test/humanoid/humanoid-builders.test.js.map +1 -0
- package/node_modules/@playdrop/boxel-core/dist/test/index.test.d.ts +1 -0
- package/node_modules/@playdrop/boxel-core/dist/test/index.test.js +48 -0
- package/node_modules/@playdrop/boxel-core/dist/test/index.test.js.map +1 -0
- package/node_modules/@playdrop/boxel-core/dist/test/layer-mode.test.d.ts +1 -0
- package/node_modules/@playdrop/boxel-core/dist/test/layer-mode.test.js +67 -0
- package/node_modules/@playdrop/boxel-core/dist/test/layer-mode.test.js.map +1 -0
- package/node_modules/@playdrop/boxel-core/dist/test/materials.test.d.ts +1 -0
- package/node_modules/@playdrop/boxel-core/dist/test/materials.test.js +55 -0
- package/node_modules/@playdrop/boxel-core/dist/test/materials.test.js.map +1 -0
- package/node_modules/@playdrop/boxel-core/dist/test/palette-tools.test.d.ts +1 -0
- package/node_modules/@playdrop/boxel-core/dist/test/palette-tools.test.js +124 -0
- package/node_modules/@playdrop/boxel-core/dist/test/palette-tools.test.js.map +1 -0
- package/node_modules/@playdrop/boxel-core/dist/test/serialization.test.d.ts +1 -0
- package/node_modules/@playdrop/boxel-core/dist/test/serialization.test.js +35 -0
- package/node_modules/@playdrop/boxel-core/dist/test/serialization.test.js.map +1 -0
- package/node_modules/@playdrop/boxel-core/dist/test/textures.test.d.ts +1 -0
- package/node_modules/@playdrop/boxel-core/dist/test/textures.test.js +120 -0
- package/node_modules/@playdrop/boxel-core/dist/test/textures.test.js.map +1 -0
- package/node_modules/@playdrop/boxel-core/dist/test/types.test.d.ts +1 -0
- package/node_modules/@playdrop/boxel-core/dist/test/types.test.js +32 -0
- package/node_modules/@playdrop/boxel-core/dist/test/types.test.js.map +1 -0
- package/node_modules/@playdrop/boxel-core/dist/test/upscale.test.d.ts +1 -0
- package/node_modules/@playdrop/boxel-core/dist/test/upscale.test.js +100 -0
- package/node_modules/@playdrop/boxel-core/dist/test/upscale.test.js.map +1 -0
- package/node_modules/@playdrop/boxel-core/dist/test/validation.test.d.ts +1 -0
- package/node_modules/@playdrop/boxel-core/dist/test/validation.test.js +61 -0
- package/node_modules/@playdrop/boxel-core/dist/test/validation.test.js.map +1 -0
- package/node_modules/@playdrop/boxel-core/dist/test/voxels.test.d.ts +1 -0
- package/node_modules/@playdrop/boxel-core/dist/test/voxels.test.js +51 -0
- package/node_modules/@playdrop/boxel-core/dist/test/voxels.test.js.map +1 -0
- 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 +7 -7
- 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/src/creator-docs.d.ts +24 -0
- package/node_modules/@playdrop/config/dist/src/creator-docs.d.ts.map +1 -0
- package/node_modules/@playdrop/config/dist/src/creator-docs.js +253 -0
- package/node_modules/@playdrop/config/dist/src/creator-faq.d.ts +17 -0
- package/node_modules/@playdrop/config/dist/src/creator-faq.d.ts.map +1 -0
- package/node_modules/@playdrop/config/dist/src/creator-faq.js +141 -0
- package/node_modules/@playdrop/config/dist/test/creator-docs.test.d.ts +2 -0
- package/node_modules/@playdrop/config/dist/test/creator-docs.test.d.ts.map +1 -0
- package/node_modules/@playdrop/config/dist/test/creator-docs.test.js +36 -0
- 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
package/dist/catalogue.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.validateAppMetadata = validateAppMetadata;
|
|
4
|
+
exports.resolveCatalogueTagGroups = resolveCatalogueTagGroups;
|
|
4
5
|
exports.resolveCatalogueEntries = resolveCatalogueEntries;
|
|
5
6
|
exports.resolveWorkspaceApp = resolveWorkspaceApp;
|
|
6
7
|
exports.formatMetadataWarnings = formatMetadataWarnings;
|
|
@@ -10,6 +11,7 @@ const node_fs_1 = require("node:fs");
|
|
|
10
11
|
const node_path_1 = require("node:path");
|
|
11
12
|
const types_1 = require("@playdrop/types");
|
|
12
13
|
const catalogue_utils_1 = require("./catalogue-utils");
|
|
14
|
+
const assetSpecs_1 = require("./assetSpecs");
|
|
13
15
|
const HEX_COLOR_REGEX = /^#?(?:[0-9a-fA-F]{6})$/;
|
|
14
16
|
const SEMVER_REGEX = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/;
|
|
15
17
|
const LEGACY_CATALOGUE_VERSION_KEY = ['schema', 'Version'].join('');
|
|
@@ -20,6 +22,7 @@ const BOXEL_GENERATED_FILE_ROLES = new Set(['mesh', 'preview']);
|
|
|
20
22
|
const BOXEL_REQUIRED_FILE_ROLES = ['primary', 'mesh', 'preview'];
|
|
21
23
|
const VOX_GENERATED_FILE_ROLES = new Set(['boxel', 'mesh', 'preview']);
|
|
22
24
|
const VOX_REQUIRED_FILE_ROLES = ['primary', 'boxel', 'mesh', 'preview'];
|
|
25
|
+
const MAX_CONTENT_TAGS_PER_ITEM = 8;
|
|
23
26
|
const ASSET_SUBCATEGORY_SET_BY_CATEGORY = types_1.ASSET_SUBCATEGORY_DEFINITIONS.reduce((acc, definition) => {
|
|
24
27
|
if (!acc[definition.category]) {
|
|
25
28
|
acc[definition.category] = new Set();
|
|
@@ -165,6 +168,69 @@ function rejectLegacyShopPriceCoinsField(value, errors, context) {
|
|
|
165
168
|
}
|
|
166
169
|
return false;
|
|
167
170
|
}
|
|
171
|
+
function normalizeCatalogueTags(value, errors, context) {
|
|
172
|
+
if (value === undefined || value === null) {
|
|
173
|
+
return [];
|
|
174
|
+
}
|
|
175
|
+
if (!Array.isArray(value)) {
|
|
176
|
+
errors.push(`${context} tags must be an array of canonical tag refs.`);
|
|
177
|
+
return [];
|
|
178
|
+
}
|
|
179
|
+
const normalizedRefs = [];
|
|
180
|
+
const seenRefs = new Set();
|
|
181
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
182
|
+
const entry = value[index];
|
|
183
|
+
if (typeof entry !== 'string' || entry.trim().length === 0) {
|
|
184
|
+
errors.push(`${context} tags[${index}] must be a non-empty canonical tag ref string.`);
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
let normalizedRef = '';
|
|
188
|
+
try {
|
|
189
|
+
normalizedRef = (0, types_1.normalizeTagRef)(entry);
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
errors.push(`${context} tags[${index}] must use group-slug/tag-slug format.`);
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
if (seenRefs.has(normalizedRef)) {
|
|
196
|
+
errors.push(`${context} tags contains duplicate ref "${normalizedRef}".`);
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
seenRefs.add(normalizedRef);
|
|
200
|
+
normalizedRefs.push(normalizedRef);
|
|
201
|
+
}
|
|
202
|
+
if (normalizedRefs.length > MAX_CONTENT_TAGS_PER_ITEM) {
|
|
203
|
+
errors.push(`${context} tags supports at most ${MAX_CONTENT_TAGS_PER_ITEM} refs.`);
|
|
204
|
+
}
|
|
205
|
+
return normalizedRefs;
|
|
206
|
+
}
|
|
207
|
+
function normalizeCatalogueAllowedTargetKinds(value, errors, context) {
|
|
208
|
+
if (value === undefined || value === null) {
|
|
209
|
+
return undefined;
|
|
210
|
+
}
|
|
211
|
+
if (!Array.isArray(value)) {
|
|
212
|
+
errors.push(`${context} allowedTargetKinds must be an array of saved item kinds.`);
|
|
213
|
+
return undefined;
|
|
214
|
+
}
|
|
215
|
+
const normalizedKinds = [];
|
|
216
|
+
const seenKinds = new Set();
|
|
217
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
218
|
+
const entry = value[index];
|
|
219
|
+
const normalizedKind = typeof entry === 'string' ? entry.trim().toUpperCase() : '';
|
|
220
|
+
if (!types_1.SAVED_ITEM_KIND_VALUES.includes(normalizedKind)) {
|
|
221
|
+
errors.push(`${context} allowedTargetKinds[${index}] must be one of ${types_1.SAVED_ITEM_KIND_VALUES.join(', ')}.`);
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
const savedItemKind = normalizedKind;
|
|
225
|
+
if (seenKinds.has(savedItemKind)) {
|
|
226
|
+
errors.push(`${context} allowedTargetKinds contains duplicate value "${savedItemKind}".`);
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
seenKinds.add(savedItemKind);
|
|
230
|
+
normalizedKinds.push(savedItemKind);
|
|
231
|
+
}
|
|
232
|
+
return normalizedKinds;
|
|
233
|
+
}
|
|
168
234
|
function normalizeRelativePath(root, target) {
|
|
169
235
|
const rel = (0, node_path_1.relative)(root, target).split(node_path_1.sep).join('/');
|
|
170
236
|
return rel.replace(/^\/+/, '');
|
|
@@ -206,7 +272,7 @@ function readCatalogueFile(rootDir, filePath) {
|
|
|
206
272
|
return { error: `catalogue.json forbids top-level "${key}"` };
|
|
207
273
|
}
|
|
208
274
|
}
|
|
209
|
-
const allowedKeys = new Set(['apps', 'assets', 'assetPacks']);
|
|
275
|
+
const allowedKeys = new Set(['apps', 'tagGroups', 'assetSpecs', 'assets', 'assetPacks']);
|
|
210
276
|
const unknownKeys = Object.keys(parsed).filter((key) => !allowedKeys.has(key));
|
|
211
277
|
if (unknownKeys.length > 0) {
|
|
212
278
|
return {
|
|
@@ -752,6 +818,7 @@ function buildAppTasks(rootDir, catalogues, options) {
|
|
|
752
818
|
const errorCountBeforePlayerMeta = errors.length;
|
|
753
819
|
const achievements = validateAchievementDefinitions(entry.achievements, file.directory, errors);
|
|
754
820
|
const leaderboards = validateLeaderboardDefinitions(entry.leaderboards, errors);
|
|
821
|
+
const assetSpecSupport = (0, assetSpecs_1.normalizeAssetSpecSupportEntries)(entry.assetSpecSupport, errors, `[${label}] App "${rawName}"`);
|
|
755
822
|
if (errors.length > errorCountBeforePlayerMeta) {
|
|
756
823
|
continue;
|
|
757
824
|
}
|
|
@@ -1044,8 +1111,13 @@ function buildAppTasks(rootDir, catalogues, options) {
|
|
|
1044
1111
|
const usesPacks = Array.isArray(entry.uses?.packs)
|
|
1045
1112
|
? entry.uses.packs.filter((value) => typeof value === 'string' && value.trim().length > 0)
|
|
1046
1113
|
: [];
|
|
1114
|
+
const errorCountBeforeTagMetadata = errors.length;
|
|
1047
1115
|
const remix = normalizeCatalogueRemixRef(entry.remix, 'app', errors, `[${label}] App "${rawName}"`);
|
|
1116
|
+
const tags = normalizeCatalogueTags(entry.tags, errors, `[${label}] App "${rawName}"`);
|
|
1048
1117
|
const graphRelations = normalizeCatalogueRelations(entry.relations, errors, `[${label}] App "${rawName}"`) ?? [];
|
|
1118
|
+
if (errors.length > errorCountBeforeTagMetadata) {
|
|
1119
|
+
continue;
|
|
1120
|
+
}
|
|
1049
1121
|
const embeddedAssets = [];
|
|
1050
1122
|
const rawEmbeddedAssets = Array.isArray(entry.embeddedAssets)
|
|
1051
1123
|
? entry.embeddedAssets
|
|
@@ -1173,6 +1245,7 @@ function buildAppTasks(rootDir, catalogues, options) {
|
|
|
1173
1245
|
version,
|
|
1174
1246
|
releaseNotes,
|
|
1175
1247
|
versionVisibility,
|
|
1248
|
+
tags,
|
|
1176
1249
|
hostingMode,
|
|
1177
1250
|
authMode,
|
|
1178
1251
|
controllerMode,
|
|
@@ -1185,6 +1258,7 @@ function buildAppTasks(rootDir, catalogues, options) {
|
|
|
1185
1258
|
leaderboards,
|
|
1186
1259
|
remix,
|
|
1187
1260
|
embeddedAssets,
|
|
1261
|
+
assetSpecSupport,
|
|
1188
1262
|
uses: {
|
|
1189
1263
|
assets: usesAssets,
|
|
1190
1264
|
packs: usesPacks,
|
|
@@ -1197,7 +1271,126 @@ function buildAppTasks(rootDir, catalogues, options) {
|
|
|
1197
1271
|
}
|
|
1198
1272
|
return { tasks, warnings, errors };
|
|
1199
1273
|
}
|
|
1200
|
-
function
|
|
1274
|
+
function buildAssetSpecTasks(catalogues) {
|
|
1275
|
+
const tasks = [];
|
|
1276
|
+
const warnings = [];
|
|
1277
|
+
const errors = [];
|
|
1278
|
+
const seen = new Map();
|
|
1279
|
+
for (const file of catalogues) {
|
|
1280
|
+
const label = file.relativePath || 'catalogue.json';
|
|
1281
|
+
const rawAssetSpecs = Array.isArray(file.data.assetSpecs) ? file.data.assetSpecs : [];
|
|
1282
|
+
for (let index = 0; index < rawAssetSpecs.length; index += 1) {
|
|
1283
|
+
const entry = rawAssetSpecs[index];
|
|
1284
|
+
if (!entry || typeof entry !== 'object') {
|
|
1285
|
+
errors.push(`[${label}] Invalid assetSpecs[${index}] entry; expected object.`);
|
|
1286
|
+
continue;
|
|
1287
|
+
}
|
|
1288
|
+
const name = typeof entry.name === 'string' ? entry.name.trim() : '';
|
|
1289
|
+
if (!name) {
|
|
1290
|
+
errors.push(`[${label}] assetSpecs[${index}] is missing a name.`);
|
|
1291
|
+
continue;
|
|
1292
|
+
}
|
|
1293
|
+
if (!(0, assetSpecs_1.validateAssetSpecName)(name, errors, `[${label}] Asset spec "${name}"`)) {
|
|
1294
|
+
continue;
|
|
1295
|
+
}
|
|
1296
|
+
const version = typeof entry.version === 'string' ? entry.version.trim() : '';
|
|
1297
|
+
if (!SEMVER_REGEX.test(version)) {
|
|
1298
|
+
errors.push(`[${label}] Asset spec "${name}" must define a semver version.`);
|
|
1299
|
+
continue;
|
|
1300
|
+
}
|
|
1301
|
+
const dedupeKey = `${label}::${name}::${version}`;
|
|
1302
|
+
if (seen.has(dedupeKey)) {
|
|
1303
|
+
errors.push(`[${label}] Duplicate asset spec "${name}@${version}" in same catalogue.`);
|
|
1304
|
+
continue;
|
|
1305
|
+
}
|
|
1306
|
+
seen.set(dedupeKey, label);
|
|
1307
|
+
const displayName = typeof entry.displayName === 'string' ? entry.displayName.trim() : '';
|
|
1308
|
+
if (!displayName) {
|
|
1309
|
+
errors.push(`[${label}] Asset spec "${name}@${version}" must define displayName.`);
|
|
1310
|
+
continue;
|
|
1311
|
+
}
|
|
1312
|
+
const symbol = typeof entry.symbol === 'string' ? entry.symbol.trim() : '';
|
|
1313
|
+
if (!symbol) {
|
|
1314
|
+
errors.push(`[${label}] Asset spec "${name}@${version}" must define symbol.`);
|
|
1315
|
+
continue;
|
|
1316
|
+
}
|
|
1317
|
+
const symbolPath = (0, node_path_1.resolve)(file.directory, symbol);
|
|
1318
|
+
if (!(0, node_fs_1.existsSync)(symbolPath) || !(0, node_fs_1.statSync)(symbolPath).isFile()) {
|
|
1319
|
+
errors.push(`[${label}] Asset spec "${name}@${version}" symbol file not found at ${symbolPath}.`);
|
|
1320
|
+
continue;
|
|
1321
|
+
}
|
|
1322
|
+
const contractField = typeof entry.contract === 'string' ? entry.contract.trim() : '';
|
|
1323
|
+
if (!contractField) {
|
|
1324
|
+
errors.push(`[${label}] Asset spec "${name}@${version}" must define contract.`);
|
|
1325
|
+
continue;
|
|
1326
|
+
}
|
|
1327
|
+
const loadedContract = (0, assetSpecs_1.loadAndValidateAssetSpecContract)(file.directory, contractField, errors, `[${label}] Asset spec "${name}@${version}"`);
|
|
1328
|
+
if (!loadedContract) {
|
|
1329
|
+
continue;
|
|
1330
|
+
}
|
|
1331
|
+
let validationKind = loadedContract.validationKind;
|
|
1332
|
+
if (typeof entry.validationKind === 'string' && entry.validationKind.trim().length > 0) {
|
|
1333
|
+
const normalizedValidationKind = entry.validationKind.trim().toUpperCase();
|
|
1334
|
+
if (!types_1.ASSET_SPEC_VALIDATION_KIND_VALUES.includes(normalizedValidationKind)) {
|
|
1335
|
+
errors.push(`[${label}] Asset spec "${name}@${version}" validationKind must be one of ${types_1.ASSET_SPEC_VALIDATION_KIND_VALUES.join(', ')}.`);
|
|
1336
|
+
continue;
|
|
1337
|
+
}
|
|
1338
|
+
if (normalizedValidationKind !== loadedContract.validationKind) {
|
|
1339
|
+
errors.push(`[${label}] Asset spec "${name}@${version}" validationKind must match the contract content (${loadedContract.validationKind}).`);
|
|
1340
|
+
continue;
|
|
1341
|
+
}
|
|
1342
|
+
validationKind = normalizedValidationKind;
|
|
1343
|
+
}
|
|
1344
|
+
let status = 'ACTIVE';
|
|
1345
|
+
if (typeof entry.status === 'string' && entry.status.trim().length > 0) {
|
|
1346
|
+
const normalizedStatus = entry.status.trim().toUpperCase();
|
|
1347
|
+
if (!types_1.ASSET_SPEC_STATUS_VALUES.includes(normalizedStatus)) {
|
|
1348
|
+
errors.push(`[${label}] Asset spec "${name}@${version}" status must be one of ${types_1.ASSET_SPEC_STATUS_VALUES.join(', ')}.`);
|
|
1349
|
+
continue;
|
|
1350
|
+
}
|
|
1351
|
+
status = normalizedStatus;
|
|
1352
|
+
}
|
|
1353
|
+
const visibility = normalizeAssetVisibilityValue(entry.visibility, errors, `${label} asset spec "${name}@${version}"`);
|
|
1354
|
+
const successorVersion = typeof entry.successorVersion === 'string' && entry.successorVersion.trim().length > 0
|
|
1355
|
+
? entry.successorVersion.trim()
|
|
1356
|
+
: undefined;
|
|
1357
|
+
if (successorVersion && !SEMVER_REGEX.test(successorVersion)) {
|
|
1358
|
+
errors.push(`[${label}] Asset spec "${name}@${version}" successorVersion must be a semver string.`);
|
|
1359
|
+
continue;
|
|
1360
|
+
}
|
|
1361
|
+
const documentationField = typeof entry.documentation === 'string' && entry.documentation.trim().length > 0
|
|
1362
|
+
? entry.documentation.trim()
|
|
1363
|
+
: undefined;
|
|
1364
|
+
const documentationPath = documentationField ? (0, node_path_1.resolve)(file.directory, documentationField) : undefined;
|
|
1365
|
+
if (documentationPath && (!(0, node_fs_1.existsSync)(documentationPath) || !(0, node_fs_1.statSync)(documentationPath).isFile())) {
|
|
1366
|
+
errors.push(`[${label}] Asset spec "${name}@${version}" documentation file not found at ${documentationPath}.`);
|
|
1367
|
+
continue;
|
|
1368
|
+
}
|
|
1369
|
+
tasks.push({
|
|
1370
|
+
kind: 'asset-spec',
|
|
1371
|
+
name,
|
|
1372
|
+
version,
|
|
1373
|
+
displayName,
|
|
1374
|
+
description: typeof entry.description === 'string' ? entry.description.trim() || undefined : undefined,
|
|
1375
|
+
cataloguePath: label,
|
|
1376
|
+
catalogueAbsolutePath: file.absolutePath,
|
|
1377
|
+
catalogueDir: file.directory,
|
|
1378
|
+
username: typeof entry.username === 'string' && entry.username.trim().length > 0 ? entry.username.trim() : undefined,
|
|
1379
|
+
visibility,
|
|
1380
|
+
validationKind,
|
|
1381
|
+
status,
|
|
1382
|
+
releaseNotes: typeof entry.releaseNotes === 'string' ? entry.releaseNotes : undefined,
|
|
1383
|
+
successorVersion,
|
|
1384
|
+
symbolPath,
|
|
1385
|
+
contractPath: loadedContract.contractPath,
|
|
1386
|
+
documentationPath,
|
|
1387
|
+
contract: loadedContract.contract,
|
|
1388
|
+
});
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
return { tasks, warnings, errors };
|
|
1392
|
+
}
|
|
1393
|
+
function buildAssetTasks(catalogues, _assetSpecTasks) {
|
|
1201
1394
|
const tasks = [];
|
|
1202
1395
|
const warnings = [];
|
|
1203
1396
|
const errors = [];
|
|
@@ -1228,19 +1421,35 @@ function buildAssetTasks(catalogues) {
|
|
|
1228
1421
|
continue;
|
|
1229
1422
|
}
|
|
1230
1423
|
seen.set(dedupeKey, label);
|
|
1231
|
-
const
|
|
1232
|
-
|
|
1233
|
-
|
|
1424
|
+
const assetSpec = (0, assetSpecs_1.normalizeAssetSpecVersionRef)(entry.assetSpec, errors, `[${label}] Asset "${name}"`);
|
|
1425
|
+
const isCustomAsset = typeof assetSpec === 'string';
|
|
1426
|
+
let category;
|
|
1427
|
+
let subcategory;
|
|
1428
|
+
let format;
|
|
1429
|
+
if (isCustomAsset) {
|
|
1430
|
+
if (entry.category !== undefined || entry.subcategory !== undefined || entry.format !== undefined) {
|
|
1431
|
+
errors.push(`[${label}] Asset "${name}" must not define category, subcategory, or format when assetSpec is set.`);
|
|
1432
|
+
continue;
|
|
1433
|
+
}
|
|
1434
|
+
subcategory = null;
|
|
1234
1435
|
}
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1436
|
+
else {
|
|
1437
|
+
category = normalizeAssetCategoryValue(entry.category, errors, `[${label}] Asset "${name}"`) ?? undefined;
|
|
1438
|
+
if (!category) {
|
|
1439
|
+
continue;
|
|
1440
|
+
}
|
|
1441
|
+
subcategory = normalizeAssetSubcategoryValue(entry.subcategory, category, errors, `[${label}] Asset "${name}"`);
|
|
1442
|
+
if (!subcategory) {
|
|
1443
|
+
continue;
|
|
1444
|
+
}
|
|
1445
|
+
format = typeof entry.format === 'string' && entry.format.trim().length > 0 ? entry.format.trim().toUpperCase() : undefined;
|
|
1238
1446
|
}
|
|
1239
|
-
const format = typeof entry.format === 'string' && entry.format.trim().length > 0 ? entry.format.trim().toUpperCase() : undefined;
|
|
1240
1447
|
const fileEntries = entry.files && typeof entry.files === 'object' && !Array.isArray(entry.files)
|
|
1241
1448
|
? entry.files
|
|
1242
1449
|
: null;
|
|
1243
|
-
const generatedModel3DFormat =
|
|
1450
|
+
const generatedModel3DFormat = !isCustomAsset && category && subcategory
|
|
1451
|
+
? inferGeneratedModel3DFormat(category, subcategory, format, fileEntries)
|
|
1452
|
+
: null;
|
|
1244
1453
|
const generatedModel3DRoles = generatedModel3DFormat ? getGeneratedModel3DFileRoles(generatedModel3DFormat) : null;
|
|
1245
1454
|
if (!fileEntries || Object.keys(fileEntries).length === 0) {
|
|
1246
1455
|
errors.push(`[${label}] Asset "${name}" must define files.`);
|
|
@@ -1275,7 +1484,7 @@ function buildAssetTasks(catalogues) {
|
|
|
1275
1484
|
if (hasError) {
|
|
1276
1485
|
continue;
|
|
1277
1486
|
}
|
|
1278
|
-
if (generatedModel3DRoles) {
|
|
1487
|
+
if (!isCustomAsset && generatedModel3DRoles) {
|
|
1279
1488
|
const normalizedRoles = new Set(Object.keys(files).map((role) => normalizeFileRole(role)));
|
|
1280
1489
|
const missingRoles = generatedModel3DRoles.required.filter((role) => !normalizedRoles.has(role));
|
|
1281
1490
|
if (missingRoles.length > 0) {
|
|
@@ -1283,7 +1492,7 @@ function buildAssetTasks(catalogues) {
|
|
|
1283
1492
|
continue;
|
|
1284
1493
|
}
|
|
1285
1494
|
}
|
|
1286
|
-
if (category === 'SPRITESHEET') {
|
|
1495
|
+
if (!isCustomAsset && category === 'SPRITESHEET') {
|
|
1287
1496
|
const hasAtlas = Object.prototype.hasOwnProperty.call(files, 'atlas');
|
|
1288
1497
|
const hasManifest = Object.prototype.hasOwnProperty.call(files, 'manifest');
|
|
1289
1498
|
if (!hasAtlas || !hasManifest) {
|
|
@@ -1291,15 +1500,20 @@ function buildAssetTasks(catalogues) {
|
|
|
1291
1500
|
continue;
|
|
1292
1501
|
}
|
|
1293
1502
|
}
|
|
1294
|
-
if (category === 'AUDIO') {
|
|
1503
|
+
if (!isCustomAsset && category === 'AUDIO') {
|
|
1295
1504
|
const hasPrimary = Object.prototype.hasOwnProperty.call(files, 'primary');
|
|
1296
1505
|
if (!hasPrimary) {
|
|
1297
1506
|
errors.push(`[${label}] Asset "${name}" with category=AUDIO must define files.primary.`);
|
|
1298
1507
|
continue;
|
|
1299
1508
|
}
|
|
1300
1509
|
}
|
|
1510
|
+
const errorCountBeforeTagMetadata = errors.length;
|
|
1301
1511
|
const remix = normalizeCatalogueRemixRef(entry.remix, 'asset', errors, `[${label}] Asset "${name}"`);
|
|
1512
|
+
const tags = normalizeCatalogueTags(entry.tags, errors, `[${label}] Asset "${name}"`);
|
|
1302
1513
|
const relations = normalizeCatalogueRelations(entry.relations, errors, `[${label}] Asset "${name}"`);
|
|
1514
|
+
if (errors.length > errorCountBeforeTagMetadata) {
|
|
1515
|
+
continue;
|
|
1516
|
+
}
|
|
1303
1517
|
const username = typeof entry.username === 'string' && entry.username.trim().length > 0
|
|
1304
1518
|
? entry.username.trim()
|
|
1305
1519
|
: undefined;
|
|
@@ -1313,10 +1527,12 @@ function buildAssetTasks(catalogues) {
|
|
|
1313
1527
|
cataloguePath: label,
|
|
1314
1528
|
category,
|
|
1315
1529
|
subcategory,
|
|
1530
|
+
assetSpec,
|
|
1316
1531
|
username,
|
|
1317
1532
|
remix,
|
|
1318
1533
|
format,
|
|
1319
1534
|
visibility: normalizeAssetVisibilityValue(entry.visibility, errors, `${label} asset "${name}"`),
|
|
1535
|
+
tags,
|
|
1320
1536
|
shopListed: typeof entry.shopListed === 'boolean' ? entry.shopListed : undefined,
|
|
1321
1537
|
shopPriceCredits: Number.isInteger(entry.shopPriceCredits) ? Number(entry.shopPriceCredits) : undefined,
|
|
1322
1538
|
files,
|
|
@@ -1399,8 +1615,13 @@ function buildAssetPackTasks(catalogues) {
|
|
|
1399
1615
|
errors.push(`[${label}] Asset pack "${name}" must reference at least one asset.`);
|
|
1400
1616
|
continue;
|
|
1401
1617
|
}
|
|
1618
|
+
const errorCountBeforeTagMetadata = errors.length;
|
|
1402
1619
|
const remix = normalizeCatalogueRemixRef(entry.remix, 'pack', errors, `[${label}] Asset pack "${name}@${version}"`);
|
|
1620
|
+
const tags = normalizeCatalogueTags(entry.tags, errors, `[${label}] Asset pack "${name}@${version}"`);
|
|
1403
1621
|
const relations = normalizeCatalogueRelations(entry.relations, errors, `[${label}] Asset pack "${name}@${version}"`);
|
|
1622
|
+
if (errors.length > errorCountBeforeTagMetadata) {
|
|
1623
|
+
continue;
|
|
1624
|
+
}
|
|
1404
1625
|
const username = typeof entry.username === 'string' && entry.username.trim().length > 0
|
|
1405
1626
|
? entry.username.trim()
|
|
1406
1627
|
: undefined;
|
|
@@ -1581,6 +1802,7 @@ function buildAssetPackTasks(catalogues) {
|
|
|
1581
1802
|
downloadUrl,
|
|
1582
1803
|
visibility,
|
|
1583
1804
|
releaseNotes: typeof entry.releaseNotes === 'string' ? entry.releaseNotes : undefined,
|
|
1805
|
+
tags,
|
|
1584
1806
|
listing,
|
|
1585
1807
|
relations,
|
|
1586
1808
|
});
|
|
@@ -1588,11 +1810,112 @@ function buildAssetPackTasks(catalogues) {
|
|
|
1588
1810
|
}
|
|
1589
1811
|
return { tasks, warnings, errors };
|
|
1590
1812
|
}
|
|
1813
|
+
// eslint-disable-next-line complexity
|
|
1814
|
+
function resolveCatalogueTagGroups(rootDir) {
|
|
1815
|
+
const { files, errors: discoveryErrors } = walkCatalogueTree(rootDir);
|
|
1816
|
+
if (discoveryErrors.length > 0) {
|
|
1817
|
+
return {
|
|
1818
|
+
groups: [],
|
|
1819
|
+
errors: discoveryErrors,
|
|
1820
|
+
};
|
|
1821
|
+
}
|
|
1822
|
+
const rootCatalogue = files.find((file) => file.relativePath === 'catalogue.json');
|
|
1823
|
+
const hasNestedCatalogues = files.some((file) => file.relativePath !== 'catalogue.json');
|
|
1824
|
+
if (rootCatalogue && hasNestedCatalogues && !isCatalogueMarker(rootCatalogue)) {
|
|
1825
|
+
return {
|
|
1826
|
+
groups: [],
|
|
1827
|
+
errors: [
|
|
1828
|
+
'[catalogue.json] Workspace root catalogue.json must be {} when nested catalogue.json files exist below it.',
|
|
1829
|
+
],
|
|
1830
|
+
};
|
|
1831
|
+
}
|
|
1832
|
+
const groups = [];
|
|
1833
|
+
const errors = [];
|
|
1834
|
+
const seenGroupSlugs = new Set();
|
|
1835
|
+
for (const file of files) {
|
|
1836
|
+
const label = file.relativePath || 'catalogue.json';
|
|
1837
|
+
const rawGroups = Array.isArray(file.data.tagGroups) ? file.data.tagGroups : [];
|
|
1838
|
+
for (let index = 0; index < rawGroups.length; index += 1) {
|
|
1839
|
+
const entry = rawGroups[index];
|
|
1840
|
+
if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
|
|
1841
|
+
errors.push(`[${label}] tagGroups[${index}] must be an object.`);
|
|
1842
|
+
continue;
|
|
1843
|
+
}
|
|
1844
|
+
const slug = typeof entry.slug === 'string' ? entry.slug.trim().toLowerCase() : '';
|
|
1845
|
+
if (!slug || !(0, types_1.isValidTagSlug)(slug)) {
|
|
1846
|
+
errors.push(`[${label}] tagGroups[${index}] slug must use lowercase slug format.`);
|
|
1847
|
+
continue;
|
|
1848
|
+
}
|
|
1849
|
+
if (seenGroupSlugs.has(slug)) {
|
|
1850
|
+
errors.push(`[${label}] Duplicate tag group slug "${slug}".`);
|
|
1851
|
+
continue;
|
|
1852
|
+
}
|
|
1853
|
+
const displayName = typeof entry.displayName === 'string' ? entry.displayName.trim() : '';
|
|
1854
|
+
if (!displayName) {
|
|
1855
|
+
errors.push(`[${label}] tagGroups[${index}] displayName must be a non-empty string.`);
|
|
1856
|
+
continue;
|
|
1857
|
+
}
|
|
1858
|
+
const errorCountBeforeGroup = errors.length;
|
|
1859
|
+
const allowedTargetKinds = normalizeCatalogueAllowedTargetKinds(entry.allowedTargetKinds, errors, `[${label}] Tag group "${slug}"`);
|
|
1860
|
+
if (!Array.isArray(entry.tags)) {
|
|
1861
|
+
errors.push(`[${label}] Tag group "${slug}" must define a tags array.`);
|
|
1862
|
+
continue;
|
|
1863
|
+
}
|
|
1864
|
+
const tags = [];
|
|
1865
|
+
const seenTagSlugs = new Set();
|
|
1866
|
+
for (let tagIndex = 0; tagIndex < entry.tags.length; tagIndex += 1) {
|
|
1867
|
+
const rawTag = entry.tags[tagIndex];
|
|
1868
|
+
if (!rawTag || typeof rawTag !== 'object' || Array.isArray(rawTag)) {
|
|
1869
|
+
errors.push(`[${label}] Tag group "${slug}" tags[${tagIndex}] must be an object.`);
|
|
1870
|
+
continue;
|
|
1871
|
+
}
|
|
1872
|
+
const tagSlug = typeof rawTag.slug === 'string' ? rawTag.slug.trim().toLowerCase() : '';
|
|
1873
|
+
if (!tagSlug || !(0, types_1.isValidTagSlug)(tagSlug)) {
|
|
1874
|
+
errors.push(`[${label}] Tag group "${slug}" tags[${tagIndex}] slug must use lowercase slug format.`);
|
|
1875
|
+
continue;
|
|
1876
|
+
}
|
|
1877
|
+
if (seenTagSlugs.has(tagSlug)) {
|
|
1878
|
+
errors.push(`[${label}] Tag group "${slug}" contains duplicate tag slug "${tagSlug}".`);
|
|
1879
|
+
continue;
|
|
1880
|
+
}
|
|
1881
|
+
const tagDisplayName = typeof rawTag.displayName === 'string' ? rawTag.displayName.trim() : '';
|
|
1882
|
+
if (!tagDisplayName) {
|
|
1883
|
+
errors.push(`[${label}] Tag group "${slug}" tag "${tagSlug}" displayName must be a non-empty string.`);
|
|
1884
|
+
continue;
|
|
1885
|
+
}
|
|
1886
|
+
seenTagSlugs.add(tagSlug);
|
|
1887
|
+
tags.push({
|
|
1888
|
+
slug: tagSlug,
|
|
1889
|
+
displayName: tagDisplayName,
|
|
1890
|
+
});
|
|
1891
|
+
}
|
|
1892
|
+
if (tags.length === 0) {
|
|
1893
|
+
errors.push(`[${label}] Tag group "${slug}" must define at least one tag.`);
|
|
1894
|
+
continue;
|
|
1895
|
+
}
|
|
1896
|
+
if (errors.length > errorCountBeforeGroup) {
|
|
1897
|
+
continue;
|
|
1898
|
+
}
|
|
1899
|
+
seenGroupSlugs.add(slug);
|
|
1900
|
+
groups.push({
|
|
1901
|
+
slug,
|
|
1902
|
+
displayName,
|
|
1903
|
+
...(allowedTargetKinds ? { allowedTargetKinds } : {}),
|
|
1904
|
+
tags,
|
|
1905
|
+
});
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
return {
|
|
1909
|
+
groups,
|
|
1910
|
+
errors,
|
|
1911
|
+
};
|
|
1912
|
+
}
|
|
1591
1913
|
function resolveCatalogueEntries(rootDir, options = {}) {
|
|
1592
1914
|
const { files, errors: discoveryErrors } = walkCatalogueTree(rootDir);
|
|
1593
1915
|
if (discoveryErrors.length > 0) {
|
|
1594
1916
|
return {
|
|
1595
1917
|
apps: [],
|
|
1918
|
+
assetSpecs: [],
|
|
1596
1919
|
assets: [],
|
|
1597
1920
|
embeddedAssets: [],
|
|
1598
1921
|
assetPacks: [],
|
|
@@ -1605,6 +1928,7 @@ function resolveCatalogueEntries(rootDir, options = {}) {
|
|
|
1605
1928
|
if (rootCatalogue && hasNestedCatalogues && !isCatalogueMarker(rootCatalogue)) {
|
|
1606
1929
|
return {
|
|
1607
1930
|
apps: [],
|
|
1931
|
+
assetSpecs: [],
|
|
1608
1932
|
assets: [],
|
|
1609
1933
|
embeddedAssets: [],
|
|
1610
1934
|
assetPacks: [],
|
|
@@ -1615,13 +1939,15 @@ function resolveCatalogueEntries(rootDir, options = {}) {
|
|
|
1615
1939
|
};
|
|
1616
1940
|
}
|
|
1617
1941
|
const { tasks: appTasks, warnings: appWarnings, errors: appErrors } = buildAppTasks(rootDir, files, options);
|
|
1618
|
-
const { tasks:
|
|
1942
|
+
const { tasks: assetSpecTasks, warnings: assetSpecWarnings, errors: assetSpecErrors } = buildAssetSpecTasks(files);
|
|
1943
|
+
const { tasks: assetTasks, warnings: assetWarnings, errors: assetErrors } = buildAssetTasks(files, assetSpecTasks);
|
|
1619
1944
|
const { tasks: assetPackTasks, warnings: assetPackWarnings, errors: assetPackErrors } = buildAssetPackTasks(files);
|
|
1620
1945
|
const embeddedAssetTasks = appTasks.flatMap((task) => task.embeddedAssets);
|
|
1621
|
-
const warnings = [...appWarnings, ...assetWarnings, ...assetPackWarnings];
|
|
1622
|
-
const errors = [...appErrors, ...assetErrors, ...assetPackErrors];
|
|
1946
|
+
const warnings = [...appWarnings, ...assetSpecWarnings, ...assetWarnings, ...assetPackWarnings];
|
|
1947
|
+
const errors = [...appErrors, ...assetSpecErrors, ...assetErrors, ...assetPackErrors];
|
|
1623
1948
|
return {
|
|
1624
1949
|
apps: appTasks,
|
|
1950
|
+
assetSpecs: assetSpecTasks,
|
|
1625
1951
|
assets: assetTasks,
|
|
1626
1952
|
embeddedAssets: embeddedAssetTasks,
|
|
1627
1953
|
assetPacks: assetPackTasks,
|
package/dist/clientInfo.js
CHANGED
|
@@ -9,7 +9,23 @@ exports.getCliVersion = getCliVersion;
|
|
|
9
9
|
exports.getCliBuild = getCliBuild;
|
|
10
10
|
exports.getRuntimeInfo = getRuntimeInfo;
|
|
11
11
|
const os_1 = __importDefault(require("os"));
|
|
12
|
+
const path_1 = __importDefault(require("path"));
|
|
13
|
+
const fs_1 = require("fs");
|
|
12
14
|
const config_1 = require("@playdrop/config");
|
|
15
|
+
let cachedCliPackageVersion = null;
|
|
16
|
+
function readCliPackageVersion() {
|
|
17
|
+
if (cachedCliPackageVersion) {
|
|
18
|
+
return cachedCliPackageVersion;
|
|
19
|
+
}
|
|
20
|
+
const packageJsonPath = path_1.default.resolve(__dirname, '..', 'package.json');
|
|
21
|
+
const packageJson = JSON.parse((0, fs_1.readFileSync)(packageJsonPath, 'utf8'));
|
|
22
|
+
const version = typeof packageJson.version === 'string' ? packageJson.version.trim() : '';
|
|
23
|
+
if (!/^\d+\.\d+\.\d+$/.test(version)) {
|
|
24
|
+
throw new Error(`invalid_cli_package_version:${version}`);
|
|
25
|
+
}
|
|
26
|
+
cachedCliPackageVersion = version;
|
|
27
|
+
return version;
|
|
28
|
+
}
|
|
13
29
|
function mapPlatform(platform) {
|
|
14
30
|
switch (platform) {
|
|
15
31
|
case 'aix':
|
|
@@ -42,7 +58,7 @@ function detectPlatformVersion() {
|
|
|
42
58
|
function buildRuntimeInfo() {
|
|
43
59
|
return {
|
|
44
60
|
client: 'cli',
|
|
45
|
-
clientVersion: (
|
|
61
|
+
clientVersion: readCliPackageVersion(),
|
|
46
62
|
clientBuild: (0, config_1.getClientBuild)(),
|
|
47
63
|
platform: mapPlatform(os_1.default.platform()),
|
|
48
64
|
platformVersion: detectPlatformVersion()
|
|
@@ -52,10 +68,10 @@ function createClientHeaders() {
|
|
|
52
68
|
return (0, config_1.createClientHeaderRecord)(buildRuntimeInfo());
|
|
53
69
|
}
|
|
54
70
|
function getCliVersionLabel() {
|
|
55
|
-
return (0, config_1.
|
|
71
|
+
return `${readCliPackageVersion()} (build ${(0, config_1.getClientBuild)()})`;
|
|
56
72
|
}
|
|
57
73
|
function getCliVersion() {
|
|
58
|
-
return (
|
|
74
|
+
return readCliPackageVersion();
|
|
59
75
|
}
|
|
60
76
|
function getCliBuild() {
|
|
61
77
|
return (0, config_1.getClientBuild)();
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
type AdsCommandOptions = {
|
|
2
|
+
app?: string;
|
|
3
|
+
days?: string | number;
|
|
4
|
+
json?: boolean;
|
|
5
|
+
};
|
|
6
|
+
export declare function showAdsEarnings(options?: AdsCommandOptions): Promise<void>;
|
|
7
|
+
export declare function showAdsReport(options?: AdsCommandOptions): Promise<void>;
|
|
8
|
+
export {};
|