@oasis-path/gamma-sdk 1.0.3 → 1.0.5
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 +28 -7
- package/dist/client.d.ts +2 -37
- package/dist/client.js +18 -215
- package/dist/methods/deleteFile.d.ts +2 -0
- package/dist/methods/deleteFile.js +7 -0
- package/dist/methods/downloadFile.d.ts +1 -0
- package/dist/methods/downloadFile.js +7 -0
- package/dist/methods/generatePresignedUrl.d.ts +2 -0
- package/dist/methods/generatePresignedUrl.js +16 -0
- package/dist/methods/getFileMetadata.d.ts +2 -0
- package/dist/methods/getFileMetadata.js +7 -0
- package/dist/methods/listFiles.d.ts +2 -0
- package/dist/methods/listFiles.js +7 -0
- package/dist/methods/request.d.ts +7 -0
- package/dist/methods/request.js +122 -0
- package/dist/methods/uploadFile.d.ts +2 -0
- package/dist/methods/uploadFile.js +44 -0
- package/dist/methods/viewFileByToken.d.ts +2 -0
- package/dist/methods/viewFileByToken.js +11 -0
- package/dist/types.d.ts +13 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -136,14 +136,26 @@ console.log('Expires at:', result.expiresAt);
|
|
|
136
136
|
|
|
137
137
|
### View File by Token
|
|
138
138
|
|
|
139
|
-
Access a file using a presigned token (no API key required):
|
|
139
|
+
Access a file using a presigned token (no API key required). Returns the file data along with response headers including caching information:
|
|
140
140
|
|
|
141
141
|
```typescript
|
|
142
|
-
const
|
|
142
|
+
const result = await client.viewFileByToken('presigned-token-here');
|
|
143
143
|
|
|
144
|
-
//
|
|
145
|
-
const buffer = Buffer.from(
|
|
144
|
+
// Access file data
|
|
145
|
+
const buffer = Buffer.from(result.data);
|
|
146
146
|
fs.writeFileSync('./viewed-file.pdf', buffer);
|
|
147
|
+
|
|
148
|
+
// Access cache headers for optimization
|
|
149
|
+
console.log('Content Type:', result.headers.contentType);
|
|
150
|
+
console.log('File Size:', result.headers.contentLength);
|
|
151
|
+
console.log('ETag:', result.headers.etag); // For cache validation
|
|
152
|
+
console.log('Cache Control:', result.headers.cacheControl);
|
|
153
|
+
console.log('Cloudflare Cache Tag:', result.headers.cfCacheTag); // File ID for consistent caching
|
|
154
|
+
|
|
155
|
+
// In browser, use the headers to implement client-side caching
|
|
156
|
+
if (result.headers.etag) {
|
|
157
|
+
localStorage.setItem(`file-etag-${result.headers.cfCacheTag}`, result.headers.etag);
|
|
158
|
+
}
|
|
147
159
|
```
|
|
148
160
|
|
|
149
161
|
## API Reference
|
|
@@ -232,14 +244,22 @@ Generate a presigned URL for temporary file access.
|
|
|
232
244
|
|
|
233
245
|
**API Key Permissions Required:** `read`, `write`, or `admin`
|
|
234
246
|
|
|
235
|
-
##### `viewFileByToken(token: string): Promise<
|
|
247
|
+
##### `viewFileByToken(token: string): Promise<ViewFileByTokenResult>`
|
|
236
248
|
|
|
237
|
-
Access a file using a presigned token (no API key required).
|
|
249
|
+
Access a file using a presigned token (no API key required). Returns file data along with response headers including caching information.
|
|
238
250
|
|
|
239
251
|
**Parameters:**
|
|
240
252
|
- `token` - Presigned token from `generatePresignedUrl`
|
|
241
253
|
|
|
242
|
-
**Returns:**
|
|
254
|
+
**Returns:** Object containing:
|
|
255
|
+
- `data` - File data as ArrayBuffer
|
|
256
|
+
- `headers` - Response headers including:
|
|
257
|
+
- `contentType` - MIME type of the file
|
|
258
|
+
- `contentLength` - Size of the file in bytes
|
|
259
|
+
- `contentDisposition` - Content disposition header (inline)
|
|
260
|
+
- `etag` - Entity tag for cache validation (based on file ID)
|
|
261
|
+
- `cacheControl` - Cache control directives (1 year immutable)
|
|
262
|
+
- `cfCacheTag` - Cloudflare cache tag (file ID for consistent caching across tokens)
|
|
243
263
|
|
|
244
264
|
**API Key Permissions Required:** None (uses token authentication)
|
|
245
265
|
|
|
@@ -260,6 +280,7 @@ import {
|
|
|
260
280
|
PresignedUrlOptions,
|
|
261
281
|
PresignedUrlResponse,
|
|
262
282
|
DownloadFileResult,
|
|
283
|
+
ViewFileByTokenResult,
|
|
263
284
|
ApiErrorResponse
|
|
264
285
|
} from '@gamma/files-sdk';
|
|
265
286
|
```
|
package/dist/client.d.ts
CHANGED
|
@@ -1,49 +1,14 @@
|
|
|
1
|
-
import { GammaFilesClientConfig, UploadFileOptions, UploadFileResponse, ListFilesResponse, FileMetadataResponse, DeleteFileResponse, PresignedUrlOptions, PresignedUrlResponse } from './types';
|
|
1
|
+
import { GammaFilesClientConfig, UploadFileOptions, UploadFileResponse, ListFilesResponse, FileMetadataResponse, DeleteFileResponse, PresignedUrlOptions, PresignedUrlResponse, ViewFileByTokenResult } from './types';
|
|
2
2
|
export declare class GammaFilesClient {
|
|
3
3
|
private baseUrl;
|
|
4
4
|
private apiKey;
|
|
5
5
|
constructor(config: GammaFilesClientConfig);
|
|
6
|
-
/**
|
|
7
|
-
* Upload a file to a folder
|
|
8
|
-
* @param options Upload options including file buffer/blob, filename, and optional folderId
|
|
9
|
-
* @returns Upload response with file metadata
|
|
10
|
-
*/
|
|
11
6
|
uploadFile(options: UploadFileOptions): Promise<UploadFileResponse>;
|
|
12
|
-
/**
|
|
13
|
-
* Download a file by ID
|
|
14
|
-
* @param fileId File ID to download
|
|
15
|
-
* @returns File metadata and data buffer
|
|
16
|
-
*/
|
|
17
7
|
downloadFile(fileId: string): Promise<ArrayBuffer>;
|
|
18
|
-
/**
|
|
19
|
-
* List all files in a folder
|
|
20
|
-
* @param folderId Folder ID to list files from
|
|
21
|
-
* @returns List of files in the folder
|
|
22
|
-
*/
|
|
23
8
|
listFiles(folderId: string): Promise<ListFilesResponse>;
|
|
24
|
-
/**
|
|
25
|
-
* Delete a file by ID
|
|
26
|
-
* @param fileId File ID to delete
|
|
27
|
-
* @returns Deletion confirmation
|
|
28
|
-
*/
|
|
29
9
|
deleteFile(fileId: string): Promise<DeleteFileResponse>;
|
|
30
|
-
/**
|
|
31
|
-
* Get file metadata by ID
|
|
32
|
-
* @param fileId File ID to get metadata for
|
|
33
|
-
* @returns File metadata
|
|
34
|
-
*/
|
|
35
10
|
getFileMetadata(fileId: string): Promise<FileMetadataResponse>;
|
|
36
|
-
/**
|
|
37
|
-
* Generate a presigned URL for temporary file access
|
|
38
|
-
* @param options Options including fileId and optional expiresIn (seconds)
|
|
39
|
-
* @returns Presigned URL token and expiration info
|
|
40
|
-
*/
|
|
41
11
|
generatePresignedUrl(options: PresignedUrlOptions): Promise<PresignedUrlResponse>;
|
|
42
|
-
|
|
43
|
-
* Access a file using a presigned token (no API key required)
|
|
44
|
-
* @param token Presigned token
|
|
45
|
-
* @returns File data as ArrayBuffer
|
|
46
|
-
*/
|
|
47
|
-
viewFileByToken(token: string): Promise<ArrayBuffer>;
|
|
12
|
+
viewFileByToken(token: string): Promise<ViewFileByTokenResult>;
|
|
48
13
|
private request;
|
|
49
14
|
}
|
package/dist/client.js
CHANGED
|
@@ -1,239 +1,42 @@
|
|
|
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
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
-
};
|
|
38
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
3
|
exports.GammaFilesClient = void 0;
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
const
|
|
4
|
+
const uploadFile_1 = require("./methods/uploadFile");
|
|
5
|
+
const downloadFile_1 = require("./methods/downloadFile");
|
|
6
|
+
const listFiles_1 = require("./methods/listFiles");
|
|
7
|
+
const deleteFile_1 = require("./methods/deleteFile");
|
|
8
|
+
const getFileMetadata_1 = require("./methods/getFileMetadata");
|
|
9
|
+
const generatePresignedUrl_1 = require("./methods/generatePresignedUrl");
|
|
10
|
+
const viewFileByToken_1 = require("./methods/viewFileByToken");
|
|
11
|
+
const request_1 = require("./methods/request");
|
|
44
12
|
class GammaFilesClient {
|
|
45
13
|
constructor(config) {
|
|
46
|
-
this.baseUrl = config.baseUrl.replace(/\/$/, '');
|
|
14
|
+
this.baseUrl = config.baseUrl.replace(/\/$/, '');
|
|
47
15
|
this.apiKey = config.apiKey;
|
|
48
16
|
}
|
|
49
|
-
/**
|
|
50
|
-
* Upload a file to a folder
|
|
51
|
-
* @param options Upload options including file buffer/blob, filename, and optional folderId
|
|
52
|
-
* @returns Upload response with file metadata
|
|
53
|
-
*/
|
|
54
17
|
async uploadFile(options) {
|
|
55
|
-
|
|
56
|
-
const form = new form_data_1.default();
|
|
57
|
-
// Handle different file types
|
|
58
|
-
let fileBuffer;
|
|
59
|
-
let contentType = mimeType || 'application/octet-stream';
|
|
60
|
-
if (Buffer.isBuffer(file)) {
|
|
61
|
-
fileBuffer = file;
|
|
62
|
-
}
|
|
63
|
-
else if (typeof Blob !== 'undefined' && file instanceof Blob) {
|
|
64
|
-
// Browser environment
|
|
65
|
-
const arrayBuffer = await file.arrayBuffer();
|
|
66
|
-
fileBuffer = Buffer.from(arrayBuffer);
|
|
67
|
-
contentType = mimeType || file.type || 'application/octet-stream';
|
|
68
|
-
}
|
|
69
|
-
else if (typeof File !== 'undefined' && file instanceof File) {
|
|
70
|
-
// Browser File object
|
|
71
|
-
const arrayBuffer = await file.arrayBuffer();
|
|
72
|
-
fileBuffer = Buffer.from(arrayBuffer);
|
|
73
|
-
contentType = mimeType || file.type || 'application/octet-stream';
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
76
|
-
throw new Error('Unsupported file type');
|
|
77
|
-
}
|
|
78
|
-
form.append('file', fileBuffer, {
|
|
79
|
-
filename,
|
|
80
|
-
contentType,
|
|
81
|
-
});
|
|
82
|
-
const url = folderId
|
|
83
|
-
? `/api/files/upload/${folderId}`
|
|
84
|
-
: '/api/files/upload';
|
|
85
|
-
return this.request('POST', url, {
|
|
86
|
-
body: form,
|
|
87
|
-
headers: form.getHeaders(),
|
|
88
|
-
});
|
|
18
|
+
return (0, uploadFile_1.uploadFile)(this.baseUrl, this.apiKey, options, this.request.bind(this));
|
|
89
19
|
}
|
|
90
|
-
/**
|
|
91
|
-
* Download a file by ID
|
|
92
|
-
* @param fileId File ID to download
|
|
93
|
-
* @returns File metadata and data buffer
|
|
94
|
-
*/
|
|
95
20
|
async downloadFile(fileId) {
|
|
96
|
-
|
|
97
|
-
return this.request('GET', url, { binary: true });
|
|
21
|
+
return (0, downloadFile_1.downloadFile)(fileId, this.request.bind(this));
|
|
98
22
|
}
|
|
99
|
-
/**
|
|
100
|
-
* List all files in a folder
|
|
101
|
-
* @param folderId Folder ID to list files from
|
|
102
|
-
* @returns List of files in the folder
|
|
103
|
-
*/
|
|
104
23
|
async listFiles(folderId) {
|
|
105
|
-
|
|
106
|
-
return this.request('GET', url);
|
|
24
|
+
return (0, listFiles_1.listFiles)(folderId, this.request.bind(this));
|
|
107
25
|
}
|
|
108
|
-
/**
|
|
109
|
-
* Delete a file by ID
|
|
110
|
-
* @param fileId File ID to delete
|
|
111
|
-
* @returns Deletion confirmation
|
|
112
|
-
*/
|
|
113
26
|
async deleteFile(fileId) {
|
|
114
|
-
|
|
115
|
-
return this.request('DELETE', url);
|
|
27
|
+
return (0, deleteFile_1.deleteFile)(fileId, this.request.bind(this));
|
|
116
28
|
}
|
|
117
|
-
/**
|
|
118
|
-
* Get file metadata by ID
|
|
119
|
-
* @param fileId File ID to get metadata for
|
|
120
|
-
* @returns File metadata
|
|
121
|
-
*/
|
|
122
29
|
async getFileMetadata(fileId) {
|
|
123
|
-
|
|
124
|
-
return this.request('GET', url);
|
|
30
|
+
return (0, getFileMetadata_1.getFileMetadata)(fileId, this.request.bind(this));
|
|
125
31
|
}
|
|
126
|
-
/**
|
|
127
|
-
* Generate a presigned URL for temporary file access
|
|
128
|
-
* @param options Options including fileId and optional expiresIn (seconds)
|
|
129
|
-
* @returns Presigned URL token and expiration info
|
|
130
|
-
*/
|
|
131
32
|
async generatePresignedUrl(options) {
|
|
132
|
-
|
|
133
|
-
return this.request('POST', url, {
|
|
134
|
-
body: JSON.stringify(options),
|
|
135
|
-
headers: {
|
|
136
|
-
'Content-Type': 'application/json',
|
|
137
|
-
},
|
|
138
|
-
});
|
|
33
|
+
return (0, generatePresignedUrl_1.generatePresignedUrl)(options, this.request.bind(this));
|
|
139
34
|
}
|
|
140
|
-
/**
|
|
141
|
-
* Access a file using a presigned token (no API key required)
|
|
142
|
-
* @param token Presigned token
|
|
143
|
-
* @returns File data as ArrayBuffer
|
|
144
|
-
*/
|
|
145
35
|
async viewFileByToken(token) {
|
|
146
|
-
|
|
147
|
-
return this.request('GET', url, {
|
|
148
|
-
binary: true,
|
|
149
|
-
skipAuth: true
|
|
150
|
-
});
|
|
36
|
+
return (0, viewFileByToken_1.viewFileByToken)(token, this.request.bind(this));
|
|
151
37
|
}
|
|
152
|
-
async request(method, path, options
|
|
153
|
-
|
|
154
|
-
const isHttps = url.protocol === 'https:';
|
|
155
|
-
const lib = isHttps ? https : http;
|
|
156
|
-
return new Promise((resolve, reject) => {
|
|
157
|
-
const headers = {
|
|
158
|
-
...options.headers,
|
|
159
|
-
};
|
|
160
|
-
if (!options.skipAuth) {
|
|
161
|
-
headers['Authorization'] = `Bearer ${this.apiKey}`;
|
|
162
|
-
}
|
|
163
|
-
// If body is not FormData, set content-length
|
|
164
|
-
if (options.body && !(options.body instanceof form_data_1.default)) {
|
|
165
|
-
if (typeof options.body === 'string') {
|
|
166
|
-
headers['Content-Length'] = Buffer.byteLength(options.body).toString();
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
const reqOptions = {
|
|
170
|
-
method,
|
|
171
|
-
headers,
|
|
172
|
-
};
|
|
173
|
-
const req = lib.request(url, reqOptions, (res) => {
|
|
174
|
-
const chunks = [];
|
|
175
|
-
res.on('data', (chunk) => {
|
|
176
|
-
chunks.push(chunk);
|
|
177
|
-
});
|
|
178
|
-
res.on('end', () => {
|
|
179
|
-
const buffer = Buffer.concat(chunks);
|
|
180
|
-
const responseText = buffer.toString();
|
|
181
|
-
if (res.statusCode && res.statusCode >= 400) {
|
|
182
|
-
let errorMessage = `HTTP ${res.statusCode}`;
|
|
183
|
-
let errorDetails = '';
|
|
184
|
-
try {
|
|
185
|
-
const errorBody = JSON.parse(responseText);
|
|
186
|
-
errorMessage = errorBody.error || errorBody.message || errorMessage;
|
|
187
|
-
errorDetails = errorBody.details ? `\nDetails: ${JSON.stringify(errorBody.details)}` : '';
|
|
188
|
-
// Create a more descriptive error
|
|
189
|
-
const fullError = new Error(`API Error (${res.statusCode}): ${errorMessage}${errorDetails}\nEndpoint: ${method} ${url.pathname}`);
|
|
190
|
-
fullError.statusCode = res.statusCode;
|
|
191
|
-
fullError.responseBody = errorBody;
|
|
192
|
-
reject(fullError);
|
|
193
|
-
}
|
|
194
|
-
catch {
|
|
195
|
-
// If response is not JSON, use raw text
|
|
196
|
-
const fullError = new Error(`API Error (${res.statusCode}): ${responseText || errorMessage}\nEndpoint: ${method} ${url.pathname}`);
|
|
197
|
-
fullError.statusCode = res.statusCode;
|
|
198
|
-
fullError.responseBody = responseText;
|
|
199
|
-
reject(fullError);
|
|
200
|
-
}
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
if (options.binary) {
|
|
204
|
-
resolve(buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength));
|
|
205
|
-
}
|
|
206
|
-
else {
|
|
207
|
-
try {
|
|
208
|
-
const data = JSON.parse(responseText);
|
|
209
|
-
resolve(data);
|
|
210
|
-
}
|
|
211
|
-
catch (err) {
|
|
212
|
-
const parseError = new Error(`Failed to parse response JSON from ${method} ${url.pathname}\nResponse: ${responseText.substring(0, 200)}${responseText.length > 200 ? '...' : ''}`);
|
|
213
|
-
parseError.responseText = responseText;
|
|
214
|
-
reject(parseError);
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
});
|
|
218
|
-
});
|
|
219
|
-
req.on('error', (err) => {
|
|
220
|
-
const networkError = new Error(`Network error for ${method} ${url.pathname}: ${err.message}`);
|
|
221
|
-
networkError.originalError = err;
|
|
222
|
-
reject(networkError);
|
|
223
|
-
});
|
|
224
|
-
if (options.body) {
|
|
225
|
-
if (options.body instanceof form_data_1.default) {
|
|
226
|
-
options.body.pipe(req);
|
|
227
|
-
}
|
|
228
|
-
else {
|
|
229
|
-
req.write(options.body);
|
|
230
|
-
req.end();
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
else {
|
|
234
|
-
req.end();
|
|
235
|
-
}
|
|
236
|
-
});
|
|
38
|
+
async request(method, path, options) {
|
|
39
|
+
return (0, request_1.makeRequest)(method, path, this.baseUrl, this.apiKey, options);
|
|
237
40
|
}
|
|
238
41
|
}
|
|
239
42
|
exports.GammaFilesClient = GammaFilesClient;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function downloadFile(fileId: string, request: <T>(method: string, path: string, options?: any) => Promise<T>): Promise<ArrayBuffer>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generatePresignedUrl = generatePresignedUrl;
|
|
4
|
+
async function generatePresignedUrl(options, request) {
|
|
5
|
+
const url = '/api/files/presigned-url';
|
|
6
|
+
const payload = {
|
|
7
|
+
...options,
|
|
8
|
+
maxUsageCount: options.maxUsageCount ?? 1
|
|
9
|
+
};
|
|
10
|
+
return request('POST', url, {
|
|
11
|
+
body: JSON.stringify(payload),
|
|
12
|
+
headers: {
|
|
13
|
+
'Content-Type': 'application/json',
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
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 __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.makeRequest = makeRequest;
|
|
40
|
+
const https = __importStar(require("https"));
|
|
41
|
+
const http = __importStar(require("http"));
|
|
42
|
+
const url_1 = require("url");
|
|
43
|
+
const form_data_1 = __importDefault(require("form-data"));
|
|
44
|
+
async function makeRequest(method, path, baseUrl, apiKey, options = {}) {
|
|
45
|
+
const url = new url_1.URL(path, baseUrl);
|
|
46
|
+
const isHttps = url.protocol === 'https:';
|
|
47
|
+
const lib = isHttps ? https : http;
|
|
48
|
+
return new Promise((resolve, reject) => {
|
|
49
|
+
const headers = {
|
|
50
|
+
...options.headers,
|
|
51
|
+
};
|
|
52
|
+
if (!options.skipAuth) {
|
|
53
|
+
headers['Authorization'] = `Bearer ${apiKey}`;
|
|
54
|
+
}
|
|
55
|
+
if (options.body && !(options.body instanceof form_data_1.default)) {
|
|
56
|
+
if (typeof options.body === 'string') {
|
|
57
|
+
headers['Content-Length'] = Buffer.byteLength(options.body).toString();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const reqOptions = {
|
|
61
|
+
method,
|
|
62
|
+
headers,
|
|
63
|
+
};
|
|
64
|
+
const req = lib.request(url, reqOptions, (res) => {
|
|
65
|
+
const chunks = [];
|
|
66
|
+
res.on('data', (chunk) => {
|
|
67
|
+
chunks.push(chunk);
|
|
68
|
+
});
|
|
69
|
+
res.on('end', () => {
|
|
70
|
+
const buffer = Buffer.concat(chunks);
|
|
71
|
+
const responseText = buffer.toString();
|
|
72
|
+
if (res.statusCode && res.statusCode >= 400) {
|
|
73
|
+
const errorBody = JSON.parse(responseText);
|
|
74
|
+
const fullError = new Error(errorBody.error || errorBody.message || `HTTP ${res.statusCode}`);
|
|
75
|
+
fullError.statusCode = res.statusCode;
|
|
76
|
+
fullError.responseBody = errorBody;
|
|
77
|
+
reject(fullError);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (options.binary) {
|
|
81
|
+
const arrayBuffer = buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
|
|
82
|
+
if (options.includeHeaders) {
|
|
83
|
+
const result = {
|
|
84
|
+
data: arrayBuffer,
|
|
85
|
+
headers: {
|
|
86
|
+
contentType: res.headers['content-type'] || '',
|
|
87
|
+
contentLength: parseInt(res.headers['content-length'] || '0', 10),
|
|
88
|
+
contentDisposition: res.headers['content-disposition'] || '',
|
|
89
|
+
etag: res.headers['etag'],
|
|
90
|
+
cacheControl: res.headers['cache-control'],
|
|
91
|
+
cfCacheTag: res.headers['cf-cache-tag'],
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
resolve(result);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
resolve(arrayBuffer);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
const data = JSON.parse(responseText);
|
|
102
|
+
resolve(data);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
req.on('error', (err) => {
|
|
107
|
+
reject(err);
|
|
108
|
+
});
|
|
109
|
+
if (options.body) {
|
|
110
|
+
if (options.body instanceof form_data_1.default) {
|
|
111
|
+
options.body.pipe(req);
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
req.write(options.body);
|
|
115
|
+
req.end();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
req.end();
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.uploadFile = uploadFile;
|
|
7
|
+
const form_data_1 = __importDefault(require("form-data"));
|
|
8
|
+
async function uploadFile(baseUrl, apiKey, options, request) {
|
|
9
|
+
const { file, filename, mimeType, folderId } = options;
|
|
10
|
+
const form = new form_data_1.default();
|
|
11
|
+
let fileBuffer;
|
|
12
|
+
let contentType = mimeType || 'application/octet-stream';
|
|
13
|
+
if (Buffer.isBuffer(file)) {
|
|
14
|
+
fileBuffer = file;
|
|
15
|
+
}
|
|
16
|
+
else if (typeof file === 'string') {
|
|
17
|
+
// Handle base64 string
|
|
18
|
+
fileBuffer = Buffer.from(file, 'base64');
|
|
19
|
+
}
|
|
20
|
+
else if (typeof Blob !== 'undefined' && file instanceof Blob) {
|
|
21
|
+
const arrayBuffer = await file.arrayBuffer();
|
|
22
|
+
fileBuffer = Buffer.from(arrayBuffer);
|
|
23
|
+
contentType = mimeType || file.type || 'application/octet-stream';
|
|
24
|
+
}
|
|
25
|
+
else if (typeof File !== 'undefined' && file instanceof File) {
|
|
26
|
+
const arrayBuffer = await file.arrayBuffer();
|
|
27
|
+
fileBuffer = Buffer.from(arrayBuffer);
|
|
28
|
+
contentType = mimeType || file.type || 'application/octet-stream';
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
throw new Error('Unsupported file type');
|
|
32
|
+
}
|
|
33
|
+
form.append('file', fileBuffer, {
|
|
34
|
+
filename,
|
|
35
|
+
contentType,
|
|
36
|
+
});
|
|
37
|
+
const url = folderId
|
|
38
|
+
? `/api/files/upload/${folderId}`
|
|
39
|
+
: '/api/files/upload';
|
|
40
|
+
return request('POST', url, {
|
|
41
|
+
body: form,
|
|
42
|
+
headers: form.getHeaders(),
|
|
43
|
+
});
|
|
44
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.viewFileByToken = viewFileByToken;
|
|
4
|
+
async function viewFileByToken(token, request) {
|
|
5
|
+
const url = `/api/files/view/${token}`;
|
|
6
|
+
return request('GET', url, {
|
|
7
|
+
binary: true,
|
|
8
|
+
skipAuth: true,
|
|
9
|
+
includeHeaders: true
|
|
10
|
+
});
|
|
11
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export interface FileMetadata {
|
|
|
13
13
|
createdAt: string;
|
|
14
14
|
}
|
|
15
15
|
export interface UploadFileOptions {
|
|
16
|
-
file: Buffer | Blob | File;
|
|
16
|
+
file: Buffer | Blob | File | string;
|
|
17
17
|
filename: string;
|
|
18
18
|
mimeType?: string;
|
|
19
19
|
folderId?: string;
|
|
@@ -37,6 +37,7 @@ export interface DeleteFileResponse {
|
|
|
37
37
|
export interface PresignedUrlOptions {
|
|
38
38
|
fileId: string;
|
|
39
39
|
expiresIn?: number;
|
|
40
|
+
maxUsageCount?: number;
|
|
40
41
|
}
|
|
41
42
|
export interface PresignedUrlResponse {
|
|
42
43
|
success: true;
|
|
@@ -48,6 +49,17 @@ export interface DownloadFileResult {
|
|
|
48
49
|
file: FileMetadata;
|
|
49
50
|
data: ArrayBuffer;
|
|
50
51
|
}
|
|
52
|
+
export interface ViewFileByTokenResult {
|
|
53
|
+
data: ArrayBuffer;
|
|
54
|
+
headers: {
|
|
55
|
+
contentType: string;
|
|
56
|
+
contentLength: number;
|
|
57
|
+
contentDisposition: string;
|
|
58
|
+
etag?: string;
|
|
59
|
+
cacheControl?: string;
|
|
60
|
+
cfCacheTag?: string;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
51
63
|
export interface ApiErrorResponse {
|
|
52
64
|
success: false;
|
|
53
65
|
error: string;
|