@autonomys/auto-drive 1.2.7 → 1.3.0
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/README.md +22 -25
- package/dist/api/calls/download.d.ts +3 -3
- package/dist/api/calls/download.d.ts.map +1 -1
- package/dist/api/calls/index.d.ts +26 -19
- package/dist/api/calls/index.d.ts.map +1 -1
- package/dist/api/calls/read.d.ts +35 -18
- package/dist/api/calls/read.d.ts.map +1 -1
- package/dist/api/calls/read.js +39 -9
- package/dist/api/calls/upload.d.ts +11 -11
- package/dist/api/calls/upload.d.ts.map +1 -1
- package/dist/api/calls/upload.js +5 -5
- package/dist/api/calls/write.d.ts +9 -9
- package/dist/api/calls/write.d.ts.map +1 -1
- package/dist/api/calls/write.js +4 -4
- package/dist/api/connection.d.ts +2 -24
- package/dist/api/connection.d.ts.map +1 -1
- package/dist/api/connection.js +6 -30
- package/dist/api/handler.d.ts +3 -0
- package/dist/api/handler.d.ts.map +1 -0
- package/dist/api/handler.js +30 -0
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +2 -0
- package/dist/api/models/objects.d.ts +4 -0
- package/dist/api/models/objects.d.ts.map +1 -1
- package/dist/api/type.d.ts +172 -0
- package/dist/api/type.d.ts.map +1 -0
- package/dist/api/type.js +8 -0
- package/dist/api/types.d.ts +172 -0
- package/dist/api/types.d.ts.map +1 -0
- package/dist/api/types.js +8 -0
- package/dist/api/wrappers.d.ts +2 -115
- package/dist/api/wrappers.d.ts.map +1 -1
- package/dist/api/wrappers.js +178 -240
- package/dist/fs/wrappers.d.ts +1 -2
- package/dist/fs/wrappers.d.ts.map +1 -1
- package/dist/fs/wrappers.js +18 -19
- package/dist/node.d.ts +2 -2
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +25 -2
- package/package.json +4 -4
- package/src/api/calls/download.ts +3 -3
- package/src/api/calls/read.ts +61 -18
- package/src/api/calls/upload.ts +11 -11
- package/src/api/calls/write.ts +10 -10
- package/src/api/connection.ts +6 -61
- package/src/api/handler.ts +34 -0
- package/src/api/index.ts +2 -0
- package/src/api/models/objects.ts +5 -0
- package/src/api/types.ts +201 -0
- package/src/api/wrappers.ts +247 -300
- package/src/fs/wrappers.ts +11 -14
- package/src/node.ts +2 -2
package/src/api/wrappers.ts
CHANGED
|
@@ -3,21 +3,17 @@ import { asyncByChunk, asyncFromStream, bufferToIterable, fileToIterable } from
|
|
|
3
3
|
import { progressToPercentage } from '../utils/misc'
|
|
4
4
|
import { publicDownloadUrl } from './calls/download'
|
|
5
5
|
import { apiCalls } from './calls/index'
|
|
6
|
-
import {
|
|
6
|
+
import { ObjectSummary, Scope } from './models'
|
|
7
|
+
import { PaginatedResult } from './models/common'
|
|
7
8
|
import { GenericFile, GenericFileWithinFolder } from './models/file'
|
|
8
9
|
import { constructFromInput, constructZipBlobFromTreeAndPaths } from './models/folderTree'
|
|
9
10
|
import { SubscriptionInfo } from './models/user'
|
|
10
|
-
|
|
11
|
-
export type UploadFileOptions = {
|
|
12
|
-
password?: string
|
|
13
|
-
compression?: boolean
|
|
14
|
-
onProgress?: (progress: number) => void
|
|
15
|
-
}
|
|
11
|
+
import { AutoDriveApi, AutoDriveApiHandler, UploadFileOptions } from './types'
|
|
16
12
|
|
|
17
13
|
const UPLOAD_FILE_CHUNK_SIZE = 1024 * 1024
|
|
18
14
|
|
|
19
15
|
const uploadFileChunks = (
|
|
20
|
-
api:
|
|
16
|
+
api: AutoDriveApiHandler,
|
|
21
17
|
fileUploadId: string,
|
|
22
18
|
asyncIterable: AsyncIterable<Buffer>,
|
|
23
19
|
uploadChunkSize: number = UPLOAD_FILE_CHUNK_SIZE,
|
|
@@ -41,35 +37,72 @@ const uploadFileChunks = (
|
|
|
41
37
|
})
|
|
42
38
|
}
|
|
43
39
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
40
|
+
export const createApiInterface = (api: AutoDriveApiHandler): AutoDriveApi => {
|
|
41
|
+
const uploadFileFromInput = (
|
|
42
|
+
file: File,
|
|
43
|
+
options: UploadFileOptions = {},
|
|
44
|
+
uploadChunkSize?: number,
|
|
45
|
+
): Promise<string> => {
|
|
46
|
+
const { password = undefined, compression = true } = options
|
|
47
|
+
return new Promise(async (resolve, reject) => {
|
|
48
|
+
const { compressFile, CompressionAlgorithm, encryptFile, EncryptionAlgorithm } = await import(
|
|
49
|
+
'@autonomys/auto-dag-data'
|
|
50
|
+
)
|
|
51
|
+
let asyncIterable: AsyncIterable<Buffer> = fileToIterable(file)
|
|
52
|
+
|
|
53
|
+
if (compression) {
|
|
54
|
+
asyncIterable = compressFile(asyncIterable, {
|
|
55
|
+
level: 9,
|
|
56
|
+
algorithm: CompressionAlgorithm.ZLIB,
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (password) {
|
|
61
|
+
asyncIterable = encryptFile(asyncIterable, password, {
|
|
62
|
+
algorithm: EncryptionAlgorithm.AES_256_GCM,
|
|
63
|
+
})
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const uploadOptions = {
|
|
67
|
+
compression: compression
|
|
68
|
+
? {
|
|
69
|
+
level: 9,
|
|
70
|
+
algorithm: CompressionAlgorithm.ZLIB,
|
|
71
|
+
}
|
|
72
|
+
: undefined,
|
|
73
|
+
encryption: password
|
|
74
|
+
? {
|
|
75
|
+
algorithm: EncryptionAlgorithm.AES_256_GCM,
|
|
76
|
+
}
|
|
77
|
+
: undefined,
|
|
78
|
+
}
|
|
79
|
+
const fileUpload = await apiCalls.createFileUpload(api, {
|
|
80
|
+
mimeType: mime.lookup(file.name) || undefined,
|
|
81
|
+
filename: file.name,
|
|
82
|
+
uploadOptions,
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
await uploadFileChunks(api, fileUpload.id, asyncIterable, uploadChunkSize, (bytes) => {
|
|
86
|
+
options.onProgress?.(progressToPercentage(bytes, file.size))
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
const result = await apiCalls.completeUpload(api, { uploadId: fileUpload.id })
|
|
90
|
+
|
|
91
|
+
resolve(result.cid)
|
|
92
|
+
})
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const uploadFile = async (
|
|
96
|
+
file: GenericFile,
|
|
97
|
+
options: UploadFileOptions = {},
|
|
98
|
+
uploadChunkSize?: number,
|
|
99
|
+
): Promise<string> => {
|
|
100
|
+
const { password = undefined, compression = true } = options
|
|
101
|
+
|
|
69
102
|
const { compressFile, CompressionAlgorithm, encryptFile, EncryptionAlgorithm } = await import(
|
|
70
103
|
'@autonomys/auto-dag-data'
|
|
71
104
|
)
|
|
72
|
-
let asyncIterable: AsyncIterable<Buffer> =
|
|
105
|
+
let asyncIterable: AsyncIterable<Buffer> = file.read()
|
|
73
106
|
|
|
74
107
|
if (compression) {
|
|
75
108
|
asyncIterable = compressFile(asyncIterable, {
|
|
@@ -109,302 +142,216 @@ export const uploadFileFromInput = (
|
|
|
109
142
|
|
|
110
143
|
const result = await apiCalls.completeUpload(api, { uploadId: fileUpload.id })
|
|
111
144
|
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
}
|
|
145
|
+
return result.cid
|
|
146
|
+
}
|
|
115
147
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
uploadChunkSize?: number,
|
|
138
|
-
): Promise<string> => {
|
|
139
|
-
const { password = undefined, compression = true } = options
|
|
140
|
-
|
|
141
|
-
const { compressFile, CompressionAlgorithm, encryptFile, EncryptionAlgorithm } = await import(
|
|
142
|
-
'@autonomys/auto-dag-data'
|
|
143
|
-
)
|
|
144
|
-
let asyncIterable: AsyncIterable<Buffer> = file.read()
|
|
145
|
-
|
|
146
|
-
if (compression) {
|
|
147
|
-
asyncIterable = compressFile(asyncIterable, {
|
|
148
|
-
level: 9,
|
|
149
|
-
algorithm: CompressionAlgorithm.ZLIB,
|
|
150
|
-
})
|
|
148
|
+
const uploadObjectAsJSON = async (
|
|
149
|
+
object: unknown,
|
|
150
|
+
name?: string | undefined,
|
|
151
|
+
options: UploadFileOptions = {},
|
|
152
|
+
uploadChunkSize?: number,
|
|
153
|
+
): Promise<string> => {
|
|
154
|
+
try {
|
|
155
|
+
const json = Buffer.from(JSON.stringify(object))
|
|
156
|
+
return uploadFile(
|
|
157
|
+
{
|
|
158
|
+
read: () => bufferToIterable(json),
|
|
159
|
+
name: name || 'object.json',
|
|
160
|
+
mimeType: 'application/json',
|
|
161
|
+
size: json.length,
|
|
162
|
+
},
|
|
163
|
+
options,
|
|
164
|
+
uploadChunkSize,
|
|
165
|
+
)
|
|
166
|
+
} catch (e) {
|
|
167
|
+
throw new Error('Failed to serialize object to JSON')
|
|
168
|
+
}
|
|
151
169
|
}
|
|
152
170
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
171
|
+
const uploadFolderFromInput = async (
|
|
172
|
+
fileList: FileList | File[],
|
|
173
|
+
{
|
|
174
|
+
uploadChunkSize,
|
|
175
|
+
password,
|
|
176
|
+
onProgress,
|
|
177
|
+
}: {
|
|
178
|
+
uploadChunkSize?: number
|
|
179
|
+
password?: string
|
|
180
|
+
onProgress?: (progress: number) => void
|
|
181
|
+
} = {},
|
|
182
|
+
): Promise<string> => {
|
|
183
|
+
const files = fileList instanceof FileList ? Array.from(fileList) : fileList
|
|
184
|
+
const fileTree = constructFromInput(files)
|
|
185
|
+
|
|
186
|
+
// If password is provided, we zip the files and upload the zip file
|
|
187
|
+
if (password) {
|
|
188
|
+
const filesMap: Record<string, File> = Object.fromEntries(
|
|
189
|
+
files.map((file) => [file.webkitRelativePath, file]),
|
|
190
|
+
)
|
|
191
|
+
const zipBlob = await constructZipBlobFromTreeAndPaths(fileTree, filesMap)
|
|
192
|
+
const name = fileList[0].webkitRelativePath.split('/').filter(Boolean)[0]!
|
|
193
|
+
|
|
194
|
+
return uploadFile(
|
|
195
|
+
{
|
|
196
|
+
read: () => fileToIterable(zipBlob),
|
|
197
|
+
name: `${name}.zip`,
|
|
198
|
+
mimeType: 'application/zip',
|
|
199
|
+
size: zipBlob.size,
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
password,
|
|
203
|
+
compression: true,
|
|
204
|
+
onProgress,
|
|
205
|
+
},
|
|
206
|
+
)
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Otherwise, we upload the files as a folder w/o compression or encryption
|
|
210
|
+
const folderUpload = await apiCalls.createFolderUpload(api, {
|
|
211
|
+
fileTree,
|
|
156
212
|
})
|
|
157
|
-
}
|
|
158
213
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
214
|
+
let currentBytesUploaded = 0
|
|
215
|
+
const totalSize = files.reduce((acc, file) => acc + file.size, 0)
|
|
216
|
+
for (const file of files) {
|
|
217
|
+
await uploadFileWithinFolderUpload(
|
|
218
|
+
folderUpload.id,
|
|
219
|
+
{
|
|
220
|
+
read: () => fileToIterable(file),
|
|
221
|
+
name: file.name,
|
|
222
|
+
mimeType: mime.lookup(file.name) || undefined,
|
|
223
|
+
size: file.size,
|
|
224
|
+
path: file.webkitRelativePath,
|
|
225
|
+
},
|
|
226
|
+
uploadChunkSize,
|
|
227
|
+
{
|
|
228
|
+
onProgress: (progress) => {
|
|
229
|
+
onProgress?.(progressToPercentage(currentBytesUploaded + progress, totalSize))
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
)
|
|
233
|
+
currentBytesUploaded += file.size
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const result = await apiCalls.completeUpload(api, { uploadId: folderUpload.id })
|
|
237
|
+
|
|
238
|
+
return result.cid
|
|
171
239
|
}
|
|
172
|
-
const fileUpload = await apiCalls.createFileUpload(api, {
|
|
173
|
-
mimeType: mime.lookup(file.name) || undefined,
|
|
174
|
-
filename: file.name,
|
|
175
|
-
uploadOptions,
|
|
176
|
-
})
|
|
177
240
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
241
|
+
const uploadFileWithinFolderUpload = async (
|
|
242
|
+
uploadId: string,
|
|
243
|
+
file: GenericFileWithinFolder,
|
|
244
|
+
uploadChunkSize?: number,
|
|
245
|
+
options: Pick<UploadFileOptions, 'onProgress'> = {},
|
|
246
|
+
): Promise<string> => {
|
|
247
|
+
const fileUpload = await apiCalls.createFileUploadWithinFolderUpload(api, {
|
|
248
|
+
uploadId,
|
|
249
|
+
name: file.name,
|
|
250
|
+
mimeType: file.mimeType,
|
|
251
|
+
relativeId: file.path,
|
|
252
|
+
uploadOptions: {},
|
|
253
|
+
})
|
|
181
254
|
|
|
182
|
-
|
|
255
|
+
await uploadFileChunks(api, fileUpload.id, file.read(), uploadChunkSize, options.onProgress)
|
|
183
256
|
|
|
184
|
-
|
|
185
|
-
}
|
|
257
|
+
const result = await apiCalls.completeUpload(api, { uploadId: fileUpload.id })
|
|
186
258
|
|
|
187
|
-
|
|
188
|
-
* Uploads an object as a JSON file to the server.
|
|
189
|
-
*
|
|
190
|
-
* This function serializes the provided object to a JSON string,
|
|
191
|
-
* and then uploads the JSON string as a file to the server.
|
|
192
|
-
*
|
|
193
|
-
* @param {AutoDriveApi} api - The API instance used to send requests.
|
|
194
|
-
* @param {File | GenericFile} file - The file to be uploaded, which can be a File or a GenericFile.
|
|
195
|
-
* @param {UploadFileOptions} options - Options for the upload process.
|
|
196
|
-
* @param {string} [options.password] - The password for encryption (optional).
|
|
197
|
-
* @param {boolean} [options.compression=true] - Whether to compress the file (optional).
|
|
198
|
-
* @param {number} [uploadChunkSize] - The size of each chunk to upload (optional).
|
|
199
|
-
* @returns {Promise<string>} - The CID of the uploaded file.
|
|
200
|
-
* @throws {Error} - Throws an error if the upload fails at any stage.
|
|
201
|
-
*/
|
|
202
|
-
export const uploadObjectAsJSON = async (
|
|
203
|
-
api: AutoDriveApi,
|
|
204
|
-
object: unknown,
|
|
205
|
-
name?: string | undefined,
|
|
206
|
-
options: UploadFileOptions = {},
|
|
207
|
-
uploadChunkSize?: number,
|
|
208
|
-
): Promise<string> => {
|
|
209
|
-
try {
|
|
210
|
-
const json = Buffer.from(JSON.stringify(object))
|
|
211
|
-
return uploadFile(
|
|
212
|
-
api,
|
|
213
|
-
{
|
|
214
|
-
read: () => bufferToIterable(json),
|
|
215
|
-
name: name || 'object.json',
|
|
216
|
-
mimeType: 'application/json',
|
|
217
|
-
size: json.length,
|
|
218
|
-
},
|
|
219
|
-
options,
|
|
220
|
-
uploadChunkSize,
|
|
221
|
-
)
|
|
222
|
-
} catch (e) {
|
|
223
|
-
throw new Error('Failed to serialize object to JSON')
|
|
259
|
+
return result.cid
|
|
224
260
|
}
|
|
225
|
-
}
|
|
226
261
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
* This function retrieves all files within the specified folder,
|
|
231
|
-
* constructs a file tree representation, and initiates the upload
|
|
232
|
-
* process. It also handles optional compression of the files during
|
|
233
|
-
* the upload. If a password is provided, the files will be zipped
|
|
234
|
-
* before uploading.
|
|
235
|
-
*
|
|
236
|
-
* @param {AutoDriveApi} api - The API instance used to send requests.
|
|
237
|
-
* @param {FileList | File[]} fileList - The list of files to be uploaded.
|
|
238
|
-
* @param {Object} options - Options for the upload process.
|
|
239
|
-
* @param {number} [options.uploadChunkSize] - The size of each chunk to upload (optional).
|
|
240
|
-
* @param {string} [options.password] - The password for encryption (optional).
|
|
241
|
-
* @returns {PromisedObservable<UploadFileStatus | UploadFolderStatus>} - An observable that emits the upload status.
|
|
242
|
-
* @throws {Error} - Throws an error if the upload fails at any stage.
|
|
243
|
-
*/
|
|
244
|
-
export const uploadFolderFromInput = async (
|
|
245
|
-
api: AutoDriveApi,
|
|
246
|
-
fileList: FileList | File[],
|
|
247
|
-
{
|
|
248
|
-
uploadChunkSize,
|
|
249
|
-
password,
|
|
250
|
-
onProgress,
|
|
251
|
-
}: { uploadChunkSize?: number; password?: string; onProgress?: (progress: number) => void } = {},
|
|
252
|
-
): Promise<string> => {
|
|
253
|
-
const files = fileList instanceof FileList ? Array.from(fileList) : fileList
|
|
254
|
-
const fileTree = constructFromInput(files)
|
|
255
|
-
|
|
256
|
-
// If password is provided, we zip the files and upload the zip file
|
|
257
|
-
if (password) {
|
|
258
|
-
const filesMap: Record<string, File> = Object.fromEntries(
|
|
259
|
-
files.map((file) => [file.webkitRelativePath, file]),
|
|
260
|
-
)
|
|
261
|
-
const zipBlob = await constructZipBlobFromTreeAndPaths(fileTree, filesMap)
|
|
262
|
-
const name = fileList[0].webkitRelativePath.split('/').filter(Boolean)[0]!
|
|
263
|
-
|
|
264
|
-
return uploadFile(
|
|
265
|
-
api,
|
|
266
|
-
{
|
|
267
|
-
read: () => fileToIterable(zipBlob),
|
|
268
|
-
name: `${name}.zip`,
|
|
269
|
-
mimeType: 'application/zip',
|
|
270
|
-
size: zipBlob.size,
|
|
271
|
-
},
|
|
272
|
-
{
|
|
273
|
-
password,
|
|
274
|
-
compression: true,
|
|
275
|
-
onProgress,
|
|
276
|
-
},
|
|
262
|
+
const downloadFile = async (cid: string, password?: string): Promise<AsyncIterable<Buffer>> => {
|
|
263
|
+
const { decompressFile, CompressionAlgorithm, EncryptionAlgorithm, decryptFile } = await import(
|
|
264
|
+
'@autonomys/auto-dag-data'
|
|
277
265
|
)
|
|
278
|
-
}
|
|
279
266
|
|
|
280
|
-
|
|
281
|
-
const folderUpload = await apiCalls.createFolderUpload(api, {
|
|
282
|
-
fileTree,
|
|
283
|
-
})
|
|
267
|
+
const metadata = await apiCalls.getObjectMetadata(api, { cid })
|
|
284
268
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
mimeType: mime.lookup(file.name) || undefined,
|
|
295
|
-
size: file.size,
|
|
296
|
-
path: file.webkitRelativePath,
|
|
297
|
-
},
|
|
298
|
-
uploadChunkSize,
|
|
299
|
-
{
|
|
300
|
-
onProgress: (progress) => {
|
|
301
|
-
onProgress?.(progressToPercentage(currentBytesUploaded + progress, totalSize))
|
|
302
|
-
},
|
|
303
|
-
},
|
|
304
|
-
)
|
|
305
|
-
currentBytesUploaded += file.size
|
|
306
|
-
}
|
|
269
|
+
let iterable = asyncFromStream(await apiCalls.downloadObject(api, { cid }))
|
|
270
|
+
if (metadata.uploadOptions?.encryption) {
|
|
271
|
+
if (!password) {
|
|
272
|
+
throw new Error('Password is required to decrypt the file')
|
|
273
|
+
}
|
|
274
|
+
iterable = decryptFile(iterable, password, {
|
|
275
|
+
algorithm: EncryptionAlgorithm.AES_256_GCM,
|
|
276
|
+
})
|
|
277
|
+
}
|
|
307
278
|
|
|
308
|
-
|
|
279
|
+
if (metadata.uploadOptions?.compression) {
|
|
280
|
+
iterable = decompressFile(iterable, {
|
|
281
|
+
algorithm: CompressionAlgorithm.ZLIB,
|
|
282
|
+
})
|
|
283
|
+
}
|
|
309
284
|
|
|
310
|
-
|
|
311
|
-
}
|
|
285
|
+
return iterable
|
|
286
|
+
}
|
|
312
287
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
* @returns {Promise<void>} A promise that resolves when the file upload is complete.
|
|
321
|
-
*/
|
|
322
|
-
export const uploadFileWithinFolderUpload = async (
|
|
323
|
-
api: AutoDriveApi,
|
|
324
|
-
uploadId: string,
|
|
325
|
-
file: GenericFileWithinFolder,
|
|
326
|
-
uploadChunkSize?: number,
|
|
327
|
-
options: Pick<UploadFileOptions, 'onProgress'> = {},
|
|
328
|
-
): Promise<string> => {
|
|
329
|
-
const fileUpload = await apiCalls.createFileUploadWithinFolderUpload(api, {
|
|
330
|
-
uploadId,
|
|
331
|
-
name: file.name,
|
|
332
|
-
mimeType: file.mimeType,
|
|
333
|
-
relativeId: file.path,
|
|
334
|
-
uploadOptions: {},
|
|
335
|
-
})
|
|
288
|
+
const getPendingCredits = async (): Promise<{ upload: number; download: number }> => {
|
|
289
|
+
const me = await apiCalls.getMe(api)
|
|
290
|
+
return {
|
|
291
|
+
upload: me.subscription.pendingUploadCredits,
|
|
292
|
+
download: me.subscription.pendingDownloadCredits,
|
|
293
|
+
}
|
|
294
|
+
}
|
|
336
295
|
|
|
337
|
-
|
|
296
|
+
const getSubscriptionInfo = async (): Promise<SubscriptionInfo> => {
|
|
297
|
+
const me = await apiCalls.getMe(api)
|
|
338
298
|
|
|
339
|
-
|
|
299
|
+
return me.subscription
|
|
300
|
+
}
|
|
340
301
|
|
|
341
|
-
|
|
342
|
-
}
|
|
302
|
+
const publishObject = async (cid: string): Promise<string> => {
|
|
303
|
+
const result = await apiCalls.publishObject(api, { cid })
|
|
343
304
|
|
|
344
|
-
|
|
345
|
-
* Downloads a file from the AutoDrive service.
|
|
346
|
-
*
|
|
347
|
-
* @param {AutoDriveApi} api - The API instance to interact with the AutoDrive service.
|
|
348
|
-
* @param {string} cid - The CID of the file to be downloaded.
|
|
349
|
-
* @returns {Promise<ReadableStream<Uint8Array>>} A promise that resolves to a ReadableStream of the downloaded file.
|
|
350
|
-
*/
|
|
351
|
-
export const downloadFile = async (
|
|
352
|
-
api: AutoDriveApi,
|
|
353
|
-
cid: string,
|
|
354
|
-
password?: string,
|
|
355
|
-
): Promise<AsyncIterable<Buffer>> => {
|
|
356
|
-
const { decompressFile, CompressionAlgorithm, EncryptionAlgorithm, decryptFile } = await import(
|
|
357
|
-
'@autonomys/auto-dag-data'
|
|
358
|
-
)
|
|
359
|
-
|
|
360
|
-
const metadata = await apiCalls.getObjectMetadata(api, { cid })
|
|
361
|
-
|
|
362
|
-
let iterable = asyncFromStream(await apiCalls.downloadObject(api, { cid }))
|
|
363
|
-
if (metadata.uploadOptions?.encryption) {
|
|
364
|
-
if (!password) {
|
|
365
|
-
throw new Error('Password is required to decrypt the file')
|
|
366
|
-
}
|
|
367
|
-
iterable = decryptFile(iterable, password, {
|
|
368
|
-
algorithm: EncryptionAlgorithm.AES_256_GCM,
|
|
369
|
-
})
|
|
305
|
+
return publicDownloadUrl(api, result.result)
|
|
370
306
|
}
|
|
371
307
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
308
|
+
const getMyFiles = async (
|
|
309
|
+
page: number,
|
|
310
|
+
limit: number = 100,
|
|
311
|
+
): Promise<PaginatedResult<ObjectSummary>> => {
|
|
312
|
+
const result = await apiCalls.getRoots(api, {
|
|
313
|
+
scope: Scope.User,
|
|
314
|
+
limit,
|
|
315
|
+
offset: page * limit,
|
|
375
316
|
})
|
|
317
|
+
|
|
318
|
+
return result
|
|
376
319
|
}
|
|
377
320
|
|
|
378
|
-
|
|
379
|
-
}
|
|
321
|
+
const searchByNameOrCIDInMyFiles = async (value: string): Promise<ObjectSummary[]> => {
|
|
322
|
+
const results = await apiCalls.searchByNameOrCID(api, { value, scope: Scope.User })
|
|
380
323
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
)
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
upload: me.subscription.pendingUploadCredits,
|
|
387
|
-
download: me.subscription.pendingDownloadCredits,
|
|
324
|
+
const summaries = await Promise.all(
|
|
325
|
+
results.map(async (e) => apiCalls.getObjectSummary(api, { cid: e.cid })),
|
|
326
|
+
)
|
|
327
|
+
|
|
328
|
+
return summaries
|
|
388
329
|
}
|
|
389
|
-
}
|
|
390
330
|
|
|
391
|
-
|
|
392
|
-
|
|
331
|
+
const searchByNameOrCID = async (value: string): Promise<ObjectSummary[]> => {
|
|
332
|
+
const results = await apiCalls.searchByNameOrCID(api, { value, scope: Scope.Global })
|
|
393
333
|
|
|
394
|
-
|
|
395
|
-
}
|
|
334
|
+
const summaries = await Promise.all(
|
|
335
|
+
results.map(async (e) => apiCalls.getObjectSummary(api, { cid: e.cid })),
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
return summaries
|
|
339
|
+
}
|
|
396
340
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
341
|
+
return {
|
|
342
|
+
uploadFileFromInput,
|
|
343
|
+
uploadFile,
|
|
344
|
+
uploadObjectAsJSON,
|
|
345
|
+
uploadFolderFromInput,
|
|
346
|
+
uploadFileWithinFolderUpload,
|
|
347
|
+
downloadFile,
|
|
348
|
+
getPendingCredits,
|
|
349
|
+
getSubscriptionInfo,
|
|
350
|
+
publishObject,
|
|
351
|
+
getMyFiles,
|
|
352
|
+
searchByNameOrCIDInMyFiles,
|
|
353
|
+
searchByNameOrCID,
|
|
354
|
+
sendRequest: api.sendRequest,
|
|
355
|
+
baseUrl: api.baseUrl,
|
|
356
|
+
}
|
|
410
357
|
}
|
package/src/fs/wrappers.ts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import fs from 'fs'
|
|
2
2
|
import mime from 'mime-types'
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { constructZipFromTreeAndFileSystemPaths, getFiles } from './utils.js'
|
|
3
|
+
import { apiCalls } from '../api/index'
|
|
4
|
+
import { GenericFileWithinFolder } from '../api/models/file'
|
|
5
|
+
import { constructFromFileSystemEntries } from '../api/models/folderTree'
|
|
6
|
+
import { CompressionAlgorithm } from '../api/models/uploads'
|
|
7
|
+
import { AutoDriveApi, UploadFileOptions } from '../api/types'
|
|
8
|
+
import { fileToIterable } from '../utils/index'
|
|
9
|
+
import { progressToPercentage } from '../utils/misc'
|
|
10
|
+
import { constructZipFromTreeAndFileSystemPaths, getFiles } from './utils'
|
|
12
11
|
|
|
13
12
|
/**
|
|
14
13
|
* Uploads a file to the server with optional encryption and compression.
|
|
@@ -36,8 +35,7 @@ export const uploadFileFromFilepath = (
|
|
|
36
35
|
const { password = undefined, compression = true, onProgress } = options
|
|
37
36
|
const name = filePath.split('/').pop()!
|
|
38
37
|
|
|
39
|
-
return uploadFile(
|
|
40
|
-
api,
|
|
38
|
+
return api.uploadFile(
|
|
41
39
|
{
|
|
42
40
|
read: () => fs.createReadStream(filePath),
|
|
43
41
|
name,
|
|
@@ -91,8 +89,7 @@ export const uploadFolderFromFolderPath = async (
|
|
|
91
89
|
const filesMap = Object.fromEntries(files.map((file) => [file, file]))
|
|
92
90
|
const zipBlob = await constructZipFromTreeAndFileSystemPaths(fileTree, filesMap)
|
|
93
91
|
const name = folderPath.split('/').pop()!
|
|
94
|
-
return uploadFile(
|
|
95
|
-
api,
|
|
92
|
+
return api.uploadFile(
|
|
96
93
|
{
|
|
97
94
|
read: () => fileToIterable(zipBlob),
|
|
98
95
|
name: `${name}.zip`,
|
|
@@ -130,7 +127,7 @@ export const uploadFolderFromFolderPath = async (
|
|
|
130
127
|
const totalSize = genericFiles.reduce((acc, file) => acc + file.size, 0)
|
|
131
128
|
let progress = 0
|
|
132
129
|
for (const file of genericFiles) {
|
|
133
|
-
await uploadFileWithinFolderUpload(
|
|
130
|
+
await api.uploadFileWithinFolderUpload(folderUpload.id, file, uploadChunkSize, {
|
|
134
131
|
onProgress: (uploadedBytes) => {
|
|
135
132
|
onProgress?.(progressToPercentage(progress + uploadedBytes, totalSize))
|
|
136
133
|
},
|
package/src/node.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './browser
|
|
2
|
-
export * from './fs/index
|
|
1
|
+
export * from './browser'
|
|
2
|
+
export * as fs from './fs/index'
|