shogun-relay-sdk 1.2.8 → 1.2.10

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/client.js CHANGED
@@ -20,6 +20,10 @@ class ApiClient {
20
20
  if (this.config.token) {
21
21
  req.headers["Authorization"] = `Bearer ${this.config.token}`;
22
22
  }
23
+ // If data is FormData, remove Content-Type header to let browser set it with boundary
24
+ if (req.data instanceof FormData) {
25
+ delete req.headers["Content-Type"];
26
+ }
23
27
  return req;
24
28
  });
25
29
  }
@@ -1,6 +1,6 @@
1
1
  import { ApiClient } from "../client";
2
2
  export declare class IpfsModule {
3
- private client;
3
+ private readonly client;
4
4
  constructor(client: ApiClient);
5
5
  getStatus(): Promise<any>;
6
6
  uploadFile(fileBuffer: Buffer, filename: string, contentType: string, userAddress?: string): Promise<any>;
@@ -34,4 +34,33 @@ export declare class IpfsModule {
34
34
  repoGC(): Promise<any>;
35
35
  repoStat(): Promise<any>;
36
36
  getVersion(): Promise<any>;
37
+ /**
38
+ * Upload a file using browser FormData (for browser environments)
39
+ * @param file File object from browser File API
40
+ * @param userAddress Optional user address for authentication
41
+ * @returns Promise with upload result
42
+ */
43
+ uploadFileBrowser(file: File, userAddress?: string): Promise<any>;
44
+ /**
45
+ * Upload multiple files as a directory using browser FormData (for browser environments)
46
+ * Maintains directory structure using relative paths from File.webkitRelativePath or file.name
47
+ *
48
+ * @param files Array of File objects from browser File API
49
+ * @param userAddress Optional user address for authentication
50
+ * @returns Promise with directory CID and file information
51
+ */
52
+ uploadDirectoryBrowser(files: File[], userAddress?: string): Promise<any>;
53
+ /**
54
+ * Cat a file and return as Blob (for browser environments)
55
+ * @param cid The CID of the file
56
+ * @returns Promise with file content as Blob
57
+ */
58
+ catBlob(cid: string): Promise<Blob>;
59
+ /**
60
+ * Cat a file from directory and return as Blob (for browser environments)
61
+ * @param directoryCid The CID of the directory
62
+ * @param filePath The relative path to the file within the directory
63
+ * @returns Promise with file content as Blob
64
+ */
65
+ catFromDirectoryBlob(directoryCid: string, filePath: string): Promise<Blob>;
37
66
  }
@@ -71,8 +71,11 @@ class IpfsModule {
71
71
  // Format: /api/v0/cat?arg=QmDirectory/index.html
72
72
  const fullPath = `${directoryCid}/${filePath}`;
73
73
  // Encode only the CID part, keep slashes for navigation
74
- const encodedPath = fullPath.includes('/')
75
- ? `${encodeURIComponent(directoryCid)}/${filePath.split('/').map(p => encodeURIComponent(p)).join('/')}`
74
+ const encodedPath = fullPath.includes("/")
75
+ ? `${encodeURIComponent(directoryCid)}/${filePath
76
+ .split("/")
77
+ .map((p) => encodeURIComponent(p))
78
+ .join("/")}`
76
79
  : encodeURIComponent(fullPath);
77
80
  // Use GET instead of POST, or send empty string instead of null to avoid JSON parser error
78
81
  // IPFS API v0 cat accepts POST with empty body, but Express JSON parser fails on null
@@ -118,5 +121,98 @@ class IpfsModule {
118
121
  async getVersion() {
119
122
  return this.client.get("/api/v1/ipfs/version");
120
123
  }
124
+ /**
125
+ * Upload a file using browser FormData (for browser environments)
126
+ * @param file File object from browser File API
127
+ * @param userAddress Optional user address for authentication
128
+ * @returns Promise with upload result
129
+ */
130
+ async uploadFileBrowser(file, userAddress) {
131
+ const formData = new form_data_1.default();
132
+ formData.append("file", file, file.name);
133
+ const headers = {};
134
+ if (userAddress) {
135
+ headers["x-user-address"] = userAddress;
136
+ }
137
+ // Explicitly don't set Content-Type - let browser set it with boundary for FormData
138
+ return this.client.post("/api/v1/ipfs/upload", formData, {
139
+ headers: headers,
140
+ // Ensure axios doesn't serialize FormData as JSON
141
+ transformRequest: [(data) => {
142
+ // If it's FormData, return as-is (axios will handle it)
143
+ if (data instanceof form_data_1.default) {
144
+ return data;
145
+ }
146
+ return data;
147
+ }],
148
+ });
149
+ }
150
+ /**
151
+ * Upload multiple files as a directory using browser FormData (for browser environments)
152
+ * Maintains directory structure using relative paths from File.webkitRelativePath or file.name
153
+ *
154
+ * @param files Array of File objects from browser File API
155
+ * @param userAddress Optional user address for authentication
156
+ * @returns Promise with directory CID and file information
157
+ */
158
+ async uploadDirectoryBrowser(files, userAddress) {
159
+ if (!files || files.length === 0) {
160
+ throw new Error("At least one file is required for directory upload");
161
+ }
162
+ const formData = new form_data_1.default();
163
+ // Add all files to FormData maintaining directory structure
164
+ files.forEach((file) => {
165
+ // Use webkitRelativePath if available (from folder input), otherwise use file.name
166
+ const relativePath = file.webkitRelativePath || file.name;
167
+ formData.append("files", file, relativePath);
168
+ });
169
+ const headers = {};
170
+ if (userAddress) {
171
+ headers["x-user-address"] = userAddress;
172
+ }
173
+ // Explicitly don't set Content-Type - let browser set it with boundary for FormData
174
+ return this.client.post("/api/v1/ipfs/upload-directory", formData, {
175
+ headers: headers,
176
+ // Ensure axios doesn't serialize FormData as JSON
177
+ transformRequest: [(data) => {
178
+ // If it's FormData, return as-is (axios will handle it)
179
+ if (data instanceof form_data_1.default) {
180
+ return data;
181
+ }
182
+ return data;
183
+ }],
184
+ });
185
+ }
186
+ /**
187
+ * Cat a file and return as Blob (for browser environments)
188
+ * @param cid The CID of the file
189
+ * @returns Promise with file content as Blob
190
+ */
191
+ async catBlob(cid) {
192
+ return this.client.get(`/api/v1/ipfs/cat/${cid}`, {
193
+ responseType: "blob",
194
+ });
195
+ }
196
+ /**
197
+ * Cat a file from directory and return as Blob (for browser environments)
198
+ * @param directoryCid The CID of the directory
199
+ * @param filePath The relative path to the file within the directory
200
+ * @returns Promise with file content as Blob
201
+ */
202
+ async catFromDirectoryBlob(directoryCid, filePath) {
203
+ const fullPath = `${directoryCid}/${filePath}`;
204
+ const encodedPath = fullPath.includes("/")
205
+ ? `${encodeURIComponent(directoryCid)}/${filePath
206
+ .split("/")
207
+ .map((p) => encodeURIComponent(p))
208
+ .join("/")}`
209
+ : encodeURIComponent(fullPath);
210
+ return this.client.post(`/api/v1/ipfs/api/v0/cat?arg=${encodedPath}`, "", {
211
+ responseType: "blob",
212
+ headers: {
213
+ "Content-Type": "application/octet-stream",
214
+ },
215
+ });
216
+ }
121
217
  }
122
218
  exports.IpfsModule = IpfsModule;
@@ -9,8 +9,13 @@ export interface HealthResponse {
9
9
  };
10
10
  }
11
11
  export declare class SystemModule {
12
- private client;
12
+ private readonly client;
13
13
  constructor(client: ApiClient);
14
14
  getHealth(): Promise<HealthResponse>;
15
15
  getStats(): Promise<any>;
16
+ /**
17
+ * Simple health check endpoint
18
+ * @returns Promise with health status
19
+ */
20
+ health(): Promise<any>;
16
21
  }
@@ -12,5 +12,12 @@ class SystemModule {
12
12
  async getStats() {
13
13
  return this.client.get("/api/v1/system/stats");
14
14
  }
15
+ /**
16
+ * Simple health check endpoint
17
+ * @returns Promise with health status
18
+ */
19
+ async health() {
20
+ return this.client.get("/health");
21
+ }
15
22
  }
16
23
  exports.SystemModule = SystemModule;
@@ -5,4 +5,45 @@ export declare class UploadsModule {
5
5
  getUserUploads(identifier: string): Promise<any>;
6
6
  deleteUpload(identifier: string, hash: string): Promise<any>;
7
7
  getSystemHashes(): Promise<any>;
8
+ /**
9
+ * Get the complete system hashes map with metadata for all files
10
+ * @returns Promise with system hashes map object
11
+ */
12
+ getSystemHashesMap(): Promise<any>;
13
+ /**
14
+ * Save file metadata to system hash map
15
+ * @param metadata Metadata object containing hash, userAddress, fileName, etc.
16
+ * @returns Promise with save result
17
+ */
18
+ saveSystemHash(metadata: {
19
+ hash: string;
20
+ userAddress?: string;
21
+ fileName?: string;
22
+ displayName?: string;
23
+ originalName?: string;
24
+ fileSize?: number;
25
+ contentType?: string;
26
+ isEncrypted?: boolean;
27
+ isDirectory?: boolean;
28
+ fileCount?: number;
29
+ files?: Array<{
30
+ name: string;
31
+ path?: string;
32
+ size?: number;
33
+ mimetype?: string;
34
+ originalName?: string;
35
+ isEncrypted?: boolean;
36
+ }>;
37
+ relayUrl?: string;
38
+ uploadedAt?: number;
39
+ timestamp?: number;
40
+ [key: string]: any;
41
+ }): Promise<any>;
42
+ /**
43
+ * Remove a hash from system hash map
44
+ * @param cid The CID/hash to remove
45
+ * @param userAddress User address (defaults to "drive-user")
46
+ * @returns Promise with removal result
47
+ */
48
+ removeSystemHash(cid: string, userAddress?: string): Promise<any>;
8
49
  }
@@ -14,5 +14,34 @@ class UploadsModule {
14
14
  async getSystemHashes() {
15
15
  return this.client.get("/api/v1/user-uploads/system-hashes");
16
16
  }
17
+ /**
18
+ * Get the complete system hashes map with metadata for all files
19
+ * @returns Promise with system hashes map object
20
+ */
21
+ async getSystemHashesMap() {
22
+ return this.client.get("/api/v1/user-uploads/system-hashes-map");
23
+ }
24
+ /**
25
+ * Save file metadata to system hash map
26
+ * @param metadata Metadata object containing hash, userAddress, fileName, etc.
27
+ * @returns Promise with save result
28
+ */
29
+ async saveSystemHash(metadata) {
30
+ return this.client.post("/api/v1/user-uploads/save-system-hash", metadata);
31
+ }
32
+ /**
33
+ * Remove a hash from system hash map
34
+ * @param cid The CID/hash to remove
35
+ * @param userAddress User address (defaults to "drive-user")
36
+ * @returns Promise with removal result
37
+ */
38
+ async removeSystemHash(cid, userAddress = "drive-user") {
39
+ return this.client.delete(`/api/v1/user-uploads/remove-system-hash/${cid}`, {
40
+ data: { userAddress },
41
+ headers: {
42
+ "Content-Type": "application/json",
43
+ },
44
+ });
45
+ }
17
46
  }
18
47
  exports.UploadsModule = UploadsModule;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shogun-relay-sdk",
3
- "version": "1.2.8",
3
+ "version": "1.2.10",
4
4
  "description": "SDK for interacting with Shogun Relay API - HTTP client for IPFS, deals, registry, and network operations",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",