@insforge/sdk 0.0.6 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { UserSchema, CreateUserRequest, CreateUserResponse, CreateSessionRequest, CreateSessionResponse, GetCurrentSessionResponse } from '@insforge/shared-schemas';
1
+ import { UserSchema, CreateUserRequest, CreateUserResponse, CreateSessionRequest, CreateSessionResponse, GetCurrentSessionResponse, StorageFileSchema, ListObjectsResponseSchema } from '@insforge/shared-schemas';
2
2
  export { AuthErrorResponse, CreateSessionRequest, CreateUserRequest, UserSchema } from '@insforge/shared-schemas';
3
3
 
4
4
  /**
@@ -68,8 +68,8 @@ interface RequestOptions extends RequestInit {
68
68
  params?: Record<string, string>;
69
69
  }
70
70
  declare class HttpClient {
71
- private baseUrl;
72
- private fetch;
71
+ readonly baseUrl: string;
72
+ readonly fetch: typeof fetch;
73
73
  private defaultHeaders;
74
74
  constructor(config: InsForgeConfig);
75
75
  private buildUrl;
@@ -80,6 +80,7 @@ declare class HttpClient {
80
80
  patch<T>(path: string, body?: any, options?: RequestOptions): Promise<T>;
81
81
  delete<T>(path: string, options?: RequestOptions): Promise<T>;
82
82
  setAuthToken(token: string | null): void;
83
+ getHeaders(): Record<string, string>;
83
84
  }
84
85
 
85
86
  declare class TokenManager {
@@ -177,11 +178,12 @@ declare class QueryBuilder<T = any> {
177
178
  constructor(table: string, http: HttpClient);
178
179
  /**
179
180
  * Perform a SELECT query
181
+ * For mutations (insert/update/delete), this enables returning data
180
182
  * @param columns - Columns to select (default: '*')
181
183
  * @example
182
184
  * .select('*')
183
185
  * .select('id, title, content')
184
- * .select('*, user:user_id(name, email)') // Foreign key expansion
186
+ * .insert({ title: 'New' }).select() // Returns inserted data
185
187
  */
186
188
  select(columns?: string): this;
187
189
  /**
@@ -189,8 +191,8 @@ declare class QueryBuilder<T = any> {
189
191
  * @param values - Single object or array of objects
190
192
  * @param options - { upsert: true } for upsert behavior
191
193
  * @example
192
- * .insert({ title: 'Hello', content: 'World' })
193
- * .insert([{ title: 'Post 1' }, { title: 'Post 2' }])
194
+ * .insert({ title: 'Hello', content: 'World' }).select()
195
+ * .insert([{ title: 'Post 1' }, { title: 'Post 2' }]).select()
194
196
  */
195
197
  insert(values: Partial<T> | Partial<T>[], options?: {
196
198
  upsert?: boolean;
@@ -199,13 +201,13 @@ declare class QueryBuilder<T = any> {
199
201
  * Perform an UPDATE
200
202
  * @param values - Object with fields to update
201
203
  * @example
202
- * .update({ title: 'Updated Title' })
204
+ * .update({ title: 'Updated Title' }).select()
203
205
  */
204
206
  update(values: Partial<T>): this;
205
207
  /**
206
208
  * Perform a DELETE
207
209
  * @example
208
- * .delete()
210
+ * .delete().select()
209
211
  */
210
212
  delete(): this;
211
213
  /**
@@ -329,6 +331,81 @@ declare class Database {
329
331
  from<T = any>(table: string): QueryBuilder<T>;
330
332
  }
331
333
 
334
+ /**
335
+ * Storage module for InsForge SDK
336
+ * Handles file uploads, downloads, and bucket management
337
+ */
338
+
339
+ interface StorageResponse<T> {
340
+ data: T | null;
341
+ error: InsForgeError | null;
342
+ }
343
+ /**
344
+ * Storage bucket operations
345
+ */
346
+ declare class StorageBucket {
347
+ private bucketName;
348
+ private http;
349
+ constructor(bucketName: string, http: HttpClient);
350
+ /**
351
+ * Upload a file with a specific key
352
+ * @param path - The object key/path
353
+ * @param file - File, Blob, or FormData to upload
354
+ */
355
+ upload(path: string, file: File | Blob | FormData): Promise<StorageResponse<StorageFileSchema>>;
356
+ /**
357
+ * Upload a file with auto-generated key
358
+ * @param file - File, Blob, or FormData to upload
359
+ */
360
+ uploadAuto(file: File | Blob | FormData): Promise<StorageResponse<StorageFileSchema>>;
361
+ /**
362
+ * Download a file
363
+ * @param path - The object key/path
364
+ * Returns the file as a Blob
365
+ */
366
+ download(path: string): Promise<{
367
+ data: Blob | null;
368
+ error: InsForgeError | null;
369
+ }>;
370
+ /**
371
+ * Get public URL for a file
372
+ * @param path - The object key/path
373
+ */
374
+ getPublicUrl(path: string): string;
375
+ /**
376
+ * List objects in the bucket
377
+ * @param prefix - Filter by key prefix
378
+ * @param search - Search in file names
379
+ * @param limit - Maximum number of results (default: 100, max: 1000)
380
+ * @param offset - Number of results to skip
381
+ */
382
+ list(options?: {
383
+ prefix?: string;
384
+ search?: string;
385
+ limit?: number;
386
+ offset?: number;
387
+ }): Promise<StorageResponse<ListObjectsResponseSchema>>;
388
+ /**
389
+ * Delete a file
390
+ * @param path - The object key/path
391
+ */
392
+ remove(path: string): Promise<StorageResponse<{
393
+ message: string;
394
+ }>>;
395
+ }
396
+ /**
397
+ * Storage module for file operations
398
+ */
399
+ declare class Storage {
400
+ private http;
401
+ constructor(http: HttpClient);
402
+ /**
403
+ * Get a bucket instance for operations
404
+ * @param bucketName - Name of the bucket
405
+ */
406
+ from(bucketName: string): StorageBucket;
407
+ }
408
+
332
409
  /**
333
410
  * Main InsForge SDK Client
334
411
  *
@@ -367,6 +444,7 @@ declare class InsForgeClient {
367
444
  private tokenManager;
368
445
  readonly auth: Auth;
369
446
  readonly database: Database;
447
+ readonly storage: Storage;
370
448
  constructor(config?: InsForgeConfig);
371
449
  /**
372
450
  * Set a custom API key for authentication
@@ -400,4 +478,4 @@ declare class InsForgeClient {
400
478
 
401
479
  declare function createClient(config: InsForgeConfig): InsForgeClient;
402
480
 
403
- export { type ApiError, Auth, type AuthSession, type InsForgeConfig as ClientOptions, Database, type DatabaseResponse, HttpClient, InsForgeClient, type InsForgeConfig, InsForgeError, QueryBuilder, TokenManager, type TokenStorage, createClient, InsForgeClient as default };
481
+ export { type ApiError, Auth, type AuthSession, type InsForgeConfig as ClientOptions, Database, type DatabaseResponse, HttpClient, InsForgeClient, type InsForgeConfig, InsForgeError, QueryBuilder, Storage, StorageBucket, type StorageResponse, TokenManager, type TokenStorage, createClient, InsForgeClient as default };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { UserSchema, CreateUserRequest, CreateUserResponse, CreateSessionRequest, CreateSessionResponse, GetCurrentSessionResponse } from '@insforge/shared-schemas';
1
+ import { UserSchema, CreateUserRequest, CreateUserResponse, CreateSessionRequest, CreateSessionResponse, GetCurrentSessionResponse, StorageFileSchema, ListObjectsResponseSchema } from '@insforge/shared-schemas';
2
2
  export { AuthErrorResponse, CreateSessionRequest, CreateUserRequest, UserSchema } from '@insforge/shared-schemas';
3
3
 
4
4
  /**
@@ -68,8 +68,8 @@ interface RequestOptions extends RequestInit {
68
68
  params?: Record<string, string>;
69
69
  }
70
70
  declare class HttpClient {
71
- private baseUrl;
72
- private fetch;
71
+ readonly baseUrl: string;
72
+ readonly fetch: typeof fetch;
73
73
  private defaultHeaders;
74
74
  constructor(config: InsForgeConfig);
75
75
  private buildUrl;
@@ -80,6 +80,7 @@ declare class HttpClient {
80
80
  patch<T>(path: string, body?: any, options?: RequestOptions): Promise<T>;
81
81
  delete<T>(path: string, options?: RequestOptions): Promise<T>;
82
82
  setAuthToken(token: string | null): void;
83
+ getHeaders(): Record<string, string>;
83
84
  }
84
85
 
85
86
  declare class TokenManager {
@@ -177,11 +178,12 @@ declare class QueryBuilder<T = any> {
177
178
  constructor(table: string, http: HttpClient);
178
179
  /**
179
180
  * Perform a SELECT query
181
+ * For mutations (insert/update/delete), this enables returning data
180
182
  * @param columns - Columns to select (default: '*')
181
183
  * @example
182
184
  * .select('*')
183
185
  * .select('id, title, content')
184
- * .select('*, user:user_id(name, email)') // Foreign key expansion
186
+ * .insert({ title: 'New' }).select() // Returns inserted data
185
187
  */
186
188
  select(columns?: string): this;
187
189
  /**
@@ -189,8 +191,8 @@ declare class QueryBuilder<T = any> {
189
191
  * @param values - Single object or array of objects
190
192
  * @param options - { upsert: true } for upsert behavior
191
193
  * @example
192
- * .insert({ title: 'Hello', content: 'World' })
193
- * .insert([{ title: 'Post 1' }, { title: 'Post 2' }])
194
+ * .insert({ title: 'Hello', content: 'World' }).select()
195
+ * .insert([{ title: 'Post 1' }, { title: 'Post 2' }]).select()
194
196
  */
195
197
  insert(values: Partial<T> | Partial<T>[], options?: {
196
198
  upsert?: boolean;
@@ -199,13 +201,13 @@ declare class QueryBuilder<T = any> {
199
201
  * Perform an UPDATE
200
202
  * @param values - Object with fields to update
201
203
  * @example
202
- * .update({ title: 'Updated Title' })
204
+ * .update({ title: 'Updated Title' }).select()
203
205
  */
204
206
  update(values: Partial<T>): this;
205
207
  /**
206
208
  * Perform a DELETE
207
209
  * @example
208
- * .delete()
210
+ * .delete().select()
209
211
  */
210
212
  delete(): this;
211
213
  /**
@@ -329,6 +331,81 @@ declare class Database {
329
331
  from<T = any>(table: string): QueryBuilder<T>;
330
332
  }
331
333
 
334
+ /**
335
+ * Storage module for InsForge SDK
336
+ * Handles file uploads, downloads, and bucket management
337
+ */
338
+
339
+ interface StorageResponse<T> {
340
+ data: T | null;
341
+ error: InsForgeError | null;
342
+ }
343
+ /**
344
+ * Storage bucket operations
345
+ */
346
+ declare class StorageBucket {
347
+ private bucketName;
348
+ private http;
349
+ constructor(bucketName: string, http: HttpClient);
350
+ /**
351
+ * Upload a file with a specific key
352
+ * @param path - The object key/path
353
+ * @param file - File, Blob, or FormData to upload
354
+ */
355
+ upload(path: string, file: File | Blob | FormData): Promise<StorageResponse<StorageFileSchema>>;
356
+ /**
357
+ * Upload a file with auto-generated key
358
+ * @param file - File, Blob, or FormData to upload
359
+ */
360
+ uploadAuto(file: File | Blob | FormData): Promise<StorageResponse<StorageFileSchema>>;
361
+ /**
362
+ * Download a file
363
+ * @param path - The object key/path
364
+ * Returns the file as a Blob
365
+ */
366
+ download(path: string): Promise<{
367
+ data: Blob | null;
368
+ error: InsForgeError | null;
369
+ }>;
370
+ /**
371
+ * Get public URL for a file
372
+ * @param path - The object key/path
373
+ */
374
+ getPublicUrl(path: string): string;
375
+ /**
376
+ * List objects in the bucket
377
+ * @param prefix - Filter by key prefix
378
+ * @param search - Search in file names
379
+ * @param limit - Maximum number of results (default: 100, max: 1000)
380
+ * @param offset - Number of results to skip
381
+ */
382
+ list(options?: {
383
+ prefix?: string;
384
+ search?: string;
385
+ limit?: number;
386
+ offset?: number;
387
+ }): Promise<StorageResponse<ListObjectsResponseSchema>>;
388
+ /**
389
+ * Delete a file
390
+ * @param path - The object key/path
391
+ */
392
+ remove(path: string): Promise<StorageResponse<{
393
+ message: string;
394
+ }>>;
395
+ }
396
+ /**
397
+ * Storage module for file operations
398
+ */
399
+ declare class Storage {
400
+ private http;
401
+ constructor(http: HttpClient);
402
+ /**
403
+ * Get a bucket instance for operations
404
+ * @param bucketName - Name of the bucket
405
+ */
406
+ from(bucketName: string): StorageBucket;
407
+ }
408
+
332
409
  /**
333
410
  * Main InsForge SDK Client
334
411
  *
@@ -367,6 +444,7 @@ declare class InsForgeClient {
367
444
  private tokenManager;
368
445
  readonly auth: Auth;
369
446
  readonly database: Database;
447
+ readonly storage: Storage;
370
448
  constructor(config?: InsForgeConfig);
371
449
  /**
372
450
  * Set a custom API key for authentication
@@ -400,4 +478,4 @@ declare class InsForgeClient {
400
478
 
401
479
  declare function createClient(config: InsForgeConfig): InsForgeClient;
402
480
 
403
- export { type ApiError, Auth, type AuthSession, type InsForgeConfig as ClientOptions, Database, type DatabaseResponse, HttpClient, InsForgeClient, type InsForgeConfig, InsForgeError, QueryBuilder, TokenManager, type TokenStorage, createClient, InsForgeClient as default };
481
+ export { type ApiError, Auth, type AuthSession, type InsForgeConfig as ClientOptions, Database, type DatabaseResponse, HttpClient, InsForgeClient, type InsForgeConfig, InsForgeError, QueryBuilder, Storage, StorageBucket, type StorageResponse, TokenManager, type TokenStorage, createClient, InsForgeClient as default };
package/dist/index.js CHANGED
@@ -26,6 +26,8 @@ __export(index_exports, {
26
26
  InsForgeClient: () => InsForgeClient,
27
27
  InsForgeError: () => InsForgeError,
28
28
  QueryBuilder: () => QueryBuilder,
29
+ Storage: () => Storage,
30
+ StorageBucket: () => StorageBucket,
29
31
  TokenManager: () => TokenManager,
30
32
  createClient: () => createClient,
31
33
  default: () => index_default
@@ -83,14 +85,22 @@ var HttpClient = class {
83
85
  const requestHeaders = {
84
86
  ...this.defaultHeaders
85
87
  };
86
- if (method !== "GET" && body !== void 0) {
87
- requestHeaders["Content-Type"] = "application/json;charset=UTF-8";
88
+ let processedBody;
89
+ if (body !== void 0) {
90
+ if (typeof FormData !== "undefined" && body instanceof FormData) {
91
+ processedBody = body;
92
+ } else {
93
+ if (method !== "GET") {
94
+ requestHeaders["Content-Type"] = "application/json;charset=UTF-8";
95
+ }
96
+ processedBody = JSON.stringify(body);
97
+ }
88
98
  }
89
99
  Object.assign(requestHeaders, headers);
90
100
  const response = await this.fetch(url, {
91
101
  method,
92
102
  headers: requestHeaders,
93
- body: body ? JSON.stringify(body) : void 0,
103
+ body: processedBody,
94
104
  ...fetchOptions
95
105
  });
96
106
  if (response.status === 204) {
@@ -137,6 +147,9 @@ var HttpClient = class {
137
147
  delete this.defaultHeaders["Authorization"];
138
148
  }
139
149
  }
150
+ getHeaders() {
151
+ return { ...this.defaultHeaders };
152
+ }
140
153
  };
141
154
 
142
155
  // src/lib/token-manager.ts
@@ -379,14 +392,22 @@ var QueryBuilder = class {
379
392
  }
380
393
  /**
381
394
  * Perform a SELECT query
395
+ * For mutations (insert/update/delete), this enables returning data
382
396
  * @param columns - Columns to select (default: '*')
383
397
  * @example
384
398
  * .select('*')
385
399
  * .select('id, title, content')
386
- * .select('*, user:user_id(name, email)') // Foreign key expansion
400
+ * .insert({ title: 'New' }).select() // Returns inserted data
387
401
  */
388
402
  select(columns = "*") {
389
- this.method = "GET";
403
+ if (this.method !== "GET") {
404
+ const existingPrefer = this.headers["Prefer"] || "";
405
+ const preferParts = existingPrefer ? [existingPrefer] : [];
406
+ if (!preferParts.some((p) => p.includes("return="))) {
407
+ preferParts.push("return=representation");
408
+ }
409
+ this.headers["Prefer"] = preferParts.join(",");
410
+ }
390
411
  if (columns !== "*") {
391
412
  this.queryParams.select = columns;
392
413
  }
@@ -397,16 +418,14 @@ var QueryBuilder = class {
397
418
  * @param values - Single object or array of objects
398
419
  * @param options - { upsert: true } for upsert behavior
399
420
  * @example
400
- * .insert({ title: 'Hello', content: 'World' })
401
- * .insert([{ title: 'Post 1' }, { title: 'Post 2' }])
421
+ * .insert({ title: 'Hello', content: 'World' }).select()
422
+ * .insert([{ title: 'Post 1' }, { title: 'Post 2' }]).select()
402
423
  */
403
424
  insert(values, options) {
404
425
  this.method = "POST";
405
426
  this.body = Array.isArray(values) ? values : [values];
406
427
  if (options?.upsert) {
407
- this.headers["Prefer"] = "resolution=merge-duplicates,return=representation";
408
- } else {
409
- this.headers["Prefer"] = "return=representation";
428
+ this.headers["Prefer"] = "resolution=merge-duplicates";
410
429
  }
411
430
  return this;
412
431
  }
@@ -414,22 +433,20 @@ var QueryBuilder = class {
414
433
  * Perform an UPDATE
415
434
  * @param values - Object with fields to update
416
435
  * @example
417
- * .update({ title: 'Updated Title' })
436
+ * .update({ title: 'Updated Title' }).select()
418
437
  */
419
438
  update(values) {
420
439
  this.method = "PATCH";
421
440
  this.body = values;
422
- this.headers["Prefer"] = "return=representation";
423
441
  return this;
424
442
  }
425
443
  /**
426
444
  * Perform a DELETE
427
445
  * @example
428
- * .delete()
446
+ * .delete().select()
429
447
  */
430
448
  delete() {
431
449
  this.method = "DELETE";
432
- this.headers["Prefer"] = "return=representation";
433
450
  return this;
434
451
  }
435
452
  /**
@@ -651,6 +668,186 @@ var Database = class {
651
668
  }
652
669
  };
653
670
 
671
+ // src/modules/storage.ts
672
+ var StorageBucket = class {
673
+ constructor(bucketName, http) {
674
+ this.bucketName = bucketName;
675
+ this.http = http;
676
+ }
677
+ /**
678
+ * Upload a file with a specific key
679
+ * @param path - The object key/path
680
+ * @param file - File, Blob, or FormData to upload
681
+ */
682
+ async upload(path, file) {
683
+ try {
684
+ const formData = file instanceof FormData ? file : new FormData();
685
+ if (!(file instanceof FormData)) {
686
+ formData.append("file", file);
687
+ }
688
+ const response = await this.http.request(
689
+ "PUT",
690
+ `/api/storage/buckets/${this.bucketName}/objects/${encodeURIComponent(path)}`,
691
+ {
692
+ body: formData,
693
+ headers: {
694
+ // Don't set Content-Type, let browser set multipart boundary
695
+ }
696
+ }
697
+ );
698
+ return { data: response, error: null };
699
+ } catch (error) {
700
+ return {
701
+ data: null,
702
+ error: error instanceof InsForgeError ? error : new InsForgeError(
703
+ "Upload failed",
704
+ 500,
705
+ "STORAGE_ERROR"
706
+ )
707
+ };
708
+ }
709
+ }
710
+ /**
711
+ * Upload a file with auto-generated key
712
+ * @param file - File, Blob, or FormData to upload
713
+ */
714
+ async uploadAuto(file) {
715
+ try {
716
+ const formData = file instanceof FormData ? file : new FormData();
717
+ if (!(file instanceof FormData)) {
718
+ formData.append("file", file);
719
+ }
720
+ const response = await this.http.request(
721
+ "POST",
722
+ `/api/storage/buckets/${this.bucketName}/objects`,
723
+ {
724
+ body: formData,
725
+ headers: {
726
+ // Don't set Content-Type, let browser set multipart boundary
727
+ }
728
+ }
729
+ );
730
+ return { data: response, error: null };
731
+ } catch (error) {
732
+ return {
733
+ data: null,
734
+ error: error instanceof InsForgeError ? error : new InsForgeError(
735
+ "Upload failed",
736
+ 500,
737
+ "STORAGE_ERROR"
738
+ )
739
+ };
740
+ }
741
+ }
742
+ /**
743
+ * Download a file
744
+ * @param path - The object key/path
745
+ * Returns the file as a Blob
746
+ */
747
+ async download(path) {
748
+ try {
749
+ const url = `${this.http.baseUrl}/api/storage/buckets/${this.bucketName}/objects/${encodeURIComponent(path)}`;
750
+ const response = await this.http.fetch(url, {
751
+ method: "GET",
752
+ headers: this.http.getHeaders()
753
+ });
754
+ if (!response.ok) {
755
+ try {
756
+ const error = await response.json();
757
+ throw InsForgeError.fromApiError(error);
758
+ } catch {
759
+ throw new InsForgeError(
760
+ `Download failed: ${response.statusText}`,
761
+ response.status,
762
+ "STORAGE_ERROR"
763
+ );
764
+ }
765
+ }
766
+ const blob = await response.blob();
767
+ return { data: blob, error: null };
768
+ } catch (error) {
769
+ return {
770
+ data: null,
771
+ error: error instanceof InsForgeError ? error : new InsForgeError(
772
+ "Download failed",
773
+ 500,
774
+ "STORAGE_ERROR"
775
+ )
776
+ };
777
+ }
778
+ }
779
+ /**
780
+ * Get public URL for a file
781
+ * @param path - The object key/path
782
+ */
783
+ getPublicUrl(path) {
784
+ return `${this.http.baseUrl}/api/storage/buckets/${this.bucketName}/objects/${encodeURIComponent(path)}`;
785
+ }
786
+ /**
787
+ * List objects in the bucket
788
+ * @param prefix - Filter by key prefix
789
+ * @param search - Search in file names
790
+ * @param limit - Maximum number of results (default: 100, max: 1000)
791
+ * @param offset - Number of results to skip
792
+ */
793
+ async list(options) {
794
+ try {
795
+ const params = {};
796
+ if (options?.prefix) params.prefix = options.prefix;
797
+ if (options?.search) params.search = options.search;
798
+ if (options?.limit) params.limit = options.limit.toString();
799
+ if (options?.offset) params.offset = options.offset.toString();
800
+ const response = await this.http.get(
801
+ `/api/storage/buckets/${this.bucketName}/objects`,
802
+ { params }
803
+ );
804
+ return { data: response, error: null };
805
+ } catch (error) {
806
+ return {
807
+ data: null,
808
+ error: error instanceof InsForgeError ? error : new InsForgeError(
809
+ "List failed",
810
+ 500,
811
+ "STORAGE_ERROR"
812
+ )
813
+ };
814
+ }
815
+ }
816
+ /**
817
+ * Delete a file
818
+ * @param path - The object key/path
819
+ */
820
+ async remove(path) {
821
+ try {
822
+ const response = await this.http.delete(
823
+ `/api/storage/buckets/${this.bucketName}/objects/${encodeURIComponent(path)}`
824
+ );
825
+ return { data: response, error: null };
826
+ } catch (error) {
827
+ return {
828
+ data: null,
829
+ error: error instanceof InsForgeError ? error : new InsForgeError(
830
+ "Delete failed",
831
+ 500,
832
+ "STORAGE_ERROR"
833
+ )
834
+ };
835
+ }
836
+ }
837
+ };
838
+ var Storage = class {
839
+ constructor(http) {
840
+ this.http = http;
841
+ }
842
+ /**
843
+ * Get a bucket instance for operations
844
+ * @param bucketName - Name of the bucket
845
+ */
846
+ from(bucketName) {
847
+ return new StorageBucket(bucketName, this.http);
848
+ }
849
+ };
850
+
654
851
  // src/client.ts
655
852
  var InsForgeClient = class {
656
853
  constructor(config = {}) {
@@ -661,6 +858,7 @@ var InsForgeClient = class {
661
858
  this.tokenManager
662
859
  );
663
860
  this.database = new Database(this.http);
861
+ this.storage = new Storage(this.http);
664
862
  }
665
863
  /**
666
864
  * Set a custom API key for authentication
@@ -711,6 +909,8 @@ var index_default = InsForgeClient;
711
909
  InsForgeClient,
712
910
  InsForgeError,
713
911
  QueryBuilder,
912
+ Storage,
913
+ StorageBucket,
714
914
  TokenManager,
715
915
  createClient
716
916
  });