@squadbase/vite-server 0.1.5-dev.1 → 0.1.7-dev.0

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.
@@ -1,11 +1,75 @@
1
+ // ../connectors/src/parameter-definition.ts
2
+ var ParameterDefinition = class {
3
+ slug;
4
+ name;
5
+ description;
6
+ envVarBaseKey;
7
+ type;
8
+ secret;
9
+ required;
10
+ constructor(config) {
11
+ this.slug = config.slug;
12
+ this.name = config.name;
13
+ this.description = config.description;
14
+ this.envVarBaseKey = config.envVarBaseKey;
15
+ this.type = config.type;
16
+ this.secret = config.secret;
17
+ this.required = config.required;
18
+ }
19
+ /**
20
+ * Get the parameter value from a ConnectorConnectionObject.
21
+ */
22
+ getValue(connection2) {
23
+ const param = connection2.parameters.find(
24
+ (p) => p.parameterSlug === this.slug
25
+ );
26
+ if (!param || param.value == null) {
27
+ throw new Error(
28
+ `Parameter "${this.slug}" not found or has no value in connection "${connection2.id}"`
29
+ );
30
+ }
31
+ return param.value;
32
+ }
33
+ /**
34
+ * Try to get the parameter value. Returns undefined if not found (for optional params).
35
+ */
36
+ tryGetValue(connection2) {
37
+ const param = connection2.parameters.find(
38
+ (p) => p.parameterSlug === this.slug
39
+ );
40
+ if (!param || param.value == null) return void 0;
41
+ return param.value;
42
+ }
43
+ };
44
+
45
+ // ../connectors/src/connectors/google-sheets/parameters.ts
46
+ var parameters = {
47
+ spreadsheetId: new ParameterDefinition({
48
+ slug: "spreadsheet-id",
49
+ name: "Google Sheets Spreadsheet ID",
50
+ description: "The spreadsheet ID from the Google Sheets URL (the segment between /d/ and /edit in https://docs.google.com/spreadsheets/d/{spreadsheetId}/edit).",
51
+ envVarBaseKey: "GOOGLE_SHEETS_SPREADSHEET_ID",
52
+ type: "text",
53
+ secret: false,
54
+ required: true
55
+ })
56
+ };
57
+
1
58
  // ../connectors/src/connectors/google-sheets/sdk/index.ts
2
59
  var SHEETS_BASE_URL = "https://sheets.googleapis.com/v4/spreadsheets";
3
- function createClient(_params, fetchFn = fetch) {
60
+ function createClient(params, fetchFn = fetch) {
61
+ const spreadsheetId = params[parameters.spreadsheetId.slug];
62
+ if (!spreadsheetId) {
63
+ throw new Error(
64
+ `google-sheets: missing required parameter: ${parameters.spreadsheetId.slug}`
65
+ );
66
+ }
4
67
  function request(path2, init) {
5
- const url = `${SHEETS_BASE_URL}${path2 === "" || path2.startsWith("/") ? "" : "/"}${path2}`;
68
+ const resolvedPath = path2.replace(/\{spreadsheetId\}/g, spreadsheetId);
69
+ const url = `${SHEETS_BASE_URL}${resolvedPath === "" || resolvedPath.startsWith("/") ? "" : "/"}${resolvedPath}`;
6
70
  return fetchFn(url, init);
7
71
  }
8
- async function getSpreadsheet(spreadsheetId) {
72
+ async function getSpreadsheet() {
9
73
  const url = `${SHEETS_BASE_URL}/${spreadsheetId}?fields=spreadsheetId,properties,sheets.properties`;
10
74
  const response = await fetchFn(url);
11
75
  if (!response.ok) {
@@ -16,7 +80,7 @@ function createClient(_params, fetchFn = fetch) {
16
80
  }
17
81
  return await response.json();
18
82
  }
19
- async function getValues(spreadsheetId, range) {
83
+ async function getValues(range) {
20
84
  const url = `${SHEETS_BASE_URL}/${spreadsheetId}/values/${encodeURIComponent(range)}`;
21
85
  const response = await fetchFn(url);
22
86
  if (!response.ok) {
@@ -27,7 +91,7 @@ function createClient(_params, fetchFn = fetch) {
27
91
  }
28
92
  return await response.json();
29
93
  }
30
- async function batchGetValues(spreadsheetId, ranges) {
94
+ async function batchGetValues(ranges) {
31
95
  const searchParams = new URLSearchParams();
32
96
  for (const range of ranges) {
33
97
  searchParams.append("ranges", range);
@@ -42,63 +106,12 @@ function createClient(_params, fetchFn = fetch) {
42
106
  }
43
107
  return await response.json();
44
108
  }
45
- async function updateValues(spreadsheetId, range, values) {
46
- const url = `${SHEETS_BASE_URL}/${spreadsheetId}/values/${encodeURIComponent(range)}?valueInputOption=USER_ENTERED`;
47
- const response = await fetchFn(url, {
48
- method: "PUT",
49
- headers: { "Content-Type": "application/json" },
50
- body: JSON.stringify({ range, majorDimension: "ROWS", values })
51
- });
52
- if (!response.ok) {
53
- const body = await response.text();
54
- throw new Error(
55
- `google-sheets: updateValues failed (${response.status}): ${body}`
56
- );
57
- }
58
- return await response.json();
59
- }
60
- async function appendValues(spreadsheetId, range, values) {
61
- const url = `${SHEETS_BASE_URL}/${spreadsheetId}/values/${encodeURIComponent(range)}:append?valueInputOption=USER_ENTERED&insertDataOption=INSERT_ROWS`;
62
- const response = await fetchFn(url, {
63
- method: "POST",
64
- headers: { "Content-Type": "application/json" },
65
- body: JSON.stringify({ range, majorDimension: "ROWS", values })
66
- });
67
- if (!response.ok) {
68
- const body = await response.text();
69
- throw new Error(
70
- `google-sheets: appendValues failed (${response.status}): ${body}`
71
- );
72
- }
73
- return await response.json();
74
- }
75
- async function createSpreadsheet(title, sheetTitles) {
76
- const sheets = sheetTitles && sheetTitles.length > 0 ? sheetTitles.map((t) => ({ properties: { title: t } })) : void 0;
77
- const url = `${SHEETS_BASE_URL}`;
78
- const response = await fetchFn(url, {
79
- method: "POST",
80
- headers: { "Content-Type": "application/json" },
81
- body: JSON.stringify({
82
- properties: { title },
83
- ...sheets ? { sheets } : {}
84
- })
85
- });
86
- if (!response.ok) {
87
- const body = await response.text();
88
- throw new Error(
89
- `google-sheets: createSpreadsheet failed (${response.status}): ${body}`
90
- );
91
- }
92
- return await response.json();
93
- }
94
109
  return {
110
+ spreadsheetId,
95
111
  request,
96
112
  getSpreadsheet,
97
113
  getValues,
98
- batchGetValues,
99
- updateValues,
100
- appendValues,
101
- createSpreadsheet
114
+ batchGetValues
102
115
  };
103
116
  }
104
117
 
@@ -249,19 +262,6 @@ var AUTH_TYPES = {
249
262
  USER_PASSWORD: "user-password"
250
263
  };
251
264
 
252
- // ../connectors/src/connectors/google-sheets/setup.ts
253
- var googleSheetsOnboarding = new ConnectorOnboarding({
254
- dataOverviewInstructions: {
255
- en: `1. Create a new spreadsheet with google-sheets-oauth_request (POST with body { properties: { title: "..." } }) or use an existing spreadsheet ID.
256
- 2. Call google-sheets-oauth_request with GET /{spreadsheetId} to fetch spreadsheet metadata (sheet names and properties).`,
257
- ja: `1. google-sheets-oauth_request \u3092 POST\uFF08Body: { properties: { title: "..." } }\uFF09\u3067\u547C\u3073\u51FA\u3057\u3066\u65B0\u3057\u3044\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u3092\u4F5C\u6210\u3059\u308B\u304B\u3001\u65E2\u5B58\u306E\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8ID\u3092\u5229\u7528\u3057\u307E\u3059\u3002
258
- 2. google-sheets-oauth_request \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\u3068\u30D7\u30ED\u30D1\u30C6\u30A3\uFF09\u3092\u53D6\u5F97\u3057\u307E\u3059\u3002`
259
- }
260
- });
261
-
262
- // ../connectors/src/connectors/google-sheets/parameters.ts
263
- var parameters = {};
264
-
265
265
  // ../connectors/src/connectors/google-sheets/tools/request.ts
266
266
  import { z } from "zod";
267
267
  var SHEETS_BASE_URL2 = "https://sheets.googleapis.com/v4/spreadsheets";
@@ -302,11 +302,10 @@ var inputSchema = z.object({
302
302
  "Brief description of what you intend to accomplish with this tool call"
303
303
  ),
304
304
  connectionId: z.string().describe("ID of the Google Sheets connection to use"),
305
- method: z.enum(["GET", "POST", "PUT"]).describe("HTTP method"),
305
+ method: z.enum(["GET"]).describe("HTTP method. Only GET is supported (read-only analysis)."),
306
306
  path: z.string().describe(
307
- "API path appended to https://sheets.googleapis.com/v4/spreadsheets (e.g., '', '/{spreadsheetId}', '/{spreadsheetId}/values/Sheet1!A1:D10')."
307
+ "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."
308
308
  ),
309
- body: z.record(z.string(), z.unknown()).optional().describe("JSON request body for POST/PUT requests"),
310
309
  queryParams: z.record(z.string(), z.string()).optional().describe("Query parameters to append to the URL")
311
310
  });
312
311
  var outputSchema = z.discriminatedUnion("success", [
@@ -322,12 +321,12 @@ var outputSchema = z.discriminatedUnion("success", [
322
321
  ]);
323
322
  var requestTool = new ConnectorTool({
324
323
  name: "request",
325
- description: `Send authenticated requests to the Google Sheets API v4.
326
- Supports GET (read), POST (create/append), and PUT (update) methods.
324
+ description: `Send authenticated GET requests to the Google Sheets API v4 for read-only analysis.
325
+ The \`{spreadsheetId}\` placeholder in the path is automatically replaced with the connection's configured spreadsheet ID.
327
326
  Authentication is handled automatically via OAuth proxy.`,
328
327
  inputSchema,
329
328
  outputSchema,
330
- async execute({ connectionId, method, path: path2, body, queryParams }, connections, config) {
329
+ async execute({ connectionId, method, path: path2, queryParams }, connections, config) {
331
330
  const connection2 = connections.find((c) => c.id === connectionId);
332
331
  if (!connection2) {
333
332
  return {
@@ -335,11 +334,16 @@ Authentication is handled automatically via OAuth proxy.`,
335
334
  error: `Connection ${connectionId} not found`
336
335
  };
337
336
  }
337
+ const spreadsheetIdParam = connection2.parameters.find(
338
+ (p) => p.parameterSlug === parameters.spreadsheetId.slug
339
+ );
340
+ const spreadsheetId = spreadsheetIdParam?.value ?? void 0;
341
+ const resolvedPath = spreadsheetId ? path2.replace(/\{spreadsheetId\}/g, spreadsheetId) : path2;
338
342
  console.log(
339
- `[connector-request] google-sheets/${connection2.name}: ${method} ${path2}`
343
+ `[connector-request] google-sheets/${connection2.name}: ${method} ${resolvedPath}`
340
344
  );
341
345
  try {
342
- let url = `${SHEETS_BASE_URL2}${path2 === "" || path2.startsWith("/") ? "" : "/"}${path2}`;
346
+ let url = `${SHEETS_BASE_URL2}${resolvedPath === "" || resolvedPath.startsWith("/") ? "" : "/"}${resolvedPath}`;
343
347
  if (queryParams) {
344
348
  const searchParams = new URLSearchParams(queryParams);
345
349
  url += `?${searchParams.toString()}`;
@@ -357,8 +361,7 @@ Authentication is handled automatically via OAuth proxy.`,
357
361
  },
358
362
  body: JSON.stringify({
359
363
  url,
360
- method,
361
- ...body != null ? { body: JSON.stringify(body) } : {}
364
+ method
362
365
  }),
363
366
  signal: controller.signal
364
367
  });
@@ -378,13 +381,66 @@ Authentication is handled automatically via OAuth proxy.`,
378
381
  }
379
382
  });
380
383
 
384
+ // ../connectors/src/connectors/google-sheets/setup.ts
385
+ var requestToolName = `google-sheets-oauth_${requestTool.name}`;
386
+ var googleSheetsOnboarding = new ConnectorOnboarding({
387
+ connectionSetupInstructions: {
388
+ 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
389
+
390
+ 1. \`askUserQuestion\` \u3067\u5206\u6790\u5BFE\u8C61\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306EURL\u3092\u30D2\u30A2\u30EA\u30F3\u30B0\u3059\u308B:
391
+ - \`type\`: \`"freeText"\`
392
+ - \`question\`: \u300C\u5206\u6790\u3057\u305F\u3044Google Sheets\u306EURL\u3092\u8CBC\u308A\u4ED8\u3051\u3066\u304F\u3060\u3055\u3044\u300D
393
+ - \`placeholder\`: \`"https://docs.google.com/spreadsheets/d/.../edit"\`
394
+ 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
395
+ 3. \u62BD\u51FA\u3057\u305FID\u3092 \`updateConnectionParameters\` \u3067\u4FDD\u5B58\u3059\u308B:
396
+ - \`parameterSlug\`: \`"spreadsheet-id"\`
397
+ - \`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
398
+ 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:
399
+ - \`method\`: \`"GET"\`
400
+ - \`path\`: \`"/{spreadsheetId}"\`
401
+ 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:
402
+ - 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
403
+ - \u5165\u529B\u3055\u308C\u305FURL\u304C\u6B63\u3057\u3044\u304B
404
+
405
+ #### \u5236\u7D04
406
+ - **\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
407
+ - \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`,
408
+ 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).
409
+
410
+ 1. Call \`askUserQuestion\` to ask for the spreadsheet URL to analyze:
411
+ - \`type\`: \`"freeText"\`
412
+ - \`question\`: "Please paste the URL of the Google Sheet you want to analyze"
413
+ - \`placeholder\`: \`"https://docs.google.com/spreadsheets/d/.../edit"\`
414
+ 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.
415
+ 3. Save the extracted ID via \`updateConnectionParameters\`:
416
+ - \`parameterSlug\`: \`"spreadsheet-id"\`
417
+ - \`options\`: \`[{ value: <extracted ID>, label: <same value> }]\` (a single option is auto-selected)
418
+ 4. Verify access by calling \`${requestToolName}\`:
419
+ - \`method\`: \`"GET"\`
420
+ - \`path\`: \`"/{spreadsheetId}"\`
421
+ 5. If an error is returned, ask the user to verify:
422
+ - The OAuthed Google account has read access to the spreadsheet
423
+ - The URL they entered is correct
424
+
425
+ #### Constraints
426
+ - **Do NOT read large amounts of cell data during setup**. Only the metadata request specified above is allowed
427
+ - Write only 1 sentence between tool calls, then immediately call the next tool. Skip unnecessary explanations and proceed efficiently`
428
+ },
429
+ dataOverviewInstructions: {
430
+ en: `1. Call ${requestToolName} with GET /{spreadsheetId} to fetch spreadsheet metadata (sheet names, grid properties)
431
+ 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`,
432
+ 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
433
+ 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`
434
+ }
435
+ });
436
+
381
437
  // ../connectors/src/connectors/google-sheets/index.ts
382
438
  var tools = { request: requestTool };
383
439
  var googleSheetsConnector = new ConnectorPlugin({
384
440
  slug: "google-sheets",
385
441
  authType: AUTH_TYPES.OAUTH,
386
442
  name: "Google Sheets",
387
- description: "Connect to Google Sheets for spreadsheet data access and creation using OAuth.",
443
+ description: "Connect to an existing Google Sheets spreadsheet for read-only data analysis using OAuth.",
388
444
  iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/1UPQuggyiZmbb26CuaSr2h/032770e8739b183fa00b7625f024e536/google-sheets.svg",
389
445
  parameters,
390
446
  releaseFlag: { dev1: true, dev2: false, prod: false },
@@ -393,30 +449,25 @@ var googleSheetsConnector = new ConnectorPlugin({
393
449
  allowlist: [
394
450
  {
395
451
  host: "sheets.googleapis.com",
396
- methods: ["GET", "POST", "PUT"]
452
+ methods: ["GET"]
397
453
  }
398
454
  ]
399
455
  },
400
456
  systemPrompt: {
401
457
  en: `### Tools (setup-time only)
402
458
 
403
- - \`google-sheets-oauth_request\`: Call the Google Sheets API during setup / data overview. Supports read and write operations. Use it to get/update spreadsheet metadata, cell values, create new spreadsheets, and more. Authentication is configured automatically via OAuth.
459
+ - \`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.
404
460
 
405
461
  > **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.
406
462
 
407
- ### Google Sheets API Reference
463
+ > **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\`.
464
+
465
+ ### Google Sheets API Reference (read-only)
408
466
 
409
- #### Read Endpoints
410
467
  - GET \`/{spreadsheetId}\` \u2014 Get spreadsheet metadata (title, sheets, properties)
411
468
  - GET \`/{spreadsheetId}/values/{range}\` \u2014 Get cell values for a range
412
469
  - GET \`/{spreadsheetId}/values:batchGet?ranges={range1}&ranges={range2}\` \u2014 Get values for multiple ranges
413
470
 
414
- #### Write Endpoints
415
- - POST \`\` (empty path, with body) \u2014 Create a new spreadsheet. Body: \`{ "properties": { "title": "My Sheet" }, "sheets": [{ "properties": { "title": "Sheet1" } }] }\`
416
- - PUT \`/{spreadsheetId}/values/{range}?valueInputOption=USER_ENTERED\` \u2014 Update cell values for a range. Body: \`{ "range": "Sheet1!A1:B2", "majorDimension": "ROWS", "values": [["a","b"],["c","d"]] }\`
417
- - POST \`/{spreadsheetId}/values/{range}:append?valueInputOption=USER_ENTERED&insertDataOption=INSERT_ROWS\` \u2014 Append rows after the last row. Body: \`{ "range": "Sheet1!A1", "majorDimension": "ROWS", "values": [["a","b"]] }\`
418
- - POST \`/{spreadsheetId}:batchUpdate\` \u2014 Apply multiple updates (formatting, add sheets, merge cells, etc.). Body: \`{ "requests": [...] }\`
419
-
420
471
  ### Range Notation (A1 notation)
421
472
  - \`Sheet1!A1:D10\` \u2014 Specific range on Sheet1
422
473
  - \`Sheet1!A:A\` \u2014 Entire column A on Sheet1
@@ -429,21 +480,17 @@ var googleSheetsConnector = new ConnectorPlugin({
429
480
  - Use \`valueRenderOption=FORMATTED_VALUE\` query param to get display values
430
481
  - Use \`valueRenderOption=UNFORMATTED_VALUE\` for raw numeric values
431
482
  - Use \`majorDimension=COLUMNS\` to get data organized by columns instead of rows
432
- - For write operations, always use \`valueInputOption=USER_ENTERED\` so values are parsed as if typed by a user (dates, numbers, formulas are auto-detected)
433
- - Sharing (permissions) cannot be done via this connector; only the OAuth user has access to the created spreadsheets
434
483
 
435
484
  ### Business Logic
436
485
 
437
- 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.
486
+ 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.
438
487
 
439
488
  SDK surface (client created via \`connection(connectionId)\`):
440
- - \`client.request(path, init?)\` \u2014 low-level authenticated fetch (\`path\` is appended to \`https://sheets.googleapis.com/v4/spreadsheets\`).
441
- - \`client.getSpreadsheet(spreadsheetId)\` \u2014 fetch spreadsheet metadata.
442
- - \`client.getValues(spreadsheetId, range)\` \u2014 read a range (A1 notation).
443
- - \`client.batchGetValues(spreadsheetId, ranges)\` \u2014 read multiple ranges.
444
- - \`client.updateValues(spreadsheetId, range, values)\` \u2014 write values to a range.
445
- - \`client.appendValues(spreadsheetId, range, values)\` \u2014 append rows after the last row.
446
- - \`client.createSpreadsheet(title, sheetNames?)\` \u2014 create a new spreadsheet.
489
+ - \`client.spreadsheetId\` \u2014 the spreadsheet ID configured for this connection.
490
+ - \`client.request(path, init?)\` \u2014 low-level authenticated fetch (\`path\` is appended to \`https://sheets.googleapis.com/v4/spreadsheets\`; \`{spreadsheetId}\` is auto-replaced).
491
+ - \`client.getSpreadsheet()\` \u2014 fetch spreadsheet metadata for the configured spreadsheet.
492
+ - \`client.getValues(range)\` \u2014 read a range (A1 notation) from the configured spreadsheet.
493
+ - \`client.batchGetValues(ranges)\` \u2014 read multiple ranges from the configured spreadsheet.
447
494
 
448
495
  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.
449
496
 
@@ -454,43 +501,31 @@ import { connection } from "@squadbase/vite-server/connectors/google-sheets";
454
501
 
455
502
  const sheets = connection("<connectionId>");
456
503
 
457
- // Create a new spreadsheet
458
- const newSheet = await sheets.createSpreadsheet("Sales Report", ["Q1", "Q2", "Q3", "Q4"]);
459
- const spreadsheetId = newSheet.spreadsheetId;
460
-
461
- // Get spreadsheet metadata
462
- const metadata = await sheets.getSpreadsheet(spreadsheetId);
504
+ // Get metadata for the configured spreadsheet
505
+ const metadata = await sheets.getSpreadsheet();
463
506
  console.log(metadata.properties.title, metadata.sheets.map(s => s.properties.title));
464
507
 
465
508
  // Get cell values
466
- const values = await sheets.getValues(spreadsheetId, "Sheet1!A1:D10");
509
+ const values = await sheets.getValues("Sheet1!A1:D10");
467
510
  console.log(values.values); // 2D array
468
511
 
469
- // Update cell values
470
- await sheets.updateValues(spreadsheetId, "Sheet1!A1:B2", [["Name", "Score"], ["Alice", "100"]]);
471
-
472
- // Append rows
473
- await sheets.appendValues(spreadsheetId, "Sheet1!A1", [["Bob", "95"], ["Charlie", "88"]]);
512
+ // Batch-get multiple ranges
513
+ const batch = await sheets.batchGetValues(["Sheet1!A:A", "Sheet2!B2:C100"]);
474
514
  \`\`\``,
475
515
  ja: `### \u30C4\u30FC\u30EB\uFF08\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u6642\u306E\u307F\uFF09
476
516
 
477
- - \`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\u3068\u66F8\u304D\u8FBC\u307F\u306E\u4E21\u65B9\u3092\u30B5\u30DD\u30FC\u30C8\u3057\u307E\u3059\u3002\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\u30FB\u30BB\u30EB\u5024\u306E\u53D6\u5F97/\u66F4\u65B0\u3001\u65B0\u3057\u3044\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306E\u4F5C\u6210\u306A\u3069\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002OAuth \u7D4C\u7531\u3067\u8A8D\u8A3C\u306F\u81EA\u52D5\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002
517
+ - \`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
478
518
 
479
519
  > **\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
480
520
 
481
- ### Google Sheets API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
521
+ > **\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
522
+
523
+ ### Google Sheets API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9\uFF08\u8AAD\u307F\u53D6\u308A\u5C02\u7528\uFF09
482
524
 
483
- #### \u8AAD\u307F\u53D6\u308A\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8
484
525
  - 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
485
526
  - GET \`/{spreadsheetId}/values/{range}\` \u2014 \u7BC4\u56F2\u306E\u30BB\u30EB\u5024\u3092\u53D6\u5F97
486
527
  - GET \`/{spreadsheetId}/values:batchGet?ranges={range1}&ranges={range2}\` \u2014 \u8907\u6570\u7BC4\u56F2\u306E\u5024\u3092\u53D6\u5F97
487
528
 
488
- #### \u66F8\u304D\u8FBC\u307F\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8
489
- - POST \`\`\uFF08\u7A7A\u30D1\u30B9\u3001\u30DC\u30C7\u30A3\u4ED8\u304D\uFF09\u2014 \u65B0\u3057\u3044\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u3092\u4F5C\u6210\u3002Body: \`{ "properties": { "title": "\u30DE\u30A4\u30B7\u30FC\u30C8" }, "sheets": [{ "properties": { "title": "Sheet1" } }] }\`
490
- - PUT \`/{spreadsheetId}/values/{range}?valueInputOption=USER_ENTERED\` \u2014 \u7BC4\u56F2\u306E\u30BB\u30EB\u5024\u3092\u66F4\u65B0\u3002Body: \`{ "range": "Sheet1!A1:B2", "majorDimension": "ROWS", "values": [["a","b"],["c","d"]] }\`
491
- - POST \`/{spreadsheetId}/values/{range}:append?valueInputOption=USER_ENTERED&insertDataOption=INSERT_ROWS\` \u2014 \u6700\u7D42\u884C\u306E\u5F8C\u306B\u884C\u3092\u8FFD\u52A0\u3002Body: \`{ "range": "Sheet1!A1", "majorDimension": "ROWS", "values": [["a","b"]] }\`
492
- - POST \`/{spreadsheetId}:batchUpdate\` \u2014 \u8907\u6570\u306E\u66F4\u65B0\u3092\u9069\u7528\uFF08\u66F8\u5F0F\u8A2D\u5B9A\u3001\u30B7\u30FC\u30C8\u8FFD\u52A0\u3001\u30BB\u30EB\u7D50\u5408\u306A\u3069\uFF09\u3002Body: \`{ "requests": [...] }\`
493
-
494
529
  ### \u7BC4\u56F2\u306E\u8868\u8A18\u6CD5\uFF08A1\u8868\u8A18\u6CD5\uFF09
495
530
  - \`Sheet1!A1:D10\` \u2014 Sheet1\u4E0A\u306E\u7279\u5B9A\u7BC4\u56F2
496
531
  - \`Sheet1!A:A\` \u2014 Sheet1\u306EA\u5217\u5168\u4F53
@@ -503,21 +538,17 @@ await sheets.appendValues(spreadsheetId, "Sheet1!A1", [["Bob", "95"], ["Charlie"
503
538
  - \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
504
539
  - \u751F\u306E\u6570\u5024\u3092\u53D6\u5F97\u3059\u308B\u306B\u306F \`valueRenderOption=UNFORMATTED_VALUE\` \u3092\u4F7F\u7528\u3057\u307E\u3059
505
540
  - \u5217\u3054\u3068\u306B\u30C7\u30FC\u30BF\u3092\u53D6\u5F97\u3059\u308B\u306B\u306F \`majorDimension=COLUMNS\` \u3092\u4F7F\u7528\u3057\u307E\u3059
506
- - \u66F8\u304D\u8FBC\u307F\u64CD\u4F5C\u3067\u306F\u5E38\u306B \`valueInputOption=USER_ENTERED\` \u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u5024\u304C\u30E6\u30FC\u30B6\u30FC\u5165\u529B\u306E\u3088\u3046\u306B\u89E3\u6790\u3055\u308C\u307E\u3059\uFF08\u65E5\u4ED8\u3001\u6570\u5024\u3001\u6570\u5F0F\u304C\u81EA\u52D5\u691C\u51FA\uFF09
507
- - \u5171\u6709\uFF08permissions\uFF09\u306F\u3053\u306E\u30B3\u30CD\u30AF\u30BF\u7D4C\u7531\u3067\u306F\u884C\u3048\u307E\u305B\u3093\u3002\u4F5C\u6210\u3057\u305F\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u3078\u306F\u63A5\u7D9A\u3057\u305FOAuth\u30E6\u30FC\u30B6\u30FC\u306E\u307F\u304C\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u3067\u3059
508
541
 
509
542
  ### Business Logic
510
543
 
511
- \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
544
+ \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
512
545
 
513
546
  SDK\uFF08\`connection(connectionId)\` \u3067\u4F5C\u6210\u3057\u305F\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\uFF09:
514
- - \`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\u307E\u3059\uFF09\u3002
515
- - \`client.getSpreadsheet(spreadsheetId)\` \u2014 \u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97\u3002
516
- - \`client.getValues(spreadsheetId, range)\` \u2014 \u7BC4\u56F2\u306E\u5024\u3092\u53D6\u5F97\uFF08A1 \u8868\u8A18\uFF09\u3002
517
- - \`client.batchGetValues(spreadsheetId, ranges)\` \u2014 \u8907\u6570\u7BC4\u56F2\u306E\u5024\u3092\u53D6\u5F97\u3002
518
- - \`client.updateValues(spreadsheetId, range, values)\` \u2014 \u7BC4\u56F2\u306B\u5024\u3092\u66F8\u304D\u8FBC\u307F\u3002
519
- - \`client.appendValues(spreadsheetId, range, values)\` \u2014 \u6700\u7D42\u884C\u306E\u5F8C\u306B\u884C\u3092\u8FFD\u52A0\u3002
520
- - \`client.createSpreadsheet(title, sheetNames?)\` \u2014 \u65B0\u3057\u3044\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u3092\u4F5C\u6210\u3002
547
+ - \`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
548
+ - \`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
549
+ - \`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
550
+ - \`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
551
+ - \`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
521
552
 
522
553
  \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
523
554
 
@@ -528,23 +559,16 @@ import { connection } from "@squadbase/vite-server/connectors/google-sheets";
528
559
 
529
560
  const sheets = connection("<connectionId>");
530
561
 
531
- // \u65B0\u3057\u3044\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u3092\u4F5C\u6210
532
- const newSheet = await sheets.createSpreadsheet("\u58F2\u4E0A\u30EC\u30DD\u30FC\u30C8", ["Q1", "Q2", "Q3", "Q4"]);
533
- const spreadsheetId = newSheet.spreadsheetId;
534
-
535
- // \u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97
536
- const metadata = await sheets.getSpreadsheet(spreadsheetId);
562
+ // \u8A2D\u5B9A\u6E08\u307F\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97
563
+ const metadata = await sheets.getSpreadsheet();
537
564
  console.log(metadata.properties.title, metadata.sheets.map(s => s.properties.title));
538
565
 
539
566
  // \u30BB\u30EB\u5024\u3092\u53D6\u5F97
540
- const values = await sheets.getValues(spreadsheetId, "Sheet1!A1:D10");
567
+ const values = await sheets.getValues("Sheet1!A1:D10");
541
568
  console.log(values.values); // 2D array
542
569
 
543
- // \u30BB\u30EB\u5024\u3092\u66F4\u65B0
544
- await sheets.updateValues(spreadsheetId, "Sheet1!A1:B2", [["\u540D\u524D", "\u30B9\u30B3\u30A2"], ["Alice", "100"]]);
545
-
546
- // \u884C\u3092\u8FFD\u52A0
547
- await sheets.appendValues(spreadsheetId, "Sheet1!A1", [["Bob", "95"], ["Charlie", "88"]]);
570
+ // \u8907\u6570\u7BC4\u56F2\u3092\u30D0\u30C3\u30C1\u53D6\u5F97
571
+ const batch = await sheets.batchGetValues(["Sheet1!A:A", "Sheet2!B2:C100"]);
548
572
  \`\`\``
549
573
  },
550
574
  tools