@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 +30 -7
- package/dist/index.d.ts +30 -7
- package/dist/index.js +213 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +213 -14
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
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
|
|
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
|
-
|
|
399
|
+
private uploadDirect;
|
|
385
400
|
/**
|
|
386
401
|
* Upload a file with auto-generated key
|
|
387
|
-
* @param file - File
|
|
402
|
+
* @param file - File or Blob to upload
|
|
388
403
|
*/
|
|
389
|
-
uploadAuto(file: File | Blob
|
|
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
|
-
*
|
|
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
|
|
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
|
-
|
|
399
|
+
private uploadDirect;
|
|
385
400
|
/**
|
|
386
401
|
* Upload a file with auto-generated key
|
|
387
|
-
* @param file - File
|
|
402
|
+
* @param file - File or Blob to upload
|
|
388
403
|
*/
|
|
389
|
-
uploadAuto(file: File | Blob
|
|
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
|
-
*
|
|
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
|
|
766
|
+
* @param file - File or Blob to upload
|
|
723
767
|
*/
|
|
724
768
|
async upload(path, file) {
|
|
725
769
|
try {
|
|
726
|
-
const
|
|
727
|
-
|
|
728
|
-
|
|
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
|
-
"
|
|
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
|
|
886
|
+
* @param file - File or Blob to upload
|
|
755
887
|
*/
|
|
756
888
|
async uploadAuto(file) {
|
|
757
889
|
try {
|
|
758
|
-
const formData =
|
|
759
|
-
|
|
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
|
-
"
|
|
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) {
|