@squadbase/vite-server 0.1.7-dev.2 → 0.1.7-dev.4

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.
@@ -45,31 +45,28 @@ var ParameterDefinition = class {
45
45
  // ../connectors/src/connectors/google-sheets/sdk/index.ts
46
46
  var SHEETS_BASE_URL = "https://sheets.googleapis.com/v4/spreadsheets";
47
47
  function createClient(_params, fetchFn = fetch) {
48
- function request(path2, init) {
49
- const url = `${SHEETS_BASE_URL}${path2 === "" || path2.startsWith("/") ? "" : "/"}${path2}`;
50
- return fetchFn(url, init);
48
+ function buildUrl(path2) {
49
+ return `${SHEETS_BASE_URL}${path2 === "" || path2.startsWith("/") ? "" : "/"}${path2}`;
51
50
  }
52
- async function getSpreadsheet(spreadsheetId) {
53
- const url = `${SHEETS_BASE_URL}/${spreadsheetId}?fields=spreadsheetId,properties,sheets.properties`;
54
- const response = await fetchFn(url);
51
+ async function request(path2, init) {
52
+ return fetchFn(buildUrl(path2), init);
53
+ }
54
+ async function asJson(response, operation) {
55
55
  if (!response.ok) {
56
56
  const body = await response.text();
57
57
  throw new Error(
58
- `google-sheets: getSpreadsheet failed (${response.status}): ${body}`
58
+ `google-sheets: ${operation} failed (${response.status}): ${body}`
59
59
  );
60
60
  }
61
61
  return await response.json();
62
62
  }
63
+ async function getSpreadsheet(spreadsheetId) {
64
+ const url = `${SHEETS_BASE_URL}/${spreadsheetId}?fields=spreadsheetId,properties,sheets.properties`;
65
+ return asJson(await fetchFn(url), "getSpreadsheet");
66
+ }
63
67
  async function getValues(spreadsheetId, range) {
64
68
  const url = `${SHEETS_BASE_URL}/${spreadsheetId}/values/${encodeURIComponent(range)}`;
65
- const response = await fetchFn(url);
66
- if (!response.ok) {
67
- const body = await response.text();
68
- throw new Error(
69
- `google-sheets: getValues failed (${response.status}): ${body}`
70
- );
71
- }
72
- return await response.json();
69
+ return asJson(await fetchFn(url), "getValues");
73
70
  }
74
71
  async function batchGetValues(spreadsheetId, ranges) {
75
72
  const searchParams = new URLSearchParams();
@@ -77,20 +74,53 @@ function createClient(_params, fetchFn = fetch) {
77
74
  searchParams.append("ranges", range);
78
75
  }
79
76
  const url = `${SHEETS_BASE_URL}/${spreadsheetId}/values:batchGet?${searchParams.toString()}`;
80
- const response = await fetchFn(url);
81
- if (!response.ok) {
82
- const body = await response.text();
83
- throw new Error(
84
- `google-sheets: batchGetValues failed (${response.status}): ${body}`
85
- );
86
- }
87
- return await response.json();
77
+ return asJson(await fetchFn(url), "batchGetValues");
78
+ }
79
+ async function updateValues(spreadsheetId, range, values, valueInputOption = "USER_ENTERED") {
80
+ const url = `${SHEETS_BASE_URL}/${spreadsheetId}/values/${encodeURIComponent(range)}?valueInputOption=${valueInputOption}`;
81
+ const response = await fetchFn(url, {
82
+ method: "PUT",
83
+ headers: { "Content-Type": "application/json" },
84
+ body: JSON.stringify({ range, majorDimension: "ROWS", values })
85
+ });
86
+ return asJson(response, "updateValues");
87
+ }
88
+ async function appendValues(spreadsheetId, range, values, valueInputOption = "USER_ENTERED") {
89
+ const url = `${SHEETS_BASE_URL}/${spreadsheetId}/values/${encodeURIComponent(range)}:append?valueInputOption=${valueInputOption}`;
90
+ const response = await fetchFn(url, {
91
+ method: "POST",
92
+ headers: { "Content-Type": "application/json" },
93
+ body: JSON.stringify({ range, majorDimension: "ROWS", values })
94
+ });
95
+ return asJson(response, "appendValues");
96
+ }
97
+ async function clearValues(spreadsheetId, range) {
98
+ const url = `${SHEETS_BASE_URL}/${spreadsheetId}/values/${encodeURIComponent(range)}:clear`;
99
+ const response = await fetchFn(url, {
100
+ method: "POST",
101
+ headers: { "Content-Type": "application/json" },
102
+ body: JSON.stringify({})
103
+ });
104
+ return asJson(response, "clearValues");
105
+ }
106
+ async function batchUpdate(spreadsheetId, requests) {
107
+ const url = `${SHEETS_BASE_URL}/${spreadsheetId}:batchUpdate`;
108
+ const response = await fetchFn(url, {
109
+ method: "POST",
110
+ headers: { "Content-Type": "application/json" },
111
+ body: JSON.stringify({ requests })
112
+ });
113
+ return asJson(response, "batchUpdate");
88
114
  }
89
115
  return {
90
116
  request,
91
117
  getSpreadsheet,
92
118
  getValues,
93
- batchGetValues
119
+ batchGetValues,
120
+ updateValues,
121
+ appendValues,
122
+ clearValues,
123
+ batchUpdate
94
124
  };
95
125
  }
96
126
 
@@ -281,11 +311,16 @@ var inputSchema = z.object({
281
311
  "Brief description of what you intend to accomplish with this tool call"
282
312
  ),
283
313
  connectionId: z.string().describe("ID of the Google Sheets connection to use"),
284
- method: z.enum(["GET"]).describe("HTTP method. Only GET is supported (read-only analysis)."),
314
+ method: z.enum(["GET", "POST", "PUT"]).describe(
315
+ "HTTP method. GET for reads, PUT for values.update, POST for values.append / values:batchUpdate / values:batchGet / values:clear / values:batchClear."
316
+ ),
285
317
  path: z.string().describe(
286
- "API path appended to https://sheets.googleapis.com/v4/spreadsheets (e.g., '/{spreadsheetId}', '/{spreadsheetId}/values/Sheet1!A1:D10'). The `{spreadsheetId}` placeholder is automatically replaced with the connection's configured spreadsheet ID."
318
+ "API path appended to https://sheets.googleapis.com/v4/spreadsheets. The caller must provide the target spreadsheetId explicitly in the path (e.g., '/1AbCxyz...', '/1AbCxyz.../values/Sheet1!A1:D10')."
287
319
  ),
288
- queryParams: z.record(z.string(), z.string()).optional().describe("Query parameters to append to the URL")
320
+ queryParams: z.record(z.string(), z.string()).optional().describe("Query parameters to append to the URL"),
321
+ body: z.unknown().optional().describe(
322
+ "Request body for POST/PUT. Will be JSON-serialized. Omit for GET."
323
+ )
289
324
  });
290
325
  var outputSchema = z.discriminatedUnion("success", [
291
326
  z.object({
@@ -300,12 +335,13 @@ var outputSchema = z.discriminatedUnion("success", [
300
335
  ]);
301
336
  var requestTool = new ConnectorTool({
302
337
  name: "request",
303
- description: `Send authenticated GET requests to the Google Sheets API v4 for read-only analysis.
304
- The \`{spreadsheetId}\` placeholder in the path is automatically replaced with the connection's configured spreadsheet ID.
338
+ description: `Send authenticated requests to the Google Sheets API v4.
339
+ Supports GET (read) and POST/PUT (write: update/append/batchUpdate/clear).
340
+ The caller must include the target spreadsheetId in the path explicitly.
305
341
  Authentication is handled automatically via OAuth proxy.`,
306
342
  inputSchema,
307
343
  outputSchema,
308
- async execute({ connectionId, method, path: path2, queryParams }, connections, config) {
344
+ async execute({ connectionId, method, path: path2, queryParams, body }, connections, config) {
309
345
  const connection2 = connections.find((c) => c.id === connectionId);
310
346
  if (!connection2) {
311
347
  return {
@@ -327,16 +363,17 @@ Authentication is handled automatically via OAuth proxy.`,
327
363
  const controller = new AbortController();
328
364
  const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
329
365
  try {
366
+ const proxyBody = { url, method };
367
+ if (body !== void 0 && method !== "GET") {
368
+ proxyBody.body = body;
369
+ }
330
370
  const response = await fetch(proxyUrl, {
331
371
  method: "POST",
332
372
  headers: {
333
373
  "Content-Type": "application/json",
334
374
  Authorization: `Bearer ${token}`
335
375
  },
336
- body: JSON.stringify({
337
- url,
338
- method
339
- }),
376
+ body: JSON.stringify(proxyBody),
340
377
  signal: controller.signal
341
378
  });
342
379
  const data = await response.json();
@@ -359,52 +396,50 @@ Authentication is handled automatically via OAuth proxy.`,
359
396
  var requestToolName = `google-sheets-oauth_${requestTool.name}`;
360
397
  var googleSheetsOnboarding = new ConnectorOnboarding({
361
398
  connectionSetupInstructions: {
362
- ja: `\u4EE5\u4E0B\u306E\u624B\u9806\u3067Google Sheets (OAuth) \u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002\u5206\u6790\u5BFE\u8C61\u306E\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306F\u30E6\u30FC\u30B6\u30FC\u304B\u3089\u53D7\u3051\u53D6\u3063\u305FURL\u3067\u6307\u5B9A\u3057\u307E\u3059\uFF08\u65B0\u3057\u3044\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306F\u4F5C\u6210\u3057\u307E\u305B\u3093\uFF09\u3002
399
+ ja: `\u4EE5\u4E0B\u306E\u624B\u9806\u3067Google Sheets (OAuth) \u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002\u3053\u306E\u30B3\u30CD\u30AF\u30BF\u306F\u8AAD\u307F\u66F8\u304D\u53EF\u80FD\u306A\u30B9\u30B3\u30FC\u30D7 (\`spreadsheets\`) \u3067\u63A5\u7D9A\u3055\u308C\u3001OAuth\u8A8D\u8A3C\u3057\u305FGoogle\u30A2\u30AB\u30A6\u30F3\u30C8\u304C\u6A29\u9650\u3092\u6301\u3064\u4EFB\u610F\u306E\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306B\u5BFE\u3057\u3066\u8AAD\u307F\u66F8\u304D\u3067\u304D\u307E\u3059\u3002
363
400
 
364
- 1. \`askUserQuestion\` \u3067\u5206\u6790\u5BFE\u8C61\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306EURL\u3092\u30D2\u30A2\u30EA\u30F3\u30B0\u3059\u308B:
401
+ 1. \`askUserQuestion\` \u3067\u64CD\u4F5C\u5BFE\u8C61\u306E\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8URL\u3092\u30D2\u30A2\u30EA\u30F3\u30B0\u3059\u308B:
365
402
  - \`type\`: \`"freeText"\`
366
- - \`question\`: \u300C\u5206\u6790\u3057\u305F\u3044Google Sheets\u306EURL\u3092\u8CBC\u308A\u4ED8\u3051\u3066\u304F\u3060\u3055\u3044\u300D
403
+ - \`question\`: \u300C\u64CD\u4F5C\u3057\u305F\u3044Google Sheets\u306EURL\u3092\u8CBC\u308A\u4ED8\u3051\u3066\u304F\u3060\u3055\u3044\uFF08\u8AAD\u307F\u53D6\u308A\u30FB\u7DE8\u96C6\u3069\u3061\u3089\u3082\u53EF\u80FD\u3067\u3059\uFF09\u300D
367
404
  - \`placeholder\`: \`"https://docs.google.com/spreadsheets/d/.../edit"\`
368
405
  2. \u53D7\u3051\u53D6\u3063\u305FURL\u304B\u3089\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8ID\u3092\u62BD\u51FA\u3059\u308B\u3002URL\u306E \`/d/\` \u3068 \`/edit\`\uFF08\u307E\u305F\u306F\u672B\u5C3E\uFF09\u306E\u9593\u306B\u3042\u308B\u6587\u5B57\u5217\u304C\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8ID\u3067\u3059\uFF08\u4F8B: \`https://docs.google.com/spreadsheets/d/1AbCxyz.../edit\` \u2192 \`1AbCxyz...\`\uFF09\u3002URL\u3067\u306F\u306A\u304FID\u3060\u3051\u304C\u6E21\u3055\u308C\u305F\u5834\u5408\u306F\u305D\u306E\u307E\u307E\u5229\u7528\u3057\u307E\u3059\u3002
369
- 3. \u62BD\u51FA\u3057\u305FID\u3092 \`updateConnectionParameters\` \u3067\u4FDD\u5B58\u3059\u308B:
370
- - \`parameterSlug\`: \`"spreadsheet-id"\`
371
- - \`options\`: \`[{ value: <\u62BD\u51FA\u3057\u305FID>, label: <\u540C\u3058\u5024> }]\`\uFF081\u4EF6\u306E\u307F\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u81EA\u52D5\u9078\u629E\u3055\u308C\u308B\uFF09
372
- 4. \`${requestToolName}\` \u3067\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306B\u30A2\u30AF\u30BB\u30B9\u3067\u304D\u308B\u3053\u3068\u3092\u78BA\u8A8D\u3059\u308B:
406
+ 3. \`${requestToolName}\` \u3067\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u6027\u3092\u78BA\u8A8D\u3059\u308B:
373
407
  - \`method\`: \`"GET"\`
374
- - \`path\`: \`"/{spreadsheetId}"\`
375
- 5. \u30A8\u30E9\u30FC\u304C\u8FD4\u3055\u308C\u305F\u5834\u5408\u3001\u4EE5\u4E0B\u3092\u78BA\u8A8D\u3059\u308B\u3088\u3046\u30E6\u30FC\u30B6\u30FC\u306B\u4F1D\u3048\u308B:
376
- - OAuth\u3067\u63A5\u7D9A\u3057\u305FGoogle\u30A2\u30AB\u30A6\u30F3\u30C8\u304C\u305D\u306E\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306B\u95B2\u89A7\u6A29\u9650\u3092\u6301\u3063\u3066\u3044\u308B\u304B
377
- - \u5165\u529B\u3055\u308C\u305FURL\u304C\u6B63\u3057\u3044\u304B
408
+ - \`path\`: \`"/<\u62BD\u51FA\u3057\u305FspreadsheetId>"\`
409
+ 4. **\u691C\u8A3C\u5931\u6557\u6642\u306E\u518D\u30D2\u30A2\u30EA\u30F3\u30B0**: \u30B9\u30C6\u30C3\u30D73\u304C \`success: false\` \u3092\u8FD4\u3057\u305F\u5834\u5408\uFF08404/403/\u898B\u3064\u304B\u3089\u306A\u3044\u7B49\uFF09\u3001\u4EE5\u4E0B\u306E\u624B\u9806\u3067\u518D\u8A66\u884C\u3059\u308B:
410
+ a. \u30E6\u30FC\u30B6\u30FC\u306B\u539F\u56E0\u306E\u53EF\u80FD\u6027\u3092\u4F1D\u3048\u308B\uFF08URL\u304C\u9593\u9055\u3063\u3066\u3044\u308B\u3001OAuth\u9023\u643A\u3057\u305FGoogle\u30A2\u30AB\u30A6\u30F3\u30C8\u306B\u30A2\u30AF\u30BB\u30B9\u6A29\u9650\u304C\u306A\u3044\u3001\u30D7\u30E9\u30A4\u30D9\u30FC\u30C8\u30B7\u30FC\u30C8\u3067\u5225\u30A2\u30AB\u30A6\u30F3\u30C8\u3068\u5171\u6709\u3055\u308C\u3066\u3044\u308B \u7B49\uFF09
411
+ b. \`askUserQuestion\` \u3067\u3082\u3046\u4E00\u5EA6URL\u3092\u805E\u304D\u76F4\u3057\u3001\u518D\u5EA6 \`${requestToolName}\` \u3067\u691C\u8A3C
412
+ c. \u6210\u529F\u3059\u308B\u307E\u3067\uFF08\u307E\u305F\u306F\u30E6\u30FC\u30B6\u30FC\u304C\u4E2D\u65AD\u3059\u308B\u307E\u3067\uFF09\u3053\u306E\u30EB\u30FC\u30D7\u3092\u7E70\u308A\u8FD4\u3059
378
413
 
379
414
  #### \u5236\u7D04
380
- - **\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u4E2D\u306B\u30BB\u30EB\u5024\u3092\u5927\u91CF\u306B\u53D6\u5F97\u3057\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\u306E\u307F
415
+ - **\u63A5\u7D9A\u8A2D\u5B9A\u4E2D\u306F\u5927\u91CF\u306E\u30BB\u30EB\u5024\u3092\u53D6\u5F97\u3057\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\u306E\u307F
416
+ - **\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8ID\u3092\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u30D1\u30E9\u30E1\u30FC\u30BF\u3068\u3057\u3066\u4FDD\u5B58\u3057\u306A\u3044**\u3002\u30CF\u30F3\u30C9\u30E9\u5074\u306E\u30B3\u30FC\u30C9\uFF08\`server-logic\`\uFF09\u306B\u5BFE\u8C61\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8ID\u3092\u76F4\u63A5\u6E21\u3059\u8A2D\u8A08\u306B\u306A\u3063\u3066\u3044\u308B\u305F\u3081\u3001\`updateConnectionParameters\` \u306F\u547C\u3070\u306A\u3044\u3053\u3068
381
417
  - \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`,
382
- en: `Follow these steps to set up the Google Sheets (OAuth) connection. The spreadsheet to analyze is specified by the URL provided by the user (no new spreadsheet is created).
418
+ en: `Follow these steps to set up the Google Sheets (OAuth) connection. This connector uses the read/write \`spreadsheets\` scope, so it can read and edit any spreadsheet the authenticated Google account has access to.
383
419
 
384
- 1. Call \`askUserQuestion\` to ask for the spreadsheet URL to analyze:
420
+ 1. Call \`askUserQuestion\` to ask for the spreadsheet URL the user wants to work with:
385
421
  - \`type\`: \`"freeText"\`
386
- - \`question\`: "Please paste the URL of the Google Sheet you want to analyze"
422
+ - \`question\`: "Please paste the URL of the Google Sheet you want to work with (both read and edit are supported)."
387
423
  - \`placeholder\`: \`"https://docs.google.com/spreadsheets/d/.../edit"\`
388
424
  2. Extract the spreadsheet ID from the URL. It is the segment between \`/d/\` and \`/edit\` (or the end of the URL), e.g. \`https://docs.google.com/spreadsheets/d/1AbCxyz.../edit\` \u2192 \`1AbCxyz...\`. If the user pasted just the ID, use it as-is.
389
- 3. Save the extracted ID via \`updateConnectionParameters\`:
390
- - \`parameterSlug\`: \`"spreadsheet-id"\`
391
- - \`options\`: \`[{ value: <extracted ID>, label: <same value> }]\` (a single option is auto-selected)
392
- 4. Verify access by calling \`${requestToolName}\`:
425
+ 3. Verify accessibility by calling \`${requestToolName}\`:
393
426
  - \`method\`: \`"GET"\`
394
- - \`path\`: \`"/{spreadsheetId}"\`
395
- 5. If an error is returned, ask the user to verify:
396
- - The OAuthed Google account has read access to the spreadsheet
397
- - The URL they entered is correct
427
+ - \`path\`: \`"/<extracted spreadsheetId>"\`
428
+ 4. **Retry on verification failure**: If step 3 returns \`success: false\` (404/403/not found or any other error):
429
+ a. Tell the user the likely causes (wrong URL, OAuth-connected Google account lacks access, private sheet shared with a different account, etc.)
430
+ b. Call \`askUserQuestion\` again to re-ask for the URL and re-verify with \`${requestToolName}\`
431
+ c. Repeat until verification succeeds (or the user aborts)
398
432
 
399
433
  #### Constraints
400
- - **Do NOT read large amounts of cell data during setup**. Only the metadata request specified above is allowed
401
- - Write only 1 sentence between tool calls, then immediately call the next tool. Skip unnecessary explanations and proceed efficiently`
434
+ - **Do NOT fetch large amounts of cell data during setup**. Only the metadata request specified above is allowed.
435
+ - **Do NOT persist the spreadsheet ID as a connection parameter.** The handler-side code (\`server-logic\`) is designed to receive the target spreadsheet ID directly, so do NOT call \`updateConnectionParameters\`.
436
+ - Write only 1 sentence between tool calls, then immediately call the next tool. Skip unnecessary explanations and proceed efficiently.`
402
437
  },
403
438
  dataOverviewInstructions: {
404
- en: `1. Call ${requestToolName} with GET /{spreadsheetId} to fetch spreadsheet metadata (sheet names, grid properties)
405
- 2. For each sheet of interest, call ${requestToolName} with GET /{spreadsheetId}/values/{SheetName}!A1:Z5 to sample the first rows and understand the column layout`,
406
- ja: `1. ${requestToolName} \u3067 GET /{spreadsheetId} \u3092\u547C\u3073\u51FA\u3057\u3001\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\uFF08\u30B7\u30FC\u30C8\u540D\u3001\u30B0\u30EA\u30C3\u30C9\u30D7\u30ED\u30D1\u30C6\u30A3\uFF09\u3092\u53D6\u5F97
407
- 2. \u4E3B\u8981\u306A\u30B7\u30FC\u30C8\u306B\u3064\u3044\u3066 ${requestToolName} \u3067 GET /{spreadsheetId}/values/{\u30B7\u30FC\u30C8\u540D}!A1:Z5 \u3092\u547C\u3073\u51FA\u3057\u3001\u5148\u982D\u6570\u884C\u3092\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0\u3057\u3066\u30AB\u30E9\u30E0\u69CB\u9020\u3092\u628A\u63E1`
439
+ en: `1. Call ${requestToolName} with GET /<spreadsheetId> to fetch spreadsheet metadata (sheet names, grid properties)
440
+ 2. For each sheet of interest, call ${requestToolName} with GET /<spreadsheetId>/values/<SheetName>!A1:Z5 to sample the first rows and understand the column layout`,
441
+ ja: `1. ${requestToolName} \u3067 GET /<spreadsheetId> \u3092\u547C\u3073\u51FA\u3057\u3001\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\uFF08\u30B7\u30FC\u30C8\u540D\u3001\u30B0\u30EA\u30C3\u30C9\u30D7\u30ED\u30D1\u30C6\u30A3\uFF09\u3092\u53D6\u5F97
442
+ 2. \u4E3B\u8981\u306A\u30B7\u30FC\u30C8\u306B\u3064\u3044\u3066 ${requestToolName} \u3067 GET /<spreadsheetId>/values/<\u30B7\u30FC\u30C8\u540D>!A1:Z5 \u3092\u547C\u3073\u51FA\u3057\u3001\u5148\u982D\u6570\u884C\u3092\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0\u3057\u3066\u30AB\u30E9\u30E0\u69CB\u9020\u3092\u628A\u63E1`
408
443
  }
409
444
  });
410
445
 
@@ -427,7 +462,7 @@ var googleSheetsConnector = new ConnectorPlugin({
427
462
  slug: "google-sheets",
428
463
  authType: AUTH_TYPES.OAUTH,
429
464
  name: "Google Sheets",
430
- description: "Connect to an existing Google Sheets spreadsheet for read-only data analysis using OAuth.",
465
+ description: "Connect to Google Sheets for read/write access via OAuth. Any spreadsheet the authenticated Google account can access is supported \u2014 the target spreadsheetId is passed per call.",
431
466
  iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/1UPQuggyiZmbb26CuaSr2h/032770e8739b183fa00b7625f024e536/google-sheets.svg",
432
467
  parameters,
433
468
  releaseFlag: { dev1: true, dev2: false, prod: false },
@@ -436,25 +471,33 @@ var googleSheetsConnector = new ConnectorPlugin({
436
471
  allowlist: [
437
472
  {
438
473
  host: "sheets.googleapis.com",
439
- methods: ["GET"]
474
+ methods: ["GET", "POST", "PUT"]
440
475
  }
441
476
  ]
442
477
  },
443
478
  systemPrompt: {
444
479
  en: `### Tools (setup-time only)
445
480
 
446
- - \`google-sheets-oauth_request\`: Call the Google Sheets API during setup / data overview. Read-only (GET only). Use it to fetch spreadsheet metadata and sample cell values. The \`{spreadsheetId}\` placeholder in the path is automatically replaced with the spreadsheet configured at setup time. Authentication is configured automatically via OAuth.
481
+ - \`google-sheets-oauth_request\`: Call the Google Sheets API during setup / data overview. Supports GET, POST, and PUT. The caller must include the target spreadsheetId in the path explicitly (e.g., \`/1AbCxyz...\`, \`/1AbCxyz.../values/Sheet1!A1:D10\`). Authentication is configured automatically via OAuth.
447
482
 
448
- > **Important**: The \`google-sheets-oauth_request\` tool is only available at setup time. Inside server-logic handlers, use the SDK (\`connection(id).getValues\`, etc.) \u2014 the SDK's fetch is already wired through the OAuth proxy. **Do NOT** hand-roll HTTP calls to \`_sqcore/connections/*/request\` from a handler.
483
+ > **Important**: The \`google-sheets-oauth_request\` tool is only available at setup time. Inside server-logic handlers, use the SDK (\`connection(id).getValues(spreadsheetId, range)\`, etc.) \u2014 the SDK's fetch is already wired through the OAuth proxy. **Do NOT** hand-roll HTTP calls to \`_sqcore/connections/*/request\` from a handler.
449
484
 
450
- > **Connection scope**: Each connection is bound to a single spreadsheet selected at setup time via URL. This connector does NOT create new spreadsheets and does NOT write to spreadsheets. The OAuth scope is \`spreadsheets.readonly\`.
485
+ > **Connection scope**: The OAuth scope is \`spreadsheets\` (read/write). A connection is NOT bound to a single spreadsheet \u2014 the target spreadsheetId is passed per call. The spreadsheetId is NOT stored as a connection parameter or environment variable; pass it explicitly from the caller (e.g., as a query param or request input to the handler).
451
486
 
452
- ### Google Sheets API Reference (read-only)
487
+ ### Google Sheets API Reference
453
488
 
489
+ Reads:
454
490
  - GET \`/{spreadsheetId}\` \u2014 Get spreadsheet metadata (title, sheets, properties)
455
491
  - GET \`/{spreadsheetId}/values/{range}\` \u2014 Get cell values for a range
456
492
  - GET \`/{spreadsheetId}/values:batchGet?ranges={range1}&ranges={range2}\` \u2014 Get values for multiple ranges
457
493
 
494
+ Writes:
495
+ - PUT \`/{spreadsheetId}/values/{range}?valueInputOption=USER_ENTERED\` \u2014 Overwrite a range (body: \`{ range, majorDimension, values }\`)
496
+ - POST \`/{spreadsheetId}/values/{range}:append?valueInputOption=USER_ENTERED\` \u2014 Append rows after the existing data
497
+ - POST \`/{spreadsheetId}/values/{range}:clear\` \u2014 Clear values in a range
498
+ - POST \`/{spreadsheetId}/values:batchUpdate\` \u2014 Batch update / batch clear
499
+ - POST \`/{spreadsheetId}:batchUpdate\` \u2014 Structural edits (addSheet, deleteSheet, updateCells, formatting, \u2026)
500
+
458
501
  ### Range Notation (A1 notation)
459
502
  - \`Sheet1!A1:D10\` \u2014 Specific range on Sheet1
460
503
  - \`Sheet1!A:A\` \u2014 Entire column A on Sheet1
@@ -464,20 +507,24 @@ var googleSheetsConnector = new ConnectorPlugin({
464
507
 
465
508
  ### Tips
466
509
  - To explore a spreadsheet, first get metadata to see available sheet names
510
+ - Use \`valueInputOption=USER_ENTERED\` to parse formulas/dates like the UI; use \`RAW\` to store inputs literally
467
511
  - Use \`valueRenderOption=FORMATTED_VALUE\` query param to get display values
468
512
  - Use \`valueRenderOption=UNFORMATTED_VALUE\` for raw numeric values
469
513
  - Use \`majorDimension=COLUMNS\` to get data organized by columns instead of rows
470
514
 
471
515
  ### Business Logic
472
516
 
473
- 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 and do NOT read \`INTERNAL_SQUADBASE_*\` env vars \u2014 the SDK takes care of OAuth. The spreadsheet ID is bound to the connection at setup time; do NOT ask handler callers to pass it.
517
+ 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 and do NOT read \`INTERNAL_SQUADBASE_*\` env vars \u2014 the SDK takes care of OAuth. The target spreadsheetId is NOT stored on the connection \u2014 the handler caller must pass it (as part of the request input).
474
518
 
475
519
  SDK surface (client created via \`connection(connectionId)\`):
476
- - \`client.spreadsheetId\` \u2014 the spreadsheet ID configured for this connection.
477
- - \`client.request(path, init?)\` \u2014 low-level authenticated fetch (\`path\` is appended to \`https://sheets.googleapis.com/v4/spreadsheets\`; \`{spreadsheetId}\` is auto-replaced).
478
- - \`client.getSpreadsheet()\` \u2014 fetch spreadsheet metadata for the configured spreadsheet.
479
- - \`client.getValues(range)\` \u2014 read a range (A1 notation) from the configured spreadsheet.
480
- - \`client.batchGetValues(ranges)\` \u2014 read multiple ranges from the configured spreadsheet.
520
+ - \`client.request(path, init?)\` \u2014 low-level authenticated fetch (\`path\` is appended to \`https://sheets.googleapis.com/v4/spreadsheets\`; the caller must include the target spreadsheetId).
521
+ - \`client.getSpreadsheet(spreadsheetId)\` \u2014 fetch spreadsheet metadata.
522
+ - \`client.getValues(spreadsheetId, range)\` \u2014 read a range (A1 notation).
523
+ - \`client.batchGetValues(spreadsheetId, ranges)\` \u2014 read multiple ranges.
524
+ - \`client.updateValues(spreadsheetId, range, values, valueInputOption?)\` \u2014 overwrite a range (requires write scope).
525
+ - \`client.appendValues(spreadsheetId, range, values, valueInputOption?)\` \u2014 append rows (requires write scope).
526
+ - \`client.clearValues(spreadsheetId, range)\` \u2014 clear a range (requires write scope).
527
+ - \`client.batchUpdate(spreadsheetId, requests)\` \u2014 structural edits (requires write scope).
481
528
 
482
529
  If a handler test fails with \`Connection proxy is not configured\`, retry \u2014 the sandbox is still initializing. Do NOT abandon the SDK and construct OAuth proxy URLs manually.
483
530
 
@@ -487,32 +534,44 @@ If a handler test fails with \`Connection proxy is not configured\`, retry \u201
487
534
  import { connection } from "@squadbase/vite-server/connectors/google-sheets";
488
535
 
489
536
  const sheets = connection("<connectionId>");
537
+ const spreadsheetId = "<passed from request input>";
490
538
 
491
- // Get metadata for the configured spreadsheet
492
- const metadata = await sheets.getSpreadsheet();
493
- console.log(metadata.properties.title, metadata.sheets.map(s => s.properties.title));
539
+ // Read: metadata and values
540
+ const metadata = await sheets.getSpreadsheet(spreadsheetId);
541
+ const values = await sheets.getValues(spreadsheetId, "Sheet1!A1:D10");
494
542
 
495
- // Get cell values
496
- const values = await sheets.getValues("Sheet1!A1:D10");
497
- console.log(values.values); // 2D array
543
+ // Write: overwrite, append, clear
544
+ await sheets.updateValues(spreadsheetId, "Sheet1!A1:B2", [["name", "age"], ["Alice", 30]]);
545
+ await sheets.appendValues(spreadsheetId, "Sheet1!A:B", [["Bob", 25]]);
546
+ await sheets.clearValues(spreadsheetId, "Sheet1!A1:B10");
498
547
 
499
- // Batch-get multiple ranges
500
- const batch = await sheets.batchGetValues(["Sheet1!A:A", "Sheet2!B2:C100"]);
548
+ // Structural edits (add a sheet)
549
+ await sheets.batchUpdate(spreadsheetId, [
550
+ { addSheet: { properties: { title: "NewSheet" } } },
551
+ ]);
501
552
  \`\`\``,
502
553
  ja: `### \u30C4\u30FC\u30EB\uFF08\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u6642\u306E\u307F\uFF09
503
554
 
504
- - \`google-sheets-oauth_request\`: \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3084\u30C7\u30FC\u30BF\u6982\u8981\u628A\u63E1\u6642\u306B Google Sheets API \u3092\u547C\u3073\u51FA\u3059\u30C4\u30FC\u30EB\u3067\u3059\u3002\u8AAD\u307F\u53D6\u308A\u5C02\u7528\uFF08GET \u306E\u307F\uFF09\u3067\u3059\u3002\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\u53D6\u5F97\u3084\u30BB\u30EB\u5024\u306E\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u30D1\u30B9\u5185\u306E \`{spreadsheetId}\` \u30D7\u30EC\u30FC\u30B9\u30DB\u30EB\u30C0\u306F\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u6642\u306B\u6307\u5B9A\u3055\u308C\u305F\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8ID\u306B\u81EA\u52D5\u7684\u306B\u7F6E\u63DB\u3055\u308C\u307E\u3059\u3002OAuth \u7D4C\u7531\u3067\u8A8D\u8A3C\u306F\u81EA\u52D5\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002
555
+ - \`google-sheets-oauth_request\`: \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3084\u30C7\u30FC\u30BF\u6982\u8981\u628A\u63E1\u6642\u306B Google Sheets API \u3092\u547C\u3073\u51FA\u3059\u30C4\u30FC\u30EB\u3067\u3059\u3002GET / POST / PUT \u3092\u30B5\u30DD\u30FC\u30C8\u3057\u307E\u3059\u3002\u547C\u3073\u51FA\u3057\u5074\u304C\u30D1\u30B9\u306B\u5BFE\u8C61\u306E spreadsheetId \u3092\u660E\u793A\u7684\u306B\u542B\u3081\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\uFF08\u4F8B: \`/1AbCxyz...\`\u3001\`/1AbCxyz.../values/Sheet1!A1:D10\`\uFF09\u3002OAuth \u7D4C\u7531\u3067\u8A8D\u8A3C\u306F\u81EA\u52D5\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002
505
556
 
506
- > **\u91CD\u8981**: \`google-sheets-oauth_request\` \u306F\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u6642\u306E\u307F\u5229\u7528\u53EF\u80FD\u3067\u3059\u3002\u30B5\u30FC\u30D0\u30FC\u30ED\u30B8\u30C3\u30AF\u306E\u30CF\u30F3\u30C9\u30E9\u5185\u3067\u306F\u5FC5\u305A SDK\uFF08\`connection(id).getValues\` \u306A\u3069\uFF09\u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044\u3002SDK \u306E fetch \u306F OAuth \u30D7\u30ED\u30AD\u30B7\u7D4C\u7531\u3067\u65E2\u306B\u914D\u7DDA\u3055\u308C\u3066\u3044\u307E\u3059\u3002\u30CF\u30F3\u30C9\u30E9\u304B\u3089 \`_sqcore/connections/*/request\` \u3092\u624B\u66F8\u304D\u3067\u547C\u3073\u51FA\u3055\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
557
+ > **\u91CD\u8981**: \`google-sheets-oauth_request\` \u306F\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u6642\u306E\u307F\u5229\u7528\u53EF\u80FD\u3067\u3059\u3002\u30B5\u30FC\u30D0\u30FC\u30ED\u30B8\u30C3\u30AF\u306E\u30CF\u30F3\u30C9\u30E9\u5185\u3067\u306F\u5FC5\u305A SDK\uFF08\`connection(id).getValues(spreadsheetId, range)\` \u306A\u3069\uFF09\u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044\u3002SDK \u306E fetch \u306F OAuth \u30D7\u30ED\u30AD\u30B7\u7D4C\u7531\u3067\u65E2\u306B\u914D\u7DDA\u3055\u308C\u3066\u3044\u307E\u3059\u3002\u30CF\u30F3\u30C9\u30E9\u304B\u3089 \`_sqcore/connections/*/request\` \u3092\u624B\u66F8\u304D\u3067\u547C\u3073\u51FA\u3055\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
507
558
 
508
- > **\u63A5\u7D9A\u30B9\u30B3\u30FC\u30D7**: \u5404\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306F\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u6642\u306BURL\u3067\u6307\u5B9A\u3055\u308C\u305F1\u3064\u306E\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306B\u7D10\u3065\u304D\u307E\u3059\u3002\u3053\u306E\u30B3\u30CD\u30AF\u30BF\u306F\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306E\u4F5C\u6210\u3084\u66F8\u304D\u8FBC\u307F\u306F\u884C\u3044\u307E\u305B\u3093\u3002OAuth \u30B9\u30B3\u30FC\u30D7\u306F \`spreadsheets.readonly\` \u3067\u3059\u3002
559
+ > **\u63A5\u7D9A\u30B9\u30B3\u30FC\u30D7**: OAuth \u30B9\u30B3\u30FC\u30D7\u306F \`spreadsheets\`\uFF08\u8AAD\u307F\u66F8\u304D\u53EF\u80FD\uFF09\u3067\u3059\u3002\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306F\u5358\u4E00\u306E\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306B\u7D10\u3065\u304D\u307E\u305B\u3093 \u2014 \u5BFE\u8C61\u306E spreadsheetId \u306F\u547C\u3073\u51FA\u3057\u3054\u3068\u306B\u6E21\u3057\u307E\u3059\u3002spreadsheetId \u306F\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u30D1\u30E9\u30E1\u30FC\u30BF\u3084\u74B0\u5883\u5909\u6570\u3068\u3057\u3066\u4FDD\u5B58\u3055\u308C\u306A\u3044\u305F\u3081\u3001\u30CF\u30F3\u30C9\u30E9\u306E\u547C\u3073\u51FA\u3057\u5143\uFF08\u30EA\u30AF\u30A8\u30B9\u30C8\u5165\u529B\u306A\u3069\uFF09\u304B\u3089\u660E\u793A\u7684\u306B\u6E21\u3057\u3066\u304F\u3060\u3055\u3044\u3002
509
560
 
510
- ### Google Sheets API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9\uFF08\u8AAD\u307F\u53D6\u308A\u5C02\u7528\uFF09
561
+ ### Google Sheets API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
511
562
 
563
+ \u8AAD\u307F\u53D6\u308A:
512
564
  - GET \`/{spreadsheetId}\` \u2014 \u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97\uFF08\u30BF\u30A4\u30C8\u30EB\u3001\u30B7\u30FC\u30C8\u3001\u30D7\u30ED\u30D1\u30C6\u30A3\uFF09
513
565
  - GET \`/{spreadsheetId}/values/{range}\` \u2014 \u7BC4\u56F2\u306E\u30BB\u30EB\u5024\u3092\u53D6\u5F97
514
566
  - GET \`/{spreadsheetId}/values:batchGet?ranges={range1}&ranges={range2}\` \u2014 \u8907\u6570\u7BC4\u56F2\u306E\u5024\u3092\u53D6\u5F97
515
567
 
568
+ \u66F8\u304D\u8FBC\u307F:
569
+ - PUT \`/{spreadsheetId}/values/{range}?valueInputOption=USER_ENTERED\` \u2014 \u7BC4\u56F2\u3092\u4E0A\u66F8\u304D\uFF08body: \`{ range, majorDimension, values }\`\uFF09
570
+ - POST \`/{spreadsheetId}/values/{range}:append?valueInputOption=USER_ENTERED\` \u2014 \u65E2\u5B58\u30C7\u30FC\u30BF\u306E\u5F8C\u308D\u306B\u884C\u3092\u8FFD\u8A18
571
+ - POST \`/{spreadsheetId}/values/{range}:clear\` \u2014 \u7BC4\u56F2\u306E\u5024\u3092\u30AF\u30EA\u30A2
572
+ - POST \`/{spreadsheetId}/values:batchUpdate\` \u2014 \u30D0\u30C3\u30C1\u66F4\u65B0 / \u30D0\u30C3\u30C1\u30AF\u30EA\u30A2
573
+ - POST \`/{spreadsheetId}:batchUpdate\` \u2014 \u69CB\u9020\u5909\u66F4\uFF08addSheet, deleteSheet, updateCells, \u66F8\u5F0F\u8A2D\u5B9A \u7B49\uFF09
574
+
516
575
  ### \u7BC4\u56F2\u306E\u8868\u8A18\u6CD5\uFF08A1\u8868\u8A18\u6CD5\uFF09
517
576
  - \`Sheet1!A1:D10\` \u2014 Sheet1\u4E0A\u306E\u7279\u5B9A\u7BC4\u56F2
518
577
  - \`Sheet1!A:A\` \u2014 Sheet1\u306EA\u5217\u5168\u4F53
@@ -522,20 +581,24 @@ const batch = await sheets.batchGetValues(["Sheet1!A:A", "Sheet2!B2:C100"]);
522
581
 
523
582
  ### \u30D2\u30F3\u30C8
524
583
  - \u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u3092\u63A2\u7D22\u3059\u308B\u306B\u306F\u3001\u307E\u305A\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97\u3057\u3066\u5229\u7528\u53EF\u80FD\u306A\u30B7\u30FC\u30C8\u540D\u3092\u78BA\u8A8D\u3057\u307E\u3059
584
+ - \u6570\u5F0F\u3084\u65E5\u4ED8\u3092 UI \u3068\u540C\u3058\u3088\u3046\u306B\u89E3\u91C8\u3055\u305B\u308B\u306B\u306F \`valueInputOption=USER_ENTERED\`\u3001\u305D\u306E\u307E\u307E\u6587\u5B57\u5217\u3068\u3057\u3066\u4FDD\u5B58\u3059\u308B\u306B\u306F \`RAW\` \u3092\u4F7F\u3044\u307E\u3059
525
585
  - \u8868\u793A\u5024\u3092\u53D6\u5F97\u3059\u308B\u306B\u306F \`valueRenderOption=FORMATTED_VALUE\` \u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF\u3092\u4F7F\u7528\u3057\u307E\u3059
526
586
  - \u751F\u306E\u6570\u5024\u3092\u53D6\u5F97\u3059\u308B\u306B\u306F \`valueRenderOption=UNFORMATTED_VALUE\` \u3092\u4F7F\u7528\u3057\u307E\u3059
527
587
  - \u5217\u3054\u3068\u306B\u30C7\u30FC\u30BF\u3092\u53D6\u5F97\u3059\u308B\u306B\u306F \`majorDimension=COLUMNS\` \u3092\u4F7F\u7528\u3057\u307E\u3059
528
588
 
529
589
  ### Business Logic
530
590
 
531
- \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\u30BF SDK \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\`INTERNAL_SQUADBASE_*\` \u306E\u74B0\u5883\u5909\u6570\u3092\u4F7F\u3063\u3066\u624B\u52D5\u3067 OAuth \u30D7\u30ED\u30AD\u30B7\u3092\u53E9\u304F\u3053\u3068\u3082\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044 \u2014 SDK \u304C OAuth \u3092\u51E6\u7406\u3057\u307E\u3059\u3002\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8ID\u306F\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u6642\u306B\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306B\u7D10\u3065\u3051\u3089\u308C\u3066\u3044\u308B\u306E\u3067\u3001\u30CF\u30F3\u30C9\u30E9\u306E\u547C\u3073\u51FA\u3057\u5143\u306B\u6E21\u3055\u305B\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
591
+ \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\u30BF SDK \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\`INTERNAL_SQUADBASE_*\` \u306E\u74B0\u5883\u5909\u6570\u3092\u4F7F\u3063\u3066\u624B\u52D5\u3067 OAuth \u30D7\u30ED\u30AD\u30B7\u3092\u53E9\u304F\u3053\u3068\u3082\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044 \u2014 SDK \u304C OAuth \u3092\u51E6\u7406\u3057\u307E\u3059\u3002\u5BFE\u8C61 spreadsheetId \u306F\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306B\u4FDD\u5B58\u3055\u308C\u306A\u3044\u305F\u3081\u3001\u30CF\u30F3\u30C9\u30E9\u306E\u547C\u3073\u51FA\u3057\u5143\uFF08\u30EA\u30AF\u30A8\u30B9\u30C8\u5165\u529B\u306A\u3069\uFF09\u304B\u3089\u6E21\u3057\u3066\u304F\u3060\u3055\u3044\u3002
532
592
 
533
593
  SDK\uFF08\`connection(connectionId)\` \u3067\u4F5C\u6210\u3057\u305F\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\uFF09:
534
- - \`client.spreadsheetId\` \u2014 \u3053\u306E\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306B\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u308B\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8ID\u3002
535
- - \`client.request(path, init?)\` \u2014 \u4F4E\u30EC\u30D9\u30EB\u306E\u8A8D\u8A3C\u4ED8\u304D fetch\uFF08\`path\` \u306F \`https://sheets.googleapis.com/v4/spreadsheets\` \u306B\u8FFD\u52A0\u3055\u308C\u3001\`{spreadsheetId}\` \u306F\u81EA\u52D5\u7F6E\u63DB\u3055\u308C\u307E\u3059\uFF09\u3002
536
- - \`client.getSpreadsheet()\` \u2014 \u8A2D\u5B9A\u6E08\u307F\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97\u3002
537
- - \`client.getValues(range)\` \u2014 \u8A2D\u5B9A\u6E08\u307F\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306E\u7BC4\u56F2\u306E\u5024\u3092\u53D6\u5F97\uFF08A1 \u8868\u8A18\uFF09\u3002
538
- - \`client.batchGetValues(ranges)\` \u2014 \u8A2D\u5B9A\u6E08\u307F\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306E\u8907\u6570\u7BC4\u56F2\u306E\u5024\u3092\u53D6\u5F97\u3002
594
+ - \`client.request(path, init?)\` \u2014 \u4F4E\u30EC\u30D9\u30EB\u306E\u8A8D\u8A3C\u4ED8\u304D fetch\uFF08\`path\` \u306F \`https://sheets.googleapis.com/v4/spreadsheets\` \u306B\u8FFD\u52A0\u3055\u308C\u3001\u547C\u3073\u51FA\u3057\u5074\u304C spreadsheetId \u3092\u542B\u3081\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\uFF09\u3002
595
+ - \`client.getSpreadsheet(spreadsheetId)\` \u2014 \u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97\u3002
596
+ - \`client.getValues(spreadsheetId, range)\` \u2014 \u7BC4\u56F2\u306E\u5024\u3092\u53D6\u5F97\uFF08A1 \u8868\u8A18\uFF09\u3002
597
+ - \`client.batchGetValues(spreadsheetId, ranges)\` \u2014 \u8907\u6570\u7BC4\u56F2\u306E\u5024\u3092\u53D6\u5F97\u3002
598
+ - \`client.updateValues(spreadsheetId, range, values, valueInputOption?)\` \u2014 \u7BC4\u56F2\u3092\u4E0A\u66F8\u304D\uFF08\u66F8\u304D\u8FBC\u307F\u30B9\u30B3\u30FC\u30D7\u304C\u5FC5\u8981\uFF09\u3002
599
+ - \`client.appendValues(spreadsheetId, range, values, valueInputOption?)\` \u2014 \u884C\u3092\u8FFD\u8A18\uFF08\u66F8\u304D\u8FBC\u307F\u30B9\u30B3\u30FC\u30D7\u304C\u5FC5\u8981\uFF09\u3002
600
+ - \`client.clearValues(spreadsheetId, range)\` \u2014 \u7BC4\u56F2\u306E\u5024\u3092\u30AF\u30EA\u30A2\uFF08\u66F8\u304D\u8FBC\u307F\u30B9\u30B3\u30FC\u30D7\u304C\u5FC5\u8981\uFF09\u3002
601
+ - \`client.batchUpdate(spreadsheetId, requests)\` \u2014 \u69CB\u9020\u5909\u66F4\uFF08\u66F8\u304D\u8FBC\u307F\u30B9\u30B3\u30FC\u30D7\u304C\u5FC5\u8981\uFF09\u3002
539
602
 
540
603
  \u30CF\u30F3\u30C9\u30E9\u306E\u30C6\u30B9\u30C8\u304C \`Connection proxy is not configured\` \u3067\u5931\u6557\u3059\u308B\u5834\u5408\u306F\u518D\u8A66\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u901A\u5E38\u306F\u30B5\u30F3\u30C9\u30DC\u30C3\u30AF\u30B9\u306E\u521D\u671F\u5316\u4E2D\u306B\u8D77\u304D\u307E\u3059\u3002SDK \u3092\u8AE6\u3081\u3066 OAuth \u30D7\u30ED\u30AD\u30B7\u306E URL \u3092\u81EA\u5206\u3067\u7D44\u307F\u7ACB\u3066\u308B\u3053\u3068\u306F **\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044**\u3002
541
604
 
@@ -545,17 +608,21 @@ SDK\uFF08\`connection(connectionId)\` \u3067\u4F5C\u6210\u3057\u305F\u30AF\u30E9
545
608
  import { connection } from "@squadbase/vite-server/connectors/google-sheets";
546
609
 
547
610
  const sheets = connection("<connectionId>");
611
+ const spreadsheetId = "<\u30EA\u30AF\u30A8\u30B9\u30C8\u5165\u529B\u304B\u3089\u53D7\u3051\u53D6\u308B>";
548
612
 
549
- // \u8A2D\u5B9A\u6E08\u307F\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97
550
- const metadata = await sheets.getSpreadsheet();
551
- console.log(metadata.properties.title, metadata.sheets.map(s => s.properties.title));
613
+ // \u8AAD\u307F\u53D6\u308A: \u30E1\u30BF\u30C7\u30FC\u30BF\u3068\u5024
614
+ const metadata = await sheets.getSpreadsheet(spreadsheetId);
615
+ const values = await sheets.getValues(spreadsheetId, "Sheet1!A1:D10");
552
616
 
553
- // \u30BB\u30EB\u5024\u3092\u53D6\u5F97
554
- const values = await sheets.getValues("Sheet1!A1:D10");
555
- console.log(values.values); // 2D array
617
+ // \u66F8\u304D\u8FBC\u307F: \u4E0A\u66F8\u304D\u30FB\u8FFD\u8A18\u30FB\u30AF\u30EA\u30A2
618
+ await sheets.updateValues(spreadsheetId, "Sheet1!A1:B2", [["name", "age"], ["Alice", 30]]);
619
+ await sheets.appendValues(spreadsheetId, "Sheet1!A:B", [["Bob", 25]]);
620
+ await sheets.clearValues(spreadsheetId, "Sheet1!A1:B10");
556
621
 
557
- // \u8907\u6570\u7BC4\u56F2\u3092\u30D0\u30C3\u30C1\u53D6\u5F97
558
- const batch = await sheets.batchGetValues(["Sheet1!A:A", "Sheet2!B2:C100"]);
622
+ // \u69CB\u9020\u5909\u66F4\uFF08\u30B7\u30FC\u30C8\u3092\u8FFD\u52A0\uFF09
623
+ await sheets.batchUpdate(spreadsheetId, [
624
+ { addSheet: { properties: { title: "NewSheet" } } },
625
+ ]);
559
626
  \`\`\``
560
627
  },
561
628
  tools