@squadbase/vite-server 0.1.12-dev.a9ac647 → 0.1.17-dev.3b633bb
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 +14375 -1652
- package/dist/connectors/airtable-oauth.js +282 -46
- package/dist/connectors/airtable.js +319 -51
- package/dist/connectors/amplitude.js +322 -47
- package/dist/connectors/anthropic.js +135 -47
- package/dist/connectors/asana.js +327 -49
- package/dist/connectors/attio.js +302 -49
- package/dist/connectors/aws-billing.js +287 -46
- package/dist/connectors/azure-sql.js +421 -102
- package/dist/connectors/backlog-api-key.js +317 -47
- package/dist/connectors/clickup.js +338 -49
- package/dist/connectors/cosmosdb.js +305 -50
- package/dist/connectors/customerio.js +319 -47
- package/dist/connectors/dbt.js +340 -47
- package/dist/connectors/freshdesk.js +342 -53
- package/dist/connectors/freshsales.js +333 -52
- package/dist/connectors/freshservice.js +361 -53
- package/dist/connectors/gamma.js +327 -52
- package/dist/connectors/gemini.js +134 -47
- package/dist/connectors/github.js +386 -49
- package/dist/connectors/gmail-oauth.js +204 -7
- package/dist/connectors/gmail.js +350 -47
- package/dist/connectors/google-ads.js +288 -46
- package/dist/connectors/google-analytics-oauth.js +310 -46
- package/dist/connectors/google-analytics.js +547 -87
- package/dist/connectors/google-audit-log.js +438 -47
- package/dist/connectors/google-calendar-oauth.js +259 -46
- package/dist/connectors/google-calendar.js +359 -47
- package/dist/connectors/google-docs.js +220 -6
- package/dist/connectors/google-drive.js +262 -5
- package/dist/connectors/google-search-console-oauth.js +256 -46
- package/dist/connectors/google-sheets.js +272 -47
- package/dist/connectors/google-slides.js +205 -6
- package/dist/connectors/grafana.js +332 -49
- package/dist/connectors/hubspot-oauth.js +208 -5
- package/dist/connectors/hubspot.js +306 -49
- package/dist/connectors/influxdb.js +416 -51
- package/dist/connectors/intercom-oauth.js +210 -5
- package/dist/connectors/intercom.js +302 -49
- package/dist/connectors/jdbc.js +762 -110
- package/dist/connectors/jira-api-key.js +326 -47
- package/dist/connectors/kintone-api-token.js +281 -47
- package/dist/connectors/kintone.js +328 -47
- package/dist/connectors/linear.js +330 -49
- package/dist/connectors/linkedin-ads.js +268 -50
- package/dist/connectors/mailchimp-oauth.js +268 -46
- package/dist/connectors/mailchimp.js +320 -49
- package/dist/connectors/meta-ads-oauth.js +273 -48
- package/dist/connectors/meta-ads.js +285 -50
- package/dist/connectors/mixpanel.js +338 -47
- package/dist/connectors/monday.js +360 -49
- package/dist/connectors/mongodb.js +319 -57
- package/dist/connectors/notion-oauth.js +231 -5
- package/dist/connectors/notion.js +323 -51
- package/dist/connectors/openai.js +134 -47
- package/dist/connectors/oracle.js +454 -103
- package/dist/connectors/outlook-oauth.js +204 -5
- package/dist/connectors/powerbi-oauth.js +498 -5
- package/dist/connectors/salesforce.js +384 -49
- package/dist/connectors/semrush.js +609 -49
- package/dist/connectors/sentry.js +289 -50
- package/dist/connectors/shopify-oauth.js +187 -5
- package/dist/connectors/shopify.js +357 -47
- package/dist/connectors/sqlserver.js +415 -102
- package/dist/connectors/stripe-api-key.js +269 -46
- package/dist/connectors/stripe-oauth.js +202 -5
- package/dist/connectors/supabase.js +303 -48
- package/dist/connectors/tableau.js +536 -163
- package/dist/connectors/tiktok-ads.js +279 -48
- package/dist/connectors/wix-store.js +320 -49
- package/dist/connectors/zendesk-oauth.js +239 -5
- package/dist/connectors/zendesk.js +358 -47
- package/dist/index.d.ts +149 -1
- package/dist/index.js +15057 -2117
- package/dist/main.js +15005 -2073
- package/dist/vite-plugin.js +14752 -2019
- package/package.json +1 -1
package/dist/connectors/gamma.js
CHANGED
|
@@ -1,48 +1,60 @@
|
|
|
1
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
2
|
+
var __esm = (fn, res) => function __init() {
|
|
3
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
4
|
+
};
|
|
5
|
+
|
|
1
6
|
// ../connectors/src/parameter-definition.ts
|
|
2
|
-
var ParameterDefinition
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
7
|
+
var ParameterDefinition;
|
|
8
|
+
var init_parameter_definition = __esm({
|
|
9
|
+
"../connectors/src/parameter-definition.ts"() {
|
|
10
|
+
"use strict";
|
|
11
|
+
ParameterDefinition = class {
|
|
12
|
+
slug;
|
|
13
|
+
name;
|
|
14
|
+
description;
|
|
15
|
+
envVarBaseKey;
|
|
16
|
+
type;
|
|
17
|
+
secret;
|
|
18
|
+
required;
|
|
19
|
+
constructor(config) {
|
|
20
|
+
this.slug = config.slug;
|
|
21
|
+
this.name = config.name;
|
|
22
|
+
this.description = config.description;
|
|
23
|
+
this.envVarBaseKey = config.envVarBaseKey;
|
|
24
|
+
this.type = config.type;
|
|
25
|
+
this.secret = config.secret;
|
|
26
|
+
this.required = config.required;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get the parameter value from a ConnectorConnectionObject.
|
|
30
|
+
*/
|
|
31
|
+
getValue(connection2) {
|
|
32
|
+
const param = connection2.parameters.find(
|
|
33
|
+
(p) => p.parameterSlug === this.slug
|
|
34
|
+
);
|
|
35
|
+
if (!param || param.value == null) {
|
|
36
|
+
throw new Error(
|
|
37
|
+
`Parameter "${this.slug}" not found or has no value in connection "${connection2.id}"`
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
return param.value;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Try to get the parameter value. Returns undefined if not found (for optional params).
|
|
44
|
+
*/
|
|
45
|
+
tryGetValue(connection2) {
|
|
46
|
+
const param = connection2.parameters.find(
|
|
47
|
+
(p) => p.parameterSlug === this.slug
|
|
48
|
+
);
|
|
49
|
+
if (!param || param.value == null) return void 0;
|
|
50
|
+
return param.value;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
42
53
|
}
|
|
43
|
-
};
|
|
54
|
+
});
|
|
44
55
|
|
|
45
56
|
// ../connectors/src/connectors/gamma/parameters.ts
|
|
57
|
+
init_parameter_definition();
|
|
46
58
|
var parameters = {
|
|
47
59
|
apiKey: new ParameterDefinition({
|
|
48
60
|
slug: "api-key",
|
|
@@ -210,6 +222,28 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
210
222
|
tools;
|
|
211
223
|
query;
|
|
212
224
|
checkConnection;
|
|
225
|
+
/**
|
|
226
|
+
* SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
|
|
227
|
+
* implement this expose a step-by-step exploration flow (database/schema/
|
|
228
|
+
* table/etc. discovery) that the dashboard backend drives via the
|
|
229
|
+
* `/connections/:connectionId/setup` endpoint. Implement by delegating to
|
|
230
|
+
* `runSetupFlow` from `setup-flow.ts`.
|
|
231
|
+
*/
|
|
232
|
+
setup;
|
|
233
|
+
/**
|
|
234
|
+
* Opt-out of the default "verify before save" behavior on connection
|
|
235
|
+
* creation. The backend invokes `checkConnection` synchronously while
|
|
236
|
+
* creating the connection and aborts (no row inserted) if it fails — this
|
|
237
|
+
* flag disables that for connectors where the check cannot succeed pre-save:
|
|
238
|
+
*
|
|
239
|
+
* - `squadbase-db` populates `connection-url` only after Neon provisioning
|
|
240
|
+
* - OAuth connectors require an OAuth-aware proxyFetch keyed by the
|
|
241
|
+
* connectionId, which doesn't exist until the row is saved
|
|
242
|
+
*
|
|
243
|
+
* Exceptions are the explicit position; new credential-input connectors get
|
|
244
|
+
* the default verify-on-create behavior without opt-in.
|
|
245
|
+
*/
|
|
246
|
+
skipConnectionCheckOnCreate;
|
|
213
247
|
constructor(config) {
|
|
214
248
|
this.slug = config.slug;
|
|
215
249
|
this.authType = config.authType;
|
|
@@ -226,6 +260,8 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
226
260
|
this.tools = config.tools;
|
|
227
261
|
this.query = config.query;
|
|
228
262
|
this.checkConnection = config.checkConnection;
|
|
263
|
+
this.setup = config.setup;
|
|
264
|
+
this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
|
|
229
265
|
}
|
|
230
266
|
get connectorKey() {
|
|
231
267
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
@@ -290,6 +326,76 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
290
326
|
}
|
|
291
327
|
};
|
|
292
328
|
|
|
329
|
+
// ../connectors/src/setup-flow.ts
|
|
330
|
+
async function runSetupFlow(flow, params, ctx, config) {
|
|
331
|
+
const runtime = {
|
|
332
|
+
params,
|
|
333
|
+
language: ctx.language,
|
|
334
|
+
config
|
|
335
|
+
};
|
|
336
|
+
let state = flow.initialState();
|
|
337
|
+
let answerIdx = 0;
|
|
338
|
+
const pendingParameterUpdates = [];
|
|
339
|
+
for (const step of flow.steps) {
|
|
340
|
+
const ans = ctx.answers[answerIdx];
|
|
341
|
+
if (ans && ans.questionSlug === step.slug) {
|
|
342
|
+
state = step.applyAnswer(state, ans.answer);
|
|
343
|
+
if (step.toParameterUpdates) {
|
|
344
|
+
pendingParameterUpdates.push(...step.toParameterUpdates(state));
|
|
345
|
+
}
|
|
346
|
+
answerIdx += 1;
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
|
|
350
|
+
if (step.type === "text") {
|
|
351
|
+
if (step.fetchOptions) {
|
|
352
|
+
const options2 = await step.fetchOptions(state, runtime);
|
|
353
|
+
if (options2.length === 0) {
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
return {
|
|
358
|
+
type: "nextQuestion",
|
|
359
|
+
questionSlug: step.slug,
|
|
360
|
+
question: step.question[ctx.language],
|
|
361
|
+
questionType: "text",
|
|
362
|
+
allowFreeText: resolvedAllowFreeText,
|
|
363
|
+
...pendingParameterUpdates.length > 0 && {
|
|
364
|
+
parameterUpdates: pendingParameterUpdates
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
|
|
369
|
+
if (options.length === 0) {
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
372
|
+
return {
|
|
373
|
+
type: "nextQuestion",
|
|
374
|
+
questionSlug: step.slug,
|
|
375
|
+
question: step.question[ctx.language],
|
|
376
|
+
questionType: step.type,
|
|
377
|
+
options,
|
|
378
|
+
allowFreeText: resolvedAllowFreeText,
|
|
379
|
+
...pendingParameterUpdates.length > 0 && {
|
|
380
|
+
parameterUpdates: pendingParameterUpdates
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
const dataInvestigationResult = await flow.finalize(state, runtime);
|
|
385
|
+
return {
|
|
386
|
+
type: "fulfilled",
|
|
387
|
+
dataInvestigationResult,
|
|
388
|
+
...pendingParameterUpdates.length > 0 && {
|
|
389
|
+
parameterUpdates: pendingParameterUpdates
|
|
390
|
+
}
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
async function resolveSetupSelection(params) {
|
|
394
|
+
const { selected, allSentinel, fetchAll, limit } = params;
|
|
395
|
+
const resolved = selected.includes(allSentinel) ? await fetchAll() : selected.filter((v) => v !== allSentinel);
|
|
396
|
+
return resolved.slice(0, limit);
|
|
397
|
+
}
|
|
398
|
+
|
|
293
399
|
// ../connectors/src/auth-types.ts
|
|
294
400
|
var AUTH_TYPES = {
|
|
295
401
|
OAUTH: "oauth",
|
|
@@ -312,9 +418,122 @@ var gammaOnboarding = new ConnectorOnboarding({
|
|
|
312
418
|
}
|
|
313
419
|
});
|
|
314
420
|
|
|
421
|
+
// ../connectors/src/connectors/gamma/utils.ts
|
|
422
|
+
var BASE_URL2 = "https://public-api.gamma.app/v1.0";
|
|
423
|
+
function apiFetch(params, path2, init) {
|
|
424
|
+
const apiKey = params[parameters.apiKey.slug];
|
|
425
|
+
if (!apiKey) {
|
|
426
|
+
throw new Error(`gamma: missing required parameter: ${parameters.apiKey.slug}`);
|
|
427
|
+
}
|
|
428
|
+
const headers = new Headers(init?.headers);
|
|
429
|
+
headers.set("X-API-KEY", apiKey);
|
|
430
|
+
if (!headers.has("Content-Type")) headers.set("Content-Type", "application/json");
|
|
431
|
+
const trimmedPath = path2.startsWith("/") ? path2 : `/${path2}`;
|
|
432
|
+
return fetch(`${BASE_URL2}${trimmedPath}`, { ...init, headers });
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// ../connectors/src/connectors/gamma/setup-flow.ts
|
|
436
|
+
var ALL_FOLDERS = "__ALL_FOLDERS__";
|
|
437
|
+
var GAMMA_SETUP_MAX_FOLDERS = 20;
|
|
438
|
+
var FOLDERS_PAGE_LIMIT = 50;
|
|
439
|
+
async function listAllFolders(params) {
|
|
440
|
+
const results = [];
|
|
441
|
+
let after;
|
|
442
|
+
for (let i = 0; i < 10; i++) {
|
|
443
|
+
const qs = new URLSearchParams();
|
|
444
|
+
qs.set("limit", String(FOLDERS_PAGE_LIMIT));
|
|
445
|
+
if (after) qs.set("after", after);
|
|
446
|
+
const res = await apiFetch(params, `/folders?${qs.toString()}`);
|
|
447
|
+
if (!res.ok) {
|
|
448
|
+
const body = await res.text().catch(() => res.statusText);
|
|
449
|
+
throw new Error(`gamma: listFolders failed (${res.status}): ${body}`);
|
|
450
|
+
}
|
|
451
|
+
const data = await res.json();
|
|
452
|
+
for (const item of data.data ?? []) results.push(item);
|
|
453
|
+
if (!data.hasMore || !data.nextCursor) break;
|
|
454
|
+
after = data.nextCursor;
|
|
455
|
+
}
|
|
456
|
+
return results;
|
|
457
|
+
}
|
|
458
|
+
async function listThemes(params) {
|
|
459
|
+
const res = await apiFetch(params, "/themes?limit=50");
|
|
460
|
+
if (!res.ok) {
|
|
461
|
+
return [];
|
|
462
|
+
}
|
|
463
|
+
const data = await res.json();
|
|
464
|
+
return data.data ?? [];
|
|
465
|
+
}
|
|
466
|
+
function folderLabel(f) {
|
|
467
|
+
return f.name ?? f.title ?? f.id ?? "(Untitled)";
|
|
468
|
+
}
|
|
469
|
+
var gammaSetupFlow = {
|
|
470
|
+
initialState: () => ({}),
|
|
471
|
+
steps: [
|
|
472
|
+
{
|
|
473
|
+
slug: "folders",
|
|
474
|
+
type: "multiSelect",
|
|
475
|
+
question: {
|
|
476
|
+
ja: "\u5BFE\u8C61\u306E\u30D5\u30A9\u30EB\u30C0\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
|
|
477
|
+
en: "Select target folders (multi-select allowed)"
|
|
478
|
+
},
|
|
479
|
+
async fetchOptions(_state, rt) {
|
|
480
|
+
const folders = await listAllFolders(rt.params);
|
|
481
|
+
const options = folders.filter((f) => f.id).map((f) => ({ value: f.id, label: folderLabel(f) }));
|
|
482
|
+
return [
|
|
483
|
+
{
|
|
484
|
+
value: ALL_FOLDERS,
|
|
485
|
+
label: rt.language === "ja" ? "\u3059\u3079\u3066\u306E\u30D5\u30A9\u30EB\u30C0" : "All folders"
|
|
486
|
+
},
|
|
487
|
+
...options
|
|
488
|
+
];
|
|
489
|
+
},
|
|
490
|
+
applyAnswer: (state, answer) => ({ ...state, folders: answer })
|
|
491
|
+
}
|
|
492
|
+
],
|
|
493
|
+
async finalize(state, rt) {
|
|
494
|
+
if (!state.folders) {
|
|
495
|
+
throw new Error("Gamma setup: incomplete state on finalize");
|
|
496
|
+
}
|
|
497
|
+
const allFolders = await listAllFolders(rt.params);
|
|
498
|
+
const folderById = new Map(
|
|
499
|
+
allFolders.filter((f) => f.id).map((f) => [f.id, f])
|
|
500
|
+
);
|
|
501
|
+
const targetIds = await resolveSetupSelection({
|
|
502
|
+
selected: state.folders,
|
|
503
|
+
allSentinel: ALL_FOLDERS,
|
|
504
|
+
fetchAll: async () => allFolders.map((f) => f.id ?? "").filter((id) => id),
|
|
505
|
+
limit: GAMMA_SETUP_MAX_FOLDERS
|
|
506
|
+
});
|
|
507
|
+
const sections = ["## Gamma", ""];
|
|
508
|
+
if (!targetIds.length) {
|
|
509
|
+
sections.push("_No folders selected._", "");
|
|
510
|
+
} else {
|
|
511
|
+
sections.push(`### Folders (${targetIds.length})`, "");
|
|
512
|
+
for (const id of targetIds) {
|
|
513
|
+
const folder = folderById.get(id);
|
|
514
|
+
sections.push(`- ${folderLabel(folder ?? { id })} (id: \`${id}\`)`);
|
|
515
|
+
}
|
|
516
|
+
sections.push("");
|
|
517
|
+
}
|
|
518
|
+
const themes = await listThemes(rt.params);
|
|
519
|
+
if (themes.length) {
|
|
520
|
+
sections.push(`### Available themes (${themes.length})`, "");
|
|
521
|
+
for (const theme of themes.slice(0, 20)) {
|
|
522
|
+
const label = theme.name ?? theme.id ?? "(unnamed)";
|
|
523
|
+
sections.push(`- ${label}`);
|
|
524
|
+
}
|
|
525
|
+
if (themes.length > 20) {
|
|
526
|
+
sections.push(`- \u2026and ${themes.length - 20} more`);
|
|
527
|
+
}
|
|
528
|
+
sections.push("");
|
|
529
|
+
}
|
|
530
|
+
return sections.join("\n");
|
|
531
|
+
}
|
|
532
|
+
};
|
|
533
|
+
|
|
315
534
|
// ../connectors/src/connectors/gamma/tools/request.ts
|
|
316
535
|
import { z } from "zod";
|
|
317
|
-
var
|
|
536
|
+
var BASE_URL3 = "https://public-api.gamma.app/v1.0";
|
|
318
537
|
var REQUEST_TIMEOUT_MS = 6e4;
|
|
319
538
|
var inputSchema = z.object({
|
|
320
539
|
toolUseIntent: z.string().optional().describe(
|
|
@@ -359,7 +578,7 @@ For creating presentations/documents, prefer the gamma_generate tool instead.`,
|
|
|
359
578
|
);
|
|
360
579
|
try {
|
|
361
580
|
const apiKey = parameters.apiKey.getValue(connection2);
|
|
362
|
-
const url = `${
|
|
581
|
+
const url = `${BASE_URL3}${path2}`;
|
|
363
582
|
const controller = new AbortController();
|
|
364
583
|
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
365
584
|
try {
|
|
@@ -391,7 +610,7 @@ For creating presentations/documents, prefer the gamma_generate tool instead.`,
|
|
|
391
610
|
|
|
392
611
|
// ../connectors/src/connectors/gamma/tools/generate.ts
|
|
393
612
|
import { z as z2 } from "zod";
|
|
394
|
-
var
|
|
613
|
+
var BASE_URL4 = "https://public-api.gamma.app/v1.0";
|
|
395
614
|
var POLL_INTERVAL_MS = 5e3;
|
|
396
615
|
var MAX_POLL_DURATION_MS = 3e5;
|
|
397
616
|
var inputSchema2 = z2.object({
|
|
@@ -508,7 +727,7 @@ Gamma does NOT support image uploads. To visualize data, embed raw numbers direc
|
|
|
508
727
|
if (textAmount) textOptions.amount = textAmount;
|
|
509
728
|
if (Object.keys(textOptions).length > 0) body.textOptions = textOptions;
|
|
510
729
|
if (imageSource) body.imageOptions = { source: imageSource };
|
|
511
|
-
const createRes = await fetch(`${
|
|
730
|
+
const createRes = await fetch(`${BASE_URL4}/generations`, {
|
|
512
731
|
method: "POST",
|
|
513
732
|
headers,
|
|
514
733
|
body: JSON.stringify(body)
|
|
@@ -528,7 +747,7 @@ Gamma does NOT support image uploads. To visualize data, embed raw numbers direc
|
|
|
528
747
|
const deadline = Date.now() + MAX_POLL_DURATION_MS;
|
|
529
748
|
while (Date.now() < deadline) {
|
|
530
749
|
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
|
|
531
|
-
const pollRes = await fetch(`${
|
|
750
|
+
const pollRes = await fetch(`${BASE_URL4}/generations/${generationId}`, {
|
|
532
751
|
method: "GET",
|
|
533
752
|
headers
|
|
534
753
|
});
|
|
@@ -727,7 +946,43 @@ export default async function handler(c: Context) {
|
|
|
727
946
|
#### \u30C7\u30FC\u30BF\u306E\u53EF\u8996\u5316
|
|
728
947
|
Gamma\u306F\u753B\u50CF\u306E\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u306B\u5BFE\u5FDC\u3057\u3066\u3044\u307E\u305B\u3093\u3002\u30C7\u30FC\u30BF\u3092\u53EF\u8996\u5316\u3057\u305F\u3044\u5834\u5408\uFF08\u30C1\u30E3\u30FC\u30C8\u3001\u30B0\u30E9\u30D5\u3001\u30C6\u30FC\u30D6\u30EB\u306A\u3069\uFF09\u306F\u3001\`inputText\` \u306B\u6570\u5024\u3084\u30C7\u30FC\u30BF\u3092\u69CB\u9020\u5316\u30C6\u30AD\u30B9\u30C8\uFF08\u30DE\u30FC\u30AF\u30C0\u30A6\u30F3\u30C6\u30FC\u30D6\u30EB\u3001\u6570\u5024\u4ED8\u304D\u7B87\u6761\u66F8\u304D\u306A\u3069\uFF09\u3068\u3057\u3066\u76F4\u63A5\u57CB\u3081\u8FBC\u3093\u3067\u304F\u3060\u3055\u3044\u3002Gamma AI\u304C\u30C7\u30FC\u30BF\u304B\u3089\u9069\u5207\u306A\u30D3\u30B8\u30E5\u30A2\u30EB\u8981\u7D20\u3092\u751F\u6210\u3057\u307E\u3059\u3002\u30ED\u30FC\u30AB\u30EB\u3067\u30C1\u30E3\u30FC\u30C8\u753B\u50CF\u3092\u751F\u6210\u3057\u3066\u542B\u3081\u308B\u306E\u3067\u306F\u306A\u304F\u3001\u30C7\u30FC\u30BF\u306E\u5024\u3092\u30A4\u30F3\u30E9\u30A4\u30F3\u3067\u6E21\u3057\u3066Gamma\u306B\u53EF\u8996\u5316\u3055\u305B\u3066\u304F\u3060\u3055\u3044\u3002`
|
|
729
948
|
},
|
|
730
|
-
tools
|
|
949
|
+
tools,
|
|
950
|
+
setup: (params, ctx, config) => runSetupFlow(gammaSetupFlow, params, ctx, config),
|
|
951
|
+
async checkConnection(params, _config) {
|
|
952
|
+
const apiKey = params[parameters.apiKey.slug];
|
|
953
|
+
if (!apiKey) {
|
|
954
|
+
return {
|
|
955
|
+
success: false,
|
|
956
|
+
error: `Missing required parameter: ${parameters.apiKey.slug}`
|
|
957
|
+
};
|
|
958
|
+
}
|
|
959
|
+
try {
|
|
960
|
+
const res = await fetch(
|
|
961
|
+
"https://public-api.gamma.app/v1.0/folders?limit=1",
|
|
962
|
+
{
|
|
963
|
+
method: "GET",
|
|
964
|
+
headers: {
|
|
965
|
+
"X-API-KEY": apiKey,
|
|
966
|
+
Accept: "application/json"
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
);
|
|
970
|
+
if (!res.ok) {
|
|
971
|
+
const data = await res.json().catch(() => null);
|
|
972
|
+
const message = typeof data?.message === "string" && data.message || typeof data?.error === "string" && data.error || `HTTP ${res.status} ${res.statusText}`;
|
|
973
|
+
return {
|
|
974
|
+
success: false,
|
|
975
|
+
error: `Gamma API failed: ${message}`
|
|
976
|
+
};
|
|
977
|
+
}
|
|
978
|
+
return { success: true };
|
|
979
|
+
} catch (error) {
|
|
980
|
+
return {
|
|
981
|
+
success: false,
|
|
982
|
+
error: error instanceof Error ? error.message : String(error)
|
|
983
|
+
};
|
|
984
|
+
}
|
|
985
|
+
}
|
|
731
986
|
});
|
|
732
987
|
|
|
733
988
|
// src/connectors/create-connector-sdk.ts
|
|
@@ -756,6 +1011,7 @@ function resolveEnvVarOptional(entry, key) {
|
|
|
756
1011
|
import { getContext } from "hono/context-storage";
|
|
757
1012
|
import { getCookie } from "hono/cookie";
|
|
758
1013
|
var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
|
|
1014
|
+
var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
|
|
759
1015
|
function normalizeHeaders(input) {
|
|
760
1016
|
const out = {};
|
|
761
1017
|
if (!input) return out;
|
|
@@ -764,6 +1020,11 @@ function normalizeHeaders(input) {
|
|
|
764
1020
|
});
|
|
765
1021
|
return out;
|
|
766
1022
|
}
|
|
1023
|
+
function extractInputUrl(input) {
|
|
1024
|
+
if (typeof input === "string") return input;
|
|
1025
|
+
if (input instanceof URL) return input.href;
|
|
1026
|
+
return input.url;
|
|
1027
|
+
}
|
|
767
1028
|
function createSandboxProxyFetch(connectionId) {
|
|
768
1029
|
return async (input, init) => {
|
|
769
1030
|
const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
|
|
@@ -773,10 +1034,17 @@ function createSandboxProxyFetch(connectionId) {
|
|
|
773
1034
|
"Connection proxy is not configured. Please check your deployment settings."
|
|
774
1035
|
);
|
|
775
1036
|
}
|
|
776
|
-
const originalUrl =
|
|
1037
|
+
const originalUrl = extractInputUrl(input);
|
|
1038
|
+
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
1039
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
1040
|
+
const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
1041
|
+
return fetch(sessionUrl, {
|
|
1042
|
+
method: "POST",
|
|
1043
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
1044
|
+
});
|
|
1045
|
+
}
|
|
777
1046
|
const originalMethod = init?.method ?? "GET";
|
|
778
1047
|
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
779
|
-
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
780
1048
|
const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
781
1049
|
return fetch(proxyUrl, {
|
|
782
1050
|
method: "POST",
|
|
@@ -802,10 +1070,9 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
802
1070
|
}
|
|
803
1071
|
const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
|
|
804
1072
|
const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
1073
|
+
const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
805
1074
|
return async (input, init) => {
|
|
806
|
-
const originalUrl =
|
|
807
|
-
const originalMethod = init?.method ?? "GET";
|
|
808
|
-
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
1075
|
+
const originalUrl = extractInputUrl(input);
|
|
809
1076
|
const c = getContext();
|
|
810
1077
|
const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
|
|
811
1078
|
if (!appSession) {
|
|
@@ -813,6 +1080,14 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
813
1080
|
"No authentication method available for connection proxy."
|
|
814
1081
|
);
|
|
815
1082
|
}
|
|
1083
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
1084
|
+
return fetch(sessionUrl, {
|
|
1085
|
+
method: "POST",
|
|
1086
|
+
headers: { Authorization: `Bearer ${appSession}` }
|
|
1087
|
+
});
|
|
1088
|
+
}
|
|
1089
|
+
const originalMethod = init?.method ?? "GET";
|
|
1090
|
+
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
816
1091
|
return fetch(proxyUrl, {
|
|
817
1092
|
method: "POST",
|
|
818
1093
|
headers: {
|