most-box 0.0.4 → 0.0.7
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/LICENSE +21 -21
- package/README.md +222 -182
- package/electron/main.js +67 -0
- package/out/404/index.html +2 -2
- package/out/404.html +2 -2
- package/out/__next.__PAGE__.txt +6 -4
- package/out/__next._full.txt +20 -17
- package/out/__next._head.txt +3 -3
- package/out/__next._index.txt +6 -5
- package/out/__next._tree.txt +4 -2
- package/out/_next/static/chunks/003jnm.v5tzw5.js +1 -0
- package/out/_next/static/chunks/00re8v.gbcywn.js +1 -0
- package/out/_next/static/chunks/00s106sbq8t9v.js +1 -0
- package/out/_next/static/chunks/012hi627qrdnn.js +1 -0
- package/out/_next/static/chunks/0174xh3wfsjm1.js +2 -0
- package/out/_next/static/chunks/01xlw8hd842-c.js +1 -0
- package/out/_next/static/chunks/02~o2nmo5pmy1.js +1 -0
- package/out/_next/static/chunks/07t.dhhokszz5.css +1 -0
- package/out/_next/static/chunks/0_wia9ofmsi1c.css +2 -0
- package/out/_next/static/chunks/0ah8fihozo2_u.js +5 -0
- package/out/_next/static/chunks/0bzupvr5gt3k9.js +31 -0
- package/out/_next/static/chunks/0d3shmwh5_nmn.js +1 -0
- package/out/_next/static/chunks/0e_h0d3ekzks8.css +1 -0
- package/out/_next/static/chunks/0gdluj423gso1.js +1 -0
- package/out/_next/static/chunks/0gmoiq06srjay.css +1 -0
- package/out/_next/static/chunks/0ho~log~~-jwp.css +1 -0
- package/out/_next/static/chunks/0imkasy7kb67u.js +1 -0
- package/out/_next/static/chunks/0jjc_b9q_ldi2.js +1 -0
- package/out/_next/static/chunks/0jl~j62iz2uvr.js +1 -0
- package/out/_next/static/chunks/0lqslm813wk_h.js +1 -0
- package/out/_next/static/chunks/{0bogtdbh.dcu1.js → 0n~dq4kpx9xxx.js} +1 -1
- package/out/_next/static/chunks/0pqt~8bl3ukh4.js +4 -0
- package/out/_next/static/chunks/0q782fxxd0lx~.js +1 -0
- package/out/_next/static/chunks/0qub_r0x_r-e9.css +1 -0
- package/out/_next/static/chunks/0slwj0c46k5cu.js +1 -0
- package/out/_next/static/chunks/0sorqk.oc6b7j.css +1 -0
- package/out/_next/static/chunks/0tapzqc6hgvx-.js +1 -0
- package/out/_next/static/chunks/0xsc7z5x8n7wg.js +1 -0
- package/out/_next/static/chunks/0zm~gys2jwl0g.js +1 -0
- package/out/_next/static/chunks/turbopack-0a_g3u0ud~jb8.js +1 -0
- package/out/_not-found/__next._full.txt +19 -15
- package/out/_not-found/__next._head.txt +3 -3
- package/out/_not-found/__next._index.txt +6 -5
- package/out/_not-found/__next._not-found.__PAGE__.txt +9 -0
- package/out/_not-found/__next._not-found.txt +3 -3
- package/out/_not-found/__next._tree.txt +2 -2
- package/out/_not-found/index.html +2 -2
- package/out/_not-found/index.txt +19 -15
- package/out/app/__next._full.txt +20 -0
- package/out/app/__next._head.txt +5 -0
- package/out/app/__next._index.txt +7 -0
- package/out/app/__next._tree.txt +2 -0
- package/out/app/__next.app.__PAGE__.txt +9 -0
- package/out/app/__next.app.txt +5 -0
- package/out/app/index.html +15 -0
- package/out/app/index.txt +20 -0
- package/out/changelog/__next._full.txt +22 -0
- package/out/changelog/__next._head.txt +5 -0
- package/out/changelog/__next._index.txt +7 -0
- package/out/changelog/__next._tree.txt +3 -0
- package/out/changelog/__next.changelog.__PAGE__.txt +10 -0
- package/out/changelog/__next.changelog.txt +5 -0
- package/out/changelog/index.html +15 -0
- package/out/changelog/index.txt +22 -0
- package/out/chat/__next._full.txt +20 -18
- package/out/chat/__next._head.txt +3 -3
- package/out/chat/__next._index.txt +6 -5
- package/out/chat/__next._tree.txt +3 -3
- package/out/chat/__next.chat.__PAGE__.txt +9 -0
- package/out/chat/__next.chat.txt +5 -4
- package/out/chat/index.html +2 -2
- package/out/chat/index.txt +20 -18
- package/out/docs/__next._full.txt +22 -0
- package/out/docs/__next._head.txt +5 -0
- package/out/docs/__next._index.txt +7 -0
- package/out/docs/__next._tree.txt +3 -0
- package/out/docs/__next.docs.__PAGE__.txt +10 -0
- package/out/docs/__next.docs.txt +5 -0
- package/out/docs/getting-started/__next._full.txt +22 -0
- package/out/docs/getting-started/__next._head.txt +5 -0
- package/out/docs/getting-started/__next._index.txt +7 -0
- package/out/docs/getting-started/__next._tree.txt +3 -0
- package/out/docs/getting-started/__next.docs.getting-started.__PAGE__.txt +10 -0
- package/out/docs/getting-started/__next.docs.getting-started.txt +5 -0
- package/out/docs/getting-started/__next.docs.txt +5 -0
- package/out/docs/getting-started/index.html +15 -0
- package/out/docs/getting-started/index.txt +22 -0
- package/out/docs/index.html +15 -0
- package/out/docs/index.txt +22 -0
- package/out/download/__next._full.txt +34 -0
- package/out/download/__next._head.txt +5 -0
- package/out/download/__next._index.txt +7 -0
- package/out/download/__next._tree.txt +4 -0
- package/out/download/__next.download.__PAGE__.txt +16 -0
- package/out/download/__next.download.txt +5 -0
- package/out/download/index.html +15 -0
- package/out/download/index.txt +34 -0
- package/out/fonts/jetbrains-mono-latin-400-normal.woff2 +0 -0
- package/out/fonts/jetbrains-mono-latin-500-normal.woff2 +0 -0
- package/out/fonts/jetbrains-mono-latin-600-normal.woff2 +0 -0
- package/out/fonts/jetbrains-mono-latin-700-normal.woff2 +0 -0
- package/out/index.html +2 -2
- package/out/index.txt +20 -17
- package/out/ping/__next._full.txt +21 -0
- package/out/ping/__next._head.txt +5 -0
- package/out/ping/__next._index.txt +7 -0
- package/out/ping/__next._tree.txt +4 -0
- package/out/ping/__next.ping.__PAGE__.txt +10 -0
- package/out/ping/__next.ping.txt +5 -0
- package/out/ping/index.html +15 -0
- package/out/ping/index.txt +21 -0
- package/out/pwa-512x512.png +0 -0
- package/out/web3/__next._full.txt +21 -0
- package/out/web3/__next._head.txt +5 -0
- package/out/web3/__next._index.txt +7 -0
- package/out/web3/__next._tree.txt +3 -0
- package/out/web3/__next.web3.__PAGE__.txt +9 -0
- package/out/web3/__next.web3.txt +6 -0
- package/out/web3/ed25519/__next._full.txt +20 -0
- package/out/web3/ed25519/__next._head.txt +5 -0
- package/out/web3/ed25519/__next._index.txt +7 -0
- package/out/web3/ed25519/__next._tree.txt +3 -0
- package/out/web3/ed25519/__next.web3.ed25519.__PAGE__.txt +6 -0
- package/out/web3/ed25519/__next.web3.ed25519.txt +5 -0
- package/out/web3/ed25519/__next.web3.txt +6 -0
- package/out/web3/ed25519/index.html +1 -0
- package/out/web3/ed25519/index.txt +20 -0
- package/out/web3/index.html +15 -0
- package/out/web3/index.txt +21 -0
- package/out/web3/tools/__next._full.txt +20 -0
- package/out/web3/tools/__next._head.txt +5 -0
- package/out/web3/tools/__next._index.txt +7 -0
- package/out/web3/tools/__next._tree.txt +3 -0
- package/out/web3/tools/__next.web3.tools.__PAGE__.txt +6 -0
- package/out/web3/tools/__next.web3.tools.txt +5 -0
- package/out/web3/tools/__next.web3.txt +6 -0
- package/out/web3/tools/index.html +1 -0
- package/out/web3/tools/index.txt +20 -0
- package/package.json +162 -53
- package/public/fonts/jetbrains-mono-latin-400-normal.woff2 +0 -0
- package/public/fonts/jetbrains-mono-latin-500-normal.woff2 +0 -0
- package/public/fonts/jetbrains-mono-latin-600-normal.woff2 +0 -0
- package/public/fonts/jetbrains-mono-latin-700-normal.woff2 +0 -0
- package/public/pwa-512x512.png +0 -0
- package/server/cli.js +3 -0
- package/server/index.js +995 -0
- package/{src → server/src}/config.js +51 -50
- package/{src → server/src}/core/cid.js +157 -150
- package/{src → server/src}/index.js +1952 -1669
- package/server/src/utils/api.js +68 -0
- package/server/src/utils/avatar.js +11 -0
- package/{src → server/src}/utils/errors.js +70 -66
- package/server/src/utils/mostWallet.js +42 -0
- package/server/src/utils/mp.js +105 -0
- package/{src → server/src}/utils/security.js +173 -169
- package/server/src/utils/userIdentity.js +93 -0
- package/cli.js +0 -2
- package/out/_next/static/chunks/00l-yd3t8dvwz.js +0 -5
- package/out/_next/static/chunks/03k8t3tgym~8~.js +0 -1
- package/out/_next/static/chunks/09vfh8lfuacc0.css +0 -1
- package/out/_next/static/chunks/0dbhjjzl8qfwv.js +0 -1
- package/out/_next/static/chunks/0f73psqhr8dre.css +0 -1
- package/out/_next/static/chunks/0fbi7z4_.4j1j.js +0 -1
- package/out/_next/static/chunks/0ht900cau6_ur.js +0 -31
- package/out/_next/static/chunks/0ohm.ia-4ec60.js +0 -1
- package/out/_next/static/chunks/0u5ydb-f0.vxl.js +0 -1
- package/out/_next/static/chunks/14t2m1on-s5v~.js +0 -1
- package/out/_next/static/chunks/turbopack-076ce9exut_h3.js +0 -1
- package/out/_not-found/__next._not-found/__PAGE__.txt +0 -5
- package/out/app.css +0 -1535
- package/out/bundle.js +0 -107
- package/out/bundle.js.map +0 -7
- package/out/chat/__next.chat/__PAGE__.txt +0 -9
- package/out/chat-page.js +0 -112
- package/out/chat.css +0 -378
- package/out/index.js +0 -148
- package/public/app.css +0 -1535
- package/public/bundle.js +0 -107
- package/public/bundle.js.map +0 -7
- package/public/chat-page.js +0 -112
- package/public/chat.css +0 -378
- package/public/index.js +0 -148
- package/server.js +0 -880
- package/src/utils/api.js +0 -6
- /package/out/_next/static/{0h4f4QFk_KC9FlSRfQACk → sV38nXrv3xVVO6wvSdFlZ}/_buildManifest.js +0 -0
- /package/out/_next/static/{0h4f4QFk_KC9FlSRfQACk → sV38nXrv3xVVO6wvSdFlZ}/_clientMiddlewareManifest.js +0 -0
- /package/out/_next/static/{0h4f4QFk_KC9FlSRfQACk → sV38nXrv3xVVO6wvSdFlZ}/_ssgManifest.js +0 -0
|
@@ -1,50 +1,51 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 应用配置
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
// 文件大小限制
|
|
6
|
-
export const MAX_FILE_SIZE = 100 * 1024 * 1024 * 1024 // 100 GB
|
|
7
|
-
|
|
8
|
-
// 网络超时(毫秒)
|
|
9
|
-
export const CONNECTION_TIMEOUT = 120000
|
|
10
|
-
export const DOWNLOAD_TIMEOUT = 900000
|
|
11
|
-
|
|
12
|
-
// P2P 设置
|
|
13
|
-
export const GLOBAL_SHARED_SEED_STRING = 'most-box-global-shared-seed-v1'
|
|
14
|
-
export const MAX_PEERS = 64
|
|
15
|
-
export const SWARM_KEEP_ALIVE_INTERVAL = 5000
|
|
16
|
-
export const SWARM_RANDOM_PUNCH_INTERVAL = 20000
|
|
17
|
-
|
|
18
|
-
// 驱动器超时(毫秒)
|
|
19
|
-
export const DRIVE_ENTRY_TIMEOUT = 10000
|
|
20
|
-
export const DRIVE_SYNC_TIMEOUT = 10000
|
|
21
|
-
export const STREAM_READ_TIMEOUT = 10000
|
|
22
|
-
|
|
23
|
-
//
|
|
24
|
-
export const
|
|
25
|
-
|
|
26
|
-
//
|
|
27
|
-
export const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
//
|
|
35
|
-
export const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
]
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
export const
|
|
47
|
-
export const
|
|
48
|
-
export const
|
|
49
|
-
export const
|
|
50
|
-
export const
|
|
1
|
+
/**
|
|
2
|
+
* 应用配置
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// 文件大小限制
|
|
6
|
+
export const MAX_FILE_SIZE = 100 * 1024 * 1024 * 1024 // 100 GB
|
|
7
|
+
|
|
8
|
+
// 网络超时(毫秒)
|
|
9
|
+
export const CONNECTION_TIMEOUT = 120000
|
|
10
|
+
export const DOWNLOAD_TIMEOUT = 900000
|
|
11
|
+
|
|
12
|
+
// P2P 设置
|
|
13
|
+
export const GLOBAL_SHARED_SEED_STRING = 'most-box-global-shared-seed-v1'
|
|
14
|
+
export const MAX_PEERS = 64
|
|
15
|
+
export const SWARM_KEEP_ALIVE_INTERVAL = 5000
|
|
16
|
+
export const SWARM_RANDOM_PUNCH_INTERVAL = 20000
|
|
17
|
+
|
|
18
|
+
// 驱动器超时(毫秒)
|
|
19
|
+
export const DRIVE_ENTRY_TIMEOUT = 10000
|
|
20
|
+
export const DRIVE_SYNC_TIMEOUT = 10000
|
|
21
|
+
export const STREAM_READ_TIMEOUT = 10000
|
|
22
|
+
|
|
23
|
+
// 文件写入块大小(字节)
|
|
24
|
+
export const FILE_WRITE_CHUNK_SIZE = 64 * 1024
|
|
25
|
+
|
|
26
|
+
// 下载轮询间隔(毫秒)
|
|
27
|
+
export const DOWNLOAD_POLL_INTERVAL_MIN = 500
|
|
28
|
+
export const DOWNLOAD_POLL_INTERVAL_MAX = 2000
|
|
29
|
+
export const DRIVE_UPDATE_INTERVAL = 2000
|
|
30
|
+
|
|
31
|
+
// 进度更新节流间隔(毫秒)
|
|
32
|
+
export const PROGRESS_THROTTLE = 500
|
|
33
|
+
|
|
34
|
+
// 默认读取限制
|
|
35
|
+
export const DEFAULT_READ_LIMIT = 10000
|
|
36
|
+
|
|
37
|
+
// DHT 引导节点,用于 Hyperswarm/HyperDHT
|
|
38
|
+
// 使用与 Keet.io/HyperDHT 相同的引导节点以保证兼容性
|
|
39
|
+
// 格式:[suggested-IP@]<host>:<port> 以避免 DNS 调用
|
|
40
|
+
export const SWARM_BOOTSTRAP = [
|
|
41
|
+
'88.99.3.86@node1.hyperdht.org:49737',
|
|
42
|
+
'142.93.90.113@node2.hyperdht.org:49737',
|
|
43
|
+
'138.68.147.8@node3.hyperdht.org:49737',
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
export const CHANNEL_NAME_MIN_LENGTH = 3
|
|
47
|
+
export const CHANNEL_NAME_MAX_LENGTH = 20
|
|
48
|
+
export const CHANNEL_NAME_REGEX = /^[a-zA-Z0-9_-]+$/
|
|
49
|
+
export const CHANNEL_NAME_PREFIX = 'most-box-room-'
|
|
50
|
+
export const CHANNEL_MESSAGE_LIMIT = 100
|
|
51
|
+
export const MAX_MESSAGE_LENGTH = 10000
|
|
@@ -1,150 +1,157 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CID(内容标识符)计算模块
|
|
3
|
-
* 处理文件的 IPFS UnixFS CID 计算
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import fs from 'node:fs'
|
|
7
|
-
import { Readable } from 'node:stream'
|
|
8
|
-
import { importer } from 'ipfs-unixfs-importer'
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* 用于 CID 计算的虚拟 Blockstore
|
|
12
|
-
* 不存储任何数据,仅用于流式 CID 计算
|
|
13
|
-
*/
|
|
14
|
-
function createDummyBlockstore() {
|
|
15
|
-
return {
|
|
16
|
-
put: async (key,
|
|
17
|
-
get: async () => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* @param {
|
|
29
|
-
* @param {
|
|
30
|
-
* @param {
|
|
31
|
-
* @
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
let
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
} else if (Buffer.isBuffer(content)) {
|
|
60
|
-
totalSize = content.length
|
|
61
|
-
source = [
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
throw new Error(
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
if (!cidString
|
|
105
|
-
return { valid: false, error: '
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
cidString =
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
cidString =
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
1
|
+
/**
|
|
2
|
+
* CID(内容标识符)计算模块
|
|
3
|
+
* 处理文件的 IPFS UnixFS CID 计算
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import fs from 'node:fs'
|
|
7
|
+
import { Readable } from 'node:stream'
|
|
8
|
+
import { importer } from 'ipfs-unixfs-importer'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* 用于 CID 计算的虚拟 Blockstore
|
|
12
|
+
* 不存储任何数据,仅用于流式 CID 计算
|
|
13
|
+
*/
|
|
14
|
+
function createDummyBlockstore() {
|
|
15
|
+
return {
|
|
16
|
+
put: async (key, _val) => key,
|
|
17
|
+
get: async () => {
|
|
18
|
+
throw new Error('Not implemented')
|
|
19
|
+
},
|
|
20
|
+
has: async () => false,
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* 计算内容的 IPFS UnixFS CID v1
|
|
26
|
+
* 使用流式方法高效处理大文件
|
|
27
|
+
*
|
|
28
|
+
* @param {string|Buffer|AsyncIterable} content - 文件路径(字符串)、Buffer 或异步迭代器
|
|
29
|
+
* @param {object} options - 计算选项
|
|
30
|
+
* @param {boolean} [options.rawLeaves=true] - 使用原始叶子节点以支持现代 CID
|
|
31
|
+
* @param {number} [options.cidVersion=1] - CID 版本(0 或 1)
|
|
32
|
+
* @param {number} [options.size] - 总字节数(可选,自动检测)
|
|
33
|
+
* @returns {Promise<{cid: import('multiformats/cid').CID, size: number}>}
|
|
34
|
+
*/
|
|
35
|
+
export async function calculateCid(content, options = {}) {
|
|
36
|
+
const { rawLeaves = true, cidVersion = 1, size: providedSize } = options
|
|
37
|
+
|
|
38
|
+
const blockstore = createDummyBlockstore()
|
|
39
|
+
|
|
40
|
+
let rootCid = null
|
|
41
|
+
let totalSize = providedSize || 0
|
|
42
|
+
|
|
43
|
+
let source
|
|
44
|
+
|
|
45
|
+
if (typeof content === 'string') {
|
|
46
|
+
const filePath = content
|
|
47
|
+
try {
|
|
48
|
+
const stat = await fs.promises.stat(filePath)
|
|
49
|
+
totalSize = stat.size
|
|
50
|
+
} catch {
|
|
51
|
+
// 忽略 stat 错误,大小将为 0
|
|
52
|
+
}
|
|
53
|
+
source = [
|
|
54
|
+
{
|
|
55
|
+
path: 'file',
|
|
56
|
+
content: fs.createReadStream(filePath),
|
|
57
|
+
},
|
|
58
|
+
]
|
|
59
|
+
} else if (Buffer.isBuffer(content)) {
|
|
60
|
+
totalSize = content.length
|
|
61
|
+
source = [
|
|
62
|
+
{
|
|
63
|
+
path: 'file',
|
|
64
|
+
content: Readable.from(content),
|
|
65
|
+
},
|
|
66
|
+
]
|
|
67
|
+
} else {
|
|
68
|
+
source = [
|
|
69
|
+
{
|
|
70
|
+
path: 'file',
|
|
71
|
+
content,
|
|
72
|
+
},
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
for await (const entry of importer(source, blockstore, {
|
|
78
|
+
cidVersion,
|
|
79
|
+
rawLeaves,
|
|
80
|
+
wrapWithDirectory: false,
|
|
81
|
+
})) {
|
|
82
|
+
rootCid = entry.cid
|
|
83
|
+
}
|
|
84
|
+
} catch (err) {
|
|
85
|
+
throw new Error(`Failed to calculate CID: ${err.message}`)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (!rootCid) {
|
|
89
|
+
throw new Error('Failed to calculate CID: no root CID generated')
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return {
|
|
93
|
+
cid: rootCid,
|
|
94
|
+
size: totalSize,
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* 验证 CID 字符串
|
|
100
|
+
* @param {string} cidString - 要验证的 CID 字符串
|
|
101
|
+
* @returns {{ valid: boolean, error?: string }}
|
|
102
|
+
*/
|
|
103
|
+
export function validateCidString(cidString) {
|
|
104
|
+
if (!cidString || typeof cidString !== 'string') {
|
|
105
|
+
return { valid: false, error: 'CID must be a non-empty string' }
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (!cidString.startsWith('b')) {
|
|
109
|
+
return {
|
|
110
|
+
valid: false,
|
|
111
|
+
error: 'Invalid CID format: CID v1 must start with "b"',
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return { valid: true }
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* 解析 most:// 链接并提取 CID
|
|
120
|
+
* @param {string} link - most://<cid> 格式的链接
|
|
121
|
+
* @returns {{ cid: string, error?: string }}
|
|
122
|
+
*/
|
|
123
|
+
export function parseMostLink(link) {
|
|
124
|
+
if (!link || typeof link !== 'string') {
|
|
125
|
+
return { cid: '', error: 'Link must be a non-empty string' }
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
let cidString = link
|
|
129
|
+
|
|
130
|
+
if (link.startsWith('most://')) {
|
|
131
|
+
cidString = link.replace('most://', '')
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// 移除尾部斜杠和空白
|
|
135
|
+
cidString = cidString.trim().replace(/\/+$/, '')
|
|
136
|
+
|
|
137
|
+
// 移除 query string,提取 filename
|
|
138
|
+
let fileName = null
|
|
139
|
+
if (cidString.includes('?')) {
|
|
140
|
+
const [cidPart, queryPart] = cidString.split('?')
|
|
141
|
+
cidString = cidPart
|
|
142
|
+
const params = new URLSearchParams(queryPart)
|
|
143
|
+
fileName = params.get('filename')
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// 处理可能的额外路径的 URL 解析
|
|
147
|
+
if (cidString.includes('/')) {
|
|
148
|
+
cidString = cidString.split('/')[0]
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const validation = validateCidString(cidString)
|
|
152
|
+
if (!validation.valid) {
|
|
153
|
+
return { cid: '', error: validation.error }
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return { cid: cidString, fileName }
|
|
157
|
+
}
|