@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/exporter.cjs
CHANGED
|
@@ -216,58 +216,6 @@ var import_zod = require("zod");
|
|
|
216
216
|
var import_zod2 = require("zod");
|
|
217
217
|
var import_zod3 = require("zod");
|
|
218
218
|
var import_zod4 = require("zod");
|
|
219
|
-
function preprocessTimestamp(val) {
|
|
220
|
-
if (val === null || val === void 0) return void 0;
|
|
221
|
-
let num;
|
|
222
|
-
if (typeof val === "number") {
|
|
223
|
-
num = val;
|
|
224
|
-
} else if (typeof val === "string") {
|
|
225
|
-
const trimmed = val.trim();
|
|
226
|
-
if (!trimmed) return void 0;
|
|
227
|
-
const parsed = Number(trimmed);
|
|
228
|
-
if (!isNaN(parsed)) {
|
|
229
|
-
num = parsed;
|
|
230
|
-
} else {
|
|
231
|
-
const date = new Date(trimmed);
|
|
232
|
-
if (isNaN(date.getTime())) return void 0;
|
|
233
|
-
num = Math.floor(date.getTime() / 1e3);
|
|
234
|
-
}
|
|
235
|
-
} else {
|
|
236
|
-
return void 0;
|
|
237
|
-
}
|
|
238
|
-
if (num > 1e10) {
|
|
239
|
-
num = Math.floor(num / 1e3);
|
|
240
|
-
}
|
|
241
|
-
if (num < 0) return void 0;
|
|
242
|
-
return num;
|
|
243
|
-
}
|
|
244
|
-
function preprocessNumeric(val) {
|
|
245
|
-
if (val === null || val === void 0) return void 0;
|
|
246
|
-
if (typeof val === "number") {
|
|
247
|
-
return isNaN(val) ? void 0 : val;
|
|
248
|
-
}
|
|
249
|
-
if (typeof val === "string") {
|
|
250
|
-
const trimmed = val.trim();
|
|
251
|
-
if (!trimmed) return void 0;
|
|
252
|
-
const parsed = Number(trimmed);
|
|
253
|
-
return isNaN(parsed) ? void 0 : parsed;
|
|
254
|
-
}
|
|
255
|
-
return void 0;
|
|
256
|
-
}
|
|
257
|
-
var KNOWN_ASSET_TYPES = /* @__PURE__ */ new Set([
|
|
258
|
-
"icon",
|
|
259
|
-
"background",
|
|
260
|
-
"emotion",
|
|
261
|
-
"user_icon",
|
|
262
|
-
"sound",
|
|
263
|
-
"video",
|
|
264
|
-
"custom",
|
|
265
|
-
"x-risu-asset"
|
|
266
|
-
]);
|
|
267
|
-
function preprocessAssetType(val) {
|
|
268
|
-
if (typeof val !== "string") return "custom";
|
|
269
|
-
return KNOWN_ASSET_TYPES.has(val) ? val : "custom";
|
|
270
|
-
}
|
|
271
219
|
var ISO8601Schema = import_zod.z.string().datetime();
|
|
272
220
|
var UUIDSchema = import_zod.z.string().uuid();
|
|
273
221
|
var SpecSchema = import_zod.z.enum(["v2", "v3"]);
|
|
@@ -290,19 +238,16 @@ var SourceFormatSchema = import_zod.z.enum([
|
|
|
290
238
|
// VoxPkg format
|
|
291
239
|
]);
|
|
292
240
|
var OriginalShapeSchema = import_zod.z.enum(["wrapped", "unwrapped", "legacy"]);
|
|
293
|
-
var AssetTypeSchema = import_zod.z.
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
"x-risu-asset"
|
|
304
|
-
])
|
|
305
|
-
);
|
|
241
|
+
var AssetTypeSchema = import_zod.z.enum([
|
|
242
|
+
"icon",
|
|
243
|
+
"background",
|
|
244
|
+
"emotion",
|
|
245
|
+
"user_icon",
|
|
246
|
+
"sound",
|
|
247
|
+
"video",
|
|
248
|
+
"custom",
|
|
249
|
+
"x-risu-asset"
|
|
250
|
+
]);
|
|
306
251
|
var AssetDescriptorSchema = import_zod.z.object({
|
|
307
252
|
type: AssetTypeSchema,
|
|
308
253
|
uri: import_zod.z.string(),
|
|
@@ -336,8 +281,8 @@ var CCv2LorebookEntrySchema = import_zod2.z.object({
|
|
|
336
281
|
var CCv2CharacterBookSchema = import_zod2.z.object({
|
|
337
282
|
name: import_zod2.z.string().optional(),
|
|
338
283
|
description: import_zod2.z.string().optional(),
|
|
339
|
-
scan_depth: import_zod2.z.
|
|
340
|
-
token_budget: import_zod2.z.
|
|
284
|
+
scan_depth: import_zod2.z.number().int().nonnegative().optional(),
|
|
285
|
+
token_budget: import_zod2.z.number().int().nonnegative().optional(),
|
|
341
286
|
recursive_scanning: import_zod2.z.boolean().optional(),
|
|
342
287
|
extensions: import_zod2.z.record(import_zod2.z.unknown()).optional(),
|
|
343
288
|
entries: import_zod2.z.array(CCv2LorebookEntrySchema)
|
|
@@ -400,8 +345,8 @@ var CCv3LorebookEntrySchema = import_zod3.z.object({
|
|
|
400
345
|
var CCv3CharacterBookSchema = import_zod3.z.object({
|
|
401
346
|
name: import_zod3.z.string().optional(),
|
|
402
347
|
description: import_zod3.z.string().optional(),
|
|
403
|
-
scan_depth: import_zod3.z.
|
|
404
|
-
token_budget: import_zod3.z.
|
|
348
|
+
scan_depth: import_zod3.z.number().int().nonnegative().optional(),
|
|
349
|
+
token_budget: import_zod3.z.number().int().nonnegative().optional(),
|
|
405
350
|
recursive_scanning: import_zod3.z.boolean().optional(),
|
|
406
351
|
extensions: import_zod3.z.record(import_zod3.z.unknown()).optional(),
|
|
407
352
|
entries: import_zod3.z.array(CCv3LorebookEntrySchema)
|
|
@@ -433,9 +378,10 @@ var CCv3DataInnerSchema = import_zod3.z.object({
|
|
|
433
378
|
nickname: import_zod3.z.string().optional(),
|
|
434
379
|
creator_notes_multilingual: import_zod3.z.record(import_zod3.z.string()).optional(),
|
|
435
380
|
source: import_zod3.z.array(import_zod3.z.string()).optional(),
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
modification_date: import_zod3.z.
|
|
381
|
+
creation_date: import_zod3.z.number().int().nonnegative().optional(),
|
|
382
|
+
// Unix timestamp in seconds
|
|
383
|
+
modification_date: import_zod3.z.number().int().nonnegative().optional()
|
|
384
|
+
// Unix timestamp in seconds
|
|
439
385
|
});
|
|
440
386
|
var CCv3DataSchema = import_zod3.z.object({
|
|
441
387
|
spec: import_zod3.z.literal("chara_card_v3"),
|
|
@@ -600,6 +546,36 @@ var SAFE_ASSET_TYPES = /* @__PURE__ */ new Set([
|
|
|
600
546
|
"data",
|
|
601
547
|
"unknown"
|
|
602
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
|
+
]);
|
|
603
579
|
function getCharxCategory(mimetype) {
|
|
604
580
|
if (mimetype.startsWith("image/")) return "images";
|
|
605
581
|
if (mimetype.startsWith("audio/")) return "audio";
|
|
@@ -615,20 +591,11 @@ function sanitizeAssetType(type) {
|
|
|
615
591
|
return sanitized || "custom";
|
|
616
592
|
}
|
|
617
593
|
function sanitizeExtension(ext) {
|
|
618
|
-
const normalized = ext.
|
|
619
|
-
if (
|
|
620
|
-
|
|
621
|
-
}
|
|
622
|
-
if (normalized.length > 64) {
|
|
623
|
-
throw new Error(`Invalid asset extension: too long (${normalized.length} chars)`);
|
|
624
|
-
}
|
|
625
|
-
if (normalized.includes("/") || normalized.includes("\\") || normalized.includes("\0")) {
|
|
626
|
-
throw new Error("Invalid asset extension: path separators are not allowed");
|
|
627
|
-
}
|
|
628
|
-
if (!/^[a-z0-9][a-z0-9._-]*$/.test(normalized)) {
|
|
629
|
-
throw new Error(`Invalid asset extension: "${ext}"`);
|
|
594
|
+
const normalized = ext.replace(/^\./, "").toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
595
|
+
if (SAFE_EXTENSIONS.has(normalized)) {
|
|
596
|
+
return normalized;
|
|
630
597
|
}
|
|
631
|
-
return
|
|
598
|
+
return "bin";
|
|
632
599
|
}
|
|
633
600
|
function sanitizeName(name, ext) {
|
|
634
601
|
let safeName = name;
|
|
@@ -7079,22 +7046,6 @@ function sanitizeName2(name, ext) {
|
|
|
7079
7046
|
if (!safeName) safeName = "asset";
|
|
7080
7047
|
return safeName;
|
|
7081
7048
|
}
|
|
7082
|
-
function sanitizeExtension2(ext) {
|
|
7083
|
-
const normalized = ext.trim().replace(/^\./, "").toLowerCase();
|
|
7084
|
-
if (!normalized) {
|
|
7085
|
-
throw new Error("Invalid asset extension: empty extension");
|
|
7086
|
-
}
|
|
7087
|
-
if (normalized.length > 64) {
|
|
7088
|
-
throw new Error(`Invalid asset extension: too long (${normalized.length} chars)`);
|
|
7089
|
-
}
|
|
7090
|
-
if (normalized.includes("/") || normalized.includes("\\") || normalized.includes("\0")) {
|
|
7091
|
-
throw new Error("Invalid asset extension: path separators are not allowed");
|
|
7092
|
-
}
|
|
7093
|
-
if (!/^[a-z0-9][a-z0-9._-]*$/.test(normalized)) {
|
|
7094
|
-
throw new Error(`Invalid asset extension: "${ext}"`);
|
|
7095
|
-
}
|
|
7096
|
-
return normalized;
|
|
7097
|
-
}
|
|
7098
7049
|
function writeVoxta(card, assets, options = {}) {
|
|
7099
7050
|
const { compressionLevel = 6, includePackageJson = false } = options;
|
|
7100
7051
|
const cardData = card.data;
|
|
@@ -7183,9 +7134,8 @@ function writeVoxta(card, assets, options = {}) {
|
|
|
7183
7134
|
let assetCount = 0;
|
|
7184
7135
|
let mainThumbnail;
|
|
7185
7136
|
for (const asset of assets) {
|
|
7186
|
-
const
|
|
7187
|
-
const
|
|
7188
|
-
const finalFilename = `${safeName}.${safeExt}`;
|
|
7137
|
+
const safeName = sanitizeName2(asset.name, asset.ext);
|
|
7138
|
+
const finalFilename = `${safeName}.${asset.ext}`;
|
|
7189
7139
|
let voxtaPath = "";
|
|
7190
7140
|
const tags = asset.tags || [];
|
|
7191
7141
|
const isMainIcon = asset.type === "icon" && (tags.includes("portrait-override") || asset.name === "main" || asset.isMain);
|