@autonomys/auto-files 1.4.34 → 1.5.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/LICENSE +18 -0
- package/dist/api.d.ts +22 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +93 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/utils.d.ts +2 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +33 -0
- package/package.json +9 -4
- package/src/api.ts +0 -106
- package/src/index.ts +0 -1
- package/src/utils.ts +0 -18
- package/tsconfig.json +0 -11
package/LICENSE
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Autonomys Network (autonomys.xyz)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
1. **Attribution**: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
2. **No Warranty**: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
15
|
+
|
|
16
|
+
3. **Limitation of Liability**: IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
17
|
+
|
|
18
|
+
---
|
package/dist/api.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { CompressionOptions, EncryptionOptions } from '@autonomys/auto-drive';
|
|
2
|
+
import { Readable } from 'stream';
|
|
3
|
+
interface FetchedFile {
|
|
4
|
+
length: bigint;
|
|
5
|
+
compression: CompressionOptions | undefined;
|
|
6
|
+
encryption: EncryptionOptions | undefined;
|
|
7
|
+
data: Readable;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Creates an API client for interacting with the Auto Files service
|
|
11
|
+
* @param baseUrl - The base URL of the Auto Files API
|
|
12
|
+
* @param apiSecret - The API secret key for authentication
|
|
13
|
+
* @returns An object containing methods to interact with the API
|
|
14
|
+
*/
|
|
15
|
+
export declare const createAutoFilesApi: (baseUrl: string, apiSecret: string) => {
|
|
16
|
+
getFile: (cid: string, { retriesPerFetch, onProgress, }?: {
|
|
17
|
+
retriesPerFetch?: number;
|
|
18
|
+
onProgress?: (progress: number) => void;
|
|
19
|
+
}) => Promise<FetchedFile>;
|
|
20
|
+
};
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAC7E,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAGjC,UAAU,WAAW;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,kBAAkB,GAAG,SAAS,CAAA;IAC3C,UAAU,EAAE,iBAAiB,GAAG,SAAS,CAAA;IACzC,IAAI,EAAE,QAAQ,CAAA;CACf;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,SAAS,MAAM,EAAE,WAAW,MAAM;mBA+C5D,MAAM,qCAIR;QAAE,eAAe,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,KACvE,OAAO,CAAC,WAAW,CAAC;CAoCxB,CAAA"}
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.createAutoFilesApi = void 0;
|
|
13
|
+
const stream_1 = require("stream");
|
|
14
|
+
const utils_1 = require("./utils");
|
|
15
|
+
/**
|
|
16
|
+
* Creates an API client for interacting with the Auto Files service
|
|
17
|
+
* @param baseUrl - The base URL of the Auto Files API
|
|
18
|
+
* @param apiSecret - The API secret key for authentication
|
|
19
|
+
* @returns An object containing methods to interact with the API
|
|
20
|
+
*/
|
|
21
|
+
const createAutoFilesApi = (baseUrl, apiSecret) => {
|
|
22
|
+
/**
|
|
23
|
+
* Makes an authenticated fetch request to the API
|
|
24
|
+
* @param url - The URL to fetch from
|
|
25
|
+
* @param options - Optional fetch request options
|
|
26
|
+
* @returns A Promise that resolves to the fetch Response
|
|
27
|
+
*/
|
|
28
|
+
const authFetch = (url, options = {}) => {
|
|
29
|
+
const urlObj = new URL(url);
|
|
30
|
+
return fetch(urlObj.toString(), Object.assign(Object.assign({}, options), { headers: Object.assign(Object.assign({}, options.headers), { Authorization: `Bearer ${apiSecret}` }) }));
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Fetches a specific chunk of a file from the API
|
|
34
|
+
* @param cid - The content identifier of the file
|
|
35
|
+
* @param chunk - The chunk number to fetch
|
|
36
|
+
* @returns A Promise that resolves to the chunk data as ArrayBuffer, or null if chunk doesn't exist
|
|
37
|
+
* @throws Error if the chunk fetch fails
|
|
38
|
+
*/
|
|
39
|
+
const getChunk = (cid, chunk) => __awaiter(void 0, void 0, void 0, function* () {
|
|
40
|
+
const response = yield authFetch(`${baseUrl}/files/${cid}/partial?chunk=${chunk}`);
|
|
41
|
+
if (!response.ok) {
|
|
42
|
+
throw new Error('Error fetching chunk');
|
|
43
|
+
}
|
|
44
|
+
if (response.status === 204) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
const buffer = yield response.arrayBuffer();
|
|
48
|
+
console.log('Chunk download finished:', buffer.byteLength);
|
|
49
|
+
return buffer;
|
|
50
|
+
});
|
|
51
|
+
/**
|
|
52
|
+
* Fetches a complete file from the API with support for progress tracking and retries
|
|
53
|
+
* @param cid - The content identifier of the file to fetch
|
|
54
|
+
* @param options - Optional configuration for the fetch operation
|
|
55
|
+
* @param options.retriesPerFetch - Number of retry attempts for failed requests (default: 3)
|
|
56
|
+
* @param options.onProgress - Optional callback function to track download progress (0-1)
|
|
57
|
+
* @returns A Promise that resolves to a FetchedFile object containing the file data and metadata
|
|
58
|
+
* @throws Error if the file metadata fetch fails
|
|
59
|
+
*/
|
|
60
|
+
const getFile = (cid_1, ...args_1) => __awaiter(void 0, [cid_1, ...args_1], void 0, function* (cid, { retriesPerFetch = 3, onProgress, } = {}) {
|
|
61
|
+
var _a, _b, _c;
|
|
62
|
+
const response = yield (0, utils_1.withRetries)(() => authFetch(`${baseUrl}/files/${cid}/metadata`), retriesPerFetch);
|
|
63
|
+
if (!response.ok) {
|
|
64
|
+
throw new Error('Error fetching file header');
|
|
65
|
+
}
|
|
66
|
+
const metadata = yield response.json();
|
|
67
|
+
// Parse size from string to bigint
|
|
68
|
+
const length = BigInt((_a = metadata.size) !== null && _a !== void 0 ? _a : 0);
|
|
69
|
+
const compression = (_b = metadata.uploadOptions) === null || _b === void 0 ? void 0 : _b.compression;
|
|
70
|
+
const encryption = (_c = metadata.uploadOptions) === null || _c === void 0 ? void 0 : _c.encryption;
|
|
71
|
+
let i = 0;
|
|
72
|
+
let totalDownloaded = BigInt(0);
|
|
73
|
+
const precision = Math.pow(10, 4);
|
|
74
|
+
return {
|
|
75
|
+
data: new stream_1.Readable({
|
|
76
|
+
read() {
|
|
77
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
78
|
+
var _a;
|
|
79
|
+
const chunk = yield (0, utils_1.withRetries)(() => getChunk(cid, i++), retriesPerFetch);
|
|
80
|
+
this.push(chunk ? Buffer.from(chunk) : null);
|
|
81
|
+
totalDownloaded += BigInt((_a = chunk === null || chunk === void 0 ? void 0 : chunk.byteLength) !== null && _a !== void 0 ? _a : 0);
|
|
82
|
+
onProgress === null || onProgress === void 0 ? void 0 : onProgress(Number((BigInt(precision) * totalDownloaded) / length) / precision);
|
|
83
|
+
});
|
|
84
|
+
},
|
|
85
|
+
}),
|
|
86
|
+
length,
|
|
87
|
+
compression,
|
|
88
|
+
encryption,
|
|
89
|
+
};
|
|
90
|
+
});
|
|
91
|
+
return { getFile };
|
|
92
|
+
};
|
|
93
|
+
exports.createAutoFilesApi = createAutoFilesApi;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./api"), exports);
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,GAAI,CAAC,EAAE,IAAI,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,MAAM,EAAE,QAAO,MAAa,eAiBzF,CAAA"}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.withRetries = void 0;
|
|
13
|
+
const withRetries = (fn, retries, delay = 1000) => {
|
|
14
|
+
return new Promise((resolve, reject) => {
|
|
15
|
+
const attempt = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
16
|
+
try {
|
|
17
|
+
const result = yield fn();
|
|
18
|
+
resolve(result);
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
if (retries > 0) {
|
|
22
|
+
yield new Promise((resolve) => setTimeout(resolve, delay));
|
|
23
|
+
attempt();
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
reject(error);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
attempt();
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
exports.withRetries = withRetries;
|
package/package.json
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autonomys/auto-files",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"packageManager": "yarn@4.7.0",
|
|
5
|
-
"private": false,
|
|
6
5
|
"scripts": {
|
|
7
6
|
"build": "tsc"
|
|
8
7
|
},
|
|
9
8
|
"devDependencies": {
|
|
10
9
|
"typescript": "^5.5.4"
|
|
11
10
|
},
|
|
11
|
+
"main": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
12
16
|
"exports": {
|
|
13
17
|
".": {
|
|
14
18
|
"require": "./dist/index.js",
|
|
@@ -17,6 +21,7 @@
|
|
|
17
21
|
}
|
|
18
22
|
},
|
|
19
23
|
"dependencies": {
|
|
20
|
-
"@autonomys/auto-drive": "^1.
|
|
21
|
-
}
|
|
24
|
+
"@autonomys/auto-drive": "^1.5.0"
|
|
25
|
+
},
|
|
26
|
+
"gitHead": "27ce75d189f2a9b0f3459cf19cc05dc07ff16100"
|
|
22
27
|
}
|
package/src/api.ts
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import { CompressionOptions, EncryptionOptions } from '@autonomys/auto-drive'
|
|
2
|
-
import { Readable } from 'stream'
|
|
3
|
-
import { withRetries } from './utils'
|
|
4
|
-
|
|
5
|
-
interface FetchedFile {
|
|
6
|
-
length: bigint
|
|
7
|
-
compression: CompressionOptions | undefined
|
|
8
|
-
encryption: EncryptionOptions | undefined
|
|
9
|
-
data: Readable
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Creates an API client for interacting with the Auto Files service
|
|
14
|
-
* @param baseUrl - The base URL of the Auto Files API
|
|
15
|
-
* @param apiSecret - The API secret key for authentication
|
|
16
|
-
* @returns An object containing methods to interact with the API
|
|
17
|
-
*/
|
|
18
|
-
export const createAutoFilesApi = (baseUrl: string, apiSecret: string) => {
|
|
19
|
-
/**
|
|
20
|
-
* Makes an authenticated fetch request to the API
|
|
21
|
-
* @param url - The URL to fetch from
|
|
22
|
-
* @param options - Optional fetch request options
|
|
23
|
-
* @returns A Promise that resolves to the fetch Response
|
|
24
|
-
*/
|
|
25
|
-
const authFetch = (url: string, options: RequestInit = {}) => {
|
|
26
|
-
const urlObj = new URL(url)
|
|
27
|
-
return fetch(urlObj.toString(), {
|
|
28
|
-
...options,
|
|
29
|
-
headers: { ...options.headers, Authorization: `Bearer ${apiSecret}` },
|
|
30
|
-
})
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Fetches a specific chunk of a file from the API
|
|
35
|
-
* @param cid - The content identifier of the file
|
|
36
|
-
* @param chunk - The chunk number to fetch
|
|
37
|
-
* @returns A Promise that resolves to the chunk data as ArrayBuffer, or null if chunk doesn't exist
|
|
38
|
-
* @throws Error if the chunk fetch fails
|
|
39
|
-
*/
|
|
40
|
-
const getChunk = async (cid: string, chunk: number): Promise<ArrayBuffer | null> => {
|
|
41
|
-
const response = await authFetch(`${baseUrl}/files/${cid}/partial?chunk=${chunk}`)
|
|
42
|
-
if (!response.ok) {
|
|
43
|
-
throw new Error('Error fetching chunk')
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (response.status === 204) {
|
|
47
|
-
return null
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const buffer = await response.arrayBuffer()
|
|
51
|
-
console.log('Chunk download finished:', buffer.byteLength)
|
|
52
|
-
return buffer
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Fetches a complete file from the API with support for progress tracking and retries
|
|
57
|
-
* @param cid - The content identifier of the file to fetch
|
|
58
|
-
* @param options - Optional configuration for the fetch operation
|
|
59
|
-
* @param options.retriesPerFetch - Number of retry attempts for failed requests (default: 3)
|
|
60
|
-
* @param options.onProgress - Optional callback function to track download progress (0-1)
|
|
61
|
-
* @returns A Promise that resolves to a FetchedFile object containing the file data and metadata
|
|
62
|
-
* @throws Error if the file metadata fetch fails
|
|
63
|
-
*/
|
|
64
|
-
const getFile = async (
|
|
65
|
-
cid: string,
|
|
66
|
-
{
|
|
67
|
-
retriesPerFetch = 3,
|
|
68
|
-
onProgress,
|
|
69
|
-
}: { retriesPerFetch?: number; onProgress?: (progress: number) => void } = {},
|
|
70
|
-
): Promise<FetchedFile> => {
|
|
71
|
-
const response = await withRetries(
|
|
72
|
-
() => authFetch(`${baseUrl}/files/${cid}/metadata`),
|
|
73
|
-
retriesPerFetch,
|
|
74
|
-
)
|
|
75
|
-
if (!response.ok) {
|
|
76
|
-
throw new Error('Error fetching file header')
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const metadata = await response.json()
|
|
80
|
-
|
|
81
|
-
// Parse size from string to bigint
|
|
82
|
-
const length = BigInt(metadata.size ?? 0)
|
|
83
|
-
|
|
84
|
-
const compression = metadata.uploadOptions?.compression
|
|
85
|
-
const encryption = metadata.uploadOptions?.encryption
|
|
86
|
-
|
|
87
|
-
let i = 0
|
|
88
|
-
let totalDownloaded = BigInt(0)
|
|
89
|
-
const precision = 10 ** 4
|
|
90
|
-
return {
|
|
91
|
-
data: new Readable({
|
|
92
|
-
async read() {
|
|
93
|
-
const chunk = await withRetries(() => getChunk(cid, i++), retriesPerFetch)
|
|
94
|
-
this.push(chunk ? Buffer.from(chunk) : null)
|
|
95
|
-
totalDownloaded += BigInt(chunk?.byteLength ?? 0)
|
|
96
|
-
onProgress?.(Number((BigInt(precision) * totalDownloaded) / length) / precision)
|
|
97
|
-
},
|
|
98
|
-
}),
|
|
99
|
-
length,
|
|
100
|
-
compression,
|
|
101
|
-
encryption,
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return { getFile }
|
|
106
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './api'
|
package/src/utils.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export const withRetries = <T>(fn: () => Promise<T>, retries: number, delay: number = 1000) => {
|
|
2
|
-
return new Promise<T>((resolve, reject) => {
|
|
3
|
-
const attempt = async () => {
|
|
4
|
-
try {
|
|
5
|
-
const result = await fn()
|
|
6
|
-
resolve(result)
|
|
7
|
-
} catch (error) {
|
|
8
|
-
if (retries > 0) {
|
|
9
|
-
await new Promise((resolve) => setTimeout(resolve, delay))
|
|
10
|
-
attempt()
|
|
11
|
-
} else {
|
|
12
|
-
reject(error)
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
attempt()
|
|
17
|
-
})
|
|
18
|
-
}
|