/
base.ts
63 lines (55 loc) · 1.62 KB
/
base.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import { create, IPFSHTTPClient, Options } from "ipfs-http-client";
import fetch from "cross-fetch";
import { concat, toString } from "uint8arrays";
import { CID } from "multiformats/cid";
/**
* Base IPFS storage class that wraps an instance of `IPFSHTTPClient`.
*/
export class BaseIpfsStorage {
public ipfsClient: IPFSHTTPClient;
constructor(opts: Options) {
this.ipfsClient = create(opts);
}
public async add(value: Parameters<IPFSHTTPClient["add"]>[0]) {
const addResult = await this.ipfsClient.add(value, {
pin: true
});
const cid = addResult.cid.toString();
return cid;
}
public async get<T>(uriOrHash: string, asJson = true): Promise<T | string> {
let cid: CID = null;
try {
cid = CID.parse(
uriOrHash.startsWith("ipfs://")
? uriOrHash.split("ipfs://")[1]
: uriOrHash
);
} catch (error) {
// if parsing fails, we assume it is a url
}
const value = await (cid
? this.getByCID<T>(cid.toString(), asJson)
: this.getByURL<T>(uriOrHash, asJson));
return value;
}
public async getByCID<T>(cid: string, asJson = true): Promise<T | string> {
const chunks = [];
for await (const chunk of this.ipfsClient.cat(cid)) {
chunks.push(chunk);
}
const data = concat(chunks);
if (!asJson) {
return data as unknown as T;
}
const dataStr = toString(data);
return JSON.parse(dataStr);
}
public async getByURL<T>(url: string, asJson = true): Promise<T | string> {
const response = await fetch(url);
if (!asJson) {
return response.text();
}
return response.json();
}
}