@trops/dash-core 0.1.230 → 0.1.232

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.
@@ -32258,74 +32258,97 @@ async function installThemeFromRegistry$1(win, appId, packageName) {
32258
32258
  };
32259
32259
  }
32260
32260
 
32261
- // Check if the response is actually a ZIP (not an HTML error page or JSON error)
32262
- if (
32263
- contentType.includes("text/html") ||
32264
- contentType.includes("application/json")
32265
- ) {
32261
+ // Reject HTML error pages
32262
+ if (contentType.includes("text/html")) {
32266
32263
  const body = zipBuffer.toString("utf-8").slice(0, 200);
32267
- console.log(
32268
- `${TAG} [3/5 Download] FAIL — unexpected content type "${contentType}": ${body}`,
32269
- );
32264
+ console.log(`${TAG} [3/5 Download] FAIL — HTML response: ${body}`);
32270
32265
  return {
32271
32266
  success: false,
32272
- error: `Download failed: registry returned ${contentType} instead of a ZIP file. The download URL may be incorrect.`,
32267
+ error: `Download failed: registry returned an HTML page instead of theme data.`,
32273
32268
  };
32274
32269
  }
32275
32270
 
32276
- // Stage 4: ZIP extraction
32277
- let zip;
32278
- try {
32279
- zip = new AdmZip$1(zipBuffer);
32280
- } catch (zipErr) {
32281
- console.log(
32282
- `${TAG} [4/5 ZIP Extraction] FAIL — invalid ZIP: ${zipErr.message}`,
32283
- );
32284
- return {
32285
- success: false,
32286
- error: `ZIP extraction failed: the downloaded file is not a valid ZIP archive (${zipErr.message}).`,
32287
- };
32288
- }
32289
- const entries = zip.getEntries();
32290
- const entryNames = entries.map((e) => e.entryName);
32291
- const themeEntry = entries.find((entry) =>
32292
- entry.entryName.endsWith(".theme.json"),
32293
- );
32294
- console.log(
32295
- `${TAG} [4/5 ZIP Extraction] files=[${entryNames.join(", ")}] hasThemeJson=${!!themeEntry}`,
32296
- );
32271
+ // Stage 4: Extract theme data (JSON or ZIP)
32272
+ let themeData;
32297
32273
 
32298
- if (!themeEntry) {
32274
+ if (contentType.includes("application/json")) {
32275
+ // Registry served theme data as JSON directly — parse and use it
32276
+ console.log(`${TAG} [4/5 Extract] JSON response — parsing directly`);
32277
+ let jsonData;
32278
+ try {
32279
+ jsonData = JSON.parse(zipBuffer.toString("utf-8"));
32280
+ } catch (parseErr) {
32281
+ return {
32282
+ success: false,
32283
+ error: `Download failed: registry returned invalid JSON (${parseErr.message}).`,
32284
+ };
32285
+ }
32286
+ if (jsonData.error) {
32287
+ console.log(
32288
+ `${TAG} [4/5 Extract] FAIL — JSON error: ${jsonData.error}`,
32289
+ );
32290
+ return {
32291
+ success: false,
32292
+ error: `Download failed: ${jsonData.error}`,
32293
+ };
32294
+ }
32295
+ // The response may be raw theme data, or wrapped in a data/theme key
32296
+ themeData = jsonData.data || jsonData.theme || jsonData;
32297
+ } else {
32298
+ // ZIP response — extract .theme.json from archive
32299
+ let zip;
32300
+ try {
32301
+ zip = new AdmZip$1(zipBuffer);
32302
+ } catch (zipErr) {
32303
+ console.log(
32304
+ `${TAG} [4/5 ZIP Extraction] FAIL — invalid ZIP: ${zipErr.message}`,
32305
+ );
32306
+ return {
32307
+ success: false,
32308
+ error: `ZIP extraction failed: the downloaded file is not a valid ZIP archive (${zipErr.message}).`,
32309
+ };
32310
+ }
32311
+ const entries = zip.getEntries();
32312
+ const entryNames = entries.map((e) => e.entryName);
32313
+ const themeEntry = entries.find((entry) =>
32314
+ entry.entryName.endsWith(".theme.json"),
32315
+ );
32299
32316
  console.log(
32300
- `${TAG} [4/5 ZIP Extraction] FAIL — no .theme.json in archive`,
32317
+ `${TAG} [4/5 ZIP Extraction] files=[${entryNames.join(", ")}] hasThemeJson=${!!themeEntry}`,
32301
32318
  );
32302
- return {
32303
- success: false,
32304
- error: `ZIP extraction failed: no .theme.json file found in archive. Files present: [${entryNames.join(", ")}]`,
32305
- };
32306
- }
32307
32319
 
32308
- // Validate entry path (security: prevent path traversal)
32309
- if (
32310
- themeEntry.entryName.includes("..") ||
32311
- path$2.isAbsolute(themeEntry.entryName)
32312
- ) {
32313
- return {
32314
- success: false,
32315
- error: "ZIP extraction failed: invalid file path detected in archive.",
32316
- };
32317
- }
32320
+ if (!themeEntry) {
32321
+ console.log(
32322
+ `${TAG} [4/5 ZIP Extraction] FAIL — no .theme.json in archive`,
32323
+ );
32324
+ return {
32325
+ success: false,
32326
+ error: `ZIP extraction failed: no .theme.json file found in archive. Files present: [${entryNames.join(", ")}]`,
32327
+ };
32328
+ }
32318
32329
 
32319
- // Parse theme data
32320
- const themeJson = themeEntry.getData().toString("utf-8");
32321
- let themeData;
32322
- try {
32323
- themeData = JSON.parse(themeJson);
32324
- } catch (parseErr) {
32325
- return {
32326
- success: false,
32327
- error: `ZIP extraction failed: ${themeEntry.entryName} contains invalid JSON (${parseErr.message}).`,
32328
- };
32330
+ // Validate entry path (security: prevent path traversal)
32331
+ if (
32332
+ themeEntry.entryName.includes("..") ||
32333
+ path$2.isAbsolute(themeEntry.entryName)
32334
+ ) {
32335
+ return {
32336
+ success: false,
32337
+ error:
32338
+ "ZIP extraction failed: invalid file path detected in archive.",
32339
+ };
32340
+ }
32341
+
32342
+ // Parse theme data from ZIP entry
32343
+ const themeJson = themeEntry.getData().toString("utf-8");
32344
+ try {
32345
+ themeData = JSON.parse(themeJson);
32346
+ } catch (parseErr) {
32347
+ return {
32348
+ success: false,
32349
+ error: `ZIP extraction failed: ${themeEntry.entryName} contains invalid JSON (${parseErr.message}).`,
32350
+ };
32351
+ }
32329
32352
  }
32330
32353
 
32331
32354
  // Add registry metadata