@squadbase/vite-server 0.1.3-dev.7 → 0.1.3-dev.9
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 +1532 -1335
- package/dist/connectors/airtable-oauth.js +74 -1
- package/dist/connectors/airtable.js +74 -1
- package/dist/connectors/amplitude.js +74 -1
- package/dist/connectors/anthropic.js +74 -1
- package/dist/connectors/asana.js +74 -1
- package/dist/connectors/attio.js +74 -1
- package/dist/connectors/customerio.js +74 -1
- package/dist/connectors/dbt.js +74 -1
- package/dist/connectors/gemini.js +74 -1
- package/dist/connectors/gmail-oauth.js +74 -1
- package/dist/connectors/gmail.js +74 -1
- package/dist/connectors/google-ads-oauth.js +74 -1
- package/dist/connectors/google-ads.js +74 -1
- package/dist/connectors/google-analytics-oauth.js +87 -6
- package/dist/connectors/google-analytics.js +117 -46
- package/dist/connectors/google-calendar-oauth.js +74 -1
- package/dist/connectors/google-calendar.d.ts +1 -8
- package/dist/connectors/google-calendar.js +316 -64
- package/dist/connectors/google-sheets-oauth.js +85 -18
- package/dist/connectors/google-sheets.js +75 -2
- package/dist/connectors/grafana.js +74 -1
- package/dist/connectors/hubspot-oauth.js +74 -1
- package/dist/connectors/hubspot.js +74 -1
- package/dist/connectors/intercom-oauth.js +74 -1
- package/dist/connectors/intercom.js +74 -1
- package/dist/connectors/jira-api-key.js +74 -1
- package/dist/connectors/kintone-api-token.js +74 -1
- package/dist/connectors/kintone.js +74 -1
- package/dist/connectors/linkedin-ads-oauth.js +74 -1
- package/dist/connectors/linkedin-ads.js +74 -1
- package/dist/connectors/mailchimp-oauth.js +74 -1
- package/dist/connectors/mailchimp.js +74 -1
- package/dist/connectors/notion-oauth.js +74 -1
- package/dist/connectors/notion.js +74 -1
- package/dist/connectors/openai.js +74 -1
- package/dist/connectors/shopify-oauth.js +74 -1
- package/dist/connectors/shopify.js +74 -1
- package/dist/connectors/stripe-api-key.js +74 -1
- package/dist/connectors/stripe-oauth.js +74 -1
- package/dist/connectors/wix-store.js +74 -1
- package/dist/connectors/zendesk-oauth.js +74 -1
- package/dist/connectors/zendesk.js +74 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1568 -1335
- package/dist/main.js +1567 -1333
- package/dist/vite-plugin.js +1483 -1286
- package/package.json +1 -1
|
@@ -58,8 +58,8 @@ var parameters = {
|
|
|
58
58
|
}),
|
|
59
59
|
impersonateEmail: new ParameterDefinition({
|
|
60
60
|
slug: "impersonate-email",
|
|
61
|
-
name: "User Email Address",
|
|
62
|
-
description: "The email address of the Google Workspace user whose calendar will be accessed via Domain-wide Delegation (e.g., '
|
|
61
|
+
name: "User Email Address(es)",
|
|
62
|
+
description: "The email address(es) of the Google Workspace user(s) whose calendar will be accessed via Domain-wide Delegation. Multiple addresses can be provided as a comma-separated list (e.g., 'user1@example.com, user2@example.com') to aggregate accessible calendars across users during setup. After setup completes, this value is overwritten with the owner email of the selected calendar.",
|
|
63
63
|
envVarBaseKey: "GOOGLE_CALENDAR_IMPERSONATE_EMAIL",
|
|
64
64
|
type: "text",
|
|
65
65
|
secret: false,
|
|
@@ -104,7 +104,7 @@ function buildJwt(clientEmail, privateKey, nowSec, subject) {
|
|
|
104
104
|
const signature = base64url(sign.sign(privateKey));
|
|
105
105
|
return `${signingInput}.${signature}`;
|
|
106
106
|
}
|
|
107
|
-
function createClient(params
|
|
107
|
+
function createClient(params) {
|
|
108
108
|
const serviceAccountKeyJsonBase64 = params[parameters.serviceAccountKeyJsonBase64.slug];
|
|
109
109
|
const impersonateEmail = params[parameters.impersonateEmail.slug];
|
|
110
110
|
const defaultCalendarId = params[parameters.calendarId.slug] ?? "primary";
|
|
@@ -113,7 +113,7 @@ function createClient(params, options) {
|
|
|
113
113
|
`google-calendar: missing required parameter: ${parameters.serviceAccountKeyJsonBase64.slug}`
|
|
114
114
|
);
|
|
115
115
|
}
|
|
116
|
-
if (!impersonateEmail
|
|
116
|
+
if (!impersonateEmail) {
|
|
117
117
|
throw new Error(
|
|
118
118
|
`google-calendar: missing required parameter: ${parameters.impersonateEmail.slug}`
|
|
119
119
|
);
|
|
@@ -135,10 +135,10 @@ function createClient(params, options) {
|
|
|
135
135
|
"google-calendar: service account key JSON must contain client_email and private_key"
|
|
136
136
|
);
|
|
137
137
|
}
|
|
138
|
-
const subject =
|
|
138
|
+
const subject = impersonateEmail;
|
|
139
139
|
let cachedToken = null;
|
|
140
140
|
let tokenExpiresAt = 0;
|
|
141
|
-
async function
|
|
141
|
+
async function getAccessToken2() {
|
|
142
142
|
const nowSec = Math.floor(Date.now() / 1e3);
|
|
143
143
|
if (cachedToken && nowSec < tokenExpiresAt - 60) {
|
|
144
144
|
return cachedToken;
|
|
@@ -173,7 +173,7 @@ function createClient(params, options) {
|
|
|
173
173
|
}
|
|
174
174
|
return {
|
|
175
175
|
async request(path2, init) {
|
|
176
|
-
const accessToken = await
|
|
176
|
+
const accessToken = await getAccessToken2();
|
|
177
177
|
const resolvedPath = path2.replace(
|
|
178
178
|
/\{calendarId\}/g,
|
|
179
179
|
defaultCalendarId
|
|
@@ -196,18 +196,18 @@ function createClient(params, options) {
|
|
|
196
196
|
const data = await response.json();
|
|
197
197
|
return data.items ?? [];
|
|
198
198
|
},
|
|
199
|
-
async listEvents(
|
|
199
|
+
async listEvents(options, calendarId) {
|
|
200
200
|
const cid = resolveCalendarId(calendarId);
|
|
201
201
|
const searchParams = new URLSearchParams();
|
|
202
|
-
if (
|
|
203
|
-
if (
|
|
204
|
-
if (
|
|
205
|
-
searchParams.set("maxResults", String(
|
|
206
|
-
if (
|
|
207
|
-
if (
|
|
208
|
-
searchParams.set("singleEvents", String(
|
|
209
|
-
if (
|
|
210
|
-
if (
|
|
202
|
+
if (options?.timeMin) searchParams.set("timeMin", options.timeMin);
|
|
203
|
+
if (options?.timeMax) searchParams.set("timeMax", options.timeMax);
|
|
204
|
+
if (options?.maxResults)
|
|
205
|
+
searchParams.set("maxResults", String(options.maxResults));
|
|
206
|
+
if (options?.q) searchParams.set("q", options.q);
|
|
207
|
+
if (options?.singleEvents != null)
|
|
208
|
+
searchParams.set("singleEvents", String(options.singleEvents));
|
|
209
|
+
if (options?.orderBy) searchParams.set("orderBy", options.orderBy);
|
|
210
|
+
if (options?.pageToken) searchParams.set("pageToken", options.pageToken);
|
|
211
211
|
const qs = searchParams.toString();
|
|
212
212
|
const path2 = `/calendars/${encodeURIComponent(cid)}/events${qs ? `?${qs}` : ""}`;
|
|
213
213
|
const response = await this.request(path2, { method: "GET" });
|
|
@@ -344,34 +344,222 @@ var AUTH_TYPES = {
|
|
|
344
344
|
USER_PASSWORD: "user-password"
|
|
345
345
|
};
|
|
346
346
|
|
|
347
|
+
// ../connectors/src/connectors/google-calendar/tools/list-calendars.ts
|
|
348
|
+
import * as crypto2 from "crypto";
|
|
349
|
+
import { z } from "zod";
|
|
350
|
+
var TOKEN_URL2 = "https://oauth2.googleapis.com/token";
|
|
351
|
+
var BASE_URL2 = "https://www.googleapis.com/calendar/v3";
|
|
352
|
+
var SCOPE2 = "https://www.googleapis.com/auth/calendar.readonly https://www.googleapis.com/auth/calendar.events.readonly";
|
|
353
|
+
var REQUEST_TIMEOUT_MS = 6e4;
|
|
354
|
+
function base64url2(input) {
|
|
355
|
+
const buf = typeof input === "string" ? Buffer.from(input) : input;
|
|
356
|
+
return buf.toString("base64url");
|
|
357
|
+
}
|
|
358
|
+
function buildJwt2(clientEmail, privateKey, nowSec, subject) {
|
|
359
|
+
const header = base64url2(JSON.stringify({ alg: "RS256", typ: "JWT" }));
|
|
360
|
+
const payload = base64url2(
|
|
361
|
+
JSON.stringify({
|
|
362
|
+
iss: clientEmail,
|
|
363
|
+
sub: subject,
|
|
364
|
+
scope: SCOPE2,
|
|
365
|
+
aud: TOKEN_URL2,
|
|
366
|
+
iat: nowSec,
|
|
367
|
+
exp: nowSec + 3600
|
|
368
|
+
})
|
|
369
|
+
);
|
|
370
|
+
const signingInput = `${header}.${payload}`;
|
|
371
|
+
const sign = crypto2.createSign("RSA-SHA256");
|
|
372
|
+
sign.update(signingInput);
|
|
373
|
+
sign.end();
|
|
374
|
+
const signature = base64url2(sign.sign(privateKey));
|
|
375
|
+
return `${signingInput}.${signature}`;
|
|
376
|
+
}
|
|
377
|
+
async function getAccessToken(serviceAccount, subject) {
|
|
378
|
+
const nowSec = Math.floor(Date.now() / 1e3);
|
|
379
|
+
const jwt = buildJwt2(
|
|
380
|
+
serviceAccount.client_email,
|
|
381
|
+
serviceAccount.private_key,
|
|
382
|
+
nowSec,
|
|
383
|
+
subject
|
|
384
|
+
);
|
|
385
|
+
const response = await fetch(TOKEN_URL2, {
|
|
386
|
+
method: "POST",
|
|
387
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
388
|
+
body: new URLSearchParams({
|
|
389
|
+
grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
|
|
390
|
+
assertion: jwt
|
|
391
|
+
})
|
|
392
|
+
});
|
|
393
|
+
if (!response.ok) {
|
|
394
|
+
const text = await response.text();
|
|
395
|
+
throw new Error(
|
|
396
|
+
`token exchange failed for ${subject} (${response.status}): ${text}`
|
|
397
|
+
);
|
|
398
|
+
}
|
|
399
|
+
const data = await response.json();
|
|
400
|
+
return data.access_token;
|
|
401
|
+
}
|
|
402
|
+
var inputSchema = z.object({
|
|
403
|
+
toolUseIntent: z.string().optional().describe(
|
|
404
|
+
"Brief description of what you intend to accomplish with this tool call"
|
|
405
|
+
),
|
|
406
|
+
connectionId: z.string().describe("ID of the Google Calendar connection to use")
|
|
407
|
+
});
|
|
408
|
+
var outputSchema = z.discriminatedUnion("success", [
|
|
409
|
+
z.object({
|
|
410
|
+
success: z.literal(true),
|
|
411
|
+
calendars: z.array(
|
|
412
|
+
z.object({
|
|
413
|
+
impersonateEmail: z.string(),
|
|
414
|
+
id: z.string(),
|
|
415
|
+
summary: z.string(),
|
|
416
|
+
primary: z.boolean().optional(),
|
|
417
|
+
accessRole: z.string()
|
|
418
|
+
})
|
|
419
|
+
),
|
|
420
|
+
errors: z.array(
|
|
421
|
+
z.object({
|
|
422
|
+
impersonateEmail: z.string(),
|
|
423
|
+
error: z.string()
|
|
424
|
+
})
|
|
425
|
+
)
|
|
426
|
+
}),
|
|
427
|
+
z.object({
|
|
428
|
+
success: z.literal(false),
|
|
429
|
+
error: z.string()
|
|
430
|
+
})
|
|
431
|
+
]);
|
|
432
|
+
var listCalendarsTool = new ConnectorTool({
|
|
433
|
+
name: "listCalendars",
|
|
434
|
+
description: "List Google Calendars accessible via Domain-wide Delegation by impersonating the Google Workspace user(s) configured on the connection's `impersonate-email` parameter (comma-separated list supported). Use during setup to aggregate calendars across the configured emails.",
|
|
435
|
+
inputSchema,
|
|
436
|
+
outputSchema,
|
|
437
|
+
async execute({ connectionId }, connections) {
|
|
438
|
+
const connection2 = connections.find((c) => c.id === connectionId);
|
|
439
|
+
if (!connection2) {
|
|
440
|
+
return {
|
|
441
|
+
success: false,
|
|
442
|
+
error: `Connection ${connectionId} not found`
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
const impersonateEmailRaw = parameters.impersonateEmail.getValue(connection2);
|
|
446
|
+
const emails = impersonateEmailRaw.split(",").map((e) => e.trim()).filter((e) => e.length > 0);
|
|
447
|
+
if (emails.length === 0) {
|
|
448
|
+
return {
|
|
449
|
+
success: false,
|
|
450
|
+
error: "impersonate-email parameter is empty"
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
console.log(
|
|
454
|
+
`[connector-request] google-calendar/${connection2.name}: listCalendars for ${emails.join(",")}`
|
|
455
|
+
);
|
|
456
|
+
let serviceAccount;
|
|
457
|
+
try {
|
|
458
|
+
const keyJsonBase64 = parameters.serviceAccountKeyJsonBase64.getValue(connection2);
|
|
459
|
+
const decoded = Buffer.from(keyJsonBase64, "base64").toString("utf-8");
|
|
460
|
+
serviceAccount = JSON.parse(decoded);
|
|
461
|
+
} catch (err) {
|
|
462
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
463
|
+
return {
|
|
464
|
+
success: false,
|
|
465
|
+
error: `failed to decode service account key: ${msg}`
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
if (!serviceAccount.client_email || !serviceAccount.private_key) {
|
|
469
|
+
return {
|
|
470
|
+
success: false,
|
|
471
|
+
error: "service account key JSON must contain client_email and private_key"
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
const aggregated = [];
|
|
475
|
+
const errors = [];
|
|
476
|
+
for (const email of emails) {
|
|
477
|
+
const controller = new AbortController();
|
|
478
|
+
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
479
|
+
try {
|
|
480
|
+
const token = await getAccessToken(serviceAccount, email);
|
|
481
|
+
const response = await fetch(`${BASE_URL2}/users/me/calendarList`, {
|
|
482
|
+
method: "GET",
|
|
483
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
484
|
+
signal: controller.signal
|
|
485
|
+
});
|
|
486
|
+
const data = await response.json();
|
|
487
|
+
if (!response.ok) {
|
|
488
|
+
const errorObj = data?.error;
|
|
489
|
+
errors.push({
|
|
490
|
+
impersonateEmail: email,
|
|
491
|
+
error: errorObj?.message ?? `HTTP ${response.status} ${response.statusText}`
|
|
492
|
+
});
|
|
493
|
+
continue;
|
|
494
|
+
}
|
|
495
|
+
const items = data.items ?? [];
|
|
496
|
+
for (const c of items) {
|
|
497
|
+
aggregated.push({
|
|
498
|
+
impersonateEmail: email,
|
|
499
|
+
id: c.id,
|
|
500
|
+
summary: c.summary,
|
|
501
|
+
primary: c.primary,
|
|
502
|
+
accessRole: c.accessRole
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
} catch (err) {
|
|
506
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
507
|
+
errors.push({ impersonateEmail: email, error: msg });
|
|
508
|
+
} finally {
|
|
509
|
+
clearTimeout(timeout);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
return {
|
|
513
|
+
success: true,
|
|
514
|
+
calendars: aggregated,
|
|
515
|
+
errors
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
});
|
|
519
|
+
|
|
347
520
|
// ../connectors/src/connectors/google-calendar/setup.ts
|
|
521
|
+
var listCalendarsToolName = `google-calendar_${listCalendarsTool.name}`;
|
|
348
522
|
var googleCalendarOnboarding = new ConnectorOnboarding({
|
|
349
523
|
connectionSetupInstructions: {
|
|
350
524
|
ja: `\u4EE5\u4E0B\u306E\u624B\u9806\u3067Google Calendar\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002
|
|
351
525
|
|
|
352
|
-
1. \
|
|
353
|
-
2. \
|
|
526
|
+
1. \`${listCalendarsToolName}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E \`impersonate-email\` \u30D1\u30E9\u30E1\u30FC\u30BF\u306B\u8A2D\u5B9A\u3055\u308C\u305F\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\uFF08\u30AB\u30F3\u30DE\u533A\u5207\u308A\u5BFE\u5FDC\uFF09\u3067\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306A\u30AB\u30EC\u30F3\u30C0\u30FC\u4E00\u89A7\u3092\u53D6\u5F97\u3059\u308B
|
|
527
|
+
2. \u8FD4\u5374\u3055\u308C\u305F \`calendars\` \u914D\u5217\uFF08\u5404\u8981\u7D20: \`{ impersonateEmail, id, summary, primary, accessRole }\`\uFF09\u3092\u5143\u306B\u3001\u300C\u4F7F\u7528\u3059\u308B\u30AB\u30EC\u30F3\u30C0\u30FC\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u300D\u3068\u30E6\u30FC\u30B6\u30FC\u306B\u4F1D\u3048\u305F\u4E0A\u3067\u3001\`updateConnectionParameters\` \u3092\u547C\u3073\u51FA\u3059:
|
|
528
|
+
- \`parameterSlug\`: \`"calendar-id"\`
|
|
529
|
+
- \`options\`: \u30AB\u30EC\u30F3\u30C0\u30FC\u4E00\u89A7\u3002\u5404 option \u306E \`label\` \u306F \`\u30AB\u30EC\u30F3\u30C0\u30FC\u540D (owner: impersonateEmail)\` \u306E\u5F62\u5F0F\u3001\`value\` \u306F\u30AB\u30EC\u30F3\u30C0\u30FCID
|
|
530
|
+
- \`errors\` \u306B\u5931\u6557\u3057\u305F\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u304C\u3042\u308B\u5834\u5408\u306F\u3001\u305D\u306E\u65E8\u3092\u77ED\u304F\u4F1D\u3048\u308B
|
|
531
|
+
3. \u30E6\u30FC\u30B6\u30FC\u304C\u9078\u629E\u3057\u305F\u30AB\u30EC\u30F3\u30C0\u30FC\u306E \`label\` \u304C\u30E1\u30C3\u30BB\u30FC\u30B8\u3068\u3057\u3066\u5C4A\u304F\u3002\u305D\u306E label \u304B\u3089 owner \u306E\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092\u62BD\u51FA\u3057\u3001\`updateConnectionParameters\` \u3092\u547C\u3073\u51FA\u3059:
|
|
354
532
|
- \`parameterSlug\`: \`"impersonate-email"\`
|
|
355
|
-
- \`
|
|
356
|
-
|
|
533
|
+
- \`options\`: \`[{ value: <ownerEmail>, label: <ownerEmail> }]\`\uFF08\u9078\u629E\u6E08\u307F\u30AB\u30EC\u30F3\u30C0\u30FC\u306E owner email \u3092\u5358\u4E00\u30AA\u30D7\u30B7\u30E7\u30F3\u3068\u3057\u3066\u6E21\u3059\uFF09
|
|
534
|
+
4. \`updateConnectionContext\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001\u5BFE\u8C61\u60C5\u5831\u3092\u8A18\u9332\u3059\u308B:
|
|
357
535
|
- \`user\`: \u8A2D\u5B9A\u3057\u305F\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9
|
|
358
|
-
- \`
|
|
536
|
+
- \`calendar\`: \u9078\u629E\u3055\u308C\u305F\u30AB\u30EC\u30F3\u30C0\u30FC\u540D
|
|
537
|
+
- \`calendarId\`: \u9078\u629E\u3055\u308C\u305F\u30AB\u30EC\u30F3\u30C0\u30FCID
|
|
538
|
+
- \`note\`: \u300CDomain-wide Delegation\u3067 {email} \u306E {calendar} \u306B\u30A2\u30AF\u30BB\u30B9\u300D\u306A\u3069\u306E\u8AAC\u660E
|
|
359
539
|
|
|
360
540
|
#### \u5236\u7D04
|
|
361
|
-
- **\
|
|
541
|
+
- **\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u4E2D\u306B\u30E6\u30FC\u30B6\u30FC\u3078\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u7B49\u306E\u5165\u529B\u3092\u6C42\u3081\u306A\u3044\u3053\u3068**\u3002\u5FC5\u8981\u306A\u5024\u306F\u63A5\u7D9A\u4F5C\u6210\u6642\u306E\u30D1\u30E9\u30E1\u30FC\u30BF\uFF08\`impersonate-email\`\uFF09\u304B\u3089\u53D6\u5F97\u3059\u308B
|
|
542
|
+
- **\u30B5\u30FC\u30D3\u30B9\u30A2\u30AB\u30A6\u30F3\u30C8\u306E\u30C9\u30E1\u30A4\u30F3\u5168\u4F53\u306E\u59D4\u4EFB\u8A2D\u5B9A\u304C\u5FC5\u8981\u3067\u3059**\u3002\`${listCalendarsToolName}\` \u306E \`errors\` \u306B\u6A29\u9650\u30A8\u30E9\u30FC\u304C\u51FA\u308B\u5834\u5408\u3001Google Workspace\u7BA1\u7406\u8005\u306BDomain-wide Delegation\u306E\u8A2D\u5B9A\u78BA\u8A8D\u3092\u4FC3\u3057\u3066\u304F\u3060\u3055\u3044
|
|
362
543
|
- \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`,
|
|
363
544
|
en: `Follow these steps to set up the Google Calendar connection.
|
|
364
545
|
|
|
365
|
-
1.
|
|
366
|
-
2.
|
|
546
|
+
1. Call \`${listCalendarsToolName}\` to list calendars accessible via the email address(es) configured in the connection's \`impersonate-email\` parameter (comma-separated list supported)
|
|
547
|
+
2. Using the returned \`calendars\` array (each item: \`{ impersonateEmail, id, summary, primary, accessRole }\`), tell the user "Please select a calendar.", then call \`updateConnectionParameters\`:
|
|
548
|
+
- \`parameterSlug\`: \`"calendar-id"\`
|
|
549
|
+
- \`options\`: The calendar list. Each option's \`label\` should be \`Calendar Name (owner: impersonateEmail)\`, \`value\` should be the calendar ID
|
|
550
|
+
- If \`errors\` contains failing email addresses, briefly mention them
|
|
551
|
+
3. The \`label\` of the user's selected calendar will arrive as a message. Extract the owner email from that label and call \`updateConnectionParameters\`:
|
|
367
552
|
- \`parameterSlug\`: \`"impersonate-email"\`
|
|
368
|
-
- \`
|
|
369
|
-
|
|
553
|
+
- \`options\`: \`[{ value: <ownerEmail>, label: <ownerEmail> }]\` (pass the selected calendar's owner email as a single option)
|
|
554
|
+
4. Call \`updateConnectionContext\` to record the target:
|
|
370
555
|
- \`user\`: The configured email address
|
|
371
|
-
- \`
|
|
556
|
+
- \`calendar\`: The selected calendar's name
|
|
557
|
+
- \`calendarId\`: The selected calendar ID
|
|
558
|
+
- \`note\`: A description such as "Accessing {email}'s {calendar} via Domain-wide Delegation"
|
|
372
559
|
|
|
373
560
|
#### Constraints
|
|
374
|
-
- **
|
|
561
|
+
- **Do NOT prompt the user for any input (e.g., email addresses) during setup**. The required values come from the connection parameters (\`impersonate-email\`) filled in at connection creation time
|
|
562
|
+
- **Domain-wide Delegation must be configured on the service account**. If \`${listCalendarsToolName}\` returns permission errors in the \`errors\` field, ask the user to verify the Domain-wide Delegation setup with their Google Workspace administrator
|
|
375
563
|
- Write only 1 sentence between tool calls, then immediately call the next tool. Skip unnecessary explanations and proceed efficiently`
|
|
376
564
|
},
|
|
377
565
|
dataOverviewInstructions: {
|
|
@@ -385,33 +573,33 @@ var googleCalendarOnboarding = new ConnectorOnboarding({
|
|
|
385
573
|
});
|
|
386
574
|
|
|
387
575
|
// ../connectors/src/connectors/google-calendar/tools/request.ts
|
|
388
|
-
import { z } from "zod";
|
|
389
|
-
var
|
|
390
|
-
var
|
|
391
|
-
var
|
|
392
|
-
toolUseIntent:
|
|
576
|
+
import { z as z2 } from "zod";
|
|
577
|
+
var BASE_URL3 = "https://www.googleapis.com/calendar/v3";
|
|
578
|
+
var REQUEST_TIMEOUT_MS2 = 6e4;
|
|
579
|
+
var inputSchema2 = z2.object({
|
|
580
|
+
toolUseIntent: z2.string().optional().describe(
|
|
393
581
|
"Brief description of what you intend to accomplish with this tool call"
|
|
394
582
|
),
|
|
395
|
-
connectionId:
|
|
396
|
-
method:
|
|
397
|
-
path:
|
|
583
|
+
connectionId: z2.string().describe("ID of the Google Calendar connection to use"),
|
|
584
|
+
method: z2.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]).describe("HTTP method"),
|
|
585
|
+
path: z2.string().describe(
|
|
398
586
|
"API path appended to https://www.googleapis.com/calendar/v3 (e.g., '/calendars/{calendarId}/events'). {calendarId} is automatically replaced."
|
|
399
587
|
),
|
|
400
|
-
queryParams:
|
|
401
|
-
body:
|
|
402
|
-
subject:
|
|
588
|
+
queryParams: z2.record(z2.string(), z2.string()).optional().describe("Query parameters to append to the URL"),
|
|
589
|
+
body: z2.record(z2.string(), z2.unknown()).optional().describe("Request body (JSON) for POST/PUT/PATCH methods"),
|
|
590
|
+
subject: z2.string().optional().describe(
|
|
403
591
|
"Override the email address of the user to impersonate via Domain-wide Delegation. If omitted, the connection's configured user email is used."
|
|
404
592
|
)
|
|
405
593
|
});
|
|
406
|
-
var
|
|
407
|
-
|
|
408
|
-
success:
|
|
409
|
-
status:
|
|
410
|
-
data:
|
|
594
|
+
var outputSchema2 = z2.discriminatedUnion("success", [
|
|
595
|
+
z2.object({
|
|
596
|
+
success: z2.literal(true),
|
|
597
|
+
status: z2.number(),
|
|
598
|
+
data: z2.record(z2.string(), z2.unknown())
|
|
411
599
|
}),
|
|
412
|
-
|
|
413
|
-
success:
|
|
414
|
-
error:
|
|
600
|
+
z2.object({
|
|
601
|
+
success: z2.literal(false),
|
|
602
|
+
error: z2.string()
|
|
415
603
|
})
|
|
416
604
|
]);
|
|
417
605
|
var requestTool = new ConnectorTool({
|
|
@@ -419,8 +607,8 @@ var requestTool = new ConnectorTool({
|
|
|
419
607
|
description: `Send authenticated requests to the Google Calendar API v3.
|
|
420
608
|
Authentication is handled automatically using a service account.
|
|
421
609
|
{calendarId} in the path is automatically replaced with the connection's default calendar ID.`,
|
|
422
|
-
inputSchema,
|
|
423
|
-
outputSchema,
|
|
610
|
+
inputSchema: inputSchema2,
|
|
611
|
+
outputSchema: outputSchema2,
|
|
424
612
|
async execute({ connectionId, method, path: path2, queryParams, body, subject }, connections) {
|
|
425
613
|
const connection2 = connections.find((c) => c.id === connectionId);
|
|
426
614
|
if (!connection2) {
|
|
@@ -463,13 +651,13 @@ Authentication is handled automatically using a service account.
|
|
|
463
651
|
};
|
|
464
652
|
}
|
|
465
653
|
const resolvedPath = path2.replace(/\{calendarId\}/g, calendarId);
|
|
466
|
-
let url = `${
|
|
654
|
+
let url = `${BASE_URL3}${resolvedPath.startsWith("/") ? "" : "/"}${resolvedPath}`;
|
|
467
655
|
if (queryParams) {
|
|
468
656
|
const searchParams = new URLSearchParams(queryParams);
|
|
469
657
|
url += `?${searchParams.toString()}`;
|
|
470
658
|
}
|
|
471
659
|
const controller = new AbortController();
|
|
472
|
-
const timeout = setTimeout(() => controller.abort(),
|
|
660
|
+
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS2);
|
|
473
661
|
try {
|
|
474
662
|
const response = await fetch(url, {
|
|
475
663
|
method,
|
|
@@ -507,7 +695,7 @@ Authentication is handled automatically using a service account.
|
|
|
507
695
|
});
|
|
508
696
|
|
|
509
697
|
// ../connectors/src/connectors/google-calendar/index.ts
|
|
510
|
-
var tools = { request: requestTool };
|
|
698
|
+
var tools = { request: requestTool, listCalendars: listCalendarsTool };
|
|
511
699
|
var googleCalendarConnector = new ConnectorPlugin({
|
|
512
700
|
slug: "google-calendar",
|
|
513
701
|
authType: AUTH_TYPES.SERVICE_ACCOUNT,
|
|
@@ -686,6 +874,79 @@ function resolveEnvVarOptional(entry, key) {
|
|
|
686
874
|
return process.env[envVarName] || void 0;
|
|
687
875
|
}
|
|
688
876
|
|
|
877
|
+
// src/connector-client/proxy-fetch.ts
|
|
878
|
+
import { getContext } from "hono/context-storage";
|
|
879
|
+
import { getCookie } from "hono/cookie";
|
|
880
|
+
var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
|
|
881
|
+
function createSandboxProxyFetch(connectionId) {
|
|
882
|
+
return async (input, init) => {
|
|
883
|
+
const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
|
|
884
|
+
const sandboxId = process.env.INTERNAL_SQUADBASE_SANDBOX_ID;
|
|
885
|
+
if (!token || !sandboxId) {
|
|
886
|
+
throw new Error(
|
|
887
|
+
"Connection proxy is not configured. Please check your deployment settings."
|
|
888
|
+
);
|
|
889
|
+
}
|
|
890
|
+
const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
|
891
|
+
const originalMethod = init?.method ?? "GET";
|
|
892
|
+
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
893
|
+
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
894
|
+
const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
895
|
+
return fetch(proxyUrl, {
|
|
896
|
+
method: "POST",
|
|
897
|
+
headers: {
|
|
898
|
+
"Content-Type": "application/json",
|
|
899
|
+
Authorization: `Bearer ${token}`
|
|
900
|
+
},
|
|
901
|
+
body: JSON.stringify({
|
|
902
|
+
url: originalUrl,
|
|
903
|
+
method: originalMethod,
|
|
904
|
+
body: originalBody
|
|
905
|
+
})
|
|
906
|
+
});
|
|
907
|
+
};
|
|
908
|
+
}
|
|
909
|
+
function createDeployedAppProxyFetch(connectionId) {
|
|
910
|
+
const projectId = process.env["SQUADBASE_PROJECT_ID"];
|
|
911
|
+
if (!projectId) {
|
|
912
|
+
throw new Error(
|
|
913
|
+
"Connection proxy is not configured. Please check your deployment settings."
|
|
914
|
+
);
|
|
915
|
+
}
|
|
916
|
+
const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
|
|
917
|
+
const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
918
|
+
return async (input, init) => {
|
|
919
|
+
const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
|
920
|
+
const originalMethod = init?.method ?? "GET";
|
|
921
|
+
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
922
|
+
const c = getContext();
|
|
923
|
+
const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
|
|
924
|
+
if (!appSession) {
|
|
925
|
+
throw new Error(
|
|
926
|
+
"No authentication method available for connection proxy."
|
|
927
|
+
);
|
|
928
|
+
}
|
|
929
|
+
return fetch(proxyUrl, {
|
|
930
|
+
method: "POST",
|
|
931
|
+
headers: {
|
|
932
|
+
"Content-Type": "application/json",
|
|
933
|
+
Authorization: `Bearer ${appSession}`
|
|
934
|
+
},
|
|
935
|
+
body: JSON.stringify({
|
|
936
|
+
url: originalUrl,
|
|
937
|
+
method: originalMethod,
|
|
938
|
+
body: originalBody
|
|
939
|
+
})
|
|
940
|
+
});
|
|
941
|
+
};
|
|
942
|
+
}
|
|
943
|
+
function createProxyFetch(connectionId) {
|
|
944
|
+
if (process.env.INTERNAL_SQUADBASE_SANDBOX_ID) {
|
|
945
|
+
return createSandboxProxyFetch(connectionId);
|
|
946
|
+
}
|
|
947
|
+
return createDeployedAppProxyFetch(connectionId);
|
|
948
|
+
}
|
|
949
|
+
|
|
689
950
|
// src/connectors/create-connector-sdk.ts
|
|
690
951
|
function loadConnectionsSync() {
|
|
691
952
|
const filePath = process.env.CONNECTIONS_PATH ?? path.join(process.cwd(), ".squadbase/connections.json");
|
|
@@ -719,21 +980,12 @@ function createConnectorSdk(plugin, createClient2) {
|
|
|
719
980
|
if (val !== void 0) params[param.slug] = val;
|
|
720
981
|
}
|
|
721
982
|
}
|
|
722
|
-
return createClient2(params);
|
|
983
|
+
return createClient2(params, createProxyFetch(connectionId));
|
|
723
984
|
};
|
|
724
985
|
}
|
|
725
986
|
|
|
726
987
|
// src/connectors/entries/google-calendar.ts
|
|
727
|
-
var
|
|
728
|
-
var connection = (connectionId, options) => {
|
|
729
|
-
if (options) {
|
|
730
|
-
return createConnectorSdk(
|
|
731
|
-
googleCalendarConnector,
|
|
732
|
-
(params) => createClient(params, options)
|
|
733
|
-
)(connectionId);
|
|
734
|
-
}
|
|
735
|
-
return baseConnection(connectionId);
|
|
736
|
-
};
|
|
988
|
+
var connection = createConnectorSdk(googleCalendarConnector, createClient);
|
|
737
989
|
export {
|
|
738
990
|
connection
|
|
739
991
|
};
|
|
@@ -90,7 +90,7 @@ var parameters = {
|
|
|
90
90
|
envVarBaseKey: "GOOGLE_SHEETS_OAUTH_SPREADSHEET_URL",
|
|
91
91
|
type: "text",
|
|
92
92
|
secret: false,
|
|
93
|
-
required:
|
|
93
|
+
required: true
|
|
94
94
|
})
|
|
95
95
|
};
|
|
96
96
|
|
|
@@ -394,41 +394,35 @@ Authentication is handled automatically via OAuth proxy.
|
|
|
394
394
|
var requestToolName = `google-sheets-oauth_${requestTool.name}`;
|
|
395
395
|
var googleSheetsOnboarding = new ConnectorOnboarding({
|
|
396
396
|
connectionSetupInstructions: {
|
|
397
|
-
ja: `\u4EE5\u4E0B\u306E\u624B\u9806\u3067Google Sheets\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002
|
|
397
|
+
ja: `\u4EE5\u4E0B\u306E\u624B\u9806\u3067Google Sheets\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8URL\u306F\u63A5\u7D9A\u30D1\u30E9\u30E1\u30FC\u30BF\u3068\u3057\u3066\u65E2\u306B\u767B\u9332\u6E08\u307F\u3067\u3059\u3002\u30E6\u30FC\u30B6\u30FC\u306B\u805E\u304D\u8FD4\u3055\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
|
|
398
398
|
|
|
399
|
-
1. \
|
|
400
|
-
2. \u30E6\u30FC\u30B6\u30FC\u304CURL\u3092\u63D0\u4F9B\u3057\u305F\u3089\u3001\`updateConnectionParameters\` \u3092\u547C\u3073\u51FA\u3059:
|
|
401
|
-
- \`parameterSlug\`: \`"spreadsheet-url"\`
|
|
402
|
-
- \`value\`: \u30E6\u30FC\u30B6\u30FC\u304C\u63D0\u4F9B\u3057\u305FURL\uFF08\u305D\u306E\u307E\u307E\u4FDD\u5B58\u3002ID\u306E\u62BD\u51FA\u306F\u81EA\u52D5\u3067\u884C\u308F\u308C\u307E\u3059\uFF09
|
|
403
|
-
3. \`${requestToolName}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97\u3059\u308B:
|
|
399
|
+
1. \`${requestToolName}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97\u3059\u308B:
|
|
404
400
|
- \`method\`: \`"GET"\`
|
|
405
401
|
- \`path\`: \`"/{spreadsheetId}?fields=spreadsheetId,properties.title,sheets.properties.title"\`
|
|
406
|
-
|
|
407
|
-
|
|
402
|
+
2. \u30A8\u30E9\u30FC\u304C\u8FD4\u3055\u308C\u305F\u5834\u5408\u3001\u30E6\u30FC\u30B6\u30FC\u306B\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306E\u5171\u6709\u8A2D\u5B9A\u3092\u78BA\u8A8D\u3059\u308B\u3088\u3046\u4F1D\u3048\u308B
|
|
403
|
+
3. \`updateConnectionContext\` \u3092\u547C\u3073\u51FA\u3059:
|
|
408
404
|
- \`spreadsheet\`: \u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306E\u30BF\u30A4\u30C8\u30EB
|
|
409
405
|
- \`sheets\`: \u30B7\u30FC\u30C8\u540D\u4E00\u89A7\uFF08\u30AB\u30F3\u30DE\u533A\u5207\u308A\uFF09
|
|
410
406
|
- \`note\`: \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u5185\u5BB9\u306E\u7C21\u5358\u306A\u8AAC\u660E
|
|
411
407
|
|
|
412
408
|
#### \u5236\u7D04
|
|
413
409
|
- **\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u4E2D\u306B\u30B7\u30FC\u30C8\u306E\u30C7\u30FC\u30BF\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\u30E1\u30BF\u30C7\u30FC\u30BF\u53D6\u5F97\u30EA\u30AF\u30A8\u30B9\u30C8\u306E\u307F
|
|
410
|
+
- \u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8URL\u3092\u30E6\u30FC\u30B6\u30FC\u306B\u805E\u304D\u8FD4\u3055\u306A\u3044\u3053\u3068\uFF08\u767B\u9332\u6E08\u307F\u30D1\u30E9\u30E1\u30FC\u30BF\u3092\u305D\u306E\u307E\u307E\u4F7F\u7528\u3059\u308B\uFF09
|
|
414
411
|
- \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`,
|
|
415
|
-
en: `Follow these steps to set up the Google Sheets connection.
|
|
412
|
+
en: `Follow these steps to set up the Google Sheets connection. The spreadsheet URL is already registered as a connection parameter \u2014 do NOT ask the user for it again.
|
|
416
413
|
|
|
417
|
-
1.
|
|
418
|
-
2. When the user provides a URL, call \`updateConnectionParameters\`:
|
|
419
|
-
- \`parameterSlug\`: \`"spreadsheet-url"\`
|
|
420
|
-
- \`value\`: The URL provided by the user (save as-is; the spreadsheet ID is extracted automatically)
|
|
421
|
-
3. Call \`${requestToolName}\` to fetch spreadsheet metadata:
|
|
414
|
+
1. Call \`${requestToolName}\` to fetch spreadsheet metadata:
|
|
422
415
|
- \`method\`: \`"GET"\`
|
|
423
416
|
- \`path\`: \`"/{spreadsheetId}?fields=spreadsheetId,properties.title,sheets.properties.title"\`
|
|
424
|
-
|
|
425
|
-
|
|
417
|
+
2. If an error is returned, ask the user to check the spreadsheet sharing settings
|
|
418
|
+
3. Call \`updateConnectionContext\`:
|
|
426
419
|
- \`spreadsheet\`: The spreadsheet title
|
|
427
420
|
- \`sheets\`: Sheet names (comma-separated)
|
|
428
421
|
- \`note\`: Brief description of the setup
|
|
429
422
|
|
|
430
423
|
#### Constraints
|
|
431
424
|
- **Do NOT read sheet data during setup**. Only the metadata request specified in the steps above is allowed
|
|
425
|
+
- Do NOT ask the user for the spreadsheet URL \u2014 it is already stored as a connection parameter
|
|
432
426
|
- Write only 1 sentence between tool calls, then immediately call the next tool. Skip unnecessary explanations and proceed efficiently`
|
|
433
427
|
},
|
|
434
428
|
dataOverviewInstructions: {
|
|
@@ -607,6 +601,79 @@ function resolveEnvVarOptional(entry, key) {
|
|
|
607
601
|
return process.env[envVarName] || void 0;
|
|
608
602
|
}
|
|
609
603
|
|
|
604
|
+
// src/connector-client/proxy-fetch.ts
|
|
605
|
+
import { getContext } from "hono/context-storage";
|
|
606
|
+
import { getCookie } from "hono/cookie";
|
|
607
|
+
var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
|
|
608
|
+
function createSandboxProxyFetch(connectionId) {
|
|
609
|
+
return async (input, init) => {
|
|
610
|
+
const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
|
|
611
|
+
const sandboxId = process.env.INTERNAL_SQUADBASE_SANDBOX_ID;
|
|
612
|
+
if (!token || !sandboxId) {
|
|
613
|
+
throw new Error(
|
|
614
|
+
"Connection proxy is not configured. Please check your deployment settings."
|
|
615
|
+
);
|
|
616
|
+
}
|
|
617
|
+
const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
|
618
|
+
const originalMethod = init?.method ?? "GET";
|
|
619
|
+
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
620
|
+
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
621
|
+
const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
622
|
+
return fetch(proxyUrl, {
|
|
623
|
+
method: "POST",
|
|
624
|
+
headers: {
|
|
625
|
+
"Content-Type": "application/json",
|
|
626
|
+
Authorization: `Bearer ${token}`
|
|
627
|
+
},
|
|
628
|
+
body: JSON.stringify({
|
|
629
|
+
url: originalUrl,
|
|
630
|
+
method: originalMethod,
|
|
631
|
+
body: originalBody
|
|
632
|
+
})
|
|
633
|
+
});
|
|
634
|
+
};
|
|
635
|
+
}
|
|
636
|
+
function createDeployedAppProxyFetch(connectionId) {
|
|
637
|
+
const projectId = process.env["SQUADBASE_PROJECT_ID"];
|
|
638
|
+
if (!projectId) {
|
|
639
|
+
throw new Error(
|
|
640
|
+
"Connection proxy is not configured. Please check your deployment settings."
|
|
641
|
+
);
|
|
642
|
+
}
|
|
643
|
+
const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
|
|
644
|
+
const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
645
|
+
return async (input, init) => {
|
|
646
|
+
const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
|
647
|
+
const originalMethod = init?.method ?? "GET";
|
|
648
|
+
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
649
|
+
const c = getContext();
|
|
650
|
+
const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
|
|
651
|
+
if (!appSession) {
|
|
652
|
+
throw new Error(
|
|
653
|
+
"No authentication method available for connection proxy."
|
|
654
|
+
);
|
|
655
|
+
}
|
|
656
|
+
return fetch(proxyUrl, {
|
|
657
|
+
method: "POST",
|
|
658
|
+
headers: {
|
|
659
|
+
"Content-Type": "application/json",
|
|
660
|
+
Authorization: `Bearer ${appSession}`
|
|
661
|
+
},
|
|
662
|
+
body: JSON.stringify({
|
|
663
|
+
url: originalUrl,
|
|
664
|
+
method: originalMethod,
|
|
665
|
+
body: originalBody
|
|
666
|
+
})
|
|
667
|
+
});
|
|
668
|
+
};
|
|
669
|
+
}
|
|
670
|
+
function createProxyFetch(connectionId) {
|
|
671
|
+
if (process.env.INTERNAL_SQUADBASE_SANDBOX_ID) {
|
|
672
|
+
return createSandboxProxyFetch(connectionId);
|
|
673
|
+
}
|
|
674
|
+
return createDeployedAppProxyFetch(connectionId);
|
|
675
|
+
}
|
|
676
|
+
|
|
610
677
|
// src/connectors/create-connector-sdk.ts
|
|
611
678
|
function loadConnectionsSync() {
|
|
612
679
|
const filePath = process.env.CONNECTIONS_PATH ?? path.join(process.cwd(), ".squadbase/connections.json");
|
|
@@ -640,7 +707,7 @@ function createConnectorSdk(plugin, createClient2) {
|
|
|
640
707
|
if (val !== void 0) params[param.slug] = val;
|
|
641
708
|
}
|
|
642
709
|
}
|
|
643
|
-
return createClient2(params);
|
|
710
|
+
return createClient2(params, createProxyFetch(connectionId));
|
|
644
711
|
};
|
|
645
712
|
}
|
|
646
713
|
|