@superblocksteam/sdk-api 2.0.103 → 2.0.104-next.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.
Files changed (106) hide show
  1. package/README.md +58 -299
  2. package/dist/api/definition.js +1 -1
  3. package/dist/api/definition.js.map +1 -1
  4. package/dist/api/index.d.ts +0 -2
  5. package/dist/api/index.d.ts.map +1 -1
  6. package/dist/api/index.js +0 -2
  7. package/dist/api/index.js.map +1 -1
  8. package/dist/errors.d.ts +0 -44
  9. package/dist/errors.d.ts.map +1 -1
  10. package/dist/errors.js +0 -32
  11. package/dist/errors.js.map +1 -1
  12. package/dist/index.d.ts +5 -5
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +5 -9
  15. package/dist/index.js.map +1 -1
  16. package/dist/integrations/anthropic/types.d.ts +3 -22
  17. package/dist/integrations/anthropic/types.d.ts.map +1 -1
  18. package/dist/integrations/base/index.d.ts +1 -1
  19. package/dist/integrations/base/index.d.ts.map +1 -1
  20. package/dist/integrations/base/rest-api-integration-client.d.ts +4 -48
  21. package/dist/integrations/base/rest-api-integration-client.d.ts.map +1 -1
  22. package/dist/integrations/base/rest-api-integration-client.js +2 -110
  23. package/dist/integrations/base/rest-api-integration-client.js.map +1 -1
  24. package/dist/integrations/base/types.d.ts +1 -67
  25. package/dist/integrations/base/types.d.ts.map +1 -1
  26. package/dist/integrations/index.d.ts +1 -1
  27. package/dist/integrations/index.d.ts.map +1 -1
  28. package/dist/integrations/index.js.map +1 -1
  29. package/dist/integrations/openai_v2/types.d.ts +4 -22
  30. package/dist/integrations/openai_v2/types.d.ts.map +1 -1
  31. package/dist/integrations/registry.d.ts +0 -16
  32. package/dist/integrations/registry.d.ts.map +1 -1
  33. package/dist/integrations/registry.js +38 -38
  34. package/dist/integrations/registry.js.map +1 -1
  35. package/dist/integrations/registry.test.js +1 -3
  36. package/dist/integrations/registry.test.js.map +1 -1
  37. package/dist/integrations/restapiintegration/types.d.ts +2 -2
  38. package/dist/integrations/restapiintegration/types.d.ts.map +1 -1
  39. package/dist/integrations/snowflakecortex/client.d.ts +1 -2
  40. package/dist/integrations/snowflakecortex/client.d.ts.map +1 -1
  41. package/dist/integrations/snowflakecortex/client.js +1 -2
  42. package/dist/integrations/snowflakecortex/client.js.map +1 -1
  43. package/dist/integrations/snowflakecortex/types.d.ts +3 -4
  44. package/dist/integrations/snowflakecortex/types.d.ts.map +1 -1
  45. package/dist/runtime/index.d.ts +0 -3
  46. package/dist/runtime/index.d.ts.map +1 -1
  47. package/dist/runtime/index.js +1 -6
  48. package/dist/runtime/index.js.map +1 -1
  49. package/package.json +1 -1
  50. package/src/api/definition.ts +1 -1
  51. package/src/api/index.ts +0 -4
  52. package/src/errors.ts +0 -48
  53. package/src/index.ts +2 -28
  54. package/src/integrations/anthropic/README.md +5 -101
  55. package/src/integrations/anthropic/types.ts +3 -29
  56. package/src/integrations/base/index.ts +0 -2
  57. package/src/integrations/base/rest-api-integration-client.ts +4 -153
  58. package/src/integrations/base/types.ts +3 -74
  59. package/src/integrations/cohere/README.md +11 -11
  60. package/src/integrations/fireworks/README.md +43 -17
  61. package/src/integrations/googleanalytics/README.md +2 -2
  62. package/src/integrations/googledrive/README.md +2 -2
  63. package/src/integrations/groq/README.md +41 -34
  64. package/src/integrations/gsheets/README.md +2 -2
  65. package/src/integrations/index.ts +0 -1
  66. package/src/integrations/launchdarkly/README.md +2 -2
  67. package/src/integrations/mistral/README.md +39 -13
  68. package/src/integrations/openai_v2/README.md +44 -116
  69. package/src/integrations/openai_v2/types.ts +4 -29
  70. package/src/integrations/pagerduty/README.md +2 -2
  71. package/src/integrations/perplexity/README.md +2 -1
  72. package/src/integrations/registry.test.ts +1 -3
  73. package/src/integrations/registry.ts +38 -127
  74. package/src/integrations/restapiintegration/README.md +4 -43
  75. package/src/integrations/restapiintegration/types.ts +2 -8
  76. package/src/integrations/sendgrid/README.md +2 -2
  77. package/src/integrations/snowflakecortex/README.md +4 -53
  78. package/src/integrations/snowflakecortex/client.ts +2 -3
  79. package/src/integrations/snowflakecortex/types.ts +3 -11
  80. package/src/integrations/stabilityai/README.md +2 -2
  81. package/src/runtime/index.ts +1 -23
  82. package/dist/api/streaming.d.ts +0 -229
  83. package/dist/api/streaming.d.ts.map +0 -1
  84. package/dist/api/streaming.js +0 -107
  85. package/dist/api/streaming.js.map +0 -1
  86. package/dist/api/streaming.test.d.ts +0 -5
  87. package/dist/api/streaming.test.d.ts.map +0 -1
  88. package/dist/api/streaming.test.js +0 -364
  89. package/dist/api/streaming.test.js.map +0 -1
  90. package/dist/runtime/execute.d.ts +0 -128
  91. package/dist/runtime/execute.d.ts.map +0 -1
  92. package/dist/runtime/execute.js +0 -84
  93. package/dist/runtime/execute.js.map +0 -1
  94. package/dist/runtime/streaming-context.d.ts +0 -49
  95. package/dist/runtime/streaming-context.d.ts.map +0 -1
  96. package/dist/runtime/streaming-context.js +0 -71
  97. package/dist/runtime/streaming-context.js.map +0 -1
  98. package/dist/runtime/streaming-executor.d.ts +0 -159
  99. package/dist/runtime/streaming-executor.d.ts.map +0 -1
  100. package/dist/runtime/streaming-executor.js +0 -229
  101. package/dist/runtime/streaming-executor.js.map +0 -1
  102. package/src/api/streaming.test.ts +0 -433
  103. package/src/api/streaming.ts +0 -303
  104. package/src/runtime/execute.ts +0 -221
  105. package/src/runtime/streaming-context.ts +0 -164
  106. package/src/runtime/streaming-executor.ts +0 -367
@@ -1,303 +0,0 @@
1
- /**
2
- * Streaming API definition function.
3
- *
4
- * This module provides the `streamingApi()` function used to define TypeScript-based APIs
5
- * that yield chunks over time, enabling real-time streaming from LLMs and other sources.
6
- */
7
-
8
- import type { z } from "zod";
9
-
10
- import {
11
- extractIntegrationDeclarations,
12
- type IntegrationDeclaration,
13
- } from "../integrations/declarations.js";
14
- import type { ApiContext, AnyIntegrationRef } from "../types.js";
15
- import { consumeEntryPoint } from "./definition.js";
16
-
17
- /**
18
- * Configuration for defining a streaming TypeScript-based API.
19
- *
20
- * @template TInput - Zod schema type for input validation
21
- * @template TChunk - Zod schema type for each streamed chunk
22
- * @template TIntegrations - Record of integration declarations
23
- *
24
- * @example
25
- * ```typescript
26
- * import { streamingApi, z, anthropic } from '@superblocksteam/sdk-api';
27
- *
28
- * export default streamingApi({
29
- * integrations: {
30
- * ai: anthropic('Production Anthropic'),
31
- * },
32
- *
33
- * input: z.object({
34
- * prompt: z.string(),
35
- * }),
36
- *
37
- * chunk: z.object({
38
- * type: z.literal('text-delta'),
39
- * text: z.string(),
40
- * }),
41
- *
42
- * async *run(ctx, { prompt }) {
43
- * const stream = ctx.integrations.ai.streamApiRequest(
44
- * {
45
- * method: 'POST',
46
- * path: '/v1/messages',
47
- * body: {
48
- * model: 'claude-3-5-sonnet-20241022',
49
- * max_tokens: 1024,
50
- * stream: true,
51
- * messages: [{ role: 'user', content: prompt }],
52
- * },
53
- * },
54
- * { chunk: AnthropicStreamEventSchema }
55
- * );
56
- *
57
- * for await (const event of stream) {
58
- * if (event.type === 'content_block_delta') {
59
- * yield { type: 'text-delta' as const, text: event.delta.text };
60
- * }
61
- * }
62
- * },
63
- * });
64
- * ```
65
- */
66
- export interface StreamingApiConfig<
67
- TInput extends z.ZodType,
68
- TChunk extends z.ZodType,
69
- TIntegrations extends Record<string, AnyIntegrationRef> = Record<
70
- string,
71
- never
72
- >,
73
- > {
74
- /**
75
- * Name for this API.
76
- *
77
- * Used for identification in execution logs and debugging.
78
- */
79
- name: string;
80
-
81
- /**
82
- * Plain-language summary of what this API does and which integrations it uses,
83
- * written for a non-technical audience.
84
- *
85
- * This field is auto-generated by the AI agent when creating or editing an API.
86
- */
87
- description?: string;
88
-
89
- /**
90
- * Integration declarations for this API.
91
- *
92
- * Declare integrations upfront to enable type-safe access via `ctx.integrations`
93
- * and to allow the runtime to authenticate integrations before execution.
94
- *
95
- * @example
96
- * ```typescript
97
- * integrations: {
98
- * ai: anthropic('Production Anthropic'),
99
- * db: postgres('Cache DB'),
100
- * }
101
- * ```
102
- */
103
- integrations?: TIntegrations;
104
-
105
- /** Zod schema for input validation */
106
- input: TInput;
107
-
108
- /**
109
- * Zod schema for validating each streamed chunk.
110
- *
111
- * Every chunk yielded by the run function is validated against this schema.
112
- * Validation errors will terminate the stream.
113
- */
114
- chunk: TChunk;
115
-
116
- /**
117
- * The streaming API implementation function (async generator).
118
- *
119
- * @param ctx - Execution context with access to integrations
120
- * @param input - Validated input parameters (can be destructured)
121
- * @yields Chunks that are validated against the chunk schema
122
- */
123
- run: (
124
- ctx: ApiContext<TIntegrations>,
125
- input: z.infer<TInput>,
126
- ) => AsyncIterable<z.infer<TChunk>>;
127
- }
128
-
129
- /**
130
- * A compiled streaming API definition ready for execution.
131
- *
132
- * @template TInput - The inferred input type
133
- * @template TChunk - The inferred chunk type
134
- */
135
- export interface CompiledStreamingApi<TInput = unknown, TChunk = unknown> {
136
- /** Name of the API for identification in logs and debugging */
137
- readonly name: string;
138
-
139
- /** Plain-language summary of what this API does */
140
- readonly description?: string;
141
- /**
142
- * Source file path relative to the app root (e.g. "server/apis/Chat/api.ts").
143
- * Injected automatically by the Vite plugin — not authored by the user.
144
- */
145
- readonly entryPoint?: string;
146
-
147
- /** Zod schema for validating inputs */
148
- readonly inputSchema: z.ZodType<TInput>;
149
-
150
- /**
151
- * Zod schema for validating each streamed chunk.
152
- *
153
- * Every chunk yielded by the API is validated against this schema
154
- * before being sent to the client.
155
- */
156
- readonly chunkSchema: z.ZodType<TChunk>;
157
-
158
- /**
159
- * The streaming API implementation function.
160
- *
161
- * @param ctx - Execution context
162
- * @param input - Validated input parameters
163
- * @returns AsyncIterable yielding validated chunks
164
- */
165
- readonly run: (
166
- ctx: ApiContext<Record<string, AnyIntegrationRef>>,
167
- input: TInput,
168
- ) => AsyncIterable<TChunk>;
169
-
170
- /**
171
- * Declared integrations for upfront authentication.
172
- *
173
- * This array contains all integrations declared in the API config,
174
- * allowing the runtime to authenticate them before API execution.
175
- */
176
- readonly integrations: ReadonlyArray<IntegrationDeclaration>;
177
-
178
- /**
179
- * Runtime flag indicating this is a streaming API.
180
- *
181
- * Always `true` for streaming APIs. Use `isStreamingApi()` type guard
182
- * to distinguish streaming APIs from regular APIs at runtime.
183
- */
184
- readonly isStreaming: true;
185
- }
186
-
187
- /**
188
- * Define a streaming TypeScript-based API with chunk validation.
189
- *
190
- * This function creates a compiled streaming API definition that yields
191
- * chunks over time. Each chunk is validated against the provided schema.
192
- *
193
- * Use this for:
194
- * - Real-time LLM token streaming (OpenAI, Anthropic, etc.)
195
- * - Server-sent events
196
- * - Long-running operations with progress updates
197
- * - Any API that produces output incrementally
198
- *
199
- * @param config - The streaming API configuration
200
- * @returns A compiled streaming API definition
201
- *
202
- * @example
203
- * ```typescript
204
- * import { streamingApi, z, openai } from '@superblocksteam/sdk-api';
205
- *
206
- * export default streamingApi({
207
- * integrations: {
208
- * ai: openai('Production OpenAI'),
209
- * },
210
- *
211
- * input: z.object({
212
- * prompt: z.string(),
213
- * }),
214
- *
215
- * chunk: z.object({
216
- * content: z.string(),
217
- * }),
218
- *
219
- * async *run(ctx, { prompt }) {
220
- * const stream = ctx.integrations.ai.streamApiRequest(
221
- * {
222
- * method: 'POST',
223
- * path: '/v1/chat/completions',
224
- * body: {
225
- * model: 'gpt-4',
226
- * stream: true,
227
- * messages: [{ role: 'user', content: prompt }],
228
- * },
229
- * },
230
- * { chunk: OpenAIChunkSchema }
231
- * );
232
- *
233
- * for await (const chunk of stream) {
234
- * const content = chunk.choices[0]?.delta?.content;
235
- * if (content) {
236
- * yield { content };
237
- * }
238
- * }
239
- * },
240
- * });
241
- * ```
242
- */
243
- export function streamingApi<
244
- TInput extends z.ZodType,
245
- TChunk extends z.ZodType,
246
- TIntegrations extends Record<string, AnyIntegrationRef> = Record<
247
- string,
248
- never
249
- >,
250
- >(
251
- config: StreamingApiConfig<TInput, TChunk, TIntegrations>,
252
- ): CompiledStreamingApi<z.infer<TInput>, z.infer<TChunk>> {
253
- // Extract integration declarations for upfront auth
254
- const integrations = extractIntegrationDeclarations(config.integrations);
255
-
256
- const compiled: CompiledStreamingApi<z.infer<TInput>, z.infer<TChunk>> = {
257
- name: config.name,
258
- description: config.description,
259
- entryPoint: consumeEntryPoint(),
260
- inputSchema: config.input,
261
- chunkSchema: config.chunk,
262
- run: config.run as (
263
- ctx: ApiContext<Record<string, AnyIntegrationRef>>,
264
- input: z.infer<TInput>,
265
- ) => AsyncIterable<z.infer<TChunk>>,
266
- integrations,
267
- isStreaming: true,
268
- };
269
-
270
- return compiled;
271
- }
272
-
273
- /**
274
- * Type guard to check if an API is a streaming API.
275
- *
276
- * @param api - The API to check
277
- * @returns `true` if the API is a streaming API, `false` otherwise
278
- *
279
- * @example
280
- * ```typescript
281
- * import { isStreamingApi, executeApi, executeStreamingApi } from '@superblocksteam/sdk-api';
282
- *
283
- * if (isStreamingApi(api)) {
284
- * await executeStreamingApi(api, request);
285
- * } else {
286
- * await executeApi(api, request);
287
- * }
288
- * ```
289
- */
290
- export function isStreamingApi(
291
- api: unknown,
292
- ): api is CompiledStreamingApi<unknown, unknown> {
293
- return (
294
- typeof api === "object" &&
295
- api !== null &&
296
- "isStreaming" in api &&
297
- (api as Record<string, unknown>).isStreaming === true &&
298
- "inputSchema" in api &&
299
- "chunkSchema" in api &&
300
- "run" in api &&
301
- typeof (api as Record<string, unknown>).run === "function"
302
- );
303
- }
@@ -1,221 +0,0 @@
1
- /**
2
- * Unified API execution function.
3
- *
4
- * Provides a single `execute()` function that handles both regular and streaming APIs,
5
- * detecting the API type at runtime and returning appropriate result types.
6
- */
7
-
8
- import type { CompiledApi } from "../api/definition.js";
9
- import { isStreamingApi, type CompiledStreamingApi } from "../api/streaming.js";
10
- import type { TraceMetadata } from "../integrations/registry.js";
11
- import type { IntegrationConfig } from "../integrations/types.js";
12
- import type { ApiUser } from "../types.js";
13
- import { executeApi, type ExecuteApiResponse } from "./executor.js";
14
- import { createStreamingApiGenerator } from "./streaming-executor.js";
15
-
16
- /**
17
- * Unified request for executing any API (regular or streaming).
18
- *
19
- * This interface combines the fields from both `ExecuteApiRequest` and
20
- * `ExecuteStreamingApiRequest` into a single type. The `executeStreamingQuery`
21
- * field is only required when executing streaming APIs that use streaming
22
- * integration support.
23
- */
24
- export interface UnifiedExecuteApiRequest {
25
- /** Raw input data to be validated */
26
- input: unknown;
27
-
28
- /** Available integration configurations */
29
- integrations: IntegrationConfig[];
30
-
31
- /** Unique execution ID for tracing */
32
- executionId: string;
33
-
34
- /** Environment variables available to the API */
35
- env: Record<string, string>;
36
-
37
- /** User information extracted from the Superblocks JWT */
38
- user: ApiUser;
39
-
40
- /**
41
- * Function to execute integration operations (non-streaming).
42
- *
43
- * @param integrationId - The integration ID
44
- * @param request - Plugin-specific request object
45
- * @param bindings - Optional bindings for language plugins
46
- * @returns Promise resolving to the operation result
47
- */
48
- executeQuery: (
49
- integrationId: string,
50
- request: Record<string, unknown>,
51
- bindings?: Record<string, unknown>,
52
- metadata?: TraceMetadata,
53
- ) => Promise<unknown>;
54
-
55
- /**
56
- * Function to execute streaming integration operations.
57
- * Optional - only needed for streaming APIs that use streaming integrations.
58
- *
59
- * @param integrationId - The integration ID
60
- * @param request - Plugin-specific request object
61
- * @param metadata - Optional trace metadata for diagnostics
62
- * @returns AsyncIterable yielding raw chunks
63
- */
64
- executeStreamingQuery?: (
65
- integrationId: string,
66
- request: Record<string, unknown>,
67
- metadata?: TraceMetadata,
68
- ) => AsyncIterable<unknown>;
69
- }
70
-
71
- /**
72
- * Union type for any compiled API (regular or streaming).
73
- *
74
- * Note: This is a permissive type for runtime use. The `execute` function
75
- * provides overloads for proper type inference.
76
- */
77
- export type AnyCompiledApi =
78
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
79
- | CompiledApi<any, any>
80
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
81
- | CompiledStreamingApi<any, any>;
82
-
83
- /**
84
- * Execute a regular (non-streaming) compiled API.
85
- *
86
- * @param api - The compiled API definition
87
- * @param request - The execution request
88
- * @returns Promise resolving to execution response with success/error and output
89
- *
90
- * @example
91
- * ```typescript
92
- * const response = await execute(myApi, {
93
- * input: { userId: '123' },
94
- * integrations: [...],
95
- * executionId: 'exec_abc',
96
- * env: {},
97
- * executeQuery: async (id, req) => orchestrator.execute(id, req),
98
- * });
99
- *
100
- * if (response.success) {
101
- * console.log(response.output);
102
- * } else {
103
- * console.error(response.error);
104
- * }
105
- * ```
106
- */
107
- export function execute<TInput, TOutput>(
108
- api: CompiledApi<TInput, TOutput>,
109
- request: UnifiedExecuteApiRequest,
110
- ): Promise<ExecuteApiResponse<TOutput>>;
111
-
112
- /**
113
- * Execute a streaming compiled API.
114
- *
115
- * @param api - The compiled streaming API definition
116
- * @param request - The execution request
117
- * @returns AsyncGenerator that yields validated chunks
118
- *
119
- * @example
120
- * ```typescript
121
- * const stream = execute(myStreamingApi, {
122
- * input: { prompt: 'Hello' },
123
- * integrations: [...],
124
- * executionId: 'exec_abc',
125
- * env: {},
126
- * executeQuery: async (id, req) => orchestrator.execute(id, req),
127
- * executeStreamingQuery: (id, req) => orchestrator.stream(id, req),
128
- * });
129
- *
130
- * for await (const chunk of stream) {
131
- * console.log(chunk.text);
132
- * }
133
- * ```
134
- */
135
- export function execute<TInput, TChunk>(
136
- api: CompiledStreamingApi<TInput, TChunk>,
137
- request: UnifiedExecuteApiRequest,
138
- ): AsyncGenerator<TChunk, void, undefined>;
139
-
140
- /**
141
- * Execute any compiled API (regular or streaming).
142
- *
143
- * This unified function detects whether the API is streaming or regular
144
- * and returns the appropriate result type:
145
- *
146
- * - **Regular APIs**: Returns `Promise<ExecuteApiResponse<TOutput>>`
147
- * - **Streaming APIs**: Returns `AsyncGenerator<TChunk>`
148
- *
149
- * @param api - The compiled API definition (regular or streaming)
150
- * @param request - The execution request
151
- * @returns Promise for regular APIs, AsyncGenerator for streaming APIs
152
- *
153
- * @example Regular API
154
- * ```typescript
155
- * const response = await execute(myApi, {
156
- * input: { userId: '123' },
157
- * integrations: [...],
158
- * executionId: 'exec_abc',
159
- * env: {},
160
- * executeQuery: async (id, req) => orchestrator.execute(id, req),
161
- * });
162
- *
163
- * if (response.success) {
164
- * console.log(response.output);
165
- * }
166
- * ```
167
- *
168
- * @example Streaming API
169
- * ```typescript
170
- * const stream = execute(myStreamingApi, {
171
- * input: { prompt: 'Hello' },
172
- * integrations: [...],
173
- * executionId: 'exec_abc',
174
- * env: {},
175
- * executeQuery: async (id, req) => orchestrator.execute(id, req),
176
- * executeStreamingQuery: (id, req) => orchestrator.stream(id, req),
177
- * });
178
- *
179
- * for await (const chunk of stream) {
180
- * console.log(chunk.text);
181
- * }
182
- * ```
183
- */
184
- export function execute(
185
- api: AnyCompiledApi,
186
- request: UnifiedExecuteApiRequest,
187
- ):
188
- | Promise<ExecuteApiResponse<unknown>>
189
- | AsyncGenerator<unknown, void, undefined> {
190
- if (isStreamingApi(api)) {
191
- // Streaming API - return generator directly
192
- return createStreamingApiGenerator(
193
- api as CompiledStreamingApi<unknown, unknown>,
194
- request,
195
- );
196
- } else {
197
- // Regular API - return promise
198
- return executeApi(api as CompiledApi<unknown, unknown>, request);
199
- }
200
- }
201
-
202
- /**
203
- * Type guard to check if an API is a streaming API.
204
- *
205
- * Use this to determine which result type you'll get from `execute()`.
206
- *
207
- * @param api - The API to check
208
- * @returns `true` if the API is a streaming API
209
- *
210
- * @example
211
- * ```typescript
212
- * if (isStreamingApi(api)) {
213
- * const stream = execute(api, request);
214
- * for await (const chunk of stream) { ... }
215
- * } else {
216
- * const response = await execute(api, request);
217
- * if (response.success) { ... }
218
- * }
219
- * ```
220
- */
221
- export { isStreamingApi };
@@ -1,164 +0,0 @@
1
- /**
2
- * Streaming API execution context factory.
3
- *
4
- * Creates the context object for streaming API functions, providing
5
- * access to integrations (with streaming support), logging, and environment.
6
- */
7
-
8
- import type { IntegrationDeclaration } from "../integrations/declarations.js";
9
- import {
10
- createClient,
11
- type QueryExecutor,
12
- type StreamingQueryExecutor,
13
- type TraceMetadata,
14
- } from "../integrations/registry.js";
15
- import type {
16
- IntegrationConfig,
17
- IntegrationClientImpl,
18
- } from "../integrations/types.js";
19
- import type {
20
- ApiContext,
21
- ApiUser,
22
- Logger,
23
- AnyIntegrationRef,
24
- } from "../types.js";
25
- import { createDefaultLogger } from "./logger.js";
26
-
27
- /**
28
- * Options for creating a streaming API execution context.
29
- */
30
- export interface CreateStreamingContextOptions {
31
- /** Available integration configurations keyed by id */
32
- integrations: Map<string, IntegrationConfig>;
33
-
34
- /**
35
- * Declared integrations from the API config.
36
- */
37
- integrationDeclarations: IntegrationDeclaration[];
38
-
39
- /**
40
- * Function to execute integration operations (non-streaming).
41
- */
42
- executeQuery: (
43
- integrationId: string,
44
- request: Record<string, unknown>,
45
- bindings?: Record<string, unknown>,
46
- metadata?: TraceMetadata,
47
- ) => Promise<unknown>;
48
-
49
- /**
50
- * Function to execute streaming integration operations.
51
- * Optional - if not provided, streaming operations will throw an error.
52
- */
53
- executeStreamingQuery?: (
54
- integrationId: string,
55
- request: Record<string, unknown>,
56
- metadata?: TraceMetadata,
57
- ) => AsyncIterable<unknown>;
58
-
59
- /** Execution ID for logging correlation */
60
- executionId: string;
61
-
62
- /** Environment variables */
63
- env: Record<string, string>;
64
-
65
- /** User information from JWT */
66
- user: ApiUser;
67
-
68
- /** Optional custom logger */
69
- logger?: Logger;
70
- }
71
-
72
- /**
73
- * Creates a streaming API execution context.
74
- *
75
- * Similar to createApiContext but supports streaming query execution
76
- * for integration clients that support it.
77
- *
78
- * @param options - Context creation options
79
- * @returns The API context for streaming API execution
80
- */
81
- export function createStreamingApiContext(
82
- options: CreateStreamingContextOptions,
83
- ): ApiContext<Record<string, AnyIntegrationRef>> {
84
- const {
85
- integrations,
86
- integrationDeclarations,
87
- executeQuery,
88
- executeStreamingQuery,
89
- executionId,
90
- env,
91
- user,
92
- logger,
93
- } = options;
94
-
95
- // Cache for created integration clients
96
- const clientCache = new Map<string, IntegrationClientImpl>();
97
-
98
- // Create logger
99
- const log = logger ?? createDefaultLogger(executionId);
100
-
101
- /**
102
- * Gets or creates a typed integration client by id and plugin ID.
103
- * Supports streaming execution if provided.
104
- */
105
- function getTypedClient(id: string, pluginId: string): IntegrationClientImpl {
106
- const cached = clientCache.get(id);
107
- if (cached) {
108
- return cached;
109
- }
110
-
111
- const config = integrations.get(id);
112
-
113
- // Create executor bound to this integration
114
- const boundExecutor: QueryExecutor = (
115
- request: Record<string, unknown>,
116
- bindings?: Record<string, unknown>,
117
- metadata?: TraceMetadata,
118
- ) => executeQuery(id, request, bindings, metadata);
119
-
120
- // Create streaming executor if provided
121
- const boundStreamingExecutor: StreamingQueryExecutor | undefined =
122
- executeStreamingQuery
123
- ? (request: Record<string, unknown>, metadata?: TraceMetadata) =>
124
- executeStreamingQuery(id, request, metadata)
125
- : undefined;
126
-
127
- const clientConfig: IntegrationConfig = config ?? {
128
- id,
129
- name: id,
130
- pluginId,
131
- configuration: {},
132
- };
133
-
134
- // Create client with streaming support
135
- const client = createClient({
136
- config: clientConfig,
137
- executeQuery: boundExecutor,
138
- executeStreamingQuery: boundStreamingExecutor,
139
- });
140
-
141
- clientCache.set(id, client);
142
- return client;
143
- }
144
-
145
- // Build the integrations object from declarations
146
- const integrationsObject: Record<string, IntegrationClientImpl> = {};
147
-
148
- for (const declaration of integrationDeclarations) {
149
- Object.defineProperty(integrationsObject, declaration.key, {
150
- get: () => getTypedClient(declaration.id, declaration.pluginId),
151
- enumerable: true,
152
- configurable: false,
153
- });
154
- }
155
-
156
- return {
157
- integrations: integrationsObject as ApiContext<
158
- Record<string, AnyIntegrationRef>
159
- >["integrations"],
160
- log,
161
- env: Object.freeze({ ...env }),
162
- user,
163
- };
164
- }