@squadbase/vite-server 0.1.3-dev.5 → 0.1.3-dev.7
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 +2097 -1441
- package/dist/connectors/gmail.d.ts +5 -0
- package/dist/connectors/gmail.js +802 -0
- package/dist/connectors/google-ads-oauth.js +1 -1
- package/dist/connectors/google-analytics.js +259 -35
- package/dist/connectors/google-calendar-oauth.js +1 -1
- package/dist/connectors/google-calendar.d.ts +8 -1
- package/dist/connectors/google-calendar.js +115 -31
- package/dist/connectors/google-sheets-oauth.js +66 -23
- package/dist/connectors/google-sheets.js +33 -7
- package/dist/connectors/grafana.d.ts +5 -0
- package/dist/connectors/grafana.js +565 -0
- package/dist/index.js +2095 -1439
- package/dist/main.js +2095 -1439
- package/dist/vite-plugin.js +2095 -1439
- package/package.json +9 -1
|
@@ -56,6 +56,15 @@ var parameters = {
|
|
|
56
56
|
secret: true,
|
|
57
57
|
required: true
|
|
58
58
|
}),
|
|
59
|
+
impersonateEmail: new ParameterDefinition({
|
|
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., 'user@example.com'). The service account will act on behalf of this user.",
|
|
63
|
+
envVarBaseKey: "GOOGLE_CALENDAR_IMPERSONATE_EMAIL",
|
|
64
|
+
type: "text",
|
|
65
|
+
secret: false,
|
|
66
|
+
required: true
|
|
67
|
+
}),
|
|
59
68
|
calendarId: new ParameterDefinition({
|
|
60
69
|
slug: "calendar-id",
|
|
61
70
|
name: "Default Calendar ID",
|
|
@@ -75,17 +84,19 @@ function base64url(input) {
|
|
|
75
84
|
const buf = typeof input === "string" ? Buffer.from(input) : input;
|
|
76
85
|
return buf.toString("base64url");
|
|
77
86
|
}
|
|
78
|
-
function buildJwt(clientEmail, privateKey, nowSec) {
|
|
87
|
+
function buildJwt(clientEmail, privateKey, nowSec, subject) {
|
|
79
88
|
const header = base64url(JSON.stringify({ alg: "RS256", typ: "JWT" }));
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
+
const claims = {
|
|
90
|
+
iss: clientEmail,
|
|
91
|
+
scope: SCOPE,
|
|
92
|
+
aud: TOKEN_URL,
|
|
93
|
+
iat: nowSec,
|
|
94
|
+
exp: nowSec + 3600
|
|
95
|
+
};
|
|
96
|
+
if (subject) {
|
|
97
|
+
claims.sub = subject;
|
|
98
|
+
}
|
|
99
|
+
const payload = base64url(JSON.stringify(claims));
|
|
89
100
|
const signingInput = `${header}.${payload}`;
|
|
90
101
|
const sign = crypto.createSign("RSA-SHA256");
|
|
91
102
|
sign.update(signingInput);
|
|
@@ -93,14 +104,20 @@ function buildJwt(clientEmail, privateKey, nowSec) {
|
|
|
93
104
|
const signature = base64url(sign.sign(privateKey));
|
|
94
105
|
return `${signingInput}.${signature}`;
|
|
95
106
|
}
|
|
96
|
-
function createClient(params) {
|
|
107
|
+
function createClient(params, options) {
|
|
97
108
|
const serviceAccountKeyJsonBase64 = params[parameters.serviceAccountKeyJsonBase64.slug];
|
|
109
|
+
const impersonateEmail = params[parameters.impersonateEmail.slug];
|
|
98
110
|
const defaultCalendarId = params[parameters.calendarId.slug] ?? "primary";
|
|
99
111
|
if (!serviceAccountKeyJsonBase64) {
|
|
100
112
|
throw new Error(
|
|
101
113
|
`google-calendar: missing required parameter: ${parameters.serviceAccountKeyJsonBase64.slug}`
|
|
102
114
|
);
|
|
103
115
|
}
|
|
116
|
+
if (!impersonateEmail && !options?.subject) {
|
|
117
|
+
throw new Error(
|
|
118
|
+
`google-calendar: missing required parameter: ${parameters.impersonateEmail.slug}`
|
|
119
|
+
);
|
|
120
|
+
}
|
|
104
121
|
let serviceAccountKey;
|
|
105
122
|
try {
|
|
106
123
|
const decoded = Buffer.from(
|
|
@@ -118,6 +135,7 @@ function createClient(params) {
|
|
|
118
135
|
"google-calendar: service account key JSON must contain client_email and private_key"
|
|
119
136
|
);
|
|
120
137
|
}
|
|
138
|
+
const subject = options?.subject ?? impersonateEmail;
|
|
121
139
|
let cachedToken = null;
|
|
122
140
|
let tokenExpiresAt = 0;
|
|
123
141
|
async function getAccessToken() {
|
|
@@ -128,7 +146,8 @@ function createClient(params) {
|
|
|
128
146
|
const jwt = buildJwt(
|
|
129
147
|
serviceAccountKey.client_email,
|
|
130
148
|
serviceAccountKey.private_key,
|
|
131
|
-
nowSec
|
|
149
|
+
nowSec,
|
|
150
|
+
subject
|
|
132
151
|
);
|
|
133
152
|
const response = await fetch(TOKEN_URL, {
|
|
134
153
|
method: "POST",
|
|
@@ -177,18 +196,18 @@ function createClient(params) {
|
|
|
177
196
|
const data = await response.json();
|
|
178
197
|
return data.items ?? [];
|
|
179
198
|
},
|
|
180
|
-
async listEvents(
|
|
199
|
+
async listEvents(options2, calendarId) {
|
|
181
200
|
const cid = resolveCalendarId(calendarId);
|
|
182
201
|
const searchParams = new URLSearchParams();
|
|
183
|
-
if (
|
|
184
|
-
if (
|
|
185
|
-
if (
|
|
186
|
-
searchParams.set("maxResults", String(
|
|
187
|
-
if (
|
|
188
|
-
if (
|
|
189
|
-
searchParams.set("singleEvents", String(
|
|
190
|
-
if (
|
|
191
|
-
if (
|
|
202
|
+
if (options2?.timeMin) searchParams.set("timeMin", options2.timeMin);
|
|
203
|
+
if (options2?.timeMax) searchParams.set("timeMax", options2.timeMax);
|
|
204
|
+
if (options2?.maxResults)
|
|
205
|
+
searchParams.set("maxResults", String(options2.maxResults));
|
|
206
|
+
if (options2?.q) searchParams.set("q", options2.q);
|
|
207
|
+
if (options2?.singleEvents != null)
|
|
208
|
+
searchParams.set("singleEvents", String(options2.singleEvents));
|
|
209
|
+
if (options2?.orderBy) searchParams.set("orderBy", options2.orderBy);
|
|
210
|
+
if (options2?.pageToken) searchParams.set("pageToken", options2.pageToken);
|
|
192
211
|
const qs = searchParams.toString();
|
|
193
212
|
const path2 = `/calendars/${encodeURIComponent(cid)}/events${qs ? `?${qs}` : ""}`;
|
|
194
213
|
const response = await this.request(path2, { method: "GET" });
|
|
@@ -327,6 +346,34 @@ var AUTH_TYPES = {
|
|
|
327
346
|
|
|
328
347
|
// ../connectors/src/connectors/google-calendar/setup.ts
|
|
329
348
|
var googleCalendarOnboarding = new ConnectorOnboarding({
|
|
349
|
+
connectionSetupInstructions: {
|
|
350
|
+
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
|
+
|
|
352
|
+
1. \u30E6\u30FC\u30B6\u30FC\u306B\u300C\u30AB\u30EC\u30F3\u30C0\u30FC\u306B\u30A2\u30AF\u30BB\u30B9\u3057\u305F\u3044Google Workspace\u30A2\u30AB\u30A6\u30F3\u30C8\u306E\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092\u6559\u3048\u3066\u304F\u3060\u3055\u3044\uFF08\u4F8B: user@example.com\uFF09\u300D\u3068\u4F1D\u3048\u308B
|
|
353
|
+
2. \u30E6\u30FC\u30B6\u30FC\u304C\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092\u63D0\u4F9B\u3057\u305F\u3089\u3001\`updateConnectionParameters\` \u3092\u547C\u3073\u51FA\u3059:
|
|
354
|
+
- \`parameterSlug\`: \`"impersonate-email"\`
|
|
355
|
+
- \`value\`: \u30E6\u30FC\u30B6\u30FC\u304C\u63D0\u4F9B\u3057\u305F\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9
|
|
356
|
+
3. \`updateConnectionContext\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001\u5BFE\u8C61\u30E6\u30FC\u30B6\u30FC\u306E\u60C5\u5831\u3092\u8A18\u9332\u3059\u308B:
|
|
357
|
+
- \`user\`: \u8A2D\u5B9A\u3057\u305F\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9
|
|
358
|
+
- \`note\`: \u300CDomain-wide Delegation\u3067 {email} \u306E\u30AB\u30EC\u30F3\u30C0\u30FC\u306B\u30A2\u30AF\u30BB\u30B9\u300D\u306A\u3069\u306E\u8AAC\u660E
|
|
359
|
+
|
|
360
|
+
#### \u5236\u7D04
|
|
361
|
+
- **\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\u30A2\u30AF\u30BB\u30B9\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
|
+
- \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
|
+
en: `Follow these steps to set up the Google Calendar connection.
|
|
364
|
+
|
|
365
|
+
1. Ask the user for the Google Workspace email address whose calendar should be accessed (e.g., user@example.com)
|
|
366
|
+
2. When the user provides an email, call \`updateConnectionParameters\`:
|
|
367
|
+
- \`parameterSlug\`: \`"impersonate-email"\`
|
|
368
|
+
- \`value\`: The email provided by the user
|
|
369
|
+
3. Call \`updateConnectionContext\` to record the target user:
|
|
370
|
+
- \`user\`: The configured email address
|
|
371
|
+
- \`note\`: A description such as "Accessing {email}'s calendar via Domain-wide Delegation"
|
|
372
|
+
|
|
373
|
+
#### Constraints
|
|
374
|
+
- **Domain-wide Delegation must be configured on the service account**. If access errors occur, ask the user to verify the Domain-wide Delegation setup with their Google Workspace administrator
|
|
375
|
+
- Write only 1 sentence between tool calls, then immediately call the next tool. Skip unnecessary explanations and proceed efficiently`
|
|
376
|
+
},
|
|
330
377
|
dataOverviewInstructions: {
|
|
331
378
|
en: `1. Call google-calendar_request with GET /calendars/{calendarId} to get the default calendar's metadata
|
|
332
379
|
2. Call google-calendar_request with GET /users/me/calendarList to list all accessible calendars
|
|
@@ -351,7 +398,10 @@ var inputSchema = z.object({
|
|
|
351
398
|
"API path appended to https://www.googleapis.com/calendar/v3 (e.g., '/calendars/{calendarId}/events'). {calendarId} is automatically replaced."
|
|
352
399
|
),
|
|
353
400
|
queryParams: z.record(z.string(), z.string()).optional().describe("Query parameters to append to the URL"),
|
|
354
|
-
body: z.record(z.string(), z.unknown()).optional().describe("Request body (JSON) for POST/PUT/PATCH methods")
|
|
401
|
+
body: z.record(z.string(), z.unknown()).optional().describe("Request body (JSON) for POST/PUT/PATCH methods"),
|
|
402
|
+
subject: z.string().optional().describe(
|
|
403
|
+
"Override the email address of the user to impersonate via Domain-wide Delegation. If omitted, the connection's configured user email is used."
|
|
404
|
+
)
|
|
355
405
|
});
|
|
356
406
|
var outputSchema = z.discriminatedUnion("success", [
|
|
357
407
|
z.object({
|
|
@@ -371,7 +421,7 @@ Authentication is handled automatically using a service account.
|
|
|
371
421
|
{calendarId} in the path is automatically replaced with the connection's default calendar ID.`,
|
|
372
422
|
inputSchema,
|
|
373
423
|
outputSchema,
|
|
374
|
-
async execute({ connectionId, method, path: path2, queryParams, body }, connections) {
|
|
424
|
+
async execute({ connectionId, method, path: path2, queryParams, body, subject }, connections) {
|
|
375
425
|
const connection2 = connections.find((c) => c.id === connectionId);
|
|
376
426
|
if (!connection2) {
|
|
377
427
|
return {
|
|
@@ -385,7 +435,15 @@ Authentication is handled automatically using a service account.
|
|
|
385
435
|
try {
|
|
386
436
|
const { GoogleAuth } = await import("google-auth-library");
|
|
387
437
|
const keyJsonBase64 = parameters.serviceAccountKeyJsonBase64.getValue(connection2);
|
|
438
|
+
const impersonateEmail = parameters.impersonateEmail.tryGetValue(connection2);
|
|
388
439
|
const calendarId = parameters.calendarId.tryGetValue(connection2) ?? "primary";
|
|
440
|
+
const resolvedSubject = subject ?? impersonateEmail;
|
|
441
|
+
if (!resolvedSubject) {
|
|
442
|
+
return {
|
|
443
|
+
success: false,
|
|
444
|
+
error: `Missing required parameter: ${parameters.impersonateEmail.slug}. Configure the user email for this connection.`
|
|
445
|
+
};
|
|
446
|
+
}
|
|
389
447
|
const credentials = JSON.parse(
|
|
390
448
|
Buffer.from(keyJsonBase64, "base64").toString("utf-8")
|
|
391
449
|
);
|
|
@@ -394,7 +452,8 @@ Authentication is handled automatically using a service account.
|
|
|
394
452
|
scopes: [
|
|
395
453
|
"https://www.googleapis.com/auth/calendar.readonly",
|
|
396
454
|
"https://www.googleapis.com/auth/calendar.events.readonly"
|
|
397
|
-
]
|
|
455
|
+
],
|
|
456
|
+
clientOptions: { subject: resolvedSubject }
|
|
398
457
|
});
|
|
399
458
|
const token = await auth.getAccessToken();
|
|
400
459
|
if (!token) {
|
|
@@ -454,25 +513,33 @@ var googleCalendarConnector = new ConnectorPlugin({
|
|
|
454
513
|
authType: AUTH_TYPES.SERVICE_ACCOUNT,
|
|
455
514
|
name: "Google Calendar",
|
|
456
515
|
description: "Connect to Google Calendar for calendar and event data access using a service account.",
|
|
457
|
-
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/
|
|
516
|
+
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/2YsqoBEpdELmfDeFcyGHyE/4494c633b5ae15e562cb739cd85442c1/google-calendar.png",
|
|
458
517
|
parameters,
|
|
459
518
|
releaseFlag: { dev1: true, dev2: true, prod: true },
|
|
460
519
|
onboarding: googleCalendarOnboarding,
|
|
461
520
|
systemPrompt: {
|
|
462
521
|
en: `### Tools
|
|
463
522
|
|
|
464
|
-
- \`google-calendar_request\`: The only way to call the Google Calendar API. Use it to list calendars, get events, and manage calendar data. Authentication is handled automatically using a service account. The {calendarId} placeholder in paths is automatically replaced with the configured default calendar ID.
|
|
523
|
+
- \`google-calendar_request\`: The only way to call the Google Calendar API. Use it to list calendars, get events, and manage calendar data. Authentication is handled automatically using a service account with Domain-wide Delegation \u2014 the service account impersonates the user configured on the connection (\`impersonate-email\` parameter). The {calendarId} placeholder in paths is automatically replaced with the configured default calendar ID. Pass an optional \`subject\` only if you need to override the configured user for a specific request.
|
|
465
524
|
|
|
466
525
|
### Business Logic
|
|
467
526
|
|
|
468
527
|
The business logic type for this connector is "typescript". Use the connector SDK in your handler. Do NOT read credentials from environment variables.
|
|
469
528
|
|
|
470
|
-
SDK methods (client created via \`connection(connectionId)\`):
|
|
529
|
+
SDK methods (client created via \`connection(connectionId)\` \u2014 the connection's \`impersonate-email\` parameter is used automatically for Domain-wide Delegation):
|
|
471
530
|
- \`client.listCalendars()\` \u2014 list all accessible calendars
|
|
472
531
|
- \`client.listEvents(options?, calendarId?)\` \u2014 list events with optional filters
|
|
473
532
|
- \`client.getEvent(eventId, calendarId?)\` \u2014 get a single event by ID
|
|
474
533
|
- \`client.request(path, init?)\` \u2014 low-level authenticated fetch
|
|
475
534
|
|
|
535
|
+
#### Domain-wide Delegation
|
|
536
|
+
|
|
537
|
+
The target user email is configured on the connection (\`impersonate-email\` parameter), so \`connection()\` automatically uses it. Pass \`subject\` only to override it:
|
|
538
|
+
|
|
539
|
+
\`\`\`ts
|
|
540
|
+
const calendar = connection("<connectionId>", { subject: "other-user@example.com" });
|
|
541
|
+
\`\`\`
|
|
542
|
+
|
|
476
543
|
\`\`\`ts
|
|
477
544
|
import type { Context } from "hono";
|
|
478
545
|
import { connection } from "@squadbase/vite-server/connectors/google-calendar";
|
|
@@ -524,18 +591,26 @@ export default async function handler(c: Context) {
|
|
|
524
591
|
- The default calendar ID is "primary" if not configured`,
|
|
525
592
|
ja: `### \u30C4\u30FC\u30EB
|
|
526
593
|
|
|
527
|
-
- \`google-calendar_request\`: Google Calendar API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30AB\u30EC\u30F3\u30C0\u30FC\u306E\u4E00\u89A7\u53D6\u5F97\u3001\u30A4\u30D9\u30F3\u30C8\u306E\u53D6\u5F97\u3001\u30AB\u30EC\u30F3\u30C0\u30FC\u30C7\u30FC\u30BF\u306E\u7BA1\u7406\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u30B5\u30FC\u30D3\u30B9\u30A2\u30AB\u30A6\u30F3\u30C8\
|
|
594
|
+
- \`google-calendar_request\`: Google Calendar API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30AB\u30EC\u30F3\u30C0\u30FC\u306E\u4E00\u89A7\u53D6\u5F97\u3001\u30A4\u30D9\u30F3\u30C8\u306E\u53D6\u5F97\u3001\u30AB\u30EC\u30F3\u30C0\u30FC\u30C7\u30FC\u30BF\u306E\u7BA1\u7406\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u30B5\u30FC\u30D3\u30B9\u30A2\u30AB\u30A6\u30F3\u30C8\uFF0BDomain-wide Delegation\u3067\u8A8D\u8A3C\u304C\u81EA\u52D5\u7684\u306B\u51E6\u7406\u3055\u308C\u3001\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306B\u8A2D\u5B9A\u3055\u308C\u305F\u30E6\u30FC\u30B6\u30FC\uFF08\`impersonate-email\`\u30D1\u30E9\u30E1\u30FC\u30BF\uFF09\u3068\u3057\u3066\u52D5\u4F5C\u3057\u307E\u3059\u3002\u30D1\u30B9\u5185\u306E{calendarId}\u30D7\u30EC\u30FC\u30B9\u30DB\u30EB\u30C0\u30FC\u306F\u8A2D\u5B9A\u6E08\u307F\u306E\u30C7\u30D5\u30A9\u30EB\u30C8\u30AB\u30EC\u30F3\u30C0\u30FCID\u3067\u81EA\u52D5\u7684\u306B\u7F6E\u63DB\u3055\u308C\u307E\u3059\u3002\u7279\u5B9A\u30EA\u30AF\u30A8\u30B9\u30C8\u3067\u8A2D\u5B9A\u30E6\u30FC\u30B6\u30FC\u3092\u4E0A\u66F8\u304D\u3057\u305F\u3044\u5834\u5408\u306E\u307F\u3001\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\`subject\`\u30D1\u30E9\u30E1\u30FC\u30BF\u3092\u6E21\u3057\u3066\u304F\u3060\u3055\u3044\u3002
|
|
528
595
|
|
|
529
596
|
### Business Logic
|
|
530
597
|
|
|
531
598
|
\u3053\u306E\u30B3\u30CD\u30AF\u30BF\u306E\u30D3\u30B8\u30CD\u30B9\u30ED\u30B8\u30C3\u30AF\u30BF\u30A4\u30D7\u306F "typescript" \u3067\u3059\u3002\u30CF\u30F3\u30C9\u30E9\u5185\u3067\u306F\u30B3\u30CD\u30AF\u30BFSDK\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u74B0\u5883\u5909\u6570\u304B\u3089\u8A8D\u8A3C\u60C5\u5831\u3092\u8AAD\u307F\u53D6\u3089\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
|
|
532
599
|
|
|
533
|
-
SDK\u30E1\u30BD\u30C3\u30C9 (\`connection(connectionId)\` \u3067\u4F5C\u6210\u3057\u305F\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8):
|
|
600
|
+
SDK\u30E1\u30BD\u30C3\u30C9 (\`connection(connectionId)\` \u3067\u4F5C\u6210\u3057\u305F\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8 \u2014 \u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\`impersonate-email\`\u30D1\u30E9\u30E1\u30FC\u30BF\u304C\u81EA\u52D5\u7684\u306BDomain-wide Delegation\u306Esubject\u3068\u3057\u3066\u4F7F\u308F\u308C\u307E\u3059):
|
|
534
601
|
- \`client.listCalendars()\` \u2014 \u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306A\u5168\u30AB\u30EC\u30F3\u30C0\u30FC\u306E\u4E00\u89A7\u53D6\u5F97
|
|
535
602
|
- \`client.listEvents(options?, calendarId?)\` \u2014 \u30D5\u30A3\u30EB\u30BF\u30FC\u4ED8\u304D\u30A4\u30D9\u30F3\u30C8\u4E00\u89A7\u53D6\u5F97
|
|
536
603
|
- \`client.getEvent(eventId, calendarId?)\` \u2014 ID\u306B\u3088\u308B\u5358\u4E00\u30A4\u30D9\u30F3\u30C8\u53D6\u5F97
|
|
537
604
|
- \`client.request(path, init?)\` \u2014 \u4F4E\u30EC\u30D9\u30EB\u306E\u8A8D\u8A3C\u4ED8\u304Dfetch
|
|
538
605
|
|
|
606
|
+
#### Domain-wide Delegation
|
|
607
|
+
|
|
608
|
+
\u5BFE\u8C61\u30E6\u30FC\u30B6\u30FC\u306E\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u306F\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\uFF08\`impersonate-email\`\u30D1\u30E9\u30E1\u30FC\u30BF\uFF09\u306B\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u308B\u305F\u3081\u3001\`connection()\`\u306F\u81EA\u52D5\u7684\u306B\u305D\u308C\u3092\u4F7F\u3044\u307E\u3059\u3002\u4E0A\u66F8\u304D\u3057\u305F\u3044\u5834\u5408\u306E\u307F\`subject\`\u3092\u6E21\u3057\u307E\u3059\uFF1A
|
|
609
|
+
|
|
610
|
+
\`\`\`ts
|
|
611
|
+
const calendar = connection("<connectionId>", { subject: "other-user@example.com" });
|
|
612
|
+
\`\`\`
|
|
613
|
+
|
|
539
614
|
\`\`\`ts
|
|
540
615
|
import type { Context } from "hono";
|
|
541
616
|
import { connection } from "@squadbase/vite-server/connectors/google-calendar";
|
|
@@ -649,7 +724,16 @@ function createConnectorSdk(plugin, createClient2) {
|
|
|
649
724
|
}
|
|
650
725
|
|
|
651
726
|
// src/connectors/entries/google-calendar.ts
|
|
652
|
-
var
|
|
727
|
+
var baseConnection = createConnectorSdk(googleCalendarConnector, createClient);
|
|
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
|
+
};
|
|
653
737
|
export {
|
|
654
738
|
connection
|
|
655
739
|
};
|
|
@@ -1,3 +1,42 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __esm = (fn, res) => function __init() {
|
|
4
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
5
|
+
};
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
// ../connectors/src/connectors/google-sheets/utils.ts
|
|
12
|
+
function extractSpreadsheetId(urlOrId) {
|
|
13
|
+
const trimmed = urlOrId.trim();
|
|
14
|
+
const match = trimmed.match(SPREADSHEET_URL_PATTERN);
|
|
15
|
+
if (match) {
|
|
16
|
+
return match[1];
|
|
17
|
+
}
|
|
18
|
+
return trimmed;
|
|
19
|
+
}
|
|
20
|
+
var SPREADSHEET_URL_PATTERN;
|
|
21
|
+
var init_utils = __esm({
|
|
22
|
+
"../connectors/src/connectors/google-sheets/utils.ts"() {
|
|
23
|
+
"use strict";
|
|
24
|
+
SPREADSHEET_URL_PATTERN = /docs\.google\.com\/spreadsheets\/d\/([a-zA-Z0-9_-]+)/;
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// ../connectors/src/connectors/google-sheets-oauth/utils.ts
|
|
29
|
+
var utils_exports = {};
|
|
30
|
+
__export(utils_exports, {
|
|
31
|
+
extractSpreadsheetId: () => extractSpreadsheetId
|
|
32
|
+
});
|
|
33
|
+
var init_utils2 = __esm({
|
|
34
|
+
"../connectors/src/connectors/google-sheets-oauth/utils.ts"() {
|
|
35
|
+
"use strict";
|
|
36
|
+
init_utils();
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
1
40
|
// ../connectors/src/parameter-definition.ts
|
|
2
41
|
var ParameterDefinition = class {
|
|
3
42
|
slug;
|
|
@@ -44,11 +83,11 @@ var ParameterDefinition = class {
|
|
|
44
83
|
|
|
45
84
|
// ../connectors/src/connectors/google-sheets-oauth/parameters.ts
|
|
46
85
|
var parameters = {
|
|
47
|
-
|
|
48
|
-
slug: "spreadsheet-
|
|
49
|
-
name: "
|
|
50
|
-
description: "The
|
|
51
|
-
envVarBaseKey: "
|
|
86
|
+
spreadsheetUrl: new ParameterDefinition({
|
|
87
|
+
slug: "spreadsheet-url",
|
|
88
|
+
name: "Google Spreadsheet URL",
|
|
89
|
+
description: "The URL of the Google Spreadsheet (e.g., https://docs.google.com/spreadsheets/d/xxxxx/edit). The spreadsheet ID is automatically extracted from the URL.",
|
|
90
|
+
envVarBaseKey: "GOOGLE_SHEETS_OAUTH_SPREADSHEET_URL",
|
|
52
91
|
type: "text",
|
|
53
92
|
secret: false,
|
|
54
93
|
required: false
|
|
@@ -56,9 +95,11 @@ var parameters = {
|
|
|
56
95
|
};
|
|
57
96
|
|
|
58
97
|
// ../connectors/src/connectors/google-sheets-oauth/sdk/index.ts
|
|
98
|
+
init_utils2();
|
|
59
99
|
var BASE_URL = "https://sheets.googleapis.com/v4/spreadsheets";
|
|
60
100
|
function createClient(params, fetchFn = fetch) {
|
|
61
|
-
const
|
|
101
|
+
const spreadsheetUrl = params[parameters.spreadsheetUrl.slug];
|
|
102
|
+
const defaultSpreadsheetId = spreadsheetUrl ? extractSpreadsheetId(spreadsheetUrl) : void 0;
|
|
62
103
|
function resolveSpreadsheetId(override) {
|
|
63
104
|
const id = override ?? defaultSpreadsheetId;
|
|
64
105
|
if (!id) {
|
|
@@ -233,6 +274,7 @@ var AUTH_TYPES = {
|
|
|
233
274
|
|
|
234
275
|
// ../connectors/src/connectors/google-sheets-oauth/tools/request.ts
|
|
235
276
|
import { z } from "zod";
|
|
277
|
+
init_utils2();
|
|
236
278
|
var BASE_URL2 = "https://sheets.googleapis.com/v4/spreadsheets";
|
|
237
279
|
var REQUEST_TIMEOUT_MS = 6e4;
|
|
238
280
|
var cachedToken = null;
|
|
@@ -307,7 +349,8 @@ Authentication is handled automatically via OAuth proxy.
|
|
|
307
349
|
`[connector-request] google-sheets-oauth/${connection2.name}: ${method} ${path2}`
|
|
308
350
|
);
|
|
309
351
|
try {
|
|
310
|
-
const
|
|
352
|
+
const spreadsheetUrl = parameters.spreadsheetUrl.tryGetValue(connection2);
|
|
353
|
+
const spreadsheetId = spreadsheetUrl ? extractSpreadsheetId(spreadsheetUrl) : void 0;
|
|
311
354
|
const resolvedPath = spreadsheetId ? path2.replace(/\{spreadsheetId\}/g, spreadsheetId) : path2;
|
|
312
355
|
let url = `${BASE_URL2}${resolvedPath.startsWith("/") ? "" : "/"}${resolvedPath}`;
|
|
313
356
|
if (queryParams) {
|
|
@@ -354,15 +397,14 @@ var googleSheetsOnboarding = new ConnectorOnboarding({
|
|
|
354
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
|
|
355
398
|
|
|
356
399
|
1. \u30E6\u30FC\u30B6\u30FC\u306B\u300C\u4F7F\u7528\u3059\u308BGoogle Sheets\u306EURL\u3092\u8CBC\u308A\u4ED8\u3051\u3066\u304F\u3060\u3055\u3044\uFF08\u4F8B: https://docs.google.com/spreadsheets/d/xxxxx/edit\uFF09\u300D\u3068\u4F1D\u3048\u308B
|
|
357
|
-
2. \u30E6\u30FC\u30B6\u30FC\u304CURL\
|
|
358
|
-
|
|
359
|
-
- \`
|
|
360
|
-
|
|
361
|
-
4. \`${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:
|
|
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:
|
|
362
404
|
- \`method\`: \`"GET"\`
|
|
363
405
|
- \`path\`: \`"/{spreadsheetId}?fields=spreadsheetId,properties.title,sheets.properties.title"\`
|
|
364
|
-
|
|
365
|
-
|
|
406
|
+
4. \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
|
|
407
|
+
5. \`updateConnectionContext\` \u3092\u547C\u3073\u51FA\u3059:
|
|
366
408
|
- \`spreadsheet\`: \u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306E\u30BF\u30A4\u30C8\u30EB
|
|
367
409
|
- \`sheets\`: \u30B7\u30FC\u30C8\u540D\u4E00\u89A7\uFF08\u30AB\u30F3\u30DE\u533A\u5207\u308A\uFF09
|
|
368
410
|
- \`note\`: \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u5185\u5BB9\u306E\u7C21\u5358\u306A\u8AAC\u660E
|
|
@@ -373,15 +415,14 @@ var googleSheetsOnboarding = new ConnectorOnboarding({
|
|
|
373
415
|
en: `Follow these steps to set up the Google Sheets connection.
|
|
374
416
|
|
|
375
417
|
1. Ask the user to paste the Google Sheets URL (e.g., https://docs.google.com/spreadsheets/d/xxxxx/edit)
|
|
376
|
-
2. When the user provides a URL
|
|
377
|
-
|
|
378
|
-
- \`
|
|
379
|
-
|
|
380
|
-
4. Call \`${requestToolName}\` to fetch spreadsheet metadata:
|
|
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:
|
|
381
422
|
- \`method\`: \`"GET"\`
|
|
382
423
|
- \`path\`: \`"/{spreadsheetId}?fields=spreadsheetId,properties.title,sheets.properties.title"\`
|
|
383
|
-
|
|
384
|
-
|
|
424
|
+
4. If an error is returned, ask the user to check the spreadsheet sharing settings
|
|
425
|
+
5. Call \`updateConnectionContext\`:
|
|
385
426
|
- \`spreadsheet\`: The spreadsheet title
|
|
386
427
|
- \`sheets\`: Sheet names (comma-separated)
|
|
387
428
|
- \`note\`: Brief description of the setup
|
|
@@ -518,10 +559,12 @@ batch.valueRanges.forEach(vr => console.log(vr.range, vr.values));
|
|
|
518
559
|
tools,
|
|
519
560
|
async checkConnection(params, config) {
|
|
520
561
|
const { proxyFetch } = config;
|
|
521
|
-
const
|
|
522
|
-
if (!
|
|
562
|
+
const spreadsheetUrl = params[parameters.spreadsheetUrl.slug];
|
|
563
|
+
if (!spreadsheetUrl) {
|
|
523
564
|
return { success: true };
|
|
524
565
|
}
|
|
566
|
+
const { extractSpreadsheetId: extractSpreadsheetId2 } = await Promise.resolve().then(() => (init_utils2(), utils_exports));
|
|
567
|
+
const spreadsheetId = extractSpreadsheetId2(spreadsheetUrl);
|
|
525
568
|
const url = `https://sheets.googleapis.com/v4/spreadsheets/${spreadsheetId}?fields=spreadsheetId,properties.title`;
|
|
526
569
|
try {
|
|
527
570
|
const res = await proxyFetch(url, { method: "GET" });
|
|
@@ -1,3 +1,25 @@
|
|
|
1
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
2
|
+
var __esm = (fn, res) => function __init() {
|
|
3
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
// ../connectors/src/connectors/google-sheets/utils.ts
|
|
7
|
+
function extractSpreadsheetId(urlOrId) {
|
|
8
|
+
const trimmed = urlOrId.trim();
|
|
9
|
+
const match = trimmed.match(SPREADSHEET_URL_PATTERN);
|
|
10
|
+
if (match) {
|
|
11
|
+
return match[1];
|
|
12
|
+
}
|
|
13
|
+
return trimmed;
|
|
14
|
+
}
|
|
15
|
+
var SPREADSHEET_URL_PATTERN;
|
|
16
|
+
var init_utils = __esm({
|
|
17
|
+
"../connectors/src/connectors/google-sheets/utils.ts"() {
|
|
18
|
+
"use strict";
|
|
19
|
+
SPREADSHEET_URL_PATTERN = /docs\.google\.com\/spreadsheets\/d\/([a-zA-Z0-9_-]+)/;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
|
|
1
23
|
// ../connectors/src/parameter-definition.ts
|
|
2
24
|
var ParameterDefinition = class {
|
|
3
25
|
slug;
|
|
@@ -56,11 +78,11 @@ var parameters = {
|
|
|
56
78
|
secret: true,
|
|
57
79
|
required: true
|
|
58
80
|
}),
|
|
59
|
-
|
|
60
|
-
slug: "spreadsheet-
|
|
61
|
-
name: "
|
|
62
|
-
description: "The
|
|
63
|
-
envVarBaseKey: "
|
|
81
|
+
spreadsheetUrl: new ParameterDefinition({
|
|
82
|
+
slug: "spreadsheet-url",
|
|
83
|
+
name: "Google Spreadsheet URL",
|
|
84
|
+
description: "The URL of the Google Spreadsheet (e.g., https://docs.google.com/spreadsheets/d/xxxxx/edit). The spreadsheet ID is automatically extracted from the URL.",
|
|
85
|
+
envVarBaseKey: "GOOGLE_SHEETS_SPREADSHEET_URL",
|
|
64
86
|
type: "text",
|
|
65
87
|
secret: false,
|
|
66
88
|
required: false
|
|
@@ -68,6 +90,7 @@ var parameters = {
|
|
|
68
90
|
};
|
|
69
91
|
|
|
70
92
|
// ../connectors/src/connectors/google-sheets/sdk/index.ts
|
|
93
|
+
init_utils();
|
|
71
94
|
var TOKEN_URL = "https://oauth2.googleapis.com/token";
|
|
72
95
|
var BASE_URL = "https://sheets.googleapis.com/v4/spreadsheets";
|
|
73
96
|
var SCOPE = "https://www.googleapis.com/auth/spreadsheets.readonly";
|
|
@@ -95,7 +118,8 @@ function buildJwt(clientEmail, privateKey, nowSec) {
|
|
|
95
118
|
}
|
|
96
119
|
function createClient(params) {
|
|
97
120
|
const serviceAccountKeyJsonBase64 = params[parameters.serviceAccountKeyJsonBase64.slug];
|
|
98
|
-
const
|
|
121
|
+
const spreadsheetUrl = params[parameters.spreadsheetUrl.slug];
|
|
122
|
+
const defaultSpreadsheetId = spreadsheetUrl ? extractSpreadsheetId(spreadsheetUrl) : void 0;
|
|
99
123
|
if (!serviceAccountKeyJsonBase64) {
|
|
100
124
|
throw new Error(
|
|
101
125
|
`google-sheets: missing required parameter: ${parameters.serviceAccountKeyJsonBase64.slug}`
|
|
@@ -335,6 +359,7 @@ var googleSheetsOnboarding = new ConnectorOnboarding({
|
|
|
335
359
|
|
|
336
360
|
// ../connectors/src/connectors/google-sheets/tools/request.ts
|
|
337
361
|
import { z } from "zod";
|
|
362
|
+
init_utils();
|
|
338
363
|
var BASE_URL2 = "https://sheets.googleapis.com/v4/spreadsheets";
|
|
339
364
|
var REQUEST_TIMEOUT_MS = 6e4;
|
|
340
365
|
var inputSchema = z.object({
|
|
@@ -380,7 +405,8 @@ Authentication is handled automatically using a service account.
|
|
|
380
405
|
try {
|
|
381
406
|
const { GoogleAuth } = await import("google-auth-library");
|
|
382
407
|
const keyJsonBase64 = parameters.serviceAccountKeyJsonBase64.getValue(connection2);
|
|
383
|
-
const
|
|
408
|
+
const spreadsheetUrl = parameters.spreadsheetUrl.tryGetValue(connection2);
|
|
409
|
+
const spreadsheetId = spreadsheetUrl ? extractSpreadsheetId(spreadsheetUrl) : void 0;
|
|
384
410
|
const credentials = JSON.parse(
|
|
385
411
|
Buffer.from(keyJsonBase64, "base64").toString("utf-8")
|
|
386
412
|
);
|