@squadbase/vite-server 0.1.3-dev.0 → 0.1.3-dev.2
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/cli/index.js +82143 -9661
- package/dist/connectors/asana.d.ts +5 -0
- package/dist/connectors/asana.js +661 -0
- package/dist/connectors/customerio.d.ts +5 -0
- package/dist/connectors/customerio.js +633 -0
- package/dist/connectors/gemini.js +1 -1
- package/dist/connectors/gmail-oauth.d.ts +5 -0
- package/dist/connectors/gmail-oauth.js +639 -0
- package/dist/connectors/google-ads.d.ts +5 -0
- package/dist/connectors/google-ads.js +784 -0
- package/dist/connectors/google-sheets.d.ts +5 -0
- package/dist/connectors/google-sheets.js +598 -0
- package/dist/connectors/hubspot.js +14 -5
- package/dist/connectors/intercom-oauth.d.ts +5 -0
- package/dist/connectors/intercom-oauth.js +510 -0
- package/dist/connectors/intercom.d.ts +5 -0
- package/dist/connectors/intercom.js +627 -0
- package/dist/connectors/jira-api-key.d.ts +5 -0
- package/dist/connectors/jira-api-key.js +524 -0
- package/dist/connectors/linkedin-ads-oauth.d.ts +5 -0
- package/dist/connectors/linkedin-ads-oauth.js +774 -0
- package/dist/connectors/linkedin-ads.d.ts +5 -0
- package/dist/connectors/linkedin-ads.js +782 -0
- package/dist/connectors/mailchimp-oauth.d.ts +5 -0
- package/dist/connectors/mailchimp-oauth.js +539 -0
- package/dist/connectors/mailchimp.d.ts +5 -0
- package/dist/connectors/mailchimp.js +646 -0
- package/dist/connectors/notion-oauth.d.ts +5 -0
- package/dist/connectors/notion-oauth.js +493 -0
- package/dist/connectors/notion.d.ts +5 -0
- package/dist/connectors/notion.js +580 -0
- package/dist/connectors/zendesk-oauth.d.ts +5 -0
- package/dist/connectors/zendesk-oauth.js +505 -0
- package/dist/connectors/zendesk.d.ts +5 -0
- package/dist/connectors/zendesk.js +631 -0
- package/dist/index.js +82350 -7194
- package/dist/main.js +82336 -7180
- package/dist/vite-plugin.js +82235 -7079
- package/package.json +66 -2
|
@@ -0,0 +1,639 @@
|
|
|
1
|
+
// ../connectors/src/connectors/gmail-oauth/sdk/index.ts
|
|
2
|
+
var BASE_URL = "https://gmail.googleapis.com/gmail/v1/users";
|
|
3
|
+
function createClient(_params, fetchFn = fetch) {
|
|
4
|
+
function request(path2, init) {
|
|
5
|
+
const url = `${BASE_URL}${path2.startsWith("/") ? "" : "/"}${path2}`;
|
|
6
|
+
return fetchFn(url, init);
|
|
7
|
+
}
|
|
8
|
+
async function getProfile() {
|
|
9
|
+
const response = await request("/me/profile");
|
|
10
|
+
if (!response.ok) {
|
|
11
|
+
const body = await response.text();
|
|
12
|
+
throw new Error(
|
|
13
|
+
`gmail: getProfile failed (${response.status}): ${body}`
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
return await response.json();
|
|
17
|
+
}
|
|
18
|
+
async function listLabels() {
|
|
19
|
+
const response = await request("/me/labels");
|
|
20
|
+
if (!response.ok) {
|
|
21
|
+
const body = await response.text();
|
|
22
|
+
throw new Error(
|
|
23
|
+
`gmail: listLabels failed (${response.status}): ${body}`
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
return await response.json();
|
|
27
|
+
}
|
|
28
|
+
async function listMessages(options) {
|
|
29
|
+
const params = new URLSearchParams();
|
|
30
|
+
if (options?.q) params.set("q", options.q);
|
|
31
|
+
if (options?.maxResults) params.set("maxResults", String(options.maxResults));
|
|
32
|
+
if (options?.pageToken) params.set("pageToken", options.pageToken);
|
|
33
|
+
if (options?.labelIds) {
|
|
34
|
+
for (const labelId of options.labelIds) {
|
|
35
|
+
params.append("labelIds", labelId);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const qs = params.toString();
|
|
39
|
+
const response = await request(`/me/messages${qs ? `?${qs}` : ""}`);
|
|
40
|
+
if (!response.ok) {
|
|
41
|
+
const body = await response.text();
|
|
42
|
+
throw new Error(
|
|
43
|
+
`gmail: listMessages failed (${response.status}): ${body}`
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
return await response.json();
|
|
47
|
+
}
|
|
48
|
+
async function getMessage(messageId, format) {
|
|
49
|
+
const params = new URLSearchParams();
|
|
50
|
+
if (format) params.set("format", format);
|
|
51
|
+
const qs = params.toString();
|
|
52
|
+
const response = await request(
|
|
53
|
+
`/me/messages/${encodeURIComponent(messageId)}${qs ? `?${qs}` : ""}`
|
|
54
|
+
);
|
|
55
|
+
if (!response.ok) {
|
|
56
|
+
const body = await response.text();
|
|
57
|
+
throw new Error(
|
|
58
|
+
`gmail: getMessage failed (${response.status}): ${body}`
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
return await response.json();
|
|
62
|
+
}
|
|
63
|
+
async function listThreads(options) {
|
|
64
|
+
const params = new URLSearchParams();
|
|
65
|
+
if (options?.q) params.set("q", options.q);
|
|
66
|
+
if (options?.maxResults) params.set("maxResults", String(options.maxResults));
|
|
67
|
+
if (options?.pageToken) params.set("pageToken", options.pageToken);
|
|
68
|
+
if (options?.labelIds) {
|
|
69
|
+
for (const labelId of options.labelIds) {
|
|
70
|
+
params.append("labelIds", labelId);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const qs = params.toString();
|
|
74
|
+
const response = await request(`/me/threads${qs ? `?${qs}` : ""}`);
|
|
75
|
+
if (!response.ok) {
|
|
76
|
+
const body = await response.text();
|
|
77
|
+
throw new Error(
|
|
78
|
+
`gmail: listThreads failed (${response.status}): ${body}`
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
return await response.json();
|
|
82
|
+
}
|
|
83
|
+
async function getThread(threadId, format) {
|
|
84
|
+
const params = new URLSearchParams();
|
|
85
|
+
if (format) params.set("format", format);
|
|
86
|
+
const qs = params.toString();
|
|
87
|
+
const response = await request(
|
|
88
|
+
`/me/threads/${encodeURIComponent(threadId)}${qs ? `?${qs}` : ""}`
|
|
89
|
+
);
|
|
90
|
+
if (!response.ok) {
|
|
91
|
+
const body = await response.text();
|
|
92
|
+
throw new Error(
|
|
93
|
+
`gmail: getThread failed (${response.status}): ${body}`
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
return await response.json();
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
request,
|
|
100
|
+
getProfile,
|
|
101
|
+
listLabels,
|
|
102
|
+
listMessages,
|
|
103
|
+
getMessage,
|
|
104
|
+
listThreads,
|
|
105
|
+
getThread
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// ../connectors/src/connector-onboarding.ts
|
|
110
|
+
var ConnectorOnboarding = class {
|
|
111
|
+
/** Phase 1: Connection setup instructions (optional — some connectors don't need this) */
|
|
112
|
+
connectionSetupInstructions;
|
|
113
|
+
/** Phase 2: Data overview instructions */
|
|
114
|
+
dataOverviewInstructions;
|
|
115
|
+
constructor(config) {
|
|
116
|
+
this.connectionSetupInstructions = config.connectionSetupInstructions;
|
|
117
|
+
this.dataOverviewInstructions = config.dataOverviewInstructions;
|
|
118
|
+
}
|
|
119
|
+
getConnectionSetupPrompt(language) {
|
|
120
|
+
return this.connectionSetupInstructions?.[language] ?? null;
|
|
121
|
+
}
|
|
122
|
+
getDataOverviewInstructions(language) {
|
|
123
|
+
return this.dataOverviewInstructions[language];
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
// ../connectors/src/connector-tool.ts
|
|
128
|
+
var ConnectorTool = class {
|
|
129
|
+
name;
|
|
130
|
+
description;
|
|
131
|
+
inputSchema;
|
|
132
|
+
outputSchema;
|
|
133
|
+
_execute;
|
|
134
|
+
constructor(config) {
|
|
135
|
+
this.name = config.name;
|
|
136
|
+
this.description = config.description;
|
|
137
|
+
this.inputSchema = config.inputSchema;
|
|
138
|
+
this.outputSchema = config.outputSchema;
|
|
139
|
+
this._execute = config.execute;
|
|
140
|
+
}
|
|
141
|
+
createTool(connections, config) {
|
|
142
|
+
return {
|
|
143
|
+
description: this.description,
|
|
144
|
+
inputSchema: this.inputSchema,
|
|
145
|
+
outputSchema: this.outputSchema,
|
|
146
|
+
execute: (input) => this._execute(input, connections, config)
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
// ../connectors/src/connector-plugin.ts
|
|
152
|
+
var ConnectorPlugin = class _ConnectorPlugin {
|
|
153
|
+
slug;
|
|
154
|
+
authType;
|
|
155
|
+
name;
|
|
156
|
+
description;
|
|
157
|
+
iconUrl;
|
|
158
|
+
parameters;
|
|
159
|
+
releaseFlag;
|
|
160
|
+
proxyPolicy;
|
|
161
|
+
experimentalAttributes;
|
|
162
|
+
onboarding;
|
|
163
|
+
systemPrompt;
|
|
164
|
+
tools;
|
|
165
|
+
query;
|
|
166
|
+
checkConnection;
|
|
167
|
+
constructor(config) {
|
|
168
|
+
this.slug = config.slug;
|
|
169
|
+
this.authType = config.authType;
|
|
170
|
+
this.name = config.name;
|
|
171
|
+
this.description = config.description;
|
|
172
|
+
this.iconUrl = config.iconUrl;
|
|
173
|
+
this.parameters = config.parameters;
|
|
174
|
+
this.releaseFlag = config.releaseFlag;
|
|
175
|
+
this.proxyPolicy = config.proxyPolicy;
|
|
176
|
+
this.experimentalAttributes = config.experimentalAttributes;
|
|
177
|
+
this.onboarding = config.onboarding;
|
|
178
|
+
this.systemPrompt = config.systemPrompt;
|
|
179
|
+
this.tools = config.tools;
|
|
180
|
+
this.query = config.query;
|
|
181
|
+
this.checkConnection = config.checkConnection;
|
|
182
|
+
}
|
|
183
|
+
get connectorKey() {
|
|
184
|
+
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Create tools for connections that belong to this connector.
|
|
188
|
+
* Filters connections by connectorKey internally.
|
|
189
|
+
* Returns tools keyed as `${connectorKey}_${toolName}`.
|
|
190
|
+
*/
|
|
191
|
+
createTools(connections, config) {
|
|
192
|
+
const myConnections = connections.filter(
|
|
193
|
+
(c) => _ConnectorPlugin.deriveKey(c.connector.slug, c.connector.authType) === this.connectorKey
|
|
194
|
+
);
|
|
195
|
+
const result = {};
|
|
196
|
+
for (const t of Object.values(this.tools)) {
|
|
197
|
+
result[`${this.connectorKey}_${t.name}`] = t.createTool(
|
|
198
|
+
myConnections,
|
|
199
|
+
config
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
return result;
|
|
203
|
+
}
|
|
204
|
+
static deriveKey(slug, authType) {
|
|
205
|
+
return authType ? `${slug}-${authType}` : slug;
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
// ../connectors/src/auth-types.ts
|
|
210
|
+
var AUTH_TYPES = {
|
|
211
|
+
OAUTH: "oauth",
|
|
212
|
+
API_KEY: "api-key",
|
|
213
|
+
JWT: "jwt",
|
|
214
|
+
SERVICE_ACCOUNT: "service-account",
|
|
215
|
+
PAT: "pat"
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
// ../connectors/src/connectors/gmail-oauth/tools/request.ts
|
|
219
|
+
import { z } from "zod";
|
|
220
|
+
var BASE_URL2 = "https://gmail.googleapis.com/gmail/v1/users";
|
|
221
|
+
var REQUEST_TIMEOUT_MS = 6e4;
|
|
222
|
+
var cachedToken = null;
|
|
223
|
+
async function getProxyToken(config) {
|
|
224
|
+
if (cachedToken && cachedToken.expiresAt > Date.now() + 6e4) {
|
|
225
|
+
return cachedToken.token;
|
|
226
|
+
}
|
|
227
|
+
const url = `${config.appApiBaseUrl}/v0/database/${config.projectId}/environment/${config.environmentId}/oauth-request-proxy-token`;
|
|
228
|
+
const res = await fetch(url, {
|
|
229
|
+
method: "POST",
|
|
230
|
+
headers: {
|
|
231
|
+
"Content-Type": "application/json",
|
|
232
|
+
"x-api-key": config.appApiKey,
|
|
233
|
+
"project-id": config.projectId
|
|
234
|
+
},
|
|
235
|
+
body: JSON.stringify({
|
|
236
|
+
sandboxId: config.sandboxId,
|
|
237
|
+
issuedBy: "coding-agent"
|
|
238
|
+
})
|
|
239
|
+
});
|
|
240
|
+
if (!res.ok) {
|
|
241
|
+
const errorText = await res.text().catch(() => res.statusText);
|
|
242
|
+
throw new Error(
|
|
243
|
+
`Failed to get proxy token: HTTP ${res.status} ${errorText}`
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
const data = await res.json();
|
|
247
|
+
cachedToken = {
|
|
248
|
+
token: data.token,
|
|
249
|
+
expiresAt: new Date(data.expiresAt).getTime()
|
|
250
|
+
};
|
|
251
|
+
return data.token;
|
|
252
|
+
}
|
|
253
|
+
var inputSchema = z.object({
|
|
254
|
+
toolUseIntent: z.string().optional().describe(
|
|
255
|
+
"Brief description of what you intend to accomplish with this tool call"
|
|
256
|
+
),
|
|
257
|
+
connectionId: z.string().describe("ID of the Gmail OAuth connection to use"),
|
|
258
|
+
method: z.enum(["GET"]).describe("HTTP method (read-only, GET only)"),
|
|
259
|
+
path: z.string().describe(
|
|
260
|
+
"API path appended to https://gmail.googleapis.com/gmail/v1/users (e.g., '/me/messages', '/me/messages/{id}', '/me/labels'). Use '/me' as the userId."
|
|
261
|
+
),
|
|
262
|
+
queryParams: z.record(z.string(), z.string()).optional().describe(
|
|
263
|
+
"Query parameters to append to the URL (e.g., { q: 'from:example@gmail.com', maxResults: '10' })"
|
|
264
|
+
)
|
|
265
|
+
});
|
|
266
|
+
var outputSchema = z.discriminatedUnion("success", [
|
|
267
|
+
z.object({
|
|
268
|
+
success: z.literal(true),
|
|
269
|
+
status: z.number(),
|
|
270
|
+
data: z.record(z.string(), z.unknown())
|
|
271
|
+
}),
|
|
272
|
+
z.object({
|
|
273
|
+
success: z.literal(false),
|
|
274
|
+
error: z.string()
|
|
275
|
+
})
|
|
276
|
+
]);
|
|
277
|
+
var requestTool = new ConnectorTool({
|
|
278
|
+
name: "request",
|
|
279
|
+
description: `Send authenticated GET requests to the Gmail API v1.
|
|
280
|
+
Authentication is handled automatically via OAuth proxy.
|
|
281
|
+
All paths are relative to https://gmail.googleapis.com/gmail/v1/users. Use '/me' as the userId prefix (e.g., '/me/messages').`,
|
|
282
|
+
inputSchema,
|
|
283
|
+
outputSchema,
|
|
284
|
+
async execute({ connectionId, method, path: path2, queryParams }, connections, config) {
|
|
285
|
+
const connection2 = connections.find((c) => c.id === connectionId);
|
|
286
|
+
if (!connection2) {
|
|
287
|
+
return {
|
|
288
|
+
success: false,
|
|
289
|
+
error: `Connection ${connectionId} not found`
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
console.log(
|
|
293
|
+
`[connector-request] gmail-oauth/${connection2.name}: ${method} ${path2}`
|
|
294
|
+
);
|
|
295
|
+
try {
|
|
296
|
+
let url = `${BASE_URL2}${path2.startsWith("/") ? "" : "/"}${path2}`;
|
|
297
|
+
if (queryParams) {
|
|
298
|
+
const searchParams = new URLSearchParams(queryParams);
|
|
299
|
+
url += `?${searchParams.toString()}`;
|
|
300
|
+
}
|
|
301
|
+
const token = await getProxyToken(config.oauthProxy);
|
|
302
|
+
const proxyUrl = `https://${config.oauthProxy.sandboxId}.${config.oauthProxy.previewBaseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
303
|
+
const controller = new AbortController();
|
|
304
|
+
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
305
|
+
try {
|
|
306
|
+
const response = await fetch(proxyUrl, {
|
|
307
|
+
method: "POST",
|
|
308
|
+
headers: {
|
|
309
|
+
"Content-Type": "application/json",
|
|
310
|
+
Authorization: `Bearer ${token}`
|
|
311
|
+
},
|
|
312
|
+
body: JSON.stringify({
|
|
313
|
+
url,
|
|
314
|
+
method
|
|
315
|
+
}),
|
|
316
|
+
signal: controller.signal
|
|
317
|
+
});
|
|
318
|
+
const data = await response.json();
|
|
319
|
+
if (!response.ok) {
|
|
320
|
+
const errorMessage = typeof data?.error === "string" ? data.error : typeof data?.message === "string" ? data.message : `HTTP ${response.status} ${response.statusText}`;
|
|
321
|
+
return { success: false, error: errorMessage };
|
|
322
|
+
}
|
|
323
|
+
return { success: true, status: response.status, data };
|
|
324
|
+
} finally {
|
|
325
|
+
clearTimeout(timeout);
|
|
326
|
+
}
|
|
327
|
+
} catch (err) {
|
|
328
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
329
|
+
return { success: false, error: msg };
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
// ../connectors/src/connectors/gmail-oauth/setup.ts
|
|
335
|
+
var requestToolName = `gmail-oauth_${requestTool.name}`;
|
|
336
|
+
var gmailOnboarding = new ConnectorOnboarding({
|
|
337
|
+
connectionSetupInstructions: {
|
|
338
|
+
ja: `\u4EE5\u4E0B\u306E\u624B\u9806\u3067Gmail\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002
|
|
339
|
+
|
|
340
|
+
1. \`${requestToolName}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u30E6\u30FC\u30B6\u30FC\u306E\u30D7\u30ED\u30D5\u30A3\u30FC\u30EB\u3092\u53D6\u5F97\u3059\u308B:
|
|
341
|
+
- \`method\`: \`"GET"\`
|
|
342
|
+
- \`path\`: \`"/me/profile"\`
|
|
343
|
+
2. \u30A8\u30E9\u30FC\u304C\u8FD4\u3055\u308C\u305F\u5834\u5408\u3001OAuth\u306E\u8A8D\u8A3C\u304C\u6B63\u3057\u304F\u5B8C\u4E86\u3057\u3066\u3044\u308B\u304B\u78BA\u8A8D\u3059\u308B\u3088\u3046\u30E6\u30FC\u30B6\u30FC\u306B\u4F1D\u3048\u308B
|
|
344
|
+
3. \`${requestToolName}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u30E9\u30D9\u30EB\u4E00\u89A7\u3092\u53D6\u5F97\u3059\u308B:
|
|
345
|
+
- \`method\`: \`"GET"\`
|
|
346
|
+
- \`path\`: \`"/me/labels"\`
|
|
347
|
+
4. \`updateConnectionContext\` \u3092\u547C\u3073\u51FA\u3059:
|
|
348
|
+
- \`email\`: \u30E6\u30FC\u30B6\u30FC\u306E\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9
|
|
349
|
+
- \`labels\`: \u4E3B\u8981\u306A\u30E9\u30D9\u30EB\u540D\u4E00\u89A7\uFF08\u30AB\u30F3\u30DE\u533A\u5207\u308A\u3001INBOX, SENT, DRAFT, SPAM, TRASH\u7B49\u306E\u30B7\u30B9\u30C6\u30E0\u30E9\u30D9\u30EB\u3092\u542B\u3080\uFF09
|
|
350
|
+
- \`note\`: \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u5185\u5BB9\u306E\u7C21\u5358\u306A\u8AAC\u660E
|
|
351
|
+
|
|
352
|
+
#### \u5236\u7D04
|
|
353
|
+
- **\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u4E2D\u306B\u30E1\u30C3\u30BB\u30FC\u30B8\u672C\u6587\u3092\u8AAD\u307F\u53D6\u3089\u306A\u3044\u3053\u3068**\u3002\u5B9F\u884C\u3057\u3066\u3088\u3044\u306E\u306F\u4E0A\u8A18\u624B\u9806\u3067\u6307\u5B9A\u3055\u308C\u305F\u30D7\u30ED\u30D5\u30A3\u30FC\u30EB\u53D6\u5F97\u3068\u30E9\u30D9\u30EB\u4E00\u89A7\u53D6\u5F97\u306E\u307F
|
|
354
|
+
- \u30C4\u30FC\u30EB\u9593\u306F1\u6587\u3060\u3051\u66F8\u3044\u3066\u5373\u6B21\u306E\u30C4\u30FC\u30EB\u547C\u3073\u51FA\u3057\u3002\u4E0D\u8981\u306A\u8AAC\u660E\u306F\u7701\u7565\u3057\u3001\u52B9\u7387\u7684\u306B\u9032\u3081\u308B`,
|
|
355
|
+
en: `Follow these steps to set up the Gmail connection.
|
|
356
|
+
|
|
357
|
+
1. Call \`${requestToolName}\` to get the user's profile:
|
|
358
|
+
- \`method\`: \`"GET"\`
|
|
359
|
+
- \`path\`: \`"/me/profile"\`
|
|
360
|
+
2. If an error is returned, ask the user to verify that OAuth authentication completed correctly
|
|
361
|
+
3. Call \`${requestToolName}\` to get the label list:
|
|
362
|
+
- \`method\`: \`"GET"\`
|
|
363
|
+
- \`path\`: \`"/me/labels"\`
|
|
364
|
+
4. Call \`updateConnectionContext\`:
|
|
365
|
+
- \`email\`: The user's email address
|
|
366
|
+
- \`labels\`: Key label names (comma-separated, including system labels like INBOX, SENT, DRAFT, SPAM, TRASH)
|
|
367
|
+
- \`note\`: Brief description of the setup
|
|
368
|
+
|
|
369
|
+
#### Constraints
|
|
370
|
+
- **Do NOT read message bodies during setup**. Only the profile and label list requests specified above are allowed
|
|
371
|
+
- Write only 1 sentence between tool calls, then immediately call the next tool. Skip unnecessary explanations and proceed efficiently`
|
|
372
|
+
},
|
|
373
|
+
dataOverviewInstructions: {
|
|
374
|
+
en: `1. Call gmail-oauth_request with GET /me/labels to list all labels
|
|
375
|
+
2. Call gmail-oauth_request with GET /me/messages?maxResults=5 to get recent message IDs
|
|
376
|
+
3. Call gmail-oauth_request with GET /me/messages/{id}?format=metadata for each message to see subjects and senders`,
|
|
377
|
+
ja: `1. gmail-oauth_request \u3067 GET /me/labels \u3092\u547C\u3073\u51FA\u3057\u3001\u5168\u30E9\u30D9\u30EB\u4E00\u89A7\u3092\u53D6\u5F97
|
|
378
|
+
2. gmail-oauth_request \u3067 GET /me/messages?maxResults=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u6700\u65B0\u30E1\u30C3\u30BB\u30FC\u30B8ID\u3092\u53D6\u5F97
|
|
379
|
+
3. \u5404\u30E1\u30C3\u30BB\u30FC\u30B8\u306B\u3064\u3044\u3066 gmail-oauth_request \u3067 GET /me/messages/{id}?format=metadata \u3092\u547C\u3073\u51FA\u3057\u3001\u4EF6\u540D\u3068\u9001\u4FE1\u8005\u3092\u78BA\u8A8D`
|
|
380
|
+
}
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
// ../connectors/src/connectors/gmail-oauth/parameters.ts
|
|
384
|
+
var parameters = {};
|
|
385
|
+
|
|
386
|
+
// ../connectors/src/connectors/gmail-oauth/index.ts
|
|
387
|
+
var tools = { request: requestTool };
|
|
388
|
+
var gmailOauthConnector = new ConnectorPlugin({
|
|
389
|
+
slug: "gmail",
|
|
390
|
+
authType: AUTH_TYPES.OAUTH,
|
|
391
|
+
name: "Gmail (OAuth)",
|
|
392
|
+
description: "Connect to Gmail for email data access using OAuth. Read-only access to messages, threads, and labels.",
|
|
393
|
+
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/4V3rfaSc1ksFIt2eHBNIwJ/7f3be41a154a6d96dcf229ed0e5858c9/Gmail_icon__2020_.svg.png",
|
|
394
|
+
parameters,
|
|
395
|
+
releaseFlag: { dev1: true, dev2: false, prod: false },
|
|
396
|
+
onboarding: gmailOnboarding,
|
|
397
|
+
proxyPolicy: {
|
|
398
|
+
allowlist: [
|
|
399
|
+
{
|
|
400
|
+
host: "gmail.googleapis.com",
|
|
401
|
+
methods: ["GET"]
|
|
402
|
+
}
|
|
403
|
+
]
|
|
404
|
+
},
|
|
405
|
+
systemPrompt: {
|
|
406
|
+
en: `### Tools
|
|
407
|
+
|
|
408
|
+
- \`gmail-oauth_request\`: The only way to call the Gmail API (read-only). Use it to list messages, get message details, list labels, list threads, and get user profile. Authentication is configured automatically via OAuth.
|
|
409
|
+
|
|
410
|
+
### Gmail API Reference
|
|
411
|
+
|
|
412
|
+
#### Available Endpoints
|
|
413
|
+
- GET \`/me/profile\` \u2014 Get the authenticated user's profile (email address, total messages/threads)
|
|
414
|
+
- GET \`/me/labels\` \u2014 List all labels in the mailbox
|
|
415
|
+
- GET \`/me/labels/{id}\` \u2014 Get details for a specific label
|
|
416
|
+
- GET \`/me/messages\` \u2014 List messages (returns IDs only; use format param on individual messages)
|
|
417
|
+
- GET \`/me/messages/{id}\` \u2014 Get a specific message
|
|
418
|
+
- GET \`/me/threads\` \u2014 List threads
|
|
419
|
+
- GET \`/me/threads/{id}\` \u2014 Get a specific thread with all its messages
|
|
420
|
+
|
|
421
|
+
#### Key Query Parameters
|
|
422
|
+
- \`q\` \u2014 Gmail search query (same syntax as Gmail search box). Examples:
|
|
423
|
+
- \`from:user@example.com\` \u2014 Messages from a specific sender
|
|
424
|
+
- \`subject:meeting\` \u2014 Messages with "meeting" in the subject
|
|
425
|
+
- \`after:2025/01/01 before:2025/02/01\` \u2014 Messages within a date range
|
|
426
|
+
- \`label:INBOX is:unread\` \u2014 Unread messages in inbox
|
|
427
|
+
- \`has:attachment\` \u2014 Messages with attachments
|
|
428
|
+
- \`maxResults\` \u2014 Maximum number of results (default 100, max 500)
|
|
429
|
+
- \`pageToken\` \u2014 Token for pagination (from nextPageToken in response)
|
|
430
|
+
- \`labelIds\` \u2014 Filter by label IDs (e.g., \`INBOX\`, \`SENT\`, \`DRAFT\`)
|
|
431
|
+
- \`format\` \u2014 Message format for /messages/{id} and /threads/{id}:
|
|
432
|
+
- \`full\` \u2014 Complete message with parsed payload (default)
|
|
433
|
+
- \`metadata\` \u2014 Only headers (Subject, From, To, Date) without body
|
|
434
|
+
- \`minimal\` \u2014 Only IDs, labels, and snippet
|
|
435
|
+
- \`raw\` \u2014 Full RFC 2822 formatted message in base64url
|
|
436
|
+
|
|
437
|
+
#### Tips
|
|
438
|
+
- Always use \`/me\` as the userId \u2014 it refers to the authenticated user
|
|
439
|
+
- List endpoints return only IDs; fetch individual resources for details
|
|
440
|
+
- Use \`format=metadata\` to efficiently get subject/sender without full body
|
|
441
|
+
- Message body content is base64url encoded in \`payload.body.data\` or nested \`payload.parts[].body.data\`
|
|
442
|
+
- Use \`q\` parameter for powerful search filtering (same as Gmail search syntax)
|
|
443
|
+
- System labels include: INBOX, SENT, DRAFT, SPAM, TRASH, UNREAD, STARRED, IMPORTANT, CATEGORY_PERSONAL, CATEGORY_SOCIAL, CATEGORY_PROMOTIONS, CATEGORY_UPDATES, CATEGORY_FORUMS
|
|
444
|
+
|
|
445
|
+
### Business Logic
|
|
446
|
+
|
|
447
|
+
The business logic type for this connector is "typescript". Write handler code using the connector SDK shown below. Do NOT access credentials directly from environment variables.
|
|
448
|
+
|
|
449
|
+
#### Example
|
|
450
|
+
|
|
451
|
+
\`\`\`ts
|
|
452
|
+
import { connection } from "@squadbase/vite-server/connectors/gmail-oauth";
|
|
453
|
+
|
|
454
|
+
const gmail = connection("<connectionId>");
|
|
455
|
+
|
|
456
|
+
// Get user profile
|
|
457
|
+
const profile = await gmail.getProfile();
|
|
458
|
+
console.log(profile.emailAddress, profile.messagesTotal);
|
|
459
|
+
|
|
460
|
+
// List recent messages
|
|
461
|
+
const messages = await gmail.listMessages({ maxResults: 10 });
|
|
462
|
+
for (const msg of messages.messages) {
|
|
463
|
+
const detail = await gmail.getMessage(msg.id, "metadata");
|
|
464
|
+
const subject = detail.payload.headers.find(h => h.name === "Subject")?.value;
|
|
465
|
+
console.log(subject, detail.snippet);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
// Search messages
|
|
469
|
+
const results = await gmail.listMessages({ q: "from:boss@company.com is:unread" });
|
|
470
|
+
|
|
471
|
+
// List labels
|
|
472
|
+
const labels = await gmail.listLabels();
|
|
473
|
+
labels.labels.forEach(l => console.log(l.name, l.messagesTotal));
|
|
474
|
+
|
|
475
|
+
// Get a thread
|
|
476
|
+
const thread = await gmail.getThread("<threadId>");
|
|
477
|
+
thread.messages.forEach(m => console.log(m.snippet));
|
|
478
|
+
\`\`\``,
|
|
479
|
+
ja: `### \u30C4\u30FC\u30EB
|
|
480
|
+
|
|
481
|
+
- \`gmail-oauth_request\`: Gmail API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\uFF08\u8AAD\u307F\u53D6\u308A\u5C02\u7528\uFF09\u3002\u30E1\u30C3\u30BB\u30FC\u30B8\u4E00\u89A7\u306E\u53D6\u5F97\u3001\u30E1\u30C3\u30BB\u30FC\u30B8\u8A73\u7D30\u306E\u53D6\u5F97\u3001\u30E9\u30D9\u30EB\u4E00\u89A7\u3001\u30B9\u30EC\u30C3\u30C9\u4E00\u89A7\u3001\u30E6\u30FC\u30B6\u30FC\u30D7\u30ED\u30D5\u30A3\u30FC\u30EB\u306E\u53D6\u5F97\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002OAuth\u7D4C\u7531\u3067\u8A8D\u8A3C\u306F\u81EA\u52D5\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002
|
|
482
|
+
|
|
483
|
+
### Gmail API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
|
|
484
|
+
|
|
485
|
+
#### \u5229\u7528\u53EF\u80FD\u306A\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8
|
|
486
|
+
- GET \`/me/profile\` \u2014 \u8A8D\u8A3C\u6E08\u307F\u30E6\u30FC\u30B6\u30FC\u306E\u30D7\u30ED\u30D5\u30A3\u30FC\u30EB\u3092\u53D6\u5F97\uFF08\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3001\u30E1\u30C3\u30BB\u30FC\u30B8/\u30B9\u30EC\u30C3\u30C9\u7DCF\u6570\uFF09
|
|
487
|
+
- GET \`/me/labels\` \u2014 \u30E1\u30FC\u30EB\u30DC\u30C3\u30AF\u30B9\u306E\u5168\u30E9\u30D9\u30EB\u3092\u4E00\u89A7
|
|
488
|
+
- GET \`/me/labels/{id}\` \u2014 \u7279\u5B9A\u30E9\u30D9\u30EB\u306E\u8A73\u7D30\u3092\u53D6\u5F97
|
|
489
|
+
- GET \`/me/messages\` \u2014 \u30E1\u30C3\u30BB\u30FC\u30B8\u4E00\u89A7\uFF08ID\u306E\u307F\u8FD4\u5374\u3002\u500B\u5225\u30E1\u30C3\u30BB\u30FC\u30B8\u3067format\u30D1\u30E9\u30E1\u30FC\u30BF\u3092\u4F7F\u7528\uFF09
|
|
490
|
+
- GET \`/me/messages/{id}\` \u2014 \u7279\u5B9A\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u53D6\u5F97
|
|
491
|
+
- GET \`/me/threads\` \u2014 \u30B9\u30EC\u30C3\u30C9\u4E00\u89A7
|
|
492
|
+
- GET \`/me/threads/{id}\` \u2014 \u7279\u5B9A\u30B9\u30EC\u30C3\u30C9\u306E\u5168\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u53D6\u5F97
|
|
493
|
+
|
|
494
|
+
#### \u4E3B\u8981\u306A\u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF
|
|
495
|
+
- \`q\` \u2014 Gmail\u691C\u7D22\u30AF\u30A8\u30EA\uFF08Gmail\u691C\u7D22\u30DC\u30C3\u30AF\u30B9\u3068\u540C\u3058\u69CB\u6587\uFF09\u3002\u4F8B\uFF1A
|
|
496
|
+
- \`from:user@example.com\` \u2014 \u7279\u5B9A\u306E\u9001\u4FE1\u8005\u304B\u3089\u306E\u30E1\u30C3\u30BB\u30FC\u30B8
|
|
497
|
+
- \`subject:meeting\` \u2014 \u4EF6\u540D\u306B\u300Cmeeting\u300D\u3092\u542B\u3080\u30E1\u30C3\u30BB\u30FC\u30B8
|
|
498
|
+
- \`after:2025/01/01 before:2025/02/01\` \u2014 \u65E5\u4ED8\u7BC4\u56F2\u5185\u306E\u30E1\u30C3\u30BB\u30FC\u30B8
|
|
499
|
+
- \`label:INBOX is:unread\` \u2014 \u53D7\u4FE1\u30C8\u30EC\u30A4\u306E\u672A\u8AAD\u30E1\u30C3\u30BB\u30FC\u30B8
|
|
500
|
+
- \`has:attachment\` \u2014 \u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u4ED8\u304D\u30E1\u30C3\u30BB\u30FC\u30B8
|
|
501
|
+
- \`maxResults\` \u2014 \u6700\u5927\u7D50\u679C\u6570\uFF08\u30C7\u30D5\u30A9\u30EB\u30C8100\u3001\u6700\u5927500\uFF09
|
|
502
|
+
- \`pageToken\` \u2014 \u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3\u7528\u30C8\u30FC\u30AF\u30F3\uFF08\u30EC\u30B9\u30DD\u30F3\u30B9\u306EnextPageToken\u304B\u3089\u53D6\u5F97\uFF09
|
|
503
|
+
- \`labelIds\` \u2014 \u30E9\u30D9\u30EBID\u3067\u30D5\u30A3\u30EB\u30BF\uFF08\u4F8B\uFF1A\`INBOX\`, \`SENT\`, \`DRAFT\`\uFF09
|
|
504
|
+
- \`format\` \u2014 /messages/{id} \u3068 /threads/{id} \u306E\u30E1\u30C3\u30BB\u30FC\u30B8\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\uFF1A
|
|
505
|
+
- \`full\` \u2014 \u30D1\u30FC\u30B9\u6E08\u307F\u30DA\u30A4\u30ED\u30FC\u30C9\u4ED8\u304D\u306E\u5B8C\u5168\u306A\u30E1\u30C3\u30BB\u30FC\u30B8\uFF08\u30C7\u30D5\u30A9\u30EB\u30C8\uFF09
|
|
506
|
+
- \`metadata\` \u2014 \u30D8\u30C3\u30C0\u30FC\u306E\u307F\uFF08Subject, From, To, Date\uFF09\u3001\u672C\u6587\u306A\u3057
|
|
507
|
+
- \`minimal\` \u2014 ID\u3001\u30E9\u30D9\u30EB\u3001\u30B9\u30CB\u30DA\u30C3\u30C8\u306E\u307F
|
|
508
|
+
- \`raw\` \u2014 base64url\u30A8\u30F3\u30B3\u30FC\u30C9\u3055\u308C\u305F\u5B8C\u5168\u306ARFC 2822\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u30E1\u30C3\u30BB\u30FC\u30B8
|
|
509
|
+
|
|
510
|
+
#### \u30D2\u30F3\u30C8
|
|
511
|
+
- userId\u306B\u306F\u5E38\u306B \`/me\` \u3092\u4F7F\u7528 \u2014 \u8A8D\u8A3C\u6E08\u307F\u30E6\u30FC\u30B6\u30FC\u3092\u6307\u3057\u307E\u3059
|
|
512
|
+
- \u4E00\u89A7\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u306FID\u306E\u307F\u8FD4\u5374\u3057\u307E\u3059\u3002\u8A73\u7D30\u306F\u500B\u5225\u30EA\u30BD\u30FC\u30B9\u3092\u53D6\u5F97\u3057\u3066\u304F\u3060\u3055\u3044
|
|
513
|
+
- \u4EF6\u540D/\u9001\u4FE1\u8005\u3092\u52B9\u7387\u7684\u306B\u53D6\u5F97\u3059\u308B\u306B\u306F \`format=metadata\` \u3092\u4F7F\u7528\u3057\u307E\u3059
|
|
514
|
+
- \u30E1\u30C3\u30BB\u30FC\u30B8\u672C\u6587\u306F \`payload.body.data\` \u307E\u305F\u306F\u30CD\u30B9\u30C8\u3055\u308C\u305F \`payload.parts[].body.data\` \u306Bbase64url\u30A8\u30F3\u30B3\u30FC\u30C9\u3067\u683C\u7D0D\u3055\u308C\u3066\u3044\u307E\u3059
|
|
515
|
+
- \u5F37\u529B\u306A\u691C\u7D22\u30D5\u30A3\u30EB\u30BF\u30EA\u30F3\u30B0\u306B\u306F \`q\` \u30D1\u30E9\u30E1\u30FC\u30BF\u3092\u4F7F\u7528\uFF08Gmail\u691C\u7D22\u3068\u540C\u3058\u69CB\u6587\uFF09
|
|
516
|
+
- \u30B7\u30B9\u30C6\u30E0\u30E9\u30D9\u30EB: INBOX, SENT, DRAFT, SPAM, TRASH, UNREAD, STARRED, IMPORTANT, CATEGORY_PERSONAL, CATEGORY_SOCIAL, CATEGORY_PROMOTIONS, CATEGORY_UPDATES, CATEGORY_FORUMS
|
|
517
|
+
|
|
518
|
+
### Business Logic
|
|
519
|
+
|
|
520
|
+
\u3053\u306E\u30B3\u30CD\u30AF\u30BF\u306E\u30D3\u30B8\u30CD\u30B9\u30ED\u30B8\u30C3\u30AF\u30BF\u30A4\u30D7\u306F "typescript" \u3067\u3059\u3002\u4EE5\u4E0B\u306B\u793A\u3059\u30B3\u30CD\u30AF\u30BFSDK\u3092\u4F7F\u7528\u3057\u3066\u30CF\u30F3\u30C9\u30E9\u30B3\u30FC\u30C9\u3092\u8A18\u8FF0\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u74B0\u5883\u5909\u6570\u304B\u3089\u76F4\u63A5\u8A8D\u8A3C\u60C5\u5831\u306B\u30A2\u30AF\u30BB\u30B9\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
|
|
521
|
+
|
|
522
|
+
#### Example
|
|
523
|
+
|
|
524
|
+
\`\`\`ts
|
|
525
|
+
import { connection } from "@squadbase/vite-server/connectors/gmail-oauth";
|
|
526
|
+
|
|
527
|
+
const gmail = connection("<connectionId>");
|
|
528
|
+
|
|
529
|
+
// Get user profile
|
|
530
|
+
const profile = await gmail.getProfile();
|
|
531
|
+
console.log(profile.emailAddress, profile.messagesTotal);
|
|
532
|
+
|
|
533
|
+
// List recent messages
|
|
534
|
+
const messages = await gmail.listMessages({ maxResults: 10 });
|
|
535
|
+
for (const msg of messages.messages) {
|
|
536
|
+
const detail = await gmail.getMessage(msg.id, "metadata");
|
|
537
|
+
const subject = detail.payload.headers.find(h => h.name === "Subject")?.value;
|
|
538
|
+
console.log(subject, detail.snippet);
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// Search messages
|
|
542
|
+
const results = await gmail.listMessages({ q: "from:boss@company.com is:unread" });
|
|
543
|
+
|
|
544
|
+
// List labels
|
|
545
|
+
const labels = await gmail.listLabels();
|
|
546
|
+
labels.labels.forEach(l => console.log(l.name, l.messagesTotal));
|
|
547
|
+
|
|
548
|
+
// Get a thread
|
|
549
|
+
const thread = await gmail.getThread("<threadId>");
|
|
550
|
+
thread.messages.forEach(m => console.log(m.snippet));
|
|
551
|
+
\`\`\``
|
|
552
|
+
},
|
|
553
|
+
tools,
|
|
554
|
+
async checkConnection(_params, config) {
|
|
555
|
+
const { proxyFetch } = config;
|
|
556
|
+
const url = "https://gmail.googleapis.com/gmail/v1/users/me/profile";
|
|
557
|
+
try {
|
|
558
|
+
const res = await proxyFetch(url, { method: "GET" });
|
|
559
|
+
if (!res.ok) {
|
|
560
|
+
const errorText = await res.text().catch(() => res.statusText);
|
|
561
|
+
return {
|
|
562
|
+
success: false,
|
|
563
|
+
error: `Gmail API failed: HTTP ${res.status} ${errorText}`
|
|
564
|
+
};
|
|
565
|
+
}
|
|
566
|
+
return { success: true };
|
|
567
|
+
} catch (error) {
|
|
568
|
+
return {
|
|
569
|
+
success: false,
|
|
570
|
+
error: error instanceof Error ? error.message : String(error)
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
});
|
|
575
|
+
|
|
576
|
+
// src/connectors/create-connector-sdk.ts
|
|
577
|
+
import { readFileSync } from "fs";
|
|
578
|
+
import path from "path";
|
|
579
|
+
|
|
580
|
+
// src/connector-client/env.ts
|
|
581
|
+
function resolveEnvVar(entry, key, connectionId) {
|
|
582
|
+
const envVarName = entry.envVars[key];
|
|
583
|
+
if (!envVarName) {
|
|
584
|
+
throw new Error(`Connection "${connectionId}" is missing envVars mapping for key "${key}"`);
|
|
585
|
+
}
|
|
586
|
+
const value = process.env[envVarName];
|
|
587
|
+
if (!value) {
|
|
588
|
+
throw new Error(`Environment variable "${envVarName}" (for connection "${connectionId}", key "${key}") is not set`);
|
|
589
|
+
}
|
|
590
|
+
return value;
|
|
591
|
+
}
|
|
592
|
+
function resolveEnvVarOptional(entry, key) {
|
|
593
|
+
const envVarName = entry.envVars[key];
|
|
594
|
+
if (!envVarName) return void 0;
|
|
595
|
+
return process.env[envVarName] || void 0;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
// src/connectors/create-connector-sdk.ts
|
|
599
|
+
function loadConnectionsSync() {
|
|
600
|
+
const filePath = process.env.CONNECTIONS_PATH ?? path.join(process.cwd(), ".squadbase/connections.json");
|
|
601
|
+
try {
|
|
602
|
+
const raw = readFileSync(filePath, "utf-8");
|
|
603
|
+
return JSON.parse(raw);
|
|
604
|
+
} catch {
|
|
605
|
+
return {};
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
function createConnectorSdk(plugin, createClient2) {
|
|
609
|
+
return (connectionId) => {
|
|
610
|
+
const connections = loadConnectionsSync();
|
|
611
|
+
const entry = connections[connectionId];
|
|
612
|
+
if (!entry) {
|
|
613
|
+
throw new Error(
|
|
614
|
+
`Connection "${connectionId}" not found in .squadbase/connections.json`
|
|
615
|
+
);
|
|
616
|
+
}
|
|
617
|
+
if (entry.connector.slug !== plugin.slug) {
|
|
618
|
+
throw new Error(
|
|
619
|
+
`Connection "${connectionId}" is not a ${plugin.slug} connection (got "${entry.connector.slug}")`
|
|
620
|
+
);
|
|
621
|
+
}
|
|
622
|
+
const params = {};
|
|
623
|
+
for (const param of Object.values(plugin.parameters)) {
|
|
624
|
+
if (param.required) {
|
|
625
|
+
params[param.slug] = resolveEnvVar(entry, param.slug, connectionId);
|
|
626
|
+
} else {
|
|
627
|
+
const val = resolveEnvVarOptional(entry, param.slug);
|
|
628
|
+
if (val !== void 0) params[param.slug] = val;
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
return createClient2(params);
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
// src/connectors/entries/gmail-oauth.ts
|
|
636
|
+
var connection = createConnectorSdk(gmailOauthConnector, createClient);
|
|
637
|
+
export {
|
|
638
|
+
connection
|
|
639
|
+
};
|