@character-foundry/character-foundry 0.1.8 → 0.1.9-dev.1765913722

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/dist/index.js CHANGED
@@ -104,7 +104,23 @@ function streamingUnzipSync(data, limits = DEFAULT_ZIP_LIMITS) {
104
104
  if (unsafePathHandling === "warn" && limits.onUnsafePath) {
105
105
  limits.onUnsafePath(file.name, reason);
106
106
  }
107
- file.ondata = () => {
107
+ file.ondata = (err, chunk, _final) => {
108
+ if (error) return;
109
+ if (err) {
110
+ error = err;
111
+ return;
112
+ }
113
+ if (chunk && chunk.length > 0) {
114
+ totalBytes += chunk.length;
115
+ if (totalBytes > limits.maxTotalSize) {
116
+ error = new ZipPreflightError(
117
+ `Total actual size ${totalBytes} exceeds limit ${limits.maxTotalSize}`,
118
+ totalBytes,
119
+ limits.maxTotalSize
120
+ );
121
+ file.terminate();
122
+ }
123
+ }
108
124
  };
109
125
  file.start();
110
126
  return;
@@ -8507,6 +8523,43 @@ var DEFAULT_OPTIONS3 = {
8507
8523
  maxTotalSize: 500 * 1024 * 1024,
8508
8524
  extractAssets: true
8509
8525
  };
8526
+ var ASSET_PREFIX_VARIANTS = [
8527
+ { prefix: "__asset:", format: "CCv3 (SillyTavern)" },
8528
+ { prefix: "asset:", format: "CCv2/CCv3 common" },
8529
+ { prefix: "pngchunk:", format: "Explicit PNG chunk" },
8530
+ { prefix: "chara-ext-asset_:", format: "RisuAI (with colon)" },
8531
+ { prefix: "chara-ext-asset_", format: "RisuAI" },
8532
+ { prefix: "__asset_", format: "Legacy underscore variant" }
8533
+ ];
8534
+ function isChunkReference(uri) {
8535
+ return ASSET_PREFIX_VARIANTS.some(({ prefix }) => uri.startsWith(prefix)) || !uri.includes(":");
8536
+ }
8537
+ function stripAssetPrefix(uri) {
8538
+ for (const { prefix } of ASSET_PREFIX_VARIANTS) {
8539
+ if (uri.startsWith(prefix)) {
8540
+ return uri.substring(prefix.length);
8541
+ }
8542
+ }
8543
+ return uri;
8544
+ }
8545
+ function generateChunkKeyCandidates(assetId, originalUri) {
8546
+ return [
8547
+ assetId,
8548
+ // Plain ID: "0"
8549
+ originalUri,
8550
+ // Original URI: "__asset:0"
8551
+ `asset:${assetId}`,
8552
+ // Common format
8553
+ `__asset:${assetId}`,
8554
+ // CCv3 format
8555
+ `__asset_${assetId}`,
8556
+ // Legacy underscore variant
8557
+ `chara-ext-asset_${assetId}`,
8558
+ // RisuAI format
8559
+ `chara-ext-asset_:${assetId}`
8560
+ // RisuAI format with colon
8561
+ ];
8562
+ }
8510
8563
  function estimateBase64DecodedSize(base64Length) {
8511
8564
  return Math.ceil(base64Length * 0.75);
8512
8565
  }
@@ -8574,39 +8627,22 @@ function parsePng(data, options) {
8574
8627
  if (extracted.extraChunks && options.extractAssets && card.data.assets) {
8575
8628
  const usedChunks = /* @__PURE__ */ new Set();
8576
8629
  const chunkMap = /* @__PURE__ */ new Map();
8630
+ const risuIndexPrefixes = ASSET_PREFIX_VARIANTS.filter((v) => v.prefix.startsWith("chara-ext-asset_"));
8577
8631
  for (const chunk of extracted.extraChunks) {
8578
8632
  chunkMap.set(chunk.keyword, chunk);
8579
- if (chunk.keyword.startsWith("chara-ext-asset_")) {
8580
- const suffix = chunk.keyword.replace("chara-ext-asset_", "");
8581
- chunkMap.set(suffix, chunk);
8582
- if (suffix.startsWith(":")) {
8583
- chunkMap.set(suffix.substring(1), chunk);
8633
+ for (const { prefix } of risuIndexPrefixes) {
8634
+ if (chunk.keyword.startsWith(prefix)) {
8635
+ const suffix = chunk.keyword.substring(prefix.length);
8636
+ chunkMap.set(suffix, chunk);
8637
+ break;
8584
8638
  }
8585
8639
  }
8586
8640
  }
8587
8641
  for (const descriptor of card.data.assets) {
8588
8642
  if (!descriptor.uri) continue;
8589
- if (descriptor.uri.startsWith("__asset:") || descriptor.uri.startsWith("asset:") || descriptor.uri.startsWith("pngchunk:") || !descriptor.uri.includes(":")) {
8590
- let assetId = descriptor.uri;
8591
- if (assetId.startsWith("__asset:")) assetId = assetId.substring(8);
8592
- else if (assetId.startsWith("asset:")) assetId = assetId.substring(6);
8593
- else if (assetId.startsWith("pngchunk:")) assetId = assetId.substring(9);
8594
- const candidates = [
8595
- assetId,
8596
- // "0"
8597
- descriptor.uri,
8598
- // "__asset:0"
8599
- `asset:${assetId}`,
8600
- // "asset:0"
8601
- `__asset:${assetId}`,
8602
- // "__asset:0"
8603
- `__asset_${assetId}`,
8604
- // "__asset_0"
8605
- `chara-ext-asset_${assetId}`,
8606
- // "chara-ext-asset_0"
8607
- `chara-ext-asset_:${assetId}`
8608
- // "chara-ext-asset_:0"
8609
- ];
8643
+ if (isChunkReference(descriptor.uri)) {
8644
+ const assetId = stripAssetPrefix(descriptor.uri);
8645
+ const candidates = generateChunkKeyCandidates(assetId, descriptor.uri);
8610
8646
  let chunk;
8611
8647
  for (const candidate of candidates) {
8612
8648
  chunk = chunkMap.get(candidate);
@@ -8653,13 +8689,15 @@ function parsePng(data, options) {
8653
8689
  }
8654
8690
  }
8655
8691
  }
8692
+ const risuPrefixes = ASSET_PREFIX_VARIANTS.filter((v) => v.prefix.startsWith("chara-ext-asset_"));
8656
8693
  for (const chunk of extracted.extraChunks) {
8657
8694
  if (!usedChunks.has(chunk.keyword)) {
8658
8695
  let assetId = null;
8659
- if (chunk.keyword.startsWith("chara-ext-asset_:")) {
8660
- assetId = chunk.keyword.substring("chara-ext-asset_:".length);
8661
- } else if (chunk.keyword.startsWith("chara-ext-asset_")) {
8662
- assetId = chunk.keyword.substring("chara-ext-asset_".length);
8696
+ for (const { prefix } of risuPrefixes) {
8697
+ if (chunk.keyword.startsWith(prefix)) {
8698
+ assetId = chunk.keyword.substring(prefix.length);
8699
+ break;
8700
+ }
8663
8701
  }
8664
8702
  if (assetId) {
8665
8703
  try {