@autonomys/auto-drive 1.1.4 → 1.2.1
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 +42 -84
- package/dist/api/calls/index.d.ts +1 -0
- package/dist/api/calls/index.d.ts.map +1 -1
- package/dist/api/calls/read.d.ts +9 -0
- package/dist/api/calls/read.d.ts.map +1 -1
- package/dist/api/calls/read.js +18 -1
- package/dist/api/models/user.d.ts +28 -0
- package/dist/api/models/user.d.ts.map +1 -0
- package/dist/api/models/user.js +8 -0
- package/dist/api/wrappers.d.ts +30 -8
- package/dist/api/wrappers.d.ts.map +1 -1
- package/dist/api/wrappers.js +148 -137
- package/dist/fs/wrappers.d.ts +4 -5
- package/dist/fs/wrappers.d.ts.map +1 -1
- package/dist/fs/wrappers.js +33 -65
- package/dist/utils/async.d.ts +1 -0
- package/dist/utils/async.d.ts.map +1 -1
- package/dist/utils/async.js +7 -1
- package/dist/utils/autohash.d.ts +17 -0
- package/dist/utils/autohash.d.ts.map +1 -0
- package/dist/utils/autohash.js +73 -0
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +0 -1
- package/dist/utils/observable.d.ts +1 -6
- package/dist/utils/observable.d.ts.map +1 -1
- package/dist/utils/observable.js +0 -50
- package/package.json +3 -4
- package/src/api/calls/read.ts +19 -0
- package/src/api/models/user.ts +31 -0
- package/src/api/wrappers.ts +172 -114
- package/src/fs/wrappers.ts +44 -39
- package/src/utils/async.ts +4 -0
- package/src/utils/index.ts +0 -1
- package/tsconfig.json +3 -1
- package/src/utils/observable.ts +0 -19
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.getToolsFromAutoDagData = exports.AutoCID = void 0;
|
|
46
|
+
class AutoCID {
|
|
47
|
+
constructor(cid, tools) {
|
|
48
|
+
this.cid = cid;
|
|
49
|
+
this.tools = tools;
|
|
50
|
+
}
|
|
51
|
+
static create(cid) {
|
|
52
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
53
|
+
const tools = yield exports.getToolsFromAutoDagData;
|
|
54
|
+
return new AutoCID(cid, tools);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
get asString() {
|
|
58
|
+
return this.cid;
|
|
59
|
+
}
|
|
60
|
+
get asCID() {
|
|
61
|
+
return this.tools.stringToCid(this.cid);
|
|
62
|
+
}
|
|
63
|
+
get asBlake3Hash() {
|
|
64
|
+
return Buffer.from(this.tools.blake3HashFromCid(this.asCID));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
exports.AutoCID = AutoCID;
|
|
68
|
+
exports.getToolsFromAutoDagData = Promise.resolve().then(() => __importStar(require('@autonomys/auto-dag-data'))).then(({ stringToCid, blake3HashFromCid }) => {
|
|
69
|
+
return {
|
|
70
|
+
stringToCid,
|
|
71
|
+
blake3HashFromCid,
|
|
72
|
+
};
|
|
73
|
+
});
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA;AACtB,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA;AACtB,cAAc,SAAS,CAAA"}
|
package/dist/utils/index.js
CHANGED
|
@@ -16,5 +16,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./async"), exports);
|
|
18
18
|
__exportStar(require("./misc"), exports);
|
|
19
|
-
__exportStar(require("./observable"), exports);
|
|
20
19
|
__exportStar(require("./types"), exports);
|
|
@@ -1,7 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export declare class PromisedObservable<T> extends rxjs.Observable<T> {
|
|
3
|
-
constructor(subscribe?: (this: rxjs.Observable<T>, subscriber: rxjs.Subscriber<T>) => void);
|
|
4
|
-
get promise(): Promise<T>;
|
|
5
|
-
}
|
|
6
|
-
export declare const firstValueFrom: typeof rxjs.firstValueFrom, lastValueFrom: typeof rxjs.lastValueFrom;
|
|
1
|
+
export {};
|
|
7
2
|
//# sourceMappingURL=observable.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observable.d.ts","sourceRoot":"","sources":["../../src/utils/observable.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"observable.d.ts","sourceRoot":"","sources":["../../src/utils/observable.ts"],"names":[],"mappings":""}
|
package/dist/utils/observable.js
CHANGED
|
@@ -1,52 +1,2 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.lastValueFrom = exports.firstValueFrom = exports.PromisedObservable = void 0;
|
|
37
|
-
const rxjs = __importStar(require("rxjs"));
|
|
38
|
-
const asyncCallback = (callback) => {
|
|
39
|
-
return (t) => {
|
|
40
|
-
callback(t);
|
|
41
|
-
};
|
|
42
|
-
};
|
|
43
|
-
class PromisedObservable extends rxjs.Observable {
|
|
44
|
-
constructor(subscribe) {
|
|
45
|
-
super(subscribe && asyncCallback(subscribe));
|
|
46
|
-
}
|
|
47
|
-
get promise() {
|
|
48
|
-
return (0, exports.lastValueFrom)(this);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
exports.PromisedObservable = PromisedObservable;
|
|
52
|
-
exports.firstValueFrom = rxjs.firstValueFrom, exports.lastValueFrom = rxjs.lastValueFrom;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autonomys/auto-drive",
|
|
3
3
|
"packageManager": "yarn@4.2.2",
|
|
4
|
-
"version": "1.1
|
|
4
|
+
"version": "1.2.1",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -42,13 +42,12 @@
|
|
|
42
42
|
"typescript": "^5.6.3"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@autonomys/auto-dag-data": "^1.1
|
|
45
|
+
"@autonomys/auto-dag-data": "^1.2.1",
|
|
46
46
|
"jszip": "^3.10.1",
|
|
47
47
|
"mime-types": "^2.1.35",
|
|
48
48
|
"process": "^0.11.10",
|
|
49
|
-
"rxjs": "^7.8.1",
|
|
50
49
|
"stream": "^0.0.3",
|
|
51
50
|
"zod": "^3.23.8"
|
|
52
51
|
},
|
|
53
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "72285a024adcc7681ec59fabd1f061a6e40aeb09"
|
|
54
53
|
}
|
package/src/api/calls/read.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { ArgsWithoutPagination, ArgsWithPagination } from '../../utils/types'
|
|
|
2
2
|
import { AutoDriveApi } from '../connection'
|
|
3
3
|
import { PaginatedResult } from '../models/common'
|
|
4
4
|
import { ObjectInformation, ObjectSummary, Scope } from '../models/objects'
|
|
5
|
+
import { UserInfo } from '../models/user'
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Retrieves the root objects based on the specified scope.
|
|
@@ -193,3 +194,21 @@ export const getObjectMetadata = async (
|
|
|
193
194
|
|
|
194
195
|
return response.json()
|
|
195
196
|
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Get upload and download limits of the user
|
|
200
|
+
*
|
|
201
|
+
* @param {AutoDriveApi} api - The API instance used to send requests.
|
|
202
|
+
* @returns {Promise<UserInfo>} - A promise that resolves to the user info.
|
|
203
|
+
* @throws {Error} - Throws an error if the request fails.
|
|
204
|
+
*/
|
|
205
|
+
export const getMe = async (api: AutoDriveApi): Promise<UserInfo> => {
|
|
206
|
+
const response = await api.sendRequest('@me', {
|
|
207
|
+
method: 'GET',
|
|
208
|
+
})
|
|
209
|
+
if (!response.ok) {
|
|
210
|
+
throw new Error(`Failed to get limits: ${response.statusText}`)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return response.json()
|
|
214
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export type SubscriptionGranularity = 'monthly'
|
|
2
|
+
|
|
3
|
+
export type SubscriptionInfo = {
|
|
4
|
+
id: string
|
|
5
|
+
organizationId: string
|
|
6
|
+
uploadLimit: number
|
|
7
|
+
downloadLimit: number
|
|
8
|
+
granularity: SubscriptionGranularity
|
|
9
|
+
pendingUploadCredits: number
|
|
10
|
+
pendingDownloadCredits: number
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export enum UserRole {
|
|
14
|
+
User = 'User',
|
|
15
|
+
Admin = 'Admin',
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type User = {
|
|
19
|
+
oauthProvider: string
|
|
20
|
+
oauthUserId: string
|
|
21
|
+
role: UserRole
|
|
22
|
+
downloadCredits: number
|
|
23
|
+
uploadCredits: number
|
|
24
|
+
publicId: string
|
|
25
|
+
onboarded: true
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type UserInfo = {
|
|
29
|
+
user: User
|
|
30
|
+
subscription: SubscriptionInfo
|
|
31
|
+
}
|
package/src/api/wrappers.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import mime from 'mime-types'
|
|
2
|
-
import { asyncByChunk, asyncFromStream, fileToIterable } from '../utils/async'
|
|
2
|
+
import { asyncByChunk, asyncFromStream, bufferToIterable, fileToIterable } from '../utils/async'
|
|
3
3
|
import { progressToPercentage } from '../utils/misc'
|
|
4
|
-
import { PromisedObservable } from '../utils/observable'
|
|
5
4
|
import { apiCalls } from './calls/index'
|
|
6
5
|
import { AutoDriveApi } from './connection'
|
|
7
6
|
import { GenericFile, GenericFileWithinFolder } from './models/file'
|
|
8
7
|
import { constructFromInput, constructZipBlobFromTreeAndPaths } from './models/folderTree'
|
|
9
|
-
import {
|
|
8
|
+
import { SubscriptionInfo } from './models/user'
|
|
10
9
|
|
|
11
10
|
export type UploadFileOptions = {
|
|
12
11
|
password?: string
|
|
13
12
|
compression?: boolean
|
|
13
|
+
onProgress?: (progress: number) => void
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
const UPLOAD_FILE_CHUNK_SIZE = 1024 * 1024
|
|
@@ -20,17 +20,23 @@ const uploadFileChunks = (
|
|
|
20
20
|
fileUploadId: string,
|
|
21
21
|
asyncIterable: AsyncIterable<Buffer>,
|
|
22
22
|
uploadChunkSize: number = UPLOAD_FILE_CHUNK_SIZE,
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
23
|
+
onProgress?: (uploadedBytes: number) => void,
|
|
24
|
+
): Promise<void> => {
|
|
25
|
+
return new Promise(async (resolve, reject) => {
|
|
26
|
+
try {
|
|
27
|
+
let index = 0
|
|
28
|
+
let uploadBytes = 0
|
|
29
|
+
for await (const chunk of asyncByChunk(asyncIterable, uploadChunkSize)) {
|
|
30
|
+
await apiCalls.uploadFileChunk(api, { uploadId: fileUploadId, chunk, index })
|
|
31
|
+
uploadBytes += chunk.length
|
|
32
|
+
onProgress?.(uploadBytes)
|
|
33
|
+
index++
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
resolve()
|
|
37
|
+
} catch (e) {
|
|
38
|
+
reject(e)
|
|
32
39
|
}
|
|
33
|
-
subscriber.complete()
|
|
34
40
|
})
|
|
35
41
|
}
|
|
36
42
|
|
|
@@ -56,11 +62,12 @@ export const uploadFileFromInput = (
|
|
|
56
62
|
file: File,
|
|
57
63
|
options: UploadFileOptions = {},
|
|
58
64
|
uploadChunkSize?: number,
|
|
59
|
-
):
|
|
65
|
+
): Promise<string> => {
|
|
60
66
|
const { password = undefined, compression = true } = options
|
|
61
|
-
return new
|
|
62
|
-
const {
|
|
63
|
-
|
|
67
|
+
return new Promise(async (resolve, reject) => {
|
|
68
|
+
const { compressFile, CompressionAlgorithm, encryptFile, EncryptionAlgorithm } = await import(
|
|
69
|
+
'@autonomys/auto-dag-data'
|
|
70
|
+
)
|
|
64
71
|
let asyncIterable: AsyncIterable<Buffer> = fileToIterable(file)
|
|
65
72
|
|
|
66
73
|
if (compression) {
|
|
@@ -95,14 +102,13 @@ export const uploadFileFromInput = (
|
|
|
95
102
|
uploadOptions,
|
|
96
103
|
})
|
|
97
104
|
|
|
98
|
-
await uploadFileChunks(api, fileUpload.id, asyncIterable, uploadChunkSize
|
|
99
|
-
|
|
100
|
-
)
|
|
105
|
+
await uploadFileChunks(api, fileUpload.id, asyncIterable, uploadChunkSize, (bytes) => {
|
|
106
|
+
options.onProgress?.(progressToPercentage(bytes, file.size))
|
|
107
|
+
})
|
|
101
108
|
|
|
102
109
|
const result = await apiCalls.completeUpload(api, { uploadId: fileUpload.id })
|
|
103
110
|
|
|
104
|
-
|
|
105
|
-
subscriber.complete()
|
|
111
|
+
resolve(result.cid)
|
|
106
112
|
})
|
|
107
113
|
}
|
|
108
114
|
|
|
@@ -120,63 +126,101 @@ export const uploadFileFromInput = (
|
|
|
120
126
|
* @param {string} [options.password] - The password for encryption (optional).
|
|
121
127
|
* @param {boolean} [options.compression=true] - Whether to compress the file (optional).
|
|
122
128
|
* @param {number} [uploadChunkSize] - The size of each chunk to upload (optional).
|
|
123
|
-
* @returns {
|
|
129
|
+
* @returns {Promise<string>} - The CID of the uploaded file.
|
|
124
130
|
* @throws {Error} - Throws an error if the upload fails at any stage.
|
|
125
131
|
*/
|
|
126
|
-
export const uploadFile = (
|
|
132
|
+
export const uploadFile = async (
|
|
127
133
|
api: AutoDriveApi,
|
|
128
134
|
file: GenericFile,
|
|
129
135
|
options: UploadFileOptions = {},
|
|
130
136
|
uploadChunkSize?: number,
|
|
131
|
-
):
|
|
137
|
+
): Promise<string> => {
|
|
132
138
|
const { password = undefined, compression = true } = options
|
|
133
139
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
if (compression) {
|
|
140
|
-
asyncIterable = compressFile(asyncIterable, {
|
|
141
|
-
level: 9,
|
|
142
|
-
algorithm: CompressionAlgorithm.ZLIB,
|
|
143
|
-
})
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
if (password) {
|
|
147
|
-
asyncIterable = encryptFile(asyncIterable, password, {
|
|
148
|
-
algorithm: EncryptionAlgorithm.AES_256_GCM,
|
|
149
|
-
})
|
|
150
|
-
}
|
|
140
|
+
const { compressFile, CompressionAlgorithm, encryptFile, EncryptionAlgorithm } = await import(
|
|
141
|
+
'@autonomys/auto-dag-data'
|
|
142
|
+
)
|
|
143
|
+
let asyncIterable: AsyncIterable<Buffer> = file.read()
|
|
151
144
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
algorithm: CompressionAlgorithm.ZLIB,
|
|
157
|
-
}
|
|
158
|
-
: undefined,
|
|
159
|
-
encryption: password
|
|
160
|
-
? {
|
|
161
|
-
algorithm: EncryptionAlgorithm.AES_256_GCM,
|
|
162
|
-
}
|
|
163
|
-
: undefined,
|
|
164
|
-
}
|
|
165
|
-
const fileUpload = await apiCalls.createFileUpload(api, {
|
|
166
|
-
mimeType: mime.lookup(file.name) || undefined,
|
|
167
|
-
filename: file.name,
|
|
168
|
-
uploadOptions,
|
|
145
|
+
if (compression) {
|
|
146
|
+
asyncIterable = compressFile(asyncIterable, {
|
|
147
|
+
level: 9,
|
|
148
|
+
algorithm: CompressionAlgorithm.ZLIB,
|
|
169
149
|
})
|
|
150
|
+
}
|
|
170
151
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
152
|
+
if (password) {
|
|
153
|
+
asyncIterable = encryptFile(asyncIterable, password, {
|
|
154
|
+
algorithm: EncryptionAlgorithm.AES_256_GCM,
|
|
155
|
+
})
|
|
156
|
+
}
|
|
174
157
|
|
|
175
|
-
|
|
158
|
+
const uploadOptions = {
|
|
159
|
+
compression: compression
|
|
160
|
+
? {
|
|
161
|
+
level: 9,
|
|
162
|
+
algorithm: CompressionAlgorithm.ZLIB,
|
|
163
|
+
}
|
|
164
|
+
: undefined,
|
|
165
|
+
encryption: password
|
|
166
|
+
? {
|
|
167
|
+
algorithm: EncryptionAlgorithm.AES_256_GCM,
|
|
168
|
+
}
|
|
169
|
+
: undefined,
|
|
170
|
+
}
|
|
171
|
+
const fileUpload = await apiCalls.createFileUpload(api, {
|
|
172
|
+
mimeType: mime.lookup(file.name) || undefined,
|
|
173
|
+
filename: file.name,
|
|
174
|
+
uploadOptions,
|
|
175
|
+
})
|
|
176
176
|
|
|
177
|
-
|
|
178
|
-
|
|
177
|
+
await uploadFileChunks(api, fileUpload.id, asyncIterable, uploadChunkSize, (bytes) => {
|
|
178
|
+
options.onProgress?.(progressToPercentage(bytes, file.size))
|
|
179
179
|
})
|
|
180
|
+
|
|
181
|
+
const result = await apiCalls.completeUpload(api, { uploadId: fileUpload.id })
|
|
182
|
+
|
|
183
|
+
return result.cid
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Uploads an object as a JSON file to the server.
|
|
188
|
+
*
|
|
189
|
+
* This function serializes the provided object to a JSON string,
|
|
190
|
+
* and then uploads the JSON string as a file to the server.
|
|
191
|
+
*
|
|
192
|
+
* @param {AutoDriveApi} api - The API instance used to send requests.
|
|
193
|
+
* @param {File | GenericFile} file - The file to be uploaded, which can be a File or a GenericFile.
|
|
194
|
+
* @param {UploadFileOptions} options - Options for the upload process.
|
|
195
|
+
* @param {string} [options.password] - The password for encryption (optional).
|
|
196
|
+
* @param {boolean} [options.compression=true] - Whether to compress the file (optional).
|
|
197
|
+
* @param {number} [uploadChunkSize] - The size of each chunk to upload (optional).
|
|
198
|
+
* @returns {Promise<string>} - The CID of the uploaded file.
|
|
199
|
+
* @throws {Error} - Throws an error if the upload fails at any stage.
|
|
200
|
+
*/
|
|
201
|
+
export const uploadObjectAsJSON = async (
|
|
202
|
+
api: AutoDriveApi,
|
|
203
|
+
object: unknown,
|
|
204
|
+
name?: string | undefined,
|
|
205
|
+
options: UploadFileOptions = {},
|
|
206
|
+
uploadChunkSize?: number,
|
|
207
|
+
): Promise<string> => {
|
|
208
|
+
try {
|
|
209
|
+
const json = Buffer.from(JSON.stringify(object))
|
|
210
|
+
return uploadFile(
|
|
211
|
+
api,
|
|
212
|
+
{
|
|
213
|
+
read: () => bufferToIterable(json),
|
|
214
|
+
name: name || 'object.json',
|
|
215
|
+
mimeType: 'application/json',
|
|
216
|
+
size: json.length,
|
|
217
|
+
},
|
|
218
|
+
options,
|
|
219
|
+
uploadChunkSize,
|
|
220
|
+
)
|
|
221
|
+
} catch (e) {
|
|
222
|
+
throw new Error('Failed to serialize object to JSON')
|
|
223
|
+
}
|
|
180
224
|
}
|
|
181
225
|
|
|
182
226
|
/**
|
|
@@ -199,8 +243,12 @@ export const uploadFile = (
|
|
|
199
243
|
export const uploadFolderFromInput = async (
|
|
200
244
|
api: AutoDriveApi,
|
|
201
245
|
fileList: FileList | File[],
|
|
202
|
-
{
|
|
203
|
-
|
|
246
|
+
{
|
|
247
|
+
uploadChunkSize,
|
|
248
|
+
password,
|
|
249
|
+
onProgress,
|
|
250
|
+
}: { uploadChunkSize?: number; password?: string; onProgress?: (progress: number) => void } = {},
|
|
251
|
+
): Promise<string> => {
|
|
204
252
|
const files = fileList instanceof FileList ? Array.from(fileList) : fileList
|
|
205
253
|
const fileTree = constructFromInput(files)
|
|
206
254
|
|
|
@@ -223,45 +271,42 @@ export const uploadFolderFromInput = async (
|
|
|
223
271
|
{
|
|
224
272
|
password,
|
|
225
273
|
compression: true,
|
|
274
|
+
onProgress,
|
|
226
275
|
},
|
|
227
276
|
)
|
|
228
277
|
}
|
|
229
278
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
})
|
|
279
|
+
// Otherwise, we upload the files as a folder w/o compression or encryption
|
|
280
|
+
const folderUpload = await apiCalls.createFolderUpload(api, {
|
|
281
|
+
fileTree,
|
|
282
|
+
})
|
|
235
283
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
284
|
+
let currentBytesUploaded = 0
|
|
285
|
+
const totalSize = files.reduce((acc, file) => acc + file.size, 0)
|
|
286
|
+
for (const file of files) {
|
|
287
|
+
await uploadFileWithinFolderUpload(
|
|
288
|
+
api,
|
|
289
|
+
folderUpload.id,
|
|
290
|
+
{
|
|
291
|
+
read: () => fileToIterable(file),
|
|
292
|
+
name: file.name,
|
|
293
|
+
mimeType: mime.lookup(file.name) || undefined,
|
|
294
|
+
size: file.size,
|
|
295
|
+
path: file.webkitRelativePath,
|
|
296
|
+
},
|
|
297
|
+
uploadChunkSize,
|
|
298
|
+
{
|
|
299
|
+
onProgress: (progress) => {
|
|
300
|
+
onProgress?.(progressToPercentage(currentBytesUploaded + progress, totalSize))
|
|
248
301
|
},
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
progress: progressToPercentage(currentBytesUploaded + e.uploadBytes, totalSize),
|
|
254
|
-
})
|
|
255
|
-
})
|
|
256
|
-
|
|
257
|
-
currentBytesUploaded += file.size
|
|
258
|
-
}
|
|
302
|
+
},
|
|
303
|
+
)
|
|
304
|
+
currentBytesUploaded += file.size
|
|
305
|
+
}
|
|
259
306
|
|
|
260
|
-
|
|
307
|
+
const result = await apiCalls.completeUpload(api, { uploadId: folderUpload.id })
|
|
261
308
|
|
|
262
|
-
|
|
263
|
-
subscriber.complete()
|
|
264
|
-
})
|
|
309
|
+
return result.cid
|
|
265
310
|
}
|
|
266
311
|
|
|
267
312
|
/**
|
|
@@ -273,29 +318,26 @@ export const uploadFolderFromInput = async (
|
|
|
273
318
|
*
|
|
274
319
|
* @returns {Promise<void>} A promise that resolves when the file upload is complete.
|
|
275
320
|
*/
|
|
276
|
-
export const uploadFileWithinFolderUpload = (
|
|
321
|
+
export const uploadFileWithinFolderUpload = async (
|
|
277
322
|
api: AutoDriveApi,
|
|
278
323
|
uploadId: string,
|
|
279
324
|
file: GenericFileWithinFolder,
|
|
280
325
|
uploadChunkSize?: number,
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
326
|
+
options: Pick<UploadFileOptions, 'onProgress'> = {},
|
|
327
|
+
): Promise<string> => {
|
|
328
|
+
const fileUpload = await apiCalls.createFileUploadWithinFolderUpload(api, {
|
|
329
|
+
uploadId,
|
|
330
|
+
name: file.name,
|
|
331
|
+
mimeType: file.mimeType,
|
|
332
|
+
relativeId: file.path,
|
|
333
|
+
uploadOptions: {},
|
|
334
|
+
})
|
|
290
335
|
|
|
291
|
-
|
|
292
|
-
subscriber.next({ uploadBytes: e.uploadBytes }),
|
|
293
|
-
)
|
|
336
|
+
await uploadFileChunks(api, fileUpload.id, file.read(), uploadChunkSize, options.onProgress)
|
|
294
337
|
|
|
295
|
-
|
|
338
|
+
const result = await apiCalls.completeUpload(api, { uploadId: fileUpload.id })
|
|
296
339
|
|
|
297
|
-
|
|
298
|
-
})
|
|
340
|
+
return result.cid
|
|
299
341
|
}
|
|
300
342
|
|
|
301
343
|
/**
|
|
@@ -334,3 +376,19 @@ export const downloadFile = async (
|
|
|
334
376
|
|
|
335
377
|
return iterable
|
|
336
378
|
}
|
|
379
|
+
|
|
380
|
+
export const getPendingCredits = async (
|
|
381
|
+
api: AutoDriveApi,
|
|
382
|
+
): Promise<{ upload: number; download: number }> => {
|
|
383
|
+
const me = await apiCalls.getMe(api)
|
|
384
|
+
return {
|
|
385
|
+
upload: me.subscription.pendingUploadCredits,
|
|
386
|
+
download: me.subscription.pendingDownloadCredits,
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
export const getSubscriptionInfo = async (api: AutoDriveApi): Promise<SubscriptionInfo> => {
|
|
391
|
+
const me = await apiCalls.getMe(api)
|
|
392
|
+
|
|
393
|
+
return me.subscription
|
|
394
|
+
}
|