@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 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 fileData = await client.viewFileByToken('presigned-token-here');
142
+ const result = await client.viewFileByToken('presigned-token-here');
143
143
 
144
- // Handle the file data as needed
145
- const buffer = Buffer.from(fileData);
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<ArrayBuffer>`
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:** File data as ArrayBuffer
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 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"));
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(/\/$/, ''); // Remove trailing slash
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
- const { file, filename, mimeType, folderId } = options;
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
- const url = `/api/files/download/${fileId}`;
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
- const url = `/api/files/list/${folderId}`;
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
- const url = `/api/files/${fileId}`;
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
- const url = `/api/files/${fileId}/metadata`;
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
- const url = '/api/files/presigned-url';
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
- const url = `/api/files/view/${token}`;
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
- const url = new url_1.URL(path, this.baseUrl);
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,2 @@
1
+ import { DeleteFileResponse } from '../types';
2
+ export declare function deleteFile(fileId: string, request: <T>(method: string, path: string, options?: any) => Promise<T>): Promise<DeleteFileResponse>;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deleteFile = deleteFile;
4
+ async function deleteFile(fileId, request) {
5
+ const url = `/api/files/${fileId}`;
6
+ return request('DELETE', url);
7
+ }
@@ -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,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.downloadFile = downloadFile;
4
+ async function downloadFile(fileId, request) {
5
+ const url = `/api/files/download/${fileId}`;
6
+ return request('GET', url, { binary: true });
7
+ }
@@ -0,0 +1,2 @@
1
+ import { PresignedUrlOptions, PresignedUrlResponse } from '../types';
2
+ export declare function generatePresignedUrl(options: PresignedUrlOptions, request: <T>(method: string, path: string, options?: any) => Promise<T>): Promise<PresignedUrlResponse>;
@@ -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,2 @@
1
+ import { FileMetadataResponse } from '../types';
2
+ export declare function getFileMetadata(fileId: string, request: <T>(method: string, path: string, options?: any) => Promise<T>): Promise<FileMetadataResponse>;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getFileMetadata = getFileMetadata;
4
+ async function getFileMetadata(fileId, request) {
5
+ const url = `/api/files/${fileId}/metadata`;
6
+ return request('GET', url);
7
+ }
@@ -0,0 +1,2 @@
1
+ import { ListFilesResponse } from '../types';
2
+ export declare function listFiles(folderId: string, request: <T>(method: string, path: string, options?: any) => Promise<T>): Promise<ListFilesResponse>;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.listFiles = listFiles;
4
+ async function listFiles(folderId, request) {
5
+ const url = `/api/files/list/${folderId}`;
6
+ return request('GET', url);
7
+ }
@@ -0,0 +1,7 @@
1
+ export declare function makeRequest<T>(method: string, path: string, baseUrl: string, apiKey: string, options?: {
2
+ body?: any;
3
+ headers?: Record<string, string>;
4
+ binary?: boolean;
5
+ skipAuth?: boolean;
6
+ includeHeaders?: boolean;
7
+ }): Promise<T>;
@@ -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,2 @@
1
+ import { UploadFileOptions, UploadFileResponse } from '../types';
2
+ export declare function uploadFile(baseUrl: string, apiKey: string, options: UploadFileOptions, request: <T>(method: string, path: string, options?: any) => Promise<T>): Promise<UploadFileResponse>;
@@ -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,2 @@
1
+ import { ViewFileByTokenResult } from '../types';
2
+ export declare function viewFileByToken(token: string, request: <T>(method: string, path: string, options?: any) => Promise<T>): Promise<ViewFileByTokenResult>;
@@ -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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oasis-path/gamma-sdk",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "TypeScript SDK for Gamma Files API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",