@superblocksteam/sdk-api 2.0.102-next.0 → 2.0.102
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 +41 -47
- 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 +3 -9
- package/dist/integrations/couchbase/client.d.ts.map +1 -1
- package/dist/integrations/couchbase/client.js +33 -27
- 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 +1 -3
- 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 +0 -1
- package/src/api/definition.ts +1 -1
- package/src/api/streaming.test.ts +2 -3
- package/src/api/streaming.ts +1 -2
- package/src/integrations/athena/client.ts +3 -5
- package/src/integrations/athena/types.ts +0 -1
- package/src/integrations/base/graphql-integration-client.ts +2 -3
- package/src/integrations/base/rest-api-integration-client.ts +7 -9
- package/src/integrations/base/types.ts +0 -1
- package/src/integrations/bigquery/client.ts +3 -5
- package/src/integrations/bigquery/types.ts +0 -1
- package/src/integrations/cockroachdb/client.ts +3 -5
- package/src/integrations/cockroachdb/types.ts +0 -1
- package/src/integrations/cosmosdb/client.test.ts +1 -2
- package/src/integrations/cosmosdb/client.ts +3 -5
- package/src/integrations/cosmosdb/types.ts +0 -1
- package/src/integrations/couchbase/client.ts +46 -34
- package/src/integrations/couchbase/types.ts +0 -1
- package/src/integrations/databricks/client.ts +3 -5
- package/src/integrations/databricks/types.ts +0 -1
- package/src/integrations/declarations.test.ts +0 -1
- package/src/integrations/declarations.ts +36 -36
- package/src/integrations/dynamodb/client.ts +2 -3
- package/src/integrations/dynamodb/types.ts +0 -1
- package/src/integrations/gcs/client.ts +3 -5
- package/src/integrations/gcs/types.ts +0 -1
- package/src/integrations/graphql/types.ts +1 -2
- package/src/integrations/gsheets/client.ts +3 -5
- package/src/integrations/gsheets/types.ts +0 -1
- package/src/integrations/kafka/client.ts +2 -3
- package/src/integrations/kafka/types.ts +0 -1
- package/src/integrations/kinesis/client.ts +2 -2
- package/src/integrations/lakebase/client.ts +4 -6
- package/src/integrations/lakebase/types.ts +0 -1
- package/src/integrations/mariadb/client.ts +3 -5
- package/src/integrations/mariadb/types.ts +0 -1
- package/src/integrations/mongodb/client.ts +3 -5
- package/src/integrations/mongodb/types.ts +0 -1
- package/src/integrations/mssql/client.ts +3 -5
- package/src/integrations/mssql/types.ts +0 -1
- package/src/integrations/mysql/client.ts +3 -5
- package/src/integrations/mysql/types.ts +0 -1
- package/src/integrations/oracledb/client.ts +3 -5
- package/src/integrations/oracledb/types.ts +0 -1
- package/src/integrations/postgres/client.ts +4 -6
- package/src/integrations/postgres/types.ts +0 -1
- package/src/integrations/python/client.test.ts +2 -3
- package/src/integrations/python/client.ts +3 -5
- package/src/integrations/python/types.ts +0 -1
- package/src/integrations/redis/client.ts +2 -3
- package/src/integrations/redis/types.ts +0 -1
- package/src/integrations/redshift/client.ts +3 -5
- package/src/integrations/redshift/types.ts +0 -1
- package/src/integrations/registry.test.ts +0 -1
- package/src/integrations/registry.ts +23 -23
- package/src/integrations/s3/client.ts +3 -5
- package/src/integrations/s3/types.ts +1 -4
- package/src/integrations/salesforce/client.ts +2 -3
- package/src/integrations/salesforce/types.ts +0 -1
- package/src/integrations/smtp/client.ts +2 -4
- package/src/integrations/snowflake/client.ts +3 -5
- package/src/integrations/snowflake/types.ts +0 -1
- package/src/integrations/snowflakepostgres/client.ts +1 -1
- package/src/integrations/snowflakepostgres/types.ts +0 -1
- 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 +0 -1
- package/src/integrations/lakebase/README.md +0 -242
- package/src/integrations/restapiintegration/README.md +0 -359
- package/src/integrations/smtp/README.md +0 -220
- package/src/integrations/snowflakecortex/README.md +0 -216
- package/src/integrations/snowflakepostgres/README.md +0 -233
package/src/runtime/context.ts
CHANGED
|
@@ -5,22 +5,22 @@
|
|
|
5
5
|
* providing access to integrations, logging, and environment.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import type { IntegrationDeclaration } from "../integrations/declarations.js";
|
|
9
|
-
import {
|
|
10
|
-
createClient,
|
|
11
|
-
type QueryExecutor,
|
|
12
|
-
type TraceMetadata,
|
|
13
|
-
} from "../integrations/registry.js";
|
|
14
|
-
import type {
|
|
15
|
-
IntegrationConfig,
|
|
16
|
-
IntegrationClientImpl,
|
|
17
|
-
} from "../integrations/types.js";
|
|
18
8
|
import type {
|
|
19
9
|
ApiContext,
|
|
20
10
|
ApiUser,
|
|
21
11
|
Logger,
|
|
22
12
|
AnyIntegrationRef,
|
|
23
13
|
} from "../types.js";
|
|
14
|
+
import type {
|
|
15
|
+
IntegrationConfig,
|
|
16
|
+
IntegrationClientImpl,
|
|
17
|
+
} from "../integrations/types.js";
|
|
18
|
+
import type { IntegrationDeclaration } from "../integrations/declarations.js";
|
|
19
|
+
import {
|
|
20
|
+
createClient,
|
|
21
|
+
type QueryExecutor,
|
|
22
|
+
type TraceMetadata,
|
|
23
|
+
} from "../integrations/registry.js";
|
|
24
24
|
import { createDefaultLogger } from "./logger.js";
|
|
25
25
|
|
|
26
26
|
/**
|
|
@@ -5,6 +5,16 @@
|
|
|
5
5
|
* access to integrations (with streaming support), logging, and environment.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
import type {
|
|
9
|
+
ApiContext,
|
|
10
|
+
ApiUser,
|
|
11
|
+
Logger,
|
|
12
|
+
AnyIntegrationRef,
|
|
13
|
+
} from "../types.js";
|
|
14
|
+
import type {
|
|
15
|
+
IntegrationConfig,
|
|
16
|
+
IntegrationClientImpl,
|
|
17
|
+
} from "../integrations/types.js";
|
|
8
18
|
import type { IntegrationDeclaration } from "../integrations/declarations.js";
|
|
9
19
|
import {
|
|
10
20
|
createClient,
|
|
@@ -12,16 +22,6 @@ import {
|
|
|
12
22
|
type StreamingQueryExecutor,
|
|
13
23
|
type TraceMetadata,
|
|
14
24
|
} 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
25
|
import { createDefaultLogger } from "./logger.js";
|
|
26
26
|
|
|
27
27
|
/**
|
|
@@ -10,6 +10,10 @@ import { getIntegrationDeclarations } from "../integrations/declarations.js";
|
|
|
10
10
|
import type { TraceMetadata } from "../integrations/registry.js";
|
|
11
11
|
import type { IntegrationConfig } from "../integrations/types.js";
|
|
12
12
|
import type { ApiUser } from "../types.js";
|
|
13
|
+
import {
|
|
14
|
+
createStreamingApiContext,
|
|
15
|
+
type CreateStreamingContextOptions,
|
|
16
|
+
} from "./streaming-context.js";
|
|
13
17
|
import {
|
|
14
18
|
SdkError,
|
|
15
19
|
InputValidationError,
|
|
@@ -17,10 +21,6 @@ import {
|
|
|
17
21
|
ErrorCode,
|
|
18
22
|
type ErrorCodeType,
|
|
19
23
|
} from "./errors.js";
|
|
20
|
-
import {
|
|
21
|
-
createStreamingApiContext,
|
|
22
|
-
type CreateStreamingContextOptions,
|
|
23
|
-
} from "./streaming-context.js";
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* Request to execute a streaming API.
|
package/src/types.ts
CHANGED
|
@@ -1,242 +0,0 @@
|
|
|
1
|
-
# Lakebase Client
|
|
2
|
-
|
|
3
|
-
Execute SQL queries and statements against Lakebase databases with full type safety and runtime validation.
|
|
4
|
-
|
|
5
|
-
## Methods
|
|
6
|
-
|
|
7
|
-
| Method | Description |
|
|
8
|
-
| ------------------------------------------- | -------------------------------------------------------------------------- |
|
|
9
|
-
| `query<T>(sql, schema, params?, metadata?)` | Execute a SELECT query and return validated, typed results |
|
|
10
|
-
| `execute(sql, params?, metadata?)` | Execute a statement (INSERT, UPDATE, DELETE) and return affected row count |
|
|
11
|
-
|
|
12
|
-
## Usage
|
|
13
|
-
|
|
14
|
-
### Basic Query with Schema Validation
|
|
15
|
-
|
|
16
|
-
```typescript
|
|
17
|
-
import { api, z, lakebase } from "@superblocksteam/sdk-api";
|
|
18
|
-
|
|
19
|
-
// Integration ID from the integrations panel
|
|
20
|
-
const LAKEBASE_DB = "a1b2c3d4-5678-90ab-cdef-111111111111";
|
|
21
|
-
|
|
22
|
-
const UserSchema = z.object({
|
|
23
|
-
id: z.string(),
|
|
24
|
-
name: z.string(),
|
|
25
|
-
email: z.string(),
|
|
26
|
-
created_at: z.string(),
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
export default api({
|
|
30
|
-
name: "GetUsers",
|
|
31
|
-
integrations: {
|
|
32
|
-
db: lakebase(LAKEBASE_DB),
|
|
33
|
-
},
|
|
34
|
-
input: z.object({
|
|
35
|
-
status: z.string(),
|
|
36
|
-
}),
|
|
37
|
-
output: z.object({
|
|
38
|
-
users: z.array(UserSchema),
|
|
39
|
-
}),
|
|
40
|
-
async run(ctx, { status }) {
|
|
41
|
-
const users = await ctx.integrations.db.query(
|
|
42
|
-
"SELECT id, name, email, created_at FROM users WHERE status = $1",
|
|
43
|
-
UserSchema,
|
|
44
|
-
[status],
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
return { users };
|
|
48
|
-
},
|
|
49
|
-
});
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### Executing INSERT, UPDATE, DELETE Statements
|
|
53
|
-
|
|
54
|
-
```typescript
|
|
55
|
-
import { api, z, lakebase } from "@superblocksteam/sdk-api";
|
|
56
|
-
|
|
57
|
-
const LAKEBASE_DB = "a1b2c3d4-5678-90ab-cdef-111111111111";
|
|
58
|
-
|
|
59
|
-
export default api({
|
|
60
|
-
name: "ManageUsers",
|
|
61
|
-
integrations: {
|
|
62
|
-
db: lakebase(LAKEBASE_DB),
|
|
63
|
-
},
|
|
64
|
-
input: z.object({
|
|
65
|
-
name: z.string(),
|
|
66
|
-
email: z.string(),
|
|
67
|
-
}),
|
|
68
|
-
output: z.object({ success: z.boolean() }),
|
|
69
|
-
|
|
70
|
-
async run(ctx, { name, email }) {
|
|
71
|
-
// INSERT
|
|
72
|
-
await ctx.integrations.db.execute(
|
|
73
|
-
"INSERT INTO users (name, email) VALUES ($1, $2)",
|
|
74
|
-
[name, email],
|
|
75
|
-
);
|
|
76
|
-
|
|
77
|
-
// UPDATE
|
|
78
|
-
const updateResult = await ctx.integrations.db.execute(
|
|
79
|
-
"UPDATE users SET last_login = NOW() WHERE email = $1",
|
|
80
|
-
[email],
|
|
81
|
-
);
|
|
82
|
-
console.log(`Updated ${updateResult.rowCount} rows`);
|
|
83
|
-
|
|
84
|
-
// DELETE
|
|
85
|
-
const deleteResult = await ctx.integrations.db.execute(
|
|
86
|
-
"DELETE FROM sessions WHERE expires_at < NOW()",
|
|
87
|
-
);
|
|
88
|
-
console.log(`Deleted ${deleteResult.rowCount} expired sessions`);
|
|
89
|
-
|
|
90
|
-
return { success: true };
|
|
91
|
-
},
|
|
92
|
-
});
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
### Query with JOIN
|
|
96
|
-
|
|
97
|
-
```typescript
|
|
98
|
-
const OrderSchema = z.object({
|
|
99
|
-
order_id: z.string(),
|
|
100
|
-
customer_name: z.string(),
|
|
101
|
-
total: z.string(), // NUMERIC as string
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
const orders = await ctx.integrations.db.query(
|
|
105
|
-
`SELECT o.id as order_id, c.name as customer_name, o.total
|
|
106
|
-
FROM orders o
|
|
107
|
-
JOIN customers c ON o.customer_id = c.id
|
|
108
|
-
WHERE o.status = $1`,
|
|
109
|
-
OrderSchema,
|
|
110
|
-
["pending"],
|
|
111
|
-
);
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
## Trace Metadata
|
|
115
|
-
|
|
116
|
-
All methods accept an optional `metadata` parameter as the last argument for diagnostics labeling:
|
|
117
|
-
|
|
118
|
-
```typescript
|
|
119
|
-
const users = await ctx.integrations.db.query(
|
|
120
|
-
"SELECT * FROM users WHERE status = $1",
|
|
121
|
-
UserSchema,
|
|
122
|
-
["active"],
|
|
123
|
-
{ label: "Fetch active users" },
|
|
124
|
-
);
|
|
125
|
-
|
|
126
|
-
await ctx.integrations.db.execute(
|
|
127
|
-
"DELETE FROM sessions WHERE expires_at < NOW()",
|
|
128
|
-
undefined, // no params
|
|
129
|
-
{ label: "Clean expired sessions" },
|
|
130
|
-
);
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
When `includeDiagnostics` is enabled, `label` and `description` appear in the trace view. See the [root SDK README](../../../README.md#trace-metadata) for details.
|
|
134
|
-
|
|
135
|
-
## Common Pitfalls
|
|
136
|
-
|
|
137
|
-
### Uses `$1` Placeholders (PostgreSQL-Style)
|
|
138
|
-
|
|
139
|
-
Lakebase uses `$1, $2, ...` for parameter placeholders, following PostgreSQL conventions:
|
|
140
|
-
|
|
141
|
-
```typescript
|
|
142
|
-
// WRONG - Question-mark placeholders
|
|
143
|
-
const users = await ctx.integrations.db.query(
|
|
144
|
-
"SELECT * FROM users WHERE name = ? AND status = ?",
|
|
145
|
-
UserSchema,
|
|
146
|
-
[name, status],
|
|
147
|
-
);
|
|
148
|
-
|
|
149
|
-
// CORRECT - Use $1, $2, ... placeholders
|
|
150
|
-
const users = await ctx.integrations.db.query(
|
|
151
|
-
"SELECT * FROM users WHERE name = $1 AND status = $2",
|
|
152
|
-
UserSchema,
|
|
153
|
-
[name, status],
|
|
154
|
-
);
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
### Schema Parameter is Required
|
|
158
|
-
|
|
159
|
-
The `query()` method requires a Zod schema for runtime validation:
|
|
160
|
-
|
|
161
|
-
```typescript
|
|
162
|
-
// WRONG - Missing schema parameter
|
|
163
|
-
const users = await ctx.integrations.db.query(
|
|
164
|
-
"SELECT * FROM users",
|
|
165
|
-
[
|
|
166
|
-
/* params */
|
|
167
|
-
], // This is wrong - params are 3rd argument
|
|
168
|
-
);
|
|
169
|
-
|
|
170
|
-
// CORRECT - Schema is the second parameter
|
|
171
|
-
const users = await ctx.integrations.db.query(
|
|
172
|
-
"SELECT * FROM users WHERE id = $1",
|
|
173
|
-
UserSchema, // Schema is required
|
|
174
|
-
[userId], // Params are optional, third argument
|
|
175
|
-
);
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
### Use Parameterized Queries to Prevent SQL Injection
|
|
179
|
-
|
|
180
|
-
Always use `$1, $2, ...` placeholders instead of string interpolation:
|
|
181
|
-
|
|
182
|
-
```typescript
|
|
183
|
-
// WRONG - SQL injection vulnerability
|
|
184
|
-
const users = await ctx.integrations.db.query(
|
|
185
|
-
`SELECT * FROM users WHERE name = '${userName}'`, // DANGEROUS!
|
|
186
|
-
UserSchema,
|
|
187
|
-
);
|
|
188
|
-
|
|
189
|
-
// CORRECT - Use parameterized queries
|
|
190
|
-
const users = await ctx.integrations.db.query(
|
|
191
|
-
"SELECT * FROM users WHERE name = $1",
|
|
192
|
-
UserSchema,
|
|
193
|
-
[userName], // Safe - value is escaped
|
|
194
|
-
);
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
### NUMERIC/DECIMAL Values Returned as Strings
|
|
198
|
-
|
|
199
|
-
Large `NUMERIC` and `DECIMAL` columns are returned as strings to preserve precision:
|
|
200
|
-
|
|
201
|
-
```typescript
|
|
202
|
-
// WRONG - May lose precision
|
|
203
|
-
const schema = z.object({ price: z.number() });
|
|
204
|
-
|
|
205
|
-
// CORRECT - Keep as string or transform
|
|
206
|
-
const schema = z.object({
|
|
207
|
-
price: z.string().transform((val) => parseFloat(val)),
|
|
208
|
-
});
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
### Handling NULL Values
|
|
212
|
-
|
|
213
|
-
```typescript
|
|
214
|
-
// WRONG - Will fail if column contains NULL
|
|
215
|
-
const schema = z.object({ bio: z.string() });
|
|
216
|
-
|
|
217
|
-
// CORRECT - Mark nullable columns
|
|
218
|
-
const schema = z.object({ bio: z.string().nullable() });
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
## Error Handling
|
|
222
|
-
|
|
223
|
-
### QueryValidationError
|
|
224
|
-
|
|
225
|
-
Thrown when query results fail schema validation:
|
|
226
|
-
|
|
227
|
-
```typescript
|
|
228
|
-
import { QueryValidationError } from "@superblocksteam/sdk-api";
|
|
229
|
-
|
|
230
|
-
try {
|
|
231
|
-
const users = await ctx.integrations.db.query(
|
|
232
|
-
"SELECT * FROM users",
|
|
233
|
-
UserSchema,
|
|
234
|
-
);
|
|
235
|
-
} catch (error) {
|
|
236
|
-
if (error instanceof QueryValidationError) {
|
|
237
|
-
console.error("Row index:", error.details.rowIndex);
|
|
238
|
-
console.error("Validation errors:", error.details.errors);
|
|
239
|
-
console.error("Actual row data:", error.details.row);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
```
|
|
@@ -1,359 +0,0 @@
|
|
|
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
|
-
```
|