@character-foundry/character-foundry 0.1.5 → 0.1.7
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/app-framework.cjs +143 -26
- package/dist/app-framework.cjs.map +1 -1
- package/dist/app-framework.d.cts +16 -1
- package/dist/app-framework.d.ts +16 -1
- package/dist/app-framework.js +151 -34
- package/dist/app-framework.js.map +1 -1
- package/dist/charx.cjs +70 -8
- package/dist/charx.cjs.map +1 -1
- package/dist/charx.js +70 -8
- package/dist/charx.js.map +1 -1
- package/dist/core.cjs +93 -6
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +42 -1
- package/dist/core.d.ts +42 -1
- package/dist/core.js +93 -6
- package/dist/core.js.map +1 -1
- package/dist/exporter.cjs +88 -8
- package/dist/exporter.cjs.map +1 -1
- package/dist/exporter.js +89 -9
- package/dist/exporter.js.map +1 -1
- package/dist/federation.cjs +1 -0
- package/dist/federation.cjs.map +1 -1
- package/dist/federation.js +1 -0
- package/dist/federation.js.map +1 -1
- package/dist/image-utils.cjs +249 -0
- package/dist/image-utils.cjs.map +1 -0
- package/dist/image-utils.d.cts +136 -0
- package/dist/image-utils.d.ts +136 -0
- package/dist/image-utils.js +226 -0
- package/dist/image-utils.js.map +1 -0
- package/dist/index.cjs +122 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +123 -19
- package/dist/index.js.map +1 -1
- package/dist/loader.cjs +42 -14
- package/dist/loader.cjs.map +1 -1
- package/dist/loader.js +43 -15
- package/dist/loader.js.map +1 -1
- package/dist/lorebook.cjs +1 -0
- package/dist/lorebook.cjs.map +1 -1
- package/dist/lorebook.js +1 -0
- package/dist/lorebook.js.map +1 -1
- package/dist/media.cjs +1 -0
- package/dist/media.cjs.map +1 -1
- package/dist/media.js +1 -0
- package/dist/media.js.map +1 -1
- package/dist/normalizer.cjs +1 -0
- package/dist/normalizer.cjs.map +1 -1
- package/dist/normalizer.d.cts +1 -0
- package/dist/normalizer.d.ts +1 -0
- package/dist/normalizer.js +1 -0
- package/dist/normalizer.js.map +1 -1
- package/dist/png.cjs +19 -0
- package/dist/png.cjs.map +1 -1
- package/dist/png.js +19 -0
- package/dist/png.js.map +1 -1
- package/dist/schemas.cjs +80 -0
- package/dist/schemas.cjs.map +1 -1
- package/dist/schemas.d.cts +30 -0
- package/dist/schemas.d.ts +30 -0
- package/dist/schemas.js +80 -0
- package/dist/schemas.js.map +1 -1
- package/dist/voxta.cjs +14 -102
- package/dist/voxta.cjs.map +1 -1
- package/dist/voxta.js +15 -103
- package/dist/voxta.js.map +1 -1
- package/package.json +16 -5
package/dist/exporter.js
CHANGED
|
@@ -49,10 +49,14 @@ function alloc(size) {
|
|
|
49
49
|
return new Uint8Array(size);
|
|
50
50
|
}
|
|
51
51
|
var isNode = typeof process !== "undefined" && process.versions != null && process.versions.node != null;
|
|
52
|
+
var LARGE_BUFFER_THRESHOLD = 1024 * 1024;
|
|
52
53
|
function encode(data) {
|
|
53
54
|
if (isNode) {
|
|
54
55
|
return Buffer.from(data).toString("base64");
|
|
55
56
|
}
|
|
57
|
+
if (data.length > LARGE_BUFFER_THRESHOLD) {
|
|
58
|
+
return encodeChunked(data);
|
|
59
|
+
}
|
|
56
60
|
let binary = "";
|
|
57
61
|
for (let i = 0; i < data.length; i++) {
|
|
58
62
|
binary += String.fromCharCode(data[i]);
|
|
@@ -60,6 +64,21 @@ function encode(data) {
|
|
|
60
64
|
return btoa(binary);
|
|
61
65
|
}
|
|
62
66
|
var ENCODE_CHUNK_SIZE = 64 * 1024;
|
|
67
|
+
function encodeChunked(data) {
|
|
68
|
+
if (isNode) {
|
|
69
|
+
return Buffer.from(data).toString("base64");
|
|
70
|
+
}
|
|
71
|
+
const chunks = [];
|
|
72
|
+
for (let i = 0; i < data.length; i += ENCODE_CHUNK_SIZE) {
|
|
73
|
+
const chunk = data.subarray(i, Math.min(i + ENCODE_CHUNK_SIZE, data.length));
|
|
74
|
+
let binary = "";
|
|
75
|
+
for (let j = 0; j < chunk.length; j++) {
|
|
76
|
+
binary += String.fromCharCode(chunk[j]);
|
|
77
|
+
}
|
|
78
|
+
chunks.push(binary);
|
|
79
|
+
}
|
|
80
|
+
return btoa(chunks.join(""));
|
|
81
|
+
}
|
|
63
82
|
var FOUNDRY_ERROR_MARKER = /* @__PURE__ */ Symbol.for("@character-foundry/core:FoundryError");
|
|
64
83
|
var FoundryError = class extends Error {
|
|
65
84
|
constructor(message, code) {
|
|
@@ -478,12 +497,69 @@ var DEFAULT_OPTIONS = {
|
|
|
478
497
|
preserveXMeta: true,
|
|
479
498
|
preserveModuleRisum: true
|
|
480
499
|
};
|
|
500
|
+
var SAFE_ASSET_TYPES = /* @__PURE__ */ new Set([
|
|
501
|
+
"icon",
|
|
502
|
+
"user_icon",
|
|
503
|
+
"emotion",
|
|
504
|
+
"background",
|
|
505
|
+
"sound",
|
|
506
|
+
"video",
|
|
507
|
+
"custom",
|
|
508
|
+
"x-risu-asset",
|
|
509
|
+
"data",
|
|
510
|
+
"unknown"
|
|
511
|
+
]);
|
|
512
|
+
var SAFE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
513
|
+
// Images
|
|
514
|
+
"png",
|
|
515
|
+
"jpg",
|
|
516
|
+
"jpeg",
|
|
517
|
+
"webp",
|
|
518
|
+
"gif",
|
|
519
|
+
"avif",
|
|
520
|
+
"svg",
|
|
521
|
+
"bmp",
|
|
522
|
+
"ico",
|
|
523
|
+
// Audio
|
|
524
|
+
"mp3",
|
|
525
|
+
"wav",
|
|
526
|
+
"ogg",
|
|
527
|
+
"flac",
|
|
528
|
+
"m4a",
|
|
529
|
+
"aac",
|
|
530
|
+
"opus",
|
|
531
|
+
// Video
|
|
532
|
+
"mp4",
|
|
533
|
+
"webm",
|
|
534
|
+
"avi",
|
|
535
|
+
"mov",
|
|
536
|
+
"mkv",
|
|
537
|
+
// Data
|
|
538
|
+
"json",
|
|
539
|
+
"txt",
|
|
540
|
+
"bin"
|
|
541
|
+
]);
|
|
481
542
|
function getCharxCategory(mimetype) {
|
|
482
543
|
if (mimetype.startsWith("image/")) return "images";
|
|
483
544
|
if (mimetype.startsWith("audio/")) return "audio";
|
|
484
545
|
if (mimetype.startsWith("video/")) return "video";
|
|
485
546
|
return "other";
|
|
486
547
|
}
|
|
548
|
+
function sanitizeAssetType(type) {
|
|
549
|
+
const normalized = type.toLowerCase().replace(/[^a-z0-9-_]/g, "-");
|
|
550
|
+
if (SAFE_ASSET_TYPES.has(normalized)) {
|
|
551
|
+
return normalized;
|
|
552
|
+
}
|
|
553
|
+
const sanitized = normalized.replace(/[^a-z0-9]/g, "");
|
|
554
|
+
return sanitized || "custom";
|
|
555
|
+
}
|
|
556
|
+
function sanitizeExtension(ext) {
|
|
557
|
+
const normalized = ext.replace(/^\./, "").toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
558
|
+
if (SAFE_EXTENSIONS.has(normalized)) {
|
|
559
|
+
return normalized;
|
|
560
|
+
}
|
|
561
|
+
return "bin";
|
|
562
|
+
}
|
|
487
563
|
function sanitizeName(name, ext) {
|
|
488
564
|
let safeName = name;
|
|
489
565
|
if (safeName.toLowerCase().endsWith(`.${ext.toLowerCase()}`)) {
|
|
@@ -517,10 +593,12 @@ Import this file into SillyTavern, RisuAI, or other compatible applications.
|
|
|
517
593
|
let assetCount = 0;
|
|
518
594
|
for (let i = 0; i < assets.length; i++) {
|
|
519
595
|
const asset = assets[i];
|
|
520
|
-
const
|
|
596
|
+
const safeType = sanitizeAssetType(asset.type);
|
|
597
|
+
const safeExt = sanitizeExtension(asset.ext);
|
|
598
|
+
const mimetype = getMimeTypeFromExt(safeExt);
|
|
521
599
|
const category = getCharxCategory(mimetype);
|
|
522
|
-
const safeName = sanitizeName(asset.name,
|
|
523
|
-
const assetPath = `assets/${
|
|
600
|
+
const safeName = sanitizeName(asset.name, safeExt);
|
|
601
|
+
const assetPath = `assets/${safeType}/${category}/${safeName}.${safeExt}`;
|
|
524
602
|
zipEntries[assetPath] = [asset.data, { level: compressionLevel }];
|
|
525
603
|
assetCount++;
|
|
526
604
|
if (emitXMeta && mimetype.startsWith("image/")) {
|
|
@@ -541,16 +619,18 @@ Import this file into SillyTavern, RisuAI, or other compatible applications.
|
|
|
541
619
|
};
|
|
542
620
|
}
|
|
543
621
|
function transformAssetUris(card, assets) {
|
|
544
|
-
const transformed = JSON.parse(JSON.stringify(card));
|
|
622
|
+
const transformed = typeof structuredClone === "function" ? structuredClone(card) : JSON.parse(JSON.stringify(card));
|
|
545
623
|
transformed.data.assets = assets.map((asset) => {
|
|
546
|
-
const
|
|
624
|
+
const safeType = sanitizeAssetType(asset.type);
|
|
625
|
+
const safeExt = sanitizeExtension(asset.ext);
|
|
626
|
+
const mimetype = getMimeTypeFromExt(safeExt);
|
|
547
627
|
const category = getCharxCategory(mimetype);
|
|
548
|
-
const safeName = sanitizeName(asset.name,
|
|
628
|
+
const safeName = sanitizeName(asset.name, safeExt);
|
|
549
629
|
return {
|
|
550
630
|
type: asset.type,
|
|
551
|
-
uri: `embeded://assets/${
|
|
631
|
+
uri: `embeded://assets/${safeType}/${category}/${safeName}.${safeExt}`,
|
|
552
632
|
name: safeName,
|
|
553
|
-
ext:
|
|
633
|
+
ext: safeExt
|
|
554
634
|
};
|
|
555
635
|
});
|
|
556
636
|
return transformed;
|
|
@@ -6877,7 +6957,7 @@ function getExtension(format) {
|
|
|
6877
6957
|
}
|
|
6878
6958
|
|
|
6879
6959
|
// ../voxta/dist/index.js
|
|
6880
|
-
import {
|
|
6960
|
+
import { zipSync as zipSync22 } from "fflate";
|
|
6881
6961
|
var DEFAULT_OPTIONS2 = {
|
|
6882
6962
|
maxFileSize: 50 * 1024 * 1024,
|
|
6883
6963
|
// 50MB
|