@superblocksteam/sdk-api 0.0.9 → 0.0.11

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 (54) hide show
  1. package/README.md +23 -0
  2. package/dist/index.d.ts +1 -1
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/integrations/dynamodb/client.d.ts +6 -2
  6. package/dist/integrations/dynamodb/client.d.ts.map +1 -1
  7. package/dist/integrations/dynamodb/client.js +83 -10
  8. package/dist/integrations/dynamodb/client.js.map +1 -1
  9. package/dist/integrations/dynamodb/client.test.d.ts +8 -0
  10. package/dist/integrations/dynamodb/client.test.d.ts.map +1 -0
  11. package/dist/integrations/dynamodb/client.test.js +198 -0
  12. package/dist/integrations/dynamodb/client.test.js.map +1 -0
  13. package/dist/integrations/dynamodb/index.d.ts +1 -1
  14. package/dist/integrations/dynamodb/index.d.ts.map +1 -1
  15. package/dist/integrations/dynamodb/index.js.map +1 -1
  16. package/dist/integrations/dynamodb/types.d.ts +27 -1
  17. package/dist/integrations/dynamodb/types.d.ts.map +1 -1
  18. package/dist/integrations/index.d.ts +1 -1
  19. package/dist/integrations/index.d.ts.map +1 -1
  20. package/dist/integrations/index.js.map +1 -1
  21. package/dist/runtime/context.d.ts +6 -0
  22. package/dist/runtime/context.d.ts.map +1 -1
  23. package/dist/runtime/context.js +2 -1
  24. package/dist/runtime/context.js.map +1 -1
  25. package/dist/runtime/executor.d.ts +6 -0
  26. package/dist/runtime/executor.d.ts.map +1 -1
  27. package/dist/runtime/executor.js +1 -0
  28. package/dist/runtime/executor.js.map +1 -1
  29. package/dist/types.d.ts +10 -0
  30. package/dist/types.d.ts.map +1 -1
  31. package/package.json +1 -1
  32. package/src/index.ts +1 -0
  33. package/src/integrations/anthropic/README.md +7 -0
  34. package/src/integrations/bigquery/README.md +1 -0
  35. package/src/integrations/box/README.md +3 -0
  36. package/src/integrations/cohere/README.md +7 -0
  37. package/src/integrations/dynamodb/README.md +33 -12
  38. package/src/integrations/dynamodb/client.test.ts +254 -0
  39. package/src/integrations/dynamodb/client.ts +121 -16
  40. package/src/integrations/dynamodb/index.ts +5 -1
  41. package/src/integrations/dynamodb/types.ts +33 -1
  42. package/src/integrations/fireworks/README.md +7 -0
  43. package/src/integrations/gemini/README.md +8 -0
  44. package/src/integrations/groq/README.md +7 -0
  45. package/src/integrations/index.ts +1 -0
  46. package/src/integrations/mistral/README.md +7 -0
  47. package/src/integrations/openai_v2/README.md +7 -0
  48. package/src/integrations/perplexity/README.md +7 -0
  49. package/src/integrations/s3/README.md +1 -0
  50. package/src/integrations/snowflakecortex/README.md +8 -0
  51. package/src/integrations/stabilityai/README.md +7 -0
  52. package/src/runtime/context.ts +9 -0
  53. package/src/runtime/executor.ts +8 -0
  54. package/src/types.ts +11 -0
@@ -12,7 +12,23 @@ import { RestApiValidationError } from "../../errors.js";
12
12
  import { IntegrationError } from "../../runtime/errors.js";
13
13
  import type { QueryExecutor, TraceMetadata } from "../registry.js";
14
14
  import type { IntegrationConfig, IntegrationClientImpl } from "../types.js";
15
- import type { DynamoDBClient, DynamoDBAttributeValue } from "./types.js";
15
+ import type {
16
+ DynamoDBClient,
17
+ DynamoDBAttributeValue,
18
+ DynamoDBScanOptions,
19
+ } from "./types.js";
20
+
21
+ const DYNAMODB_SCAN_OPTION_KEYS = new Set<string>([
22
+ "filterExpression",
23
+ "expressionAttributeValues",
24
+ "expressionAttributeNames",
25
+ "exclusiveStartKey",
26
+ "limit",
27
+ "projectionExpression",
28
+ "indexName",
29
+ "segment",
30
+ "totalSegments",
31
+ ]);
16
32
 
17
33
  /**
18
34
  * Internal implementation of DynamoDBClient.
@@ -189,33 +205,120 @@ export class DynamoDBClientImpl
189
205
  return this.executeWithErrorHandling(request, "deleteItem", metadata);
190
206
  }
191
207
 
208
+ /** Copy optional AWS Scan fields onto the request body. */
209
+ private applyScanParams(
210
+ params: Record<string, unknown>,
211
+ options: DynamoDBScanOptions,
212
+ ): void {
213
+ if (options.filterExpression) {
214
+ params.FilterExpression = options.filterExpression;
215
+ }
216
+ if (
217
+ options.expressionAttributeValues &&
218
+ Object.keys(options.expressionAttributeValues).length > 0
219
+ ) {
220
+ params.ExpressionAttributeValues = options.expressionAttributeValues;
221
+ }
222
+ if (
223
+ options.expressionAttributeNames &&
224
+ Object.keys(options.expressionAttributeNames).length > 0
225
+ ) {
226
+ params.ExpressionAttributeNames = options.expressionAttributeNames;
227
+ }
228
+ if (options.exclusiveStartKey) {
229
+ params.ExclusiveStartKey = options.exclusiveStartKey;
230
+ }
231
+ if (options.limit !== undefined) {
232
+ params.Limit = options.limit;
233
+ }
234
+ if (options.projectionExpression) {
235
+ params.ProjectionExpression = options.projectionExpression;
236
+ }
237
+ if (options.indexName) {
238
+ params.IndexName = options.indexName;
239
+ }
240
+ if (options.segment !== undefined) {
241
+ params.Segment = options.segment;
242
+ }
243
+ if (options.totalSegments !== undefined) {
244
+ params.TotalSegments = options.totalSegments;
245
+ }
246
+ }
247
+
248
+ private isScanOptions(value: unknown): value is DynamoDBScanOptions {
249
+ return (
250
+ typeof value === "object" &&
251
+ value !== null &&
252
+ Object.keys(value).every((key) => DYNAMODB_SCAN_OPTION_KEYS.has(key))
253
+ );
254
+ }
255
+
256
+ private isTraceMetadata(value: unknown): value is TraceMetadata {
257
+ return (
258
+ typeof value === "object" &&
259
+ value !== null &&
260
+ Object.keys(value).every(
261
+ (key) => key === "label" || key === "description",
262
+ ) &&
263
+ Object.values(value).every(
264
+ (entry) => entry === undefined || typeof entry === "string",
265
+ )
266
+ );
267
+ }
268
+
192
269
  async scan<T>(
193
270
  table: string,
194
271
  schema: z.ZodSchema<T>,
195
- filterExpression?: string,
196
- expressionAttributeValues?: Record<string, DynamoDBAttributeValue>,
272
+ filterExpressionOrOptions?: string | DynamoDBScanOptions,
273
+ expressionAttributeValuesOrMetadata?:
274
+ | Record<string, DynamoDBAttributeValue>
275
+ | TraceMetadata,
197
276
  expressionAttributeNames?: Record<string, string>,
198
277
  metadata?: TraceMetadata,
199
278
  ): Promise<T> {
200
279
  const params: Record<string, unknown> = { TableName: table };
280
+ let resolvedMetadata = metadata;
281
+
282
+ if (
283
+ typeof filterExpressionOrOptions === "object" &&
284
+ filterExpressionOrOptions !== null
285
+ ) {
286
+ if (!this.isScanOptions(filterExpressionOrOptions)) {
287
+ throw new Error(
288
+ `Invalid DynamoDB scan options: ${Object.keys(filterExpressionOrOptions).join(", ")}`,
289
+ );
290
+ }
291
+ this.applyScanParams(params, filterExpressionOrOptions);
201
292
 
202
- if (filterExpression) {
203
- params.FilterExpression = filterExpression;
204
- }
205
-
206
- if (expressionAttributeValues) {
207
- params.ExpressionAttributeValues = expressionAttributeValues;
208
- }
209
-
210
- if (expressionAttributeNames) {
211
- params.ExpressionAttributeNames = expressionAttributeNames;
293
+ if (expressionAttributeValuesOrMetadata !== undefined) {
294
+ if (!this.isTraceMetadata(expressionAttributeValuesOrMetadata)) {
295
+ throw new Error("Invalid DynamoDB scan trace metadata");
296
+ }
297
+ resolvedMetadata = expressionAttributeValuesOrMetadata;
298
+ }
299
+ } else {
300
+ if (filterExpressionOrOptions) {
301
+ params.FilterExpression = filterExpressionOrOptions;
302
+ }
303
+ if (
304
+ expressionAttributeValuesOrMetadata &&
305
+ Object.keys(expressionAttributeValuesOrMetadata).length > 0
306
+ ) {
307
+ params.ExpressionAttributeValues = expressionAttributeValuesOrMetadata;
308
+ }
309
+ if (
310
+ expressionAttributeNames &&
311
+ Object.keys(expressionAttributeNames).length > 0
312
+ ) {
313
+ params.ExpressionAttributeNames = expressionAttributeNames;
314
+ }
212
315
  }
213
316
 
214
317
  const request = this.buildRequest("scan", params);
215
318
  const result = await this.executeWithErrorHandling(
216
319
  request,
217
320
  "scan",
218
- metadata,
321
+ resolvedMetadata,
219
322
  );
220
323
  return this.validateResult(result, schema, "scan");
221
324
  }
@@ -233,8 +336,10 @@ export class DynamoDBClientImpl
233
336
  KeyConditionExpression: keyConditionExpression,
234
337
  ExpressionAttributeValues: expressionAttributeValues,
235
338
  };
236
-
237
- if (expressionAttributeNames) {
339
+ if (
340
+ expressionAttributeNames &&
341
+ Object.keys(expressionAttributeNames).length > 0
342
+ ) {
238
343
  params.ExpressionAttributeNames = expressionAttributeNames;
239
344
  }
240
345
 
@@ -4,5 +4,9 @@
4
4
  * @module
5
5
  */
6
6
 
7
- export type { DynamoDBClient, DynamoDBAttributeValue } from "./types.js";
7
+ export type {
8
+ DynamoDBClient,
9
+ DynamoDBAttributeValue,
10
+ DynamoDBScanOptions,
11
+ } from "./types.js";
8
12
  export { DynamoDBClientImpl } from "./client.js";
@@ -37,6 +37,24 @@ export type DynamoDBAttributeValue =
37
37
  | { NS: string[] }
38
38
  | { BS: string[] };
39
39
 
40
+ /**
41
+ * Optional Scan parameters forwarded to the AWS SDK.
42
+ *
43
+ * Use `exclusiveStartKey` with `LastEvaluatedKey` from a previous page to
44
+ * continue past DynamoDB's 1 MB per-Scan limit.
45
+ */
46
+ export interface DynamoDBScanOptions {
47
+ filterExpression?: string;
48
+ expressionAttributeValues?: Record<string, DynamoDBAttributeValue>;
49
+ expressionAttributeNames?: Record<string, string>;
50
+ exclusiveStartKey?: Record<string, DynamoDBAttributeValue>;
51
+ limit?: number;
52
+ projectionExpression?: string;
53
+ indexName?: string;
54
+ segment?: number;
55
+ totalSegments?: number;
56
+ }
57
+
40
58
  /**
41
59
  * DynamoDB client for database operations.
42
60
  *
@@ -84,6 +102,11 @@ export type DynamoDBAttributeValue =
84
102
  * 'status = :s',
85
103
  * { ':s': { S: 'active' } }
86
104
  * );
105
+ *
106
+ * // Paginate past the 1 MB Scan limit
107
+ * const page = await ctx.integrations.db.scan('users', UsersSchema, {
108
+ * exclusiveStartKey: lastEvaluatedKey,
109
+ * });
87
110
  * ```
88
111
  */
89
112
  export interface DynamoDBClient extends BaseIntegrationClient {
@@ -122,7 +145,10 @@ export interface DynamoDBClient extends BaseIntegrationClient {
122
145
  ): Promise<T>;
123
146
 
124
147
  /**
125
- * Scan a DynamoDB table with optional filter.
148
+ * Scan a DynamoDB table.
149
+ *
150
+ * Prefer the options-object form when paginating (`exclusiveStartKey`) or
151
+ * when you need `limit`, `indexName`, or parallel scan segments.
126
152
  *
127
153
  * @param table - The table name
128
154
  * @param schema - Zod schema for validating the result
@@ -133,6 +159,12 @@ export interface DynamoDBClient extends BaseIntegrationClient {
133
159
  * @param metadata - Optional trace metadata for diagnostics
134
160
  * @returns The validated result
135
161
  */
162
+ scan<T>(
163
+ table: string,
164
+ schema: z.ZodSchema<T>,
165
+ options: DynamoDBScanOptions,
166
+ metadata?: TraceMetadata,
167
+ ): Promise<T>;
136
168
  scan<T>(
137
169
  table: string,
138
170
  schema: z.ZodSchema<T>,
@@ -293,6 +293,13 @@ All methods accept an optional `metadata` parameter as the last argument for dia
293
293
 
294
294
  ## Common Pitfalls
295
295
 
296
+ ### Streaming Is Not Supported
297
+
298
+ `apiRequest()` does not support streaming or Server-Sent Events. Do not set
299
+ `stream: true` — streaming responses fail schema validation. Every call
300
+ returns the complete response; if a UI needs real-time token streaming,
301
+ handle it at the frontend layer, not through the SDK.
302
+
296
303
  ### No Specialized Methods
297
304
 
298
305
  ```typescript
@@ -265,6 +265,14 @@ All methods accept an optional `metadata` parameter as the last argument for dia
265
265
 
266
266
  ## Common Pitfalls
267
267
 
268
+ ### Streaming Is Not Supported
269
+
270
+ `apiRequest()` does not support streaming or Server-Sent Events. Use
271
+ `:generateContent`, never `:streamGenerateContent` or `alt=sse` — streaming
272
+ responses fail schema validation. Every call returns the complete response;
273
+ if a UI needs real-time token streaming, handle it at the frontend layer,
274
+ not through the SDK.
275
+
268
276
  ### No Specialized Methods
269
277
 
270
278
  ```typescript
@@ -251,6 +251,13 @@ All methods accept an optional `metadata` parameter as the last argument for dia
251
251
 
252
252
  ## Common Pitfalls
253
253
 
254
+ ### Streaming Is Not Supported
255
+
256
+ `apiRequest()` does not support streaming or Server-Sent Events. Do not set
257
+ `stream: true` — streaming responses fail schema validation. Every call
258
+ returns the complete response; if a UI needs real-time token streaming,
259
+ handle it at the frontend layer, not through the SDK.
260
+
254
261
  ### No Specialized Methods
255
262
 
256
263
  ```typescript
@@ -363,6 +363,7 @@ export { MongoDBClientImpl } from "./mongodb/index.js";
363
363
  export type {
364
364
  DynamoDBClient,
365
365
  DynamoDBAttributeValue,
366
+ DynamoDBScanOptions,
366
367
  } from "./dynamodb/index.js";
367
368
  export { DynamoDBClientImpl } from "./dynamodb/index.js";
368
369
 
@@ -277,6 +277,13 @@ All methods accept an optional `metadata` parameter as the last argument for dia
277
277
 
278
278
  ## Common Pitfalls
279
279
 
280
+ ### Streaming Is Not Supported
281
+
282
+ `apiRequest()` does not support streaming or Server-Sent Events. Do not set
283
+ `stream: true` — streaming responses fail schema validation. Every call
284
+ returns the complete response; if a UI needs real-time token streaming,
285
+ handle it at the frontend layer, not through the SDK.
286
+
280
287
  ### No Specialized Methods
281
288
 
282
289
  ```typescript
@@ -257,6 +257,13 @@ All methods accept an optional `metadata` parameter as the last argument for dia
257
257
 
258
258
  ## Common Pitfalls
259
259
 
260
+ ### Streaming Is Not Supported
261
+
262
+ `apiRequest()` does not support streaming or Server-Sent Events. Do not set
263
+ `stream: true` — streaming responses fail schema validation. Every call
264
+ returns the complete response; if a UI needs real-time token streaming,
265
+ handle it at the frontend layer, not through the SDK.
266
+
260
267
  ### No Specialized Methods
261
268
 
262
269
  The OpenAI client only provides `apiRequest()`. There are no other specialized methods:
@@ -189,6 +189,13 @@ All methods accept an optional `metadata` parameter as the last argument for dia
189
189
 
190
190
  ## Common Pitfalls
191
191
 
192
+ ### Streaming Is Not Supported
193
+
194
+ `apiRequest()` does not support streaming or Server-Sent Events. Do not set
195
+ `stream: true` — streaming responses fail schema validation. Every call
196
+ returns the complete response; if a UI needs real-time token streaming,
197
+ handle it at the frontend layer, not through the SDK.
198
+
192
199
  ### No Specialized Methods
193
200
 
194
201
  ```typescript
@@ -25,6 +25,7 @@ import { api, z, s3 } from "@superblocksteam/sdk-api";
25
25
  const PROD_S3 = "a1b2c3d4-5678-90ab-cdef-s300000001";
26
26
 
27
27
  export default api({
28
+ name: "ListBucketObjects",
28
29
  integrations: {
29
30
  storage: s3(PROD_S3),
30
31
  },
@@ -108,6 +108,14 @@ All methods accept an optional `metadata` parameter as the last argument for dia
108
108
 
109
109
  ## Common Pitfalls
110
110
 
111
+ ### Streaming Is Not Supported
112
+
113
+ `apiRequest()` does not support streaming or Server-Sent Events. Always set
114
+ `stream: false` in Cortex request bodies (as the examples do) — a streaming
115
+ response fails schema validation. Every call returns the complete response;
116
+ if a UI needs real-time token streaming, handle it at the frontend layer,
117
+ not through the SDK.
118
+
111
119
  ### No Specialized Methods
112
120
 
113
121
  The Snowflake Cortex client only provides `apiRequest()`. There are no other specialized methods:
@@ -234,6 +234,13 @@ All methods accept an optional `metadata` parameter as the last argument for dia
234
234
 
235
235
  ## Common Pitfalls
236
236
 
237
+ ### Streaming Is Not Supported
238
+
239
+ `apiRequest()` does not support streaming or Server-Sent Events. Do not set
240
+ `stream: true` — streaming responses fail schema validation. Every call
241
+ returns the complete response; if a UI needs real-time token streaming,
242
+ handle it at the frontend layer, not through the SDK.
243
+
237
244
  ### No Specialized Methods
238
245
 
239
246
  ```typescript
@@ -57,6 +57,13 @@ export interface CreateContextOptions {
57
57
  /** Environment variables */
58
58
  env: Record<string, string>;
59
59
 
60
+ /**
61
+ * Server-resolved data tag key.
62
+ *
63
+ * Optional for compatibility with execution wrappers from older agents.
64
+ */
65
+ dataTag?: string;
66
+
60
67
  /** User information from JWT */
61
68
  user: ApiUser;
62
69
 
@@ -101,6 +108,7 @@ export function createApiContext(
101
108
  executeQuery,
102
109
  executionId,
103
110
  env,
111
+ dataTag,
104
112
  user,
105
113
  logger,
106
114
  } = options;
@@ -172,6 +180,7 @@ export function createApiContext(
172
180
  >["integrations"],
173
181
  log,
174
182
  env: Object.freeze({ ...env }),
183
+ dataTag,
175
184
  user,
176
185
  };
177
186
  }
@@ -36,6 +36,13 @@ export interface ExecuteApiRequest {
36
36
  /** Environment variables available to the API */
37
37
  env: Record<string, string>;
38
38
 
39
+ /**
40
+ * Server-resolved data tag key for this execution.
41
+ *
42
+ * Optional on the low-level request for compatibility with older runtimes.
43
+ */
44
+ dataTag?: string;
45
+
39
46
  /** User information extracted from the Superblocks JWT */
40
47
  user: ApiUser;
41
48
 
@@ -162,6 +169,7 @@ export async function executeApi<TInput = unknown, TOutput = unknown>(
162
169
  executeQuery: request.executeQuery,
163
170
  executionId: request.executionId,
164
171
  env: request.env,
172
+ dataTag: request.dataTag,
165
173
  user: request.user,
166
174
  });
167
175
 
package/src/types.ts CHANGED
@@ -182,6 +182,17 @@ export interface ApiContext<
182
182
  /** Access to environment variables */
183
183
  readonly env: Readonly<Record<string, string>>;
184
184
 
185
+ /**
186
+ * Canonical key of the requested data tag validated for this execution.
187
+ *
188
+ * This identifies the integration configuration in use, not a user's
189
+ * environment entitlement. It is supplied by the Superblocks runtime and
190
+ * cannot be selected through API input. It is undefined when no data tag was
191
+ * resolved or on runtimes that predate data-tag context support;
192
+ * authorization checks must deny access in those cases.
193
+ */
194
+ readonly dataTag?: string;
195
+
185
196
  /** User information from the Superblocks JWT */
186
197
  readonly user: ApiUser;
187
198
  }