@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,287 +1,145 @@
|
|
|
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-drive/sdk/index.ts
|
|
46
|
-
import * as crypto from "crypto";
|
|
47
|
-
|
|
48
|
-
// ../connectors/src/connectors/google-drive/parameters.ts
|
|
49
|
-
var parameters = {
|
|
50
|
-
serviceAccountKeyJsonBase64: new ParameterDefinition({
|
|
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 Drive.",
|
|
54
|
-
envVarBaseKey: "GOOGLE_DRIVE_SERVICE_ACCOUNT_JSON_BASE64",
|
|
55
|
-
type: "base64EncodedJson",
|
|
56
|
-
secret: true,
|
|
57
|
-
required: true
|
|
58
|
-
}),
|
|
59
|
-
folderId: new ParameterDefinition({
|
|
60
|
-
slug: "folder-id",
|
|
61
|
-
name: "Google Drive Folder ID",
|
|
62
|
-
description: "The ID of a default Google Drive folder to scope operations to (e.g., from the folder URL: https://drive.google.com/drive/folders/{folderId}). Optional \u2014 if not set, operations target the root of My Drive.",
|
|
63
|
-
envVarBaseKey: "GOOGLE_DRIVE_FOLDER_ID",
|
|
64
|
-
type: "text",
|
|
65
|
-
secret: false,
|
|
66
|
-
required: false
|
|
67
|
-
})
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
// ../connectors/src/connectors/google-drive-oauth/utils.ts
|
|
71
|
-
var FOLDER_URL_PATTERN = /drive\.google\.com\/drive\/folders\/([a-zA-Z0-9_-]+)/;
|
|
72
|
-
function extractFolderId(urlOrId) {
|
|
73
|
-
const trimmed = urlOrId.trim();
|
|
74
|
-
const match = trimmed.match(FOLDER_URL_PATTERN);
|
|
75
|
-
if (match) {
|
|
76
|
-
return match[1];
|
|
77
|
-
}
|
|
78
|
-
return trimmed;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
1
|
// ../connectors/src/connectors/google-drive/sdk/index.ts
|
|
82
|
-
var TOKEN_URL = "https://oauth2.googleapis.com/token";
|
|
83
2
|
var BASE_URL = "https://www.googleapis.com/drive/v3";
|
|
84
|
-
var SCOPE = "https://www.googleapis.com/auth/drive";
|
|
85
|
-
function base64url(input) {
|
|
86
|
-
const buf = typeof input === "string" ? Buffer.from(input) : input;
|
|
87
|
-
return buf.toString("base64url");
|
|
88
|
-
}
|
|
89
|
-
function buildJwt(clientEmail, privateKey, nowSec) {
|
|
90
|
-
const header = base64url(JSON.stringify({ alg: "RS256", typ: "JWT" }));
|
|
91
|
-
const payload = base64url(
|
|
92
|
-
JSON.stringify({
|
|
93
|
-
iss: clientEmail,
|
|
94
|
-
scope: SCOPE,
|
|
95
|
-
aud: TOKEN_URL,
|
|
96
|
-
iat: nowSec,
|
|
97
|
-
exp: nowSec + 3600
|
|
98
|
-
})
|
|
99
|
-
);
|
|
100
|
-
const signingInput = `${header}.${payload}`;
|
|
101
|
-
const sign = crypto.createSign("RSA-SHA256");
|
|
102
|
-
sign.update(signingInput);
|
|
103
|
-
sign.end();
|
|
104
|
-
const signature = base64url(sign.sign(privateKey));
|
|
105
|
-
return `${signingInput}.${signature}`;
|
|
106
|
-
}
|
|
107
3
|
var DEFAULT_FILE_FIELDS = "id,name,mimeType,parents,webViewLink,webContentLink,createdTime,modifiedTime,size,starred,trashed,shared,owners";
|
|
108
|
-
function createClient(
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
if (!serviceAccountKeyJsonBase64) {
|
|
113
|
-
throw new Error(
|
|
114
|
-
`google-drive: missing required parameter: ${parameters.serviceAccountKeyJsonBase64.slug}`
|
|
115
|
-
);
|
|
4
|
+
function createClient(_params, fetchFn = fetch) {
|
|
5
|
+
function request(path2, init) {
|
|
6
|
+
const url = `${BASE_URL}${path2.startsWith("/") ? "" : "/"}${path2}`;
|
|
7
|
+
return fetchFn(url, init);
|
|
116
8
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
).
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
)
|
|
9
|
+
async function listFiles(options) {
|
|
10
|
+
const searchParams = new URLSearchParams();
|
|
11
|
+
const query = options?.query ?? "";
|
|
12
|
+
if (query) searchParams.set("q", query);
|
|
13
|
+
if (options?.pageSize) searchParams.set("pageSize", String(options.pageSize));
|
|
14
|
+
if (options?.pageToken) searchParams.set("pageToken", options.pageToken);
|
|
15
|
+
if (options?.orderBy) searchParams.set("orderBy", options.orderBy);
|
|
16
|
+
searchParams.set("fields", options?.fields ?? `nextPageToken,files(${DEFAULT_FILE_FIELDS})`);
|
|
17
|
+
const url = `${BASE_URL}/files?${searchParams.toString()}`;
|
|
18
|
+
const response = await fetchFn(url);
|
|
19
|
+
if (!response.ok) {
|
|
20
|
+
const body = await response.text();
|
|
21
|
+
throw new Error(
|
|
22
|
+
`google-drive: listFiles failed (${response.status}): ${body}`
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
return await response.json();
|
|
128
26
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
)
|
|
27
|
+
async function getFile(fileId, fields) {
|
|
28
|
+
const url = `${BASE_URL}/files/${fileId}?fields=${fields ?? DEFAULT_FILE_FIELDS}`;
|
|
29
|
+
const response = await fetchFn(url);
|
|
30
|
+
if (!response.ok) {
|
|
31
|
+
const body = await response.text();
|
|
32
|
+
throw new Error(
|
|
33
|
+
`google-drive: getFile failed (${response.status}): ${body}`
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
return await response.json();
|
|
133
37
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
if (
|
|
139
|
-
|
|
38
|
+
async function createFile(options) {
|
|
39
|
+
const metadata = { name: options.name };
|
|
40
|
+
if (options.mimeType) metadata.mimeType = options.mimeType;
|
|
41
|
+
if (options.description) metadata.description = options.description;
|
|
42
|
+
if (options.parents) {
|
|
43
|
+
metadata.parents = options.parents;
|
|
140
44
|
}
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
serviceAccountKey.private_key,
|
|
144
|
-
nowSec
|
|
145
|
-
);
|
|
146
|
-
const response = await fetch(TOKEN_URL, {
|
|
45
|
+
const url = `${BASE_URL}/files?fields=${DEFAULT_FILE_FIELDS}`;
|
|
46
|
+
const response = await fetchFn(url, {
|
|
147
47
|
method: "POST",
|
|
148
|
-
headers: { "Content-Type": "application/
|
|
149
|
-
body:
|
|
150
|
-
grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
|
|
151
|
-
assertion: jwt
|
|
152
|
-
})
|
|
48
|
+
headers: { "Content-Type": "application/json" },
|
|
49
|
+
body: JSON.stringify(metadata)
|
|
153
50
|
});
|
|
154
51
|
if (!response.ok) {
|
|
155
|
-
const
|
|
52
|
+
const body = await response.text();
|
|
156
53
|
throw new Error(
|
|
157
|
-
`google-drive:
|
|
54
|
+
`google-drive: createFile failed (${response.status}): ${body}`
|
|
158
55
|
);
|
|
159
56
|
}
|
|
160
|
-
|
|
161
|
-
cachedToken = data.access_token;
|
|
162
|
-
tokenExpiresAt = nowSec + data.expires_in;
|
|
163
|
-
return cachedToken;
|
|
57
|
+
return await response.json();
|
|
164
58
|
}
|
|
165
|
-
async function
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
if (
|
|
170
|
-
|
|
59
|
+
async function updateFile(fileId, metadata, addParents, removeParents) {
|
|
60
|
+
const searchParams = new URLSearchParams();
|
|
61
|
+
searchParams.set("fields", DEFAULT_FILE_FIELDS);
|
|
62
|
+
if (addParents) searchParams.set("addParents", addParents);
|
|
63
|
+
if (removeParents) searchParams.set("removeParents", removeParents);
|
|
64
|
+
const url = `${BASE_URL}/files/${fileId}?${searchParams.toString()}`;
|
|
65
|
+
const response = await fetchFn(url, {
|
|
66
|
+
method: "PATCH",
|
|
67
|
+
headers: { "Content-Type": "application/json" },
|
|
68
|
+
body: JSON.stringify(metadata)
|
|
69
|
+
});
|
|
70
|
+
if (!response.ok) {
|
|
71
|
+
const body = await response.text();
|
|
72
|
+
throw new Error(
|
|
73
|
+
`google-drive: updateFile failed (${response.status}): ${body}`
|
|
74
|
+
);
|
|
171
75
|
}
|
|
172
|
-
return
|
|
76
|
+
return await response.json();
|
|
173
77
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if (options?.pageToken) searchParams.set("pageToken", options.pageToken);
|
|
189
|
-
if (options?.orderBy) searchParams.set("orderBy", options.orderBy);
|
|
190
|
-
searchParams.set("fields", options?.fields ?? `nextPageToken,files(${DEFAULT_FILE_FIELDS})`);
|
|
191
|
-
const response = await authenticatedFetch(`${BASE_URL}/files?${searchParams.toString()}`);
|
|
192
|
-
if (!response.ok) {
|
|
193
|
-
const body = await response.text();
|
|
194
|
-
throw new Error(`google-drive: listFiles failed (${response.status}): ${body}`);
|
|
195
|
-
}
|
|
196
|
-
return await response.json();
|
|
197
|
-
},
|
|
198
|
-
async getFile(fileId, fields) {
|
|
199
|
-
const response = await authenticatedFetch(
|
|
200
|
-
`${BASE_URL}/files/${fileId}?fields=${fields ?? DEFAULT_FILE_FIELDS}`
|
|
78
|
+
async function copyFile(fileId, name, parents) {
|
|
79
|
+
const metadata = {};
|
|
80
|
+
if (name) metadata.name = name;
|
|
81
|
+
if (parents) metadata.parents = parents;
|
|
82
|
+
const url = `${BASE_URL}/files/${fileId}/copy?fields=${DEFAULT_FILE_FIELDS}`;
|
|
83
|
+
const response = await fetchFn(url, {
|
|
84
|
+
method: "POST",
|
|
85
|
+
headers: { "Content-Type": "application/json" },
|
|
86
|
+
body: JSON.stringify(metadata)
|
|
87
|
+
});
|
|
88
|
+
if (!response.ok) {
|
|
89
|
+
const body = await response.text();
|
|
90
|
+
throw new Error(
|
|
91
|
+
`google-drive: copyFile failed (${response.status}): ${body}`
|
|
201
92
|
);
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
if (options.parents) {
|
|
213
|
-
metadata.parents = options.parents;
|
|
214
|
-
} else if (defaultFolderId) {
|
|
215
|
-
metadata.parents = [defaultFolderId];
|
|
216
|
-
}
|
|
217
|
-
const response = await authenticatedFetch(`${BASE_URL}/files?fields=${DEFAULT_FILE_FIELDS}`, {
|
|
218
|
-
method: "POST",
|
|
219
|
-
body: JSON.stringify(metadata)
|
|
220
|
-
});
|
|
221
|
-
if (!response.ok) {
|
|
222
|
-
const body = await response.text();
|
|
223
|
-
throw new Error(`google-drive: createFile failed (${response.status}): ${body}`);
|
|
224
|
-
}
|
|
225
|
-
return await response.json();
|
|
226
|
-
},
|
|
227
|
-
async updateFile(fileId, metadata, addParents, removeParents) {
|
|
228
|
-
const sp = new URLSearchParams();
|
|
229
|
-
sp.set("fields", DEFAULT_FILE_FIELDS);
|
|
230
|
-
if (addParents) sp.set("addParents", addParents);
|
|
231
|
-
if (removeParents) sp.set("removeParents", removeParents);
|
|
232
|
-
const response = await authenticatedFetch(`${BASE_URL}/files/${fileId}?${sp.toString()}`, {
|
|
233
|
-
method: "PATCH",
|
|
234
|
-
body: JSON.stringify(metadata)
|
|
235
|
-
});
|
|
236
|
-
if (!response.ok) {
|
|
237
|
-
const body = await response.text();
|
|
238
|
-
throw new Error(`google-drive: updateFile failed (${response.status}): ${body}`);
|
|
239
|
-
}
|
|
240
|
-
return await response.json();
|
|
241
|
-
},
|
|
242
|
-
async copyFile(fileId, name, parents) {
|
|
243
|
-
const metadata = {};
|
|
244
|
-
if (name) metadata.name = name;
|
|
245
|
-
if (parents) metadata.parents = parents;
|
|
246
|
-
const response = await authenticatedFetch(`${BASE_URL}/files/${fileId}/copy?fields=${DEFAULT_FILE_FIELDS}`, {
|
|
247
|
-
method: "POST",
|
|
248
|
-
body: JSON.stringify(metadata)
|
|
249
|
-
});
|
|
250
|
-
if (!response.ok) {
|
|
251
|
-
const body = await response.text();
|
|
252
|
-
throw new Error(`google-drive: copyFile failed (${response.status}): ${body}`);
|
|
253
|
-
}
|
|
254
|
-
return await response.json();
|
|
255
|
-
},
|
|
256
|
-
async listPermissions(fileId) {
|
|
257
|
-
const response = await authenticatedFetch(
|
|
258
|
-
`${BASE_URL}/files/${fileId}/permissions?fields=permissions(id,type,role,emailAddress,displayName)`
|
|
93
|
+
}
|
|
94
|
+
return await response.json();
|
|
95
|
+
}
|
|
96
|
+
async function listPermissions(fileId) {
|
|
97
|
+
const url = `${BASE_URL}/files/${fileId}/permissions?fields=permissions(id,type,role,emailAddress,displayName)`;
|
|
98
|
+
const response = await fetchFn(url);
|
|
99
|
+
if (!response.ok) {
|
|
100
|
+
const body = await response.text();
|
|
101
|
+
throw new Error(
|
|
102
|
+
`google-drive: listPermissions failed (${response.status}): ${body}`
|
|
259
103
|
);
|
|
260
|
-
if (!response.ok) {
|
|
261
|
-
const body = await response.text();
|
|
262
|
-
throw new Error(`google-drive: listPermissions failed (${response.status}): ${body}`);
|
|
263
|
-
}
|
|
264
|
-
return await response.json();
|
|
265
|
-
},
|
|
266
|
-
async shareFile(fileId, type, role, emailAddress) {
|
|
267
|
-
const permission = { type, role };
|
|
268
|
-
if (emailAddress) permission.emailAddress = emailAddress;
|
|
269
|
-
const response = await authenticatedFetch(`${BASE_URL}/files/${fileId}/permissions`, {
|
|
270
|
-
method: "POST",
|
|
271
|
-
body: JSON.stringify(permission)
|
|
272
|
-
});
|
|
273
|
-
if (!response.ok) {
|
|
274
|
-
const body = await response.text();
|
|
275
|
-
throw new Error(`google-drive: shareFile failed (${response.status}): ${body}`);
|
|
276
|
-
}
|
|
277
|
-
return await response.json();
|
|
278
|
-
},
|
|
279
|
-
downloadFile(fileId) {
|
|
280
|
-
return authenticatedFetch(`${BASE_URL}/files/${fileId}?alt=media`);
|
|
281
|
-
},
|
|
282
|
-
exportFile(fileId, mimeType) {
|
|
283
|
-
return authenticatedFetch(`${BASE_URL}/files/${fileId}/export?mimeType=${encodeURIComponent(mimeType)}`);
|
|
284
104
|
}
|
|
105
|
+
return await response.json();
|
|
106
|
+
}
|
|
107
|
+
async function shareFile(fileId, type, role, emailAddress) {
|
|
108
|
+
const permission = { type, role };
|
|
109
|
+
if (emailAddress) permission.emailAddress = emailAddress;
|
|
110
|
+
const url = `${BASE_URL}/files/${fileId}/permissions`;
|
|
111
|
+
const response = await fetchFn(url, {
|
|
112
|
+
method: "POST",
|
|
113
|
+
headers: { "Content-Type": "application/json" },
|
|
114
|
+
body: JSON.stringify(permission)
|
|
115
|
+
});
|
|
116
|
+
if (!response.ok) {
|
|
117
|
+
const body = await response.text();
|
|
118
|
+
throw new Error(
|
|
119
|
+
`google-drive: shareFile failed (${response.status}): ${body}`
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
return await response.json();
|
|
123
|
+
}
|
|
124
|
+
function downloadFile(fileId) {
|
|
125
|
+
const url = `${BASE_URL}/files/${fileId}?alt=media`;
|
|
126
|
+
return fetchFn(url);
|
|
127
|
+
}
|
|
128
|
+
function exportFile(fileId, mimeType) {
|
|
129
|
+
const url = `${BASE_URL}/files/${fileId}/export?mimeType=${encodeURIComponent(mimeType)}`;
|
|
130
|
+
return fetchFn(url);
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
request,
|
|
134
|
+
listFiles,
|
|
135
|
+
getFile,
|
|
136
|
+
createFile,
|
|
137
|
+
updateFile,
|
|
138
|
+
copyFile,
|
|
139
|
+
listPermissions,
|
|
140
|
+
shareFile,
|
|
141
|
+
downloadFile,
|
|
142
|
+
exportFile
|
|
285
143
|
};
|
|
286
144
|
}
|
|
287
145
|
|
|
@@ -367,16 +225,27 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
367
225
|
* Filters connections by connectorKey internally.
|
|
368
226
|
* Returns tools keyed as `${connectorKey}_${toolName}`.
|
|
369
227
|
*/
|
|
370
|
-
createTools(connections, config) {
|
|
228
|
+
createTools(connections, config, opts) {
|
|
371
229
|
const myConnections = connections.filter(
|
|
372
230
|
(c) => _ConnectorPlugin.deriveKey(c.connector.slug, c.connector.authType) === this.connectorKey
|
|
373
231
|
);
|
|
374
232
|
const result = {};
|
|
375
233
|
for (const t of Object.values(this.tools)) {
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
234
|
+
const tool = t.createTool(myConnections, config);
|
|
235
|
+
const originalToModelOutput = tool.toModelOutput;
|
|
236
|
+
result[`${this.connectorKey}_${t.name}`] = {
|
|
237
|
+
...tool,
|
|
238
|
+
toModelOutput: async (options) => {
|
|
239
|
+
if (!originalToModelOutput) {
|
|
240
|
+
return opts.truncateOutput(options.output);
|
|
241
|
+
}
|
|
242
|
+
const modelOutput = await originalToModelOutput(options);
|
|
243
|
+
if (modelOutput.type === "text" || modelOutput.type === "json") {
|
|
244
|
+
return opts.truncateOutput(modelOutput.value);
|
|
245
|
+
}
|
|
246
|
+
return modelOutput;
|
|
247
|
+
}
|
|
248
|
+
};
|
|
380
249
|
}
|
|
381
250
|
return result;
|
|
382
251
|
}
|
|
@@ -405,10 +274,44 @@ var googleDriveOnboarding = new ConnectorOnboarding({
|
|
|
405
274
|
}
|
|
406
275
|
});
|
|
407
276
|
|
|
277
|
+
// ../connectors/src/connectors/google-drive/parameters.ts
|
|
278
|
+
var parameters = {};
|
|
279
|
+
|
|
408
280
|
// ../connectors/src/connectors/google-drive/tools/request.ts
|
|
409
281
|
import { z } from "zod";
|
|
410
282
|
var BASE_URL2 = "https://www.googleapis.com/drive/v3";
|
|
411
283
|
var REQUEST_TIMEOUT_MS = 6e4;
|
|
284
|
+
var cachedToken = null;
|
|
285
|
+
async function getProxyToken(config) {
|
|
286
|
+
if (cachedToken && cachedToken.expiresAt > Date.now() + 6e4) {
|
|
287
|
+
return cachedToken.token;
|
|
288
|
+
}
|
|
289
|
+
const url = `${config.appApiBaseUrl}/v0/database/${config.projectId}/environment/${config.environmentId}/oauth-request-proxy-token`;
|
|
290
|
+
const res = await fetch(url, {
|
|
291
|
+
method: "POST",
|
|
292
|
+
headers: {
|
|
293
|
+
"Content-Type": "application/json",
|
|
294
|
+
"x-api-key": config.appApiKey,
|
|
295
|
+
"project-id": config.projectId
|
|
296
|
+
},
|
|
297
|
+
body: JSON.stringify({
|
|
298
|
+
sandboxId: config.sandboxId,
|
|
299
|
+
issuedBy: "coding-agent"
|
|
300
|
+
})
|
|
301
|
+
});
|
|
302
|
+
if (!res.ok) {
|
|
303
|
+
const errorText = await res.text().catch(() => res.statusText);
|
|
304
|
+
throw new Error(
|
|
305
|
+
`Failed to get proxy token: HTTP ${res.status} ${errorText}`
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
const data = await res.json();
|
|
309
|
+
cachedToken = {
|
|
310
|
+
token: data.token,
|
|
311
|
+
expiresAt: new Date(data.expiresAt).getTime()
|
|
312
|
+
};
|
|
313
|
+
return data.token;
|
|
314
|
+
}
|
|
412
315
|
var inputSchema = z.object({
|
|
413
316
|
toolUseIntent: z.string().optional().describe(
|
|
414
317
|
"Brief description of what you intend to accomplish with this tool call"
|
|
@@ -416,7 +319,7 @@ var inputSchema = z.object({
|
|
|
416
319
|
connectionId: z.string().describe("ID of the Google Drive connection to use"),
|
|
417
320
|
method: z.enum(["GET", "POST", "PATCH"]).describe("HTTP method"),
|
|
418
321
|
path: z.string().describe(
|
|
419
|
-
"API path appended to https://www.googleapis.com/drive/v3 (e.g., '/files', '/files/{fileId}')."
|
|
322
|
+
"API path appended to https://www.googleapis.com/drive/v3 (e.g., '/files', '/files/{fileId}', '/files/{fileId}/permissions')."
|
|
420
323
|
),
|
|
421
324
|
body: z.record(z.string(), z.unknown()).optional().describe("JSON request body for POST/PATCH requests"),
|
|
422
325
|
queryParams: z.record(z.string(), z.string()).optional().describe("Query parameters to append to the URL")
|
|
@@ -425,7 +328,7 @@ var outputSchema = z.discriminatedUnion("success", [
|
|
|
425
328
|
z.object({
|
|
426
329
|
success: z.literal(true),
|
|
427
330
|
status: z.number(),
|
|
428
|
-
data: z.unknown()
|
|
331
|
+
data: z.record(z.string(), z.unknown())
|
|
429
332
|
}),
|
|
430
333
|
z.object({
|
|
431
334
|
success: z.literal(false),
|
|
@@ -436,10 +339,10 @@ var requestTool = new ConnectorTool({
|
|
|
436
339
|
name: "request",
|
|
437
340
|
description: `Send authenticated requests to the Google Drive API v3.
|
|
438
341
|
Supports GET (read/list/download), POST (create/copy), and PATCH (update) methods.
|
|
439
|
-
Authentication is handled automatically
|
|
342
|
+
Authentication is handled automatically via OAuth proxy.`,
|
|
440
343
|
inputSchema,
|
|
441
344
|
outputSchema,
|
|
442
|
-
async execute({ connectionId, method, path: path2, body, queryParams }, connections) {
|
|
345
|
+
async execute({ connectionId, method, path: path2, body, queryParams }, connections, config) {
|
|
443
346
|
const connection2 = connections.find((c) => c.id === connectionId);
|
|
444
347
|
if (!connection2) {
|
|
445
348
|
return {
|
|
@@ -451,46 +354,33 @@ Authentication is handled automatically using a service account.`,
|
|
|
451
354
|
`[connector-request] google-drive/${connection2.name}: ${method} ${path2}`
|
|
452
355
|
);
|
|
453
356
|
try {
|
|
454
|
-
const { GoogleAuth } = await import("google-auth-library");
|
|
455
|
-
const keyJsonBase64 = parameters.serviceAccountKeyJsonBase64.getValue(connection2);
|
|
456
|
-
const credentials = JSON.parse(
|
|
457
|
-
Buffer.from(keyJsonBase64, "base64").toString("utf-8")
|
|
458
|
-
);
|
|
459
|
-
const auth = new GoogleAuth({
|
|
460
|
-
credentials,
|
|
461
|
-
scopes: ["https://www.googleapis.com/auth/drive"]
|
|
462
|
-
});
|
|
463
|
-
const token = await auth.getAccessToken();
|
|
464
|
-
if (!token) {
|
|
465
|
-
return {
|
|
466
|
-
success: false,
|
|
467
|
-
error: "Failed to obtain access token"
|
|
468
|
-
};
|
|
469
|
-
}
|
|
470
357
|
let url = `${BASE_URL2}${path2.startsWith("/") ? "" : "/"}${path2}`;
|
|
471
358
|
if (queryParams) {
|
|
472
359
|
const searchParams = new URLSearchParams(queryParams);
|
|
473
360
|
url += `?${searchParams.toString()}`;
|
|
474
361
|
}
|
|
362
|
+
const token = await getProxyToken(config.oauthProxy);
|
|
363
|
+
const proxyUrl = `https://${config.oauthProxy.sandboxId}.${config.oauthProxy.previewBaseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
475
364
|
const controller = new AbortController();
|
|
476
365
|
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
477
366
|
try {
|
|
478
|
-
const response = await fetch(
|
|
479
|
-
method,
|
|
367
|
+
const response = await fetch(proxyUrl, {
|
|
368
|
+
method: "POST",
|
|
480
369
|
headers: {
|
|
481
|
-
|
|
482
|
-
|
|
370
|
+
"Content-Type": "application/json",
|
|
371
|
+
Authorization: `Bearer ${token}`
|
|
483
372
|
},
|
|
484
|
-
|
|
373
|
+
body: JSON.stringify({
|
|
374
|
+
url,
|
|
375
|
+
method,
|
|
376
|
+
...body != null ? { body: JSON.stringify(body) } : {}
|
|
377
|
+
}),
|
|
485
378
|
signal: controller.signal
|
|
486
379
|
});
|
|
487
380
|
const data = await response.json();
|
|
488
381
|
if (!response.ok) {
|
|
489
|
-
const
|
|
490
|
-
return {
|
|
491
|
-
success: false,
|
|
492
|
-
error: errorObj?.error?.message ?? `HTTP ${response.status} ${response.statusText}`
|
|
493
|
-
};
|
|
382
|
+
const errorMessage = typeof data?.error === "string" ? data.error : typeof data?.message === "string" ? data.message : `HTTP ${response.status} ${response.statusText}`;
|
|
383
|
+
return { success: false, error: errorMessage };
|
|
494
384
|
}
|
|
495
385
|
return { success: true, status: response.status, data };
|
|
496
386
|
} finally {
|
|
@@ -507,47 +397,93 @@ Authentication is handled automatically using a service account.`,
|
|
|
507
397
|
var tools = { request: requestTool };
|
|
508
398
|
var googleDriveConnector = new ConnectorPlugin({
|
|
509
399
|
slug: "google-drive",
|
|
510
|
-
authType: AUTH_TYPES.
|
|
400
|
+
authType: AUTH_TYPES.OAUTH,
|
|
511
401
|
name: "Google Drive",
|
|
512
|
-
description: "Connect to Google Drive for file management, sharing, and collaboration using
|
|
402
|
+
description: "Connect to Google Drive for file management, sharing, and collaboration using OAuth.",
|
|
513
403
|
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/4GJX5yQTogUgar1buWxXbv/4b43a65353319c508111489f834d22c4/google_drive.png",
|
|
514
404
|
parameters,
|
|
515
405
|
releaseFlag: { dev1: true, dev2: false, prod: false },
|
|
516
406
|
onboarding: googleDriveOnboarding,
|
|
407
|
+
proxyPolicy: {
|
|
408
|
+
allowlist: [
|
|
409
|
+
{
|
|
410
|
+
host: "www.googleapis.com",
|
|
411
|
+
pathPrefix: "/drive/",
|
|
412
|
+
methods: ["GET", "POST", "PATCH"]
|
|
413
|
+
}
|
|
414
|
+
]
|
|
415
|
+
},
|
|
517
416
|
systemPrompt: {
|
|
518
417
|
en: `### Tools
|
|
519
418
|
|
|
520
|
-
- \`google-drive_request\`: Send authenticated requests to the Google Drive API v3. Supports GET, POST, and PATCH methods. Authentication is configured automatically via
|
|
419
|
+
- \`google-drive_request\`: Send authenticated requests to the Google Drive API v3. Supports GET, POST, and PATCH methods. Authentication is configured automatically via OAuth.
|
|
521
420
|
|
|
522
421
|
### Google Drive API Reference
|
|
523
422
|
|
|
524
423
|
#### Files
|
|
525
424
|
- GET \`/files\` \u2014 List files. Key query params: \`q\` (search query), \`pageSize\`, \`pageToken\`, \`orderBy\`, \`fields\`
|
|
526
|
-
- GET \`/files/{fileId}\` \u2014 Get file metadata
|
|
425
|
+
- GET \`/files/{fileId}\` \u2014 Get file metadata. Use \`fields\` param to select specific fields
|
|
527
426
|
- GET \`/files/{fileId}?alt=media\` \u2014 Download file content (for non-Google-Workspace files)
|
|
528
427
|
- POST \`/files\` \u2014 Create a new file or folder (metadata only). Body: \`{ "name": "My File", "mimeType": "...", "parents": ["folderId"] }\`
|
|
529
|
-
- PATCH \`/files/{fileId}\` \u2014 Update file metadata (rename, move, star). Use \`addParents\`/\`removeParents\` query params to move
|
|
530
|
-
- POST \`/files/{fileId}/copy\` \u2014 Copy a file
|
|
428
|
+
- PATCH \`/files/{fileId}\` \u2014 Update file metadata (rename, move, star). Body: \`{ "name": "New Name" }\`. Use \`addParents\`/\`removeParents\` query params to move
|
|
429
|
+
- POST \`/files/{fileId}/copy\` \u2014 Copy a file. Body: \`{ "name": "Copy of File", "parents": ["folderId"] }\`
|
|
531
430
|
|
|
532
431
|
#### Download & Export
|
|
533
432
|
- GET \`/files/{fileId}?alt=media\` \u2014 Download file content (PDFs, images, text files, etc.)
|
|
534
|
-
- GET \`/files/{fileId}/export?mimeType={mimeType}\` \u2014 Export Google Workspace
|
|
433
|
+
- GET \`/files/{fileId}/export?mimeType={mimeType}\` \u2014 Export a Google Workspace file (Docs, Sheets, Slides) to another format
|
|
535
434
|
|
|
536
435
|
#### Permissions (Sharing)
|
|
537
|
-
- GET \`/files/{fileId}/permissions\` \u2014 List permissions
|
|
436
|
+
- GET \`/files/{fileId}/permissions\` \u2014 List permissions on a file
|
|
538
437
|
- POST \`/files/{fileId}/permissions\` \u2014 Share a file. Body: \`{ "type": "user", "role": "writer", "emailAddress": "user@example.com" }\`
|
|
539
438
|
|
|
439
|
+
#### Account Info
|
|
440
|
+
- GET \`/about?fields=user,storageQuota\` \u2014 Get account info and storage usage
|
|
441
|
+
|
|
540
442
|
### Search Query Syntax (\`q\` parameter)
|
|
443
|
+
- \`name = 'My Document'\` \u2014 Exact name match
|
|
541
444
|
- \`name contains 'report'\` \u2014 Name contains text
|
|
542
445
|
- \`mimeType = 'application/vnd.google-apps.folder'\` \u2014 Folders only
|
|
543
446
|
- \`mimeType = 'application/vnd.google-apps.spreadsheet'\` \u2014 Google Sheets only
|
|
447
|
+
- \`mimeType = 'application/vnd.google-apps.presentation'\` \u2014 Google Slides only
|
|
448
|
+
- \`mimeType = 'application/vnd.google-apps.document'\` \u2014 Google Docs only
|
|
544
449
|
- \`'folderId' in parents\` \u2014 Files in a specific folder
|
|
545
450
|
- \`trashed = false\` \u2014 Exclude trashed files
|
|
546
|
-
-
|
|
451
|
+
- \`starred = true\` \u2014 Starred files
|
|
452
|
+
- \`sharedWithMe\` \u2014 Files shared with the user
|
|
453
|
+
- \`modifiedTime > '2024-01-01T00:00:00'\` \u2014 Modified after date
|
|
454
|
+
- Combine with \`and\`/\`or\`/\`not\`: \`mimeType = 'application/vnd.google-apps.folder' and name contains 'project'\`
|
|
455
|
+
|
|
456
|
+
### Common MIME Types
|
|
457
|
+
| Type | MIME Type |
|
|
458
|
+
|------|-----------|
|
|
459
|
+
| Folder | \`application/vnd.google-apps.folder\` |
|
|
460
|
+
| Google Docs | \`application/vnd.google-apps.document\` |
|
|
461
|
+
| Google Sheets | \`application/vnd.google-apps.spreadsheet\` |
|
|
462
|
+
| Google Slides | \`application/vnd.google-apps.presentation\` |
|
|
463
|
+
| PDF | \`application/pdf\` |
|
|
464
|
+
|
|
465
|
+
### Export MIME Types (for Google Workspace files)
|
|
466
|
+
| Source | Export Format | MIME Type |
|
|
467
|
+
|--------|--------------|-----------|
|
|
468
|
+
| Docs | PDF | \`application/pdf\` |
|
|
469
|
+
| Docs | Word | \`application/vnd.openxmlformats-officedocument.wordprocessingml.document\` |
|
|
470
|
+
| Docs | Plain Text | \`text/plain\` |
|
|
471
|
+
| Sheets | PDF | \`application/pdf\` |
|
|
472
|
+
| Sheets | Excel | \`application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\` |
|
|
473
|
+
| Sheets | CSV | \`text/csv\` |
|
|
474
|
+
| Slides | PDF | \`application/pdf\` |
|
|
475
|
+
| Slides | PowerPoint | \`application/vnd.openxmlformats-officedocument.presentationml.presentation\` |
|
|
476
|
+
|
|
477
|
+
### Tips
|
|
478
|
+
- Always use \`fields\` parameter to limit response data and improve performance
|
|
479
|
+
- Use \`orderBy=modifiedTime desc\` to get most recently modified files first
|
|
480
|
+
- To create a folder, use mimeType \`application/vnd.google-apps.folder\`
|
|
481
|
+
- To move a file, use PATCH with \`addParents\` and \`removeParents\` query params
|
|
482
|
+
- Files in "My Drive" have no parent specified; use \`'root' in parents\` to list root files
|
|
547
483
|
|
|
548
484
|
### Business Logic
|
|
549
485
|
|
|
550
|
-
The business logic type for this connector is "typescript". Write handler code using the connector SDK shown below.
|
|
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.
|
|
551
487
|
|
|
552
488
|
#### Example
|
|
553
489
|
|
|
@@ -556,45 +492,118 @@ import { connection } from "@squadbase/vite-server/connectors/google-drive";
|
|
|
556
492
|
|
|
557
493
|
const drive = connection("<connectionId>");
|
|
558
494
|
|
|
495
|
+
// List recent files
|
|
559
496
|
const result = await drive.listFiles({ pageSize: 20, orderBy: "modifiedTime desc" });
|
|
560
497
|
result.files.forEach(f => console.log(f.name, f.mimeType));
|
|
561
498
|
|
|
562
|
-
|
|
499
|
+
// Search for spreadsheets
|
|
500
|
+
const sheets = await drive.listFiles({
|
|
501
|
+
query: "mimeType = 'application/vnd.google-apps.spreadsheet' and name contains 'report'"
|
|
502
|
+
});
|
|
503
|
+
|
|
504
|
+
// Get file metadata
|
|
505
|
+
const file = await drive.getFile("fileId123");
|
|
506
|
+
console.log(file.name, file.webViewLink);
|
|
507
|
+
|
|
508
|
+
// Create a folder
|
|
509
|
+
const folder = await drive.createFile({
|
|
510
|
+
name: "Reports",
|
|
511
|
+
mimeType: "application/vnd.google-apps.folder",
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
// Create a Google Sheets file inside the folder
|
|
515
|
+
const sheet = await drive.createFile({
|
|
516
|
+
name: "Q1 Report",
|
|
517
|
+
mimeType: "application/vnd.google-apps.spreadsheet",
|
|
518
|
+
parents: [folder.id],
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
// Download file content (non-Google-Workspace files)
|
|
563
522
|
const content = await drive.downloadFile("fileId123");
|
|
523
|
+
const text = await content.text(); // or content.arrayBuffer() for binary
|
|
524
|
+
|
|
525
|
+
// Export a Google Docs file as PDF
|
|
564
526
|
const pdf = await drive.exportFile("docFileId", "application/pdf");
|
|
527
|
+
|
|
528
|
+
// Share a file
|
|
529
|
+
await drive.shareFile("fileId123", "user", "writer", "colleague@example.com");
|
|
530
|
+
|
|
531
|
+
// Copy a file
|
|
532
|
+
const copy = await drive.copyFile("fileId123", "Backup Copy");
|
|
533
|
+
|
|
534
|
+
// Move a file to a different folder
|
|
535
|
+
await drive.updateFile("fileId123", {}, "newFolderId", "oldFolderId");
|
|
565
536
|
\`\`\``,
|
|
566
537
|
ja: `### \u30C4\u30FC\u30EB
|
|
567
538
|
|
|
568
|
-
- \`google-drive_request\`: Google Drive API v3\u3078\u306E\u8A8D\u8A3C\u6E08\u307F\u30EA\u30AF\u30A8\u30B9\u30C8\u3092\u9001\u4FE1\u3057\u307E\u3059\u3002GET, POST, PATCH\u30E1\u30BD\u30C3\u30C9\u3092\u30B5\u30DD\u30FC\u30C8\u3057\u307E\u3059\
|
|
539
|
+
- \`google-drive_request\`: Google Drive API v3\u3078\u306E\u8A8D\u8A3C\u6E08\u307F\u30EA\u30AF\u30A8\u30B9\u30C8\u3092\u9001\u4FE1\u3057\u307E\u3059\u3002GET, POST, PATCH\u30E1\u30BD\u30C3\u30C9\u3092\u30B5\u30DD\u30FC\u30C8\u3057\u307E\u3059\u3002OAuth\u7D4C\u7531\u3067\u8A8D\u8A3C\u306F\u81EA\u52D5\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002
|
|
569
540
|
|
|
570
541
|
### Google Drive API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
|
|
571
542
|
|
|
572
543
|
#### \u30D5\u30A1\u30A4\u30EB
|
|
573
|
-
- GET \`/files\` \u2014 \u30D5\u30A1\u30A4\u30EB\u4E00\u89A7\u3002\u4E3B\u8981\u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF: \`q
|
|
574
|
-
- GET \`/files/{fileId}\` \u2014 \u30D5\u30A1\u30A4\u30EB\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97
|
|
575
|
-
- GET \`/files/{fileId}?alt=media\` \u2014 \u30D5\u30A1\u30A4\u30EB\u30B3\u30F3\u30C6\u30F3\u30C4\u3092\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9\uFF08\u975EGoogle Workspace\u30D5\u30A1\u30A4\u30EB\uFF09
|
|
576
|
-
- POST \`/files\` \u2014 \u65B0\u3057\u3044\u30D5\u30A1\u30A4\u30EB\u307E\u305F\u306F\u30D5\u30A9\u30EB\u30C0\u3092\u4F5C\u6210\uFF08\u30E1\u30BF\u30C7\u30FC\u30BF\u306E\u307F\uFF09
|
|
577
|
-
- PATCH \`/files/{fileId}\` \u2014 \u30D5\u30A1\u30A4\u30EB\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u66F4\u65B0\uFF08\u540D\u524D\u5909\u66F4\u3001\u79FB\u52D5\u3001\u30B9\u30BF\u30FC\uFF09
|
|
578
|
-
- POST \`/files/{fileId}/copy\` \u2014 \u30D5\u30A1\u30A4\u30EB\u3092\u30B3\u30D4\u30FC
|
|
544
|
+
- GET \`/files\` \u2014 \u30D5\u30A1\u30A4\u30EB\u4E00\u89A7\u3002\u4E3B\u8981\u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF: \`q\`\uFF08\u691C\u7D22\u30AF\u30A8\u30EA\uFF09, \`pageSize\`, \`pageToken\`, \`orderBy\`, \`fields\`
|
|
545
|
+
- GET \`/files/{fileId}\` \u2014 \u30D5\u30A1\u30A4\u30EB\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97\u3002\`fields\`\u30D1\u30E9\u30E1\u30FC\u30BF\u3067\u7279\u5B9A\u306E\u30D5\u30A3\u30FC\u30EB\u30C9\u3092\u9078\u629E
|
|
546
|
+
- GET \`/files/{fileId}?alt=media\` \u2014 \u30D5\u30A1\u30A4\u30EB\u30B3\u30F3\u30C6\u30F3\u30C4\u3092\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9\uFF08\u975EGoogle Workspace\u30D5\u30A1\u30A4\u30EB\u5411\u3051\uFF09
|
|
547
|
+
- POST \`/files\` \u2014 \u65B0\u3057\u3044\u30D5\u30A1\u30A4\u30EB\u307E\u305F\u306F\u30D5\u30A9\u30EB\u30C0\u3092\u4F5C\u6210\uFF08\u30E1\u30BF\u30C7\u30FC\u30BF\u306E\u307F\uFF09\u3002Body: \`{ "name": "\u30DE\u30A4\u30D5\u30A1\u30A4\u30EB", "mimeType": "...", "parents": ["folderId"] }\`
|
|
548
|
+
- PATCH \`/files/{fileId}\` \u2014 \u30D5\u30A1\u30A4\u30EB\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u66F4\u65B0\uFF08\u540D\u524D\u5909\u66F4\u3001\u79FB\u52D5\u3001\u30B9\u30BF\u30FC\uFF09\u3002Body: \`{ "name": "\u65B0\u3057\u3044\u540D\u524D" }\`\u3002\`addParents\`/\`removeParents\`\u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF\u3067\u79FB\u52D5
|
|
549
|
+
- POST \`/files/{fileId}/copy\` \u2014 \u30D5\u30A1\u30A4\u30EB\u3092\u30B3\u30D4\u30FC\u3002Body: \`{ "name": "\u30B3\u30D4\u30FC", "parents": ["folderId"] }\`
|
|
579
550
|
|
|
580
551
|
#### \u30C0\u30A6\u30F3\u30ED\u30FC\u30C9 & \u30A8\u30AF\u30B9\u30DD\u30FC\u30C8
|
|
581
|
-
- GET \`/files/{fileId}?alt=media\` \u2014 \u30D5\u30A1\u30A4\u30EB\u30B3\u30F3\u30C6\u30F3\u30C4\u3092\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9
|
|
582
|
-
- GET \`/files/{fileId}/export?mimeType={mimeType}\` \u2014 Google Workspace\u30D5\u30A1\u30A4\u30EB\u3092\u5225\u5F62\u5F0F\u306B\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8
|
|
552
|
+
- GET \`/files/{fileId}?alt=media\` \u2014 \u30D5\u30A1\u30A4\u30EB\u30B3\u30F3\u30C6\u30F3\u30C4\u3092\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9\uFF08PDF\u3001\u753B\u50CF\u3001\u30C6\u30AD\u30B9\u30C8\u30D5\u30A1\u30A4\u30EB\u7B49\uFF09
|
|
553
|
+
- GET \`/files/{fileId}/export?mimeType={mimeType}\` \u2014 Google Workspace\u30D5\u30A1\u30A4\u30EB\uFF08Docs, Sheets, Slides\uFF09\u3092\u5225\u306E\u5F62\u5F0F\u306B\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8
|
|
583
554
|
|
|
584
555
|
#### \u30D1\u30FC\u30DF\u30C3\u30B7\u30E7\u30F3\uFF08\u5171\u6709\uFF09
|
|
585
|
-
- GET \`/files/{fileId}/permissions\` \u2014 \u30D1\u30FC\u30DF\u30C3\u30B7\u30E7\u30F3\u4E00\u89A7
|
|
586
|
-
- POST \`/files/{fileId}/permissions\` \u2014 \u30D5\u30A1\u30A4\u30EB\u3092\u5171\u6709
|
|
556
|
+
- GET \`/files/{fileId}/permissions\` \u2014 \u30D5\u30A1\u30A4\u30EB\u306E\u30D1\u30FC\u30DF\u30C3\u30B7\u30E7\u30F3\u4E00\u89A7
|
|
557
|
+
- POST \`/files/{fileId}/permissions\` \u2014 \u30D5\u30A1\u30A4\u30EB\u3092\u5171\u6709\u3002Body: \`{ "type": "user", "role": "writer", "emailAddress": "user@example.com" }\`
|
|
558
|
+
|
|
559
|
+
#### \u30A2\u30AB\u30A6\u30F3\u30C8\u60C5\u5831
|
|
560
|
+
- GET \`/about?fields=user,storageQuota\` \u2014 \u30A2\u30AB\u30A6\u30F3\u30C8\u60C5\u5831\u3068\u30B9\u30C8\u30EC\u30FC\u30B8\u4F7F\u7528\u91CF\u3092\u53D6\u5F97
|
|
587
561
|
|
|
588
562
|
### \u691C\u7D22\u30AF\u30A8\u30EA\u69CB\u6587\uFF08\`q\` \u30D1\u30E9\u30E1\u30FC\u30BF\uFF09
|
|
563
|
+
- \`name = '\u30DE\u30A4\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8'\` \u2014 \u540D\u524D\u306E\u5B8C\u5168\u4E00\u81F4
|
|
589
564
|
- \`name contains '\u30EC\u30DD\u30FC\u30C8'\` \u2014 \u540D\u524D\u306B\u30C6\u30AD\u30B9\u30C8\u3092\u542B\u3080
|
|
590
565
|
- \`mimeType = 'application/vnd.google-apps.folder'\` \u2014 \u30D5\u30A9\u30EB\u30C0\u306E\u307F
|
|
591
|
-
- \`'
|
|
566
|
+
- \`mimeType = 'application/vnd.google-apps.spreadsheet'\` \u2014 Google Sheets\u306E\u307F
|
|
567
|
+
- \`mimeType = 'application/vnd.google-apps.presentation'\` \u2014 Google Slides\u306E\u307F
|
|
568
|
+
- \`mimeType = 'application/vnd.google-apps.document'\` \u2014 Google Docs\u306E\u307F
|
|
569
|
+
- \`'folderId' in parents\` \u2014 \u7279\u5B9A\u306E\u30D5\u30A9\u30EB\u30C0\u5185\u306E\u30D5\u30A1\u30A4\u30EB
|
|
592
570
|
- \`trashed = false\` \u2014 \u30B4\u30DF\u7BB1\u3092\u9664\u5916
|
|
593
|
-
- \`
|
|
571
|
+
- \`starred = true\` \u2014 \u30B9\u30BF\u30FC\u4ED8\u304D\u30D5\u30A1\u30A4\u30EB
|
|
572
|
+
- \`sharedWithMe\` \u2014 \u5171\u6709\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB
|
|
573
|
+
- \`modifiedTime > '2024-01-01T00:00:00'\` \u2014 \u6307\u5B9A\u65E5\u4EE5\u964D\u306B\u66F4\u65B0
|
|
574
|
+
- \`and\`/\`or\`/\`not\`\u3067\u7D44\u307F\u5408\u308F\u305B: \`mimeType = 'application/vnd.google-apps.folder' and name contains 'project'\`
|
|
575
|
+
|
|
576
|
+
### \u4E3B\u8981\u306A MIME \u30BF\u30A4\u30D7
|
|
577
|
+
| \u30BF\u30A4\u30D7 | MIME Type |
|
|
578
|
+
|--------|-----------|
|
|
579
|
+
| \u30D5\u30A9\u30EB\u30C0 | \`application/vnd.google-apps.folder\` |
|
|
580
|
+
| Google Docs | \`application/vnd.google-apps.document\` |
|
|
581
|
+
| Google Sheets | \`application/vnd.google-apps.spreadsheet\` |
|
|
582
|
+
| Google Slides | \`application/vnd.google-apps.presentation\` |
|
|
583
|
+
| PDF | \`application/pdf\` |
|
|
584
|
+
|
|
585
|
+
### \u30A8\u30AF\u30B9\u30DD\u30FC\u30C8 MIME \u30BF\u30A4\u30D7\uFF08Google Workspace\u30D5\u30A1\u30A4\u30EB\u7528\uFF09
|
|
586
|
+
| \u30BD\u30FC\u30B9 | \u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u5F62\u5F0F | MIME Type |
|
|
587
|
+
|--------|----------------|-----------|
|
|
588
|
+
| Docs | PDF | \`application/pdf\` |
|
|
589
|
+
| Docs | Word | \`application/vnd.openxmlformats-officedocument.wordprocessingml.document\` |
|
|
590
|
+
| Docs | \u30D7\u30EC\u30FC\u30F3\u30C6\u30AD\u30B9\u30C8 | \`text/plain\` |
|
|
591
|
+
| Sheets | PDF | \`application/pdf\` |
|
|
592
|
+
| Sheets | Excel | \`application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\` |
|
|
593
|
+
| Sheets | CSV | \`text/csv\` |
|
|
594
|
+
| Slides | PDF | \`application/pdf\` |
|
|
595
|
+
| Slides | PowerPoint | \`application/vnd.openxmlformats-officedocument.presentationml.presentation\` |
|
|
596
|
+
|
|
597
|
+
### \u30D2\u30F3\u30C8
|
|
598
|
+
- \`fields\`\u30D1\u30E9\u30E1\u30FC\u30BF\u3092\u4F7F\u7528\u3057\u3066\u30EC\u30B9\u30DD\u30F3\u30B9\u30C7\u30FC\u30BF\u3092\u5236\u9650\u3057\u3001\u30D1\u30D5\u30A9\u30FC\u30DE\u30F3\u30B9\u3092\u5411\u4E0A\u3055\u305B\u3066\u304F\u3060\u3055\u3044
|
|
599
|
+
- \`orderBy=modifiedTime desc\`\u3067\u6700\u8FD1\u66F4\u65B0\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB\u3092\u5148\u306B\u53D6\u5F97
|
|
600
|
+
- \u30D5\u30A9\u30EB\u30C0\u3092\u4F5C\u6210\u3059\u308B\u306B\u306FmimeType\u306B\`application/vnd.google-apps.folder\`\u3092\u4F7F\u7528
|
|
601
|
+
- \u30D5\u30A1\u30A4\u30EB\u3092\u79FB\u52D5\u3059\u308B\u306B\u306FPATCH\u3067\`addParents\`\u3068\`removeParents\`\u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF\u3092\u4F7F\u7528
|
|
602
|
+
- \u300C\u30DE\u30A4\u30C9\u30E9\u30A4\u30D6\u300D\u306E\u30EB\u30FC\u30C8\u30D5\u30A1\u30A4\u30EB\u306F\`'root' in parents\`\u3067\u4E00\u89A7\u8868\u793A
|
|
594
603
|
|
|
595
604
|
### Business Logic
|
|
596
605
|
|
|
597
|
-
\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\
|
|
606
|
+
\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
|
|
598
607
|
|
|
599
608
|
#### Example
|
|
600
609
|
|
|
@@ -603,15 +612,70 @@ import { connection } from "@squadbase/vite-server/connectors/google-drive";
|
|
|
603
612
|
|
|
604
613
|
const drive = connection("<connectionId>");
|
|
605
614
|
|
|
615
|
+
// \u6700\u8FD1\u306E\u30D5\u30A1\u30A4\u30EB\u3092\u4E00\u89A7\u8868\u793A
|
|
606
616
|
const result = await drive.listFiles({ pageSize: 20, orderBy: "modifiedTime desc" });
|
|
607
617
|
result.files.forEach(f => console.log(f.name, f.mimeType));
|
|
608
618
|
|
|
609
|
-
|
|
619
|
+
// \u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u3092\u691C\u7D22
|
|
620
|
+
const sheets = await drive.listFiles({
|
|
621
|
+
query: "mimeType = 'application/vnd.google-apps.spreadsheet' and name contains '\u30EC\u30DD\u30FC\u30C8'"
|
|
622
|
+
});
|
|
623
|
+
|
|
624
|
+
// \u30D5\u30A1\u30A4\u30EB\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u53D6\u5F97
|
|
625
|
+
const file = await drive.getFile("fileId123");
|
|
626
|
+
console.log(file.name, file.webViewLink);
|
|
627
|
+
|
|
628
|
+
// \u30D5\u30A9\u30EB\u30C0\u3092\u4F5C\u6210
|
|
629
|
+
const folder = await drive.createFile({
|
|
630
|
+
name: "\u30EC\u30DD\u30FC\u30C8",
|
|
631
|
+
mimeType: "application/vnd.google-apps.folder",
|
|
632
|
+
});
|
|
633
|
+
|
|
634
|
+
// \u30D5\u30A9\u30EB\u30C0\u5185\u306BGoogle Sheets\u30D5\u30A1\u30A4\u30EB\u3092\u4F5C\u6210
|
|
635
|
+
const sheet = await drive.createFile({
|
|
636
|
+
name: "Q1\u30EC\u30DD\u30FC\u30C8",
|
|
637
|
+
mimeType: "application/vnd.google-apps.spreadsheet",
|
|
638
|
+
parents: [folder.id],
|
|
639
|
+
});
|
|
640
|
+
|
|
641
|
+
// \u30D5\u30A1\u30A4\u30EB\u30B3\u30F3\u30C6\u30F3\u30C4\u3092\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9\uFF08\u975EGoogle Workspace\u30D5\u30A1\u30A4\u30EB\uFF09
|
|
610
642
|
const content = await drive.downloadFile("fileId123");
|
|
643
|
+
const text = await content.text(); // \u30D0\u30A4\u30CA\u30EA\u306E\u5834\u5408\u306F content.arrayBuffer()
|
|
644
|
+
|
|
645
|
+
// Google Docs\u30D5\u30A1\u30A4\u30EB\u3092PDF\u3068\u3057\u3066\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8
|
|
611
646
|
const pdf = await drive.exportFile("docFileId", "application/pdf");
|
|
647
|
+
|
|
648
|
+
// \u30D5\u30A1\u30A4\u30EB\u3092\u5171\u6709
|
|
649
|
+
await drive.shareFile("fileId123", "user", "writer", "colleague@example.com");
|
|
650
|
+
|
|
651
|
+
// \u30D5\u30A1\u30A4\u30EB\u3092\u30B3\u30D4\u30FC
|
|
652
|
+
const copy = await drive.copyFile("fileId123", "\u30D0\u30C3\u30AF\u30A2\u30C3\u30D7\u30B3\u30D4\u30FC");
|
|
653
|
+
|
|
654
|
+
// \u30D5\u30A1\u30A4\u30EB\u3092\u5225\u306E\u30D5\u30A9\u30EB\u30C0\u306B\u79FB\u52D5
|
|
655
|
+
await drive.updateFile("fileId123", {}, "newFolderId", "oldFolderId");
|
|
612
656
|
\`\`\``
|
|
613
657
|
},
|
|
614
|
-
tools
|
|
658
|
+
tools,
|
|
659
|
+
async checkConnection(_params, config) {
|
|
660
|
+
const { proxyFetch } = config;
|
|
661
|
+
const url = "https://www.googleapis.com/drive/v3/about?fields=user";
|
|
662
|
+
try {
|
|
663
|
+
const res = await proxyFetch(url, { method: "GET" });
|
|
664
|
+
if (!res.ok) {
|
|
665
|
+
const errorText = await res.text().catch(() => res.statusText);
|
|
666
|
+
return {
|
|
667
|
+
success: false,
|
|
668
|
+
error: `Google Drive API failed: HTTP ${res.status} ${errorText}`
|
|
669
|
+
};
|
|
670
|
+
}
|
|
671
|
+
return { success: true };
|
|
672
|
+
} catch (error) {
|
|
673
|
+
return {
|
|
674
|
+
success: false,
|
|
675
|
+
error: error instanceof Error ? error.message : String(error)
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
}
|
|
615
679
|
});
|
|
616
680
|
|
|
617
681
|
// src/connectors/create-connector-sdk.ts
|