@inferencesh/sdk 0.6.14 → 0.6.19

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.
Files changed (89) hide show
  1. package/README.md +1 -1
  2. package/dist/agent/actions.js +10 -0
  3. package/dist/agent/provider.d.ts +2 -1
  4. package/dist/agent/provider.js +5 -5
  5. package/dist/agent/types.d.ts +3 -0
  6. package/dist/api/apps.d.ts +4 -0
  7. package/dist/api/apps.js +6 -0
  8. package/dist/api/index.d.ts +3 -3
  9. package/dist/http/index.d.ts +3 -3
  10. package/dist/index.d.ts +9 -9
  11. package/dist/types.d.ts +131 -19
  12. package/dist/types.js +26 -9
  13. package/package.json +8 -5
  14. package/dist/agent/actions.test.d.ts +0 -1
  15. package/dist/agent/actions.test.js +0 -820
  16. package/dist/agent/api.test.d.ts +0 -1
  17. package/dist/agent/api.test.js +0 -246
  18. package/dist/agent/reducer.test.d.ts +0 -1
  19. package/dist/agent/reducer.test.js +0 -131
  20. package/dist/agent/types.test.d.ts +0 -1
  21. package/dist/agent/types.test.js +0 -75
  22. package/dist/api/agents.test.d.ts +0 -1
  23. package/dist/api/agents.test.js +0 -1014
  24. package/dist/api/api-keys.test.d.ts +0 -1
  25. package/dist/api/api-keys.test.js +0 -44
  26. package/dist/api/apps.test.d.ts +0 -1
  27. package/dist/api/apps.test.js +0 -135
  28. package/dist/api/chats.test.d.ts +0 -1
  29. package/dist/api/chats.test.js +0 -85
  30. package/dist/api/engines.test.d.ts +0 -1
  31. package/dist/api/engines.test.js +0 -133
  32. package/dist/api/files.test.d.ts +0 -1
  33. package/dist/api/files.test.js +0 -256
  34. package/dist/api/flow-runs.test.d.ts +0 -1
  35. package/dist/api/flow-runs.test.js +0 -97
  36. package/dist/api/flows.test.d.ts +0 -1
  37. package/dist/api/flows.test.js +0 -118
  38. package/dist/api/integrations.test.d.ts +0 -1
  39. package/dist/api/integrations.test.js +0 -109
  40. package/dist/api/knowledge.test.d.ts +0 -1
  41. package/dist/api/knowledge.test.js +0 -238
  42. package/dist/api/mcp-servers.test.d.ts +0 -1
  43. package/dist/api/mcp-servers.test.js +0 -98
  44. package/dist/api/projects.test.d.ts +0 -1
  45. package/dist/api/projects.test.js +0 -61
  46. package/dist/api/search.test.d.ts +0 -1
  47. package/dist/api/search.test.js +0 -50
  48. package/dist/api/secrets.test.d.ts +0 -1
  49. package/dist/api/secrets.test.js +0 -61
  50. package/dist/api/sessions.test.d.ts +0 -1
  51. package/dist/api/sessions.test.js +0 -61
  52. package/dist/api/tasks.test.d.ts +0 -1
  53. package/dist/api/tasks.test.js +0 -381
  54. package/dist/api/teams.test.d.ts +0 -1
  55. package/dist/api/teams.test.js +0 -139
  56. package/dist/client.test.d.ts +0 -1
  57. package/dist/client.test.js +0 -446
  58. package/dist/http/client.test.d.ts +0 -1
  59. package/dist/http/client.test.js +0 -435
  60. package/dist/http/errors.test.d.ts +0 -1
  61. package/dist/http/errors.test.js +0 -66
  62. package/dist/http/poll.test.d.ts +0 -1
  63. package/dist/http/poll.test.js +0 -146
  64. package/dist/http/streamable.test.d.ts +0 -4
  65. package/dist/http/streamable.test.js +0 -510
  66. package/dist/integration.test.d.ts +0 -9
  67. package/dist/integration.test.js +0 -107
  68. package/dist/proxy/express.test.d.ts +0 -1
  69. package/dist/proxy/express.test.js +0 -106
  70. package/dist/proxy/hono.test.d.ts +0 -1
  71. package/dist/proxy/hono.test.js +0 -90
  72. package/dist/proxy/index.test.d.ts +0 -1
  73. package/dist/proxy/index.test.js +0 -173
  74. package/dist/proxy/nextjs.test.d.ts +0 -1
  75. package/dist/proxy/nextjs.test.js +0 -125
  76. package/dist/proxy/remix.test.d.ts +0 -1
  77. package/dist/proxy/remix.test.js +0 -66
  78. package/dist/proxy/svelte.test.d.ts +0 -1
  79. package/dist/proxy/svelte.test.js +0 -69
  80. package/dist/sessions.integration.test.d.ts +0 -13
  81. package/dist/sessions.integration.test.js +0 -310
  82. package/dist/stream.test.d.ts +0 -1
  83. package/dist/stream.test.js +0 -363
  84. package/dist/streamable.integration.test.d.ts +0 -11
  85. package/dist/streamable.integration.test.js +0 -150
  86. package/dist/tool-builder.test.d.ts +0 -1
  87. package/dist/tool-builder.test.js +0 -407
  88. package/dist/utils.test.d.ts +0 -1
  89. package/dist/utils.test.js +0 -43
@@ -1,106 +0,0 @@
1
- import { INF_TARGET_HEADER } from './index';
2
- import { createHandler } from './express';
3
- function createMockResponse() {
4
- const res = {
5
- statusCode: 200,
6
- headers: {},
7
- body: undefined,
8
- chunks: [],
9
- status(code) {
10
- this.statusCode = code;
11
- return this;
12
- },
13
- setHeader(name, value) {
14
- this.headers[name] = value;
15
- },
16
- json(data) {
17
- this.body = data;
18
- return this;
19
- },
20
- send(data) {
21
- this.body = data;
22
- return this;
23
- },
24
- write(chunk) {
25
- this.chunks.push(chunk);
26
- },
27
- end() {
28
- return;
29
- },
30
- };
31
- return res;
32
- }
33
- describe('express createHandler', () => {
34
- const originalFetch = global.fetch;
35
- beforeEach(() => {
36
- jest.clearAllMocks();
37
- process.env.INFERENCE_API_KEY = 'express-test-key';
38
- });
39
- afterEach(() => {
40
- global.fetch = originalFetch;
41
- });
42
- it('should return 400 when target URL is missing', async () => {
43
- const handler = createHandler();
44
- const req = {
45
- method: 'POST',
46
- body: {},
47
- headers: {},
48
- query: {},
49
- };
50
- const res = createMockResponse();
51
- await handler(req, res, jest.fn());
52
- expect(res.statusCode).toBe(400);
53
- expect(res.body).toEqual({
54
- error: `Missing ${INF_TARGET_HEADER} header or __inf_target query param`,
55
- });
56
- });
57
- it('should proxy JSON responses through res.json()', async () => {
58
- global.fetch = jest.fn().mockResolvedValue(new Response(JSON.stringify({ ok: true }), {
59
- status: 200,
60
- headers: { 'content-type': 'application/json' },
61
- }));
62
- const handler = createHandler();
63
- const target = 'https://api.inference.sh/v1/run';
64
- const req = {
65
- method: 'POST',
66
- body: { prompt: 'hi' },
67
- headers: { [INF_TARGET_HEADER]: target },
68
- query: {},
69
- };
70
- const res = createMockResponse();
71
- await handler(req, res, jest.fn());
72
- expect(res.statusCode).toBe(200);
73
- expect(res.body).toEqual({ ok: true });
74
- expect(global.fetch).toHaveBeenCalledWith(target, expect.objectContaining({
75
- headers: expect.objectContaining({
76
- authorization: 'Bearer express-test-key',
77
- }),
78
- }));
79
- });
80
- it('should stream SSE responses with res.write()', async () => {
81
- const encoder = new TextEncoder();
82
- const stream = new ReadableStream({
83
- start(controller) {
84
- controller.enqueue(encoder.encode('data: {"x":1}\n\n'));
85
- controller.close();
86
- },
87
- });
88
- global.fetch = jest.fn().mockResolvedValue(new Response(stream, {
89
- status: 200,
90
- headers: { 'content-type': 'text/event-stream' },
91
- }));
92
- const handler = createHandler();
93
- const target = 'https://api.inference.sh/v1/stream';
94
- const req = {
95
- method: 'POST',
96
- body: {},
97
- headers: { [INF_TARGET_HEADER]: target },
98
- query: {},
99
- };
100
- const res = createMockResponse();
101
- await handler(req, res, jest.fn());
102
- expect(res.statusCode).toBe(200);
103
- expect(res.chunks.length).toBeGreaterThan(0);
104
- expect(res.body).toBeUndefined();
105
- });
106
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,90 +0,0 @@
1
- import { INF_TARGET_HEADER } from './index';
2
- import { createHandler } from './hono';
3
- function createMockContext(overrides = {}) {
4
- const headers = new Headers(overrides.headers ?? {});
5
- const url = overrides.url ?? 'http://localhost/api/inference/proxy';
6
- return {
7
- req: {
8
- method: overrides.method ?? 'POST',
9
- url,
10
- raw: { headers },
11
- header: (name) => headers.get(name) ?? undefined,
12
- text: () => Promise.resolve(overrides.body ?? '{"ok":true}'),
13
- },
14
- };
15
- }
16
- describe('hono createHandler', () => {
17
- const originalFetch = global.fetch;
18
- beforeEach(() => {
19
- jest.clearAllMocks();
20
- process.env.INFERENCE_API_KEY = 'hono-test-key';
21
- });
22
- afterEach(() => {
23
- global.fetch = originalFetch;
24
- });
25
- it('should return 400 when target URL is missing', async () => {
26
- const handler = createHandler();
27
- const response = await handler(createMockContext());
28
- expect(response.status).toBe(400);
29
- expect(await response.json()).toEqual({
30
- error: `Missing ${INF_TARGET_HEADER} header or __inf_target query param`,
31
- });
32
- });
33
- it('should proxy JSON responses', async () => {
34
- global.fetch = jest.fn().mockResolvedValue(new Response(JSON.stringify({ ok: true }), {
35
- status: 200,
36
- headers: { 'content-type': 'application/json' },
37
- }));
38
- const handler = createHandler();
39
- const target = 'https://api.inference.sh/v1/run';
40
- const response = await handler(createMockContext({
41
- headers: { [INF_TARGET_HEADER]: target },
42
- }));
43
- expect(response.status).toBe(200);
44
- expect(await response.json()).toEqual({ ok: true });
45
- expect(global.fetch).toHaveBeenCalledWith(target, expect.objectContaining({
46
- headers: expect.objectContaining({
47
- authorization: 'Bearer hono-test-key',
48
- }),
49
- }));
50
- });
51
- it('should passthrough SSE streaming responses', async () => {
52
- const encoder = new TextEncoder();
53
- const stream = new ReadableStream({
54
- start(controller) {
55
- controller.enqueue(encoder.encode('data: {"x":1}\n\n'));
56
- controller.close();
57
- },
58
- });
59
- global.fetch = jest.fn().mockResolvedValue(new Response(stream, {
60
- status: 200,
61
- headers: { 'content-type': 'text/event-stream' },
62
- }));
63
- const handler = createHandler();
64
- const target = 'https://api.inference.sh/v1/stream';
65
- const response = await handler(createMockContext({
66
- headers: { [INF_TARGET_HEADER]: target },
67
- }));
68
- expect(response.status).toBe(200);
69
- expect(response.headers.get('content-type')).toContain('text/event-stream');
70
- expect(await response.text()).toContain('data:');
71
- });
72
- it('should resolve API key via resolveApiKey option', async () => {
73
- global.fetch = jest.fn().mockResolvedValue(new Response(JSON.stringify({ ok: true }), {
74
- status: 200,
75
- headers: { 'content-type': 'application/json' },
76
- }));
77
- const handler = createHandler({
78
- resolveApiKey: async () => 'custom-hono-key',
79
- });
80
- const target = 'https://api.inference.sh/v1/run';
81
- await handler(createMockContext({
82
- headers: { [INF_TARGET_HEADER]: target },
83
- }));
84
- expect(global.fetch).toHaveBeenCalledWith(target, expect.objectContaining({
85
- headers: expect.objectContaining({
86
- authorization: 'Bearer custom-hono-key',
87
- }),
88
- }));
89
- });
90
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,173 +0,0 @@
1
- import { INF_TARGET_HEADER, INF_TARGET_PARAM, headersToRecord, processProxyRequest, } from './index';
2
- function createTestAdapter(overrides = {}) {
3
- const state = { status: 0 };
4
- const adapter = {
5
- framework: 'test',
6
- method: 'POST',
7
- body: async () => '{"ok":true}',
8
- headers: () => ({}),
9
- header: () => undefined,
10
- query: () => undefined,
11
- setHeader: (name, value) => {
12
- state.headers = state.headers ?? {};
13
- state.headers[name] = value;
14
- },
15
- error: (status, message) => {
16
- state.status = status;
17
- state.body = message;
18
- return state;
19
- },
20
- respond: async (response) => {
21
- state.status = response.status;
22
- state.body = await response.text();
23
- return state;
24
- },
25
- ...overrides,
26
- };
27
- return adapter;
28
- }
29
- describe('headersToRecord', () => {
30
- it('should convert Headers to a plain record', () => {
31
- const headers = new Headers({ 'x-test': 'value', 'content-type': 'application/json' });
32
- expect(headersToRecord(headers)).toEqual({
33
- 'x-test': 'value',
34
- 'content-type': 'application/json',
35
- });
36
- });
37
- });
38
- describe('processProxyRequest', () => {
39
- const originalFetch = global.fetch;
40
- const originalApiKey = process.env.INFERENCE_API_KEY;
41
- beforeEach(() => {
42
- jest.clearAllMocks();
43
- process.env.INFERENCE_API_KEY = 'env-test-key';
44
- global.fetch = jest.fn().mockResolvedValue(new Response(JSON.stringify({ ok: true }), {
45
- status: 200,
46
- headers: { 'content-type': 'application/json' },
47
- }));
48
- });
49
- afterEach(() => {
50
- global.fetch = originalFetch;
51
- if (originalApiKey === undefined) {
52
- delete process.env.INFERENCE_API_KEY;
53
- }
54
- else {
55
- process.env.INFERENCE_API_KEY = originalApiKey;
56
- }
57
- });
58
- it('should reject requests without a target URL', async () => {
59
- const result = await processProxyRequest(createTestAdapter());
60
- expect(result.status).toBe(400);
61
- expect(result.body).toEqual({
62
- error: `Missing ${INF_TARGET_HEADER} header or ${INF_TARGET_PARAM} query param`,
63
- });
64
- expect(global.fetch).not.toHaveBeenCalled();
65
- });
66
- it('should reject invalid target URLs', async () => {
67
- const result = await processProxyRequest(createTestAdapter({
68
- header: (name) => (name === INF_TARGET_HEADER ? 'not-a-url' : undefined),
69
- }));
70
- expect(result.status).toBe(400);
71
- expect(result.body).toEqual({ error: 'Invalid target URL' });
72
- expect(global.fetch).not.toHaveBeenCalled();
73
- });
74
- it('should reject non-inference.sh domains', async () => {
75
- const result = await processProxyRequest(createTestAdapter({
76
- header: (name) => name === INF_TARGET_HEADER ? 'https://evil.example.com/run' : undefined,
77
- }));
78
- expect(result.status).toBe(412);
79
- expect(result.body).toEqual({
80
- error: 'Target must be an inference.sh domain, got: evil.example.com',
81
- });
82
- expect(global.fetch).not.toHaveBeenCalled();
83
- });
84
- it('should reject when no API key is configured', async () => {
85
- delete process.env.INFERENCE_API_KEY;
86
- const result = await processProxyRequest(createTestAdapter({
87
- header: (name) => name === INF_TARGET_HEADER ? 'https://api.inference.sh/run' : undefined,
88
- }));
89
- expect(result.status).toBe(401);
90
- expect(result.body).toEqual({
91
- error: 'Missing INFERENCE_API_KEY environment variable',
92
- });
93
- expect(global.fetch).not.toHaveBeenCalled();
94
- });
95
- it('should proxy valid inference.sh requests with env API key', async () => {
96
- const target = 'https://api.inference.sh/v1/tasks/1';
97
- const result = await processProxyRequest(createTestAdapter({
98
- header: (name) => (name === INF_TARGET_HEADER ? target : undefined),
99
- }));
100
- expect(result.status).toBe(200);
101
- expect(global.fetch).toHaveBeenCalledWith(target, expect.objectContaining({
102
- method: 'POST',
103
- headers: expect.objectContaining({
104
- authorization: 'Bearer env-test-key',
105
- 'x-inf-proxy': '@inferencesh/sdk-proxy/test',
106
- }),
107
- }));
108
- });
109
- it('should prefer client Authorization header over env API key', async () => {
110
- const target = 'https://api.inference.sh/v1/tasks/1';
111
- await processProxyRequest(createTestAdapter({
112
- header: (name) => {
113
- if (name === INF_TARGET_HEADER)
114
- return target;
115
- if (name === 'authorization')
116
- return 'Bearer client-session-token';
117
- return undefined;
118
- },
119
- }));
120
- expect(global.fetch).toHaveBeenCalledWith(target, expect.objectContaining({
121
- headers: expect.objectContaining({
122
- authorization: 'Bearer client-session-token',
123
- }),
124
- }));
125
- });
126
- it('should use query param fallback when header is missing (SSE clients)', async () => {
127
- const target = 'https://api.inference.sh/v1/stream';
128
- const encoded = encodeURIComponent(target);
129
- await processProxyRequest(createTestAdapter({
130
- query: (name) => (name === INF_TARGET_PARAM ? encoded : undefined),
131
- }));
132
- expect(global.fetch).toHaveBeenCalledWith(target, expect.any(Object));
133
- });
134
- it('should honor custom allowedDomains', async () => {
135
- const target = 'https://cdn.custom.example/upload';
136
- await processProxyRequest(createTestAdapter({
137
- header: (name) => (name === INF_TARGET_HEADER ? target : undefined),
138
- }), { apiKey: 'custom-key', allowedDomains: [/custom\.example$/] });
139
- expect(global.fetch).toHaveBeenCalledWith(target, expect.any(Object));
140
- });
141
- it('should forward x-inf-* request headers to upstream', async () => {
142
- const target = 'https://api.inference.sh/run';
143
- await processProxyRequest(createTestAdapter({
144
- header: (name) => {
145
- if (name === INF_TARGET_HEADER)
146
- return target;
147
- if (name === 'x-inf-session-id')
148
- return 'sess-123';
149
- return undefined;
150
- },
151
- headers: () => ({
152
- [INF_TARGET_HEADER]: target,
153
- 'x-inf-session-id': 'sess-123',
154
- }),
155
- }), { apiKey: 'key' });
156
- expect(global.fetch).toHaveBeenCalledWith(target, expect.objectContaining({
157
- headers: expect.objectContaining({
158
- 'x-inf-session-id': 'sess-123',
159
- }),
160
- }));
161
- });
162
- it('should omit body for GET requests', async () => {
163
- const target = 'https://api.inference.sh/tasks/1';
164
- await processProxyRequest(createTestAdapter({
165
- method: 'GET',
166
- header: (name) => (name === INF_TARGET_HEADER ? target : undefined),
167
- }), { apiKey: 'key' });
168
- expect(global.fetch).toHaveBeenCalledWith(target, expect.objectContaining({
169
- method: 'GET',
170
- body: undefined,
171
- }));
172
- });
173
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,125 +0,0 @@
1
- import { INF_TARGET_HEADER } from './index';
2
- import { handlers, pageHandler } from './nextjs';
3
- function createMockPageResponse() {
4
- const res = {
5
- statusCode: 200,
6
- headers: {},
7
- body: undefined,
8
- status(code) {
9
- this.statusCode = code;
10
- return this;
11
- },
12
- setHeader(name, value) {
13
- this.headers[name] = value;
14
- },
15
- json(data) {
16
- this.body = data;
17
- return this;
18
- },
19
- send(data) {
20
- this.body = data;
21
- return this;
22
- },
23
- };
24
- return res;
25
- }
26
- function createMockNextRequest(overrides = {}) {
27
- const headers = new Headers(overrides.headers ?? {});
28
- return {
29
- method: overrides.method ?? 'POST',
30
- url: overrides.url ?? 'http://localhost/api/inference/proxy',
31
- headers,
32
- text: () => Promise.resolve(overrides.body ?? '{"prompt":"hi"}'),
33
- };
34
- }
35
- describe('nextjs pageHandler', () => {
36
- const originalFetch = global.fetch;
37
- beforeEach(() => {
38
- jest.clearAllMocks();
39
- process.env.INFERENCE_API_KEY = 'nextjs-test-key';
40
- });
41
- afterEach(() => {
42
- global.fetch = originalFetch;
43
- });
44
- it('should return 400 when target URL is missing', async () => {
45
- const req = { method: 'POST', body: {}, headers: {}, query: {} };
46
- const res = createMockPageResponse();
47
- await pageHandler(req, res);
48
- expect(res.statusCode).toBe(400);
49
- expect(res.body).toEqual({
50
- error: `Missing ${INF_TARGET_HEADER} header or __inf_target query param`,
51
- });
52
- });
53
- it('should proxy JSON responses through res.json()', async () => {
54
- global.fetch = jest.fn().mockResolvedValue(new Response(JSON.stringify({ ok: true }), {
55
- status: 200,
56
- headers: { 'content-type': 'application/json' },
57
- }));
58
- const target = 'https://api.inference.sh/v1/run';
59
- const req = {
60
- method: 'POST',
61
- body: { prompt: 'hi' },
62
- headers: { [INF_TARGET_HEADER]: target },
63
- query: {},
64
- };
65
- const res = createMockPageResponse();
66
- await pageHandler(req, res);
67
- expect(res.statusCode).toBe(200);
68
- expect(res.body).toEqual({ ok: true });
69
- });
70
- it('should proxy non-JSON responses through res.send()', async () => {
71
- global.fetch = jest.fn().mockResolvedValue(new Response('plain text', {
72
- status: 200,
73
- headers: { 'content-type': 'text/plain' },
74
- }));
75
- const target = 'https://api.inference.sh/v1/run';
76
- const req = {
77
- method: 'POST',
78
- body: {},
79
- headers: { [INF_TARGET_HEADER]: target },
80
- query: {},
81
- };
82
- const res = createMockPageResponse();
83
- await pageHandler(req, res);
84
- expect(res.statusCode).toBe(200);
85
- expect(res.body).toBe('plain text');
86
- });
87
- });
88
- describe('nextjs handlers (App Router)', () => {
89
- const originalFetch = global.fetch;
90
- beforeEach(() => {
91
- jest.clearAllMocks();
92
- process.env.INFERENCE_API_KEY = 'nextjs-test-key';
93
- });
94
- afterEach(() => {
95
- global.fetch = originalFetch;
96
- });
97
- it('should return 400 when target URL is missing', async () => {
98
- const response = await handlers.GET(createMockNextRequest());
99
- expect(response.status).toBe(400);
100
- expect(await response.json()).toEqual({
101
- error: `Missing ${INF_TARGET_HEADER} header or __inf_target query param`,
102
- });
103
- });
104
- it('should passthrough streaming responses via Response body', async () => {
105
- const encoder = new TextEncoder();
106
- const stream = new ReadableStream({
107
- start(controller) {
108
- controller.enqueue(encoder.encode('data: {"x":1}\n\n'));
109
- controller.close();
110
- },
111
- });
112
- global.fetch = jest.fn().mockResolvedValue(new Response(stream, {
113
- status: 200,
114
- headers: { 'content-type': 'text/event-stream' },
115
- }));
116
- const target = 'https://api.inference.sh/v1/stream';
117
- const response = await handlers.GET(createMockNextRequest({
118
- method: 'GET',
119
- headers: { [INF_TARGET_HEADER]: target },
120
- }));
121
- expect(response.status).toBe(200);
122
- expect(response.body).toBeDefined();
123
- expect(response.headers.get('content-type')).toContain('text/event-stream');
124
- });
125
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,66 +0,0 @@
1
- import { INF_TARGET_HEADER } from './index';
2
- import { createHandler } from './remix';
3
- describe('remix createHandler', () => {
4
- const originalFetch = global.fetch;
5
- beforeEach(() => {
6
- jest.clearAllMocks();
7
- process.env.INFERENCE_API_KEY = 'remix-test-key';
8
- });
9
- afterEach(() => {
10
- global.fetch = originalFetch;
11
- });
12
- it('should return 400 when target URL is missing', async () => {
13
- const handler = createHandler();
14
- const request = new Request('http://localhost/api/inference/proxy', {
15
- method: 'POST',
16
- body: '{}',
17
- });
18
- const response = await handler({ request });
19
- expect(response.status).toBe(400);
20
- expect(await response.json()).toEqual({
21
- error: `Missing ${INF_TARGET_HEADER} header or __inf_target query param`,
22
- });
23
- });
24
- it('should proxy JSON responses with framework remix', async () => {
25
- global.fetch = jest.fn().mockResolvedValue(new Response(JSON.stringify({ ok: true }), {
26
- status: 200,
27
- headers: { 'content-type': 'application/json' },
28
- }));
29
- const target = 'https://api.inference.sh/v1/run';
30
- const handler = createHandler();
31
- const request = new Request('http://localhost/api/inference/proxy', {
32
- method: 'POST',
33
- headers: { [INF_TARGET_HEADER]: target },
34
- body: '{"prompt":"hi"}',
35
- });
36
- const response = await handler({ request });
37
- expect(response.status).toBe(200);
38
- expect(await response.json()).toEqual({ ok: true });
39
- expect(global.fetch).toHaveBeenCalledWith(target, expect.objectContaining({
40
- headers: expect.objectContaining({
41
- authorization: 'Bearer remix-test-key',
42
- }),
43
- }));
44
- });
45
- it('should use custom resolveApiKey when provided', async () => {
46
- global.fetch = jest.fn().mockResolvedValue(new Response(JSON.stringify({ ok: true }), {
47
- status: 200,
48
- headers: { 'content-type': 'application/json' },
49
- }));
50
- const handler = createHandler({
51
- resolveApiKey: async () => 'custom-remix-key',
52
- });
53
- const target = 'https://api.inference.sh/v1/run';
54
- const request = new Request('http://localhost/api/inference/proxy', {
55
- method: 'POST',
56
- headers: { [INF_TARGET_HEADER]: target },
57
- body: '{}',
58
- });
59
- await handler({ request });
60
- expect(global.fetch).toHaveBeenCalledWith(target, expect.objectContaining({
61
- headers: expect.objectContaining({
62
- authorization: 'Bearer custom-remix-key',
63
- }),
64
- }));
65
- });
66
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,69 +0,0 @@
1
- import { INF_TARGET_HEADER } from './index';
2
- import { createHandler } from './svelte';
3
- function createMockRequestEvent(request) {
4
- return { request };
5
- }
6
- describe('svelte createHandler', () => {
7
- const originalFetch = global.fetch;
8
- beforeEach(() => {
9
- jest.clearAllMocks();
10
- process.env.INFERENCE_API_KEY = 'svelte-test-key';
11
- });
12
- afterEach(() => {
13
- global.fetch = originalFetch;
14
- });
15
- it('should return 400 when target URL is missing', async () => {
16
- const handler = createHandler();
17
- const request = new Request('http://localhost/api/inference/proxy', {
18
- method: 'POST',
19
- body: '{}',
20
- });
21
- const response = await handler(createMockRequestEvent(request));
22
- expect(response.status).toBe(400);
23
- expect(await response.json()).toEqual({
24
- error: `Missing ${INF_TARGET_HEADER} header or __inf_target query param`,
25
- });
26
- });
27
- it('should proxy JSON responses with framework sveltekit', async () => {
28
- global.fetch = jest.fn().mockResolvedValue(new Response(JSON.stringify({ ok: true }), {
29
- status: 200,
30
- headers: { 'content-type': 'application/json' },
31
- }));
32
- const target = 'https://api.inference.sh/v1/run';
33
- const handler = createHandler();
34
- const request = new Request('http://localhost/api/inference/proxy', {
35
- method: 'POST',
36
- headers: { [INF_TARGET_HEADER]: target },
37
- body: '{"prompt":"hi"}',
38
- });
39
- const response = await handler(createMockRequestEvent(request));
40
- expect(response.status).toBe(200);
41
- expect(await response.json()).toEqual({ ok: true });
42
- expect(global.fetch).toHaveBeenCalledWith(target, expect.objectContaining({
43
- headers: expect.objectContaining({
44
- authorization: 'Bearer svelte-test-key',
45
- }),
46
- }));
47
- });
48
- it('should use custom resolveApiKey when provided', async () => {
49
- global.fetch = jest.fn().mockResolvedValue(new Response(JSON.stringify({ ok: true }), {
50
- status: 200,
51
- headers: { 'content-type': 'application/json' },
52
- }));
53
- const handler = createHandler({
54
- resolveApiKey: async () => 'custom-svelte-key',
55
- });
56
- const target = 'https://api.inference.sh/v1/run';
57
- const request = new Request('http://localhost/api/inference/proxy', {
58
- method: 'POST',
59
- headers: { [INF_TARGET_HEADER]: target },
60
- body: '{}',
61
- });
62
- await handler(createMockRequestEvent(request));
63
- expect(global.fetch).toHaveBeenCalledWith(target, expect.objectContaining({
64
- headers: expect.objectContaining({
65
- authorization: 'Bearer custom-svelte-key',
66
- }),
67
- }));
68
- });
69
- });
@@ -1,13 +0,0 @@
1
- /**
2
- * Sessions integration tests for @inferencesh/sdk
3
- *
4
- * These tests hit the real API and require INFERENCE_API_KEY to be set.
5
- * Run with: npm run test:integration
6
- *
7
- * Prerequisites:
8
- * - API and scheduler must be running
9
- * - Test app deployed: infsh/session-test
10
- *
11
- * @jest-environment node
12
- */
13
- export {};