@inferencesh/sdk 0.4.4 → 0.4.8

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.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { ApiAppRunRequest, TaskDTO as Task, File, ChatDTO, ChatMessageDTO, AgentRuntimeConfig } from './types';
1
+ import { ApiAppRunRequest, TaskDTO as Task, File, ChatDTO, ChatMessageDTO, AgentConfig } from './types';
2
2
  import { EventSource } from 'eventsource';
3
3
  /**
4
- * Ad-hoc agent configuration - extends AgentRuntimeConfig with core_app_ref required
5
- * Uses Partial to make name/system_prompt optional for ad-hoc usage
4
+ * Ad-hoc agent configuration - extends AgentConfig with core_app_ref required
5
+ * Uses Partial to make fields optional for ad-hoc usage
6
6
  */
7
- export type AdHocAgentConfig = Partial<AgentRuntimeConfig> & {
7
+ export type AdHocAgentConfig = Partial<AgentConfig> & {
8
8
  /** Core LLM app ref: namespace/name@shortid (required for ad-hoc agents) */
9
9
  core_app_ref: string;
10
10
  };
@@ -29,10 +29,17 @@ export interface UploadFileOptions {
29
29
  public?: boolean;
30
30
  }
31
31
  export interface InferenceConfig {
32
- /** Your inference.sh API key */
33
- apiKey: string;
32
+ /** Your inference.sh API key (required unless using proxyUrl) */
33
+ apiKey?: string;
34
34
  /** Custom API base URL (defaults to https://api.inference.sh) */
35
35
  baseUrl?: string;
36
+ /**
37
+ * Proxy URL for frontend apps.
38
+ * When set, requests are routed through your proxy server to protect API keys.
39
+ * @example "/api/inference/proxy"
40
+ * @example "https://myapp.com/api/inference/proxy"
41
+ */
42
+ proxyUrl?: string;
36
43
  }
37
44
  export interface RunOptions {
38
45
  /** Callback for real-time status updates */
@@ -60,6 +67,7 @@ export interface RunOptions {
60
67
  export declare class Inference {
61
68
  private readonly apiKey;
62
69
  private readonly baseUrl;
70
+ private readonly proxyUrl;
63
71
  constructor(config: InferenceConfig);
64
72
  /** @internal */
65
73
  _request<T>(method: "get" | "post" | "put" | "delete", endpoint: string, options?: {
package/dist/client.js CHANGED
@@ -17,26 +17,39 @@ const errors_1 = require("./errors");
17
17
  */
18
18
  class Inference {
19
19
  constructor(config) {
20
- if (!config.apiKey) {
21
- throw new Error('API key is required');
20
+ // Either apiKey or proxyUrl must be provided
21
+ if (!config.apiKey && !config.proxyUrl) {
22
+ throw new Error('Either apiKey or proxyUrl is required');
22
23
  }
23
24
  this.apiKey = config.apiKey;
24
25
  this.baseUrl = config.baseUrl || "https://api.inference.sh";
26
+ this.proxyUrl = config.proxyUrl;
25
27
  }
26
28
  /** @internal */
27
29
  async _request(method, endpoint, options = {}) {
28
- const url = new URL(`${this.baseUrl}${endpoint}`);
30
+ // Build the target URL (always points to the API)
31
+ const targetUrl = new URL(`${this.baseUrl}${endpoint}`);
29
32
  if (options.params) {
30
33
  Object.entries(options.params).forEach(([key, value]) => {
31
34
  if (value !== undefined && value !== null) {
32
- url.searchParams.append(key, String(value));
35
+ targetUrl.searchParams.append(key, String(value));
33
36
  }
34
37
  });
35
38
  }
39
+ // In proxy mode, requests go to the proxy with target URL in a header
40
+ const isProxyMode = !!this.proxyUrl;
41
+ const fetchUrl = isProxyMode ? this.proxyUrl : targetUrl.toString();
36
42
  const headers = {
37
43
  "Content-Type": "application/json",
38
- Authorization: `Bearer ${this.apiKey}`,
39
44
  };
45
+ if (isProxyMode) {
46
+ // Proxy mode: send target URL as header, no auth (proxy handles it)
47
+ headers["x-inf-target-url"] = targetUrl.toString();
48
+ }
49
+ else {
50
+ // Direct mode: include authorization header
51
+ headers["Authorization"] = `Bearer ${this.apiKey}`;
52
+ }
40
53
  const fetchOptions = {
41
54
  method: method.toUpperCase(),
42
55
  headers,
@@ -45,7 +58,7 @@ class Inference {
45
58
  if (options.data) {
46
59
  fetchOptions.body = JSON.stringify(options.data);
47
60
  }
48
- const response = await fetch(url.toString(), fetchOptions);
61
+ const response = await fetch(fetchUrl, fetchOptions);
49
62
  const responseText = await response.text();
50
63
  // Try to parse as JSON
51
64
  let data = null;
@@ -94,15 +107,27 @@ class Inference {
94
107
  }
95
108
  /** @internal */
96
109
  _createEventSource(endpoint) {
97
- const url = new URL(`${this.baseUrl}${endpoint}`);
98
- return new eventsource_1.EventSource(url.toString(), {
99
- fetch: (input, init) => fetch(input, {
100
- ...init,
101
- headers: {
102
- ...init.headers,
103
- Authorization: `Bearer ${this.apiKey}`,
104
- },
105
- }),
110
+ const targetUrl = new URL(`${this.baseUrl}${endpoint}`);
111
+ const isProxyMode = !!this.proxyUrl;
112
+ const fetchUrl = isProxyMode ? this.proxyUrl : targetUrl.toString();
113
+ return new eventsource_1.EventSource(fetchUrl, {
114
+ fetch: (input, init) => {
115
+ const headers = {
116
+ ...init?.headers,
117
+ };
118
+ if (isProxyMode) {
119
+ // Proxy mode: send target URL as header
120
+ headers["x-inf-target-url"] = targetUrl.toString();
121
+ }
122
+ else {
123
+ // Direct mode: include authorization header
124
+ headers["Authorization"] = `Bearer ${this.apiKey}`;
125
+ }
126
+ return fetch(input, {
127
+ ...init,
128
+ headers,
129
+ });
130
+ },
106
131
  });
107
132
  }
108
133
  _stripTask(task) {
@@ -14,9 +14,9 @@ describe('Inference', () => {
14
14
  const client = new client_1.Inference({ apiKey: 'test-api-key' });
15
15
  expect(client).toBeInstanceOf(client_1.Inference);
16
16
  });
17
- it('should throw error when apiKey is missing', () => {
18
- expect(() => new client_1.Inference({ apiKey: '' })).toThrow('API key is required');
19
- expect(() => new client_1.Inference({})).toThrow('API key is required');
17
+ it('should throw error when neither apiKey nor proxyUrl is provided', () => {
18
+ expect(() => new client_1.Inference({ apiKey: '' })).toThrow('Either apiKey or proxyUrl is required');
19
+ expect(() => new client_1.Inference({})).toThrow('Either apiKey or proxyUrl is required');
20
20
  });
21
21
  it('should use default baseUrl when not provided', () => {
22
22
  const client = new client_1.Inference({ apiKey: 'test-api-key' });
package/dist/index.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  export { Inference, inference, InferenceConfig, RunOptions, UploadFileOptions, Agent, AdHocAgentConfig, SendMessageOptions, } from './client';
2
- export { AgentConfig, AdHocAgentOptions, TemplateAgentOptions, AgentOptions, } from './agent';
3
2
  export { tool, appTool, agentTool, webhookTool, internalTools, string, number, integer, boolean, enumOf, object, array, optional } from './tool-builder';
4
3
  export { StreamManager, PartialDataWrapper } from './stream';
5
4
  export { InferenceError, RequirementsNotMetException } from './errors';
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Express.js proxy handler for Inference.sh API
3
+ *
4
+ * @example
5
+ * ```typescript
6
+ * import express from "express";
7
+ * import * as inferenceProxy from "@inferencesh/sdk/proxy/express";
8
+ *
9
+ * const app = express();
10
+ * app.use(express.json());
11
+ * app.all(inferenceProxy.route, inferenceProxy.handler);
12
+ * ```
13
+ */
14
+ import type { RequestHandler } from "express";
15
+ /**
16
+ * The default proxy route path.
17
+ */
18
+ export declare const route = "/api/inference/proxy";
19
+ /**
20
+ * Express middleware handler for the Inference.sh proxy.
21
+ *
22
+ * Requires `express.json()` middleware to be applied before this handler.
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * import express from "express";
27
+ * import cors from "cors";
28
+ * import * as inferenceProxy from "@inferencesh/sdk/proxy/express";
29
+ *
30
+ * const app = express();
31
+ * app.use(express.json());
32
+ *
33
+ * // If clients are external, enable CORS
34
+ * app.all(inferenceProxy.route, cors(), inferenceProxy.handler);
35
+ * ```
36
+ */
37
+ export declare const handler: RequestHandler;
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ /**
3
+ * Express.js proxy handler for Inference.sh API
4
+ *
5
+ * @example
6
+ * ```typescript
7
+ * import express from "express";
8
+ * import * as inferenceProxy from "@inferencesh/sdk/proxy/express";
9
+ *
10
+ * const app = express();
11
+ * app.use(express.json());
12
+ * app.all(inferenceProxy.route, inferenceProxy.handler);
13
+ * ```
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.handler = exports.route = void 0;
17
+ const index_1 = require("./index");
18
+ /**
19
+ * The default proxy route path.
20
+ */
21
+ exports.route = index_1.DEFAULT_PROXY_ROUTE;
22
+ /**
23
+ * Express middleware handler for the Inference.sh proxy.
24
+ *
25
+ * Requires `express.json()` middleware to be applied before this handler.
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * import express from "express";
30
+ * import cors from "cors";
31
+ * import * as inferenceProxy from "@inferencesh/sdk/proxy/express";
32
+ *
33
+ * const app = express();
34
+ * app.use(express.json());
35
+ *
36
+ * // If clients are external, enable CORS
37
+ * app.all(inferenceProxy.route, cors(), inferenceProxy.handler);
38
+ * ```
39
+ */
40
+ const handler = async (req, res, _next) => {
41
+ const responseHeaders = {};
42
+ return (0, index_1.handleRequest)({
43
+ id: "express",
44
+ method: req.method,
45
+ getRequestBody: async () => JSON.stringify(req.body),
46
+ getHeaders: () => req.headers,
47
+ getHeader: (name) => req.headers[name],
48
+ sendHeader: (name, value) => {
49
+ responseHeaders[name] = value;
50
+ res.setHeader(name, value);
51
+ },
52
+ respondWith: (status, data) => {
53
+ return res.status(status).json(data);
54
+ },
55
+ sendResponse: async (response) => {
56
+ // Copy status
57
+ res.status(response.status);
58
+ // Handle streaming responses
59
+ const contentType = response.headers.get("content-type");
60
+ if (contentType?.includes("text/event-stream") ||
61
+ contentType?.includes("application/octet-stream")) {
62
+ // Stream the response
63
+ if (response.body) {
64
+ const reader = response.body.getReader();
65
+ while (true) {
66
+ const { done, value } = await reader.read();
67
+ if (done)
68
+ break;
69
+ res.write(value);
70
+ }
71
+ }
72
+ res.end();
73
+ return res;
74
+ }
75
+ // Handle JSON responses
76
+ if (contentType?.includes("application/json")) {
77
+ return res.json(await response.json());
78
+ }
79
+ // Handle text responses
80
+ return res.send(await response.text());
81
+ },
82
+ });
83
+ };
84
+ exports.handler = handler;
@@ -0,0 +1 @@
1
+ export * from "./express.js";
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Hono proxy handler for Inference.sh API
3
+ *
4
+ * Lightweight handler for Hono framework, ideal for edge/serverless deployments.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { Hono } from "hono";
9
+ * import { createRouteHandler } from "@inferencesh/sdk/proxy/hono";
10
+ *
11
+ * const app = new Hono();
12
+ * const proxyHandler = createRouteHandler();
13
+ *
14
+ * app.all("/api/inference/proxy", proxyHandler);
15
+ * ```
16
+ */
17
+ import type { Context } from "hono";
18
+ export interface HonoProxyOptions {
19
+ /**
20
+ * Custom function to resolve the API key.
21
+ * Defaults to reading from INFERENCE_API_KEY environment variable.
22
+ */
23
+ resolveApiKey?: () => Promise<string | undefined>;
24
+ }
25
+ type RouteHandler = (context: Context) => Promise<Response>;
26
+ /**
27
+ * Creates a Hono route handler that proxies requests to the Inference.sh API.
28
+ *
29
+ * This is a drop-in handler for Hono applications that keeps API keys safe
30
+ * by running on your server.
31
+ *
32
+ * @param options - Proxy options
33
+ * @returns A Hono route handler function
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * import { Hono } from "hono";
38
+ * import { createRouteHandler } from "@inferencesh/sdk/proxy/hono";
39
+ *
40
+ * const app = new Hono();
41
+ * const proxyHandler = createRouteHandler();
42
+ *
43
+ * app.all("/api/inference/proxy", proxyHandler);
44
+ *
45
+ * export default app;
46
+ * ```
47
+ *
48
+ * @example Custom API key resolver
49
+ * ```typescript
50
+ * const proxyHandler = createRouteHandler({
51
+ * resolveApiKey: async () => {
52
+ * // Load from a secrets manager
53
+ * return await getSecretFromVault("INFERENCE_API_KEY");
54
+ * },
55
+ * });
56
+ * ```
57
+ */
58
+ export declare function createRouteHandler({ resolveApiKey, }?: HonoProxyOptions): RouteHandler;
59
+ export {};
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ /**
3
+ * Hono proxy handler for Inference.sh API
4
+ *
5
+ * Lightweight handler for Hono framework, ideal for edge/serverless deployments.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { Hono } from "hono";
10
+ * import { createRouteHandler } from "@inferencesh/sdk/proxy/hono";
11
+ *
12
+ * const app = new Hono();
13
+ * const proxyHandler = createRouteHandler();
14
+ *
15
+ * app.all("/api/inference/proxy", proxyHandler);
16
+ * ```
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.createRouteHandler = createRouteHandler;
20
+ const index_1 = require("./index");
21
+ /**
22
+ * Creates a Hono route handler that proxies requests to the Inference.sh API.
23
+ *
24
+ * This is a drop-in handler for Hono applications that keeps API keys safe
25
+ * by running on your server.
26
+ *
27
+ * @param options - Proxy options
28
+ * @returns A Hono route handler function
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * import { Hono } from "hono";
33
+ * import { createRouteHandler } from "@inferencesh/sdk/proxy/hono";
34
+ *
35
+ * const app = new Hono();
36
+ * const proxyHandler = createRouteHandler();
37
+ *
38
+ * app.all("/api/inference/proxy", proxyHandler);
39
+ *
40
+ * export default app;
41
+ * ```
42
+ *
43
+ * @example Custom API key resolver
44
+ * ```typescript
45
+ * const proxyHandler = createRouteHandler({
46
+ * resolveApiKey: async () => {
47
+ * // Load from a secrets manager
48
+ * return await getSecretFromVault("INFERENCE_API_KEY");
49
+ * },
50
+ * });
51
+ * ```
52
+ */
53
+ function createRouteHandler({ resolveApiKey = index_1.resolveApiKeyFromEnv, } = {}) {
54
+ const routeHandler = async (context) => {
55
+ const responseHeaders = new Headers();
56
+ return (0, index_1.handleRequest)({
57
+ id: "hono",
58
+ method: context.req.method,
59
+ respondWith: (status, data) => {
60
+ return new Response(JSON.stringify(data), {
61
+ status,
62
+ headers: {
63
+ "Content-Type": "application/json",
64
+ ...Object.fromEntries(responseHeaders.entries()),
65
+ },
66
+ });
67
+ },
68
+ getHeaders: () => (0, index_1.fromHeaders)(context.req.raw.headers),
69
+ getHeader: (name) => context.req.header(name),
70
+ sendHeader: (name, value) => responseHeaders.set(name, value),
71
+ getRequestBody: async () => {
72
+ try {
73
+ return await context.req.text();
74
+ }
75
+ catch {
76
+ return undefined;
77
+ }
78
+ },
79
+ sendResponse: index_1.responsePassthrough,
80
+ resolveApiKey,
81
+ });
82
+ };
83
+ return routeHandler;
84
+ }
@@ -0,0 +1 @@
1
+ export * from "./hono.js";
@@ -0,0 +1,55 @@
1
+ /**
2
+ * @inferencesh/sdk/proxy - Server-side proxy for Inference.sh API
3
+ *
4
+ * Protects API keys by proxying requests from frontend apps through your server.
5
+ * Supports Next.js (App & Page Router), Express, Hono, Remix, and SvelteKit.
6
+ */
7
+ export declare const TARGET_URL_HEADER = "x-inf-target-url";
8
+ export declare const DEFAULT_PROXY_ROUTE = "/api/inference/proxy";
9
+ export type HeaderValue = string | string[] | undefined | null;
10
+ /**
11
+ * The proxy behavior interface - a subset of request/response objects
12
+ * that abstracts framework-specific APIs.
13
+ */
14
+ export interface ProxyBehavior<ResponseType> {
15
+ /** Framework identifier for logging/debugging */
16
+ id: string;
17
+ /** HTTP method */
18
+ method: string;
19
+ /** Return an error response */
20
+ respondWith(status: number, data: string | object): ResponseType;
21
+ /** Pass through a fetch Response */
22
+ sendResponse(response: Response): Promise<ResponseType>;
23
+ /** Get all headers as a record */
24
+ getHeaders(): Record<string, HeaderValue>;
25
+ /** Get a single header value */
26
+ getHeader(name: string): HeaderValue;
27
+ /** Set a response header */
28
+ sendHeader(name: string, value: string): void;
29
+ /** Get the request body as a string */
30
+ getRequestBody(): Promise<string | undefined>;
31
+ /** Optional custom API key resolver */
32
+ resolveApiKey?: () => Promise<string | undefined>;
33
+ }
34
+ /**
35
+ * Core proxy request handler.
36
+ *
37
+ * Proxies requests to the Inference.sh API with server-side credential injection.
38
+ * This handler is framework-agnostic and works via the ProxyBehavior interface.
39
+ *
40
+ * @param behavior - Framework-specific request/response handling
41
+ * @returns Promise that resolves when the request is handled
42
+ */
43
+ export declare function handleRequest<ResponseType>(behavior: ProxyBehavior<ResponseType>): Promise<ResponseType>;
44
+ /**
45
+ * Convert a Headers object to a plain record.
46
+ */
47
+ export declare function fromHeaders(headers: Headers): Record<string, string | string[]>;
48
+ /**
49
+ * Simple passthrough for Response objects (used in app router style handlers).
50
+ */
51
+ export declare const responsePassthrough: (res: Response) => Promise<Response>;
52
+ /**
53
+ * Resolve API key from environment (exposed for custom handlers).
54
+ */
55
+ export declare const resolveApiKeyFromEnv: () => Promise<string | undefined>;
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ /**
3
+ * @inferencesh/sdk/proxy - Server-side proxy for Inference.sh API
4
+ *
5
+ * Protects API keys by proxying requests from frontend apps through your server.
6
+ * Supports Next.js (App & Page Router), Express, Hono, Remix, and SvelteKit.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.resolveApiKeyFromEnv = exports.responsePassthrough = exports.DEFAULT_PROXY_ROUTE = exports.TARGET_URL_HEADER = void 0;
10
+ exports.handleRequest = handleRequest;
11
+ exports.fromHeaders = fromHeaders;
12
+ exports.TARGET_URL_HEADER = "x-inf-target-url";
13
+ exports.DEFAULT_PROXY_ROUTE = "/api/inference/proxy";
14
+ const INFERENCE_API_KEY = process.env.INFERENCE_API_KEY;
15
+ // Only allow requests to inference.sh domains
16
+ const INFERENCE_URL_REGEX = /(\.|^)inference\.sh$/;
17
+ /**
18
+ * Utility to get a header value as string from potentially array value.
19
+ */
20
+ function singleHeaderValue(value) {
21
+ if (!value)
22
+ return undefined;
23
+ if (Array.isArray(value))
24
+ return value[0];
25
+ return value;
26
+ }
27
+ /**
28
+ * Get the API key from environment variables.
29
+ */
30
+ function getApiKey() {
31
+ return INFERENCE_API_KEY;
32
+ }
33
+ // Headers to exclude from response passthrough
34
+ const EXCLUDED_HEADERS = ["content-length", "content-encoding"];
35
+ /**
36
+ * Core proxy request handler.
37
+ *
38
+ * Proxies requests to the Inference.sh API with server-side credential injection.
39
+ * This handler is framework-agnostic and works via the ProxyBehavior interface.
40
+ *
41
+ * @param behavior - Framework-specific request/response handling
42
+ * @returns Promise that resolves when the request is handled
43
+ */
44
+ async function handleRequest(behavior) {
45
+ // 1. Get and validate target URL
46
+ const targetUrl = singleHeaderValue(behavior.getHeader(exports.TARGET_URL_HEADER));
47
+ if (!targetUrl) {
48
+ return behavior.respondWith(400, {
49
+ error: `Missing the ${exports.TARGET_URL_HEADER} header`,
50
+ });
51
+ }
52
+ // 2. Validate target is an inference.sh domain
53
+ let urlHost;
54
+ try {
55
+ urlHost = new URL(targetUrl).host;
56
+ }
57
+ catch {
58
+ return behavior.respondWith(400, {
59
+ error: `Invalid ${exports.TARGET_URL_HEADER} header: not a valid URL`,
60
+ });
61
+ }
62
+ if (!INFERENCE_URL_REGEX.test(urlHost)) {
63
+ return behavior.respondWith(412, {
64
+ error: `Invalid ${exports.TARGET_URL_HEADER} header: must be an inference.sh domain`,
65
+ });
66
+ }
67
+ // 3. Get API key
68
+ const apiKey = behavior.resolveApiKey
69
+ ? await behavior.resolveApiKey()
70
+ : getApiKey();
71
+ if (!apiKey) {
72
+ return behavior.respondWith(401, {
73
+ error: "Missing INFERENCE_API_KEY environment variable",
74
+ });
75
+ }
76
+ // 4. Build forwarded headers (x-inf-* prefixed)
77
+ const forwardedHeaders = {};
78
+ const allHeaders = behavior.getHeaders();
79
+ for (const key of Object.keys(allHeaders)) {
80
+ if (key.toLowerCase().startsWith("x-inf-")) {
81
+ const value = singleHeaderValue(allHeaders[key]);
82
+ if (value) {
83
+ forwardedHeaders[key.toLowerCase()] = value;
84
+ }
85
+ }
86
+ }
87
+ // 5. Forward content-type if present
88
+ const contentType = singleHeaderValue(behavior.getHeader("content-type"));
89
+ // 6. Build proxy user agent
90
+ const proxyUserAgent = `@inferencesh/sdk-proxy/${behavior.id}`;
91
+ const userAgent = singleHeaderValue(behavior.getHeader("user-agent"));
92
+ // 7. Make the proxied request
93
+ const res = await fetch(targetUrl, {
94
+ method: behavior.method,
95
+ headers: {
96
+ ...forwardedHeaders,
97
+ authorization: singleHeaderValue(behavior.getHeader("authorization")) ??
98
+ `Bearer ${apiKey}`,
99
+ accept: "application/json",
100
+ "content-type": contentType || "application/json",
101
+ "user-agent": userAgent || proxyUserAgent,
102
+ "x-inf-client-proxy": proxyUserAgent,
103
+ },
104
+ body: behavior.method?.toUpperCase() === "GET"
105
+ ? undefined
106
+ : await behavior.getRequestBody(),
107
+ });
108
+ // 8. Copy response headers (excluding certain ones)
109
+ res.headers.forEach((value, key) => {
110
+ if (!EXCLUDED_HEADERS.includes(key.toLowerCase())) {
111
+ behavior.sendHeader(key, value);
112
+ }
113
+ });
114
+ // 9. Return the response
115
+ return behavior.sendResponse(res);
116
+ }
117
+ /**
118
+ * Convert a Headers object to a plain record.
119
+ */
120
+ function fromHeaders(headers) {
121
+ const result = {};
122
+ headers.forEach((value, key) => {
123
+ result[key] = value;
124
+ });
125
+ return result;
126
+ }
127
+ /**
128
+ * Simple passthrough for Response objects (used in app router style handlers).
129
+ */
130
+ const responsePassthrough = (res) => Promise.resolve(res);
131
+ exports.responsePassthrough = responsePassthrough;
132
+ /**
133
+ * Resolve API key from environment (exposed for custom handlers).
134
+ */
135
+ const resolveApiKeyFromEnv = () => Promise.resolve(getApiKey());
136
+ exports.resolveApiKeyFromEnv = resolveApiKeyFromEnv;
@@ -0,0 +1 @@
1
+ export * from "./index.js";
@@ -0,0 +1 @@
1
+ export {};