@character-foundry/character-foundry 0.4.1 → 0.4.2-dev.1765997746
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/charx.cjs +17 -38
- package/dist/charx.cjs.map +1 -1
- package/dist/charx.d.cts +27 -18
- package/dist/charx.d.ts +27 -18
- package/dist/charx.js +17 -38
- package/dist/charx.js.map +1 -1
- package/dist/exporter.cjs +36 -40
- package/dist/exporter.cjs.map +1 -1
- package/dist/exporter.d.cts +27 -18
- package/dist/exporter.d.ts +27 -18
- package/dist/exporter.js +36 -40
- package/dist/exporter.js.map +1 -1
- package/dist/federation.cjs +104 -36
- package/dist/federation.cjs.map +1 -1
- package/dist/federation.d.cts +62 -18
- package/dist/federation.d.ts +62 -18
- package/dist/federation.js +104 -36
- package/dist/federation.js.map +1 -1
- package/dist/index.cjs +36 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +63 -42
- package/dist/index.d.ts +63 -42
- package/dist/index.js +36 -40
- package/dist/index.js.map +1 -1
- package/dist/loader.cjs +103 -17
- package/dist/loader.cjs.map +1 -1
- package/dist/loader.d.cts +56 -28
- package/dist/loader.d.ts +56 -28
- package/dist/loader.js +103 -17
- package/dist/loader.js.map +1 -1
- package/dist/lorebook.d.cts +51 -34
- package/dist/lorebook.d.ts +51 -34
- package/dist/normalizer.cjs +4 -4
- package/dist/normalizer.cjs.map +1 -1
- package/dist/normalizer.d.cts +90 -60
- package/dist/normalizer.d.ts +90 -60
- package/dist/normalizer.js +4 -4
- package/dist/normalizer.js.map +1 -1
- package/dist/png.cjs +4 -4
- package/dist/png.cjs.map +1 -1
- package/dist/png.d.cts +48 -32
- package/dist/png.d.ts +48 -32
- package/dist/png.js +4 -4
- package/dist/png.js.map +1 -1
- package/dist/schemas.cjs +9 -9
- package/dist/schemas.cjs.map +1 -1
- package/dist/schemas.d.cts +144 -96
- package/dist/schemas.d.ts +144 -96
- package/dist/schemas.js +9 -9
- package/dist/schemas.js.map +1 -1
- package/dist/voxta.cjs +23 -6
- package/dist/voxta.cjs.map +1 -1
- package/dist/voxta.d.cts +42 -28
- package/dist/voxta.d.ts +42 -28
- package/dist/voxta.js +23 -6
- package/dist/voxta.js.map +1 -1
- package/package.json +6 -6
package/dist/exporter.cjs
CHANGED
|
@@ -265,7 +265,7 @@ var CCv2LorebookEntrySchema = import_zod2.z.object({
|
|
|
265
265
|
content: import_zod2.z.string(),
|
|
266
266
|
enabled: import_zod2.z.boolean().default(true),
|
|
267
267
|
// Default to enabled if missing
|
|
268
|
-
insertion_order: import_zod2.z.
|
|
268
|
+
insertion_order: import_zod2.z.preprocess((v) => v ?? 0, import_zod2.z.number().int()),
|
|
269
269
|
// Optional fields - be lenient with nulls since wild data has them
|
|
270
270
|
extensions: import_zod2.z.record(import_zod2.z.unknown()).optional(),
|
|
271
271
|
case_sensitive: import_zod2.z.boolean().nullable().optional(),
|
|
@@ -276,7 +276,7 @@ var CCv2LorebookEntrySchema = import_zod2.z.object({
|
|
|
276
276
|
selective: import_zod2.z.boolean().nullable().optional(),
|
|
277
277
|
secondary_keys: import_zod2.z.array(import_zod2.z.string()).nullable().optional(),
|
|
278
278
|
constant: import_zod2.z.boolean().nullable().optional(),
|
|
279
|
-
position: import_zod2.z.union([import_zod2.z.enum(["before_char", "after_char"]), import_zod2.z.number().int(), import_zod2.z.literal("")]).nullable().optional()
|
|
279
|
+
position: import_zod2.z.union([import_zod2.z.enum(["before_char", "after_char", "in_chat"]), import_zod2.z.number().int(), import_zod2.z.literal("")]).nullable().optional()
|
|
280
280
|
}).passthrough();
|
|
281
281
|
var CCv2CharacterBookSchema = import_zod2.z.object({
|
|
282
282
|
name: import_zod2.z.string().optional(),
|
|
@@ -319,7 +319,7 @@ var CCv3LorebookEntrySchema = import_zod3.z.object({
|
|
|
319
319
|
content: import_zod3.z.string(),
|
|
320
320
|
enabled: import_zod3.z.boolean().default(true),
|
|
321
321
|
// Default to enabled if missing
|
|
322
|
-
insertion_order: import_zod3.z.
|
|
322
|
+
insertion_order: import_zod3.z.preprocess((v) => v ?? 0, import_zod3.z.number().int()),
|
|
323
323
|
// Optional fields - be lenient with nulls since wild data has them
|
|
324
324
|
case_sensitive: import_zod3.z.boolean().nullable().optional(),
|
|
325
325
|
name: import_zod3.z.string().optional(),
|
|
@@ -329,7 +329,7 @@ var CCv3LorebookEntrySchema = import_zod3.z.object({
|
|
|
329
329
|
selective: import_zod3.z.boolean().nullable().optional(),
|
|
330
330
|
secondary_keys: import_zod3.z.array(import_zod3.z.string()).nullable().optional(),
|
|
331
331
|
constant: import_zod3.z.boolean().nullable().optional(),
|
|
332
|
-
position: import_zod3.z.union([import_zod3.z.enum(["before_char", "after_char"]), import_zod3.z.number().int(), import_zod3.z.literal("")]).nullable().optional(),
|
|
332
|
+
position: import_zod3.z.union([import_zod3.z.enum(["before_char", "after_char", "in_chat"]), import_zod3.z.number().int(), import_zod3.z.literal("")]).nullable().optional(),
|
|
333
333
|
extensions: import_zod3.z.record(import_zod3.z.unknown()).optional(),
|
|
334
334
|
// v3 specific - also lenient with types since SillyTavern uses numbers for enums
|
|
335
335
|
automation_id: import_zod3.z.string().optional(),
|
|
@@ -546,36 +546,6 @@ var SAFE_ASSET_TYPES = /* @__PURE__ */ new Set([
|
|
|
546
546
|
"data",
|
|
547
547
|
"unknown"
|
|
548
548
|
]);
|
|
549
|
-
var SAFE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
550
|
-
// Images
|
|
551
|
-
"png",
|
|
552
|
-
"jpg",
|
|
553
|
-
"jpeg",
|
|
554
|
-
"webp",
|
|
555
|
-
"gif",
|
|
556
|
-
"avif",
|
|
557
|
-
"svg",
|
|
558
|
-
"bmp",
|
|
559
|
-
"ico",
|
|
560
|
-
// Audio
|
|
561
|
-
"mp3",
|
|
562
|
-
"wav",
|
|
563
|
-
"ogg",
|
|
564
|
-
"flac",
|
|
565
|
-
"m4a",
|
|
566
|
-
"aac",
|
|
567
|
-
"opus",
|
|
568
|
-
// Video
|
|
569
|
-
"mp4",
|
|
570
|
-
"webm",
|
|
571
|
-
"avi",
|
|
572
|
-
"mov",
|
|
573
|
-
"mkv",
|
|
574
|
-
// Data
|
|
575
|
-
"json",
|
|
576
|
-
"txt",
|
|
577
|
-
"bin"
|
|
578
|
-
]);
|
|
579
549
|
function getCharxCategory(mimetype) {
|
|
580
550
|
if (mimetype.startsWith("image/")) return "images";
|
|
581
551
|
if (mimetype.startsWith("audio/")) return "audio";
|
|
@@ -591,11 +561,20 @@ function sanitizeAssetType(type) {
|
|
|
591
561
|
return sanitized || "custom";
|
|
592
562
|
}
|
|
593
563
|
function sanitizeExtension(ext) {
|
|
594
|
-
const normalized = ext.replace(/^\./, "").toLowerCase()
|
|
595
|
-
if (
|
|
596
|
-
|
|
564
|
+
const normalized = ext.trim().replace(/^\./, "").toLowerCase();
|
|
565
|
+
if (!normalized) {
|
|
566
|
+
throw new Error("Invalid asset extension: empty extension");
|
|
567
|
+
}
|
|
568
|
+
if (normalized.length > 64) {
|
|
569
|
+
throw new Error(`Invalid asset extension: too long (${normalized.length} chars)`);
|
|
570
|
+
}
|
|
571
|
+
if (normalized.includes("/") || normalized.includes("\\") || normalized.includes("\0")) {
|
|
572
|
+
throw new Error("Invalid asset extension: path separators are not allowed");
|
|
573
|
+
}
|
|
574
|
+
if (!/^[a-z0-9][a-z0-9._-]*$/.test(normalized)) {
|
|
575
|
+
throw new Error(`Invalid asset extension: "${ext}"`);
|
|
597
576
|
}
|
|
598
|
-
return
|
|
577
|
+
return normalized;
|
|
599
578
|
}
|
|
600
579
|
function sanitizeName(name, ext) {
|
|
601
580
|
let safeName = name;
|
|
@@ -7046,6 +7025,22 @@ function sanitizeName2(name, ext) {
|
|
|
7046
7025
|
if (!safeName) safeName = "asset";
|
|
7047
7026
|
return safeName;
|
|
7048
7027
|
}
|
|
7028
|
+
function sanitizeExtension2(ext) {
|
|
7029
|
+
const normalized = ext.trim().replace(/^\./, "").toLowerCase();
|
|
7030
|
+
if (!normalized) {
|
|
7031
|
+
throw new Error("Invalid asset extension: empty extension");
|
|
7032
|
+
}
|
|
7033
|
+
if (normalized.length > 64) {
|
|
7034
|
+
throw new Error(`Invalid asset extension: too long (${normalized.length} chars)`);
|
|
7035
|
+
}
|
|
7036
|
+
if (normalized.includes("/") || normalized.includes("\\") || normalized.includes("\0")) {
|
|
7037
|
+
throw new Error("Invalid asset extension: path separators are not allowed");
|
|
7038
|
+
}
|
|
7039
|
+
if (!/^[a-z0-9][a-z0-9._-]*$/.test(normalized)) {
|
|
7040
|
+
throw new Error(`Invalid asset extension: "${ext}"`);
|
|
7041
|
+
}
|
|
7042
|
+
return normalized;
|
|
7043
|
+
}
|
|
7049
7044
|
function writeVoxta(card, assets, options = {}) {
|
|
7050
7045
|
const { compressionLevel = 6, includePackageJson = false } = options;
|
|
7051
7046
|
const cardData = card.data;
|
|
@@ -7134,8 +7129,9 @@ function writeVoxta(card, assets, options = {}) {
|
|
|
7134
7129
|
let assetCount = 0;
|
|
7135
7130
|
let mainThumbnail;
|
|
7136
7131
|
for (const asset of assets) {
|
|
7137
|
-
const
|
|
7138
|
-
const
|
|
7132
|
+
const safeExt = sanitizeExtension2(asset.ext);
|
|
7133
|
+
const safeName = sanitizeName2(asset.name, safeExt);
|
|
7134
|
+
const finalFilename = `${safeName}.${safeExt}`;
|
|
7139
7135
|
let voxtaPath = "";
|
|
7140
7136
|
const tags = asset.tags || [];
|
|
7141
7137
|
const isMainIcon = asset.type === "icon" && (tags.includes("portrait-override") || asset.name === "main" || asset.isMain);
|