@applica-software-guru/didonato-storage-client 1.0.30 → 1.0.32
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/dist/index.d.mts +136 -21
- package/dist/index.d.ts +136 -21
- package/dist/index.js +162 -55
- package/dist/index.mjs +166 -49
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,24 +1,139 @@
|
|
|
1
|
-
interface
|
|
1
|
+
interface SignResponse {
|
|
2
|
+
key: string;
|
|
3
|
+
uploadUrl?: string;
|
|
4
|
+
url?: string;
|
|
5
|
+
fields?: Record<string, string>;
|
|
6
|
+
requiredHeaders?: Record<string, string>;
|
|
7
|
+
expiresIn?: number;
|
|
8
|
+
debug?: {
|
|
9
|
+
canonicalRequest?: string;
|
|
10
|
+
stringToSign?: string;
|
|
11
|
+
signatureHex?: string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
interface CreateUploadSignatureRequest {
|
|
15
|
+
filename: string;
|
|
16
|
+
contentType: string;
|
|
17
|
+
maxSize: number;
|
|
18
|
+
}
|
|
19
|
+
type CreateUploadSignatureResponse = SignResponse;
|
|
20
|
+
interface FileMetadata {
|
|
21
|
+
_id?: string;
|
|
22
|
+
ownerId: string;
|
|
23
|
+
key: string;
|
|
24
|
+
originalName: string;
|
|
25
|
+
contentType: string;
|
|
26
|
+
size: number;
|
|
27
|
+
createdAt: string;
|
|
28
|
+
}
|
|
29
|
+
interface CompleteResponse {
|
|
30
|
+
insertedId?: string;
|
|
31
|
+
doc?: FileMetadata;
|
|
32
|
+
}
|
|
33
|
+
interface FinalizeUploadRequest {
|
|
34
|
+
key: string;
|
|
35
|
+
originalName: string;
|
|
36
|
+
contentType: string;
|
|
37
|
+
size: number;
|
|
38
|
+
}
|
|
39
|
+
type FinalizeUploadResponse = CompleteResponse;
|
|
40
|
+
interface ListFilesMeta {
|
|
41
|
+
page: number;
|
|
42
|
+
limit: number;
|
|
43
|
+
total: number;
|
|
44
|
+
totalPages: number;
|
|
45
|
+
}
|
|
46
|
+
interface ListFilesResponse {
|
|
47
|
+
files: FileMetadata[];
|
|
48
|
+
meta: ListFilesMeta;
|
|
49
|
+
}
|
|
50
|
+
interface GetFilesRequest {
|
|
51
|
+
q?: string;
|
|
52
|
+
page?: number;
|
|
53
|
+
limit?: number;
|
|
54
|
+
}
|
|
55
|
+
type GetFilesResponse = ListFilesResponse;
|
|
56
|
+
interface GetDownloadUrlRequest {
|
|
57
|
+
id: string;
|
|
58
|
+
}
|
|
59
|
+
interface GetDownloadUrlResponse {
|
|
60
|
+
downloadUrl: string;
|
|
61
|
+
expiresIn?: number;
|
|
62
|
+
}
|
|
63
|
+
interface DownloadFileRequest {
|
|
64
|
+
id: string;
|
|
65
|
+
}
|
|
66
|
+
interface DownloadFileResponse {
|
|
67
|
+
blob: Blob;
|
|
68
|
+
}
|
|
69
|
+
interface DeleteFileRequest {
|
|
70
|
+
id: string;
|
|
71
|
+
}
|
|
72
|
+
interface DeleteFileResponse {
|
|
73
|
+
ok: boolean;
|
|
74
|
+
}
|
|
75
|
+
interface ProgressInfo {
|
|
76
|
+
loaded: number;
|
|
77
|
+
total: number;
|
|
78
|
+
percent?: number;
|
|
79
|
+
}
|
|
80
|
+
interface UploadToSignedUrlRequest {
|
|
81
|
+
uploadUrl: string;
|
|
82
|
+
file: Blob | File;
|
|
83
|
+
requiredHeaders?: Record<string, string>;
|
|
84
|
+
onProgress?: (p: ProgressInfo) => void;
|
|
85
|
+
}
|
|
86
|
+
interface UploadToSignedFormRequest {
|
|
87
|
+
uploadUrl: string;
|
|
88
|
+
fields: Record<string, string>;
|
|
89
|
+
file: Blob | File;
|
|
90
|
+
onProgress?: (p: ProgressInfo) => void;
|
|
91
|
+
}
|
|
92
|
+
interface UploadFileRequest {
|
|
93
|
+
file: Blob | File;
|
|
94
|
+
opts?: {
|
|
95
|
+
filename?: string;
|
|
96
|
+
contentType?: string;
|
|
97
|
+
size?: number;
|
|
98
|
+
};
|
|
99
|
+
onProgress?: (p: ProgressInfo) => void;
|
|
100
|
+
}
|
|
101
|
+
interface UploadFileResponse {
|
|
102
|
+
sig: SignResponse;
|
|
103
|
+
complete: CompleteResponse;
|
|
104
|
+
}
|
|
105
|
+
interface IDidonatoStorageClient {
|
|
106
|
+
createUploadSignature(req: CreateUploadSignatureRequest): Promise<CreateUploadSignatureResponse>;
|
|
107
|
+
finalizeUpload(req: FinalizeUploadRequest): Promise<FinalizeUploadResponse>;
|
|
108
|
+
getFiles(req?: GetFilesRequest): Promise<GetFilesResponse>;
|
|
109
|
+
getDownloadUrl(req: GetDownloadUrlRequest): Promise<GetDownloadUrlResponse>;
|
|
110
|
+
downloadFile(req: DownloadFileRequest): Promise<DownloadFileResponse>;
|
|
111
|
+
deleteFile(req: DeleteFileRequest): Promise<DeleteFileResponse>;
|
|
112
|
+
uploadFile?: (req: UploadFileRequest) => Promise<UploadFileResponse>;
|
|
113
|
+
}
|
|
114
|
+
type TokenProvider = string | (() => string | null | Promise<string | null>) | null;
|
|
115
|
+
interface ClientOptions {
|
|
2
116
|
baseUrl?: string;
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
117
|
+
getAuthToken?: TokenProvider;
|
|
118
|
+
token?: TokenProvider;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
declare class DidonatoStorageClient implements IDidonatoStorageClient {
|
|
122
|
+
private baseUrl;
|
|
123
|
+
private getAuthToken;
|
|
124
|
+
constructor(opts?: ClientOptions);
|
|
125
|
+
private resolveToken;
|
|
126
|
+
private headers;
|
|
127
|
+
private _fetch;
|
|
128
|
+
createUploadSignature(req: CreateUploadSignatureRequest): Promise<CreateUploadSignatureResponse>;
|
|
129
|
+
finalizeUpload(req: FinalizeUploadRequest): Promise<FinalizeUploadResponse>;
|
|
130
|
+
getFiles(req?: GetFilesRequest): Promise<GetFilesResponse>;
|
|
131
|
+
getDownloadUrl(req: GetDownloadUrlRequest): Promise<GetDownloadUrlResponse>;
|
|
132
|
+
downloadFile(req: DownloadFileRequest): Promise<DownloadFileResponse>;
|
|
133
|
+
deleteFile(req: DeleteFileRequest): Promise<DeleteFileResponse>;
|
|
134
|
+
private _uploadToSignedUrl;
|
|
135
|
+
private _uploadToSignedForm;
|
|
136
|
+
uploadFile(req: UploadFileRequest): Promise<UploadFileResponse>;
|
|
22
137
|
}
|
|
23
138
|
|
|
24
|
-
export { type
|
|
139
|
+
export { type ClientOptions, type CompleteResponse, type CreateUploadSignatureRequest, type CreateUploadSignatureResponse, type DeleteFileRequest, type DeleteFileResponse, DidonatoStorageClient, type DownloadFileRequest, type DownloadFileResponse, type FileMetadata, type FinalizeUploadRequest, type FinalizeUploadResponse, type GetDownloadUrlRequest, type GetDownloadUrlResponse, type GetFilesRequest, type GetFilesResponse, type IDidonatoStorageClient, type ListFilesMeta, type ListFilesResponse, type ProgressInfo, type SignResponse, type TokenProvider, type UploadFileRequest, type UploadFileResponse, type UploadToSignedFormRequest, type UploadToSignedUrlRequest, DidonatoStorageClient as default };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,24 +1,139 @@
|
|
|
1
|
-
interface
|
|
1
|
+
interface SignResponse {
|
|
2
|
+
key: string;
|
|
3
|
+
uploadUrl?: string;
|
|
4
|
+
url?: string;
|
|
5
|
+
fields?: Record<string, string>;
|
|
6
|
+
requiredHeaders?: Record<string, string>;
|
|
7
|
+
expiresIn?: number;
|
|
8
|
+
debug?: {
|
|
9
|
+
canonicalRequest?: string;
|
|
10
|
+
stringToSign?: string;
|
|
11
|
+
signatureHex?: string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
interface CreateUploadSignatureRequest {
|
|
15
|
+
filename: string;
|
|
16
|
+
contentType: string;
|
|
17
|
+
maxSize: number;
|
|
18
|
+
}
|
|
19
|
+
type CreateUploadSignatureResponse = SignResponse;
|
|
20
|
+
interface FileMetadata {
|
|
21
|
+
_id?: string;
|
|
22
|
+
ownerId: string;
|
|
23
|
+
key: string;
|
|
24
|
+
originalName: string;
|
|
25
|
+
contentType: string;
|
|
26
|
+
size: number;
|
|
27
|
+
createdAt: string;
|
|
28
|
+
}
|
|
29
|
+
interface CompleteResponse {
|
|
30
|
+
insertedId?: string;
|
|
31
|
+
doc?: FileMetadata;
|
|
32
|
+
}
|
|
33
|
+
interface FinalizeUploadRequest {
|
|
34
|
+
key: string;
|
|
35
|
+
originalName: string;
|
|
36
|
+
contentType: string;
|
|
37
|
+
size: number;
|
|
38
|
+
}
|
|
39
|
+
type FinalizeUploadResponse = CompleteResponse;
|
|
40
|
+
interface ListFilesMeta {
|
|
41
|
+
page: number;
|
|
42
|
+
limit: number;
|
|
43
|
+
total: number;
|
|
44
|
+
totalPages: number;
|
|
45
|
+
}
|
|
46
|
+
interface ListFilesResponse {
|
|
47
|
+
files: FileMetadata[];
|
|
48
|
+
meta: ListFilesMeta;
|
|
49
|
+
}
|
|
50
|
+
interface GetFilesRequest {
|
|
51
|
+
q?: string;
|
|
52
|
+
page?: number;
|
|
53
|
+
limit?: number;
|
|
54
|
+
}
|
|
55
|
+
type GetFilesResponse = ListFilesResponse;
|
|
56
|
+
interface GetDownloadUrlRequest {
|
|
57
|
+
id: string;
|
|
58
|
+
}
|
|
59
|
+
interface GetDownloadUrlResponse {
|
|
60
|
+
downloadUrl: string;
|
|
61
|
+
expiresIn?: number;
|
|
62
|
+
}
|
|
63
|
+
interface DownloadFileRequest {
|
|
64
|
+
id: string;
|
|
65
|
+
}
|
|
66
|
+
interface DownloadFileResponse {
|
|
67
|
+
blob: Blob;
|
|
68
|
+
}
|
|
69
|
+
interface DeleteFileRequest {
|
|
70
|
+
id: string;
|
|
71
|
+
}
|
|
72
|
+
interface DeleteFileResponse {
|
|
73
|
+
ok: boolean;
|
|
74
|
+
}
|
|
75
|
+
interface ProgressInfo {
|
|
76
|
+
loaded: number;
|
|
77
|
+
total: number;
|
|
78
|
+
percent?: number;
|
|
79
|
+
}
|
|
80
|
+
interface UploadToSignedUrlRequest {
|
|
81
|
+
uploadUrl: string;
|
|
82
|
+
file: Blob | File;
|
|
83
|
+
requiredHeaders?: Record<string, string>;
|
|
84
|
+
onProgress?: (p: ProgressInfo) => void;
|
|
85
|
+
}
|
|
86
|
+
interface UploadToSignedFormRequest {
|
|
87
|
+
uploadUrl: string;
|
|
88
|
+
fields: Record<string, string>;
|
|
89
|
+
file: Blob | File;
|
|
90
|
+
onProgress?: (p: ProgressInfo) => void;
|
|
91
|
+
}
|
|
92
|
+
interface UploadFileRequest {
|
|
93
|
+
file: Blob | File;
|
|
94
|
+
opts?: {
|
|
95
|
+
filename?: string;
|
|
96
|
+
contentType?: string;
|
|
97
|
+
size?: number;
|
|
98
|
+
};
|
|
99
|
+
onProgress?: (p: ProgressInfo) => void;
|
|
100
|
+
}
|
|
101
|
+
interface UploadFileResponse {
|
|
102
|
+
sig: SignResponse;
|
|
103
|
+
complete: CompleteResponse;
|
|
104
|
+
}
|
|
105
|
+
interface IDidonatoStorageClient {
|
|
106
|
+
createUploadSignature(req: CreateUploadSignatureRequest): Promise<CreateUploadSignatureResponse>;
|
|
107
|
+
finalizeUpload(req: FinalizeUploadRequest): Promise<FinalizeUploadResponse>;
|
|
108
|
+
getFiles(req?: GetFilesRequest): Promise<GetFilesResponse>;
|
|
109
|
+
getDownloadUrl(req: GetDownloadUrlRequest): Promise<GetDownloadUrlResponse>;
|
|
110
|
+
downloadFile(req: DownloadFileRequest): Promise<DownloadFileResponse>;
|
|
111
|
+
deleteFile(req: DeleteFileRequest): Promise<DeleteFileResponse>;
|
|
112
|
+
uploadFile?: (req: UploadFileRequest) => Promise<UploadFileResponse>;
|
|
113
|
+
}
|
|
114
|
+
type TokenProvider = string | (() => string | null | Promise<string | null>) | null;
|
|
115
|
+
interface ClientOptions {
|
|
2
116
|
baseUrl?: string;
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
117
|
+
getAuthToken?: TokenProvider;
|
|
118
|
+
token?: TokenProvider;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
declare class DidonatoStorageClient implements IDidonatoStorageClient {
|
|
122
|
+
private baseUrl;
|
|
123
|
+
private getAuthToken;
|
|
124
|
+
constructor(opts?: ClientOptions);
|
|
125
|
+
private resolveToken;
|
|
126
|
+
private headers;
|
|
127
|
+
private _fetch;
|
|
128
|
+
createUploadSignature(req: CreateUploadSignatureRequest): Promise<CreateUploadSignatureResponse>;
|
|
129
|
+
finalizeUpload(req: FinalizeUploadRequest): Promise<FinalizeUploadResponse>;
|
|
130
|
+
getFiles(req?: GetFilesRequest): Promise<GetFilesResponse>;
|
|
131
|
+
getDownloadUrl(req: GetDownloadUrlRequest): Promise<GetDownloadUrlResponse>;
|
|
132
|
+
downloadFile(req: DownloadFileRequest): Promise<DownloadFileResponse>;
|
|
133
|
+
deleteFile(req: DeleteFileRequest): Promise<DeleteFileResponse>;
|
|
134
|
+
private _uploadToSignedUrl;
|
|
135
|
+
private _uploadToSignedForm;
|
|
136
|
+
uploadFile(req: UploadFileRequest): Promise<UploadFileResponse>;
|
|
22
137
|
}
|
|
23
138
|
|
|
24
|
-
export { type
|
|
139
|
+
export { type ClientOptions, type CompleteResponse, type CreateUploadSignatureRequest, type CreateUploadSignatureResponse, type DeleteFileRequest, type DeleteFileResponse, DidonatoStorageClient, type DownloadFileRequest, type DownloadFileResponse, type FileMetadata, type FinalizeUploadRequest, type FinalizeUploadResponse, type GetDownloadUrlRequest, type GetDownloadUrlResponse, type GetFilesRequest, type GetFilesResponse, type IDidonatoStorageClient, type ListFilesMeta, type ListFilesResponse, type ProgressInfo, type SignResponse, type TokenProvider, type UploadFileRequest, type UploadFileResponse, type UploadToSignedFormRequest, type UploadToSignedUrlRequest, DidonatoStorageClient as default };
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __export = (target, all) => {
|
|
9
7
|
for (var name in all)
|
|
@@ -17,81 +15,190 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
15
|
}
|
|
18
16
|
return to;
|
|
19
17
|
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
19
|
|
|
30
20
|
// src/index.ts
|
|
31
21
|
var index_exports = {};
|
|
32
22
|
__export(index_exports, {
|
|
33
23
|
DidonatoStorageClient: () => DidonatoStorageClient,
|
|
34
|
-
default: () =>
|
|
24
|
+
default: () => client_default
|
|
35
25
|
});
|
|
36
26
|
module.exports = __toCommonJS(index_exports);
|
|
37
27
|
|
|
38
|
-
// src/
|
|
39
|
-
var import_cross_fetch = __toESM(require("cross-fetch"));
|
|
28
|
+
// src/client.ts
|
|
40
29
|
var DidonatoStorageClient = class {
|
|
41
30
|
constructor(opts = {}) {
|
|
42
|
-
this.
|
|
31
|
+
this.baseUrl = opts.baseUrl || "";
|
|
32
|
+
this.getAuthToken = typeof opts.getAuthToken === "function" ? opts.getAuthToken : (opts.getAuthToken ?? opts.token) || null;
|
|
43
33
|
}
|
|
44
|
-
async
|
|
45
|
-
|
|
46
|
-
if (
|
|
47
|
-
if (typeof t === "function") {
|
|
34
|
+
async resolveToken() {
|
|
35
|
+
if (!this.getAuthToken) return null;
|
|
36
|
+
if (typeof this.getAuthToken === "function") {
|
|
48
37
|
try {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return
|
|
38
|
+
const v = this.getAuthToken();
|
|
39
|
+
if (v instanceof Promise) return await v;
|
|
40
|
+
return v;
|
|
41
|
+
} catch {
|
|
42
|
+
return null;
|
|
52
43
|
}
|
|
53
44
|
}
|
|
54
|
-
return
|
|
55
|
-
}
|
|
56
|
-
async getSignedUrl(key, expiresSec = 3600) {
|
|
57
|
-
return `${this.options.baseUrl || "https://storage.example.com"}/signed/${encodeURIComponent(
|
|
58
|
-
key
|
|
59
|
-
)}?exp=${expiresSec}`;
|
|
45
|
+
return this.getAuthToken;
|
|
60
46
|
}
|
|
61
|
-
async
|
|
62
|
-
const
|
|
63
|
-
const
|
|
64
|
-
if (
|
|
65
|
-
|
|
66
|
-
return json;
|
|
47
|
+
async headers(extra = {}) {
|
|
48
|
+
const h = { ...extra };
|
|
49
|
+
const token = await this.resolveToken();
|
|
50
|
+
if (token) h["Authorization"] = `Bearer ${token}`;
|
|
51
|
+
return h;
|
|
67
52
|
}
|
|
68
|
-
async
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
53
|
+
async _fetch(path, opts = {}) {
|
|
54
|
+
const url = (this.baseUrl || "") + path;
|
|
55
|
+
const resolvedHeaders = await this.headers();
|
|
56
|
+
const headers = { ...resolvedHeaders, ...opts.headers || {} };
|
|
57
|
+
const fetchOpts = { ...opts, headers };
|
|
58
|
+
const res = await fetch(url, fetchOpts);
|
|
59
|
+
if (!res.ok) {
|
|
60
|
+
let body = null;
|
|
61
|
+
try {
|
|
62
|
+
body = await res.json();
|
|
63
|
+
} catch (e) {
|
|
64
|
+
try {
|
|
65
|
+
body = await res.text();
|
|
66
|
+
} catch {
|
|
67
|
+
body = null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const err = new Error("Request failed");
|
|
71
|
+
err.status = res.status;
|
|
72
|
+
err.body = body;
|
|
73
|
+
throw err;
|
|
74
|
+
}
|
|
75
|
+
const ct = res.headers && typeof res.headers.get === "function" ? res.headers.get("content-type") || "" : "";
|
|
76
|
+
if (ct.includes("application/json")) return await res.json();
|
|
77
|
+
try {
|
|
78
|
+
if (typeof res.text === "function") return await res.text();
|
|
79
|
+
} catch {
|
|
75
80
|
}
|
|
76
|
-
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
async createUploadSignature(req) {
|
|
84
|
+
return this._fetch("/api/sign-post", {
|
|
85
|
+
method: "POST",
|
|
86
|
+
headers: { "Content-Type": "application/json" },
|
|
87
|
+
body: JSON.stringify({
|
|
88
|
+
filename: req.filename,
|
|
89
|
+
contentType: req.contentType,
|
|
90
|
+
maxSize: req.maxSize,
|
|
91
|
+
expiresIn: 300
|
|
92
|
+
})
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
async finalizeUpload(req) {
|
|
96
|
+
return this._fetch("/api/complete-upload", {
|
|
97
|
+
method: "POST",
|
|
98
|
+
headers: { "Content-Type": "application/json" },
|
|
99
|
+
body: JSON.stringify(req)
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
async getFiles(req = {}) {
|
|
103
|
+
const qs = [];
|
|
104
|
+
if (req.q) qs.push("q=" + encodeURIComponent(req.q));
|
|
105
|
+
if (req.page) qs.push("page=" + encodeURIComponent(String(req.page)));
|
|
106
|
+
if (req.limit) qs.push("limit=" + encodeURIComponent(String(req.limit)));
|
|
107
|
+
const path = "/api/files" + (qs.length ? "?" + qs.join("&") : "");
|
|
108
|
+
return this._fetch(path, { method: "GET" });
|
|
109
|
+
}
|
|
110
|
+
async getDownloadUrl(req) {
|
|
111
|
+
return this._fetch(`/api/files/${encodeURIComponent(req.id)}/download`, { method: "GET" });
|
|
112
|
+
}
|
|
113
|
+
async downloadFile(req) {
|
|
114
|
+
const res = await this.getDownloadUrl({ id: req.id });
|
|
115
|
+
if (!res || !res.downloadUrl) throw new Error("No download URL");
|
|
116
|
+
const headers = await this.headers();
|
|
117
|
+
const r = await fetch(res.downloadUrl, { headers });
|
|
118
|
+
if (!r.ok) throw new Error("Download failed");
|
|
119
|
+
const blob = await r.blob();
|
|
120
|
+
return { blob };
|
|
77
121
|
}
|
|
78
|
-
async
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
const headers = token ? { Authorization: `Bearer ${token}` } : void 0;
|
|
82
|
-
const res = await (0, import_cross_fetch.default)(url, { method: "DELETE", headers });
|
|
83
|
-
return res.ok;
|
|
122
|
+
async deleteFile(req) {
|
|
123
|
+
await this._fetch(`/api/files/${encodeURIComponent(req.id)}`, { method: "DELETE" });
|
|
124
|
+
return { ok: true };
|
|
84
125
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
126
|
+
_uploadToSignedUrl(req) {
|
|
127
|
+
return new Promise(async (resolve, reject) => {
|
|
128
|
+
try {
|
|
129
|
+
const authHeaders = await this.headers();
|
|
130
|
+
const xhr = new XMLHttpRequest();
|
|
131
|
+
xhr.open("PUT", req.uploadUrl);
|
|
132
|
+
Object.keys(authHeaders || {}).forEach((k) => {
|
|
133
|
+
try {
|
|
134
|
+
xhr.setRequestHeader(k, authHeaders[k]);
|
|
135
|
+
} catch {
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
Object.keys(req.requiredHeaders || {}).forEach((k) => {
|
|
139
|
+
try {
|
|
140
|
+
xhr.setRequestHeader(k, (req.requiredHeaders || {})[k]);
|
|
141
|
+
} catch {
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
xhr.upload.onprogress = (ev) => {
|
|
145
|
+
if (!ev.lengthComputable) return req.onProgress && req.onProgress({ loaded: ev.loaded, total: ev.total });
|
|
146
|
+
req.onProgress && req.onProgress({ loaded: ev.loaded, total: ev.total, percent: ev.loaded / ev.total * 100 });
|
|
147
|
+
};
|
|
148
|
+
xhr.onload = () => {
|
|
149
|
+
if (xhr.status >= 200 && xhr.status < 300) resolve({ status: xhr.status });
|
|
150
|
+
else reject(new Error("Upload failed: " + xhr.status));
|
|
151
|
+
};
|
|
152
|
+
xhr.onerror = () => reject(new Error("Upload error"));
|
|
153
|
+
xhr.send(req.file);
|
|
154
|
+
} catch (err) {
|
|
155
|
+
reject(err);
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
_uploadToSignedForm(req) {
|
|
160
|
+
return new Promise(async (resolve, reject) => {
|
|
161
|
+
try {
|
|
162
|
+
const xhr = new XMLHttpRequest();
|
|
163
|
+
xhr.open("POST", req.uploadUrl);
|
|
164
|
+
const form = new FormData();
|
|
165
|
+
Object.entries(req.fields || {}).forEach(([k, v]) => form.append(k, v));
|
|
166
|
+
form.append("file", req.file);
|
|
167
|
+
xhr.upload.onprogress = (ev) => {
|
|
168
|
+
if (!ev.lengthComputable) return req.onProgress && req.onProgress({ loaded: ev.loaded, total: ev.total });
|
|
169
|
+
req.onProgress && req.onProgress({ loaded: ev.loaded, total: ev.total, percent: ev.loaded / ev.total * 100 });
|
|
170
|
+
};
|
|
171
|
+
xhr.onload = () => {
|
|
172
|
+
if (xhr.status >= 200 && xhr.status < 300) resolve({ status: xhr.status });
|
|
173
|
+
else reject(new Error("Upload failed: " + xhr.status));
|
|
174
|
+
};
|
|
175
|
+
xhr.onerror = () => reject(new Error("Upload error"));
|
|
176
|
+
xhr.send(form);
|
|
177
|
+
} catch (err) {
|
|
178
|
+
reject(err);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
async uploadFile(req) {
|
|
183
|
+
const file = req.file;
|
|
184
|
+
const opts = req.opts || {};
|
|
185
|
+
const onProgress = req.onProgress;
|
|
186
|
+
const filename = opts.filename ?? (file instanceof File ? file.name : "file.bin");
|
|
187
|
+
const contentType = opts.contentType ?? (file instanceof File ? file.type || "application/octet-stream" : "application/octet-stream");
|
|
188
|
+
const size = typeof opts.size === "number" ? opts.size : file instanceof File ? file.size : 0;
|
|
189
|
+
const sig = await this.createUploadSignature({ filename, contentType, maxSize: size });
|
|
190
|
+
if (!sig) throw new Error("No signature from server");
|
|
191
|
+
if (sig.url || sig.uploadUrl) {
|
|
192
|
+
const postUrl = sig.url || sig.uploadUrl;
|
|
193
|
+
await this._uploadToSignedForm({ uploadUrl: postUrl, fields: sig.fields || {}, file, onProgress });
|
|
194
|
+
} else {
|
|
195
|
+
throw new Error("No usable upload info from server");
|
|
196
|
+
}
|
|
197
|
+
const complete = await this.finalizeUpload({ key: sig.key, originalName: filename, contentType, size });
|
|
198
|
+
return { sig, complete };
|
|
93
199
|
}
|
|
94
200
|
};
|
|
201
|
+
var client_default = DidonatoStorageClient;
|
|
95
202
|
// Annotate the CommonJS export names for ESM import in node:
|
|
96
203
|
0 && (module.exports = {
|
|
97
204
|
DidonatoStorageClient
|
package/dist/index.mjs
CHANGED
|
@@ -1,61 +1,178 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
import fetch from "cross-fetch";
|
|
1
|
+
// src/client.ts
|
|
3
2
|
var DidonatoStorageClient = class {
|
|
4
3
|
constructor(opts = {}) {
|
|
5
|
-
this.
|
|
4
|
+
this.baseUrl = opts.baseUrl || "";
|
|
5
|
+
this.getAuthToken = typeof opts.getAuthToken === "function" ? opts.getAuthToken : (opts.getAuthToken ?? opts.token) || null;
|
|
6
6
|
}
|
|
7
|
-
async
|
|
8
|
-
|
|
9
|
-
if (
|
|
10
|
-
if (typeof t === "function") {
|
|
7
|
+
async resolveToken() {
|
|
8
|
+
if (!this.getAuthToken) return null;
|
|
9
|
+
if (typeof this.getAuthToken === "function") {
|
|
11
10
|
try {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return
|
|
11
|
+
const v = this.getAuthToken();
|
|
12
|
+
if (v instanceof Promise) return await v;
|
|
13
|
+
return v;
|
|
14
|
+
} catch {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return this.getAuthToken;
|
|
19
|
+
}
|
|
20
|
+
async headers(extra = {}) {
|
|
21
|
+
const h = { ...extra };
|
|
22
|
+
const token = await this.resolveToken();
|
|
23
|
+
if (token) h["Authorization"] = `Bearer ${token}`;
|
|
24
|
+
return h;
|
|
25
|
+
}
|
|
26
|
+
async _fetch(path, opts = {}) {
|
|
27
|
+
const url = (this.baseUrl || "") + path;
|
|
28
|
+
const resolvedHeaders = await this.headers();
|
|
29
|
+
const headers = { ...resolvedHeaders, ...opts.headers || {} };
|
|
30
|
+
const fetchOpts = { ...opts, headers };
|
|
31
|
+
const res = await fetch(url, fetchOpts);
|
|
32
|
+
if (!res.ok) {
|
|
33
|
+
let body = null;
|
|
34
|
+
try {
|
|
35
|
+
body = await res.json();
|
|
36
|
+
} catch (e) {
|
|
37
|
+
try {
|
|
38
|
+
body = await res.text();
|
|
39
|
+
} catch {
|
|
40
|
+
body = null;
|
|
41
|
+
}
|
|
15
42
|
}
|
|
43
|
+
const err = new Error("Request failed");
|
|
44
|
+
err.status = res.status;
|
|
45
|
+
err.body = body;
|
|
46
|
+
throw err;
|
|
16
47
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
48
|
+
const ct = res.headers && typeof res.headers.get === "function" ? res.headers.get("content-type") || "" : "";
|
|
49
|
+
if (ct.includes("application/json")) return await res.json();
|
|
50
|
+
try {
|
|
51
|
+
if (typeof res.text === "function") return await res.text();
|
|
52
|
+
} catch {
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
async createUploadSignature(req) {
|
|
57
|
+
return this._fetch("/api/sign-post", {
|
|
58
|
+
method: "POST",
|
|
59
|
+
headers: { "Content-Type": "application/json" },
|
|
60
|
+
body: JSON.stringify({
|
|
61
|
+
filename: req.filename,
|
|
62
|
+
contentType: req.contentType,
|
|
63
|
+
maxSize: req.maxSize,
|
|
64
|
+
expiresIn: 300
|
|
65
|
+
})
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
async finalizeUpload(req) {
|
|
69
|
+
return this._fetch("/api/complete-upload", {
|
|
70
|
+
method: "POST",
|
|
71
|
+
headers: { "Content-Type": "application/json" },
|
|
72
|
+
body: JSON.stringify(req)
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
async getFiles(req = {}) {
|
|
76
|
+
const qs = [];
|
|
77
|
+
if (req.q) qs.push("q=" + encodeURIComponent(req.q));
|
|
78
|
+
if (req.page) qs.push("page=" + encodeURIComponent(String(req.page)));
|
|
79
|
+
if (req.limit) qs.push("limit=" + encodeURIComponent(String(req.limit)));
|
|
80
|
+
const path = "/api/files" + (qs.length ? "?" + qs.join("&") : "");
|
|
81
|
+
return this._fetch(path, { method: "GET" });
|
|
82
|
+
}
|
|
83
|
+
async getDownloadUrl(req) {
|
|
84
|
+
return this._fetch(`/api/files/${encodeURIComponent(req.id)}/download`, { method: "GET" });
|
|
85
|
+
}
|
|
86
|
+
async downloadFile(req) {
|
|
87
|
+
const res = await this.getDownloadUrl({ id: req.id });
|
|
88
|
+
if (!res || !res.downloadUrl) throw new Error("No download URL");
|
|
89
|
+
const headers = await this.headers();
|
|
90
|
+
const r = await fetch(res.downloadUrl, { headers });
|
|
91
|
+
if (!r.ok) throw new Error("Download failed");
|
|
92
|
+
const blob = await r.blob();
|
|
93
|
+
return { blob };
|
|
94
|
+
}
|
|
95
|
+
async deleteFile(req) {
|
|
96
|
+
await this._fetch(`/api/files/${encodeURIComponent(req.id)}`, { method: "DELETE" });
|
|
97
|
+
return { ok: true };
|
|
98
|
+
}
|
|
99
|
+
_uploadToSignedUrl(req) {
|
|
100
|
+
return new Promise(async (resolve, reject) => {
|
|
101
|
+
try {
|
|
102
|
+
const authHeaders = await this.headers();
|
|
103
|
+
const xhr = new XMLHttpRequest();
|
|
104
|
+
xhr.open("PUT", req.uploadUrl);
|
|
105
|
+
Object.keys(authHeaders || {}).forEach((k) => {
|
|
106
|
+
try {
|
|
107
|
+
xhr.setRequestHeader(k, authHeaders[k]);
|
|
108
|
+
} catch {
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
Object.keys(req.requiredHeaders || {}).forEach((k) => {
|
|
112
|
+
try {
|
|
113
|
+
xhr.setRequestHeader(k, (req.requiredHeaders || {})[k]);
|
|
114
|
+
} catch {
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
xhr.upload.onprogress = (ev) => {
|
|
118
|
+
if (!ev.lengthComputable) return req.onProgress && req.onProgress({ loaded: ev.loaded, total: ev.total });
|
|
119
|
+
req.onProgress && req.onProgress({ loaded: ev.loaded, total: ev.total, percent: ev.loaded / ev.total * 100 });
|
|
120
|
+
};
|
|
121
|
+
xhr.onload = () => {
|
|
122
|
+
if (xhr.status >= 200 && xhr.status < 300) resolve({ status: xhr.status });
|
|
123
|
+
else reject(new Error("Upload failed: " + xhr.status));
|
|
124
|
+
};
|
|
125
|
+
xhr.onerror = () => reject(new Error("Upload error"));
|
|
126
|
+
xhr.send(req.file);
|
|
127
|
+
} catch (err) {
|
|
128
|
+
reject(err);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
_uploadToSignedForm(req) {
|
|
133
|
+
return new Promise(async (resolve, reject) => {
|
|
134
|
+
try {
|
|
135
|
+
const xhr = new XMLHttpRequest();
|
|
136
|
+
xhr.open("POST", req.uploadUrl);
|
|
137
|
+
const form = new FormData();
|
|
138
|
+
Object.entries(req.fields || {}).forEach(([k, v]) => form.append(k, v));
|
|
139
|
+
form.append("file", req.file);
|
|
140
|
+
xhr.upload.onprogress = (ev) => {
|
|
141
|
+
if (!ev.lengthComputable) return req.onProgress && req.onProgress({ loaded: ev.loaded, total: ev.total });
|
|
142
|
+
req.onProgress && req.onProgress({ loaded: ev.loaded, total: ev.total, percent: ev.loaded / ev.total * 100 });
|
|
143
|
+
};
|
|
144
|
+
xhr.onload = () => {
|
|
145
|
+
if (xhr.status >= 200 && xhr.status < 300) resolve({ status: xhr.status });
|
|
146
|
+
else reject(new Error("Upload failed: " + xhr.status));
|
|
147
|
+
};
|
|
148
|
+
xhr.onerror = () => reject(new Error("Upload error"));
|
|
149
|
+
xhr.send(form);
|
|
150
|
+
} catch (err) {
|
|
151
|
+
reject(err);
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
async uploadFile(req) {
|
|
156
|
+
const file = req.file;
|
|
157
|
+
const opts = req.opts || {};
|
|
158
|
+
const onProgress = req.onProgress;
|
|
159
|
+
const filename = opts.filename ?? (file instanceof File ? file.name : "file.bin");
|
|
160
|
+
const contentType = opts.contentType ?? (file instanceof File ? file.type || "application/octet-stream" : "application/octet-stream");
|
|
161
|
+
const size = typeof opts.size === "number" ? opts.size : file instanceof File ? file.size : 0;
|
|
162
|
+
const sig = await this.createUploadSignature({ filename, contentType, maxSize: size });
|
|
163
|
+
if (!sig) throw new Error("No signature from server");
|
|
164
|
+
if (sig.url || sig.uploadUrl) {
|
|
165
|
+
const postUrl = sig.url || sig.uploadUrl;
|
|
166
|
+
await this._uploadToSignedForm({ uploadUrl: postUrl, fields: sig.fields || {}, file, onProgress });
|
|
167
|
+
} else {
|
|
168
|
+
throw new Error("No usable upload info from server");
|
|
38
169
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
async delete(key) {
|
|
42
|
-
const url = `${this.options.baseUrl || ""}/objects/${encodeURIComponent(key)}`;
|
|
43
|
-
const token = await this.getToken();
|
|
44
|
-
const headers = token ? { Authorization: `Bearer ${token}` } : void 0;
|
|
45
|
-
const res = await fetch(url, { method: "DELETE", headers });
|
|
46
|
-
return res.ok;
|
|
47
|
-
}
|
|
48
|
-
async list(prefix = "") {
|
|
49
|
-
const url = `${this.options.baseUrl || ""}/objects?prefix=${encodeURIComponent(prefix)}`;
|
|
50
|
-
const token = await this.getToken();
|
|
51
|
-
const headers = token ? { Authorization: `Bearer ${token}` } : void 0;
|
|
52
|
-
const res = await fetch(url, { headers });
|
|
53
|
-
if (!res.ok) return [];
|
|
54
|
-
const json = await res.json();
|
|
55
|
-
return Array.isArray(json) ? json : [];
|
|
170
|
+
const complete = await this.finalizeUpload({ key: sig.key, originalName: filename, contentType, size });
|
|
171
|
+
return { sig, complete };
|
|
56
172
|
}
|
|
57
173
|
};
|
|
174
|
+
var client_default = DidonatoStorageClient;
|
|
58
175
|
export {
|
|
59
176
|
DidonatoStorageClient,
|
|
60
|
-
|
|
177
|
+
client_default as default
|
|
61
178
|
};
|