hornerosssp 0.1.0 → 0.2.0
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 +39 -4
- package/dist/index.d.ts +39 -4
- package/dist/index.js +86 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +85 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -66,7 +66,12 @@ interface ConnectionData {
|
|
|
66
66
|
data: Record<string, string>;
|
|
67
67
|
}
|
|
68
68
|
interface HornerosSSPConfig {
|
|
69
|
-
|
|
69
|
+
/** API key for authentication. Falls back to HORNEROS_API_KEY env var. */
|
|
70
|
+
apiKey?: string;
|
|
71
|
+
/** Base URL of the HornerosSSP server. Falls back to HORNEROS_BASE_URL env var. */
|
|
72
|
+
baseUrl?: string;
|
|
73
|
+
/** Runtime identifier sent with every request (e.g. "node", "vercel"). */
|
|
74
|
+
runtime?: string;
|
|
70
75
|
}
|
|
71
76
|
interface ApiResponse<T> {
|
|
72
77
|
data: T;
|
|
@@ -119,7 +124,9 @@ declare class HornerosSSP {
|
|
|
119
124
|
readonly connections: Connections;
|
|
120
125
|
readonly tools: Tools;
|
|
121
126
|
private readonly baseUrl;
|
|
122
|
-
|
|
127
|
+
private readonly apiKey;
|
|
128
|
+
private readonly runtime;
|
|
129
|
+
constructor(config?: HornerosSSPConfig);
|
|
123
130
|
/** @internal */
|
|
124
131
|
fetch<T>(path: string, options?: RequestInit): Promise<T>;
|
|
125
132
|
}
|
|
@@ -143,10 +150,38 @@ declare class AuthScheme {
|
|
|
143
150
|
static GoogleLogin(): ConnectionData;
|
|
144
151
|
}
|
|
145
152
|
|
|
153
|
+
declare const HORNEROS_SDK_ERROR_CODES: {
|
|
154
|
+
readonly BACKEND: {
|
|
155
|
+
readonly NOT_FOUND: "BACKEND::NOT_FOUND";
|
|
156
|
+
readonly RATE_LIMIT: "BACKEND::RATE_LIMIT";
|
|
157
|
+
readonly BAD_REQUEST: "BACKEND::BAD_REQUEST";
|
|
158
|
+
readonly UNAUTHORIZED: "BACKEND::UNAUTHORIZED";
|
|
159
|
+
readonly SERVER_ERROR: "BACKEND::SERVER_ERROR";
|
|
160
|
+
readonly SERVER_UNAVAILABLE: "BACKEND::SERVER_UNAVAILABLE";
|
|
161
|
+
readonly UNKNOWN: "BACKEND::UNKNOWN";
|
|
162
|
+
};
|
|
163
|
+
readonly COMMON: {
|
|
164
|
+
readonly API_KEY_UNAVAILABLE: "COMMON::API_KEY_UNAVAILABLE";
|
|
165
|
+
readonly BASE_URL_NOT_REACHABLE: "COMMON::BASE_URL_NOT_REACHABLE";
|
|
166
|
+
readonly UNKNOWN: "COMMON::UNKNOWN";
|
|
167
|
+
readonly INVALID_PARAMS: "COMMON::INVALID_PARAMS";
|
|
168
|
+
};
|
|
169
|
+
readonly SDK: {
|
|
170
|
+
readonly NO_CONNECTED_ACCOUNT: "SDK::NO_CONNECTED_ACCOUNT";
|
|
171
|
+
readonly CONNECTION_TIMEOUT: "SDK::CONNECTION_TIMEOUT";
|
|
172
|
+
readonly INVALID_PARAMETER: "SDK::INVALID_PARAMETER";
|
|
173
|
+
};
|
|
174
|
+
};
|
|
146
175
|
declare class HornerosError extends Error {
|
|
176
|
+
readonly errCode: string;
|
|
147
177
|
readonly statusCode: number;
|
|
148
178
|
readonly body: unknown;
|
|
149
|
-
|
|
179
|
+
readonly description?: string;
|
|
180
|
+
readonly possibleFix?: string;
|
|
181
|
+
readonly errorId: string;
|
|
182
|
+
readonly timestamp: string;
|
|
183
|
+
constructor(errCode: string, message: string, statusCode: number, body?: unknown, description?: string, possibleFix?: string);
|
|
184
|
+
toJSON(): Record<string, unknown>;
|
|
150
185
|
}
|
|
151
186
|
declare class NotFoundError extends HornerosError {
|
|
152
187
|
constructor(message: string, body?: unknown);
|
|
@@ -158,4 +193,4 @@ declare class ConnectionTimeoutError extends HornerosError {
|
|
|
158
193
|
constructor(message?: string);
|
|
159
194
|
}
|
|
160
195
|
|
|
161
|
-
export { type ApiError, type ApiResponse, AuthScheme, type ConnectionData, type ConnectionInfo, ConnectionRequest, type ConnectionRequestData, ConnectionTimeoutError, Connections, type ExecuteToolParams, HornerosError, HornerosSSP, type HornerosSSPConfig, type InitiateConnectionParams, type McpDetail, type McpInfo, Mcps, NotFoundError, type ToolDefinition, type ToolResult, Tools, ValidationError };
|
|
196
|
+
export { type ApiError, type ApiResponse, AuthScheme, type ConnectionData, type ConnectionInfo, ConnectionRequest, type ConnectionRequestData, ConnectionTimeoutError, Connections, type ExecuteToolParams, HORNEROS_SDK_ERROR_CODES, HornerosError, HornerosSSP, type HornerosSSPConfig, type InitiateConnectionParams, type McpDetail, type McpInfo, Mcps, NotFoundError, type ToolDefinition, type ToolResult, Tools, ValidationError };
|
package/dist/index.d.ts
CHANGED
|
@@ -66,7 +66,12 @@ interface ConnectionData {
|
|
|
66
66
|
data: Record<string, string>;
|
|
67
67
|
}
|
|
68
68
|
interface HornerosSSPConfig {
|
|
69
|
-
|
|
69
|
+
/** API key for authentication. Falls back to HORNEROS_API_KEY env var. */
|
|
70
|
+
apiKey?: string;
|
|
71
|
+
/** Base URL of the HornerosSSP server. Falls back to HORNEROS_BASE_URL env var. */
|
|
72
|
+
baseUrl?: string;
|
|
73
|
+
/** Runtime identifier sent with every request (e.g. "node", "vercel"). */
|
|
74
|
+
runtime?: string;
|
|
70
75
|
}
|
|
71
76
|
interface ApiResponse<T> {
|
|
72
77
|
data: T;
|
|
@@ -119,7 +124,9 @@ declare class HornerosSSP {
|
|
|
119
124
|
readonly connections: Connections;
|
|
120
125
|
readonly tools: Tools;
|
|
121
126
|
private readonly baseUrl;
|
|
122
|
-
|
|
127
|
+
private readonly apiKey;
|
|
128
|
+
private readonly runtime;
|
|
129
|
+
constructor(config?: HornerosSSPConfig);
|
|
123
130
|
/** @internal */
|
|
124
131
|
fetch<T>(path: string, options?: RequestInit): Promise<T>;
|
|
125
132
|
}
|
|
@@ -143,10 +150,38 @@ declare class AuthScheme {
|
|
|
143
150
|
static GoogleLogin(): ConnectionData;
|
|
144
151
|
}
|
|
145
152
|
|
|
153
|
+
declare const HORNEROS_SDK_ERROR_CODES: {
|
|
154
|
+
readonly BACKEND: {
|
|
155
|
+
readonly NOT_FOUND: "BACKEND::NOT_FOUND";
|
|
156
|
+
readonly RATE_LIMIT: "BACKEND::RATE_LIMIT";
|
|
157
|
+
readonly BAD_REQUEST: "BACKEND::BAD_REQUEST";
|
|
158
|
+
readonly UNAUTHORIZED: "BACKEND::UNAUTHORIZED";
|
|
159
|
+
readonly SERVER_ERROR: "BACKEND::SERVER_ERROR";
|
|
160
|
+
readonly SERVER_UNAVAILABLE: "BACKEND::SERVER_UNAVAILABLE";
|
|
161
|
+
readonly UNKNOWN: "BACKEND::UNKNOWN";
|
|
162
|
+
};
|
|
163
|
+
readonly COMMON: {
|
|
164
|
+
readonly API_KEY_UNAVAILABLE: "COMMON::API_KEY_UNAVAILABLE";
|
|
165
|
+
readonly BASE_URL_NOT_REACHABLE: "COMMON::BASE_URL_NOT_REACHABLE";
|
|
166
|
+
readonly UNKNOWN: "COMMON::UNKNOWN";
|
|
167
|
+
readonly INVALID_PARAMS: "COMMON::INVALID_PARAMS";
|
|
168
|
+
};
|
|
169
|
+
readonly SDK: {
|
|
170
|
+
readonly NO_CONNECTED_ACCOUNT: "SDK::NO_CONNECTED_ACCOUNT";
|
|
171
|
+
readonly CONNECTION_TIMEOUT: "SDK::CONNECTION_TIMEOUT";
|
|
172
|
+
readonly INVALID_PARAMETER: "SDK::INVALID_PARAMETER";
|
|
173
|
+
};
|
|
174
|
+
};
|
|
146
175
|
declare class HornerosError extends Error {
|
|
176
|
+
readonly errCode: string;
|
|
147
177
|
readonly statusCode: number;
|
|
148
178
|
readonly body: unknown;
|
|
149
|
-
|
|
179
|
+
readonly description?: string;
|
|
180
|
+
readonly possibleFix?: string;
|
|
181
|
+
readonly errorId: string;
|
|
182
|
+
readonly timestamp: string;
|
|
183
|
+
constructor(errCode: string, message: string, statusCode: number, body?: unknown, description?: string, possibleFix?: string);
|
|
184
|
+
toJSON(): Record<string, unknown>;
|
|
150
185
|
}
|
|
151
186
|
declare class NotFoundError extends HornerosError {
|
|
152
187
|
constructor(message: string, body?: unknown);
|
|
@@ -158,4 +193,4 @@ declare class ConnectionTimeoutError extends HornerosError {
|
|
|
158
193
|
constructor(message?: string);
|
|
159
194
|
}
|
|
160
195
|
|
|
161
|
-
export { type ApiError, type ApiResponse, AuthScheme, type ConnectionData, type ConnectionInfo, ConnectionRequest, type ConnectionRequestData, ConnectionTimeoutError, Connections, type ExecuteToolParams, HornerosError, HornerosSSP, type HornerosSSPConfig, type InitiateConnectionParams, type McpDetail, type McpInfo, Mcps, NotFoundError, type ToolDefinition, type ToolResult, Tools, ValidationError };
|
|
196
|
+
export { type ApiError, type ApiResponse, AuthScheme, type ConnectionData, type ConnectionInfo, ConnectionRequest, type ConnectionRequestData, ConnectionTimeoutError, Connections, type ExecuteToolParams, HORNEROS_SDK_ERROR_CODES, HornerosError, HornerosSSP, type HornerosSSPConfig, type InitiateConnectionParams, type McpDetail, type McpInfo, Mcps, NotFoundError, type ToolDefinition, type ToolResult, Tools, ValidationError };
|
package/dist/index.js
CHANGED
|
@@ -24,6 +24,7 @@ __export(index_exports, {
|
|
|
24
24
|
ConnectionRequest: () => ConnectionRequest,
|
|
25
25
|
ConnectionTimeoutError: () => ConnectionTimeoutError,
|
|
26
26
|
Connections: () => Connections,
|
|
27
|
+
HORNEROS_SDK_ERROR_CODES: () => HORNEROS_SDK_ERROR_CODES,
|
|
27
28
|
HornerosError: () => HornerosError,
|
|
28
29
|
HornerosSSP: () => HornerosSSP,
|
|
29
30
|
Mcps: () => Mcps,
|
|
@@ -34,29 +35,77 @@ __export(index_exports, {
|
|
|
34
35
|
module.exports = __toCommonJS(index_exports);
|
|
35
36
|
|
|
36
37
|
// src/errors.ts
|
|
38
|
+
var HORNEROS_SDK_ERROR_CODES = {
|
|
39
|
+
BACKEND: {
|
|
40
|
+
NOT_FOUND: "BACKEND::NOT_FOUND",
|
|
41
|
+
RATE_LIMIT: "BACKEND::RATE_LIMIT",
|
|
42
|
+
BAD_REQUEST: "BACKEND::BAD_REQUEST",
|
|
43
|
+
UNAUTHORIZED: "BACKEND::UNAUTHORIZED",
|
|
44
|
+
SERVER_ERROR: "BACKEND::SERVER_ERROR",
|
|
45
|
+
SERVER_UNAVAILABLE: "BACKEND::SERVER_UNAVAILABLE",
|
|
46
|
+
UNKNOWN: "BACKEND::UNKNOWN"
|
|
47
|
+
},
|
|
48
|
+
COMMON: {
|
|
49
|
+
API_KEY_UNAVAILABLE: "COMMON::API_KEY_UNAVAILABLE",
|
|
50
|
+
BASE_URL_NOT_REACHABLE: "COMMON::BASE_URL_NOT_REACHABLE",
|
|
51
|
+
UNKNOWN: "COMMON::UNKNOWN",
|
|
52
|
+
INVALID_PARAMS: "COMMON::INVALID_PARAMS"
|
|
53
|
+
},
|
|
54
|
+
SDK: {
|
|
55
|
+
NO_CONNECTED_ACCOUNT: "SDK::NO_CONNECTED_ACCOUNT",
|
|
56
|
+
CONNECTION_TIMEOUT: "SDK::CONNECTION_TIMEOUT",
|
|
57
|
+
INVALID_PARAMETER: "SDK::INVALID_PARAMETER"
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
var errorCounter = 0;
|
|
37
61
|
var HornerosError = class extends Error {
|
|
38
|
-
constructor(message, statusCode, body) {
|
|
62
|
+
constructor(errCode, message, statusCode, body, description, possibleFix) {
|
|
39
63
|
super(message);
|
|
40
64
|
this.name = "HornerosError";
|
|
65
|
+
this.errCode = errCode;
|
|
41
66
|
this.statusCode = statusCode;
|
|
42
67
|
this.body = body;
|
|
68
|
+
this.description = description;
|
|
69
|
+
this.possibleFix = possibleFix;
|
|
70
|
+
this.errorId = `horneros_${Date.now()}_${++errorCounter}`;
|
|
71
|
+
this.timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
72
|
+
}
|
|
73
|
+
toJSON() {
|
|
74
|
+
return {
|
|
75
|
+
name: this.name,
|
|
76
|
+
errCode: this.errCode,
|
|
77
|
+
message: this.message,
|
|
78
|
+
statusCode: this.statusCode,
|
|
79
|
+
description: this.description,
|
|
80
|
+
possibleFix: this.possibleFix,
|
|
81
|
+
errorId: this.errorId,
|
|
82
|
+
timestamp: this.timestamp,
|
|
83
|
+
body: this.body
|
|
84
|
+
};
|
|
43
85
|
}
|
|
44
86
|
};
|
|
45
87
|
var NotFoundError = class extends HornerosError {
|
|
46
88
|
constructor(message, body) {
|
|
47
|
-
super(message, 404, body);
|
|
89
|
+
super(HORNEROS_SDK_ERROR_CODES.BACKEND.NOT_FOUND, message, 404, body);
|
|
48
90
|
this.name = "NotFoundError";
|
|
49
91
|
}
|
|
50
92
|
};
|
|
51
93
|
var ValidationError = class extends HornerosError {
|
|
52
94
|
constructor(message, body) {
|
|
53
|
-
super(message, 400, body);
|
|
95
|
+
super(HORNEROS_SDK_ERROR_CODES.BACKEND.BAD_REQUEST, message, 400, body);
|
|
54
96
|
this.name = "ValidationError";
|
|
55
97
|
}
|
|
56
98
|
};
|
|
57
99
|
var ConnectionTimeoutError = class extends HornerosError {
|
|
58
100
|
constructor(message = "Connection timed out waiting for activation") {
|
|
59
|
-
super(
|
|
101
|
+
super(
|
|
102
|
+
HORNEROS_SDK_ERROR_CODES.SDK.CONNECTION_TIMEOUT,
|
|
103
|
+
message,
|
|
104
|
+
408,
|
|
105
|
+
void 0,
|
|
106
|
+
"The connection did not become active within the timeout period.",
|
|
107
|
+
"Increase the timeout value or check that the user completed the authentication flow."
|
|
108
|
+
);
|
|
60
109
|
this.name = "ConnectionTimeoutError";
|
|
61
110
|
}
|
|
62
111
|
};
|
|
@@ -186,9 +235,35 @@ var Tools = class {
|
|
|
186
235
|
};
|
|
187
236
|
|
|
188
237
|
// src/client.ts
|
|
238
|
+
function getEnvVariable(name) {
|
|
239
|
+
if (typeof process !== "undefined" && process.env) {
|
|
240
|
+
return process.env[name];
|
|
241
|
+
}
|
|
242
|
+
return void 0;
|
|
243
|
+
}
|
|
244
|
+
var DEFAULT_BASE_URL = "http://localhost:3000";
|
|
245
|
+
function resolveConfig(config) {
|
|
246
|
+
const baseUrl = config?.baseUrl || getEnvVariable("HORNEROS_BASE_URL") || DEFAULT_BASE_URL;
|
|
247
|
+
const apiKey = config?.apiKey || getEnvVariable("HORNEROS_API_KEY") || "";
|
|
248
|
+
const runtime = config?.runtime || getEnvVariable("HORNEROS_RUNTIME") || "";
|
|
249
|
+
return { baseUrl: baseUrl.replace(/\/+$/, ""), apiKey, runtime };
|
|
250
|
+
}
|
|
189
251
|
var HornerosSSP = class {
|
|
190
252
|
constructor(config) {
|
|
191
|
-
|
|
253
|
+
const resolved = resolveConfig(config);
|
|
254
|
+
if (!resolved.apiKey) {
|
|
255
|
+
throw new HornerosError(
|
|
256
|
+
HORNEROS_SDK_ERROR_CODES.COMMON.API_KEY_UNAVAILABLE,
|
|
257
|
+
"\u{1F511} API Key is not provided",
|
|
258
|
+
401,
|
|
259
|
+
void 0,
|
|
260
|
+
"You need to provide an API key in the constructor or as the environment variable HORNEROS_API_KEY.",
|
|
261
|
+
'Provide a valid API key: new HornerosSSP({ apiKey: "hsp_xxx" }) or set HORNEROS_API_KEY in your environment.'
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
this.baseUrl = resolved.baseUrl;
|
|
265
|
+
this.apiKey = resolved.apiKey;
|
|
266
|
+
this.runtime = resolved.runtime;
|
|
192
267
|
this.mcps = new Mcps(this);
|
|
193
268
|
this.connections = new Connections(this);
|
|
194
269
|
this.tools = new Tools(this);
|
|
@@ -198,6 +273,9 @@ var HornerosSSP = class {
|
|
|
198
273
|
const url = `${this.baseUrl}/api/v1${path}`;
|
|
199
274
|
const headers = {
|
|
200
275
|
"Content-Type": "application/json",
|
|
276
|
+
"X-Api-Key": this.apiKey,
|
|
277
|
+
"X-Source": "js_sdk",
|
|
278
|
+
"X-Runtime": this.runtime,
|
|
201
279
|
...options.headers
|
|
202
280
|
};
|
|
203
281
|
const res = await globalThis.fetch(url, {
|
|
@@ -212,7 +290,8 @@ var HornerosSSP = class {
|
|
|
212
290
|
body = await res.text().catch(() => null);
|
|
213
291
|
}
|
|
214
292
|
const message = (body && typeof body === "object" && "error" in body ? body.error : null) || `HTTP ${res.status}`;
|
|
215
|
-
|
|
293
|
+
const errCode = res.status === 404 ? HORNEROS_SDK_ERROR_CODES.BACKEND.NOT_FOUND : res.status === 401 ? HORNEROS_SDK_ERROR_CODES.BACKEND.UNAUTHORIZED : res.status === 429 ? HORNEROS_SDK_ERROR_CODES.BACKEND.RATE_LIMIT : res.status === 400 ? HORNEROS_SDK_ERROR_CODES.BACKEND.BAD_REQUEST : res.status >= 500 ? HORNEROS_SDK_ERROR_CODES.BACKEND.SERVER_ERROR : HORNEROS_SDK_ERROR_CODES.BACKEND.UNKNOWN;
|
|
294
|
+
throw new HornerosError(errCode, message, res.status, body);
|
|
216
295
|
}
|
|
217
296
|
if (res.status === 204) {
|
|
218
297
|
return void 0;
|
|
@@ -248,6 +327,7 @@ var AuthScheme = class {
|
|
|
248
327
|
ConnectionRequest,
|
|
249
328
|
ConnectionTimeoutError,
|
|
250
329
|
Connections,
|
|
330
|
+
HORNEROS_SDK_ERROR_CODES,
|
|
251
331
|
HornerosError,
|
|
252
332
|
HornerosSSP,
|
|
253
333
|
Mcps,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/mcps.ts","../src/connections.ts","../src/tools.ts","../src/client.ts","../src/auth-scheme.ts"],"sourcesContent":["export { HornerosSSP } from \"./client\";\nexport { AuthScheme } from \"./auth-scheme\";\nexport { Mcps } from \"./mcps\";\nexport { Connections, ConnectionRequest } from \"./connections\";\nexport { Tools } from \"./tools\";\n\n// Errors\nexport {\n HornerosError,\n NotFoundError,\n ValidationError,\n ConnectionTimeoutError,\n} from \"./errors\";\n\n// Types\nexport type {\n HornerosSSPConfig,\n McpInfo,\n McpDetail,\n ConnectionInfo,\n ConnectionRequestData,\n InitiateConnectionParams,\n ToolDefinition,\n ToolResult,\n ExecuteToolParams,\n ConnectionData,\n ApiResponse,\n ApiError,\n} from \"./types\";\n","export class HornerosError extends Error {\n public readonly statusCode: number;\n public readonly body: unknown;\n\n constructor(message: string, statusCode: number, body?: unknown) {\n super(message);\n this.name = \"HornerosError\";\n this.statusCode = statusCode;\n this.body = body;\n }\n}\n\nexport class NotFoundError extends HornerosError {\n constructor(message: string, body?: unknown) {\n super(message, 404, body);\n this.name = \"NotFoundError\";\n }\n}\n\nexport class ValidationError extends HornerosError {\n constructor(message: string, body?: unknown) {\n super(message, 400, body);\n this.name = \"ValidationError\";\n }\n}\n\nexport class ConnectionTimeoutError extends HornerosError {\n constructor(message = \"Connection timed out waiting for activation\") {\n super(message, 408);\n this.name = \"ConnectionTimeoutError\";\n }\n}\n","import type { HornerosSSP } from \"./client\";\nimport type { McpInfo, McpDetail, ApiResponse } from \"./types\";\n\nexport class Mcps {\n constructor(private client: HornerosSSP) {}\n\n async list(): Promise<McpInfo[]> {\n const res = await this.client.fetch<ApiResponse<McpInfo[]>>(\"/mcps\");\n return res.data;\n }\n\n async get(slug: string): Promise<McpDetail> {\n const res = await this.client.fetch<ApiResponse<McpDetail>>(\n `/mcps/${encodeURIComponent(slug)}`\n );\n return res.data;\n }\n}\n","import type { HornerosSSP } from \"./client\";\nimport type {\n ConnectionInfo,\n ConnectionRequestData,\n InitiateConnectionParams,\n ApiResponse,\n} from \"./types\";\nimport { ConnectionTimeoutError } from \"./errors\";\n\nexport class ConnectionRequest {\n public readonly id: string;\n public readonly mcpUrl: string | null;\n public readonly token: string | null;\n public readonly redirectUrl: string | null;\n public readonly status: \"active\" | \"pending\";\n\n constructor(\n private client: HornerosSSP,\n data: ConnectionRequestData\n ) {\n this.id = data.id;\n this.mcpUrl = data.mcpUrl;\n this.token = data.token;\n this.redirectUrl = data.redirectUrl;\n this.status = data.status;\n }\n\n /**\n * Polls the connection until it becomes active.\n * Useful for OAuth/interactive flows where the user needs to\n * complete authentication in a browser.\n * @param timeout Max wait time in ms (default: 120000 = 2 min)\n */\n async waitForConnection(timeout = 120_000): Promise<ConnectionInfo> {\n if (this.status === \"active\") {\n const res = await this.client.fetch<ApiResponse<ConnectionInfo>>(\n `/connections/${encodeURIComponent(this.id)}`\n );\n return res.data;\n }\n\n const start = Date.now();\n const interval = 2000;\n\n while (Date.now() - start < timeout) {\n await sleep(interval);\n try {\n const res = await this.client.fetch<ApiResponse<ConnectionInfo>>(\n `/connections/${encodeURIComponent(this.id)}`\n );\n if (res.data.status === \"active\") {\n return res.data;\n }\n } catch {\n // Connection not yet created, keep polling\n }\n }\n\n throw new ConnectionTimeoutError();\n }\n}\n\nexport class Connections {\n constructor(private client: HornerosSSP) {}\n\n async initiate(params: InitiateConnectionParams): Promise<ConnectionRequest> {\n const body: Record<string, unknown> = {\n mcp_slug: params.mcpSlug,\n };\n\n if (params.appName) body.app_name = params.appName;\n if (params.userId) body.user_id = params.userId;\n if (params.credentials) body.credentials = params.credentials;\n if (params.authScheme) body.auth_scheme = params.authScheme;\n\n const res = await this.client.fetch<ApiResponse<ConnectionRequestData>>(\n \"/connections\",\n { method: \"POST\", body: JSON.stringify(body) }\n );\n\n return new ConnectionRequest(this.client, res.data);\n }\n\n async list(): Promise<ConnectionInfo[]> {\n const res =\n await this.client.fetch<ApiResponse<ConnectionInfo[]>>(\"/connections\");\n return res.data;\n }\n\n async get(id: string): Promise<ConnectionInfo> {\n const res = await this.client.fetch<ApiResponse<ConnectionInfo>>(\n `/connections/${encodeURIComponent(id)}`\n );\n return res.data;\n }\n\n async revoke(id: string): Promise<void> {\n await this.client.fetch<void>(\n `/connections/${encodeURIComponent(id)}`,\n { method: \"DELETE\" }\n );\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import type { HornerosSSP } from \"./client\";\nimport type {\n ToolDefinition,\n ToolResult,\n ExecuteToolParams,\n ApiResponse,\n} from \"./types\";\n\nexport class Tools {\n constructor(private client: HornerosSSP) {}\n\n async list(mcpSlug: string): Promise<ToolDefinition[]> {\n const res = await this.client.fetch<ApiResponse<ToolDefinition[]>>(\n `/mcps/${encodeURIComponent(mcpSlug)}/tools`\n );\n return res.data;\n }\n\n async execute(params: ExecuteToolParams): Promise<ToolResult> {\n const res = await this.client.fetch<ApiResponse<ToolResult>>(\n \"/tools/execute\",\n {\n method: \"POST\",\n body: JSON.stringify({\n mcp_slug: params.mcpSlug,\n connection_id: params.connectionId,\n tool_name: params.toolName,\n arguments: params.arguments,\n }),\n }\n );\n return res.data;\n }\n}\n","import type { HornerosSSPConfig } from \"./types\";\nimport { HornerosError } from \"./errors\";\nimport { Mcps } from \"./mcps\";\nimport { Connections } from \"./connections\";\nimport { Tools } from \"./tools\";\n\nexport class HornerosSSP {\n public readonly mcps: Mcps;\n public readonly connections: Connections;\n public readonly tools: Tools;\n\n private readonly baseUrl: string;\n\n constructor(config: HornerosSSPConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/+$/, \"\");\n\n this.mcps = new Mcps(this);\n this.connections = new Connections(this);\n this.tools = new Tools(this);\n }\n\n /** @internal */\n async fetch<T>(\n path: string,\n options: RequestInit = {}\n ): Promise<T> {\n const url = `${this.baseUrl}/api/v1${path}`;\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...(options.headers as Record<string, string>),\n };\n\n const res = await globalThis.fetch(url, {\n ...options,\n headers,\n });\n\n if (!res.ok) {\n let body: unknown;\n try {\n body = await res.json();\n } catch {\n body = await res.text().catch(() => null);\n }\n const message =\n (body && typeof body === \"object\" && \"error\" in body\n ? (body as { error: string }).error\n : null) || `HTTP ${res.status}`;\n throw new HornerosError(message, res.status, body);\n }\n\n if (res.status === 204) {\n return undefined as T;\n }\n\n return res.json() as Promise<T>;\n }\n}\n","import type { ConnectionData } from \"./types\";\n\nexport class AuthScheme {\n static APIKey(params: { api_key: string; [k: string]: string }): ConnectionData {\n return { type: \"api_key\", data: params };\n }\n\n static Bearer(params: { token: string }): ConnectionData {\n return { type: \"bearer\", data: params };\n }\n\n static Basic(params: { username: string; password: string }): ConnectionData {\n return { type: \"basic\", data: params };\n }\n\n static OAuth2(params: {\n access_token: string;\n refresh_token?: string;\n }): ConnectionData {\n return {\n type: \"oauth2\",\n data: params as Record<string, string>,\n };\n }\n\n static GoogleLogin(): ConnectionData {\n return { type: \"google_login\", data: {} };\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/mcps.ts","../src/connections.ts","../src/tools.ts","../src/client.ts","../src/auth-scheme.ts"],"sourcesContent":["export { HornerosSSP } from \"./client\";\nexport { AuthScheme } from \"./auth-scheme\";\nexport { Mcps } from \"./mcps\";\nexport { Connections, ConnectionRequest } from \"./connections\";\nexport { Tools } from \"./tools\";\n\n// Errors\nexport {\n HornerosError,\n NotFoundError,\n ValidationError,\n ConnectionTimeoutError,\n HORNEROS_SDK_ERROR_CODES,\n} from \"./errors\";\n\n// Types\nexport type {\n HornerosSSPConfig,\n McpInfo,\n McpDetail,\n ConnectionInfo,\n ConnectionRequestData,\n InitiateConnectionParams,\n ToolDefinition,\n ToolResult,\n ExecuteToolParams,\n ConnectionData,\n ApiResponse,\n ApiError,\n} from \"./types\";\n","// ── Error codes ─────────────────────────────────────────────\n\nexport const HORNEROS_SDK_ERROR_CODES = {\n BACKEND: {\n NOT_FOUND: \"BACKEND::NOT_FOUND\",\n RATE_LIMIT: \"BACKEND::RATE_LIMIT\",\n BAD_REQUEST: \"BACKEND::BAD_REQUEST\",\n UNAUTHORIZED: \"BACKEND::UNAUTHORIZED\",\n SERVER_ERROR: \"BACKEND::SERVER_ERROR\",\n SERVER_UNAVAILABLE: \"BACKEND::SERVER_UNAVAILABLE\",\n UNKNOWN: \"BACKEND::UNKNOWN\",\n },\n COMMON: {\n API_KEY_UNAVAILABLE: \"COMMON::API_KEY_UNAVAILABLE\",\n BASE_URL_NOT_REACHABLE: \"COMMON::BASE_URL_NOT_REACHABLE\",\n UNKNOWN: \"COMMON::UNKNOWN\",\n INVALID_PARAMS: \"COMMON::INVALID_PARAMS\",\n },\n SDK: {\n NO_CONNECTED_ACCOUNT: \"SDK::NO_CONNECTED_ACCOUNT\",\n CONNECTION_TIMEOUT: \"SDK::CONNECTION_TIMEOUT\",\n INVALID_PARAMETER: \"SDK::INVALID_PARAMETER\",\n },\n} as const;\n\n// ── Base error ──────────────────────────────────────────────\n\nlet errorCounter = 0;\n\nexport class HornerosError extends Error {\n public readonly errCode: string;\n public readonly statusCode: number;\n public readonly body: unknown;\n public readonly description?: string;\n public readonly possibleFix?: string;\n public readonly errorId: string;\n public readonly timestamp: string;\n\n constructor(\n errCode: string,\n message: string,\n statusCode: number,\n body?: unknown,\n description?: string,\n possibleFix?: string\n ) {\n super(message);\n this.name = \"HornerosError\";\n this.errCode = errCode;\n this.statusCode = statusCode;\n this.body = body;\n this.description = description;\n this.possibleFix = possibleFix;\n this.errorId = `horneros_${Date.now()}_${++errorCounter}`;\n this.timestamp = new Date().toISOString();\n }\n\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n errCode: this.errCode,\n message: this.message,\n statusCode: this.statusCode,\n description: this.description,\n possibleFix: this.possibleFix,\n errorId: this.errorId,\n timestamp: this.timestamp,\n body: this.body,\n };\n }\n}\n\n// ── Specialized errors ──────────────────────────────────────\n\nexport class NotFoundError extends HornerosError {\n constructor(message: string, body?: unknown) {\n super(HORNEROS_SDK_ERROR_CODES.BACKEND.NOT_FOUND, message, 404, body);\n this.name = \"NotFoundError\";\n }\n}\n\nexport class ValidationError extends HornerosError {\n constructor(message: string, body?: unknown) {\n super(HORNEROS_SDK_ERROR_CODES.BACKEND.BAD_REQUEST, message, 400, body);\n this.name = \"ValidationError\";\n }\n}\n\nexport class ConnectionTimeoutError extends HornerosError {\n constructor(message = \"Connection timed out waiting for activation\") {\n super(\n HORNEROS_SDK_ERROR_CODES.SDK.CONNECTION_TIMEOUT,\n message,\n 408,\n undefined,\n \"The connection did not become active within the timeout period.\",\n \"Increase the timeout value or check that the user completed the authentication flow.\"\n );\n this.name = \"ConnectionTimeoutError\";\n }\n}\n","import type { HornerosSSP } from \"./client\";\nimport type { McpInfo, McpDetail, ApiResponse } from \"./types\";\n\nexport class Mcps {\n constructor(private client: HornerosSSP) {}\n\n async list(): Promise<McpInfo[]> {\n const res = await this.client.fetch<ApiResponse<McpInfo[]>>(\"/mcps\");\n return res.data;\n }\n\n async get(slug: string): Promise<McpDetail> {\n const res = await this.client.fetch<ApiResponse<McpDetail>>(\n `/mcps/${encodeURIComponent(slug)}`\n );\n return res.data;\n }\n}\n","import type { HornerosSSP } from \"./client\";\nimport type {\n ConnectionInfo,\n ConnectionRequestData,\n InitiateConnectionParams,\n ApiResponse,\n} from \"./types\";\nimport { ConnectionTimeoutError } from \"./errors\";\n\nexport class ConnectionRequest {\n public readonly id: string;\n public readonly mcpUrl: string | null;\n public readonly token: string | null;\n public readonly redirectUrl: string | null;\n public readonly status: \"active\" | \"pending\";\n\n constructor(\n private client: HornerosSSP,\n data: ConnectionRequestData\n ) {\n this.id = data.id;\n this.mcpUrl = data.mcpUrl;\n this.token = data.token;\n this.redirectUrl = data.redirectUrl;\n this.status = data.status;\n }\n\n /**\n * Polls the connection until it becomes active.\n * Useful for OAuth/interactive flows where the user needs to\n * complete authentication in a browser.\n * @param timeout Max wait time in ms (default: 120000 = 2 min)\n */\n async waitForConnection(timeout = 120_000): Promise<ConnectionInfo> {\n if (this.status === \"active\") {\n const res = await this.client.fetch<ApiResponse<ConnectionInfo>>(\n `/connections/${encodeURIComponent(this.id)}`\n );\n return res.data;\n }\n\n const start = Date.now();\n const interval = 2000;\n\n while (Date.now() - start < timeout) {\n await sleep(interval);\n try {\n const res = await this.client.fetch<ApiResponse<ConnectionInfo>>(\n `/connections/${encodeURIComponent(this.id)}`\n );\n if (res.data.status === \"active\") {\n return res.data;\n }\n } catch {\n // Connection not yet created, keep polling\n }\n }\n\n throw new ConnectionTimeoutError();\n }\n}\n\nexport class Connections {\n constructor(private client: HornerosSSP) {}\n\n async initiate(params: InitiateConnectionParams): Promise<ConnectionRequest> {\n const body: Record<string, unknown> = {\n mcp_slug: params.mcpSlug,\n };\n\n if (params.appName) body.app_name = params.appName;\n if (params.userId) body.user_id = params.userId;\n if (params.credentials) body.credentials = params.credentials;\n if (params.authScheme) body.auth_scheme = params.authScheme;\n\n const res = await this.client.fetch<ApiResponse<ConnectionRequestData>>(\n \"/connections\",\n { method: \"POST\", body: JSON.stringify(body) }\n );\n\n return new ConnectionRequest(this.client, res.data);\n }\n\n async list(): Promise<ConnectionInfo[]> {\n const res =\n await this.client.fetch<ApiResponse<ConnectionInfo[]>>(\"/connections\");\n return res.data;\n }\n\n async get(id: string): Promise<ConnectionInfo> {\n const res = await this.client.fetch<ApiResponse<ConnectionInfo>>(\n `/connections/${encodeURIComponent(id)}`\n );\n return res.data;\n }\n\n async revoke(id: string): Promise<void> {\n await this.client.fetch<void>(\n `/connections/${encodeURIComponent(id)}`,\n { method: \"DELETE\" }\n );\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import type { HornerosSSP } from \"./client\";\nimport type {\n ToolDefinition,\n ToolResult,\n ExecuteToolParams,\n ApiResponse,\n} from \"./types\";\n\nexport class Tools {\n constructor(private client: HornerosSSP) {}\n\n async list(mcpSlug: string): Promise<ToolDefinition[]> {\n const res = await this.client.fetch<ApiResponse<ToolDefinition[]>>(\n `/mcps/${encodeURIComponent(mcpSlug)}/tools`\n );\n return res.data;\n }\n\n async execute(params: ExecuteToolParams): Promise<ToolResult> {\n const res = await this.client.fetch<ApiResponse<ToolResult>>(\n \"/tools/execute\",\n {\n method: \"POST\",\n body: JSON.stringify({\n mcp_slug: params.mcpSlug,\n connection_id: params.connectionId,\n tool_name: params.toolName,\n arguments: params.arguments,\n }),\n }\n );\n return res.data;\n }\n}\n","import type { HornerosSSPConfig } from \"./types\";\nimport { HornerosError, HORNEROS_SDK_ERROR_CODES } from \"./errors\";\nimport { Mcps } from \"./mcps\";\nimport { Connections } from \"./connections\";\nimport { Tools } from \"./tools\";\n\n// ── Helpers ─────────────────────────────────────────────────\n\nfunction getEnvVariable(name: string): string | undefined {\n if (typeof process !== \"undefined\" && process.env) {\n return process.env[name];\n }\n return undefined;\n}\n\nconst DEFAULT_BASE_URL = \"http://localhost:3000\";\n\nfunction resolveConfig(config?: HornerosSSPConfig) {\n const baseUrl =\n config?.baseUrl ||\n getEnvVariable(\"HORNEROS_BASE_URL\") ||\n DEFAULT_BASE_URL;\n\n const apiKey =\n config?.apiKey ||\n getEnvVariable(\"HORNEROS_API_KEY\") ||\n \"\";\n\n const runtime = config?.runtime || getEnvVariable(\"HORNEROS_RUNTIME\") || \"\";\n\n return { baseUrl: baseUrl.replace(/\\/+$/, \"\"), apiKey, runtime };\n}\n\n// ── Main client ─────────────────────────────────────────────\n\nexport class HornerosSSP {\n public readonly mcps: Mcps;\n public readonly connections: Connections;\n public readonly tools: Tools;\n\n private readonly baseUrl: string;\n private readonly apiKey: string;\n private readonly runtime: string;\n\n constructor(config?: HornerosSSPConfig) {\n const resolved = resolveConfig(config);\n\n if (!resolved.apiKey) {\n throw new HornerosError(\n HORNEROS_SDK_ERROR_CODES.COMMON.API_KEY_UNAVAILABLE,\n \"🔑 API Key is not provided\",\n 401,\n undefined,\n \"You need to provide an API key in the constructor or as the environment variable HORNEROS_API_KEY.\",\n 'Provide a valid API key: new HornerosSSP({ apiKey: \"hsp_xxx\" }) or set HORNEROS_API_KEY in your environment.'\n );\n }\n\n this.baseUrl = resolved.baseUrl;\n this.apiKey = resolved.apiKey;\n this.runtime = resolved.runtime;\n\n this.mcps = new Mcps(this);\n this.connections = new Connections(this);\n this.tools = new Tools(this);\n }\n\n /** @internal */\n async fetch<T>(\n path: string,\n options: RequestInit = {}\n ): Promise<T> {\n const url = `${this.baseUrl}/api/v1${path}`;\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"X-Api-Key\": this.apiKey,\n \"X-Source\": \"js_sdk\",\n \"X-Runtime\": this.runtime,\n ...(options.headers as Record<string, string>),\n };\n\n const res = await globalThis.fetch(url, {\n ...options,\n headers,\n });\n\n if (!res.ok) {\n let body: unknown;\n try {\n body = await res.json();\n } catch {\n body = await res.text().catch(() => null);\n }\n\n const message =\n (body && typeof body === \"object\" && \"error\" in body\n ? (body as { error: string }).error\n : null) || `HTTP ${res.status}`;\n\n const errCode =\n res.status === 404\n ? HORNEROS_SDK_ERROR_CODES.BACKEND.NOT_FOUND\n : res.status === 401\n ? HORNEROS_SDK_ERROR_CODES.BACKEND.UNAUTHORIZED\n : res.status === 429\n ? HORNEROS_SDK_ERROR_CODES.BACKEND.RATE_LIMIT\n : res.status === 400\n ? HORNEROS_SDK_ERROR_CODES.BACKEND.BAD_REQUEST\n : res.status >= 500\n ? HORNEROS_SDK_ERROR_CODES.BACKEND.SERVER_ERROR\n : HORNEROS_SDK_ERROR_CODES.BACKEND.UNKNOWN;\n\n throw new HornerosError(errCode, message, res.status, body);\n }\n\n if (res.status === 204) {\n return undefined as T;\n }\n\n return res.json() as Promise<T>;\n }\n}\n","import type { ConnectionData } from \"./types\";\n\nexport class AuthScheme {\n static APIKey(params: { api_key: string; [k: string]: string }): ConnectionData {\n return { type: \"api_key\", data: params };\n }\n\n static Bearer(params: { token: string }): ConnectionData {\n return { type: \"bearer\", data: params };\n }\n\n static Basic(params: { username: string; password: string }): ConnectionData {\n return { type: \"basic\", data: params };\n }\n\n static OAuth2(params: {\n access_token: string;\n refresh_token?: string;\n }): ConnectionData {\n return {\n type: \"oauth2\",\n data: params as Record<string, string>,\n };\n }\n\n static GoogleLogin(): ConnectionData {\n return { type: \"google_login\", data: {} };\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,27 +1,75 @@
|
|
|
1
1
|
// src/errors.ts
|
|
2
|
+
var HORNEROS_SDK_ERROR_CODES = {
|
|
3
|
+
BACKEND: {
|
|
4
|
+
NOT_FOUND: "BACKEND::NOT_FOUND",
|
|
5
|
+
RATE_LIMIT: "BACKEND::RATE_LIMIT",
|
|
6
|
+
BAD_REQUEST: "BACKEND::BAD_REQUEST",
|
|
7
|
+
UNAUTHORIZED: "BACKEND::UNAUTHORIZED",
|
|
8
|
+
SERVER_ERROR: "BACKEND::SERVER_ERROR",
|
|
9
|
+
SERVER_UNAVAILABLE: "BACKEND::SERVER_UNAVAILABLE",
|
|
10
|
+
UNKNOWN: "BACKEND::UNKNOWN"
|
|
11
|
+
},
|
|
12
|
+
COMMON: {
|
|
13
|
+
API_KEY_UNAVAILABLE: "COMMON::API_KEY_UNAVAILABLE",
|
|
14
|
+
BASE_URL_NOT_REACHABLE: "COMMON::BASE_URL_NOT_REACHABLE",
|
|
15
|
+
UNKNOWN: "COMMON::UNKNOWN",
|
|
16
|
+
INVALID_PARAMS: "COMMON::INVALID_PARAMS"
|
|
17
|
+
},
|
|
18
|
+
SDK: {
|
|
19
|
+
NO_CONNECTED_ACCOUNT: "SDK::NO_CONNECTED_ACCOUNT",
|
|
20
|
+
CONNECTION_TIMEOUT: "SDK::CONNECTION_TIMEOUT",
|
|
21
|
+
INVALID_PARAMETER: "SDK::INVALID_PARAMETER"
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
var errorCounter = 0;
|
|
2
25
|
var HornerosError = class extends Error {
|
|
3
|
-
constructor(message, statusCode, body) {
|
|
26
|
+
constructor(errCode, message, statusCode, body, description, possibleFix) {
|
|
4
27
|
super(message);
|
|
5
28
|
this.name = "HornerosError";
|
|
29
|
+
this.errCode = errCode;
|
|
6
30
|
this.statusCode = statusCode;
|
|
7
31
|
this.body = body;
|
|
32
|
+
this.description = description;
|
|
33
|
+
this.possibleFix = possibleFix;
|
|
34
|
+
this.errorId = `horneros_${Date.now()}_${++errorCounter}`;
|
|
35
|
+
this.timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
36
|
+
}
|
|
37
|
+
toJSON() {
|
|
38
|
+
return {
|
|
39
|
+
name: this.name,
|
|
40
|
+
errCode: this.errCode,
|
|
41
|
+
message: this.message,
|
|
42
|
+
statusCode: this.statusCode,
|
|
43
|
+
description: this.description,
|
|
44
|
+
possibleFix: this.possibleFix,
|
|
45
|
+
errorId: this.errorId,
|
|
46
|
+
timestamp: this.timestamp,
|
|
47
|
+
body: this.body
|
|
48
|
+
};
|
|
8
49
|
}
|
|
9
50
|
};
|
|
10
51
|
var NotFoundError = class extends HornerosError {
|
|
11
52
|
constructor(message, body) {
|
|
12
|
-
super(message, 404, body);
|
|
53
|
+
super(HORNEROS_SDK_ERROR_CODES.BACKEND.NOT_FOUND, message, 404, body);
|
|
13
54
|
this.name = "NotFoundError";
|
|
14
55
|
}
|
|
15
56
|
};
|
|
16
57
|
var ValidationError = class extends HornerosError {
|
|
17
58
|
constructor(message, body) {
|
|
18
|
-
super(message, 400, body);
|
|
59
|
+
super(HORNEROS_SDK_ERROR_CODES.BACKEND.BAD_REQUEST, message, 400, body);
|
|
19
60
|
this.name = "ValidationError";
|
|
20
61
|
}
|
|
21
62
|
};
|
|
22
63
|
var ConnectionTimeoutError = class extends HornerosError {
|
|
23
64
|
constructor(message = "Connection timed out waiting for activation") {
|
|
24
|
-
super(
|
|
65
|
+
super(
|
|
66
|
+
HORNEROS_SDK_ERROR_CODES.SDK.CONNECTION_TIMEOUT,
|
|
67
|
+
message,
|
|
68
|
+
408,
|
|
69
|
+
void 0,
|
|
70
|
+
"The connection did not become active within the timeout period.",
|
|
71
|
+
"Increase the timeout value or check that the user completed the authentication flow."
|
|
72
|
+
);
|
|
25
73
|
this.name = "ConnectionTimeoutError";
|
|
26
74
|
}
|
|
27
75
|
};
|
|
@@ -151,9 +199,35 @@ var Tools = class {
|
|
|
151
199
|
};
|
|
152
200
|
|
|
153
201
|
// src/client.ts
|
|
202
|
+
function getEnvVariable(name) {
|
|
203
|
+
if (typeof process !== "undefined" && process.env) {
|
|
204
|
+
return process.env[name];
|
|
205
|
+
}
|
|
206
|
+
return void 0;
|
|
207
|
+
}
|
|
208
|
+
var DEFAULT_BASE_URL = "http://localhost:3000";
|
|
209
|
+
function resolveConfig(config) {
|
|
210
|
+
const baseUrl = config?.baseUrl || getEnvVariable("HORNEROS_BASE_URL") || DEFAULT_BASE_URL;
|
|
211
|
+
const apiKey = config?.apiKey || getEnvVariable("HORNEROS_API_KEY") || "";
|
|
212
|
+
const runtime = config?.runtime || getEnvVariable("HORNEROS_RUNTIME") || "";
|
|
213
|
+
return { baseUrl: baseUrl.replace(/\/+$/, ""), apiKey, runtime };
|
|
214
|
+
}
|
|
154
215
|
var HornerosSSP = class {
|
|
155
216
|
constructor(config) {
|
|
156
|
-
|
|
217
|
+
const resolved = resolveConfig(config);
|
|
218
|
+
if (!resolved.apiKey) {
|
|
219
|
+
throw new HornerosError(
|
|
220
|
+
HORNEROS_SDK_ERROR_CODES.COMMON.API_KEY_UNAVAILABLE,
|
|
221
|
+
"\u{1F511} API Key is not provided",
|
|
222
|
+
401,
|
|
223
|
+
void 0,
|
|
224
|
+
"You need to provide an API key in the constructor or as the environment variable HORNEROS_API_KEY.",
|
|
225
|
+
'Provide a valid API key: new HornerosSSP({ apiKey: "hsp_xxx" }) or set HORNEROS_API_KEY in your environment.'
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
this.baseUrl = resolved.baseUrl;
|
|
229
|
+
this.apiKey = resolved.apiKey;
|
|
230
|
+
this.runtime = resolved.runtime;
|
|
157
231
|
this.mcps = new Mcps(this);
|
|
158
232
|
this.connections = new Connections(this);
|
|
159
233
|
this.tools = new Tools(this);
|
|
@@ -163,6 +237,9 @@ var HornerosSSP = class {
|
|
|
163
237
|
const url = `${this.baseUrl}/api/v1${path}`;
|
|
164
238
|
const headers = {
|
|
165
239
|
"Content-Type": "application/json",
|
|
240
|
+
"X-Api-Key": this.apiKey,
|
|
241
|
+
"X-Source": "js_sdk",
|
|
242
|
+
"X-Runtime": this.runtime,
|
|
166
243
|
...options.headers
|
|
167
244
|
};
|
|
168
245
|
const res = await globalThis.fetch(url, {
|
|
@@ -177,7 +254,8 @@ var HornerosSSP = class {
|
|
|
177
254
|
body = await res.text().catch(() => null);
|
|
178
255
|
}
|
|
179
256
|
const message = (body && typeof body === "object" && "error" in body ? body.error : null) || `HTTP ${res.status}`;
|
|
180
|
-
|
|
257
|
+
const errCode = res.status === 404 ? HORNEROS_SDK_ERROR_CODES.BACKEND.NOT_FOUND : res.status === 401 ? HORNEROS_SDK_ERROR_CODES.BACKEND.UNAUTHORIZED : res.status === 429 ? HORNEROS_SDK_ERROR_CODES.BACKEND.RATE_LIMIT : res.status === 400 ? HORNEROS_SDK_ERROR_CODES.BACKEND.BAD_REQUEST : res.status >= 500 ? HORNEROS_SDK_ERROR_CODES.BACKEND.SERVER_ERROR : HORNEROS_SDK_ERROR_CODES.BACKEND.UNKNOWN;
|
|
258
|
+
throw new HornerosError(errCode, message, res.status, body);
|
|
181
259
|
}
|
|
182
260
|
if (res.status === 204) {
|
|
183
261
|
return void 0;
|
|
@@ -212,6 +290,7 @@ export {
|
|
|
212
290
|
ConnectionRequest,
|
|
213
291
|
ConnectionTimeoutError,
|
|
214
292
|
Connections,
|
|
293
|
+
HORNEROS_SDK_ERROR_CODES,
|
|
215
294
|
HornerosError,
|
|
216
295
|
HornerosSSP,
|
|
217
296
|
Mcps,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/mcps.ts","../src/connections.ts","../src/tools.ts","../src/client.ts","../src/auth-scheme.ts"],"sourcesContent":["export class HornerosError extends Error {\n public readonly statusCode: number;\n public readonly body: unknown;\n\n constructor(message: string, statusCode: number, body?: unknown) {\n super(message);\n this.name = \"HornerosError\";\n this.statusCode = statusCode;\n this.body = body;\n }\n}\n\nexport class NotFoundError extends HornerosError {\n constructor(message: string, body?: unknown) {\n super(message, 404, body);\n this.name = \"NotFoundError\";\n }\n}\n\nexport class ValidationError extends HornerosError {\n constructor(message: string, body?: unknown) {\n super(message, 400, body);\n this.name = \"ValidationError\";\n }\n}\n\nexport class ConnectionTimeoutError extends HornerosError {\n constructor(message = \"Connection timed out waiting for activation\") {\n super(message, 408);\n this.name = \"ConnectionTimeoutError\";\n }\n}\n","import type { HornerosSSP } from \"./client\";\nimport type { McpInfo, McpDetail, ApiResponse } from \"./types\";\n\nexport class Mcps {\n constructor(private client: HornerosSSP) {}\n\n async list(): Promise<McpInfo[]> {\n const res = await this.client.fetch<ApiResponse<McpInfo[]>>(\"/mcps\");\n return res.data;\n }\n\n async get(slug: string): Promise<McpDetail> {\n const res = await this.client.fetch<ApiResponse<McpDetail>>(\n `/mcps/${encodeURIComponent(slug)}`\n );\n return res.data;\n }\n}\n","import type { HornerosSSP } from \"./client\";\nimport type {\n ConnectionInfo,\n ConnectionRequestData,\n InitiateConnectionParams,\n ApiResponse,\n} from \"./types\";\nimport { ConnectionTimeoutError } from \"./errors\";\n\nexport class ConnectionRequest {\n public readonly id: string;\n public readonly mcpUrl: string | null;\n public readonly token: string | null;\n public readonly redirectUrl: string | null;\n public readonly status: \"active\" | \"pending\";\n\n constructor(\n private client: HornerosSSP,\n data: ConnectionRequestData\n ) {\n this.id = data.id;\n this.mcpUrl = data.mcpUrl;\n this.token = data.token;\n this.redirectUrl = data.redirectUrl;\n this.status = data.status;\n }\n\n /**\n * Polls the connection until it becomes active.\n * Useful for OAuth/interactive flows where the user needs to\n * complete authentication in a browser.\n * @param timeout Max wait time in ms (default: 120000 = 2 min)\n */\n async waitForConnection(timeout = 120_000): Promise<ConnectionInfo> {\n if (this.status === \"active\") {\n const res = await this.client.fetch<ApiResponse<ConnectionInfo>>(\n `/connections/${encodeURIComponent(this.id)}`\n );\n return res.data;\n }\n\n const start = Date.now();\n const interval = 2000;\n\n while (Date.now() - start < timeout) {\n await sleep(interval);\n try {\n const res = await this.client.fetch<ApiResponse<ConnectionInfo>>(\n `/connections/${encodeURIComponent(this.id)}`\n );\n if (res.data.status === \"active\") {\n return res.data;\n }\n } catch {\n // Connection not yet created, keep polling\n }\n }\n\n throw new ConnectionTimeoutError();\n }\n}\n\nexport class Connections {\n constructor(private client: HornerosSSP) {}\n\n async initiate(params: InitiateConnectionParams): Promise<ConnectionRequest> {\n const body: Record<string, unknown> = {\n mcp_slug: params.mcpSlug,\n };\n\n if (params.appName) body.app_name = params.appName;\n if (params.userId) body.user_id = params.userId;\n if (params.credentials) body.credentials = params.credentials;\n if (params.authScheme) body.auth_scheme = params.authScheme;\n\n const res = await this.client.fetch<ApiResponse<ConnectionRequestData>>(\n \"/connections\",\n { method: \"POST\", body: JSON.stringify(body) }\n );\n\n return new ConnectionRequest(this.client, res.data);\n }\n\n async list(): Promise<ConnectionInfo[]> {\n const res =\n await this.client.fetch<ApiResponse<ConnectionInfo[]>>(\"/connections\");\n return res.data;\n }\n\n async get(id: string): Promise<ConnectionInfo> {\n const res = await this.client.fetch<ApiResponse<ConnectionInfo>>(\n `/connections/${encodeURIComponent(id)}`\n );\n return res.data;\n }\n\n async revoke(id: string): Promise<void> {\n await this.client.fetch<void>(\n `/connections/${encodeURIComponent(id)}`,\n { method: \"DELETE\" }\n );\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import type { HornerosSSP } from \"./client\";\nimport type {\n ToolDefinition,\n ToolResult,\n ExecuteToolParams,\n ApiResponse,\n} from \"./types\";\n\nexport class Tools {\n constructor(private client: HornerosSSP) {}\n\n async list(mcpSlug: string): Promise<ToolDefinition[]> {\n const res = await this.client.fetch<ApiResponse<ToolDefinition[]>>(\n `/mcps/${encodeURIComponent(mcpSlug)}/tools`\n );\n return res.data;\n }\n\n async execute(params: ExecuteToolParams): Promise<ToolResult> {\n const res = await this.client.fetch<ApiResponse<ToolResult>>(\n \"/tools/execute\",\n {\n method: \"POST\",\n body: JSON.stringify({\n mcp_slug: params.mcpSlug,\n connection_id: params.connectionId,\n tool_name: params.toolName,\n arguments: params.arguments,\n }),\n }\n );\n return res.data;\n }\n}\n","import type { HornerosSSPConfig } from \"./types\";\nimport { HornerosError } from \"./errors\";\nimport { Mcps } from \"./mcps\";\nimport { Connections } from \"./connections\";\nimport { Tools } from \"./tools\";\n\nexport class HornerosSSP {\n public readonly mcps: Mcps;\n public readonly connections: Connections;\n public readonly tools: Tools;\n\n private readonly baseUrl: string;\n\n constructor(config: HornerosSSPConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/+$/, \"\");\n\n this.mcps = new Mcps(this);\n this.connections = new Connections(this);\n this.tools = new Tools(this);\n }\n\n /** @internal */\n async fetch<T>(\n path: string,\n options: RequestInit = {}\n ): Promise<T> {\n const url = `${this.baseUrl}/api/v1${path}`;\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...(options.headers as Record<string, string>),\n };\n\n const res = await globalThis.fetch(url, {\n ...options,\n headers,\n });\n\n if (!res.ok) {\n let body: unknown;\n try {\n body = await res.json();\n } catch {\n body = await res.text().catch(() => null);\n }\n const message =\n (body && typeof body === \"object\" && \"error\" in body\n ? (body as { error: string }).error\n : null) || `HTTP ${res.status}`;\n throw new HornerosError(message, res.status, body);\n }\n\n if (res.status === 204) {\n return undefined as T;\n }\n\n return res.json() as Promise<T>;\n }\n}\n","import type { ConnectionData } from \"./types\";\n\nexport class AuthScheme {\n static APIKey(params: { api_key: string; [k: string]: string }): ConnectionData {\n return { type: \"api_key\", data: params };\n }\n\n static Bearer(params: { token: string }): ConnectionData {\n return { type: \"bearer\", data: params };\n }\n\n static Basic(params: { username: string; password: string }): ConnectionData {\n return { type: \"basic\", data: params };\n }\n\n static OAuth2(params: {\n access_token: string;\n refresh_token?: string;\n }): ConnectionData {\n return {\n type: \"oauth2\",\n data: params as Record<string, string>,\n };\n }\n\n static GoogleLogin(): ConnectionData {\n return { type: \"google_login\", data: {} };\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/mcps.ts","../src/connections.ts","../src/tools.ts","../src/client.ts","../src/auth-scheme.ts"],"sourcesContent":["// ── Error codes ─────────────────────────────────────────────\n\nexport const HORNEROS_SDK_ERROR_CODES = {\n BACKEND: {\n NOT_FOUND: \"BACKEND::NOT_FOUND\",\n RATE_LIMIT: \"BACKEND::RATE_LIMIT\",\n BAD_REQUEST: \"BACKEND::BAD_REQUEST\",\n UNAUTHORIZED: \"BACKEND::UNAUTHORIZED\",\n SERVER_ERROR: \"BACKEND::SERVER_ERROR\",\n SERVER_UNAVAILABLE: \"BACKEND::SERVER_UNAVAILABLE\",\n UNKNOWN: \"BACKEND::UNKNOWN\",\n },\n COMMON: {\n API_KEY_UNAVAILABLE: \"COMMON::API_KEY_UNAVAILABLE\",\n BASE_URL_NOT_REACHABLE: \"COMMON::BASE_URL_NOT_REACHABLE\",\n UNKNOWN: \"COMMON::UNKNOWN\",\n INVALID_PARAMS: \"COMMON::INVALID_PARAMS\",\n },\n SDK: {\n NO_CONNECTED_ACCOUNT: \"SDK::NO_CONNECTED_ACCOUNT\",\n CONNECTION_TIMEOUT: \"SDK::CONNECTION_TIMEOUT\",\n INVALID_PARAMETER: \"SDK::INVALID_PARAMETER\",\n },\n} as const;\n\n// ── Base error ──────────────────────────────────────────────\n\nlet errorCounter = 0;\n\nexport class HornerosError extends Error {\n public readonly errCode: string;\n public readonly statusCode: number;\n public readonly body: unknown;\n public readonly description?: string;\n public readonly possibleFix?: string;\n public readonly errorId: string;\n public readonly timestamp: string;\n\n constructor(\n errCode: string,\n message: string,\n statusCode: number,\n body?: unknown,\n description?: string,\n possibleFix?: string\n ) {\n super(message);\n this.name = \"HornerosError\";\n this.errCode = errCode;\n this.statusCode = statusCode;\n this.body = body;\n this.description = description;\n this.possibleFix = possibleFix;\n this.errorId = `horneros_${Date.now()}_${++errorCounter}`;\n this.timestamp = new Date().toISOString();\n }\n\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n errCode: this.errCode,\n message: this.message,\n statusCode: this.statusCode,\n description: this.description,\n possibleFix: this.possibleFix,\n errorId: this.errorId,\n timestamp: this.timestamp,\n body: this.body,\n };\n }\n}\n\n// ── Specialized errors ──────────────────────────────────────\n\nexport class NotFoundError extends HornerosError {\n constructor(message: string, body?: unknown) {\n super(HORNEROS_SDK_ERROR_CODES.BACKEND.NOT_FOUND, message, 404, body);\n this.name = \"NotFoundError\";\n }\n}\n\nexport class ValidationError extends HornerosError {\n constructor(message: string, body?: unknown) {\n super(HORNEROS_SDK_ERROR_CODES.BACKEND.BAD_REQUEST, message, 400, body);\n this.name = \"ValidationError\";\n }\n}\n\nexport class ConnectionTimeoutError extends HornerosError {\n constructor(message = \"Connection timed out waiting for activation\") {\n super(\n HORNEROS_SDK_ERROR_CODES.SDK.CONNECTION_TIMEOUT,\n message,\n 408,\n undefined,\n \"The connection did not become active within the timeout period.\",\n \"Increase the timeout value or check that the user completed the authentication flow.\"\n );\n this.name = \"ConnectionTimeoutError\";\n }\n}\n","import type { HornerosSSP } from \"./client\";\nimport type { McpInfo, McpDetail, ApiResponse } from \"./types\";\n\nexport class Mcps {\n constructor(private client: HornerosSSP) {}\n\n async list(): Promise<McpInfo[]> {\n const res = await this.client.fetch<ApiResponse<McpInfo[]>>(\"/mcps\");\n return res.data;\n }\n\n async get(slug: string): Promise<McpDetail> {\n const res = await this.client.fetch<ApiResponse<McpDetail>>(\n `/mcps/${encodeURIComponent(slug)}`\n );\n return res.data;\n }\n}\n","import type { HornerosSSP } from \"./client\";\nimport type {\n ConnectionInfo,\n ConnectionRequestData,\n InitiateConnectionParams,\n ApiResponse,\n} from \"./types\";\nimport { ConnectionTimeoutError } from \"./errors\";\n\nexport class ConnectionRequest {\n public readonly id: string;\n public readonly mcpUrl: string | null;\n public readonly token: string | null;\n public readonly redirectUrl: string | null;\n public readonly status: \"active\" | \"pending\";\n\n constructor(\n private client: HornerosSSP,\n data: ConnectionRequestData\n ) {\n this.id = data.id;\n this.mcpUrl = data.mcpUrl;\n this.token = data.token;\n this.redirectUrl = data.redirectUrl;\n this.status = data.status;\n }\n\n /**\n * Polls the connection until it becomes active.\n * Useful for OAuth/interactive flows where the user needs to\n * complete authentication in a browser.\n * @param timeout Max wait time in ms (default: 120000 = 2 min)\n */\n async waitForConnection(timeout = 120_000): Promise<ConnectionInfo> {\n if (this.status === \"active\") {\n const res = await this.client.fetch<ApiResponse<ConnectionInfo>>(\n `/connections/${encodeURIComponent(this.id)}`\n );\n return res.data;\n }\n\n const start = Date.now();\n const interval = 2000;\n\n while (Date.now() - start < timeout) {\n await sleep(interval);\n try {\n const res = await this.client.fetch<ApiResponse<ConnectionInfo>>(\n `/connections/${encodeURIComponent(this.id)}`\n );\n if (res.data.status === \"active\") {\n return res.data;\n }\n } catch {\n // Connection not yet created, keep polling\n }\n }\n\n throw new ConnectionTimeoutError();\n }\n}\n\nexport class Connections {\n constructor(private client: HornerosSSP) {}\n\n async initiate(params: InitiateConnectionParams): Promise<ConnectionRequest> {\n const body: Record<string, unknown> = {\n mcp_slug: params.mcpSlug,\n };\n\n if (params.appName) body.app_name = params.appName;\n if (params.userId) body.user_id = params.userId;\n if (params.credentials) body.credentials = params.credentials;\n if (params.authScheme) body.auth_scheme = params.authScheme;\n\n const res = await this.client.fetch<ApiResponse<ConnectionRequestData>>(\n \"/connections\",\n { method: \"POST\", body: JSON.stringify(body) }\n );\n\n return new ConnectionRequest(this.client, res.data);\n }\n\n async list(): Promise<ConnectionInfo[]> {\n const res =\n await this.client.fetch<ApiResponse<ConnectionInfo[]>>(\"/connections\");\n return res.data;\n }\n\n async get(id: string): Promise<ConnectionInfo> {\n const res = await this.client.fetch<ApiResponse<ConnectionInfo>>(\n `/connections/${encodeURIComponent(id)}`\n );\n return res.data;\n }\n\n async revoke(id: string): Promise<void> {\n await this.client.fetch<void>(\n `/connections/${encodeURIComponent(id)}`,\n { method: \"DELETE\" }\n );\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import type { HornerosSSP } from \"./client\";\nimport type {\n ToolDefinition,\n ToolResult,\n ExecuteToolParams,\n ApiResponse,\n} from \"./types\";\n\nexport class Tools {\n constructor(private client: HornerosSSP) {}\n\n async list(mcpSlug: string): Promise<ToolDefinition[]> {\n const res = await this.client.fetch<ApiResponse<ToolDefinition[]>>(\n `/mcps/${encodeURIComponent(mcpSlug)}/tools`\n );\n return res.data;\n }\n\n async execute(params: ExecuteToolParams): Promise<ToolResult> {\n const res = await this.client.fetch<ApiResponse<ToolResult>>(\n \"/tools/execute\",\n {\n method: \"POST\",\n body: JSON.stringify({\n mcp_slug: params.mcpSlug,\n connection_id: params.connectionId,\n tool_name: params.toolName,\n arguments: params.arguments,\n }),\n }\n );\n return res.data;\n }\n}\n","import type { HornerosSSPConfig } from \"./types\";\nimport { HornerosError, HORNEROS_SDK_ERROR_CODES } from \"./errors\";\nimport { Mcps } from \"./mcps\";\nimport { Connections } from \"./connections\";\nimport { Tools } from \"./tools\";\n\n// ── Helpers ─────────────────────────────────────────────────\n\nfunction getEnvVariable(name: string): string | undefined {\n if (typeof process !== \"undefined\" && process.env) {\n return process.env[name];\n }\n return undefined;\n}\n\nconst DEFAULT_BASE_URL = \"http://localhost:3000\";\n\nfunction resolveConfig(config?: HornerosSSPConfig) {\n const baseUrl =\n config?.baseUrl ||\n getEnvVariable(\"HORNEROS_BASE_URL\") ||\n DEFAULT_BASE_URL;\n\n const apiKey =\n config?.apiKey ||\n getEnvVariable(\"HORNEROS_API_KEY\") ||\n \"\";\n\n const runtime = config?.runtime || getEnvVariable(\"HORNEROS_RUNTIME\") || \"\";\n\n return { baseUrl: baseUrl.replace(/\\/+$/, \"\"), apiKey, runtime };\n}\n\n// ── Main client ─────────────────────────────────────────────\n\nexport class HornerosSSP {\n public readonly mcps: Mcps;\n public readonly connections: Connections;\n public readonly tools: Tools;\n\n private readonly baseUrl: string;\n private readonly apiKey: string;\n private readonly runtime: string;\n\n constructor(config?: HornerosSSPConfig) {\n const resolved = resolveConfig(config);\n\n if (!resolved.apiKey) {\n throw new HornerosError(\n HORNEROS_SDK_ERROR_CODES.COMMON.API_KEY_UNAVAILABLE,\n \"🔑 API Key is not provided\",\n 401,\n undefined,\n \"You need to provide an API key in the constructor or as the environment variable HORNEROS_API_KEY.\",\n 'Provide a valid API key: new HornerosSSP({ apiKey: \"hsp_xxx\" }) or set HORNEROS_API_KEY in your environment.'\n );\n }\n\n this.baseUrl = resolved.baseUrl;\n this.apiKey = resolved.apiKey;\n this.runtime = resolved.runtime;\n\n this.mcps = new Mcps(this);\n this.connections = new Connections(this);\n this.tools = new Tools(this);\n }\n\n /** @internal */\n async fetch<T>(\n path: string,\n options: RequestInit = {}\n ): Promise<T> {\n const url = `${this.baseUrl}/api/v1${path}`;\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"X-Api-Key\": this.apiKey,\n \"X-Source\": \"js_sdk\",\n \"X-Runtime\": this.runtime,\n ...(options.headers as Record<string, string>),\n };\n\n const res = await globalThis.fetch(url, {\n ...options,\n headers,\n });\n\n if (!res.ok) {\n let body: unknown;\n try {\n body = await res.json();\n } catch {\n body = await res.text().catch(() => null);\n }\n\n const message =\n (body && typeof body === \"object\" && \"error\" in body\n ? (body as { error: string }).error\n : null) || `HTTP ${res.status}`;\n\n const errCode =\n res.status === 404\n ? HORNEROS_SDK_ERROR_CODES.BACKEND.NOT_FOUND\n : res.status === 401\n ? HORNEROS_SDK_ERROR_CODES.BACKEND.UNAUTHORIZED\n : res.status === 429\n ? HORNEROS_SDK_ERROR_CODES.BACKEND.RATE_LIMIT\n : res.status === 400\n ? HORNEROS_SDK_ERROR_CODES.BACKEND.BAD_REQUEST\n : res.status >= 500\n ? HORNEROS_SDK_ERROR_CODES.BACKEND.SERVER_ERROR\n : HORNEROS_SDK_ERROR_CODES.BACKEND.UNKNOWN;\n\n throw new HornerosError(errCode, message, res.status, body);\n }\n\n if (res.status === 204) {\n return undefined as T;\n }\n\n return res.json() as Promise<T>;\n }\n}\n","import type { ConnectionData } from \"./types\";\n\nexport class AuthScheme {\n static APIKey(params: { api_key: string; [k: string]: string }): ConnectionData {\n return { type: \"api_key\", data: params };\n }\n\n static Bearer(params: { token: string }): ConnectionData {\n return { type: \"bearer\", data: params };\n }\n\n static Basic(params: { username: string; password: string }): ConnectionData {\n return { type: \"basic\", data: params };\n }\n\n static OAuth2(params: {\n access_token: string;\n refresh_token?: string;\n }): ConnectionData {\n return {\n type: \"oauth2\",\n data: params as Record<string, string>,\n };\n }\n\n static GoogleLogin(): ConnectionData {\n return { type: \"google_login\", data: {} };\n }\n}\n"],"mappings":"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","names":[]}
|