@character-foundry/character-foundry 0.4.2 → 0.4.3-dev.1766103111
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 +87 -54
- package/dist/charx.cjs.map +1 -1
- package/dist/charx.d.cts +40 -31
- package/dist/charx.d.ts +40 -31
- package/dist/charx.js +87 -54
- package/dist/charx.js.map +1 -1
- package/dist/exporter.cjs +106 -56
- package/dist/exporter.cjs.map +1 -1
- package/dist/exporter.d.cts +37 -28
- package/dist/exporter.d.ts +37 -28
- package/dist/exporter.js +106 -56
- 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 +72 -28
- package/dist/federation.d.ts +72 -28
- package/dist/federation.js +104 -36
- package/dist/federation.js.map +1 -1
- package/dist/index.cjs +106 -56
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +71 -50
- package/dist/index.d.ts +71 -50
- package/dist/index.js +106 -56
- package/dist/index.js.map +1 -1
- package/dist/loader.cjs +173 -33
- package/dist/loader.cjs.map +1 -1
- package/dist/loader.d.cts +65 -37
- package/dist/loader.d.ts +65 -37
- package/dist/loader.js +173 -33
- package/dist/loader.js.map +1 -1
- package/dist/lorebook.d.cts +57 -40
- package/dist/lorebook.d.ts +57 -40
- package/dist/normalizer.cjs +74 -20
- package/dist/normalizer.cjs.map +1 -1
- package/dist/normalizer.d.cts +97 -67
- package/dist/normalizer.d.ts +97 -67
- package/dist/normalizer.js +74 -20
- package/dist/normalizer.js.map +1 -1
- package/dist/png.cjs +74 -20
- package/dist/png.cjs.map +1 -1
- package/dist/png.d.cts +57 -41
- package/dist/png.d.ts +57 -41
- package/dist/png.js +74 -20
- package/dist/png.js.map +1 -1
- package/dist/schemas.cjs +82 -25
- package/dist/schemas.cjs.map +1 -1
- package/dist/schemas.d.cts +181 -115
- package/dist/schemas.d.ts +181 -115
- package/dist/schemas.js +82 -25
- package/dist/schemas.js.map +1 -1
- package/dist/voxta.cjs +93 -22
- package/dist/voxta.cjs.map +1 -1
- package/dist/voxta.d.cts +51 -37
- package/dist/voxta.d.ts +51 -37
- package/dist/voxta.js +93 -22
- package/dist/voxta.js.map +1 -1
- package/package.json +5 -5
package/dist/charx.cjs
CHANGED
|
@@ -440,6 +440,58 @@ var import_zod = require("zod");
|
|
|
440
440
|
var import_zod2 = require("zod");
|
|
441
441
|
var import_zod3 = require("zod");
|
|
442
442
|
var import_zod4 = require("zod");
|
|
443
|
+
function preprocessTimestamp(val) {
|
|
444
|
+
if (val === null || val === void 0) return void 0;
|
|
445
|
+
let num;
|
|
446
|
+
if (typeof val === "number") {
|
|
447
|
+
num = val;
|
|
448
|
+
} else if (typeof val === "string") {
|
|
449
|
+
const trimmed = val.trim();
|
|
450
|
+
if (!trimmed) return void 0;
|
|
451
|
+
const parsed = Number(trimmed);
|
|
452
|
+
if (!isNaN(parsed)) {
|
|
453
|
+
num = parsed;
|
|
454
|
+
} else {
|
|
455
|
+
const date = new Date(trimmed);
|
|
456
|
+
if (isNaN(date.getTime())) return void 0;
|
|
457
|
+
num = Math.floor(date.getTime() / 1e3);
|
|
458
|
+
}
|
|
459
|
+
} else {
|
|
460
|
+
return void 0;
|
|
461
|
+
}
|
|
462
|
+
if (num > 1e10) {
|
|
463
|
+
num = Math.floor(num / 1e3);
|
|
464
|
+
}
|
|
465
|
+
if (num < 0) return void 0;
|
|
466
|
+
return num;
|
|
467
|
+
}
|
|
468
|
+
function preprocessNumeric(val) {
|
|
469
|
+
if (val === null || val === void 0) return void 0;
|
|
470
|
+
if (typeof val === "number") {
|
|
471
|
+
return isNaN(val) ? void 0 : val;
|
|
472
|
+
}
|
|
473
|
+
if (typeof val === "string") {
|
|
474
|
+
const trimmed = val.trim();
|
|
475
|
+
if (!trimmed) return void 0;
|
|
476
|
+
const parsed = Number(trimmed);
|
|
477
|
+
return isNaN(parsed) ? void 0 : parsed;
|
|
478
|
+
}
|
|
479
|
+
return void 0;
|
|
480
|
+
}
|
|
481
|
+
var KNOWN_ASSET_TYPES = /* @__PURE__ */ new Set([
|
|
482
|
+
"icon",
|
|
483
|
+
"background",
|
|
484
|
+
"emotion",
|
|
485
|
+
"user_icon",
|
|
486
|
+
"sound",
|
|
487
|
+
"video",
|
|
488
|
+
"custom",
|
|
489
|
+
"x-risu-asset"
|
|
490
|
+
]);
|
|
491
|
+
function preprocessAssetType(val) {
|
|
492
|
+
if (typeof val !== "string") return "custom";
|
|
493
|
+
return KNOWN_ASSET_TYPES.has(val) ? val : "custom";
|
|
494
|
+
}
|
|
443
495
|
var ISO8601Schema = import_zod.z.string().datetime();
|
|
444
496
|
var UUIDSchema = import_zod.z.string().uuid();
|
|
445
497
|
var SpecSchema = import_zod.z.enum(["v2", "v3"]);
|
|
@@ -462,16 +514,19 @@ var SourceFormatSchema = import_zod.z.enum([
|
|
|
462
514
|
// VoxPkg format
|
|
463
515
|
]);
|
|
464
516
|
var OriginalShapeSchema = import_zod.z.enum(["wrapped", "unwrapped", "legacy"]);
|
|
465
|
-
var AssetTypeSchema = import_zod.z.
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
517
|
+
var AssetTypeSchema = import_zod.z.preprocess(
|
|
518
|
+
preprocessAssetType,
|
|
519
|
+
import_zod.z.enum([
|
|
520
|
+
"icon",
|
|
521
|
+
"background",
|
|
522
|
+
"emotion",
|
|
523
|
+
"user_icon",
|
|
524
|
+
"sound",
|
|
525
|
+
"video",
|
|
526
|
+
"custom",
|
|
527
|
+
"x-risu-asset"
|
|
528
|
+
])
|
|
529
|
+
);
|
|
475
530
|
var AssetDescriptorSchema = import_zod.z.object({
|
|
476
531
|
type: AssetTypeSchema,
|
|
477
532
|
uri: import_zod.z.string(),
|
|
@@ -500,13 +555,13 @@ var CCv2LorebookEntrySchema = import_zod2.z.object({
|
|
|
500
555
|
selective: import_zod2.z.boolean().nullable().optional(),
|
|
501
556
|
secondary_keys: import_zod2.z.array(import_zod2.z.string()).nullable().optional(),
|
|
502
557
|
constant: import_zod2.z.boolean().nullable().optional(),
|
|
503
|
-
position: import_zod2.z.union([import_zod2.z.enum(["before_char", "after_char"]), import_zod2.z.number().int(), import_zod2.z.literal("")]).nullable().optional()
|
|
558
|
+
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()
|
|
504
559
|
}).passthrough();
|
|
505
560
|
var CCv2CharacterBookSchema = import_zod2.z.object({
|
|
506
561
|
name: import_zod2.z.string().optional(),
|
|
507
562
|
description: import_zod2.z.string().optional(),
|
|
508
|
-
scan_depth: import_zod2.z.number().int().nonnegative().optional(),
|
|
509
|
-
token_budget: import_zod2.z.number().int().nonnegative().optional(),
|
|
563
|
+
scan_depth: import_zod2.z.preprocess(preprocessNumeric, import_zod2.z.number().int().nonnegative().optional()),
|
|
564
|
+
token_budget: import_zod2.z.preprocess(preprocessNumeric, import_zod2.z.number().int().nonnegative().optional()),
|
|
510
565
|
recursive_scanning: import_zod2.z.boolean().optional(),
|
|
511
566
|
extensions: import_zod2.z.record(import_zod2.z.unknown()).optional(),
|
|
512
567
|
entries: import_zod2.z.array(CCv2LorebookEntrySchema)
|
|
@@ -553,7 +608,7 @@ var CCv3LorebookEntrySchema = import_zod3.z.object({
|
|
|
553
608
|
selective: import_zod3.z.boolean().nullable().optional(),
|
|
554
609
|
secondary_keys: import_zod3.z.array(import_zod3.z.string()).nullable().optional(),
|
|
555
610
|
constant: import_zod3.z.boolean().nullable().optional(),
|
|
556
|
-
position: import_zod3.z.union([import_zod3.z.enum(["before_char", "after_char"]), import_zod3.z.number().int(), import_zod3.z.literal("")]).nullable().optional(),
|
|
611
|
+
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(),
|
|
557
612
|
extensions: import_zod3.z.record(import_zod3.z.unknown()).optional(),
|
|
558
613
|
// v3 specific - also lenient with types since SillyTavern uses numbers for enums
|
|
559
614
|
automation_id: import_zod3.z.string().optional(),
|
|
@@ -569,8 +624,8 @@ var CCv3LorebookEntrySchema = import_zod3.z.object({
|
|
|
569
624
|
var CCv3CharacterBookSchema = import_zod3.z.object({
|
|
570
625
|
name: import_zod3.z.string().optional(),
|
|
571
626
|
description: import_zod3.z.string().optional(),
|
|
572
|
-
scan_depth: import_zod3.z.number().int().nonnegative().optional(),
|
|
573
|
-
token_budget: import_zod3.z.number().int().nonnegative().optional(),
|
|
627
|
+
scan_depth: import_zod3.z.preprocess(preprocessNumeric, import_zod3.z.number().int().nonnegative().optional()),
|
|
628
|
+
token_budget: import_zod3.z.preprocess(preprocessNumeric, import_zod3.z.number().int().nonnegative().optional()),
|
|
574
629
|
recursive_scanning: import_zod3.z.boolean().optional(),
|
|
575
630
|
extensions: import_zod3.z.record(import_zod3.z.unknown()).optional(),
|
|
576
631
|
entries: import_zod3.z.array(CCv3LorebookEntrySchema)
|
|
@@ -602,10 +657,9 @@ var CCv3DataInnerSchema = import_zod3.z.object({
|
|
|
602
657
|
nickname: import_zod3.z.string().optional(),
|
|
603
658
|
creator_notes_multilingual: import_zod3.z.record(import_zod3.z.string()).optional(),
|
|
604
659
|
source: import_zod3.z.array(import_zod3.z.string()).optional(),
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
modification_date: import_zod3.z.number().int().nonnegative().optional()
|
|
608
|
-
// Unix timestamp in seconds
|
|
660
|
+
// Unix timestamps - preprocess to handle ISO strings, numeric strings, milliseconds
|
|
661
|
+
creation_date: import_zod3.z.preprocess(preprocessTimestamp, import_zod3.z.number().int().nonnegative().optional()),
|
|
662
|
+
modification_date: import_zod3.z.preprocess(preprocessTimestamp, import_zod3.z.number().int().nonnegative().optional())
|
|
609
663
|
});
|
|
610
664
|
var CCv3DataSchema = import_zod3.z.object({
|
|
611
665
|
spec: import_zod3.z.literal("chara_card_v3"),
|
|
@@ -868,36 +922,6 @@ var SAFE_ASSET_TYPES = /* @__PURE__ */ new Set([
|
|
|
868
922
|
"data",
|
|
869
923
|
"unknown"
|
|
870
924
|
]);
|
|
871
|
-
var SAFE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
872
|
-
// Images
|
|
873
|
-
"png",
|
|
874
|
-
"jpg",
|
|
875
|
-
"jpeg",
|
|
876
|
-
"webp",
|
|
877
|
-
"gif",
|
|
878
|
-
"avif",
|
|
879
|
-
"svg",
|
|
880
|
-
"bmp",
|
|
881
|
-
"ico",
|
|
882
|
-
// Audio
|
|
883
|
-
"mp3",
|
|
884
|
-
"wav",
|
|
885
|
-
"ogg",
|
|
886
|
-
"flac",
|
|
887
|
-
"m4a",
|
|
888
|
-
"aac",
|
|
889
|
-
"opus",
|
|
890
|
-
// Video
|
|
891
|
-
"mp4",
|
|
892
|
-
"webm",
|
|
893
|
-
"avi",
|
|
894
|
-
"mov",
|
|
895
|
-
"mkv",
|
|
896
|
-
// Data
|
|
897
|
-
"json",
|
|
898
|
-
"txt",
|
|
899
|
-
"bin"
|
|
900
|
-
]);
|
|
901
925
|
function getCharxCategory(mimetype) {
|
|
902
926
|
if (mimetype.startsWith("image/")) return "images";
|
|
903
927
|
if (mimetype.startsWith("audio/")) return "audio";
|
|
@@ -913,11 +937,20 @@ function sanitizeAssetType(type) {
|
|
|
913
937
|
return sanitized || "custom";
|
|
914
938
|
}
|
|
915
939
|
function sanitizeExtension(ext) {
|
|
916
|
-
const normalized = ext.replace(/^\./, "").toLowerCase()
|
|
917
|
-
if (
|
|
918
|
-
|
|
940
|
+
const normalized = ext.trim().replace(/^\./, "").toLowerCase();
|
|
941
|
+
if (!normalized) {
|
|
942
|
+
throw new Error("Invalid asset extension: empty extension");
|
|
943
|
+
}
|
|
944
|
+
if (normalized.length > 64) {
|
|
945
|
+
throw new Error(`Invalid asset extension: too long (${normalized.length} chars)`);
|
|
946
|
+
}
|
|
947
|
+
if (normalized.includes("/") || normalized.includes("\\") || normalized.includes("\0")) {
|
|
948
|
+
throw new Error("Invalid asset extension: path separators are not allowed");
|
|
949
|
+
}
|
|
950
|
+
if (!/^[a-z0-9][a-z0-9._-]*$/.test(normalized)) {
|
|
951
|
+
throw new Error(`Invalid asset extension: "${ext}"`);
|
|
919
952
|
}
|
|
920
|
-
return
|
|
953
|
+
return normalized;
|
|
921
954
|
}
|
|
922
955
|
function sanitizeName(name, ext) {
|
|
923
956
|
let safeName = name;
|