forked from
nekomimi.pet/wisp.place-monorepo
Monorepo for wisp.place. A static site hosting service built on top of the AT Protocol.
1export type FileCidsNormalizationSource =
2 | 'object'
3 | 'array'
4 | 'string-json'
5 | 'string-invalid'
6 | 'null'
7 | 'other';
8
9export type FileCidsNormalization = {
10 value: Record<string, string>;
11 source: FileCidsNormalizationSource;
12};
13
14export function normalizeFileCids(value: unknown): FileCidsNormalization {
15 if (value == null) {
16 return { value: {}, source: 'null' };
17 }
18
19 if (typeof value === 'string') {
20 try {
21 const parsed = JSON.parse(value) as unknown;
22 if (Array.isArray(parsed)) {
23 const normalized = normalizeFileCids(parsed);
24 return { value: normalized.value, source: 'string-json' };
25 }
26 if (parsed && typeof parsed === 'object') {
27 return { value: parsed as Record<string, string>, source: 'string-json' };
28 }
29 } catch {
30 // fall through to invalid
31 }
32 return { value: {}, source: 'string-invalid' };
33 }
34
35 if (Array.isArray(value)) {
36 const result: Record<string, string> = {};
37 for (const item of value) {
38 if (Array.isArray(item) && item.length >= 2) {
39 const [path, cid] = item;
40 if (typeof path === 'string' && typeof cid === 'string') {
41 result[path] = cid;
42 }
43 continue;
44 }
45
46 if (item && typeof item === 'object' && 'path' in item && 'cid' in item) {
47 const path = (item as any).path;
48 const cid = (item as any).cid;
49 if (typeof path === 'string' && typeof cid === 'string') {
50 result[path] = cid;
51 }
52 }
53 }
54 return { value: result, source: 'array' };
55 }
56
57 if (typeof value === 'object') {
58 return { value: value as Record<string, string>, source: 'object' };
59 }
60
61 return { value: {}, source: 'other' };
62}