@squadbase/vite-server 0.1.3-dev.15 → 0.1.3-dev.16
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 +2105 -2700
- package/dist/connectors/airtable-oauth.js +16 -5
- package/dist/connectors/airtable.js +16 -5
- package/dist/connectors/amplitude.js +16 -5
- package/dist/connectors/anthropic.js +16 -5
- package/dist/connectors/asana.js +16 -5
- package/dist/connectors/attio.js +16 -5
- package/dist/connectors/backlog-api-key.js +16 -5
- package/dist/connectors/customerio.js +16 -5
- package/dist/connectors/dbt.js +16 -5
- package/dist/connectors/gamma.js +16 -5
- package/dist/connectors/gemini.js +16 -5
- package/dist/connectors/gmail-oauth.js +16 -5
- package/dist/connectors/gmail.js +68 -34
- package/dist/connectors/google-ads.js +16 -5
- package/dist/connectors/google-analytics-oauth.js +16 -5
- package/dist/connectors/google-analytics.js +16 -5
- package/dist/connectors/google-calendar-oauth.js +16 -5
- package/dist/connectors/google-calendar.js +71 -48
- package/dist/connectors/{google-drive-oauth.d.ts → google-docs.d.ts} +1 -1
- package/dist/connectors/google-docs.js +585 -0
- package/dist/connectors/google-drive.d.ts +1 -1
- package/dist/connectors/google-drive.js +391 -327
- package/dist/connectors/google-sheets.d.ts +1 -1
- package/dist/connectors/google-sheets.js +210 -280
- package/dist/connectors/google-slides.d.ts +1 -1
- package/dist/connectors/google-slides.js +198 -335
- package/dist/connectors/grafana.js +16 -5
- package/dist/connectors/hubspot-oauth.js +16 -5
- package/dist/connectors/hubspot.js +16 -5
- package/dist/connectors/intercom-oauth.js +16 -5
- package/dist/connectors/intercom.js +16 -5
- package/dist/connectors/jira-api-key.js +16 -5
- package/dist/connectors/kintone-api-token.js +133 -59
- package/dist/connectors/kintone.js +16 -5
- package/dist/connectors/linkedin-ads.js +16 -5
- package/dist/connectors/mailchimp-oauth.js +16 -5
- package/dist/connectors/mailchimp.js +16 -5
- package/dist/connectors/mixpanel.js +16 -5
- package/dist/connectors/notion-oauth.js +16 -5
- package/dist/connectors/notion.js +16 -5
- package/dist/connectors/openai.js +16 -5
- package/dist/connectors/sentry.js +16 -5
- package/dist/connectors/shopify-oauth.js +16 -5
- package/dist/connectors/shopify.js +16 -5
- package/dist/connectors/stripe-api-key.js +16 -5
- package/dist/connectors/stripe-oauth.js +16 -5
- package/dist/connectors/wix-store.js +16 -5
- package/dist/connectors/zendesk-oauth.js +16 -5
- package/dist/connectors/zendesk.js +16 -5
- package/dist/index.js +2100 -2695
- package/dist/main.js +2100 -2695
- package/dist/vite-plugin.js +2100 -2695
- package/package.json +7 -15
- package/dist/connectors/google-drive-oauth.js +0 -879
- package/dist/connectors/google-sheets-oauth.d.ts +0 -5
- package/dist/connectors/google-sheets-oauth.js +0 -821
- package/dist/connectors/google-slides-oauth.d.ts +0 -5
- package/dist/connectors/google-slides-oauth.js +0 -742
|
@@ -1,272 +1,68 @@
|
|
|
1
|
-
// ../connectors/src/
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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;
|
|
1
|
+
// ../connectors/src/connectors/google-slides/sdk/index.ts
|
|
2
|
+
var SLIDES_BASE_URL = "https://slides.googleapis.com/v1/presentations";
|
|
3
|
+
function createClient(_params, fetchFn = fetch) {
|
|
4
|
+
function request(path2, init) {
|
|
5
|
+
const url = `${SLIDES_BASE_URL}${path2 === "" || path2.startsWith("/") ? "" : "/"}${path2}`;
|
|
6
|
+
return fetchFn(url, init);
|
|
18
7
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
(p) => p.parameterSlug === this.slug
|
|
25
|
-
);
|
|
26
|
-
if (!param || param.value == null) {
|
|
8
|
+
async function getPresentation(presentationId) {
|
|
9
|
+
const url = `${SLIDES_BASE_URL}/${presentationId}`;
|
|
10
|
+
const response = await fetchFn(url);
|
|
11
|
+
if (!response.ok) {
|
|
12
|
+
const body = await response.text();
|
|
27
13
|
throw new Error(
|
|
28
|
-
`
|
|
14
|
+
`google-slides: getPresentation failed (${response.status}): ${body}`
|
|
29
15
|
);
|
|
30
16
|
}
|
|
31
|
-
return
|
|
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;
|
|
17
|
+
return await response.json();
|
|
42
18
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
slug: "service-account-key-json-base64",
|
|
52
|
-
name: "Google Cloud Service Account JSON",
|
|
53
|
-
description: "The service account JSON key used to authenticate with Google Cloud Platform. Ensure that the service account has the necessary permissions to access Google Slides.",
|
|
54
|
-
envVarBaseKey: "GOOGLE_SLIDES_SERVICE_ACCOUNT_JSON_BASE64",
|
|
55
|
-
type: "base64EncodedJson",
|
|
56
|
-
secret: true,
|
|
57
|
-
required: true
|
|
58
|
-
}),
|
|
59
|
-
presentationUrl: new ParameterDefinition({
|
|
60
|
-
slug: "presentation-url",
|
|
61
|
-
name: "Google Slides Presentation URL",
|
|
62
|
-
description: "The URL of the Google Slides presentation (e.g., https://docs.google.com/presentation/d/xxxxx/edit). The presentation ID is automatically extracted from the URL.",
|
|
63
|
-
envVarBaseKey: "GOOGLE_SLIDES_PRESENTATION_URL",
|
|
64
|
-
type: "text",
|
|
65
|
-
secret: false,
|
|
66
|
-
required: false
|
|
67
|
-
}),
|
|
68
|
-
sharedDriveId: new ParameterDefinition({
|
|
69
|
-
slug: "shared-drive-id",
|
|
70
|
-
name: "Shared Drive ID",
|
|
71
|
-
description: "The ID of the Google Shared Drive where new presentations will be created. Required for service accounts that do not have their own Drive storage. You can find the ID in the Shared Drive URL: https://drive.google.com/drive/folders/{sharedDriveId}",
|
|
72
|
-
envVarBaseKey: "GOOGLE_SLIDES_SHARED_DRIVE_ID",
|
|
73
|
-
type: "text",
|
|
74
|
-
secret: false,
|
|
75
|
-
required: false
|
|
76
|
-
})
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
// ../connectors/src/connectors/google-slides-oauth/utils.ts
|
|
80
|
-
var PRESENTATION_URL_PATTERN = /docs\.google\.com\/presentation\/d\/([a-zA-Z0-9_-]+)/;
|
|
81
|
-
function extractPresentationId(urlOrId) {
|
|
82
|
-
const trimmed = urlOrId.trim();
|
|
83
|
-
const match = trimmed.match(PRESENTATION_URL_PATTERN);
|
|
84
|
-
if (match) {
|
|
85
|
-
return match[1];
|
|
86
|
-
}
|
|
87
|
-
return trimmed;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// ../connectors/src/connectors/google-slides/sdk/index.ts
|
|
91
|
-
var TOKEN_URL = "https://oauth2.googleapis.com/token";
|
|
92
|
-
var SLIDES_BASE_URL = "https://slides.googleapis.com/v1/presentations";
|
|
93
|
-
var DRIVE_FILES_URL = "https://www.googleapis.com/drive/v3/files";
|
|
94
|
-
var SCOPE = "https://www.googleapis.com/auth/presentations https://www.googleapis.com/auth/drive";
|
|
95
|
-
function base64url(input) {
|
|
96
|
-
const buf = typeof input === "string" ? Buffer.from(input) : input;
|
|
97
|
-
return buf.toString("base64url");
|
|
98
|
-
}
|
|
99
|
-
function buildJwt(clientEmail, privateKey, nowSec) {
|
|
100
|
-
const header = base64url(JSON.stringify({ alg: "RS256", typ: "JWT" }));
|
|
101
|
-
const payload = base64url(
|
|
102
|
-
JSON.stringify({
|
|
103
|
-
iss: clientEmail,
|
|
104
|
-
scope: SCOPE,
|
|
105
|
-
aud: TOKEN_URL,
|
|
106
|
-
iat: nowSec,
|
|
107
|
-
exp: nowSec + 3600
|
|
108
|
-
})
|
|
109
|
-
);
|
|
110
|
-
const signingInput = `${header}.${payload}`;
|
|
111
|
-
const sign = crypto.createSign("RSA-SHA256");
|
|
112
|
-
sign.update(signingInput);
|
|
113
|
-
sign.end();
|
|
114
|
-
const signature = base64url(sign.sign(privateKey));
|
|
115
|
-
return `${signingInput}.${signature}`;
|
|
116
|
-
}
|
|
117
|
-
function createClient(params) {
|
|
118
|
-
const serviceAccountKeyJsonBase64 = params[parameters.serviceAccountKeyJsonBase64.slug];
|
|
119
|
-
const presentationUrl = params[parameters.presentationUrl.slug];
|
|
120
|
-
const defaultPresentationId = presentationUrl ? extractPresentationId(presentationUrl) : void 0;
|
|
121
|
-
const sharedDriveId = params[parameters.sharedDriveId.slug] || void 0;
|
|
122
|
-
if (!serviceAccountKeyJsonBase64) {
|
|
123
|
-
throw new Error(
|
|
124
|
-
`google-slides: missing required parameter: ${parameters.serviceAccountKeyJsonBase64.slug}`
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
let serviceAccountKey;
|
|
128
|
-
try {
|
|
129
|
-
const decoded = Buffer.from(
|
|
130
|
-
serviceAccountKeyJsonBase64,
|
|
131
|
-
"base64"
|
|
132
|
-
).toString("utf-8");
|
|
133
|
-
serviceAccountKey = JSON.parse(decoded);
|
|
134
|
-
} catch {
|
|
135
|
-
throw new Error(
|
|
136
|
-
"google-slides: failed to decode service account key JSON from base64"
|
|
137
|
-
);
|
|
138
|
-
}
|
|
139
|
-
if (!serviceAccountKey.client_email || !serviceAccountKey.private_key) {
|
|
140
|
-
throw new Error(
|
|
141
|
-
"google-slides: service account key JSON must contain client_email and private_key"
|
|
142
|
-
);
|
|
143
|
-
}
|
|
144
|
-
let cachedToken = null;
|
|
145
|
-
let tokenExpiresAt = 0;
|
|
146
|
-
async function getAccessToken() {
|
|
147
|
-
const nowSec = Math.floor(Date.now() / 1e3);
|
|
148
|
-
if (cachedToken && nowSec < tokenExpiresAt - 60) {
|
|
149
|
-
return cachedToken;
|
|
19
|
+
async function getPage(presentationId, pageObjectId) {
|
|
20
|
+
const url = `${SLIDES_BASE_URL}/${presentationId}/pages/${pageObjectId}`;
|
|
21
|
+
const response = await fetchFn(url);
|
|
22
|
+
if (!response.ok) {
|
|
23
|
+
const body = await response.text();
|
|
24
|
+
throw new Error(
|
|
25
|
+
`google-slides: getPage failed (${response.status}): ${body}`
|
|
26
|
+
);
|
|
150
27
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
const response = await fetch(TOKEN_URL, {
|
|
28
|
+
return await response.json();
|
|
29
|
+
}
|
|
30
|
+
async function batchUpdate(presentationId, requests) {
|
|
31
|
+
const url = `${SLIDES_BASE_URL}/${presentationId}:batchUpdate`;
|
|
32
|
+
const response = await fetchFn(url, {
|
|
157
33
|
method: "POST",
|
|
158
|
-
headers: { "Content-Type": "application/
|
|
159
|
-
body:
|
|
160
|
-
grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
|
|
161
|
-
assertion: jwt
|
|
162
|
-
})
|
|
34
|
+
headers: { "Content-Type": "application/json" },
|
|
35
|
+
body: JSON.stringify({ requests })
|
|
163
36
|
});
|
|
164
37
|
if (!response.ok) {
|
|
165
|
-
const
|
|
38
|
+
const body = await response.text();
|
|
166
39
|
throw new Error(
|
|
167
|
-
`google-slides:
|
|
40
|
+
`google-slides: batchUpdate failed (${response.status}): ${body}`
|
|
168
41
|
);
|
|
169
42
|
}
|
|
170
|
-
|
|
171
|
-
cachedToken = data.access_token;
|
|
172
|
-
tokenExpiresAt = nowSec + data.expires_in;
|
|
173
|
-
return cachedToken;
|
|
43
|
+
return await response.json();
|
|
174
44
|
}
|
|
175
|
-
function
|
|
176
|
-
const
|
|
177
|
-
|
|
45
|
+
async function createPresentation(title) {
|
|
46
|
+
const url = SLIDES_BASE_URL;
|
|
47
|
+
const response = await fetchFn(url, {
|
|
48
|
+
method: "POST",
|
|
49
|
+
headers: { "Content-Type": "application/json" },
|
|
50
|
+
body: JSON.stringify({ title })
|
|
51
|
+
});
|
|
52
|
+
if (!response.ok) {
|
|
53
|
+
const body = await response.text();
|
|
178
54
|
throw new Error(
|
|
179
|
-
|
|
55
|
+
`google-slides: createPresentation failed (${response.status}): ${body}`
|
|
180
56
|
);
|
|
181
57
|
}
|
|
182
|
-
return
|
|
183
|
-
}
|
|
184
|
-
async function authenticatedFetch(url, init) {
|
|
185
|
-
const accessToken = await getAccessToken();
|
|
186
|
-
const headers = new Headers(init?.headers);
|
|
187
|
-
headers.set("Authorization", `Bearer ${accessToken}`);
|
|
188
|
-
if (!headers.has("Content-Type")) {
|
|
189
|
-
headers.set("Content-Type", "application/json");
|
|
190
|
-
}
|
|
191
|
-
return fetch(url, { ...init, headers });
|
|
58
|
+
return await response.json();
|
|
192
59
|
}
|
|
193
60
|
return {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
async getPresentation(presentationId) {
|
|
200
|
-
const id = resolvePresentationId(presentationId);
|
|
201
|
-
const response = await authenticatedFetch(`${SLIDES_BASE_URL}/${id}`);
|
|
202
|
-
if (!response.ok) {
|
|
203
|
-
const body = await response.text();
|
|
204
|
-
throw new Error(`google-slides: getPresentation failed (${response.status}): ${body}`);
|
|
205
|
-
}
|
|
206
|
-
return await response.json();
|
|
207
|
-
},
|
|
208
|
-
async getPage(pageObjectId, presentationId) {
|
|
209
|
-
const id = resolvePresentationId(presentationId);
|
|
210
|
-
const response = await authenticatedFetch(`${SLIDES_BASE_URL}/${id}/pages/${pageObjectId}`);
|
|
211
|
-
if (!response.ok) {
|
|
212
|
-
const body = await response.text();
|
|
213
|
-
throw new Error(`google-slides: getPage failed (${response.status}): ${body}`);
|
|
214
|
-
}
|
|
215
|
-
return await response.json();
|
|
216
|
-
},
|
|
217
|
-
async batchUpdate(requests, presentationId) {
|
|
218
|
-
const id = resolvePresentationId(presentationId);
|
|
219
|
-
const response = await authenticatedFetch(`${SLIDES_BASE_URL}/${id}:batchUpdate`, {
|
|
220
|
-
method: "POST",
|
|
221
|
-
body: JSON.stringify({ requests })
|
|
222
|
-
});
|
|
223
|
-
if (!response.ok) {
|
|
224
|
-
const body = await response.text();
|
|
225
|
-
throw new Error(`google-slides: batchUpdate failed (${response.status}): ${body}`);
|
|
226
|
-
}
|
|
227
|
-
return await response.json();
|
|
228
|
-
},
|
|
229
|
-
async createPresentation(title) {
|
|
230
|
-
if (sharedDriveId) {
|
|
231
|
-
const driveResponse = await authenticatedFetch(
|
|
232
|
-
`${DRIVE_FILES_URL}?supportsAllDrives=true`,
|
|
233
|
-
{
|
|
234
|
-
method: "POST",
|
|
235
|
-
body: JSON.stringify({
|
|
236
|
-
name: title,
|
|
237
|
-
mimeType: "application/vnd.google-apps.presentation",
|
|
238
|
-
parents: [sharedDriveId]
|
|
239
|
-
})
|
|
240
|
-
}
|
|
241
|
-
);
|
|
242
|
-
if (!driveResponse.ok) {
|
|
243
|
-
const body = await driveResponse.text();
|
|
244
|
-
throw new Error(
|
|
245
|
-
`google-slides: createPresentation (Drive API) failed (${driveResponse.status}): ${body}`
|
|
246
|
-
);
|
|
247
|
-
}
|
|
248
|
-
const driveFile = await driveResponse.json();
|
|
249
|
-
const slidesResponse = await authenticatedFetch(
|
|
250
|
-
`${SLIDES_BASE_URL}/${driveFile.id}`
|
|
251
|
-
);
|
|
252
|
-
if (!slidesResponse.ok) {
|
|
253
|
-
const body = await slidesResponse.text();
|
|
254
|
-
throw new Error(
|
|
255
|
-
`google-slides: getPresentation after create failed (${slidesResponse.status}): ${body}`
|
|
256
|
-
);
|
|
257
|
-
}
|
|
258
|
-
return await slidesResponse.json();
|
|
259
|
-
}
|
|
260
|
-
const response = await authenticatedFetch(SLIDES_BASE_URL, {
|
|
261
|
-
method: "POST",
|
|
262
|
-
body: JSON.stringify({ title })
|
|
263
|
-
});
|
|
264
|
-
if (!response.ok) {
|
|
265
|
-
const body = await response.text();
|
|
266
|
-
throw new Error(`google-slides: createPresentation failed (${response.status}): ${body}`);
|
|
267
|
-
}
|
|
268
|
-
return await response.json();
|
|
269
|
-
}
|
|
61
|
+
request,
|
|
62
|
+
getPresentation,
|
|
63
|
+
getPage,
|
|
64
|
+
batchUpdate,
|
|
65
|
+
createPresentation
|
|
270
66
|
};
|
|
271
67
|
}
|
|
272
68
|
|
|
@@ -352,16 +148,27 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
352
148
|
* Filters connections by connectorKey internally.
|
|
353
149
|
* Returns tools keyed as `${connectorKey}_${toolName}`.
|
|
354
150
|
*/
|
|
355
|
-
createTools(connections, config) {
|
|
151
|
+
createTools(connections, config, opts) {
|
|
356
152
|
const myConnections = connections.filter(
|
|
357
153
|
(c) => _ConnectorPlugin.deriveKey(c.connector.slug, c.connector.authType) === this.connectorKey
|
|
358
154
|
);
|
|
359
155
|
const result = {};
|
|
360
156
|
for (const t of Object.values(this.tools)) {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
157
|
+
const tool = t.createTool(myConnections, config);
|
|
158
|
+
const originalToModelOutput = tool.toModelOutput;
|
|
159
|
+
result[`${this.connectorKey}_${t.name}`] = {
|
|
160
|
+
...tool,
|
|
161
|
+
toModelOutput: async (options) => {
|
|
162
|
+
if (!originalToModelOutput) {
|
|
163
|
+
return opts.truncateOutput(options.output);
|
|
164
|
+
}
|
|
165
|
+
const modelOutput = await originalToModelOutput(options);
|
|
166
|
+
if (modelOutput.type === "text" || modelOutput.type === "json") {
|
|
167
|
+
return opts.truncateOutput(modelOutput.value);
|
|
168
|
+
}
|
|
169
|
+
return modelOutput;
|
|
170
|
+
}
|
|
171
|
+
};
|
|
365
172
|
}
|
|
366
173
|
return result;
|
|
367
174
|
}
|
|
@@ -383,17 +190,51 @@ var AUTH_TYPES = {
|
|
|
383
190
|
// ../connectors/src/connectors/google-slides/setup.ts
|
|
384
191
|
var googleSlidesOnboarding = new ConnectorOnboarding({
|
|
385
192
|
dataOverviewInstructions: {
|
|
386
|
-
en: `1.
|
|
387
|
-
2. Call google-slides_request with GET /{presentationId}
|
|
388
|
-
ja: `1. google-slides_request \
|
|
389
|
-
2. google-slides_request \u3067 GET /{presentationId}
|
|
193
|
+
en: `1. Create a new presentation with google-slides_request (POST with body { title: "..." }) or use an existing presentation ID.
|
|
194
|
+
2. Call google-slides_request with GET /{presentationId} to fetch presentation metadata (title, slide count, layout info).`,
|
|
195
|
+
ja: `1. google-slides_request \u3092 POST\uFF08Body: { title: "..." }\uFF09\u3067\u547C\u3073\u51FA\u3057\u3066\u65B0\u3057\u3044\u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u3092\u4F5C\u6210\u3059\u308B\u304B\u3001\u65E2\u5B58\u306E\u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3ID\u3092\u5229\u7528\u3057\u307E\u3059\u3002
|
|
196
|
+
2. google-slides_request \u3067 GET /{presentationId} \u3092\u547C\u3073\u51FA\u3057\u3001\u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\uFF08\u30BF\u30A4\u30C8\u30EB\u3001\u30B9\u30E9\u30A4\u30C9\u6570\u3001\u30EC\u30A4\u30A2\u30A6\u30C8\u60C5\u5831\uFF09\u3092\u53D6\u5F97\u3057\u307E\u3059\u3002`
|
|
390
197
|
}
|
|
391
198
|
});
|
|
392
199
|
|
|
200
|
+
// ../connectors/src/connectors/google-slides/parameters.ts
|
|
201
|
+
var parameters = {};
|
|
202
|
+
|
|
393
203
|
// ../connectors/src/connectors/google-slides/tools/request.ts
|
|
394
204
|
import { z } from "zod";
|
|
395
|
-
var
|
|
205
|
+
var SLIDES_BASE_URL2 = "https://slides.googleapis.com/v1/presentations";
|
|
396
206
|
var REQUEST_TIMEOUT_MS = 6e4;
|
|
207
|
+
var cachedToken = null;
|
|
208
|
+
async function getProxyToken(config) {
|
|
209
|
+
if (cachedToken && cachedToken.expiresAt > Date.now() + 6e4) {
|
|
210
|
+
return cachedToken.token;
|
|
211
|
+
}
|
|
212
|
+
const url = `${config.appApiBaseUrl}/v0/database/${config.projectId}/environment/${config.environmentId}/oauth-request-proxy-token`;
|
|
213
|
+
const res = await fetch(url, {
|
|
214
|
+
method: "POST",
|
|
215
|
+
headers: {
|
|
216
|
+
"Content-Type": "application/json",
|
|
217
|
+
"x-api-key": config.appApiKey,
|
|
218
|
+
"project-id": config.projectId
|
|
219
|
+
},
|
|
220
|
+
body: JSON.stringify({
|
|
221
|
+
sandboxId: config.sandboxId,
|
|
222
|
+
issuedBy: "coding-agent"
|
|
223
|
+
})
|
|
224
|
+
});
|
|
225
|
+
if (!res.ok) {
|
|
226
|
+
const errorText = await res.text().catch(() => res.statusText);
|
|
227
|
+
throw new Error(
|
|
228
|
+
`Failed to get proxy token: HTTP ${res.status} ${errorText}`
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
const data = await res.json();
|
|
232
|
+
cachedToken = {
|
|
233
|
+
token: data.token,
|
|
234
|
+
expiresAt: new Date(data.expiresAt).getTime()
|
|
235
|
+
};
|
|
236
|
+
return data.token;
|
|
237
|
+
}
|
|
397
238
|
var inputSchema = z.object({
|
|
398
239
|
toolUseIntent: z.string().optional().describe(
|
|
399
240
|
"Brief description of what you intend to accomplish with this tool call"
|
|
@@ -401,7 +242,7 @@ var inputSchema = z.object({
|
|
|
401
242
|
connectionId: z.string().describe("ID of the Google Slides connection to use"),
|
|
402
243
|
method: z.enum(["GET", "POST"]).describe("HTTP method"),
|
|
403
244
|
path: z.string().describe(
|
|
404
|
-
"API path appended to https://slides.googleapis.com/v1/presentations (e.g., '/{presentationId}', '/{presentationId}/pages/{pageId}').
|
|
245
|
+
"API path appended to https://slides.googleapis.com/v1/presentations (e.g., '', '/{presentationId}', '/{presentationId}/pages/{pageId}')."
|
|
405
246
|
),
|
|
406
247
|
body: z.record(z.string(), z.unknown()).optional().describe("JSON request body for POST requests"),
|
|
407
248
|
queryParams: z.record(z.string(), z.string()).optional().describe("Query parameters to append to the URL")
|
|
@@ -421,11 +262,10 @@ var requestTool = new ConnectorTool({
|
|
|
421
262
|
name: "request",
|
|
422
263
|
description: `Send authenticated requests to the Google Slides API v1.
|
|
423
264
|
Supports GET (read) and POST (create/update) methods.
|
|
424
|
-
Authentication is handled automatically
|
|
425
|
-
{presentationId} in the path is automatically replaced with the connection's default presentation ID if configured.`,
|
|
265
|
+
Authentication is handled automatically via OAuth proxy.`,
|
|
426
266
|
inputSchema,
|
|
427
267
|
outputSchema,
|
|
428
|
-
async execute({ connectionId, method, path: path2, body, queryParams }, connections) {
|
|
268
|
+
async execute({ connectionId, method, path: path2, body, queryParams }, connections, config) {
|
|
429
269
|
const connection2 = connections.find((c) => c.id === connectionId);
|
|
430
270
|
if (!connection2) {
|
|
431
271
|
return {
|
|
@@ -437,52 +277,33 @@ Authentication is handled automatically using a service account.
|
|
|
437
277
|
`[connector-request] google-slides/${connection2.name}: ${method} ${path2}`
|
|
438
278
|
);
|
|
439
279
|
try {
|
|
440
|
-
|
|
441
|
-
const keyJsonBase64 = parameters.serviceAccountKeyJsonBase64.getValue(connection2);
|
|
442
|
-
const presentationUrl = parameters.presentationUrl.tryGetValue(connection2);
|
|
443
|
-
const presentationId = presentationUrl ? extractPresentationId(presentationUrl) : void 0;
|
|
444
|
-
const credentials = JSON.parse(
|
|
445
|
-
Buffer.from(keyJsonBase64, "base64").toString("utf-8")
|
|
446
|
-
);
|
|
447
|
-
const auth = new GoogleAuth({
|
|
448
|
-
credentials,
|
|
449
|
-
scopes: [
|
|
450
|
-
"https://www.googleapis.com/auth/presentations",
|
|
451
|
-
"https://www.googleapis.com/auth/drive"
|
|
452
|
-
]
|
|
453
|
-
});
|
|
454
|
-
const token = await auth.getAccessToken();
|
|
455
|
-
if (!token) {
|
|
456
|
-
return {
|
|
457
|
-
success: false,
|
|
458
|
-
error: "Failed to obtain access token"
|
|
459
|
-
};
|
|
460
|
-
}
|
|
461
|
-
const resolvedPath = presentationId ? path2.replace(/\{presentationId\}/g, presentationId) : path2;
|
|
462
|
-
let url = `${BASE_URL}${resolvedPath.startsWith("/") ? "" : "/"}${resolvedPath}`;
|
|
280
|
+
let url = `${SLIDES_BASE_URL2}${path2 === "" || path2.startsWith("/") ? "" : "/"}${path2}`;
|
|
463
281
|
if (queryParams) {
|
|
464
282
|
const searchParams = new URLSearchParams(queryParams);
|
|
465
283
|
url += `?${searchParams.toString()}`;
|
|
466
284
|
}
|
|
285
|
+
const token = await getProxyToken(config.oauthProxy);
|
|
286
|
+
const proxyUrl = `https://${config.oauthProxy.sandboxId}.${config.oauthProxy.previewBaseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
467
287
|
const controller = new AbortController();
|
|
468
288
|
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
469
289
|
try {
|
|
470
|
-
const response = await fetch(
|
|
471
|
-
method,
|
|
290
|
+
const response = await fetch(proxyUrl, {
|
|
291
|
+
method: "POST",
|
|
472
292
|
headers: {
|
|
473
|
-
|
|
474
|
-
|
|
293
|
+
"Content-Type": "application/json",
|
|
294
|
+
Authorization: `Bearer ${token}`
|
|
475
295
|
},
|
|
476
|
-
|
|
296
|
+
body: JSON.stringify({
|
|
297
|
+
url,
|
|
298
|
+
method,
|
|
299
|
+
...body != null ? { body: JSON.stringify(body) } : {}
|
|
300
|
+
}),
|
|
477
301
|
signal: controller.signal
|
|
478
302
|
});
|
|
479
303
|
const data = await response.json();
|
|
480
304
|
if (!response.ok) {
|
|
481
|
-
const
|
|
482
|
-
return {
|
|
483
|
-
success: false,
|
|
484
|
-
error: errorObj?.message ?? `HTTP ${response.status} ${response.statusText}`
|
|
485
|
-
};
|
|
305
|
+
const errorMessage = typeof data?.error === "string" ? data.error : typeof data?.message === "string" ? data.message : `HTTP ${response.status} ${response.statusText}`;
|
|
306
|
+
return { success: false, error: errorMessage };
|
|
486
307
|
}
|
|
487
308
|
return { success: true, status: response.status, data };
|
|
488
309
|
} finally {
|
|
@@ -499,47 +320,62 @@ Authentication is handled automatically using a service account.
|
|
|
499
320
|
var tools = { request: requestTool };
|
|
500
321
|
var googleSlidesConnector = new ConnectorPlugin({
|
|
501
322
|
slug: "google-slides",
|
|
502
|
-
authType: AUTH_TYPES.
|
|
323
|
+
authType: AUTH_TYPES.OAUTH,
|
|
503
324
|
name: "Google Slides",
|
|
504
|
-
description: "Connect to Google Slides for presentation data access and creation using
|
|
325
|
+
description: "Connect to Google Slides for presentation data access and creation using OAuth.",
|
|
505
326
|
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/4oyF4yTRpemMA43X49masx/e1582d25e3b4c9a63ba83df2147c1968/google_slide.png",
|
|
506
327
|
parameters,
|
|
507
328
|
releaseFlag: { dev1: true, dev2: false, prod: false },
|
|
508
329
|
onboarding: googleSlidesOnboarding,
|
|
330
|
+
proxyPolicy: {
|
|
331
|
+
allowlist: [
|
|
332
|
+
{
|
|
333
|
+
host: "slides.googleapis.com",
|
|
334
|
+
methods: ["GET", "POST"]
|
|
335
|
+
}
|
|
336
|
+
]
|
|
337
|
+
},
|
|
509
338
|
systemPrompt: {
|
|
510
339
|
en: `### Tools
|
|
511
340
|
|
|
512
|
-
- \`google-slides_request\`:
|
|
341
|
+
- \`google-slides_request\`: The way to call the Google Slides API. Supports read and write operations. Use it to get presentation metadata, slide content, create new presentations, and modify slides. Authentication is configured automatically via OAuth.
|
|
513
342
|
|
|
514
343
|
### Google Slides API Reference
|
|
515
344
|
|
|
516
345
|
#### Read Endpoints
|
|
517
346
|
- GET \`/{presentationId}\` \u2014 Get presentation metadata (title, slides, layouts, masters)
|
|
518
|
-
- GET \`/{presentationId}/pages/{pageObjectId}\` \u2014 Get a specific slide page with all its elements
|
|
347
|
+
- GET \`/{presentationId}/pages/{pageObjectId}\` \u2014 Get a specific slide page with all its elements (shapes, text, images, tables)
|
|
519
348
|
|
|
520
349
|
#### Write Endpoints
|
|
521
350
|
- POST \`\` (empty path, with body) \u2014 Create a new presentation. Body: \`{ "title": "My Presentation" }\`
|
|
522
|
-
- POST \`/{presentationId}:batchUpdate\` \u2014 Apply multiple updates. Body: \`{ "requests": [...] }\`
|
|
351
|
+
- POST \`/{presentationId}:batchUpdate\` \u2014 Apply multiple updates to a presentation. Body: \`{ "requests": [...] }\`
|
|
523
352
|
|
|
524
353
|
#### Common batchUpdate Request Types
|
|
525
|
-
- \`createSlide\` \u2014 Add a new slide
|
|
526
|
-
- \`insertText\` \u2014 Insert text into a shape
|
|
527
|
-
- \`createShape\` \u2014 Add a shape to a slide
|
|
528
|
-
- \`createImage\` \u2014 Add an image
|
|
529
|
-
- \`deleteObject\` \u2014 Delete a page element or slide
|
|
530
|
-
- \`replaceAllText\` \u2014 Find & replace text
|
|
531
|
-
- \`updateTextStyle\` \u2014 Style text (bold, color, font)
|
|
354
|
+
- \`createSlide\` \u2014 Add a new slide: \`{ "createSlide": { "insertionIndex": 1, "slideLayoutReference": { "predefinedLayout": "BLANK" } } }\`
|
|
355
|
+
- \`insertText\` \u2014 Insert text into a shape: \`{ "insertText": { "objectId": "shapeId", "text": "Hello" } }\`
|
|
356
|
+
- \`createShape\` \u2014 Add a shape to a slide: \`{ "createShape": { "shapeType": "TEXT_BOX", "elementProperties": { "pageObjectId": "slideId", "size": {...}, "transform": {...} } } }\`
|
|
357
|
+
- \`createImage\` \u2014 Add an image: \`{ "createImage": { "url": "https://...", "elementProperties": { "pageObjectId": "slideId" } } }\`
|
|
358
|
+
- \`deleteObject\` \u2014 Delete a page element or slide: \`{ "deleteObject": { "objectId": "objectId" } }\`
|
|
359
|
+
- \`replaceAllText\` \u2014 Find & replace text: \`{ "replaceAllText": { "containsText": { "text": "old" }, "replaceText": "new" } }\`
|
|
360
|
+
- \`updateTextStyle\` \u2014 Style text (bold, color, font): \`{ "updateTextStyle": { "objectId": "shapeId", "style": { "bold": true }, "textRange": { "type": "ALL" }, "fields": "bold" } }\`
|
|
361
|
+
- \`updateShapeProperties\` \u2014 Update shape fill, outline, etc.
|
|
362
|
+
- \`createTable\` \u2014 Create a table on a slide
|
|
363
|
+
- \`insertTableRows\` / \`insertTableColumns\` \u2014 Add rows/columns to a table
|
|
364
|
+
- \`deleteTableRow\` / \`deleteTableColumn\` \u2014 Remove rows/columns
|
|
532
365
|
|
|
533
366
|
#### Predefined Slide Layouts
|
|
534
|
-
\`BLANK\`, \`TITLE\`, \`TITLE_AND_BODY\`, \`TITLE_AND_TWO_COLUMNS\`, \`TITLE_ONLY\`, \`SECTION_HEADER\`, \`ONE_COLUMN_TEXT\`, \`MAIN_POINT\`, \`BIG_NUMBER\`
|
|
367
|
+
\`BLANK\`, \`CAPTION_ONLY\`, \`TITLE\`, \`TITLE_AND_BODY\`, \`TITLE_AND_TWO_COLUMNS\`, \`TITLE_ONLY\`, \`SECTION_HEADER\`, \`SECTION_TITLE_AND_DESCRIPTION\`, \`ONE_COLUMN_TEXT\`, \`MAIN_POINT\`, \`BIG_NUMBER\`
|
|
535
368
|
|
|
536
369
|
### Tips
|
|
537
|
-
-
|
|
538
|
-
-
|
|
370
|
+
- To explore a presentation, first GET the presentation metadata to see available slide object IDs
|
|
371
|
+
- When inserting text or shapes, you need the \`pageObjectId\` of the target slide (from the metadata)
|
|
372
|
+
- batchUpdate requests are applied in order \u2014 use this for complex multi-step modifications
|
|
373
|
+
- Shape sizes and positions use EMU (English Metric Units): 1 inch = 914400 EMU, 1 pt = 12700 EMU
|
|
374
|
+
- Sharing (permissions) cannot be done via this connector; only the OAuth user has access to the created presentations
|
|
539
375
|
|
|
540
376
|
### Business Logic
|
|
541
377
|
|
|
542
|
-
The business logic type for this connector is "typescript". Write handler code using the connector SDK shown below.
|
|
378
|
+
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.
|
|
543
379
|
|
|
544
380
|
#### Example
|
|
545
381
|
|
|
@@ -548,47 +384,64 @@ import { connection } from "@squadbase/vite-server/connectors/google-slides";
|
|
|
548
384
|
|
|
549
385
|
const slides = connection("<connectionId>");
|
|
550
386
|
|
|
551
|
-
|
|
387
|
+
// Create a new presentation
|
|
388
|
+
const newPres = await slides.createPresentation("Quarterly Report");
|
|
389
|
+
const presentationId = newPres.presentationId;
|
|
390
|
+
|
|
391
|
+
// Get presentation metadata
|
|
392
|
+
const presentation = await slides.getPresentation(presentationId);
|
|
552
393
|
console.log(presentation.title, presentation.slides.length);
|
|
553
394
|
|
|
554
|
-
|
|
555
|
-
await slides.
|
|
395
|
+
// Get a specific slide's content
|
|
396
|
+
const page = await slides.getPage(presentationId, presentation.slides[0].objectId);
|
|
397
|
+
console.log(page.pageElements);
|
|
398
|
+
|
|
399
|
+
// Add a slide and insert text
|
|
400
|
+
await slides.batchUpdate(presentationId, [
|
|
556
401
|
{ createSlide: { insertionIndex: 1, slideLayoutReference: { predefinedLayout: "TITLE_AND_BODY" } } },
|
|
402
|
+
{ insertText: { objectId: "someShapeId", text: "Hello, World!" } },
|
|
557
403
|
]);
|
|
558
404
|
\`\`\``,
|
|
559
405
|
ja: `### \u30C4\u30FC\u30EB
|
|
560
406
|
|
|
561
|
-
- \`google-slides_request\`: Google Slides API
|
|
407
|
+
- \`google-slides_request\`: Google Slides API\u3092\u547C\u3073\u51FA\u3059\u624B\u6BB5\u3067\u3059\u3002\u8AAD\u307F\u53D6\u308A\u3068\u66F8\u304D\u8FBC\u307F\u306E\u4E21\u65B9\u3092\u30B5\u30DD\u30FC\u30C8\u3057\u307E\u3059\u3002\u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\u30FB\u30B9\u30E9\u30A4\u30C9\u5185\u5BB9\u306E\u53D6\u5F97\u3001\u65B0\u3057\u3044\u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u306E\u4F5C\u6210\u3001\u30B9\u30E9\u30A4\u30C9\u306E\u5909\u66F4\u306A\u3069\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002OAuth\u7D4C\u7531\u3067\u8A8D\u8A3C\u306F\u81EA\u52D5\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002
|
|
562
408
|
|
|
563
409
|
### Google Slides API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
|
|
564
410
|
|
|
565
411
|
#### \u8AAD\u307F\u53D6\u308A\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8
|
|
566
|
-
- GET \`/{presentationId}\` \u2014 \u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97
|
|
567
|
-
- GET \`/{presentationId}/pages/{pageObjectId}\` \u2014 \u7279\u5B9A\u306E\u30B9\u30E9\u30A4\u30C9\u30DA\u30FC\u30B8\u3068\u305D\u306E\u5168\u8981\u7D20\u3092\u53D6\u5F97
|
|
412
|
+
- GET \`/{presentationId}\` \u2014 \u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97\uFF08\u30BF\u30A4\u30C8\u30EB\u3001\u30B9\u30E9\u30A4\u30C9\u3001\u30EC\u30A4\u30A2\u30A6\u30C8\u3001\u30DE\u30B9\u30BF\u30FC\uFF09
|
|
413
|
+
- GET \`/{presentationId}/pages/{pageObjectId}\` \u2014 \u7279\u5B9A\u306E\u30B9\u30E9\u30A4\u30C9\u30DA\u30FC\u30B8\u3068\u305D\u306E\u5168\u8981\u7D20\uFF08\u56F3\u5F62\u3001\u30C6\u30AD\u30B9\u30C8\u3001\u753B\u50CF\u3001\u30C6\u30FC\u30D6\u30EB\uFF09\u3092\u53D6\u5F97
|
|
568
414
|
|
|
569
415
|
#### \u66F8\u304D\u8FBC\u307F\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8
|
|
570
416
|
- POST \`\`\uFF08\u7A7A\u30D1\u30B9\u3001\u30DC\u30C7\u30A3\u4ED8\u304D\uFF09\u2014 \u65B0\u3057\u3044\u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u3092\u4F5C\u6210\u3002Body: \`{ "title": "\u30DE\u30A4\u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3" }\`
|
|
571
|
-
- POST \`/{presentationId}:batchUpdate\` \u2014 \u8907\u6570\u306E\u66F4\u65B0\u3092\u9069\u7528\u3002Body: \`{ "requests": [...] }\`
|
|
417
|
+
- POST \`/{presentationId}:batchUpdate\` \u2014 \u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u306B\u8907\u6570\u306E\u66F4\u65B0\u3092\u9069\u7528\u3002Body: \`{ "requests": [...] }\`
|
|
572
418
|
|
|
573
419
|
#### \u4E3B\u306A batchUpdate \u30EA\u30AF\u30A8\u30B9\u30C8\u30BF\u30A4\u30D7
|
|
574
|
-
- \`createSlide\` \u2014 \u30B9\u30E9\u30A4\u30C9\u3092\u8FFD\u52A0
|
|
575
|
-
- \`insertText\` \u2014 \u30C6\u30AD\u30B9\u30C8\u3092\u633F\u5165
|
|
576
|
-
- \`createShape\` \u2014 \u56F3\u5F62\u3092\u8FFD\u52A0
|
|
577
|
-
- \`createImage\` \u2014 \u753B\u50CF\u3092\u8FFD\u52A0
|
|
578
|
-
- \`deleteObject\` \u2014 \u8981\u7D20\u307E\u305F\u306F\u30B9\u30E9\u30A4\u30C9\u3092\u524A\u9664
|
|
579
|
-
- \`replaceAllText\` \u2014 \u30C6\u30AD\u30B9\u30C8\u306E\u691C\u7D22\u3068\u7F6E\u63DB
|
|
580
|
-
- \`updateTextStyle\` \u2014 \u30C6\u30AD\u30B9\u30C8\u306E\u30B9\u30BF\u30A4\u30EB\u8A2D\u5B9A
|
|
420
|
+
- \`createSlide\` \u2014 \u30B9\u30E9\u30A4\u30C9\u3092\u8FFD\u52A0: \`{ "createSlide": { "insertionIndex": 1, "slideLayoutReference": { "predefinedLayout": "BLANK" } } }\`
|
|
421
|
+
- \`insertText\` \u2014 \u56F3\u5F62\u306B\u30C6\u30AD\u30B9\u30C8\u3092\u633F\u5165: \`{ "insertText": { "objectId": "shapeId", "text": "Hello" } }\`
|
|
422
|
+
- \`createShape\` \u2014 \u30B9\u30E9\u30A4\u30C9\u306B\u56F3\u5F62\u3092\u8FFD\u52A0: \`{ "createShape": { "shapeType": "TEXT_BOX", "elementProperties": { "pageObjectId": "slideId", "size": {...}, "transform": {...} } } }\`
|
|
423
|
+
- \`createImage\` \u2014 \u753B\u50CF\u3092\u8FFD\u52A0: \`{ "createImage": { "url": "https://...", "elementProperties": { "pageObjectId": "slideId" } } }\`
|
|
424
|
+
- \`deleteObject\` \u2014 \u30DA\u30FC\u30B8\u8981\u7D20\u307E\u305F\u306F\u30B9\u30E9\u30A4\u30C9\u3092\u524A\u9664: \`{ "deleteObject": { "objectId": "objectId" } }\`
|
|
425
|
+
- \`replaceAllText\` \u2014 \u30C6\u30AD\u30B9\u30C8\u306E\u691C\u7D22\u3068\u7F6E\u63DB: \`{ "replaceAllText": { "containsText": { "text": "\u53E4\u3044" }, "replaceText": "\u65B0\u3057\u3044" } }\`
|
|
426
|
+
- \`updateTextStyle\` \u2014 \u30C6\u30AD\u30B9\u30C8\u306E\u30B9\u30BF\u30A4\u30EB\u8A2D\u5B9A\uFF08\u592A\u5B57\u3001\u8272\u3001\u30D5\u30A9\u30F3\u30C8\uFF09: \`{ "updateTextStyle": { "objectId": "shapeId", "style": { "bold": true }, "textRange": { "type": "ALL" }, "fields": "bold" } }\`
|
|
427
|
+
- \`updateShapeProperties\` \u2014 \u56F3\u5F62\u306E\u5857\u308A\u3064\u3076\u3057\u3001\u30A2\u30A6\u30C8\u30E9\u30A4\u30F3\u306A\u3069\u3092\u66F4\u65B0
|
|
428
|
+
- \`createTable\` \u2014 \u30B9\u30E9\u30A4\u30C9\u306B\u30C6\u30FC\u30D6\u30EB\u3092\u4F5C\u6210
|
|
429
|
+
- \`insertTableRows\` / \`insertTableColumns\` \u2014 \u30C6\u30FC\u30D6\u30EB\u306B\u884C/\u5217\u3092\u8FFD\u52A0
|
|
430
|
+
- \`deleteTableRow\` / \`deleteTableColumn\` \u2014 \u884C/\u5217\u3092\u524A\u9664
|
|
581
431
|
|
|
582
432
|
#### \u5B9A\u7FA9\u6E08\u307F\u30B9\u30E9\u30A4\u30C9\u30EC\u30A4\u30A2\u30A6\u30C8
|
|
583
|
-
\`BLANK\`, \`TITLE\`, \`TITLE_AND_BODY\`, \`TITLE_AND_TWO_COLUMNS\`, \`TITLE_ONLY\`, \`SECTION_HEADER\`, \`ONE_COLUMN_TEXT\`, \`MAIN_POINT\`, \`BIG_NUMBER\`
|
|
433
|
+
\`BLANK\`, \`CAPTION_ONLY\`, \`TITLE\`, \`TITLE_AND_BODY\`, \`TITLE_AND_TWO_COLUMNS\`, \`TITLE_ONLY\`, \`SECTION_HEADER\`, \`SECTION_TITLE_AND_DESCRIPTION\`, \`ONE_COLUMN_TEXT\`, \`MAIN_POINT\`, \`BIG_NUMBER\`
|
|
584
434
|
|
|
585
435
|
### \u30D2\u30F3\u30C8
|
|
586
|
-
- \
|
|
587
|
-
- \u56F3\u5F62\
|
|
436
|
+
- \u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u3092\u63A2\u7D22\u3059\u308B\u306B\u306F\u3001\u307E\u305AGET\u3067\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97\u3057\u3066\u5229\u7528\u53EF\u80FD\u306A\u30B9\u30E9\u30A4\u30C9\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8ID\u3092\u78BA\u8A8D\u3057\u307E\u3059
|
|
437
|
+
- \u30C6\u30AD\u30B9\u30C8\u3084\u56F3\u5F62\u3092\u633F\u5165\u3059\u308B\u969B\u306F\u3001\u5BFE\u8C61\u30B9\u30E9\u30A4\u30C9\u306E \`pageObjectId\` \u304C\u5FC5\u8981\u3067\u3059\uFF08\u30E1\u30BF\u30C7\u30FC\u30BF\u304B\u3089\u53D6\u5F97\uFF09
|
|
438
|
+
- batchUpdate\u30EA\u30AF\u30A8\u30B9\u30C8\u306F\u9806\u756A\u306B\u9069\u7528\u3055\u308C\u307E\u3059 \u2014 \u8907\u96D1\u306A\u8907\u6570\u30B9\u30C6\u30C3\u30D7\u306E\u5909\u66F4\u306B\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044
|
|
439
|
+
- \u56F3\u5F62\u306E\u30B5\u30A4\u30BA\u3068\u4F4D\u7F6E\u306FEMU\uFF08English Metric Units\uFF09\u3092\u4F7F\u7528: 1\u30A4\u30F3\u30C1 = 914400 EMU\u30011pt = 12700 EMU
|
|
440
|
+
- \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\u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u3078\u306F\u63A5\u7D9A\u3057\u305FOAuth\u30E6\u30FC\u30B6\u30FC\u306E\u307F\u304C\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u3067\u3059
|
|
588
441
|
|
|
589
442
|
### Business Logic
|
|
590
443
|
|
|
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\
|
|
444
|
+
\u3053\u306E\u30B3\u30CD\u30AF\u30BF\u306E\u30D3\u30B8\u30CD\u30B9\u30ED\u30B8\u30C3\u30AF\u30BF\u30A4\u30D7\u306F "typescript" \u3067\u3059\u3002\u4EE5\u4E0B\u306B\u793A\u3059\u30B3\u30CD\u30AF\u30BFSDK\u3092\u4F7F\u7528\u3057\u3066\u30CF\u30F3\u30C9\u30E9\u30B3\u30FC\u30C9\u3092\u8A18\u8FF0\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u74B0\u5883\u5909\u6570\u304B\u3089\u76F4\u63A5\u8A8D\u8A3C\u60C5\u5831\u306B\u30A2\u30AF\u30BB\u30B9\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
|
|
592
445
|
|
|
593
446
|
#### Example
|
|
594
447
|
|
|
@@ -597,12 +450,22 @@ import { connection } from "@squadbase/vite-server/connectors/google-slides";
|
|
|
597
450
|
|
|
598
451
|
const slides = connection("<connectionId>");
|
|
599
452
|
|
|
600
|
-
|
|
453
|
+
// \u65B0\u3057\u3044\u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u3092\u4F5C\u6210
|
|
454
|
+
const newPres = await slides.createPresentation("\u56DB\u534A\u671F\u30EC\u30DD\u30FC\u30C8");
|
|
455
|
+
const presentationId = newPres.presentationId;
|
|
456
|
+
|
|
457
|
+
// \u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97
|
|
458
|
+
const presentation = await slides.getPresentation(presentationId);
|
|
601
459
|
console.log(presentation.title, presentation.slides.length);
|
|
602
460
|
|
|
603
|
-
|
|
604
|
-
await slides.
|
|
461
|
+
// \u7279\u5B9A\u306E\u30B9\u30E9\u30A4\u30C9\u306E\u5185\u5BB9\u3092\u53D6\u5F97
|
|
462
|
+
const page = await slides.getPage(presentationId, presentation.slides[0].objectId);
|
|
463
|
+
console.log(page.pageElements);
|
|
464
|
+
|
|
465
|
+
// \u30B9\u30E9\u30A4\u30C9\u3092\u8FFD\u52A0\u3057\u3066\u30C6\u30AD\u30B9\u30C8\u3092\u633F\u5165
|
|
466
|
+
await slides.batchUpdate(presentationId, [
|
|
605
467
|
{ createSlide: { insertionIndex: 1, slideLayoutReference: { predefinedLayout: "TITLE_AND_BODY" } } },
|
|
468
|
+
{ insertText: { objectId: "someShapeId", text: "Hello, World!" } },
|
|
606
469
|
]);
|
|
607
470
|
\`\`\``
|
|
608
471
|
},
|