@oasis-path/gamma-sdk 1.0.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/README.md ADDED
@@ -0,0 +1,285 @@
1
+ # Gamma Files SDK
2
+
3
+ TypeScript/JavaScript SDK for interacting with the Gamma Files API.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm install @gamma/files-sdk
9
+ ```
10
+
11
+ Or if you're developing locally:
12
+
13
+ ```bash
14
+ cd sdk
15
+ pnpm install
16
+ pnpm run build
17
+ ```
18
+
19
+ Then in your project:
20
+
21
+ ```bash
22
+ pnpm install ../sdk
23
+ ```
24
+
25
+ ## Configuration
26
+
27
+ Create a client instance with your API key and base URL:
28
+
29
+ ```typescript
30
+ import { GammaFilesClient } from '@gamma/files-sdk';
31
+
32
+ const client = new GammaFilesClient({
33
+ baseUrl: 'http://localhost:3000',
34
+ apiKey: 'your-api-key-here'
35
+ });
36
+ ```
37
+
38
+ ## Usage Examples
39
+
40
+ ### Upload a File
41
+
42
+ ```typescript
43
+ import * as fs from 'fs';
44
+
45
+ // Upload from Node.js Buffer
46
+ const fileBuffer = fs.readFileSync('./document.pdf');
47
+ const result = await client.uploadFile({
48
+ file: fileBuffer,
49
+ filename: 'document.pdf',
50
+ mimeType: 'application/pdf',
51
+ folderId: 'folder-id-here' // optional, uploads to root if not specified
52
+ });
53
+
54
+ console.log('Uploaded file:', result.file);
55
+ ```
56
+
57
+ In browser environment:
58
+
59
+ ```typescript
60
+ // Upload from File input
61
+ const fileInput = document.querySelector('input[type="file"]');
62
+ const file = fileInput.files[0];
63
+
64
+ const result = await client.uploadFile({
65
+ file: file,
66
+ filename: file.name,
67
+ mimeType: file.type,
68
+ folderId: 'folder-id-here' // optional
69
+ });
70
+ ```
71
+
72
+ ### Download a File
73
+
74
+ ```typescript
75
+ const fileData = await client.downloadFile('file-id-here');
76
+
77
+ // In Node.js, save to disk
78
+ const buffer = Buffer.from(fileData);
79
+ fs.writeFileSync('./downloaded-file.pdf', buffer);
80
+
81
+ // In browser, create a download link
82
+ const blob = new Blob([fileData]);
83
+ const url = URL.createObjectURL(blob);
84
+ const a = document.createElement('a');
85
+ a.href = url;
86
+ a.download = 'file.pdf';
87
+ a.click();
88
+ ```
89
+
90
+ ### List Files in a Folder
91
+
92
+ ```typescript
93
+ const result = await client.listFiles('folder-id-here');
94
+
95
+ console.log('Files:', result.files);
96
+ result.files.forEach(file => {
97
+ console.log(`- ${file.originalName} (${file.size} bytes)`);
98
+ });
99
+ ```
100
+
101
+ ### Get File Metadata
102
+
103
+ ```typescript
104
+ const result = await client.getFileMetadata('file-id-here');
105
+
106
+ console.log('File metadata:', result.file);
107
+ console.log('Name:', result.file.originalName);
108
+ console.log('Size:', result.file.size);
109
+ console.log('Type:', result.file.mimeType);
110
+ console.log('Uploaded:', result.file.createdAt);
111
+ ```
112
+
113
+ ### Delete a File
114
+
115
+ ```typescript
116
+ const result = await client.deleteFile('file-id-here');
117
+ console.log(result.message); // "File deleted successfully"
118
+ ```
119
+
120
+ ### Generate Presigned URL
121
+
122
+ Generate a temporary URL for file access without requiring API key authentication:
123
+
124
+ ```typescript
125
+ const result = await client.generatePresignedUrl({
126
+ fileId: 'file-id-here',
127
+ expiresIn: 3600 // optional, defaults to 3600 seconds (1 hour)
128
+ });
129
+
130
+ console.log('Presigned URL:', result.url);
131
+ console.log('Token:', result.token);
132
+ console.log('Expires at:', result.expiresAt);
133
+
134
+ // Share this URL with anyone - no API key needed
135
+ ```
136
+
137
+ ### View File by Token
138
+
139
+ Access a file using a presigned token (no API key required):
140
+
141
+ ```typescript
142
+ const fileData = await client.viewFileByToken('presigned-token-here');
143
+
144
+ // Handle the file data as needed
145
+ const buffer = Buffer.from(fileData);
146
+ fs.writeFileSync('./viewed-file.pdf', buffer);
147
+ ```
148
+
149
+ ## API Reference
150
+
151
+ ### `GammaFilesClient`
152
+
153
+ #### Constructor
154
+
155
+ ```typescript
156
+ new GammaFilesClient(config: GammaFilesClientConfig)
157
+ ```
158
+
159
+ **Parameters:**
160
+ - `config.baseUrl` - Base URL of the Gamma API
161
+ - `config.apiKey` - Your API key (must have appropriate permissions)
162
+
163
+ #### Methods
164
+
165
+ ##### `uploadFile(options: UploadFileOptions): Promise<UploadFileResponse>`
166
+
167
+ Upload a file to the server.
168
+
169
+ **Parameters:**
170
+ - `options.file` - File data (Buffer, Blob, or File object)
171
+ - `options.filename` - Name of the file
172
+ - `options.mimeType` - MIME type (optional, will be detected if not provided)
173
+ - `options.folderId` - Target folder ID (optional, uploads to root folder if not specified)
174
+
175
+ **Returns:** Upload response with file metadata
176
+
177
+ **API Key Permissions Required:** `write` or `admin`
178
+
179
+ ##### `downloadFile(fileId: string): Promise<ArrayBuffer>`
180
+
181
+ Download a file by ID.
182
+
183
+ **Parameters:**
184
+ - `fileId` - ID of the file to download
185
+
186
+ **Returns:** File data as ArrayBuffer
187
+
188
+ **API Key Permissions Required:** `read`, `write`, or `admin`
189
+
190
+ ##### `listFiles(folderId: string): Promise<ListFilesResponse>`
191
+
192
+ List all files in a folder.
193
+
194
+ **Parameters:**
195
+ - `folderId` - ID of the folder
196
+
197
+ **Returns:** List of files with metadata
198
+
199
+ **API Key Permissions Required:** `read`, `write`, or `admin`
200
+
201
+ ##### `deleteFile(fileId: string): Promise<DeleteFileResponse>`
202
+
203
+ Delete a file by ID.
204
+
205
+ **Parameters:**
206
+ - `fileId` - ID of the file to delete
207
+
208
+ **Returns:** Deletion confirmation message
209
+
210
+ **API Key Permissions Required:** `write` or `admin`
211
+
212
+ ##### `getFileMetadata(fileId: string): Promise<FileMetadataResponse>`
213
+
214
+ Get metadata for a specific file.
215
+
216
+ **Parameters:**
217
+ - `fileId` - ID of the file
218
+
219
+ **Returns:** File metadata
220
+
221
+ **API Key Permissions Required:** `read`, `write`, or `admin`
222
+
223
+ ##### `generatePresignedUrl(options: PresignedUrlOptions): Promise<PresignedUrlResponse>`
224
+
225
+ Generate a presigned URL for temporary file access.
226
+
227
+ **Parameters:**
228
+ - `options.fileId` - ID of the file
229
+ - `options.expiresIn` - Expiration time in seconds (min: 60, max: 86400, default: 3600)
230
+
231
+ **Returns:** Presigned URL information including token, full URL, and expiration time
232
+
233
+ **API Key Permissions Required:** `read`, `write`, or `admin`
234
+
235
+ ##### `viewFileByToken(token: string): Promise<ArrayBuffer>`
236
+
237
+ Access a file using a presigned token (no API key required).
238
+
239
+ **Parameters:**
240
+ - `token` - Presigned token from `generatePresignedUrl`
241
+
242
+ **Returns:** File data as ArrayBuffer
243
+
244
+ **API Key Permissions Required:** None (uses token authentication)
245
+
246
+ ## Types
247
+
248
+ All TypeScript types are exported from the package:
249
+
250
+ ```typescript
251
+ import {
252
+ GammaFilesClient,
253
+ GammaFilesClientConfig,
254
+ FileMetadata,
255
+ UploadFileOptions,
256
+ UploadFileResponse,
257
+ ListFilesResponse,
258
+ FileMetadataResponse,
259
+ DeleteFileResponse,
260
+ PresignedUrlOptions,
261
+ PresignedUrlResponse,
262
+ DownloadFileResult,
263
+ ApiErrorResponse
264
+ } from '@gamma/files-sdk';
265
+ ```
266
+
267
+ ## Error Handling
268
+
269
+ All methods throw errors when requests fail:
270
+
271
+ ```typescript
272
+ try {
273
+ const result = await client.uploadFile({
274
+ file: buffer,
275
+ filename: 'test.pdf'
276
+ });
277
+ console.log('Success:', result);
278
+ } catch (error) {
279
+ console.error('Upload failed:', error.message);
280
+ }
281
+ ```
282
+
283
+ ## License
284
+
285
+ MIT
@@ -0,0 +1,49 @@
1
+ import { GammaFilesClientConfig, UploadFileOptions, UploadFileResponse, ListFilesResponse, FileMetadataResponse, DeleteFileResponse, PresignedUrlOptions, PresignedUrlResponse } from './types';
2
+ export declare class GammaFilesClient {
3
+ private baseUrl;
4
+ private apiKey;
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
+ 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
+ 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
+ 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
+ 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
+ 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
+ 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>;
48
+ private request;
49
+ }
package/dist/client.js ADDED
@@ -0,0 +1,224 @@
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.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"));
44
+ class GammaFilesClient {
45
+ constructor(config) {
46
+ this.baseUrl = config.baseUrl.replace(/\/$/, ''); // Remove trailing slash
47
+ this.apiKey = config.apiKey;
48
+ }
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
+ 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
+ });
89
+ }
90
+ /**
91
+ * Download a file by ID
92
+ * @param fileId File ID to download
93
+ * @returns File metadata and data buffer
94
+ */
95
+ async downloadFile(fileId) {
96
+ const url = `/api/files/download/${fileId}`;
97
+ return this.request('GET', url, { binary: true });
98
+ }
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
+ async listFiles(folderId) {
105
+ const url = `/api/files/list/${folderId}`;
106
+ return this.request('GET', url);
107
+ }
108
+ /**
109
+ * Delete a file by ID
110
+ * @param fileId File ID to delete
111
+ * @returns Deletion confirmation
112
+ */
113
+ async deleteFile(fileId) {
114
+ const url = `/api/files/${fileId}`;
115
+ return this.request('DELETE', url);
116
+ }
117
+ /**
118
+ * Get file metadata by ID
119
+ * @param fileId File ID to get metadata for
120
+ * @returns File metadata
121
+ */
122
+ async getFileMetadata(fileId) {
123
+ const url = `/api/files/${fileId}/metadata`;
124
+ return this.request('GET', url);
125
+ }
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
+ 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
+ });
139
+ }
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
+ async viewFileByToken(token) {
146
+ const url = `/api/files/view/${token}`;
147
+ return this.request('GET', url, {
148
+ binary: true,
149
+ skipAuth: true
150
+ });
151
+ }
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['X-API-Key'] = 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
+ if (res.statusCode && res.statusCode >= 400) {
181
+ let errorMessage = `HTTP ${res.statusCode}`;
182
+ try {
183
+ const errorBody = JSON.parse(buffer.toString());
184
+ errorMessage = errorBody.error || errorMessage;
185
+ }
186
+ catch {
187
+ errorMessage = buffer.toString() || errorMessage;
188
+ }
189
+ reject(new Error(errorMessage));
190
+ return;
191
+ }
192
+ if (options.binary) {
193
+ resolve(buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength));
194
+ }
195
+ else {
196
+ try {
197
+ const data = JSON.parse(buffer.toString());
198
+ resolve(data);
199
+ }
200
+ catch (err) {
201
+ reject(new Error('Failed to parse response JSON'));
202
+ }
203
+ }
204
+ });
205
+ });
206
+ req.on('error', (err) => {
207
+ reject(err);
208
+ });
209
+ if (options.body) {
210
+ if (options.body instanceof form_data_1.default) {
211
+ options.body.pipe(req);
212
+ }
213
+ else {
214
+ req.write(options.body);
215
+ req.end();
216
+ }
217
+ }
218
+ else {
219
+ req.end();
220
+ }
221
+ });
222
+ }
223
+ }
224
+ exports.GammaFilesClient = GammaFilesClient;
@@ -0,0 +1,2 @@
1
+ export { GammaFilesClient } from './client';
2
+ export * from './types';
package/dist/index.js ADDED
@@ -0,0 +1,20 @@
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
+ exports.GammaFilesClient = void 0;
18
+ var client_1 = require("./client");
19
+ Object.defineProperty(exports, "GammaFilesClient", { enumerable: true, get: function () { return client_1.GammaFilesClient; } });
20
+ __exportStar(require("./types"), exports);
@@ -0,0 +1,55 @@
1
+ export interface GammaFilesClientConfig {
2
+ baseUrl: string;
3
+ apiKey: string;
4
+ }
5
+ export interface FileMetadata {
6
+ id: string;
7
+ name: string;
8
+ originalName: string;
9
+ mimeType: string;
10
+ size: number;
11
+ folderId: string;
12
+ uploadedBy: string;
13
+ createdAt: string;
14
+ }
15
+ export interface UploadFileOptions {
16
+ file: Buffer | Blob | File;
17
+ filename: string;
18
+ mimeType?: string;
19
+ folderId?: string;
20
+ }
21
+ export interface UploadFileResponse {
22
+ success: true;
23
+ file: FileMetadata;
24
+ }
25
+ export interface ListFilesResponse {
26
+ success: true;
27
+ files: FileMetadata[];
28
+ }
29
+ export interface FileMetadataResponse {
30
+ success: true;
31
+ file: FileMetadata;
32
+ }
33
+ export interface DeleteFileResponse {
34
+ success: true;
35
+ message: string;
36
+ }
37
+ export interface PresignedUrlOptions {
38
+ fileId: string;
39
+ expiresIn?: number;
40
+ }
41
+ export interface PresignedUrlResponse {
42
+ success: true;
43
+ token: string;
44
+ url: string;
45
+ expiresAt: string;
46
+ }
47
+ export interface DownloadFileResult {
48
+ file: FileMetadata;
49
+ data: ArrayBuffer;
50
+ }
51
+ export interface ApiErrorResponse {
52
+ success: false;
53
+ error: string;
54
+ details?: any;
55
+ }
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@oasis-path/gamma-sdk",
3
+ "version": "1.0.0",
4
+ "description": "TypeScript SDK for Gamma Files API",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "keywords": [
8
+ "gamma",
9
+ "files",
10
+ "sdk",
11
+ "api-client",
12
+ "file-management",
13
+ "typescript"
14
+ ],
15
+ "author": "",
16
+ "license": "MIT",
17
+ "devDependencies": {
18
+ "@types/node": "^20.0.0",
19
+ "typescript": "^5.0.0"
20
+ },
21
+ "dependencies": {
22
+ "form-data": "^4.0.0"
23
+ },
24
+ "files": [
25
+ "dist"
26
+ ],
27
+ "scripts": {
28
+ "build": "tsc",
29
+ "watch": "tsc --watch"
30
+ }
31
+ }