mirror of
https://github.com/DeBrosOfficial/network-ts-sdk.git
synced 2025-12-13 18:48:49 +00:00
Compare commits
No commits in common. "272c6b872cb214f64d4d54b4969558129811bd21" and "6f5be86a02473d220d5dac017ddfb22162a2517b" have entirely different histories.
272c6b872c
...
6f5be86a02
34
README.md
34
README.md
@ -272,40 +272,6 @@ peers.forEach((peer) => {
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Proxy Requests Through Anyone Network
|
|
||||||
|
|
||||||
Make anonymous HTTP requests through the Anyone network:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// Simple GET request
|
|
||||||
const response = await client.network.proxyAnon({
|
|
||||||
url: "https://api.example.com/data",
|
|
||||||
method: "GET",
|
|
||||||
headers: {
|
|
||||||
Accept: "application/json",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(response.status_code); // 200
|
|
||||||
console.log(response.body); // Response data as string
|
|
||||||
console.log(response.headers); // Response headers
|
|
||||||
|
|
||||||
// POST request with body
|
|
||||||
const postResponse = await client.network.proxyAnon({
|
|
||||||
url: "https://api.example.com/submit",
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body: JSON.stringify({ key: "value" }),
|
|
||||||
});
|
|
||||||
|
|
||||||
// Parse JSON response
|
|
||||||
const data = JSON.parse(postResponse.body);
|
|
||||||
```
|
|
||||||
|
|
||||||
**Note:** The proxy endpoint requires authentication (API key or JWT) and only works when the Anyone relay is running on the gateway server.
|
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
### ClientConfig
|
### ClientConfig
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@debros/network-ts-sdk",
|
"name": "@debros/network-ts-sdk",
|
||||||
"version": "0.2.5",
|
"version": "0.1.5",
|
||||||
"description": "TypeScript SDK for DeBros Network Gateway",
|
"description": "TypeScript SDK for DeBros Network Gateway",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
|
|||||||
@ -54,14 +54,13 @@ export class HttpClient {
|
|||||||
private getAuthHeaders(path: string): Record<string, string> {
|
private getAuthHeaders(path: string): Record<string, string> {
|
||||||
const headers: Record<string, string> = {};
|
const headers: Record<string, string> = {};
|
||||||
|
|
||||||
// For database, pubsub, and proxy operations, ONLY use API key to avoid JWT user context
|
// For database and pubsub operations, ONLY use API key to avoid JWT user context
|
||||||
// interfering with namespace-level authorization
|
// interfering with namespace-level authorization
|
||||||
const isDbOperation = path.includes("/v1/rqlite/");
|
const isDbOperation = path.includes("/v1/rqlite/");
|
||||||
const isPubSubOperation = path.includes("/v1/pubsub/");
|
const isPubSubOperation = path.includes("/v1/pubsub/");
|
||||||
const isProxyOperation = path.includes("/v1/proxy/");
|
|
||||||
|
|
||||||
if (isDbOperation || isPubSubOperation || isProxyOperation) {
|
if (isDbOperation || isPubSubOperation) {
|
||||||
// For database/pubsub/proxy operations: use only API key (preferred for namespace operations)
|
// For database/pubsub operations: use only API key (preferred for namespace operations)
|
||||||
if (this.apiKey) {
|
if (this.apiKey) {
|
||||||
headers["X-API-Key"] = this.apiKey;
|
headers["X-API-Key"] = this.apiKey;
|
||||||
} else if (this.jwt) {
|
} else if (this.jwt) {
|
||||||
@ -117,8 +116,7 @@ export class HttpClient {
|
|||||||
(path.includes("/db/") ||
|
(path.includes("/db/") ||
|
||||||
path.includes("/query") ||
|
path.includes("/query") ||
|
||||||
path.includes("/auth/") ||
|
path.includes("/auth/") ||
|
||||||
path.includes("/pubsub/") ||
|
path.includes("/pubsub/"))
|
||||||
path.includes("/proxy/"))
|
|
||||||
) {
|
) {
|
||||||
console.log("[HttpClient] Request headers for", path, {
|
console.log("[HttpClient] Request headers for", path, {
|
||||||
hasAuth: !!headers["Authorization"],
|
hasAuth: !!headers["Authorization"],
|
||||||
|
|||||||
24
src/index.ts
24
src/index.ts
@ -4,11 +4,7 @@ import { DBClient } from "./db/client";
|
|||||||
import { PubSubClient } from "./pubsub/client";
|
import { PubSubClient } from "./pubsub/client";
|
||||||
import { NetworkClient } from "./network/client";
|
import { NetworkClient } from "./network/client";
|
||||||
import { WSClientConfig } from "./core/ws";
|
import { WSClientConfig } from "./core/ws";
|
||||||
import {
|
import { StorageAdapter, MemoryStorage, LocalStorageAdapter } from "./auth/types";
|
||||||
StorageAdapter,
|
|
||||||
MemoryStorage,
|
|
||||||
LocalStorageAdapter,
|
|
||||||
} from "./auth/types";
|
|
||||||
|
|
||||||
export interface ClientConfig extends Omit<HttpClientConfig, "fetch"> {
|
export interface ClientConfig extends Omit<HttpClientConfig, "fetch"> {
|
||||||
apiKey?: string;
|
apiKey?: string;
|
||||||
@ -42,9 +38,8 @@ export function createClient(config: ClientConfig): Client {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Derive WebSocket URL from baseURL if not explicitly provided
|
// Derive WebSocket URL from baseURL if not explicitly provided
|
||||||
const wsURL =
|
const wsURL = config.wsConfig?.wsURL ??
|
||||||
config.wsConfig?.wsURL ??
|
config.baseURL.replace(/^http/, 'ws').replace(/\/$/, '');
|
||||||
config.baseURL.replace(/^http/, "ws").replace(/\/$/, "");
|
|
||||||
|
|
||||||
const db = new DBClient(httpClient);
|
const db = new DBClient(httpClient);
|
||||||
const pubsub = new PubSubClient(httpClient, {
|
const pubsub = new PubSubClient(httpClient, {
|
||||||
@ -72,7 +67,11 @@ export { PubSubClient, Subscription } from "./pubsub/client";
|
|||||||
export { NetworkClient } from "./network/client";
|
export { NetworkClient } from "./network/client";
|
||||||
export { SDKError } from "./errors";
|
export { SDKError } from "./errors";
|
||||||
export { MemoryStorage, LocalStorageAdapter } from "./auth/types";
|
export { MemoryStorage, LocalStorageAdapter } from "./auth/types";
|
||||||
export type { StorageAdapter, AuthConfig, WhoAmI } from "./auth/types";
|
export type {
|
||||||
|
StorageAdapter,
|
||||||
|
AuthConfig,
|
||||||
|
WhoAmI,
|
||||||
|
} from "./auth/types";
|
||||||
export type * from "./db/types";
|
export type * from "./db/types";
|
||||||
export type {
|
export type {
|
||||||
Message,
|
Message,
|
||||||
@ -80,9 +79,4 @@ export type {
|
|||||||
ErrorHandler,
|
ErrorHandler,
|
||||||
CloseHandler,
|
CloseHandler,
|
||||||
} from "./pubsub/client";
|
} from "./pubsub/client";
|
||||||
export type {
|
export type { PeerInfo, NetworkStatus } from "./network/client";
|
||||||
PeerInfo,
|
|
||||||
NetworkStatus,
|
|
||||||
ProxyRequest,
|
|
||||||
ProxyResponse,
|
|
||||||
} from "./network/client";
|
|
||||||
|
|||||||
@ -14,20 +14,6 @@ export interface NetworkStatus {
|
|||||||
uptime: number;
|
uptime: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProxyRequest {
|
|
||||||
url: string;
|
|
||||||
method: string;
|
|
||||||
headers?: Record<string, string>;
|
|
||||||
body?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ProxyResponse {
|
|
||||||
status_code: number;
|
|
||||||
headers: Record<string, string>;
|
|
||||||
body: string;
|
|
||||||
error?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class NetworkClient {
|
export class NetworkClient {
|
||||||
private httpClient: HttpClient;
|
private httpClient: HttpClient;
|
||||||
|
|
||||||
@ -51,9 +37,7 @@ export class NetworkClient {
|
|||||||
* Get network status.
|
* Get network status.
|
||||||
*/
|
*/
|
||||||
async status(): Promise<NetworkStatus> {
|
async status(): Promise<NetworkStatus> {
|
||||||
const response = await this.httpClient.get<NetworkStatus>(
|
const response = await this.httpClient.get<NetworkStatus>("/v1/network/status");
|
||||||
"/v1/network/status"
|
|
||||||
);
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,40 +64,4 @@ export class NetworkClient {
|
|||||||
async disconnect(peerId: string): Promise<void> {
|
async disconnect(peerId: string): Promise<void> {
|
||||||
await this.httpClient.post("/v1/network/disconnect", { peer_id: peerId });
|
await this.httpClient.post("/v1/network/disconnect", { peer_id: peerId });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Proxy an HTTP request through the Anyone network.
|
|
||||||
* Requires authentication (API key or JWT).
|
|
||||||
*
|
|
||||||
* @param request - The proxy request configuration
|
|
||||||
* @returns The proxied response
|
|
||||||
* @throws {SDKError} If the Anyone proxy is not available or the request fails
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts
|
|
||||||
* const response = await client.network.proxyAnon({
|
|
||||||
* url: 'https://api.example.com/data',
|
|
||||||
* method: 'GET',
|
|
||||||
* headers: {
|
|
||||||
* 'Accept': 'application/json'
|
|
||||||
* }
|
|
||||||
* });
|
|
||||||
*
|
|
||||||
* console.log(response.status_code); // 200
|
|
||||||
* console.log(response.body); // Response data
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
async proxyAnon(request: ProxyRequest): Promise<ProxyResponse> {
|
|
||||||
const response = await this.httpClient.post<ProxyResponse>(
|
|
||||||
"/v1/proxy/anon",
|
|
||||||
request
|
|
||||||
);
|
|
||||||
|
|
||||||
// Check if the response contains an error
|
|
||||||
if (response.error) {
|
|
||||||
throw new Error(`Proxy request failed: ${response.error}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,34 +27,4 @@ describe("Network", () => {
|
|||||||
const peers = await client.network.peers();
|
const peers = await client.network.peers();
|
||||||
expect(Array.isArray(peers)).toBe(true);
|
expect(Array.isArray(peers)).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should proxy request through Anyone network", async () => {
|
|
||||||
const client = await createTestClient();
|
|
||||||
|
|
||||||
// Test with a simple GET request
|
|
||||||
const response = await client.network.proxyAnon({
|
|
||||||
url: "https://httpbin.org/get",
|
|
||||||
method: "GET",
|
|
||||||
headers: {
|
|
||||||
"User-Agent": "DeBros-SDK-Test/1.0",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(response).toBeDefined();
|
|
||||||
expect(response.status_code).toBe(200);
|
|
||||||
expect(response.body).toBeDefined();
|
|
||||||
expect(typeof response.body).toBe("string");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should handle proxy errors gracefully", async () => {
|
|
||||||
const client = await createTestClient();
|
|
||||||
|
|
||||||
// Test with invalid URL
|
|
||||||
await expect(
|
|
||||||
client.network.proxyAnon({
|
|
||||||
url: "http://localhost:1/invalid",
|
|
||||||
method: "GET",
|
|
||||||
})
|
|
||||||
).rejects.toThrow();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user