@character-foundry/character-foundry 0.4.3-dev.1766103111 → 0.4.3
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 +52 -85
- package/dist/charx.cjs.map +1 -1
- package/dist/charx.d.cts +22 -22
- package/dist/charx.d.ts +22 -22
- package/dist/charx.js +52 -85
- package/dist/charx.js.map +1 -1
- package/dist/exporter.cjs +54 -104
- package/dist/exporter.cjs.map +1 -1
- package/dist/exporter.d.cts +19 -19
- package/dist/exporter.d.ts +19 -19
- package/dist/exporter.js +54 -104
- package/dist/exporter.js.map +1 -1
- package/dist/federation.cjs +36 -104
- package/dist/federation.cjs.map +1 -1
- package/dist/federation.d.cts +19 -54
- package/dist/federation.d.ts +19 -54
- package/dist/federation.js +36 -104
- package/dist/federation.js.map +1 -1
- package/dist/index.cjs +54 -104
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -29
- package/dist/index.d.ts +29 -29
- package/dist/index.js +54 -104
- package/dist/index.js.map +1 -1
- package/dist/loader.cjs +31 -171
- package/dist/loader.cjs.map +1 -1
- package/dist/loader.d.cts +23 -37
- package/dist/loader.d.ts +23 -37
- package/dist/loader.js +31 -171
- package/dist/loader.js.map +1 -1
- package/dist/lorebook.d.cts +23 -23
- package/dist/lorebook.d.ts +23 -23
- package/dist/normalizer.cjs +18 -72
- package/dist/normalizer.cjs.map +1 -1
- package/dist/normalizer.d.cts +37 -37
- package/dist/normalizer.d.ts +37 -37
- package/dist/normalizer.js +18 -72
- package/dist/normalizer.js.map +1 -1
- package/dist/png.cjs +18 -72
- package/dist/png.cjs.map +1 -1
- package/dist/png.d.cts +25 -25
- package/dist/png.d.ts +25 -25
- package/dist/png.js +18 -72
- package/dist/png.js.map +1 -1
- package/dist/schemas.cjs +23 -80
- package/dist/schemas.cjs.map +1 -1
- package/dist/schemas.d.cts +67 -85
- package/dist/schemas.d.ts +67 -85
- package/dist/schemas.js +23 -80
- package/dist/schemas.js.map +1 -1
- package/dist/voxta.cjs +20 -91
- package/dist/voxta.cjs.map +1 -1
- package/dist/voxta.d.cts +23 -23
- package/dist/voxta.d.ts +23 -23
- package/dist/voxta.js +20 -91
- package/dist/voxta.js.map +1 -1
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -560,58 +560,6 @@ var import_zod = require("zod");
|
|
|
560
560
|
var import_zod2 = require("zod");
|
|
561
561
|
var import_zod3 = require("zod");
|
|
562
562
|
var import_zod4 = require("zod");
|
|
563
|
-
function preprocessTimestamp(val) {
|
|
564
|
-
if (val === null || val === void 0) return void 0;
|
|
565
|
-
let num;
|
|
566
|
-
if (typeof val === "number") {
|
|
567
|
-
num = val;
|
|
568
|
-
} else if (typeof val === "string") {
|
|
569
|
-
const trimmed = val.trim();
|
|
570
|
-
if (!trimmed) return void 0;
|
|
571
|
-
const parsed = Number(trimmed);
|
|
572
|
-
if (!isNaN(parsed)) {
|
|
573
|
-
num = parsed;
|
|
574
|
-
} else {
|
|
575
|
-
const date = new Date(trimmed);
|
|
576
|
-
if (isNaN(date.getTime())) return void 0;
|
|
577
|
-
num = Math.floor(date.getTime() / 1e3);
|
|
578
|
-
}
|
|
579
|
-
} else {
|
|
580
|
-
return void 0;
|
|
581
|
-
}
|
|
582
|
-
if (num > 1e10) {
|
|
583
|
-
num = Math.floor(num / 1e3);
|
|
584
|
-
}
|
|
585
|
-
if (num < 0) return void 0;
|
|
586
|
-
return num;
|
|
587
|
-
}
|
|
588
|
-
function preprocessNumeric(val) {
|
|
589
|
-
if (val === null || val === void 0) return void 0;
|
|
590
|
-
if (typeof val === "number") {
|
|
591
|
-
return isNaN(val) ? void 0 : val;
|
|
592
|
-
}
|
|
593
|
-
if (typeof val === "string") {
|
|
594
|
-
const trimmed = val.trim();
|
|
595
|
-
if (!trimmed) return void 0;
|
|
596
|
-
const parsed = Number(trimmed);
|
|
597
|
-
return isNaN(parsed) ? void 0 : parsed;
|
|
598
|
-
}
|
|
599
|
-
return void 0;
|
|
600
|
-
}
|
|
601
|
-
var KNOWN_ASSET_TYPES = /* @__PURE__ */ new Set([
|
|
602
|
-
"icon",
|
|
603
|
-
"background",
|
|
604
|
-
"emotion",
|
|
605
|
-
"user_icon",
|
|
606
|
-
"sound",
|
|
607
|
-
"video",
|
|
608
|
-
"custom",
|
|
609
|
-
"x-risu-asset"
|
|
610
|
-
]);
|
|
611
|
-
function preprocessAssetType(val) {
|
|
612
|
-
if (typeof val !== "string") return "custom";
|
|
613
|
-
return KNOWN_ASSET_TYPES.has(val) ? val : "custom";
|
|
614
|
-
}
|
|
615
563
|
var ISO8601Schema = import_zod.z.string().datetime();
|
|
616
564
|
var UUIDSchema = import_zod.z.string().uuid();
|
|
617
565
|
var SpecSchema = import_zod.z.enum(["v2", "v3"]);
|
|
@@ -634,19 +582,16 @@ var SourceFormatSchema = import_zod.z.enum([
|
|
|
634
582
|
// VoxPkg format
|
|
635
583
|
]);
|
|
636
584
|
var OriginalShapeSchema = import_zod.z.enum(["wrapped", "unwrapped", "legacy"]);
|
|
637
|
-
var AssetTypeSchema = import_zod.z.
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
"x-risu-asset"
|
|
648
|
-
])
|
|
649
|
-
);
|
|
585
|
+
var AssetTypeSchema = import_zod.z.enum([
|
|
586
|
+
"icon",
|
|
587
|
+
"background",
|
|
588
|
+
"emotion",
|
|
589
|
+
"user_icon",
|
|
590
|
+
"sound",
|
|
591
|
+
"video",
|
|
592
|
+
"custom",
|
|
593
|
+
"x-risu-asset"
|
|
594
|
+
]);
|
|
650
595
|
var AssetDescriptorSchema = import_zod.z.object({
|
|
651
596
|
type: AssetTypeSchema,
|
|
652
597
|
uri: import_zod.z.string(),
|
|
@@ -680,8 +625,8 @@ var CCv2LorebookEntrySchema = import_zod2.z.object({
|
|
|
680
625
|
var CCv2CharacterBookSchema = import_zod2.z.object({
|
|
681
626
|
name: import_zod2.z.string().optional(),
|
|
682
627
|
description: import_zod2.z.string().optional(),
|
|
683
|
-
scan_depth: import_zod2.z.
|
|
684
|
-
token_budget: import_zod2.z.
|
|
628
|
+
scan_depth: import_zod2.z.number().int().nonnegative().optional(),
|
|
629
|
+
token_budget: import_zod2.z.number().int().nonnegative().optional(),
|
|
685
630
|
recursive_scanning: import_zod2.z.boolean().optional(),
|
|
686
631
|
extensions: import_zod2.z.record(import_zod2.z.unknown()).optional(),
|
|
687
632
|
entries: import_zod2.z.array(CCv2LorebookEntrySchema)
|
|
@@ -755,8 +700,8 @@ var CCv3LorebookEntrySchema = import_zod3.z.object({
|
|
|
755
700
|
var CCv3CharacterBookSchema = import_zod3.z.object({
|
|
756
701
|
name: import_zod3.z.string().optional(),
|
|
757
702
|
description: import_zod3.z.string().optional(),
|
|
758
|
-
scan_depth: import_zod3.z.
|
|
759
|
-
token_budget: import_zod3.z.
|
|
703
|
+
scan_depth: import_zod3.z.number().int().nonnegative().optional(),
|
|
704
|
+
token_budget: import_zod3.z.number().int().nonnegative().optional(),
|
|
760
705
|
recursive_scanning: import_zod3.z.boolean().optional(),
|
|
761
706
|
extensions: import_zod3.z.record(import_zod3.z.unknown()).optional(),
|
|
762
707
|
entries: import_zod3.z.array(CCv3LorebookEntrySchema)
|
|
@@ -788,9 +733,10 @@ var CCv3DataInnerSchema = import_zod3.z.object({
|
|
|
788
733
|
nickname: import_zod3.z.string().optional(),
|
|
789
734
|
creator_notes_multilingual: import_zod3.z.record(import_zod3.z.string()).optional(),
|
|
790
735
|
source: import_zod3.z.array(import_zod3.z.string()).optional(),
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
modification_date: import_zod3.z.
|
|
736
|
+
creation_date: import_zod3.z.number().int().nonnegative().optional(),
|
|
737
|
+
// Unix timestamp in seconds
|
|
738
|
+
modification_date: import_zod3.z.number().int().nonnegative().optional()
|
|
739
|
+
// Unix timestamp in seconds
|
|
794
740
|
});
|
|
795
741
|
var CCv3DataSchema = import_zod3.z.object({
|
|
796
742
|
spec: import_zod3.z.literal("chara_card_v3"),
|
|
@@ -1417,6 +1363,36 @@ var SAFE_ASSET_TYPES = /* @__PURE__ */ new Set([
|
|
|
1417
1363
|
"data",
|
|
1418
1364
|
"unknown"
|
|
1419
1365
|
]);
|
|
1366
|
+
var SAFE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
1367
|
+
// Images
|
|
1368
|
+
"png",
|
|
1369
|
+
"jpg",
|
|
1370
|
+
"jpeg",
|
|
1371
|
+
"webp",
|
|
1372
|
+
"gif",
|
|
1373
|
+
"avif",
|
|
1374
|
+
"svg",
|
|
1375
|
+
"bmp",
|
|
1376
|
+
"ico",
|
|
1377
|
+
// Audio
|
|
1378
|
+
"mp3",
|
|
1379
|
+
"wav",
|
|
1380
|
+
"ogg",
|
|
1381
|
+
"flac",
|
|
1382
|
+
"m4a",
|
|
1383
|
+
"aac",
|
|
1384
|
+
"opus",
|
|
1385
|
+
// Video
|
|
1386
|
+
"mp4",
|
|
1387
|
+
"webm",
|
|
1388
|
+
"avi",
|
|
1389
|
+
"mov",
|
|
1390
|
+
"mkv",
|
|
1391
|
+
// Data
|
|
1392
|
+
"json",
|
|
1393
|
+
"txt",
|
|
1394
|
+
"bin"
|
|
1395
|
+
]);
|
|
1420
1396
|
function getCharxCategory(mimetype) {
|
|
1421
1397
|
if (mimetype.startsWith("image/")) return "images";
|
|
1422
1398
|
if (mimetype.startsWith("audio/")) return "audio";
|
|
@@ -1432,20 +1408,11 @@ function sanitizeAssetType(type) {
|
|
|
1432
1408
|
return sanitized || "custom";
|
|
1433
1409
|
}
|
|
1434
1410
|
function sanitizeExtension(ext) {
|
|
1435
|
-
const normalized = ext.
|
|
1436
|
-
if (
|
|
1437
|
-
|
|
1438
|
-
}
|
|
1439
|
-
if (normalized.length > 64) {
|
|
1440
|
-
throw new Error(`Invalid asset extension: too long (${normalized.length} chars)`);
|
|
1441
|
-
}
|
|
1442
|
-
if (normalized.includes("/") || normalized.includes("\\") || normalized.includes("\0")) {
|
|
1443
|
-
throw new Error("Invalid asset extension: path separators are not allowed");
|
|
1444
|
-
}
|
|
1445
|
-
if (!/^[a-z0-9][a-z0-9._-]*$/.test(normalized)) {
|
|
1446
|
-
throw new Error(`Invalid asset extension: "${ext}"`);
|
|
1411
|
+
const normalized = ext.replace(/^\./, "").toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
1412
|
+
if (SAFE_EXTENSIONS.has(normalized)) {
|
|
1413
|
+
return normalized;
|
|
1447
1414
|
}
|
|
1448
|
-
return
|
|
1415
|
+
return "bin";
|
|
1449
1416
|
}
|
|
1450
1417
|
function sanitizeName(name, ext) {
|
|
1451
1418
|
let safeName = name;
|
|
@@ -8227,22 +8194,6 @@ function sanitizeName2(name, ext) {
|
|
|
8227
8194
|
if (!safeName) safeName = "asset";
|
|
8228
8195
|
return safeName;
|
|
8229
8196
|
}
|
|
8230
|
-
function sanitizeExtension2(ext) {
|
|
8231
|
-
const normalized = ext.trim().replace(/^\./, "").toLowerCase();
|
|
8232
|
-
if (!normalized) {
|
|
8233
|
-
throw new Error("Invalid asset extension: empty extension");
|
|
8234
|
-
}
|
|
8235
|
-
if (normalized.length > 64) {
|
|
8236
|
-
throw new Error(`Invalid asset extension: too long (${normalized.length} chars)`);
|
|
8237
|
-
}
|
|
8238
|
-
if (normalized.includes("/") || normalized.includes("\\") || normalized.includes("\0")) {
|
|
8239
|
-
throw new Error("Invalid asset extension: path separators are not allowed");
|
|
8240
|
-
}
|
|
8241
|
-
if (!/^[a-z0-9][a-z0-9._-]*$/.test(normalized)) {
|
|
8242
|
-
throw new Error(`Invalid asset extension: "${ext}"`);
|
|
8243
|
-
}
|
|
8244
|
-
return normalized;
|
|
8245
|
-
}
|
|
8246
8197
|
function writeVoxta(card, assets, options = {}) {
|
|
8247
8198
|
const { compressionLevel = 6, includePackageJson = false } = options;
|
|
8248
8199
|
const cardData = card.data;
|
|
@@ -8331,9 +8282,8 @@ function writeVoxta(card, assets, options = {}) {
|
|
|
8331
8282
|
let assetCount = 0;
|
|
8332
8283
|
let mainThumbnail;
|
|
8333
8284
|
for (const asset of assets) {
|
|
8334
|
-
const
|
|
8335
|
-
const
|
|
8336
|
-
const finalFilename = `${safeName}.${safeExt}`;
|
|
8285
|
+
const safeName = sanitizeName2(asset.name, asset.ext);
|
|
8286
|
+
const finalFilename = `${safeName}.${asset.ext}`;
|
|
8337
8287
|
let voxtaPath = "";
|
|
8338
8288
|
const tags = asset.tags || [];
|
|
8339
8289
|
const isMainIcon = asset.type === "icon" && (tags.includes("portrait-override") || asset.name === "main" || asset.isMain);
|