@squadbase/connectors 0.0.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/dist/index.d.ts +144 -0
- package/dist/index.js +352 -0
- package/dist/index.ui.d.ts +14 -0
- package/dist/index.ui.js +387 -0
- package/package.json +72 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { Tool } from 'ai';
|
|
2
|
+
import { ZodType } from 'zod';
|
|
3
|
+
|
|
4
|
+
interface ReleaseFlag {
|
|
5
|
+
dev1: boolean;
|
|
6
|
+
dev2: boolean;
|
|
7
|
+
prod: boolean;
|
|
8
|
+
}
|
|
9
|
+
interface ProxyPolicyRule {
|
|
10
|
+
host?: string;
|
|
11
|
+
hostRegex?: string;
|
|
12
|
+
port?: number;
|
|
13
|
+
pathPrefix?: string;
|
|
14
|
+
methods?: ("GET" | "POST" | "PUT" | "PATCH" | "DELETE")[];
|
|
15
|
+
allowPrivateNetwork?: boolean;
|
|
16
|
+
}
|
|
17
|
+
interface ProxyPolicy {
|
|
18
|
+
allowlist: ProxyPolicyRule[];
|
|
19
|
+
}
|
|
20
|
+
interface ConnectorConnection {
|
|
21
|
+
id: string;
|
|
22
|
+
name: string;
|
|
23
|
+
parameters: {
|
|
24
|
+
slug: string;
|
|
25
|
+
value: string | null;
|
|
26
|
+
}[];
|
|
27
|
+
}
|
|
28
|
+
interface ConnectorToolsConfig {
|
|
29
|
+
oauthProxy: {
|
|
30
|
+
appApiKey: string;
|
|
31
|
+
projectId: string;
|
|
32
|
+
environmentId: string;
|
|
33
|
+
sandboxId: string;
|
|
34
|
+
appApiBaseUrl: string;
|
|
35
|
+
previewBaseDomain: string;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
interface DatabaseClient {
|
|
39
|
+
query(sql: string, params?: unknown[]): Promise<{
|
|
40
|
+
rows: Record<string, unknown>[];
|
|
41
|
+
}>;
|
|
42
|
+
}
|
|
43
|
+
interface ConnectionEntry {
|
|
44
|
+
connector: {
|
|
45
|
+
slug: string;
|
|
46
|
+
authType?: string | null;
|
|
47
|
+
};
|
|
48
|
+
envVars: Record<string, string>;
|
|
49
|
+
}
|
|
50
|
+
interface DynamicToolProps {
|
|
51
|
+
toolName: string;
|
|
52
|
+
state: string;
|
|
53
|
+
input: unknown;
|
|
54
|
+
output: unknown;
|
|
55
|
+
errorText: string | undefined;
|
|
56
|
+
onSuggest?: (prompt: string, newThread: boolean) => void;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
declare class ParameterDefinition {
|
|
60
|
+
readonly slug: string;
|
|
61
|
+
readonly name: string;
|
|
62
|
+
readonly description: string;
|
|
63
|
+
readonly envVarBaseKey: string;
|
|
64
|
+
readonly type: "text" | "base64EncodedJson";
|
|
65
|
+
readonly secret: boolean;
|
|
66
|
+
readonly required: boolean;
|
|
67
|
+
constructor(config: {
|
|
68
|
+
slug: string;
|
|
69
|
+
name: string;
|
|
70
|
+
description: string;
|
|
71
|
+
envVarBaseKey: string;
|
|
72
|
+
type: "text" | "base64EncodedJson";
|
|
73
|
+
secret: boolean;
|
|
74
|
+
required: boolean;
|
|
75
|
+
});
|
|
76
|
+
/**
|
|
77
|
+
* Resolve a parameter value from a connection object (agent environment).
|
|
78
|
+
*/
|
|
79
|
+
resolve(connection: ConnectorConnection): string;
|
|
80
|
+
/**
|
|
81
|
+
* Resolve the value of a connection parameter from environment variables (vite-server).
|
|
82
|
+
*/
|
|
83
|
+
resolveEnvVar(entry: ConnectionEntry, connectionId: string): string;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
declare class ConnectorTool<I = any, O = any> {
|
|
87
|
+
readonly name: string;
|
|
88
|
+
readonly description: string;
|
|
89
|
+
readonly inputSchema: ZodType<I>;
|
|
90
|
+
readonly outputSchema: ZodType<O>;
|
|
91
|
+
private readonly _execute;
|
|
92
|
+
constructor(config: {
|
|
93
|
+
readonly name: string;
|
|
94
|
+
readonly description: string;
|
|
95
|
+
readonly inputSchema: ZodType<I>;
|
|
96
|
+
readonly outputSchema: ZodType<O>;
|
|
97
|
+
readonly execute: (input: I, connections: ConnectorConnection[], config: ConnectorToolsConfig) => Promise<O>;
|
|
98
|
+
});
|
|
99
|
+
createTool(connections: ConnectorConnection[], config: ConnectorToolsConfig): Tool;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
declare class ConnectorPlugin {
|
|
103
|
+
readonly slug: string;
|
|
104
|
+
readonly authType: string | null;
|
|
105
|
+
readonly name: string;
|
|
106
|
+
readonly description: string;
|
|
107
|
+
readonly iconUrl: string;
|
|
108
|
+
readonly order?: number;
|
|
109
|
+
readonly parameters: readonly ParameterDefinition[];
|
|
110
|
+
readonly releaseFlag: ReleaseFlag;
|
|
111
|
+
readonly proxyPolicy?: ProxyPolicy;
|
|
112
|
+
readonly systemPrompt: string;
|
|
113
|
+
readonly tools: readonly ConnectorTool[];
|
|
114
|
+
readonly createClient?: (entry: ConnectionEntry, connectionId: string) => DatabaseClient;
|
|
115
|
+
constructor(config: {
|
|
116
|
+
slug: string;
|
|
117
|
+
authType: string | null;
|
|
118
|
+
name: string;
|
|
119
|
+
description: string;
|
|
120
|
+
iconUrl: string;
|
|
121
|
+
order?: number;
|
|
122
|
+
parameters: readonly ParameterDefinition[];
|
|
123
|
+
releaseFlag: ReleaseFlag;
|
|
124
|
+
proxyPolicy?: ProxyPolicy;
|
|
125
|
+
systemPrompt: string;
|
|
126
|
+
tools: readonly ConnectorTool[];
|
|
127
|
+
createClient?: (entry: ConnectionEntry, connectionId: string) => DatabaseClient;
|
|
128
|
+
});
|
|
129
|
+
get connectorKey(): string;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
declare const AUTH_TYPES: {
|
|
133
|
+
readonly OAUTH: "oauth";
|
|
134
|
+
readonly API_KEY: "api-key";
|
|
135
|
+
readonly JWT: "jwt";
|
|
136
|
+
readonly SERVICE_ACCOUNT: "service-account";
|
|
137
|
+
readonly PAT: "pat";
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
declare const connectors: ConnectorPlugin[];
|
|
141
|
+
|
|
142
|
+
declare const snowflakePatConnector: ConnectorPlugin;
|
|
143
|
+
|
|
144
|
+
export { AUTH_TYPES, type ConnectionEntry, type ConnectorConnection, ConnectorPlugin, ConnectorTool, type ConnectorToolsConfig, type DatabaseClient, type DynamicToolProps, ParameterDefinition, type ProxyPolicy, type ProxyPolicyRule, type ReleaseFlag, connectors, snowflakePatConnector };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
// src/parameter-definition.ts
|
|
2
|
+
var ParameterDefinition = class {
|
|
3
|
+
slug;
|
|
4
|
+
name;
|
|
5
|
+
description;
|
|
6
|
+
envVarBaseKey;
|
|
7
|
+
type;
|
|
8
|
+
secret;
|
|
9
|
+
required;
|
|
10
|
+
constructor(config) {
|
|
11
|
+
this.slug = config.slug;
|
|
12
|
+
this.name = config.name;
|
|
13
|
+
this.description = config.description;
|
|
14
|
+
this.envVarBaseKey = config.envVarBaseKey;
|
|
15
|
+
this.type = config.type;
|
|
16
|
+
this.secret = config.secret;
|
|
17
|
+
this.required = config.required;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Resolve a parameter value from a connection object (agent environment).
|
|
21
|
+
*/
|
|
22
|
+
resolve(connection) {
|
|
23
|
+
const param = connection.parameters.find((p) => p.slug === this.slug);
|
|
24
|
+
if (!param || param.value == null) {
|
|
25
|
+
throw new Error(
|
|
26
|
+
`Parameter "${this.slug}" not found or has no value in connection "${connection.id}"`
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
return param.value;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Resolve the value of a connection parameter from environment variables (vite-server).
|
|
33
|
+
*/
|
|
34
|
+
resolveEnvVar(entry, connectionId) {
|
|
35
|
+
const envVarName = entry.envVars[this.slug];
|
|
36
|
+
if (!envVarName) {
|
|
37
|
+
throw new Error(
|
|
38
|
+
`No env var mapping for parameter "${this.slug}" in connection "${connectionId}"`
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
const value = process.env[envVarName];
|
|
42
|
+
if (!value) {
|
|
43
|
+
throw new Error(
|
|
44
|
+
`Environment variable "${envVarName}" is not set (connection "${connectionId}", parameter "${this.slug}")`
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
return value;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// src/connector-tool.ts
|
|
52
|
+
var ConnectorTool = class {
|
|
53
|
+
name;
|
|
54
|
+
description;
|
|
55
|
+
inputSchema;
|
|
56
|
+
outputSchema;
|
|
57
|
+
_execute;
|
|
58
|
+
constructor(config) {
|
|
59
|
+
this.name = config.name;
|
|
60
|
+
this.description = config.description;
|
|
61
|
+
this.inputSchema = config.inputSchema;
|
|
62
|
+
this.outputSchema = config.outputSchema;
|
|
63
|
+
this._execute = config.execute;
|
|
64
|
+
}
|
|
65
|
+
createTool(connections, config) {
|
|
66
|
+
return {
|
|
67
|
+
description: this.description,
|
|
68
|
+
inputSchema: this.inputSchema,
|
|
69
|
+
outputSchema: this.outputSchema,
|
|
70
|
+
execute: (input) => this._execute(input, connections, config)
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
// src/connector-plugin.ts
|
|
76
|
+
var ConnectorPlugin = class {
|
|
77
|
+
slug;
|
|
78
|
+
authType;
|
|
79
|
+
name;
|
|
80
|
+
description;
|
|
81
|
+
iconUrl;
|
|
82
|
+
order;
|
|
83
|
+
parameters;
|
|
84
|
+
releaseFlag;
|
|
85
|
+
proxyPolicy;
|
|
86
|
+
systemPrompt;
|
|
87
|
+
tools;
|
|
88
|
+
createClient;
|
|
89
|
+
constructor(config) {
|
|
90
|
+
this.slug = config.slug;
|
|
91
|
+
this.authType = config.authType;
|
|
92
|
+
this.name = config.name;
|
|
93
|
+
this.description = config.description;
|
|
94
|
+
this.iconUrl = config.iconUrl;
|
|
95
|
+
this.order = config.order;
|
|
96
|
+
this.parameters = config.parameters;
|
|
97
|
+
this.releaseFlag = config.releaseFlag;
|
|
98
|
+
this.proxyPolicy = config.proxyPolicy;
|
|
99
|
+
this.systemPrompt = config.systemPrompt;
|
|
100
|
+
this.tools = config.tools;
|
|
101
|
+
this.createClient = config.createClient;
|
|
102
|
+
}
|
|
103
|
+
get connectorKey() {
|
|
104
|
+
return this.authType ? `${this.slug}-${this.authType}` : this.slug;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
// src/auth-types.ts
|
|
109
|
+
var AUTH_TYPES = {
|
|
110
|
+
OAUTH: "oauth",
|
|
111
|
+
API_KEY: "api-key",
|
|
112
|
+
JWT: "jwt",
|
|
113
|
+
SERVICE_ACCOUNT: "service-account",
|
|
114
|
+
PAT: "pat"
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
// src/connectors/snowflake-pat/parameters.ts
|
|
118
|
+
var parameters = {
|
|
119
|
+
account: new ParameterDefinition({
|
|
120
|
+
slug: "account",
|
|
121
|
+
name: "Snowflake Account",
|
|
122
|
+
description: "The Snowflake account identifier (e.g., xy12345.us-east-1).",
|
|
123
|
+
envVarBaseKey: "SNOWFLAKE_ACCOUNT",
|
|
124
|
+
type: "text",
|
|
125
|
+
secret: false,
|
|
126
|
+
required: true
|
|
127
|
+
}),
|
|
128
|
+
user: new ParameterDefinition({
|
|
129
|
+
slug: "user",
|
|
130
|
+
name: "Snowflake User",
|
|
131
|
+
description: "The username for Snowflake authentication.",
|
|
132
|
+
envVarBaseKey: "SNOWFLAKE_USER",
|
|
133
|
+
type: "text",
|
|
134
|
+
secret: false,
|
|
135
|
+
required: true
|
|
136
|
+
}),
|
|
137
|
+
role: new ParameterDefinition({
|
|
138
|
+
slug: "role",
|
|
139
|
+
name: "Snowflake Role",
|
|
140
|
+
description: "The role to use when connecting to Snowflake.",
|
|
141
|
+
envVarBaseKey: "SNOWFLAKE_ROLE",
|
|
142
|
+
type: "text",
|
|
143
|
+
secret: false,
|
|
144
|
+
required: true
|
|
145
|
+
}),
|
|
146
|
+
warehouse: new ParameterDefinition({
|
|
147
|
+
slug: "warehouse",
|
|
148
|
+
name: "Snowflake Warehouse",
|
|
149
|
+
description: "The warehouse to use for executing queries.",
|
|
150
|
+
envVarBaseKey: "SNOWFLAKE_WAREHOUSE",
|
|
151
|
+
type: "text",
|
|
152
|
+
secret: false,
|
|
153
|
+
required: true
|
|
154
|
+
}),
|
|
155
|
+
pat: new ParameterDefinition({
|
|
156
|
+
slug: "pat",
|
|
157
|
+
name: "Personal Access Token",
|
|
158
|
+
description: "Snowflake Personal Access Token (PAT) for authentication.",
|
|
159
|
+
envVarBaseKey: "SNOWFLAKE_PASSWORD",
|
|
160
|
+
type: "text",
|
|
161
|
+
secret: true,
|
|
162
|
+
required: true
|
|
163
|
+
})
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
// src/connectors/snowflake-pat/tools/execute-query/tool.ts
|
|
167
|
+
import { z } from "zod";
|
|
168
|
+
var MAX_ROWS = 500;
|
|
169
|
+
var QUERY_TIMEOUT_MS = 6e4;
|
|
170
|
+
var inputSchema = z.object({
|
|
171
|
+
toolUseIntent: z.string().optional().describe(
|
|
172
|
+
"Brief description of what you intend to accomplish with this tool call"
|
|
173
|
+
),
|
|
174
|
+
connectionId: z.string().describe("ID of the Snowflake connection to use"),
|
|
175
|
+
sql: z.string().describe(
|
|
176
|
+
"Snowflake SQL query. Use fully qualified names DB.SCHEMA.TABLE for table references."
|
|
177
|
+
)
|
|
178
|
+
});
|
|
179
|
+
var outputSchema = z.discriminatedUnion("success", [
|
|
180
|
+
z.object({
|
|
181
|
+
success: z.literal(true),
|
|
182
|
+
rowCount: z.number(),
|
|
183
|
+
truncated: z.boolean(),
|
|
184
|
+
rows: z.array(z.record(z.unknown()))
|
|
185
|
+
}),
|
|
186
|
+
z.object({
|
|
187
|
+
success: z.literal(false),
|
|
188
|
+
error: z.string()
|
|
189
|
+
})
|
|
190
|
+
]);
|
|
191
|
+
var executeQueryTool = new ConnectorTool({
|
|
192
|
+
name: "executeQuery",
|
|
193
|
+
description: `Execute SQL against Snowflake. Returns up to ${MAX_ROWS} rows.
|
|
194
|
+
Use for: schema exploration (SHOW DATABASES/SCHEMAS/TABLES, DESCRIBE TABLE, INFORMATION_SCHEMA), data sampling, analytical queries.
|
|
195
|
+
Avoid loading large amounts of data; always include LIMIT in queries.`,
|
|
196
|
+
inputSchema,
|
|
197
|
+
outputSchema,
|
|
198
|
+
async execute({ connectionId, sql }, connections) {
|
|
199
|
+
const connection = connections.find((c) => c.id === connectionId);
|
|
200
|
+
if (!connection) {
|
|
201
|
+
return {
|
|
202
|
+
success: false,
|
|
203
|
+
error: `Connection ${connectionId} not found`
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
console.log(
|
|
207
|
+
`[connector-query] snowflake-pat/${connection.name}: ${sql}`
|
|
208
|
+
);
|
|
209
|
+
try {
|
|
210
|
+
const snowflake = (await import("snowflake-sdk")).default;
|
|
211
|
+
snowflake.configure({ logLevel: "ERROR" });
|
|
212
|
+
const account = parameters.account.resolve(connection);
|
|
213
|
+
const user = parameters.user.resolve(connection);
|
|
214
|
+
const role = parameters.role.resolve(connection);
|
|
215
|
+
const warehouse = parameters.warehouse.resolve(connection);
|
|
216
|
+
const password = parameters.pat.resolve(connection);
|
|
217
|
+
const conn = snowflake.createConnection({
|
|
218
|
+
account,
|
|
219
|
+
username: user,
|
|
220
|
+
role,
|
|
221
|
+
warehouse,
|
|
222
|
+
password
|
|
223
|
+
});
|
|
224
|
+
await new Promise((resolve, reject) => {
|
|
225
|
+
conn.connect((err) => {
|
|
226
|
+
if (err)
|
|
227
|
+
reject(new Error(`Snowflake connect failed: ${err.message}`));
|
|
228
|
+
else resolve();
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
const allRows = await new Promise(
|
|
232
|
+
(resolve, reject) => {
|
|
233
|
+
const timeoutId = setTimeout(() => {
|
|
234
|
+
reject(
|
|
235
|
+
new Error(
|
|
236
|
+
"Snowflake query timeout: query exceeded 60 seconds"
|
|
237
|
+
)
|
|
238
|
+
);
|
|
239
|
+
}, QUERY_TIMEOUT_MS);
|
|
240
|
+
conn.execute({
|
|
241
|
+
sqlText: sql,
|
|
242
|
+
complete: (err, _stmt, rows) => {
|
|
243
|
+
clearTimeout(timeoutId);
|
|
244
|
+
if (err)
|
|
245
|
+
reject(new Error(`Snowflake query failed: ${err.message}`));
|
|
246
|
+
else resolve(rows ?? []);
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
);
|
|
251
|
+
conn.destroy((err) => {
|
|
252
|
+
if (err)
|
|
253
|
+
console.warn(
|
|
254
|
+
`[connector-query] Snowflake destroy error: ${err.message}`
|
|
255
|
+
);
|
|
256
|
+
});
|
|
257
|
+
const truncated = allRows.length > MAX_ROWS;
|
|
258
|
+
return {
|
|
259
|
+
success: true,
|
|
260
|
+
rowCount: Math.min(allRows.length, MAX_ROWS),
|
|
261
|
+
truncated,
|
|
262
|
+
rows: allRows.slice(0, MAX_ROWS)
|
|
263
|
+
};
|
|
264
|
+
} catch (err) {
|
|
265
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
266
|
+
return { success: false, error: msg };
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
// src/connectors/snowflake-pat/index.ts
|
|
272
|
+
var tools = [executeQueryTool];
|
|
273
|
+
var snowflakePatConnector = new ConnectorPlugin({
|
|
274
|
+
slug: "snowflake",
|
|
275
|
+
authType: AUTH_TYPES.PAT,
|
|
276
|
+
name: "Snowflake (PAT)",
|
|
277
|
+
description: "Connect to Snowflake using a Personal Access Token (PAT).",
|
|
278
|
+
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/6oyVtAcP3pMlXaOrts9unk/b7a9dc25d15c388b66e983041b855447/snowflake.svg",
|
|
279
|
+
order: 11,
|
|
280
|
+
parameters: Object.values(parameters),
|
|
281
|
+
releaseFlag: { dev1: true, dev2: false, prod: false },
|
|
282
|
+
systemPrompt: `## Snowflake SQL Notes
|
|
283
|
+
- Use fully qualified names DB.SCHEMA.TABLE for table references
|
|
284
|
+
- Schema exploration commands:
|
|
285
|
+
- List databases: \`SHOW DATABASES\`
|
|
286
|
+
- List schemas: \`SHOW SCHEMAS IN DATABASE db_name\`
|
|
287
|
+
- List tables: \`SHOW TABLES IN SCHEMA db_name.schema_name\`
|
|
288
|
+
- List columns: \`DESCRIBE TABLE db_name.schema_name.table_name\`
|
|
289
|
+
- INFORMATION_SCHEMA is also available: \`SELECT * FROM db_name.INFORMATION_SCHEMA.TABLES\``,
|
|
290
|
+
tools,
|
|
291
|
+
createClient(entry, connectionId) {
|
|
292
|
+
const account = parameters.account.resolveEnvVar(entry, connectionId);
|
|
293
|
+
const user = parameters.user.resolveEnvVar(entry, connectionId);
|
|
294
|
+
const role = parameters.role.resolveEnvVar(entry, connectionId);
|
|
295
|
+
const warehouse = parameters.warehouse.resolveEnvVar(entry, connectionId);
|
|
296
|
+
const password = parameters.pat.resolveEnvVar(entry, connectionId);
|
|
297
|
+
return {
|
|
298
|
+
async query(sql) {
|
|
299
|
+
const snowflake = (await import("snowflake-sdk")).default;
|
|
300
|
+
snowflake.configure({ logLevel: "ERROR" });
|
|
301
|
+
const conn = snowflake.createConnection({
|
|
302
|
+
account,
|
|
303
|
+
username: user,
|
|
304
|
+
role,
|
|
305
|
+
warehouse,
|
|
306
|
+
password
|
|
307
|
+
});
|
|
308
|
+
await new Promise((resolve, reject) => {
|
|
309
|
+
conn.connect((err) => {
|
|
310
|
+
if (err)
|
|
311
|
+
reject(new Error(`Snowflake connect failed: ${err.message}`));
|
|
312
|
+
else resolve();
|
|
313
|
+
});
|
|
314
|
+
});
|
|
315
|
+
const rows = await new Promise(
|
|
316
|
+
(resolve, reject) => {
|
|
317
|
+
conn.execute({
|
|
318
|
+
sqlText: sql,
|
|
319
|
+
complete: (err, _stmt, rows2) => {
|
|
320
|
+
if (err)
|
|
321
|
+
reject(
|
|
322
|
+
new Error(`Snowflake query failed: ${err.message}`)
|
|
323
|
+
);
|
|
324
|
+
else resolve(rows2 ?? []);
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
);
|
|
329
|
+
conn.destroy((err) => {
|
|
330
|
+
if (err)
|
|
331
|
+
console.warn(
|
|
332
|
+
`[connector-client] Snowflake destroy error: ${err.message}`
|
|
333
|
+
);
|
|
334
|
+
});
|
|
335
|
+
return { rows };
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
// src/connectors/registry.ts
|
|
342
|
+
var connectors = [
|
|
343
|
+
snowflakePatConnector
|
|
344
|
+
];
|
|
345
|
+
export {
|
|
346
|
+
AUTH_TYPES,
|
|
347
|
+
ConnectorPlugin,
|
|
348
|
+
ConnectorTool,
|
|
349
|
+
ParameterDefinition,
|
|
350
|
+
connectors,
|
|
351
|
+
snowflakePatConnector
|
|
352
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ComponentType } from 'react';
|
|
2
|
+
|
|
3
|
+
interface DynamicToolProps {
|
|
4
|
+
toolName: string;
|
|
5
|
+
state: string;
|
|
6
|
+
input: unknown;
|
|
7
|
+
output: unknown;
|
|
8
|
+
errorText: string | undefined;
|
|
9
|
+
onSuggest?: (prompt: string, newThread: boolean) => void;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
declare function getToolComponent(connectorKey: string, toolName: string): ComponentType<DynamicToolProps> | undefined;
|
|
13
|
+
|
|
14
|
+
export { getToolComponent };
|
package/dist/index.ui.js
ADDED
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
// src/connector-plugin.ts
|
|
2
|
+
var ConnectorPlugin = class {
|
|
3
|
+
slug;
|
|
4
|
+
authType;
|
|
5
|
+
name;
|
|
6
|
+
description;
|
|
7
|
+
iconUrl;
|
|
8
|
+
order;
|
|
9
|
+
parameters;
|
|
10
|
+
releaseFlag;
|
|
11
|
+
proxyPolicy;
|
|
12
|
+
systemPrompt;
|
|
13
|
+
tools;
|
|
14
|
+
createClient;
|
|
15
|
+
constructor(config) {
|
|
16
|
+
this.slug = config.slug;
|
|
17
|
+
this.authType = config.authType;
|
|
18
|
+
this.name = config.name;
|
|
19
|
+
this.description = config.description;
|
|
20
|
+
this.iconUrl = config.iconUrl;
|
|
21
|
+
this.order = config.order;
|
|
22
|
+
this.parameters = config.parameters;
|
|
23
|
+
this.releaseFlag = config.releaseFlag;
|
|
24
|
+
this.proxyPolicy = config.proxyPolicy;
|
|
25
|
+
this.systemPrompt = config.systemPrompt;
|
|
26
|
+
this.tools = config.tools;
|
|
27
|
+
this.createClient = config.createClient;
|
|
28
|
+
}
|
|
29
|
+
get connectorKey() {
|
|
30
|
+
return this.authType ? `${this.slug}-${this.authType}` : this.slug;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// src/auth-types.ts
|
|
35
|
+
var AUTH_TYPES = {
|
|
36
|
+
OAUTH: "oauth",
|
|
37
|
+
API_KEY: "api-key",
|
|
38
|
+
JWT: "jwt",
|
|
39
|
+
SERVICE_ACCOUNT: "service-account",
|
|
40
|
+
PAT: "pat"
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// src/parameter-definition.ts
|
|
44
|
+
var ParameterDefinition = class {
|
|
45
|
+
slug;
|
|
46
|
+
name;
|
|
47
|
+
description;
|
|
48
|
+
envVarBaseKey;
|
|
49
|
+
type;
|
|
50
|
+
secret;
|
|
51
|
+
required;
|
|
52
|
+
constructor(config) {
|
|
53
|
+
this.slug = config.slug;
|
|
54
|
+
this.name = config.name;
|
|
55
|
+
this.description = config.description;
|
|
56
|
+
this.envVarBaseKey = config.envVarBaseKey;
|
|
57
|
+
this.type = config.type;
|
|
58
|
+
this.secret = config.secret;
|
|
59
|
+
this.required = config.required;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Resolve a parameter value from a connection object (agent environment).
|
|
63
|
+
*/
|
|
64
|
+
resolve(connection) {
|
|
65
|
+
const param = connection.parameters.find((p) => p.slug === this.slug);
|
|
66
|
+
if (!param || param.value == null) {
|
|
67
|
+
throw new Error(
|
|
68
|
+
`Parameter "${this.slug}" not found or has no value in connection "${connection.id}"`
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
return param.value;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Resolve the value of a connection parameter from environment variables (vite-server).
|
|
75
|
+
*/
|
|
76
|
+
resolveEnvVar(entry, connectionId) {
|
|
77
|
+
const envVarName = entry.envVars[this.slug];
|
|
78
|
+
if (!envVarName) {
|
|
79
|
+
throw new Error(
|
|
80
|
+
`No env var mapping for parameter "${this.slug}" in connection "${connectionId}"`
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
const value = process.env[envVarName];
|
|
84
|
+
if (!value) {
|
|
85
|
+
throw new Error(
|
|
86
|
+
`Environment variable "${envVarName}" is not set (connection "${connectionId}", parameter "${this.slug}")`
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
return value;
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
// src/connectors/snowflake-pat/parameters.ts
|
|
94
|
+
var parameters = {
|
|
95
|
+
account: new ParameterDefinition({
|
|
96
|
+
slug: "account",
|
|
97
|
+
name: "Snowflake Account",
|
|
98
|
+
description: "The Snowflake account identifier (e.g., xy12345.us-east-1).",
|
|
99
|
+
envVarBaseKey: "SNOWFLAKE_ACCOUNT",
|
|
100
|
+
type: "text",
|
|
101
|
+
secret: false,
|
|
102
|
+
required: true
|
|
103
|
+
}),
|
|
104
|
+
user: new ParameterDefinition({
|
|
105
|
+
slug: "user",
|
|
106
|
+
name: "Snowflake User",
|
|
107
|
+
description: "The username for Snowflake authentication.",
|
|
108
|
+
envVarBaseKey: "SNOWFLAKE_USER",
|
|
109
|
+
type: "text",
|
|
110
|
+
secret: false,
|
|
111
|
+
required: true
|
|
112
|
+
}),
|
|
113
|
+
role: new ParameterDefinition({
|
|
114
|
+
slug: "role",
|
|
115
|
+
name: "Snowflake Role",
|
|
116
|
+
description: "The role to use when connecting to Snowflake.",
|
|
117
|
+
envVarBaseKey: "SNOWFLAKE_ROLE",
|
|
118
|
+
type: "text",
|
|
119
|
+
secret: false,
|
|
120
|
+
required: true
|
|
121
|
+
}),
|
|
122
|
+
warehouse: new ParameterDefinition({
|
|
123
|
+
slug: "warehouse",
|
|
124
|
+
name: "Snowflake Warehouse",
|
|
125
|
+
description: "The warehouse to use for executing queries.",
|
|
126
|
+
envVarBaseKey: "SNOWFLAKE_WAREHOUSE",
|
|
127
|
+
type: "text",
|
|
128
|
+
secret: false,
|
|
129
|
+
required: true
|
|
130
|
+
}),
|
|
131
|
+
pat: new ParameterDefinition({
|
|
132
|
+
slug: "pat",
|
|
133
|
+
name: "Personal Access Token",
|
|
134
|
+
description: "Snowflake Personal Access Token (PAT) for authentication.",
|
|
135
|
+
envVarBaseKey: "SNOWFLAKE_PASSWORD",
|
|
136
|
+
type: "text",
|
|
137
|
+
secret: true,
|
|
138
|
+
required: true
|
|
139
|
+
})
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
// src/connectors/snowflake-pat/tools/execute-query/tool.ts
|
|
143
|
+
import { z } from "zod";
|
|
144
|
+
|
|
145
|
+
// src/connector-tool.ts
|
|
146
|
+
var ConnectorTool = class {
|
|
147
|
+
name;
|
|
148
|
+
description;
|
|
149
|
+
inputSchema;
|
|
150
|
+
outputSchema;
|
|
151
|
+
_execute;
|
|
152
|
+
constructor(config) {
|
|
153
|
+
this.name = config.name;
|
|
154
|
+
this.description = config.description;
|
|
155
|
+
this.inputSchema = config.inputSchema;
|
|
156
|
+
this.outputSchema = config.outputSchema;
|
|
157
|
+
this._execute = config.execute;
|
|
158
|
+
}
|
|
159
|
+
createTool(connections, config) {
|
|
160
|
+
return {
|
|
161
|
+
description: this.description,
|
|
162
|
+
inputSchema: this.inputSchema,
|
|
163
|
+
outputSchema: this.outputSchema,
|
|
164
|
+
execute: (input) => this._execute(input, connections, config)
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
// src/connectors/snowflake-pat/tools/execute-query/tool.ts
|
|
170
|
+
var MAX_ROWS = 500;
|
|
171
|
+
var QUERY_TIMEOUT_MS = 6e4;
|
|
172
|
+
var inputSchema = z.object({
|
|
173
|
+
toolUseIntent: z.string().optional().describe(
|
|
174
|
+
"Brief description of what you intend to accomplish with this tool call"
|
|
175
|
+
),
|
|
176
|
+
connectionId: z.string().describe("ID of the Snowflake connection to use"),
|
|
177
|
+
sql: z.string().describe(
|
|
178
|
+
"Snowflake SQL query. Use fully qualified names DB.SCHEMA.TABLE for table references."
|
|
179
|
+
)
|
|
180
|
+
});
|
|
181
|
+
var outputSchema = z.discriminatedUnion("success", [
|
|
182
|
+
z.object({
|
|
183
|
+
success: z.literal(true),
|
|
184
|
+
rowCount: z.number(),
|
|
185
|
+
truncated: z.boolean(),
|
|
186
|
+
rows: z.array(z.record(z.unknown()))
|
|
187
|
+
}),
|
|
188
|
+
z.object({
|
|
189
|
+
success: z.literal(false),
|
|
190
|
+
error: z.string()
|
|
191
|
+
})
|
|
192
|
+
]);
|
|
193
|
+
var executeQueryTool = new ConnectorTool({
|
|
194
|
+
name: "executeQuery",
|
|
195
|
+
description: `Execute SQL against Snowflake. Returns up to ${MAX_ROWS} rows.
|
|
196
|
+
Use for: schema exploration (SHOW DATABASES/SCHEMAS/TABLES, DESCRIBE TABLE, INFORMATION_SCHEMA), data sampling, analytical queries.
|
|
197
|
+
Avoid loading large amounts of data; always include LIMIT in queries.`,
|
|
198
|
+
inputSchema,
|
|
199
|
+
outputSchema,
|
|
200
|
+
async execute({ connectionId, sql }, connections) {
|
|
201
|
+
const connection = connections.find((c) => c.id === connectionId);
|
|
202
|
+
if (!connection) {
|
|
203
|
+
return {
|
|
204
|
+
success: false,
|
|
205
|
+
error: `Connection ${connectionId} not found`
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
console.log(
|
|
209
|
+
`[connector-query] snowflake-pat/${connection.name}: ${sql}`
|
|
210
|
+
);
|
|
211
|
+
try {
|
|
212
|
+
const snowflake = (await import("snowflake-sdk")).default;
|
|
213
|
+
snowflake.configure({ logLevel: "ERROR" });
|
|
214
|
+
const account = parameters.account.resolve(connection);
|
|
215
|
+
const user = parameters.user.resolve(connection);
|
|
216
|
+
const role = parameters.role.resolve(connection);
|
|
217
|
+
const warehouse = parameters.warehouse.resolve(connection);
|
|
218
|
+
const password = parameters.pat.resolve(connection);
|
|
219
|
+
const conn = snowflake.createConnection({
|
|
220
|
+
account,
|
|
221
|
+
username: user,
|
|
222
|
+
role,
|
|
223
|
+
warehouse,
|
|
224
|
+
password
|
|
225
|
+
});
|
|
226
|
+
await new Promise((resolve, reject) => {
|
|
227
|
+
conn.connect((err) => {
|
|
228
|
+
if (err)
|
|
229
|
+
reject(new Error(`Snowflake connect failed: ${err.message}`));
|
|
230
|
+
else resolve();
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
const allRows = await new Promise(
|
|
234
|
+
(resolve, reject) => {
|
|
235
|
+
const timeoutId = setTimeout(() => {
|
|
236
|
+
reject(
|
|
237
|
+
new Error(
|
|
238
|
+
"Snowflake query timeout: query exceeded 60 seconds"
|
|
239
|
+
)
|
|
240
|
+
);
|
|
241
|
+
}, QUERY_TIMEOUT_MS);
|
|
242
|
+
conn.execute({
|
|
243
|
+
sqlText: sql,
|
|
244
|
+
complete: (err, _stmt, rows) => {
|
|
245
|
+
clearTimeout(timeoutId);
|
|
246
|
+
if (err)
|
|
247
|
+
reject(new Error(`Snowflake query failed: ${err.message}`));
|
|
248
|
+
else resolve(rows ?? []);
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
);
|
|
253
|
+
conn.destroy((err) => {
|
|
254
|
+
if (err)
|
|
255
|
+
console.warn(
|
|
256
|
+
`[connector-query] Snowflake destroy error: ${err.message}`
|
|
257
|
+
);
|
|
258
|
+
});
|
|
259
|
+
const truncated = allRows.length > MAX_ROWS;
|
|
260
|
+
return {
|
|
261
|
+
success: true,
|
|
262
|
+
rowCount: Math.min(allRows.length, MAX_ROWS),
|
|
263
|
+
truncated,
|
|
264
|
+
rows: allRows.slice(0, MAX_ROWS)
|
|
265
|
+
};
|
|
266
|
+
} catch (err) {
|
|
267
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
268
|
+
return { success: false, error: msg };
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
// src/connectors/snowflake-pat/index.ts
|
|
274
|
+
var tools = [executeQueryTool];
|
|
275
|
+
var snowflakePatConnector = new ConnectorPlugin({
|
|
276
|
+
slug: "snowflake",
|
|
277
|
+
authType: AUTH_TYPES.PAT,
|
|
278
|
+
name: "Snowflake (PAT)",
|
|
279
|
+
description: "Connect to Snowflake using a Personal Access Token (PAT).",
|
|
280
|
+
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/6oyVtAcP3pMlXaOrts9unk/b7a9dc25d15c388b66e983041b855447/snowflake.svg",
|
|
281
|
+
order: 11,
|
|
282
|
+
parameters: Object.values(parameters),
|
|
283
|
+
releaseFlag: { dev1: true, dev2: false, prod: false },
|
|
284
|
+
systemPrompt: `## Snowflake SQL Notes
|
|
285
|
+
- Use fully qualified names DB.SCHEMA.TABLE for table references
|
|
286
|
+
- Schema exploration commands:
|
|
287
|
+
- List databases: \`SHOW DATABASES\`
|
|
288
|
+
- List schemas: \`SHOW SCHEMAS IN DATABASE db_name\`
|
|
289
|
+
- List tables: \`SHOW TABLES IN SCHEMA db_name.schema_name\`
|
|
290
|
+
- List columns: \`DESCRIBE TABLE db_name.schema_name.table_name\`
|
|
291
|
+
- INFORMATION_SCHEMA is also available: \`SELECT * FROM db_name.INFORMATION_SCHEMA.TABLES\``,
|
|
292
|
+
tools,
|
|
293
|
+
createClient(entry, connectionId) {
|
|
294
|
+
const account = parameters.account.resolveEnvVar(entry, connectionId);
|
|
295
|
+
const user = parameters.user.resolveEnvVar(entry, connectionId);
|
|
296
|
+
const role = parameters.role.resolveEnvVar(entry, connectionId);
|
|
297
|
+
const warehouse = parameters.warehouse.resolveEnvVar(entry, connectionId);
|
|
298
|
+
const password = parameters.pat.resolveEnvVar(entry, connectionId);
|
|
299
|
+
return {
|
|
300
|
+
async query(sql) {
|
|
301
|
+
const snowflake = (await import("snowflake-sdk")).default;
|
|
302
|
+
snowflake.configure({ logLevel: "ERROR" });
|
|
303
|
+
const conn = snowflake.createConnection({
|
|
304
|
+
account,
|
|
305
|
+
username: user,
|
|
306
|
+
role,
|
|
307
|
+
warehouse,
|
|
308
|
+
password
|
|
309
|
+
});
|
|
310
|
+
await new Promise((resolve, reject) => {
|
|
311
|
+
conn.connect((err) => {
|
|
312
|
+
if (err)
|
|
313
|
+
reject(new Error(`Snowflake connect failed: ${err.message}`));
|
|
314
|
+
else resolve();
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
const rows = await new Promise(
|
|
318
|
+
(resolve, reject) => {
|
|
319
|
+
conn.execute({
|
|
320
|
+
sqlText: sql,
|
|
321
|
+
complete: (err, _stmt, rows2) => {
|
|
322
|
+
if (err)
|
|
323
|
+
reject(
|
|
324
|
+
new Error(`Snowflake query failed: ${err.message}`)
|
|
325
|
+
);
|
|
326
|
+
else resolve(rows2 ?? []);
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
);
|
|
331
|
+
conn.destroy((err) => {
|
|
332
|
+
if (err)
|
|
333
|
+
console.warn(
|
|
334
|
+
`[connector-client] Snowflake destroy error: ${err.message}`
|
|
335
|
+
);
|
|
336
|
+
});
|
|
337
|
+
return { rows };
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
// src/connectors/snowflake-pat/tools/execute-query/ui.tsx
|
|
344
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
345
|
+
var ExecuteQueryToolComponent = ({
|
|
346
|
+
state,
|
|
347
|
+
input,
|
|
348
|
+
output,
|
|
349
|
+
errorText
|
|
350
|
+
}) => {
|
|
351
|
+
const inp = inputSchema.safeParse(input);
|
|
352
|
+
const out = outputSchema.safeParse(output);
|
|
353
|
+
const columns = out.success && out.data.success && out.data.rows.length > 0 ? Object.keys(out.data.rows[0]) : [];
|
|
354
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
355
|
+
inp.success && inp.data.sql && /* @__PURE__ */ jsx("pre", { style: { fontSize: 12, overflow: "auto", background: "#f5f5f5", padding: 8 }, children: /* @__PURE__ */ jsx("code", { children: inp.data.sql }) }),
|
|
356
|
+
state === "output-available" && out.success && out.data.success && /* @__PURE__ */ jsxs("div", { style: { overflow: "auto" }, children: [
|
|
357
|
+
/* @__PURE__ */ jsxs("table", { style: { fontSize: 12, borderCollapse: "collapse", width: "100%" }, children: [
|
|
358
|
+
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { children: columns.map((col) => /* @__PURE__ */ jsx("th", { style: { borderBottom: "1px solid #ddd", padding: "4px 8px", textAlign: "left" }, children: col }, col)) }) }),
|
|
359
|
+
/* @__PURE__ */ jsx("tbody", { children: out.data.rows.map((row, i) => /* @__PURE__ */ jsx("tr", { children: columns.map((col) => /* @__PURE__ */ jsx("td", { style: { borderBottom: "1px solid #eee", padding: "4px 8px" }, children: String(row[col] ?? "") }, col)) }, i)) })
|
|
360
|
+
] }),
|
|
361
|
+
out.data.truncated && /* @__PURE__ */ jsxs("p", { style: { fontSize: 12, color: "#888" }, children: [
|
|
362
|
+
"Showing ",
|
|
363
|
+
out.data.rowCount,
|
|
364
|
+
" rows (results truncated)"
|
|
365
|
+
] })
|
|
366
|
+
] }),
|
|
367
|
+
out.success && !out.data.success && /* @__PURE__ */ jsx("p", { style: { fontSize: 12, color: "red" }, children: out.data.error }),
|
|
368
|
+
errorText && /* @__PURE__ */ jsx("p", { style: { fontSize: 12, color: "red" }, children: errorText })
|
|
369
|
+
] });
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
// src/connectors/snowflake-pat/ui.ts
|
|
373
|
+
var toolComponents = {
|
|
374
|
+
executeQuery: ExecuteQueryToolComponent
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
// src/connectors/registry.ui.ts
|
|
378
|
+
var registry = [
|
|
379
|
+
{ connector: snowflakePatConnector, components: toolComponents }
|
|
380
|
+
];
|
|
381
|
+
function getToolComponent(connectorKey, toolName) {
|
|
382
|
+
const entry = registry.find((e) => e.connector.connectorKey === connectorKey);
|
|
383
|
+
return entry?.components[toolName];
|
|
384
|
+
}
|
|
385
|
+
export {
|
|
386
|
+
getToolComponent
|
|
387
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@squadbase/connectors",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Squadbase Connectors",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./ui": {
|
|
14
|
+
"types": "./dist/index.ui.d.ts",
|
|
15
|
+
"default": "./dist/index.ui.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "https://github.com/squadbase/squadbase-connectors"
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public",
|
|
27
|
+
"registry": "https://registry.npmjs.org/"
|
|
28
|
+
},
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "tsup",
|
|
31
|
+
"add-connector": "tsx scripts/add-connector.ts",
|
|
32
|
+
"sync:dev1": "API_BASE_URL=https://dev1-api.squadbase.dev/v0 dotenv tsx scripts/sync-connectors.ts",
|
|
33
|
+
"sync:dev2": "API_BASE_URL=https://dev2-api.squadbase.dev/v0 dotenv tsx scripts/sync-connectors.ts",
|
|
34
|
+
"sync:prod": "API_BASE_URL=https://api.squadbase.dev/v0 dotenv tsx scripts/sync-connectors.ts",
|
|
35
|
+
"prepare-test-datasource": "tsx scripts/prepare-test-datasource.ts",
|
|
36
|
+
"test": "vitest"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"ai": "^6.0.0",
|
|
40
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
41
|
+
"zod": "^3.19.0"
|
|
42
|
+
},
|
|
43
|
+
"peerDependenciesMeta": {
|
|
44
|
+
"ai": {
|
|
45
|
+
"optional": true
|
|
46
|
+
},
|
|
47
|
+
"react": {
|
|
48
|
+
"optional": true
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@kintone/rest-api-client": "^6.1.1",
|
|
53
|
+
"@squadbase/dashboard-types": "2.0.77",
|
|
54
|
+
"@types/node": "^20.19.6",
|
|
55
|
+
"@types/pg": "^8.16.0",
|
|
56
|
+
"@types/react": "^19.2.14",
|
|
57
|
+
"ai": "^6.0.116",
|
|
58
|
+
"dotenv-cli": "^11.0.0",
|
|
59
|
+
"pg": "^8.18.0",
|
|
60
|
+
"react": "^19.2.4",
|
|
61
|
+
"snowflake-sdk": "^2.3.4",
|
|
62
|
+
"strip-json-comments": "^5.0.3",
|
|
63
|
+
"tsup": "^8.5.1",
|
|
64
|
+
"tsx": "^4.19.2",
|
|
65
|
+
"typescript": "^5.3.3",
|
|
66
|
+
"vitest": "^4.0.18",
|
|
67
|
+
"zod": "^3.19.1"
|
|
68
|
+
},
|
|
69
|
+
"engines": {
|
|
70
|
+
"node": ">=18.0.0"
|
|
71
|
+
}
|
|
72
|
+
}
|