@insforge/sdk 0.0.13 → 0.0.15

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
@@ -102,6 +102,12 @@ declare class Auth {
102
102
  private tokenManager;
103
103
  private database;
104
104
  constructor(http: HttpClient, tokenManager: TokenManager);
105
+ /**
106
+ * Automatically detect and handle OAuth callback parameters in the URL
107
+ * This runs on initialization to seamlessly complete the OAuth flow
108
+ * Matches the backend's OAuth callback response (backend/src/api/routes/auth.ts:540-544)
109
+ */
110
+ private detectOAuthCallback;
105
111
  /**
106
112
  * Sign up a new user
107
113
  */
@@ -363,6 +369,7 @@ declare class Database {
363
369
  /**
364
370
  * Storage module for InsForge SDK
365
371
  * Handles file uploads, downloads, and bucket management
372
+ * Supports both presigned URLs (S3) and direct uploads (local)
366
373
  */
367
374
 
368
375
  interface StorageResponse<T> {
@@ -377,18 +384,26 @@ declare class StorageBucket {
377
384
  private http;
378
385
  constructor(bucketName: string, http: HttpClient);
379
386
  /**
380
- * Upload a file with a specific key
387
+ * Upload a file with a specific key using the appropriate strategy
381
388
  * @param path - The object key/path
382
- * @param file - File, Blob, or FormData to upload
389
+ * @param file - File or Blob to upload
390
+ */
391
+ upload(path: string, file: File | Blob): Promise<StorageResponse<StorageFileSchema>>;
392
+ /**
393
+ * Upload using presigned URL (for S3)
394
+ */
395
+ private uploadPresigned;
396
+ /**
397
+ * Upload directly to backend (for local storage)
383
398
  */
384
- upload(path: string, file: File | Blob | FormData): Promise<StorageResponse<StorageFileSchema>>;
399
+ private uploadDirect;
385
400
  /**
386
401
  * Upload a file with auto-generated key
387
- * @param file - File, Blob, or FormData to upload
402
+ * @param file - File or Blob to upload
388
403
  */
389
- uploadAuto(file: File | Blob | FormData): Promise<StorageResponse<StorageFileSchema>>;
404
+ uploadAuto(file: File | Blob): Promise<StorageResponse<StorageFileSchema>>;
390
405
  /**
391
- * Download a file
406
+ * Download a file using the appropriate strategy
392
407
  * @param path - The object key/path
393
408
  * Returns the file as a Blob
394
409
  */
@@ -397,7 +412,15 @@ declare class StorageBucket {
397
412
  error: InsForgeError | null;
398
413
  }>;
399
414
  /**
400
- * Get public URL for a file
415
+ * Download using presigned URL (for S3)
416
+ */
417
+ private downloadPresigned;
418
+ /**
419
+ * Download directly from backend (for local storage)
420
+ */
421
+ private downloadDirect;
422
+ /**
423
+ * Get public URL for a file (direct URL, may not work for private S3)
401
424
  * @param path - The object key/path
402
425
  */
403
426
  getPublicUrl(path: string): string;
package/dist/index.d.ts CHANGED
@@ -102,6 +102,12 @@ declare class Auth {
102
102
  private tokenManager;
103
103
  private database;
104
104
  constructor(http: HttpClient, tokenManager: TokenManager);
105
+ /**
106
+ * Automatically detect and handle OAuth callback parameters in the URL
107
+ * This runs on initialization to seamlessly complete the OAuth flow
108
+ * Matches the backend's OAuth callback response (backend/src/api/routes/auth.ts:540-544)
109
+ */
110
+ private detectOAuthCallback;
105
111
  /**
106
112
  * Sign up a new user
107
113
  */
@@ -363,6 +369,7 @@ declare class Database {
363
369
  /**
364
370
  * Storage module for InsForge SDK
365
371
  * Handles file uploads, downloads, and bucket management
372
+ * Supports both presigned URLs (S3) and direct uploads (local)
366
373
  */
367
374
 
368
375
  interface StorageResponse<T> {
@@ -377,18 +384,26 @@ declare class StorageBucket {
377
384
  private http;
378
385
  constructor(bucketName: string, http: HttpClient);
379
386
  /**
380
- * Upload a file with a specific key
387
+ * Upload a file with a specific key using the appropriate strategy
381
388
  * @param path - The object key/path
382
- * @param file - File, Blob, or FormData to upload
389
+ * @param file - File or Blob to upload
390
+ */
391
+ upload(path: string, file: File | Blob): Promise<StorageResponse<StorageFileSchema>>;
392
+ /**
393
+ * Upload using presigned URL (for S3)
394
+ */
395
+ private uploadPresigned;
396
+ /**
397
+ * Upload directly to backend (for local storage)
383
398
  */
384
- upload(path: string, file: File | Blob | FormData): Promise<StorageResponse<StorageFileSchema>>;
399
+ private uploadDirect;
385
400
  /**
386
401
  * Upload a file with auto-generated key
387
- * @param file - File, Blob, or FormData to upload
402
+ * @param file - File or Blob to upload
388
403
  */
389
- uploadAuto(file: File | Blob | FormData): Promise<StorageResponse<StorageFileSchema>>;
404
+ uploadAuto(file: File | Blob): Promise<StorageResponse<StorageFileSchema>>;
390
405
  /**
391
- * Download a file
406
+ * Download a file using the appropriate strategy
392
407
  * @param path - The object key/path
393
408
  * Returns the file as a Blob
394
409
  */
@@ -397,7 +412,15 @@ declare class StorageBucket {
397
412
  error: InsForgeError | null;
398
413
  }>;
399
414
  /**
400
- * Get public URL for a file
415
+ * Download using presigned URL (for S3)
416
+ */
417
+ private downloadPresigned;
418
+ /**
419
+ * Download directly from backend (for local storage)
420
+ */
421
+ private downloadDirect;
422
+ /**
423
+ * Get public URL for a file (direct URL, may not work for private S3)
401
424
  * @param path - The object key/path
402
425
  */
403
426
  getPublicUrl(path: string): string;
package/dist/index.js CHANGED
@@ -499,6 +499,50 @@ var Auth = class {
499
499
  this.http = http;
500
500
  this.tokenManager = tokenManager;
501
501
  this.database = new Database(http);
502
+ this.detectOAuthCallback();
503
+ }
504
+ /**
505
+ * Automatically detect and handle OAuth callback parameters in the URL
506
+ * This runs on initialization to seamlessly complete the OAuth flow
507
+ * Matches the backend's OAuth callback response (backend/src/api/routes/auth.ts:540-544)
508
+ */
509
+ detectOAuthCallback() {
510
+ if (typeof window === "undefined") return;
511
+ try {
512
+ const params = new URLSearchParams(window.location.search);
513
+ const accessToken = params.get("access_token");
514
+ const userId = params.get("user_id");
515
+ const email = params.get("email");
516
+ const name = params.get("name");
517
+ if (accessToken && userId && email) {
518
+ const session = {
519
+ accessToken,
520
+ user: {
521
+ id: userId,
522
+ email,
523
+ name: name || "",
524
+ // These fields are not provided by backend OAuth callback
525
+ // They'll be populated when calling getCurrentUser()
526
+ emailVerified: false,
527
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
528
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
529
+ }
530
+ };
531
+ this.tokenManager.saveSession(session);
532
+ this.http.setAuthToken(accessToken);
533
+ const url = new URL(window.location.href);
534
+ url.searchParams.delete("access_token");
535
+ url.searchParams.delete("user_id");
536
+ url.searchParams.delete("email");
537
+ url.searchParams.delete("name");
538
+ if (params.has("error")) {
539
+ url.searchParams.delete("error");
540
+ }
541
+ window.history.replaceState({}, document.title, url.toString());
542
+ }
543
+ } catch (error) {
544
+ console.debug("OAuth callback detection skipped:", error);
545
+ }
502
546
  }
503
547
  /**
504
548
  * Sign up a new user
@@ -717,16 +761,104 @@ var StorageBucket = class {
717
761
  this.http = http;
718
762
  }
719
763
  /**
720
- * Upload a file with a specific key
764
+ * Upload a file with a specific key using the appropriate strategy
721
765
  * @param path - The object key/path
722
- * @param file - File, Blob, or FormData to upload
766
+ * @param file - File or Blob to upload
723
767
  */
724
768
  async upload(path, file) {
725
769
  try {
726
- const formData = file instanceof FormData ? file : new FormData();
727
- if (!(file instanceof FormData)) {
728
- formData.append("file", file);
770
+ const strategyRequest = {
771
+ filename: path,
772
+ contentType: file.type || "application/octet-stream",
773
+ size: file.size
774
+ };
775
+ const strategy = await this.http.post(
776
+ `/api/storage/buckets/${this.bucketName}/upload-strategy`,
777
+ strategyRequest
778
+ );
779
+ if (!strategy) {
780
+ throw new InsForgeError("Failed to get upload strategy", 500, "STORAGE_ERROR");
781
+ }
782
+ if (strategy.method === "presigned") {
783
+ return await this.uploadPresigned(strategy, file);
784
+ } else {
785
+ return await this.uploadDirect(path, file);
729
786
  }
787
+ } catch (error) {
788
+ return {
789
+ data: null,
790
+ error: error instanceof InsForgeError ? error : new InsForgeError(
791
+ "Upload failed",
792
+ 500,
793
+ "STORAGE_ERROR"
794
+ )
795
+ };
796
+ }
797
+ }
798
+ /**
799
+ * Upload using presigned URL (for S3)
800
+ */
801
+ async uploadPresigned(strategy, file) {
802
+ try {
803
+ const formData = new FormData();
804
+ if (strategy.fields) {
805
+ Object.entries(strategy.fields).forEach(([key, value]) => {
806
+ formData.append(key, value);
807
+ });
808
+ }
809
+ formData.append("file", file);
810
+ const uploadResponse = await fetch(strategy.uploadUrl, {
811
+ method: "POST",
812
+ body: formData
813
+ });
814
+ if (!uploadResponse.ok) {
815
+ const text = await uploadResponse.text();
816
+ throw new InsForgeError(
817
+ `Presigned upload failed: ${text}`,
818
+ uploadResponse.status,
819
+ "STORAGE_ERROR"
820
+ );
821
+ }
822
+ if (strategy.confirmRequired && strategy.confirmUrl) {
823
+ const confirmRequest = {
824
+ size: file.size,
825
+ contentType: file.type || "application/octet-stream"
826
+ };
827
+ const confirmResponse = await this.http.post(
828
+ strategy.confirmUrl,
829
+ confirmRequest
830
+ );
831
+ return { data: confirmResponse, error: null };
832
+ }
833
+ return {
834
+ data: {
835
+ bucket: this.bucketName,
836
+ key: strategy.key,
837
+ size: file.size,
838
+ mimeType: file.type,
839
+ uploadedAt: (/* @__PURE__ */ new Date()).toISOString(),
840
+ url: this.getPublicUrl(strategy.key)
841
+ },
842
+ error: null
843
+ };
844
+ } catch (error) {
845
+ return {
846
+ data: null,
847
+ error: error instanceof InsForgeError ? error : new InsForgeError(
848
+ "Presigned upload failed",
849
+ 500,
850
+ "STORAGE_ERROR"
851
+ )
852
+ };
853
+ }
854
+ }
855
+ /**
856
+ * Upload directly to backend (for local storage)
857
+ */
858
+ async uploadDirect(path, file) {
859
+ try {
860
+ const formData = new FormData();
861
+ formData.append("file", file);
730
862
  const response = await this.http.request(
731
863
  "PUT",
732
864
  `/api/storage/buckets/${this.bucketName}/objects/${encodeURIComponent(path)}`,
@@ -742,7 +874,7 @@ var StorageBucket = class {
742
874
  return {
743
875
  data: null,
744
876
  error: error instanceof InsForgeError ? error : new InsForgeError(
745
- "Upload failed",
877
+ "Direct upload failed",
746
878
  500,
747
879
  "STORAGE_ERROR"
748
880
  )
@@ -751,14 +883,12 @@ var StorageBucket = class {
751
883
  }
752
884
  /**
753
885
  * Upload a file with auto-generated key
754
- * @param file - File, Blob, or FormData to upload
886
+ * @param file - File or Blob to upload
755
887
  */
756
888
  async uploadAuto(file) {
757
889
  try {
758
- const formData = file instanceof FormData ? file : new FormData();
759
- if (!(file instanceof FormData)) {
760
- formData.append("file", file);
761
- }
890
+ const formData = new FormData();
891
+ formData.append("file", file);
762
892
  const response = await this.http.request(
763
893
  "POST",
764
894
  `/api/storage/buckets/${this.bucketName}/objects`,
@@ -782,11 +912,78 @@ var StorageBucket = class {
782
912
  }
783
913
  }
784
914
  /**
785
- * Download a file
915
+ * Download a file using the appropriate strategy
786
916
  * @param path - The object key/path
787
917
  * Returns the file as a Blob
788
918
  */
789
919
  async download(path) {
920
+ try {
921
+ const strategyRequest = {
922
+ expiresIn: 3600
923
+ // 1 hour default
924
+ };
925
+ const strategy = await this.http.post(
926
+ `/api/storage/buckets/${this.bucketName}/objects/${encodeURIComponent(path)}/download-strategy`,
927
+ strategyRequest
928
+ );
929
+ if (!strategy) {
930
+ return await this.downloadDirect(path);
931
+ }
932
+ if (strategy.method === "presigned") {
933
+ return await this.downloadPresigned(strategy);
934
+ } else {
935
+ return await this.downloadDirect(path);
936
+ }
937
+ } catch (error) {
938
+ return {
939
+ data: null,
940
+ error: error instanceof InsForgeError ? error : new InsForgeError(
941
+ "Download failed",
942
+ 500,
943
+ "STORAGE_ERROR"
944
+ )
945
+ };
946
+ }
947
+ }
948
+ /**
949
+ * Download using presigned URL (for S3)
950
+ */
951
+ async downloadPresigned(strategy) {
952
+ try {
953
+ const headers = {};
954
+ if (strategy.headers) {
955
+ Object.entries(strategy.headers).forEach(([key, value]) => {
956
+ headers[key] = value;
957
+ });
958
+ }
959
+ const response = await fetch(strategy.url, {
960
+ method: "GET",
961
+ headers
962
+ });
963
+ if (!response.ok) {
964
+ throw new InsForgeError(
965
+ `Download failed: ${response.statusText}`,
966
+ response.status,
967
+ "STORAGE_ERROR"
968
+ );
969
+ }
970
+ const blob = await response.blob();
971
+ return { data: blob, error: null };
972
+ } catch (error) {
973
+ return {
974
+ data: null,
975
+ error: error instanceof InsForgeError ? error : new InsForgeError(
976
+ "Presigned download failed",
977
+ 500,
978
+ "STORAGE_ERROR"
979
+ )
980
+ };
981
+ }
982
+ }
983
+ /**
984
+ * Download directly from backend (for local storage)
985
+ */
986
+ async downloadDirect(path) {
790
987
  try {
791
988
  const url = `${this.http.baseUrl}/api/storage/buckets/${this.bucketName}/objects/${encodeURIComponent(path)}`;
792
989
  const response = await this.http.fetch(url, {
@@ -811,15 +1008,17 @@ var StorageBucket = class {
811
1008
  return {
812
1009
  data: null,
813
1010
  error: error instanceof InsForgeError ? error : new InsForgeError(
814
- "Download failed",
1011
+ "Direct download failed",
815
1012
  500,
816
1013
  "STORAGE_ERROR"
817
1014
  )
818
1015
  };
819
1016
  }
820
1017
  }
1018
+ // Removed getSignedUrl - this is handled internally by download()
1019
+ // The SDK abstracts away presigned URL complexity
821
1020
  /**
822
- * Get public URL for a file
1021
+ * Get public URL for a file (direct URL, may not work for private S3)
823
1022
  * @param path - The object key/path
824
1023
  */
825
1024
  getPublicUrl(path) {