Suite of AT Protocol TypeScript libraries built on web standards
1import { CID } from "multiformats/cid";
2import { asCid, RAW_BIN_MULTICODEC, SHA2_256_MULTIHASH_CODE } from "./cid.ts";
3import { isPlainObject } from "./object.ts";
4
5export type BlobRef = {
6 $type: "blob";
7 mimeType: string;
8 ref: import("./cid.ts").Cid;
9 size: number;
10};
11
12export type LegacyBlobRef = {
13 cid: string;
14 mimeType: string;
15};
16
17export function isBlobRef(
18 input: unknown,
19 options?: { strict?: boolean },
20): input is BlobRef {
21 if (!isPlainObject(input)) return false;
22 if (input.$type !== "blob") return false;
23
24 const { mimeType, size, ref } = input;
25
26 if (typeof mimeType !== "string" || !mimeType.includes("/")) return false;
27 if (typeof size !== "number" || size < 0 || !Number.isInteger(size)) {
28 return false;
29 }
30 if (typeof ref !== "object" || ref === null) return false;
31
32 for (const key in input) {
33 if (
34 key !== "$type" && key !== "mimeType" && key !== "ref" && key !== "size"
35 ) {
36 return false;
37 }
38 }
39
40 const cid = asCid(ref);
41 if (!cid) return false;
42
43 if (options?.strict) {
44 if (cid.version !== 1) return false;
45 if (cid.code !== RAW_BIN_MULTICODEC) return false;
46 if (cid.multihash.code !== SHA2_256_MULTIHASH_CODE) return false;
47 }
48
49 return true;
50}
51
52export function isLegacyBlobRef(input: unknown): input is LegacyBlobRef {
53 if (!isPlainObject(input)) return false;
54
55 const { cid, mimeType } = input;
56 if (typeof cid !== "string") return false;
57 if (typeof mimeType !== "string") return false;
58
59 for (const key in input) {
60 if (key !== "cid" && key !== "mimeType") return false;
61 }
62
63 try {
64 CID.parse(cid);
65 } catch {
66 return false;
67 }
68
69 return true;
70}