@superblocksteam/sdk-api 2.0.101-next.0 → 2.0.101-next.1
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/README.md +47 -41
- package/dist/api/definition.d.ts +1 -1
- package/dist/api/definition.d.ts.map +1 -1
- package/dist/api/definition.js.map +1 -1
- package/dist/api/definition.test.js.map +1 -1
- package/dist/api/streaming.d.ts +1 -1
- package/dist/api/streaming.d.ts.map +1 -1
- package/dist/api/streaming.js.map +1 -1
- package/dist/api/streaming.test.js +2 -2
- package/dist/api/streaming.test.js.map +1 -1
- package/dist/integrations/athena/client.d.ts +1 -1
- package/dist/integrations/athena/client.d.ts.map +1 -1
- package/dist/integrations/athena/client.js.map +1 -1
- package/dist/integrations/athena/types.d.ts.map +1 -1
- package/dist/integrations/base/graphql-integration-client.d.ts +2 -2
- package/dist/integrations/base/graphql-integration-client.d.ts.map +1 -1
- package/dist/integrations/base/graphql-integration-client.js.map +1 -1
- package/dist/integrations/base/rest-api-integration-client.d.ts +3 -3
- package/dist/integrations/base/rest-api-integration-client.d.ts.map +1 -1
- package/dist/integrations/base/rest-api-integration-client.js.map +1 -1
- package/dist/integrations/base/types.d.ts.map +1 -1
- package/dist/integrations/bigquery/client.d.ts +1 -1
- package/dist/integrations/bigquery/client.d.ts.map +1 -1
- package/dist/integrations/bigquery/client.js.map +1 -1
- package/dist/integrations/bigquery/types.d.ts.map +1 -1
- package/dist/integrations/cockroachdb/client.d.ts +1 -1
- package/dist/integrations/cockroachdb/client.d.ts.map +1 -1
- package/dist/integrations/cockroachdb/client.js.map +1 -1
- package/dist/integrations/cockroachdb/types.d.ts.map +1 -1
- package/dist/integrations/cosmosdb/client.d.ts +1 -1
- package/dist/integrations/cosmosdb/client.d.ts.map +1 -1
- package/dist/integrations/cosmosdb/client.js.map +1 -1
- package/dist/integrations/cosmosdb/client.test.js.map +1 -1
- package/dist/integrations/cosmosdb/types.d.ts.map +1 -1
- package/dist/integrations/couchbase/client.d.ts +1 -1
- package/dist/integrations/couchbase/client.d.ts.map +1 -1
- package/dist/integrations/couchbase/client.js.map +1 -1
- package/dist/integrations/couchbase/types.d.ts.map +1 -1
- package/dist/integrations/databricks/client.d.ts +1 -1
- package/dist/integrations/databricks/client.d.ts.map +1 -1
- package/dist/integrations/databricks/client.js.map +1 -1
- package/dist/integrations/databricks/types.d.ts.map +1 -1
- package/dist/integrations/declarations.d.ts +36 -36
- package/dist/integrations/declarations.d.ts.map +1 -1
- package/dist/integrations/declarations.test.js.map +1 -1
- package/dist/integrations/dynamodb/client.d.ts +1 -1
- package/dist/integrations/dynamodb/client.d.ts.map +1 -1
- package/dist/integrations/dynamodb/client.js.map +1 -1
- package/dist/integrations/dynamodb/types.d.ts.map +1 -1
- package/dist/integrations/gcs/client.d.ts +1 -1
- package/dist/integrations/gcs/client.d.ts.map +1 -1
- package/dist/integrations/gcs/client.js.map +1 -1
- package/dist/integrations/gcs/types.d.ts.map +1 -1
- package/dist/integrations/graphql/types.d.ts +1 -1
- package/dist/integrations/graphql/types.d.ts.map +1 -1
- package/dist/integrations/gsheets/client.d.ts +1 -1
- package/dist/integrations/gsheets/client.d.ts.map +1 -1
- package/dist/integrations/gsheets/client.js.map +1 -1
- package/dist/integrations/gsheets/types.d.ts.map +1 -1
- package/dist/integrations/kafka/client.d.ts +1 -1
- package/dist/integrations/kafka/client.d.ts.map +1 -1
- package/dist/integrations/kafka/client.js.map +1 -1
- package/dist/integrations/kafka/types.d.ts.map +1 -1
- package/dist/integrations/kinesis/client.d.ts +1 -1
- package/dist/integrations/kinesis/client.d.ts.map +1 -1
- package/dist/integrations/kinesis/client.js.map +1 -1
- package/dist/integrations/lakebase/client.d.ts +1 -1
- package/dist/integrations/lakebase/client.d.ts.map +1 -1
- package/dist/integrations/lakebase/client.js.map +1 -1
- package/dist/integrations/lakebase/types.d.ts.map +1 -1
- package/dist/integrations/mariadb/client.d.ts +1 -1
- package/dist/integrations/mariadb/client.d.ts.map +1 -1
- package/dist/integrations/mariadb/client.js.map +1 -1
- package/dist/integrations/mariadb/types.d.ts.map +1 -1
- package/dist/integrations/mongodb/client.d.ts +1 -1
- package/dist/integrations/mongodb/client.d.ts.map +1 -1
- package/dist/integrations/mongodb/client.js.map +1 -1
- package/dist/integrations/mongodb/types.d.ts.map +1 -1
- package/dist/integrations/mssql/client.d.ts +1 -1
- package/dist/integrations/mssql/client.d.ts.map +1 -1
- package/dist/integrations/mssql/client.js.map +1 -1
- package/dist/integrations/mssql/types.d.ts.map +1 -1
- package/dist/integrations/mysql/client.d.ts +1 -1
- package/dist/integrations/mysql/client.d.ts.map +1 -1
- package/dist/integrations/mysql/client.js.map +1 -1
- package/dist/integrations/mysql/types.d.ts.map +1 -1
- package/dist/integrations/oracledb/client.d.ts +1 -1
- package/dist/integrations/oracledb/client.d.ts.map +1 -1
- package/dist/integrations/oracledb/client.js.map +1 -1
- package/dist/integrations/oracledb/types.d.ts.map +1 -1
- package/dist/integrations/postgres/client.d.ts +2 -2
- package/dist/integrations/postgres/client.d.ts.map +1 -1
- package/dist/integrations/postgres/client.js.map +1 -1
- package/dist/integrations/postgres/types.d.ts.map +1 -1
- package/dist/integrations/python/client.d.ts +2 -2
- package/dist/integrations/python/client.d.ts.map +1 -1
- package/dist/integrations/python/client.js.map +1 -1
- package/dist/integrations/python/client.test.js.map +1 -1
- package/dist/integrations/python/types.d.ts.map +1 -1
- package/dist/integrations/redis/client.d.ts +1 -1
- package/dist/integrations/redis/client.d.ts.map +1 -1
- package/dist/integrations/redis/client.js.map +1 -1
- package/dist/integrations/redis/types.d.ts.map +1 -1
- package/dist/integrations/redshift/client.d.ts +1 -1
- package/dist/integrations/redshift/client.d.ts.map +1 -1
- package/dist/integrations/redshift/client.js.map +1 -1
- package/dist/integrations/redshift/types.d.ts.map +1 -1
- package/dist/integrations/registry.d.ts.map +1 -1
- package/dist/integrations/registry.js +22 -22
- package/dist/integrations/registry.js.map +1 -1
- package/dist/integrations/registry.test.js.map +1 -1
- package/dist/integrations/s3/client.d.ts +1 -1
- package/dist/integrations/s3/client.d.ts.map +1 -1
- package/dist/integrations/s3/client.js.map +1 -1
- package/dist/integrations/s3/types.d.ts +3 -1
- package/dist/integrations/s3/types.d.ts.map +1 -1
- package/dist/integrations/salesforce/client.d.ts +1 -1
- package/dist/integrations/salesforce/client.d.ts.map +1 -1
- package/dist/integrations/salesforce/client.js.map +1 -1
- package/dist/integrations/salesforce/types.d.ts.map +1 -1
- package/dist/integrations/smtp/client.d.ts +1 -1
- package/dist/integrations/smtp/client.d.ts.map +1 -1
- package/dist/integrations/smtp/client.js.map +1 -1
- package/dist/integrations/snowflake/client.d.ts +1 -1
- package/dist/integrations/snowflake/client.d.ts.map +1 -1
- package/dist/integrations/snowflake/client.js.map +1 -1
- package/dist/integrations/snowflake/types.d.ts.map +1 -1
- package/dist/integrations/snowflakepostgres/client.d.ts +1 -1
- package/dist/integrations/snowflakepostgres/client.d.ts.map +1 -1
- package/dist/integrations/snowflakepostgres/client.js.map +1 -1
- package/dist/integrations/snowflakepostgres/types.d.ts.map +1 -1
- package/dist/runtime/context.d.ts +2 -2
- package/dist/runtime/context.d.ts.map +1 -1
- package/dist/runtime/context.js.map +1 -1
- package/dist/runtime/streaming-context.d.ts +2 -2
- package/dist/runtime/streaming-context.d.ts.map +1 -1
- package/dist/runtime/streaming-context.js.map +1 -1
- package/dist/runtime/streaming-executor.d.ts.map +1 -1
- package/dist/runtime/streaming-executor.js +1 -1
- package/dist/runtime/streaming-executor.js.map +1 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/api/definition.test.ts +1 -0
- package/src/api/definition.ts +1 -1
- package/src/api/streaming.test.ts +3 -2
- package/src/api/streaming.ts +2 -1
- package/src/integrations/athena/client.ts +5 -3
- package/src/integrations/athena/types.ts +1 -0
- package/src/integrations/base/graphql-integration-client.ts +3 -2
- package/src/integrations/base/rest-api-integration-client.ts +9 -7
- package/src/integrations/base/types.ts +1 -0
- package/src/integrations/bigquery/client.ts +5 -3
- package/src/integrations/bigquery/types.ts +1 -0
- package/src/integrations/cockroachdb/client.ts +5 -3
- package/src/integrations/cockroachdb/types.ts +1 -0
- package/src/integrations/cosmosdb/client.test.ts +2 -1
- package/src/integrations/cosmosdb/client.ts +5 -3
- package/src/integrations/cosmosdb/types.ts +1 -0
- package/src/integrations/couchbase/client.ts +3 -2
- package/src/integrations/couchbase/types.ts +1 -0
- package/src/integrations/databricks/client.ts +5 -3
- package/src/integrations/databricks/types.ts +1 -0
- package/src/integrations/declarations.test.ts +1 -0
- package/src/integrations/declarations.ts +36 -36
- package/src/integrations/dynamodb/client.ts +3 -2
- package/src/integrations/dynamodb/types.ts +1 -0
- package/src/integrations/gcs/client.ts +5 -3
- package/src/integrations/gcs/types.ts +1 -0
- package/src/integrations/graphql/types.ts +2 -1
- package/src/integrations/gsheets/client.ts +5 -3
- package/src/integrations/gsheets/types.ts +1 -0
- package/src/integrations/kafka/client.ts +3 -2
- package/src/integrations/kafka/types.ts +1 -0
- package/src/integrations/kinesis/client.ts +2 -2
- package/src/integrations/lakebase/README.md +242 -0
- package/src/integrations/lakebase/client.ts +6 -4
- package/src/integrations/lakebase/types.ts +1 -0
- package/src/integrations/mariadb/client.ts +5 -3
- package/src/integrations/mariadb/types.ts +1 -0
- package/src/integrations/mongodb/client.ts +5 -3
- package/src/integrations/mongodb/types.ts +1 -0
- package/src/integrations/mssql/client.ts +5 -3
- package/src/integrations/mssql/types.ts +1 -0
- package/src/integrations/mysql/client.ts +5 -3
- package/src/integrations/mysql/types.ts +1 -0
- package/src/integrations/oracledb/client.ts +5 -3
- package/src/integrations/oracledb/types.ts +1 -0
- package/src/integrations/postgres/client.ts +6 -4
- package/src/integrations/postgres/types.ts +1 -0
- package/src/integrations/python/client.test.ts +3 -2
- package/src/integrations/python/client.ts +5 -3
- package/src/integrations/python/types.ts +1 -0
- package/src/integrations/redis/client.ts +3 -2
- package/src/integrations/redis/types.ts +1 -0
- package/src/integrations/redshift/client.ts +5 -3
- package/src/integrations/redshift/types.ts +1 -0
- package/src/integrations/registry.test.ts +1 -0
- package/src/integrations/registry.ts +23 -23
- package/src/integrations/restapiintegration/README.md +359 -0
- package/src/integrations/s3/client.ts +5 -3
- package/src/integrations/s3/types.ts +4 -1
- package/src/integrations/salesforce/client.ts +3 -2
- package/src/integrations/salesforce/types.ts +1 -0
- package/src/integrations/smtp/README.md +220 -0
- package/src/integrations/smtp/client.ts +4 -2
- package/src/integrations/snowflake/client.ts +5 -3
- package/src/integrations/snowflake/types.ts +1 -0
- package/src/integrations/snowflakecortex/README.md +216 -0
- package/src/integrations/snowflakepostgres/README.md +233 -0
- package/src/integrations/snowflakepostgres/client.ts +1 -1
- package/src/integrations/snowflakepostgres/types.ts +1 -0
- package/src/runtime/context.ts +10 -10
- package/src/runtime/streaming-context.ts +10 -10
- package/src/runtime/streaming-executor.ts +4 -4
- package/src/types.ts +1 -0
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
# REST API Integration Client
|
|
2
|
+
|
|
3
|
+
Make HTTP requests to any REST API configured with a base URL and authentication in the integrations page.
|
|
4
|
+
|
|
5
|
+
This is the generic REST API Integration plugin. Unlike named integrations (Slack, GitHub, etc.) which target a specific service, this plugin works with **any** HTTP API you configure as an integration.
|
|
6
|
+
|
|
7
|
+
## Methods
|
|
8
|
+
|
|
9
|
+
| Method | Description |
|
|
10
|
+
| ---------------------------------------------- | ------------------------------------------------ |
|
|
11
|
+
| `apiRequest(options, schema, metadata?)` | Make any HTTP request with schema validation |
|
|
12
|
+
| `streamApiRequest(options, schema, metadata?)` | Stream responses with real-time chunk validation |
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
### Basic GET Request
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { api, z, restApiIntegration } from "@superblocksteam/sdk-api";
|
|
20
|
+
|
|
21
|
+
// Integration ID from the integrations panel
|
|
22
|
+
const MY_API = "a1b2c3d4-5678-90ab-cdef-111111111111";
|
|
23
|
+
|
|
24
|
+
const UsersResponseSchema = z.object({
|
|
25
|
+
users: z.array(
|
|
26
|
+
z.object({
|
|
27
|
+
id: z.string(),
|
|
28
|
+
name: z.string(),
|
|
29
|
+
email: z.string(),
|
|
30
|
+
}),
|
|
31
|
+
),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
export default api({
|
|
35
|
+
name: "FetchUsers",
|
|
36
|
+
integrations: {
|
|
37
|
+
myApi: restApiIntegration(MY_API),
|
|
38
|
+
},
|
|
39
|
+
input: z.object({}),
|
|
40
|
+
output: z.object({
|
|
41
|
+
users: z.array(
|
|
42
|
+
z.object({ id: z.string(), name: z.string(), email: z.string() }),
|
|
43
|
+
),
|
|
44
|
+
}),
|
|
45
|
+
async run(ctx) {
|
|
46
|
+
const result = await ctx.integrations.myApi.apiRequest(
|
|
47
|
+
{
|
|
48
|
+
method: "GET",
|
|
49
|
+
path: "/users",
|
|
50
|
+
params: { limit: 50 },
|
|
51
|
+
},
|
|
52
|
+
{ response: UsersResponseSchema },
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
return { users: result.users };
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### POST Request with Body
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
const CreateRecordSchema = z.object({
|
|
64
|
+
id: z.string(),
|
|
65
|
+
created_at: z.string(),
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const record = await ctx.integrations.myApi.apiRequest(
|
|
69
|
+
{
|
|
70
|
+
method: "POST",
|
|
71
|
+
path: "/records",
|
|
72
|
+
body: {
|
|
73
|
+
title: "New Record",
|
|
74
|
+
description: "Created via Superblocks",
|
|
75
|
+
tags: ["automated"],
|
|
76
|
+
},
|
|
77
|
+
headers: {
|
|
78
|
+
"Content-Type": "application/json",
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
{ response: CreateRecordSchema },
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
console.log(`Created record: ${record.id}`);
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### PATCH/PUT Request
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
const UpdateResponseSchema = z.object({
|
|
91
|
+
id: z.string(),
|
|
92
|
+
updated_at: z.string(),
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
await ctx.integrations.myApi.apiRequest(
|
|
96
|
+
{
|
|
97
|
+
method: "PATCH",
|
|
98
|
+
path: `/records/${recordId}`,
|
|
99
|
+
body: {
|
|
100
|
+
title: "Updated Title",
|
|
101
|
+
status: "published",
|
|
102
|
+
},
|
|
103
|
+
headers: {
|
|
104
|
+
"Content-Type": "application/json",
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
{ response: UpdateResponseSchema },
|
|
108
|
+
);
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### DELETE Request
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
await ctx.integrations.myApi.apiRequest(
|
|
115
|
+
{
|
|
116
|
+
method: "DELETE",
|
|
117
|
+
path: `/records/${recordId}`,
|
|
118
|
+
},
|
|
119
|
+
{ response: z.object({}).passthrough() },
|
|
120
|
+
);
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Search with Query Parameters
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
const SearchResponseSchema = z.object({
|
|
127
|
+
items: z.array(
|
|
128
|
+
z.object({
|
|
129
|
+
id: z.string(),
|
|
130
|
+
title: z.string(),
|
|
131
|
+
score: z.number().optional(),
|
|
132
|
+
}),
|
|
133
|
+
),
|
|
134
|
+
total: z.number(),
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
const results = await ctx.integrations.myApi.apiRequest(
|
|
138
|
+
{
|
|
139
|
+
method: "GET",
|
|
140
|
+
path: "/search",
|
|
141
|
+
params: {
|
|
142
|
+
q: "my query",
|
|
143
|
+
page: 1,
|
|
144
|
+
per_page: 25,
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
{ response: SearchResponseSchema },
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
console.log(`Found ${results.total} results`);
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Using Multiple Integrations
|
|
154
|
+
|
|
155
|
+
You can use multiple REST API Integrations in a single API, each targeting a different service:
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
import { api, z, restApiIntegration, postgres } from "@superblocksteam/sdk-api";
|
|
159
|
+
|
|
160
|
+
const EXTERNAL_API = "a1b2c3d4-5678-90ab-cdef-111111111111";
|
|
161
|
+
const INTERNAL_API = "e5f6a7b8-9012-34cd-ef56-222222222222";
|
|
162
|
+
const MY_DB = "c3d4e5f6-7890-12ab-cdef-333333333333";
|
|
163
|
+
|
|
164
|
+
export default api({
|
|
165
|
+
name: "SyncData",
|
|
166
|
+
integrations: {
|
|
167
|
+
externalApi: restApiIntegration(EXTERNAL_API),
|
|
168
|
+
internalApi: restApiIntegration(INTERNAL_API),
|
|
169
|
+
db: postgres(MY_DB),
|
|
170
|
+
},
|
|
171
|
+
input: z.object({ query: z.string() }),
|
|
172
|
+
output: z.object({ synced: z.number() }),
|
|
173
|
+
async run(ctx, { query }) {
|
|
174
|
+
// Fetch from external API
|
|
175
|
+
const external = await ctx.integrations.externalApi.apiRequest(
|
|
176
|
+
{ method: "GET", path: "/data", params: { q: query } },
|
|
177
|
+
{ response: z.object({ items: z.array(z.unknown()) }) },
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
// Push to internal API
|
|
181
|
+
await ctx.integrations.internalApi.apiRequest(
|
|
182
|
+
{ method: "POST", path: "/import", body: { items: external.items } },
|
|
183
|
+
{ response: z.object({ imported: z.number() }) },
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
return { synced: external.items.length };
|
|
187
|
+
},
|
|
188
|
+
});
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Streaming Responses
|
|
192
|
+
|
|
193
|
+
For APIs that return streaming data (e.g., Server-Sent Events), use `streamApiRequest()`:
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
import { streamingApi, z, restApiIntegration } from "@superblocksteam/sdk-api";
|
|
197
|
+
|
|
198
|
+
const MY_API = "a1b2c3d4-5678-90ab-cdef-111111111111";
|
|
199
|
+
|
|
200
|
+
const StreamChunkSchema = z.object({
|
|
201
|
+
id: z.string(),
|
|
202
|
+
data: z.string(),
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
export default streamingApi({
|
|
206
|
+
integrations: {
|
|
207
|
+
myApi: restApiIntegration(MY_API),
|
|
208
|
+
},
|
|
209
|
+
input: z.object({ prompt: z.string() }),
|
|
210
|
+
chunk: z.object({ text: z.string() }),
|
|
211
|
+
|
|
212
|
+
async *run(ctx, { prompt }) {
|
|
213
|
+
const stream = ctx.integrations.myApi.streamApiRequest(
|
|
214
|
+
{
|
|
215
|
+
method: "POST",
|
|
216
|
+
path: "/stream",
|
|
217
|
+
body: { prompt },
|
|
218
|
+
},
|
|
219
|
+
{ chunk: StreamChunkSchema },
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
for await (const chunk of stream) {
|
|
223
|
+
yield { text: chunk.data };
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
});
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Trace Metadata
|
|
230
|
+
|
|
231
|
+
All methods accept an optional `metadata` parameter as the last argument for diagnostics labeling. See the [root SDK README](../../../README.md#trace-metadata) for details.
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
const result = await ctx.integrations.myApi.apiRequest(
|
|
235
|
+
{ method: "GET", path: "/users" },
|
|
236
|
+
{ response: UsersResponseSchema },
|
|
237
|
+
{ label: "myApi.getUsers", description: "Fetch all active users" },
|
|
238
|
+
);
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Common Pitfalls
|
|
242
|
+
|
|
243
|
+
### No `.request()` Method
|
|
244
|
+
|
|
245
|
+
The only public methods are `apiRequest()` and `streamApiRequest()`. There is no `.request()` method:
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
// WRONG - .request() does not exist
|
|
249
|
+
await ctx.integrations.myApi.request({
|
|
250
|
+
method: "GET",
|
|
251
|
+
path: "/users",
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
// CORRECT - Use apiRequest with a response schema
|
|
255
|
+
await ctx.integrations.myApi.apiRequest(
|
|
256
|
+
{ method: "GET", path: "/users" },
|
|
257
|
+
{ response: UsersResponseSchema },
|
|
258
|
+
);
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Response Schema is Required
|
|
262
|
+
|
|
263
|
+
`apiRequest()` requires a response schema for type safety:
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
// WRONG - Missing response schema
|
|
267
|
+
const result = await ctx.integrations.myApi.apiRequest({
|
|
268
|
+
method: "GET",
|
|
269
|
+
path: "/users",
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
// CORRECT - Provide a response schema
|
|
273
|
+
const result = await ctx.integrations.myApi.apiRequest(
|
|
274
|
+
{ method: "GET", path: "/users" },
|
|
275
|
+
{ response: z.object({ users: z.array(z.unknown()) }) },
|
|
276
|
+
);
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Use `body` Instead of `JSON.stringify`
|
|
280
|
+
|
|
281
|
+
The `body` field is automatically serialized. Do not stringify it manually:
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
// WRONG - Manual stringify
|
|
285
|
+
await ctx.integrations.myApi.apiRequest(
|
|
286
|
+
{
|
|
287
|
+
method: "POST",
|
|
288
|
+
path: "/records",
|
|
289
|
+
body: JSON.stringify({ title: "New" }),
|
|
290
|
+
},
|
|
291
|
+
{ response: ResponseSchema },
|
|
292
|
+
);
|
|
293
|
+
|
|
294
|
+
// CORRECT - Pass object directly
|
|
295
|
+
await ctx.integrations.myApi.apiRequest(
|
|
296
|
+
{
|
|
297
|
+
method: "POST",
|
|
298
|
+
path: "/records",
|
|
299
|
+
body: { title: "New" },
|
|
300
|
+
},
|
|
301
|
+
{ response: ResponseSchema },
|
|
302
|
+
);
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### Use `params` for Query Parameters
|
|
306
|
+
|
|
307
|
+
Query parameters go in the `params` field, not in the URL path:
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
// WRONG - Query params in path
|
|
311
|
+
await ctx.integrations.myApi.apiRequest(
|
|
312
|
+
{ method: "GET", path: "/search?q=hello&limit=10" },
|
|
313
|
+
{ response: ResponseSchema },
|
|
314
|
+
);
|
|
315
|
+
|
|
316
|
+
// CORRECT - Use params field
|
|
317
|
+
await ctx.integrations.myApi.apiRequest(
|
|
318
|
+
{
|
|
319
|
+
method: "GET",
|
|
320
|
+
path: "/search",
|
|
321
|
+
params: { q: "hello", limit: 10 },
|
|
322
|
+
},
|
|
323
|
+
{ response: ResponseSchema },
|
|
324
|
+
);
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### Use `.passthrough()` for Flexible Schemas
|
|
328
|
+
|
|
329
|
+
When the response contains fields you don't need to validate, use `.passthrough()`:
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
// Strict schema - will reject unknown fields
|
|
333
|
+
const StrictSchema = z.object({ id: z.string() });
|
|
334
|
+
|
|
335
|
+
// Flexible schema - allows additional fields
|
|
336
|
+
const FlexibleSchema = z.object({ id: z.string() }).passthrough();
|
|
337
|
+
|
|
338
|
+
// For dynamic responses
|
|
339
|
+
const GenericSchema = z.record(z.unknown());
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
## Error Handling
|
|
343
|
+
|
|
344
|
+
```typescript
|
|
345
|
+
import { RestApiValidationError } from "@superblocksteam/sdk-api";
|
|
346
|
+
|
|
347
|
+
try {
|
|
348
|
+
const result = await ctx.integrations.myApi.apiRequest(
|
|
349
|
+
{ method: "GET", path: "/users" },
|
|
350
|
+
{ response: UsersResponseSchema },
|
|
351
|
+
);
|
|
352
|
+
} catch (error) {
|
|
353
|
+
if (error instanceof RestApiValidationError) {
|
|
354
|
+
// Response didn't match the schema
|
|
355
|
+
console.error("Validation failed:", error.details.zodError);
|
|
356
|
+
console.error("Actual response:", error.details.data);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
```
|
|
@@ -4,13 +4,15 @@
|
|
|
4
4
|
* Uses the native S3 plugin type from @superblocksteam/types.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import type { z } from "zod";
|
|
8
7
|
import type { PartialMessage } from "@bufbuild/protobuf";
|
|
8
|
+
import type { z } from "zod";
|
|
9
|
+
|
|
9
10
|
import type { Plugin as S3Plugin } from "@superblocksteam/types/dist/src/plugins/s3/v1/plugin_pb";
|
|
10
|
-
|
|
11
|
-
import type { QueryExecutor, TraceMetadata } from "../registry.js";
|
|
11
|
+
|
|
12
12
|
import { RestApiValidationError } from "../../errors.js";
|
|
13
13
|
import { IntegrationError } from "../../runtime/errors.js";
|
|
14
|
+
import type { QueryExecutor, TraceMetadata } from "../registry.js";
|
|
15
|
+
import type { IntegrationConfig, IntegrationClientImpl } from "../types.js";
|
|
14
16
|
import type {
|
|
15
17
|
S3Client,
|
|
16
18
|
S3Action,
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import type { z } from "zod";
|
|
6
|
+
|
|
6
7
|
import type { BaseIntegrationClient } from "../../types.js";
|
|
7
8
|
import type { TraceMetadata } from "../registry.js";
|
|
8
9
|
|
|
@@ -129,7 +130,9 @@ export interface S3Client extends BaseIntegrationClient {
|
|
|
129
130
|
*
|
|
130
131
|
* @param bucket - Bucket name
|
|
131
132
|
* @param path - Object key/path
|
|
132
|
-
* @param body -
|
|
133
|
+
* @param body - String content stored verbatim (no base64 decoding is performed).
|
|
134
|
+
* Suitable for plain text, JSON, or CSV. For binary files (PDF, DOCX, images),
|
|
135
|
+
* use {@link S3Client.uploadMultipleObjects | uploadMultipleObjects} with file references instead.
|
|
133
136
|
* @param metadata - Optional trace metadata for diagnostics
|
|
134
137
|
*/
|
|
135
138
|
uploadObject(
|
|
@@ -6,10 +6,11 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type { z } from "zod";
|
|
9
|
-
|
|
10
|
-
import type { QueryExecutor, TraceMetadata } from "../registry.js";
|
|
9
|
+
|
|
11
10
|
import { QueryValidationError, RestApiValidationError } from "../../errors.js";
|
|
12
11
|
import { IntegrationError } from "../../runtime/errors.js";
|
|
12
|
+
import type { QueryExecutor, TraceMetadata } from "../registry.js";
|
|
13
|
+
import type { IntegrationConfig, IntegrationClientImpl } from "../types.js";
|
|
13
14
|
import { describeType } from "../utils.js";
|
|
14
15
|
import type { SalesforceClient } from "./types.js";
|
|
15
16
|
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# SMTP Client
|
|
2
|
+
|
|
3
|
+
Send emails via SMTP with support for HTML content, CC/BCC, reply-to, and attachments.
|
|
4
|
+
|
|
5
|
+
## Methods
|
|
6
|
+
|
|
7
|
+
| Method | Description |
|
|
8
|
+
| -------------------------- | ---------------------- |
|
|
9
|
+
| `send(options, metadata?)` | Send an email via SMTP |
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### Send a Simple Email
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { api, z, smtp } from "@superblocksteam/sdk-api";
|
|
17
|
+
|
|
18
|
+
// Integration ID from the integrations panel
|
|
19
|
+
const MAILER = "a1b2c3d4-5678-90ab-cdef-111111111111";
|
|
20
|
+
|
|
21
|
+
export default api({
|
|
22
|
+
name: "SendEmail",
|
|
23
|
+
integrations: {
|
|
24
|
+
mailer: smtp(MAILER),
|
|
25
|
+
},
|
|
26
|
+
input: z.object({
|
|
27
|
+
to: z.string(),
|
|
28
|
+
subject: z.string(),
|
|
29
|
+
body: z.string(),
|
|
30
|
+
}),
|
|
31
|
+
output: z.object({ success: z.boolean() }),
|
|
32
|
+
|
|
33
|
+
async run(ctx, { to, subject, body }) {
|
|
34
|
+
await ctx.integrations.mailer.send({
|
|
35
|
+
from: "noreply@example.com",
|
|
36
|
+
to,
|
|
37
|
+
subject,
|
|
38
|
+
body,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
return { success: true };
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Send HTML Email
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
await ctx.integrations.mailer.send({
|
|
50
|
+
from: "noreply@example.com",
|
|
51
|
+
to: "user@example.com",
|
|
52
|
+
subject: "Welcome!",
|
|
53
|
+
body: "<h1>Welcome!</h1><p>Thank you for signing up.</p>",
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Send with CC and BCC
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
await ctx.integrations.mailer.send({
|
|
61
|
+
from: "noreply@example.com",
|
|
62
|
+
to: "user@example.com",
|
|
63
|
+
subject: "Team Update",
|
|
64
|
+
body: "Hello team!",
|
|
65
|
+
cc: "manager@example.com,lead@example.com",
|
|
66
|
+
bcc: "archive@example.com",
|
|
67
|
+
replyTo: "support@example.com",
|
|
68
|
+
});
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Send to Multiple Recipients
|
|
72
|
+
|
|
73
|
+
Use comma-separated email addresses:
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
await ctx.integrations.mailer.send({
|
|
77
|
+
from: "noreply@example.com",
|
|
78
|
+
to: "user1@example.com,user2@example.com,user3@example.com",
|
|
79
|
+
subject: "Announcement",
|
|
80
|
+
body: "<p>Important update for the team.</p>",
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Send with Attachments
|
|
85
|
+
|
|
86
|
+
Attachments are passed as a JSON string containing an array of objects with `content` (base64-encoded), `name` (filename), and `type` (MIME type):
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
const attachments = JSON.stringify([
|
|
90
|
+
{
|
|
91
|
+
content: base64EncodedPdf, // Base64-encoded file content
|
|
92
|
+
name: "report.pdf",
|
|
93
|
+
type: "application/pdf",
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
content: base64EncodedCsv,
|
|
97
|
+
name: "data.csv",
|
|
98
|
+
type: "text/csv",
|
|
99
|
+
},
|
|
100
|
+
]);
|
|
101
|
+
|
|
102
|
+
await ctx.integrations.mailer.send({
|
|
103
|
+
from: "reports@example.com",
|
|
104
|
+
to: "user@example.com",
|
|
105
|
+
subject: "Your Report",
|
|
106
|
+
body: "<p>Please find the attached report.</p>",
|
|
107
|
+
attachments,
|
|
108
|
+
});
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Trace Metadata
|
|
112
|
+
|
|
113
|
+
The `send` method accepts an optional `metadata` parameter as the last argument for diagnostics labeling:
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
await ctx.integrations.mailer.send(
|
|
117
|
+
{
|
|
118
|
+
from: "noreply@example.com",
|
|
119
|
+
to: "user@example.com",
|
|
120
|
+
subject: "Welcome",
|
|
121
|
+
body: "Hello!",
|
|
122
|
+
},
|
|
123
|
+
{ label: "Send welcome email" },
|
|
124
|
+
);
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
When `includeDiagnostics` is enabled, `label` and `description` appear in the trace view. See the [root SDK README](../../../README.md#trace-metadata) for details.
|
|
128
|
+
|
|
129
|
+
## Send Options Reference
|
|
130
|
+
|
|
131
|
+
| Option | Type | Required | Description |
|
|
132
|
+
| ------------- | -------- | -------- | --------------------------------------------- |
|
|
133
|
+
| `from` | `string` | Yes | Sender email address |
|
|
134
|
+
| `to` | `string` | Yes | Recipient(s), comma-separated for multiple |
|
|
135
|
+
| `subject` | `string` | Yes | Email subject line |
|
|
136
|
+
| `body` | `string` | Yes | Email body (HTML or plain text) |
|
|
137
|
+
| `cc` | `string` | No | CC recipient(s), comma-separated |
|
|
138
|
+
| `bcc` | `string` | No | BCC recipient(s), comma-separated |
|
|
139
|
+
| `replyTo` | `string` | No | Reply-to email address |
|
|
140
|
+
| `attachments` | `string` | No | JSON array of `{content, name, type}` objects |
|
|
141
|
+
|
|
142
|
+
## Common Pitfalls
|
|
143
|
+
|
|
144
|
+
### Use the `send` Method, Not `apiRequest`
|
|
145
|
+
|
|
146
|
+
Unlike most integrations, SMTP has a dedicated `send()` method:
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
// WRONG - apiRequest does not exist on SmtpClient
|
|
150
|
+
await ctx.integrations.mailer.apiRequest({ ... });
|
|
151
|
+
|
|
152
|
+
// CORRECT - Use send()
|
|
153
|
+
await ctx.integrations.mailer.send({
|
|
154
|
+
from: "noreply@example.com",
|
|
155
|
+
to: "user@example.com",
|
|
156
|
+
subject: "Hello",
|
|
157
|
+
body: "World",
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Attachments Must Be a JSON String
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
// WRONG - Passing an array directly
|
|
165
|
+
await ctx.integrations.mailer.send({
|
|
166
|
+
from: "noreply@example.com",
|
|
167
|
+
to: "user@example.com",
|
|
168
|
+
subject: "Report",
|
|
169
|
+
body: "See attached",
|
|
170
|
+
attachments: [{ content: "...", name: "file.pdf", type: "application/pdf" }],
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
// CORRECT - JSON.stringify the array
|
|
174
|
+
await ctx.integrations.mailer.send({
|
|
175
|
+
from: "noreply@example.com",
|
|
176
|
+
to: "user@example.com",
|
|
177
|
+
subject: "Report",
|
|
178
|
+
body: "See attached",
|
|
179
|
+
attachments: JSON.stringify([
|
|
180
|
+
{ content: "...", name: "file.pdf", type: "application/pdf" },
|
|
181
|
+
]),
|
|
182
|
+
});
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Multiple Recipients Use Comma Separation
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
// WRONG - Array of recipients
|
|
189
|
+
await ctx.integrations.mailer.send({
|
|
190
|
+
to: ["user1@example.com", "user2@example.com"],
|
|
191
|
+
// ...
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
// CORRECT - Comma-separated string
|
|
195
|
+
await ctx.integrations.mailer.send({
|
|
196
|
+
to: "user1@example.com,user2@example.com",
|
|
197
|
+
// ...
|
|
198
|
+
});
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Error Handling
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
import { IntegrationError } from "@superblocksteam/sdk-api";
|
|
205
|
+
|
|
206
|
+
try {
|
|
207
|
+
await ctx.integrations.mailer.send({
|
|
208
|
+
from: "noreply@example.com",
|
|
209
|
+
to: "user@example.com",
|
|
210
|
+
subject: "Test",
|
|
211
|
+
body: "Hello",
|
|
212
|
+
});
|
|
213
|
+
} catch (error) {
|
|
214
|
+
if (error instanceof IntegrationError) {
|
|
215
|
+
console.error(
|
|
216
|
+
`SMTP error in ${error.integrationName}.${error.method}: ${error.message}`,
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
```
|
|
@@ -6,10 +6,12 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type { PartialMessage } from "@bufbuild/protobuf";
|
|
9
|
+
|
|
9
10
|
import type { Plugin as SmtpPlugin } from "@superblocksteam/types/dist/src/plugins/smtp/v1/plugin_pb";
|
|
10
|
-
|
|
11
|
-
import type { QueryExecutor, TraceMetadata } from "../registry.js";
|
|
11
|
+
|
|
12
12
|
import { IntegrationError } from "../../runtime/errors.js";
|
|
13
|
+
import type { QueryExecutor, TraceMetadata } from "../registry.js";
|
|
14
|
+
import type { IntegrationConfig, IntegrationClientImpl } from "../types.js";
|
|
13
15
|
import type { SmtpClient, SmtpSendOptions } from "./types.js";
|
|
14
16
|
|
|
15
17
|
/**
|
|
@@ -5,13 +5,15 @@
|
|
|
5
5
|
* runtime validation using Zod schemas.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import type { z } from "zod";
|
|
9
8
|
import type { PartialMessage } from "@bufbuild/protobuf";
|
|
9
|
+
import type { z } from "zod";
|
|
10
|
+
|
|
10
11
|
import type { Plugin as SnowflakePlugin } from "@superblocksteam/types/dist/src/plugins/snowflake/v1/plugin_pb";
|
|
11
|
-
|
|
12
|
-
import type { QueryExecutor, TraceMetadata } from "../registry.js";
|
|
12
|
+
|
|
13
13
|
import { QueryValidationError } from "../../errors.js";
|
|
14
14
|
import { IntegrationError } from "../../runtime/errors.js";
|
|
15
|
+
import type { QueryExecutor, TraceMetadata } from "../registry.js";
|
|
16
|
+
import type { IntegrationConfig, IntegrationClientImpl } from "../types.js";
|
|
15
17
|
import { describeType } from "../utils.js";
|
|
16
18
|
import type { SnowflakeClient } from "./types.js";
|
|
17
19
|
|