@wowsql/sdk 3.6.0 → 3.8.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/dist/storage.d.ts CHANGED
@@ -1,395 +1,211 @@
1
1
  /**
2
- * WowSQL Storage SDK - S3 Storage management with automatic quota validation
2
+ * WowSQL Storage SDK - PostgreSQL-native file storage
3
3
  *
4
- * @version 2.1.0
4
+ * Files are stored as BYTEA inside each project's `storage` schema.
5
+ * No external S3 dependency — everything lives in PostgreSQL.
6
+ *
7
+ * @version 3.0.0
5
8
  * @license MIT
6
9
  */
10
+ import { StorageError, StorageLimitExceededError } from './errors';
7
11
  export interface StorageConfig {
8
- /** Project slug (e.g., 'myproject') */
9
- projectSlug: string;
12
+ /** Project subdomain or full URL (e.g., 'myproject' or 'https://myproject.wowsql.com') */
13
+ projectUrl: string;
10
14
  /** API key for authentication */
11
15
  apiKey: string;
12
- /** API base URL (default: https://api.wowsql.com) */
16
+ /** Project slug override (extracted from projectUrl if not provided) */
17
+ projectSlug?: string;
18
+ /** Full base URL override (e.g., 'https://custom.host/api/v1/storage') */
13
19
  baseUrl?: string;
20
+ /** Base domain (default: wowsql.com) */
21
+ baseDomain?: string;
22
+ /** Use HTTPS (default: true) */
23
+ secure?: boolean;
14
24
  /** Request timeout in milliseconds (default: 60000 for file uploads) */
15
25
  timeout?: number;
16
- /** Automatically check quota before uploads (default: true) */
17
- autoCheckQuota?: boolean;
26
+ /** Verify SSL certificates (default: true). Set to false for self-signed certs in dev. */
27
+ verifySsl?: boolean;
18
28
  }
19
- export interface StorageQuota {
20
- /** Storage quota in GB based on plan */
21
- storage_quota_gb: number;
22
- /** Current storage used in GB */
23
- storage_used_gb: number;
24
- /** Additional storage expansion in GB */
25
- storage_expansion_gb: number;
26
- /** Available storage in GB */
27
- storage_available_gb: number;
28
- /** Usage percentage (0-100) */
29
- usage_percentage: number;
30
- /** Whether storage can be expanded (Enterprise only) */
31
- can_expand_storage: boolean;
32
- /** Whether user is on Enterprise plan */
33
- is_enterprise: boolean;
34
- /** Plan name (e.g., 'Free', 'Pro', 'Business', 'Enterprise') */
35
- plan_name: string;
29
+ export interface StorageBucket {
30
+ id: string;
31
+ name: string;
32
+ public: boolean;
33
+ file_size_limit: number | null;
34
+ allowed_mime_types: string[] | null;
35
+ created_at: string;
36
+ object_count: number;
37
+ total_size: number;
36
38
  }
37
39
  export interface StorageFile {
38
- /** File key/path in bucket */
39
- key: string;
40
- /** File size in bytes */
40
+ id: string;
41
+ bucket_id: string;
42
+ name: string;
43
+ path: string;
44
+ mime_type: string | null;
41
45
  size: number;
42
- /** Last modified timestamp */
43
- last_modified: string;
44
- /** ETag identifier */
45
- etag: string;
46
- /** Storage class (e.g., 'STANDARD') */
47
- storage_class: string;
48
- /** Presigned file URL (if requested) */
49
- file_url?: string;
50
- /** Public URL structure */
46
+ metadata: Record<string, any>;
47
+ created_at: string;
51
48
  public_url?: string;
49
+ /** Size in megabytes */
50
+ get sizeMb(): number;
51
+ /** Size in gigabytes */
52
+ get sizeGb(): number;
52
53
  }
53
- export interface FileUploadResult {
54
- /** Upload success status */
55
- success: boolean;
56
- /** File key in bucket */
57
- file_key: string;
58
- /** File size in bytes */
59
- file_size: number;
60
- /** Bucket name */
61
- bucket_name: string;
62
- /** Optional presigned URL */
63
- url?: string;
64
- /** Success message */
65
- message: string;
66
- }
67
- export interface FileUrlResult {
68
- /** File key */
69
- file_key: string;
70
- /** Presigned download URL */
71
- file_url: string;
72
- /** Public URL structure */
73
- public_url: string;
74
- /** URL expiration timestamp */
75
- expires_at: string;
76
- /** Bucket name */
77
- bucket_name: string;
78
- /** AWS region */
79
- region: string;
80
- /** File size in bytes (if available) */
81
- size?: number;
82
- }
83
- export interface StorageInfo {
84
- /** Storage ID */
85
- s3_storage_id: number;
86
- /** S3 bucket name */
87
- bucket_name: string;
88
- /** AWS region */
89
- region: string;
90
- /** Storage status ('active', 'disabled', etc.) */
91
- status: string;
92
- /** Total number of objects */
93
- total_objects: number;
94
- /** Total size in bytes */
54
+ export interface StorageQuota {
55
+ total_files: number;
95
56
  total_size_bytes: number;
96
- /** Total size in GB */
97
57
  total_size_gb: number;
98
- /** Provisioning timestamp */
99
- provisioned_at?: string;
100
- /** Creation timestamp */
101
- created_at: string;
102
- }
103
- export interface ProvisionResult {
104
- /** Success status */
105
- success: boolean;
106
- /** Storage ID */
107
- s3_storage_id: number;
108
- /** Bucket name */
109
- bucket_name: string;
110
- /** Bucket ARN */
111
- bucket_arn: string;
112
- /** AWS region */
113
- region: string;
114
- /** IAM user name */
115
- iam_user_name: string;
116
- /** Access credentials (SAVE THESE - shown only once!) */
117
- credentials: {
118
- access_key_id: string;
119
- secret_access_key: string;
120
- };
121
- /** Provisioning timestamp */
122
- provisioned_at: string;
123
- /** Success message */
124
- message: string;
125
- }
126
- export interface S3Region {
127
- /** Region code (e.g., 'us-east-1') */
128
- code: string;
129
- /** Region name (e.g., 'US East N. Virginia') */
130
- name: string;
131
- /** Storage price per GB/month */
132
- storage_price_gb: number;
133
- /** Data transfer price per GB */
134
- transfer_price_gb: number;
135
- /** Latency tier */
136
- latency_tier: string;
137
- /** Recommended region flag */
138
- recommended: boolean;
58
+ file_types: Record<string, number>;
139
59
  }
140
- export declare class StorageError extends Error {
141
- statusCode?: number | undefined;
142
- response?: any | undefined;
143
- constructor(message: string, statusCode?: number | undefined, response?: any | undefined);
144
- }
145
- export declare class StorageLimitExceededError extends StorageError {
146
- constructor(message: string, statusCode?: number, response?: any);
60
+ export interface StorageStats {
61
+ total_files: number;
62
+ total_size_bytes: number;
63
+ total_size_gb: number;
64
+ bandwidth_used_bytes: number;
65
+ file_types: Record<string, number>;
147
66
  }
67
+ export { StorageError, StorageLimitExceededError };
148
68
  /**
149
- * WowSQL Storage Client - Manage S3 storage with automatic quota validation
69
+ * WowSQL Storage Client — PostgreSQL-native file storage.
150
70
  *
151
- * Features:
152
- * - Automatic storage limit validation before upload
153
- * - Real-time quota checking
154
- * - File upload/download/delete operations
155
- * - Presigned URL generation
156
- * - Storage provisioning and management
71
+ * All files are stored directly in the project's PostgreSQL database
72
+ * inside the `storage` schema (buckets + objects as BYTEA).
157
73
  *
158
74
  * @example
159
75
  * ```typescript
160
76
  * const storage = new WowSQLStorage({
161
- * projectSlug: 'myproject',
162
- * apiKey: 'your_api_key'
77
+ * projectUrl: 'myproject',
78
+ * apiKey: 'wowsql_anon_...'
163
79
  * });
164
80
  *
165
- * // Check quota
166
- * const quota = await storage.getQuota();
167
- * console.log(`Available: ${quota.storage_available_gb.toFixed(2)} GB`);
81
+ * // Create a bucket
82
+ * const bucket = await storage.createBucket('avatars', { public: true });
168
83
  *
169
- * // Upload file (auto-validates limits)
170
- * const fileBuffer = fs.readFileSync('document.pdf');
171
- * const result = await storage.uploadFile(fileBuffer, 'document.pdf', {
172
- * folder: 'documents'
173
- * });
84
+ * // Upload a file
85
+ * const file = document.querySelector('input[type="file"]').files[0];
86
+ * const result = await storage.upload('avatars', file, 'users/profile.jpg');
174
87
  *
175
88
  * // List files
176
- * const files = await storage.listFiles({ prefix: 'documents/' });
89
+ * const files = await storage.listFiles('avatars', { prefix: 'users/' });
90
+ *
91
+ * // Get public URL
92
+ * const url = storage.getPublicUrl('avatars', 'users/profile.jpg');
177
93
  * ```
178
94
  */
179
95
  export declare class WowSQLStorage {
180
96
  private client;
97
+ private baseUrl;
181
98
  private projectSlug;
182
- private autoCheckQuota;
183
- private quotaCache?;
184
99
  constructor(config: StorageConfig);
185
100
  /**
186
- * Get storage quota and usage information
187
- *
188
- * @param forceRefresh - Force refresh quota from server (default: false)
189
- * @returns Storage quota details
101
+ * Create a new storage bucket.
190
102
  *
191
- * @example
192
- * ```typescript
193
- * const quota = await storage.getQuota();
194
- * console.log(`Used: ${quota.storage_used_gb} GB`);
195
- * console.log(`Available: ${quota.storage_available_gb} GB`);
196
- * console.log(`Usage: ${quota.usage_percentage}%`);
197
- * ```
103
+ * @param name - Bucket name (unique per project)
104
+ * @param options - Bucket configuration
198
105
  */
199
- getQuota(forceRefresh?: boolean): Promise<StorageQuota>;
106
+ createBucket(name: string, options?: {
107
+ public?: boolean;
108
+ fileSizeLimit?: number;
109
+ allowedMimeTypes?: string[];
110
+ }): Promise<StorageBucket>;
200
111
  /**
201
- * Check if file upload is allowed based on storage quota
202
- *
203
- * @param fileSizeBytes - Size of file to upload in bytes
204
- * @returns Object with allowed status and message
205
- *
206
- * @example
207
- * ```typescript
208
- * const fileSize = 1024 * 1024 * 500; // 500 MB
209
- * const check = await storage.checkUploadAllowed(fileSize);
210
- * if (!check.allowed) {
211
- * console.error(check.message);
212
- * }
213
- * ```
112
+ * List all buckets in the project.
113
+ */
114
+ listBuckets(): Promise<StorageBucket[]>;
115
+ /**
116
+ * Get a specific bucket by name.
214
117
  */
215
- checkUploadAllowed(fileSizeBytes: number): Promise<{
216
- allowed: boolean;
118
+ getBucket(name: string): Promise<StorageBucket>;
119
+ /**
120
+ * Update bucket settings.
121
+ */
122
+ updateBucket(name: string, updates: {
123
+ name?: string;
124
+ public?: boolean;
125
+ fileSizeLimit?: number | null;
126
+ allowedMimeTypes?: string[] | null;
127
+ }): Promise<StorageBucket>;
128
+ /**
129
+ * Delete a bucket and all its files.
130
+ */
131
+ deleteBucket(name: string): Promise<{
132
+ success: boolean;
217
133
  message: string;
218
134
  }>;
219
135
  /**
220
- * Upload a file to S3 storage with automatic quota validation
221
- *
222
- * @param fileData - File data as Buffer or Blob
223
- * @param fileName - File name
224
- * @param options - Upload options
225
- * @returns Upload result
226
- *
227
- * @throws {StorageLimitExceededError} If storage quota would be exceeded
228
- * @throws {StorageError} If upload fails
136
+ * Upload a file to a bucket.
229
137
  *
230
- * @example
231
- * ```typescript
232
- * // Node.js - from file
233
- * const fileBuffer = fs.readFileSync('photo.jpg');
234
- * const result = await storage.uploadFile(fileBuffer, 'photo.jpg', {
235
- * folder: 'images',
236
- * contentType: 'image/jpeg'
237
- * });
238
- *
239
- * // Browser - from File input
240
- * const file = document.querySelector('input[type="file"]').files[0];
241
- * const arrayBuffer = await file.arrayBuffer();
242
- * const result = await storage.uploadFile(
243
- * Buffer.from(arrayBuffer),
244
- * file.name,
245
- * { folder: 'uploads' }
246
- * );
247
- * ```
138
+ * @param bucketName - Target bucket
139
+ * @param fileData - File data (File, Blob, or Buffer)
140
+ * @param path - Optional path within the bucket (e.g., 'users/avatar.png')
141
+ * @param fileName - Optional file name override
248
142
  */
249
- uploadFile(fileData: Buffer | Blob, fileName: string, options?: {
250
- folder?: string;
251
- contentType?: string;
252
- checkQuota?: boolean;
253
- }): Promise<FileUploadResult>;
143
+ upload(bucketName: string, fileData: File | Blob | Buffer, path?: string, fileName?: string): Promise<StorageFile>;
254
144
  /**
255
- * Upload a file from filesystem path (Node.js only)
256
- *
257
- * @param filePath - Path to local file
258
- * @param fileName - Optional file name in bucket (defaults to filename)
259
- * @param options - Upload options
260
- * @returns Upload result
145
+ * Upload a file (compatibility alias for upload).
261
146
  *
262
- * @example
263
- * ```typescript
264
- * const result = await storage.uploadFromPath(
265
- * 'documents/report.pdf',
266
- * 'report.pdf',
267
- * { folder: 'reports' }
268
- * );
269
- * ```
147
+ * @param bucketName - Target bucket
148
+ * @param fileData - File data (File, Blob, or Buffer)
149
+ * @param path - Optional path within the bucket
150
+ * @param fileName - Optional file name override
270
151
  */
271
- uploadFromPath(filePath: string, fileName?: string, options?: {
272
- folder?: string;
273
- contentType?: string;
274
- checkQuota?: boolean;
275
- }): Promise<FileUploadResult>;
152
+ uploadFile(bucketName: string, fileData: File | Blob | Buffer, path?: string, fileName?: string): Promise<StorageFile>;
276
153
  /**
277
- * List files in S3 bucket
154
+ * Upload a file from a local file path (Node.js only).
278
155
  *
279
- * @param options - List options
280
- * @returns Array of storage files
156
+ * @param filePath - Local file path to upload
157
+ * @param bucketName - Target bucket (defaults to 'default')
158
+ * @param path - Optional path within the bucket
159
+ */
160
+ uploadFromPath(filePath: string, bucketName?: string, path?: string): Promise<StorageFile>;
161
+ /**
162
+ * List files in a bucket.
281
163
  *
282
- * @example
283
- * ```typescript
284
- * const files = await storage.listFiles({ prefix: 'documents/' });
285
- * for (const file of files) {
286
- * console.log(`${file.key}: ${(file.size / 1024 / 1024).toFixed(2)} MB`);
287
- * }
288
- * ```
164
+ * @param bucketName - Bucket to list
165
+ * @param options - Filter and pagination options
289
166
  */
290
- listFiles(options?: {
167
+ listFiles(bucketName: string, options?: {
291
168
  prefix?: string;
292
- maxKeys?: number;
169
+ limit?: number;
170
+ offset?: number;
293
171
  }): Promise<StorageFile[]>;
294
172
  /**
295
- * Delete a file from S3 bucket
296
- *
297
- * @param fileKey - Path to file in bucket
298
- * @returns Deletion result
173
+ * Download a file. Returns binary data as ArrayBuffer.
299
174
  *
300
- * @example
301
- * ```typescript
302
- * const result = await storage.deleteFile('documents/old-file.pdf');
303
- * console.log(result.message);
304
- * ```
175
+ * @param bucketName - Bucket name
176
+ * @param filePath - Path to file within the bucket
305
177
  */
306
- deleteFile(fileKey: string): Promise<{
307
- success: boolean;
308
- message: string;
309
- file_key: string;
310
- }>;
178
+ download(bucketName: string, filePath: string): Promise<ArrayBuffer>;
311
179
  /**
312
- * Get presigned URL for file access
313
- *
314
- * @param fileKey - Path to file in bucket
315
- * @param expiresIn - URL validity in seconds (default: 3600 = 1 hour)
316
- * @returns File URL and metadata
180
+ * Download a file and save to a local path (Node.js only).
317
181
  *
318
- * @example
319
- * ```typescript
320
- * const urlData = await storage.getFileUrl('photo.jpg', 7200);
321
- * console.log(urlData.file_url); // Use this for downloads
322
- * ```
182
+ * @param bucketName - Bucket name
183
+ * @param filePath - Path to file within the bucket
184
+ * @param localPath - Local file path to save to
323
185
  */
324
- getFileUrl(fileKey: string, expiresIn?: number): Promise<FileUrlResult>;
186
+ downloadToFile(bucketName: string, filePath: string, localPath: string): Promise<void>;
325
187
  /**
326
- * Generate presigned URL for file operations
188
+ * Delete a file from a bucket.
327
189
  *
328
- * @param fileKey - Path to file in bucket
329
- * @param options - Presigned URL options
330
- * @returns Presigned URL string
331
- *
332
- * @example
333
- * ```typescript
334
- * // Download URL
335
- * const downloadUrl = await storage.getPresignedUrl('file.pdf');
336
- *
337
- * // Upload URL
338
- * const uploadUrl = await storage.getPresignedUrl('new-file.pdf', {
339
- * operation: 'put_object',
340
- * expiresIn: 1800
341
- * });
342
- * ```
190
+ * @param bucketName - Bucket name
191
+ * @param filePath - Path to file within the bucket
343
192
  */
344
- getPresignedUrl(fileKey: string, options?: {
345
- expiresIn?: number;
346
- operation?: 'get_object' | 'put_object';
347
- }): Promise<string>;
193
+ deleteFile(bucketName: string, filePath: string): Promise<{
194
+ success: boolean;
195
+ message: string;
196
+ }>;
348
197
  /**
349
- * Get S3 storage information for the project
350
- *
351
- * @returns Storage information
352
- *
353
- * @example
354
- * ```typescript
355
- * const info = await storage.getStorageInfo();
356
- * console.log(`Bucket: ${info.bucket_name}`);
357
- * console.log(`Region: ${info.region}`);
358
- * console.log(`Objects: ${info.total_objects}`);
359
- * console.log(`Size: ${info.total_size_gb.toFixed(2)} GB`);
360
- * ```
198
+ * Get the public URL for a file in a public bucket.
199
+ * This URL works without authentication.
361
200
  */
362
- getStorageInfo(): Promise<StorageInfo>;
201
+ getPublicUrl(bucketName: string, filePath: string): string;
363
202
  /**
364
- * Provision S3 storage for the project
365
- *
366
- * **IMPORTANT**: Save the credentials returned! They're only shown once.
367
- *
368
- * @param region - AWS region (default: 'us-east-1')
369
- * @returns Provisioning result with credentials
370
- *
371
- * @example
372
- * ```typescript
373
- * const result = await storage.provisionStorage('us-west-2');
374
- * console.log(`Bucket: ${result.bucket_name}`);
375
- * console.log(`Access Key: ${result.credentials.access_key_id}`);
376
- * // SAVE THESE CREDENTIALS SECURELY!
377
- * ```
203
+ * Get storage statistics for the project.
378
204
  */
379
- provisionStorage(region?: string): Promise<ProvisionResult>;
205
+ getStats(): Promise<StorageStats>;
380
206
  /**
381
- * Get list of available S3 regions with pricing
382
- *
383
- * @returns Array of available regions
384
- *
385
- * @example
386
- * ```typescript
387
- * const regions = await storage.getAvailableRegions();
388
- * for (const region of regions) {
389
- * console.log(`${region.name}: $${region.storage_price_gb}/GB/month`);
390
- * }
391
- * ```
207
+ * Get storage quota for the project.
392
208
  */
393
- getAvailableRegions(): Promise<S3Region[]>;
209
+ getQuota(): Promise<StorageQuota>;
394
210
  }
395
211
  export default WowSQLStorage;