@squadbase/vite-server 0.1.12-dev.93b8799 → 0.1.17-dev.24af54e
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 +12128 -934
- package/dist/connectors/airtable-oauth.js +248 -46
- package/dist/connectors/airtable.js +285 -51
- package/dist/connectors/amplitude.js +288 -47
- package/dist/connectors/anthropic.js +126 -47
- package/dist/connectors/asana.js +293 -49
- package/dist/connectors/attio.js +268 -49
- package/dist/connectors/aws-billing.js +253 -46
- package/dist/connectors/azure-sql.js +387 -102
- package/dist/connectors/backlog-api-key.js +283 -47
- package/dist/connectors/clickup.js +304 -49
- package/dist/connectors/cosmosdb.js +271 -50
- package/dist/connectors/customerio.js +285 -47
- package/dist/connectors/dbt.js +306 -47
- package/dist/connectors/freshdesk.js +308 -53
- package/dist/connectors/freshsales.js +299 -52
- package/dist/connectors/freshservice.js +327 -53
- package/dist/connectors/gamma.js +293 -52
- package/dist/connectors/gemini.js +125 -47
- package/dist/connectors/github.js +352 -49
- package/dist/connectors/gmail-oauth.js +170 -7
- package/dist/connectors/gmail.js +316 -47
- package/dist/connectors/google-ads.js +254 -46
- package/dist/connectors/google-analytics-oauth.js +276 -46
- package/dist/connectors/google-analytics.js +378 -49
- package/dist/connectors/google-audit-log.js +404 -47
- package/dist/connectors/google-calendar-oauth.js +225 -46
- package/dist/connectors/google-calendar.js +325 -47
- package/dist/connectors/google-docs.js +186 -6
- package/dist/connectors/google-drive.js +228 -5
- package/dist/connectors/google-search-console-oauth.js +222 -46
- package/dist/connectors/google-sheets.js +238 -47
- package/dist/connectors/google-slides.js +171 -6
- package/dist/connectors/grafana.js +298 -49
- package/dist/connectors/hubspot-oauth.js +174 -5
- package/dist/connectors/hubspot.js +272 -49
- package/dist/connectors/influxdb.js +382 -51
- package/dist/connectors/intercom-oauth.js +176 -5
- package/dist/connectors/intercom.js +268 -49
- package/dist/connectors/jdbc.js +728 -110
- package/dist/connectors/jira-api-key.js +292 -47
- package/dist/connectors/kintone-api-token.js +247 -47
- package/dist/connectors/kintone.js +294 -47
- package/dist/connectors/linear.js +296 -49
- package/dist/connectors/linkedin-ads.js +234 -50
- package/dist/connectors/mailchimp-oauth.js +234 -46
- package/dist/connectors/mailchimp.js +286 -49
- package/dist/connectors/meta-ads-oauth.js +239 -48
- package/dist/connectors/meta-ads.js +251 -50
- package/dist/connectors/mixpanel.js +304 -47
- package/dist/connectors/monday.js +326 -49
- package/dist/connectors/mongodb.js +285 -57
- package/dist/connectors/notion-oauth.js +197 -5
- package/dist/connectors/notion.js +289 -51
- package/dist/connectors/openai.js +125 -47
- package/dist/connectors/oracle.js +405 -103
- package/dist/connectors/outlook-oauth.js +170 -5
- package/dist/connectors/powerbi-oauth.js +217 -5
- package/dist/connectors/salesforce.js +350 -49
- package/dist/connectors/semrush.js +280 -49
- package/dist/connectors/sentry.js +255 -50
- package/dist/connectors/shopify-oauth.js +153 -5
- package/dist/connectors/shopify.js +323 -47
- package/dist/connectors/sqlserver.js +381 -102
- package/dist/connectors/stripe-api-key.js +235 -46
- package/dist/connectors/stripe-oauth.js +168 -5
- package/dist/connectors/supabase.js +269 -48
- package/dist/connectors/tableau.js +337 -206
- package/dist/connectors/tiktok-ads.js +245 -48
- package/dist/connectors/wix-store.js +286 -49
- package/dist/connectors/zendesk-oauth.js +205 -5
- package/dist/connectors/zendesk.js +324 -47
- package/dist/index.d.ts +149 -1
- package/dist/index.js +18297 -6886
- package/dist/main.js +12785 -1382
- package/dist/vite-plugin.js +12140 -936
- package/package.json +1 -1
|
@@ -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/amplitude/parameters.ts
|
|
57
|
+
init_parameter_definition();
|
|
46
58
|
var parameters = {
|
|
47
59
|
apiKey: new ParameterDefinition({
|
|
48
60
|
slug: "api-key",
|
|
@@ -224,6 +236,20 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
224
236
|
* `runSetupFlow` from `setup-flow.ts`.
|
|
225
237
|
*/
|
|
226
238
|
setup;
|
|
239
|
+
/**
|
|
240
|
+
* Opt-out of the default "verify before save" behavior on connection
|
|
241
|
+
* creation. The backend invokes `checkConnection` synchronously while
|
|
242
|
+
* creating the connection and aborts (no row inserted) if it fails — this
|
|
243
|
+
* flag disables that for connectors where the check cannot succeed pre-save:
|
|
244
|
+
*
|
|
245
|
+
* - `squadbase-db` populates `connection-url` only after Neon provisioning
|
|
246
|
+
* - OAuth connectors require an OAuth-aware proxyFetch keyed by the
|
|
247
|
+
* connectionId, which doesn't exist until the row is saved
|
|
248
|
+
*
|
|
249
|
+
* Exceptions are the explicit position; new credential-input connectors get
|
|
250
|
+
* the default verify-on-create behavior without opt-in.
|
|
251
|
+
*/
|
|
252
|
+
skipConnectionCheckOnCreate;
|
|
227
253
|
constructor(config) {
|
|
228
254
|
this.slug = config.slug;
|
|
229
255
|
this.authType = config.authType;
|
|
@@ -241,6 +267,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
241
267
|
this.query = config.query;
|
|
242
268
|
this.checkConnection = config.checkConnection;
|
|
243
269
|
this.setup = config.setup;
|
|
270
|
+
this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
|
|
244
271
|
}
|
|
245
272
|
get connectorKey() {
|
|
246
273
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
@@ -305,6 +332,46 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
305
332
|
}
|
|
306
333
|
};
|
|
307
334
|
|
|
335
|
+
// ../connectors/src/setup-flow.ts
|
|
336
|
+
async function runSetupFlow(flow, params, ctx, config) {
|
|
337
|
+
const runtime = {
|
|
338
|
+
params,
|
|
339
|
+
language: ctx.language,
|
|
340
|
+
config
|
|
341
|
+
};
|
|
342
|
+
let state = flow.initialState();
|
|
343
|
+
let answerIdx = 0;
|
|
344
|
+
for (const step of flow.steps) {
|
|
345
|
+
const ans = ctx.answers[answerIdx];
|
|
346
|
+
if (ans && ans.questionSlug === step.slug) {
|
|
347
|
+
state = step.applyAnswer(state, ans.answer);
|
|
348
|
+
answerIdx += 1;
|
|
349
|
+
continue;
|
|
350
|
+
}
|
|
351
|
+
if (step.type === "text") {
|
|
352
|
+
return {
|
|
353
|
+
type: "nextQuestion",
|
|
354
|
+
questionSlug: step.slug,
|
|
355
|
+
question: step.question[ctx.language],
|
|
356
|
+
questionType: "text"
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
|
|
360
|
+
if (options.length === 0) {
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
return {
|
|
364
|
+
type: "nextQuestion",
|
|
365
|
+
questionSlug: step.slug,
|
|
366
|
+
question: step.question[ctx.language],
|
|
367
|
+
questionType: step.type,
|
|
368
|
+
options
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
const dataInvestigationResult = await flow.finalize(state, runtime);
|
|
372
|
+
return { type: "fulfilled", dataInvestigationResult };
|
|
373
|
+
}
|
|
374
|
+
|
|
308
375
|
// ../connectors/src/auth-types.ts
|
|
309
376
|
var AUTH_TYPES = {
|
|
310
377
|
OAUTH: "oauth",
|
|
@@ -331,6 +398,125 @@ NOTE: The Dashboard REST API endpoints (events/segmentation, funnels, retention,
|
|
|
331
398
|
}
|
|
332
399
|
});
|
|
333
400
|
|
|
401
|
+
// ../connectors/src/connectors/amplitude/utils.ts
|
|
402
|
+
function getBaseUrl(params) {
|
|
403
|
+
const region = params[parameters.region.slug];
|
|
404
|
+
return region === "eu" ? "https://analytics.eu.amplitude.com" : "https://amplitude.com";
|
|
405
|
+
}
|
|
406
|
+
async function apiFetch(params, path2, init) {
|
|
407
|
+
const apiKey = params[parameters.apiKey.slug];
|
|
408
|
+
const secretKey = params[parameters.secretKey.slug];
|
|
409
|
+
if (!apiKey || !secretKey) {
|
|
410
|
+
throw new Error(
|
|
411
|
+
"amplitude: missing required parameters: api-key and secret-key"
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
const url = `${getBaseUrl(params)}${path2.startsWith("/") ? "" : "/"}${path2}`;
|
|
415
|
+
const headers = new Headers(init?.headers);
|
|
416
|
+
headers.set("Authorization", `Basic ${btoa(`${apiKey}:${secretKey}`)}`);
|
|
417
|
+
return fetch(url, { ...init, headers });
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// ../connectors/src/connectors/amplitude/setup-flow.ts
|
|
421
|
+
var AMPLITUDE_SETUP_MAX_ENTITIES = 10;
|
|
422
|
+
var AMPLITUDE_SETUP_MAX_EVENTS = 50;
|
|
423
|
+
var ENTITY_LABELS = {
|
|
424
|
+
events: { en: "Events", ja: "Events (\u30A4\u30D9\u30F3\u30C8)" },
|
|
425
|
+
userProperties: {
|
|
426
|
+
en: "User properties",
|
|
427
|
+
ja: "User properties (\u30E6\u30FC\u30B6\u30FC\u30D7\u30ED\u30D1\u30C6\u30A3)"
|
|
428
|
+
},
|
|
429
|
+
cohorts: { en: "Cohorts", ja: "Cohorts (\u30B3\u30DB\u30FC\u30C8)" },
|
|
430
|
+
charts: { en: "Charts", ja: "Charts (\u30C1\u30E3\u30FC\u30C8)" },
|
|
431
|
+
dashboards: { en: "Dashboards", ja: "Dashboards (\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9)" }
|
|
432
|
+
};
|
|
433
|
+
var ENTITY_DESCRIPTIONS = {
|
|
434
|
+
events: {
|
|
435
|
+
en: "Tracked event types with metadata.",
|
|
436
|
+
ja: "\u30E1\u30BF\u30C7\u30FC\u30BF\u4ED8\u304D\u3067\u8FFD\u8DE1\u3055\u308C\u3066\u3044\u308B\u30A4\u30D9\u30F3\u30C8\u30BF\u30A4\u30D7\u3002"
|
|
437
|
+
},
|
|
438
|
+
userProperties: {
|
|
439
|
+
en: "User-level properties used for segmentation.",
|
|
440
|
+
ja: "\u30BB\u30B0\u30E1\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u306B\u4F7F\u308F\u308C\u308B\u30E6\u30FC\u30B6\u30FC\u30EC\u30D9\u30EB\u306E\u30D7\u30ED\u30D1\u30C6\u30A3\u3002"
|
|
441
|
+
},
|
|
442
|
+
cohorts: {
|
|
443
|
+
en: "Saved user cohorts.",
|
|
444
|
+
ja: "\u4FDD\u5B58\u6E08\u307F\u306E\u30E6\u30FC\u30B6\u30FC\u30B3\u30DB\u30FC\u30C8\u3002"
|
|
445
|
+
},
|
|
446
|
+
charts: {
|
|
447
|
+
en: "Saved analytics charts.",
|
|
448
|
+
ja: "\u4FDD\u5B58\u6E08\u307F\u306E\u30A2\u30CA\u30EA\u30C6\u30A3\u30AF\u30B9\u30C1\u30E3\u30FC\u30C8\u3002"
|
|
449
|
+
},
|
|
450
|
+
dashboards: {
|
|
451
|
+
en: "Saved dashboards.",
|
|
452
|
+
ja: "\u4FDD\u5B58\u6E08\u307F\u306E\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9\u3002"
|
|
453
|
+
}
|
|
454
|
+
};
|
|
455
|
+
var ENTITY_VALUES = [
|
|
456
|
+
"events",
|
|
457
|
+
"userProperties",
|
|
458
|
+
"cohorts",
|
|
459
|
+
"charts",
|
|
460
|
+
"dashboards"
|
|
461
|
+
];
|
|
462
|
+
async function fetchEventNames(params) {
|
|
463
|
+
try {
|
|
464
|
+
const res = await apiFetch(params, "/api/2/taxonomy/event");
|
|
465
|
+
if (!res.ok) return [];
|
|
466
|
+
const data = await res.json();
|
|
467
|
+
return (data.data ?? []).map((e) => e.event_type ?? "").filter((name) => name);
|
|
468
|
+
} catch {
|
|
469
|
+
return [];
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
var amplitudeSetupFlow = {
|
|
473
|
+
initialState: () => ({}),
|
|
474
|
+
steps: [
|
|
475
|
+
{
|
|
476
|
+
slug: "entities",
|
|
477
|
+
type: "multiSelect",
|
|
478
|
+
question: {
|
|
479
|
+
ja: "\u5BFE\u8C61\u306E\u30A8\u30F3\u30C6\u30A3\u30C6\u30A3\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
|
|
480
|
+
en: "Select target entities (multi-select allowed)"
|
|
481
|
+
},
|
|
482
|
+
async fetchOptions(_state, rt) {
|
|
483
|
+
return ENTITY_VALUES.map((value) => ({
|
|
484
|
+
value,
|
|
485
|
+
label: ENTITY_LABELS[value][rt.language]
|
|
486
|
+
}));
|
|
487
|
+
},
|
|
488
|
+
applyAnswer: (state, answer) => ({ ...state, entities: answer })
|
|
489
|
+
}
|
|
490
|
+
],
|
|
491
|
+
async finalize(state, rt) {
|
|
492
|
+
if (!state.entities) {
|
|
493
|
+
throw new Error("Amplitude setup: incomplete state on finalize");
|
|
494
|
+
}
|
|
495
|
+
const selected = state.entities.filter(
|
|
496
|
+
(e) => ENTITY_VALUES.includes(e)
|
|
497
|
+
).slice(0, AMPLITUDE_SETUP_MAX_ENTITIES);
|
|
498
|
+
const sections = ["## Amplitude", ""];
|
|
499
|
+
for (const entity of selected) {
|
|
500
|
+
sections.push(`### ${ENTITY_LABELS[entity].en}`, "");
|
|
501
|
+
sections.push(ENTITY_DESCRIPTIONS[entity][rt.language], "");
|
|
502
|
+
if (entity === "events") {
|
|
503
|
+
const names = (await fetchEventNames(rt.params)).slice(
|
|
504
|
+
0,
|
|
505
|
+
AMPLITUDE_SETUP_MAX_EVENTS
|
|
506
|
+
);
|
|
507
|
+
if (names.length > 0) {
|
|
508
|
+
sections.push("Event names:", "");
|
|
509
|
+
for (const name of names) {
|
|
510
|
+
sections.push(`- ${name}`);
|
|
511
|
+
}
|
|
512
|
+
sections.push("");
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
return sections.join("\n");
|
|
517
|
+
}
|
|
518
|
+
};
|
|
519
|
+
|
|
334
520
|
// ../connectors/src/connectors/amplitude/tools/request.ts
|
|
335
521
|
import { z } from "zod";
|
|
336
522
|
var REQUEST_TIMEOUT_MS = 6e4;
|
|
@@ -559,7 +745,42 @@ export default async function handler(c: Context) {
|
|
|
559
745
|
- \`i\` \u2014 \u30A4\u30F3\u30BF\u30FC\u30D0\u30EB\uFF081=\u65E5\u6B21\u30017=\u9031\u6B21\u300130=\u6708\u6B21\uFF09
|
|
560
746
|
- \`g\` \u2014 \u30B0\u30EB\u30FC\u30D7\u5316\u30D7\u30ED\u30D1\u30C6\u30A3`
|
|
561
747
|
},
|
|
562
|
-
tools
|
|
748
|
+
tools,
|
|
749
|
+
setup: (params, ctx, config) => runSetupFlow(amplitudeSetupFlow, params, ctx, config),
|
|
750
|
+
async checkConnection(params, _config) {
|
|
751
|
+
const apiKey = params[parameters.apiKey.slug];
|
|
752
|
+
const secretKey = params[parameters.secretKey.slug];
|
|
753
|
+
if (!apiKey || !secretKey) {
|
|
754
|
+
return {
|
|
755
|
+
success: false,
|
|
756
|
+
error: "Missing required parameters: api-key and secret-key"
|
|
757
|
+
};
|
|
758
|
+
}
|
|
759
|
+
const region = params[parameters.region.slug];
|
|
760
|
+
const baseUrl = region === "eu" ? "https://analytics.eu.amplitude.com" : "https://amplitude.com";
|
|
761
|
+
try {
|
|
762
|
+
const res = await fetch(`${baseUrl}/api/2/events/list`, {
|
|
763
|
+
method: "GET",
|
|
764
|
+
headers: {
|
|
765
|
+
Authorization: `Basic ${btoa(`${apiKey}:${secretKey}`)}`,
|
|
766
|
+
Accept: "application/json"
|
|
767
|
+
}
|
|
768
|
+
});
|
|
769
|
+
if (!res.ok) {
|
|
770
|
+
const errorText = await res.text().catch(() => res.statusText);
|
|
771
|
+
return {
|
|
772
|
+
success: false,
|
|
773
|
+
error: `Amplitude API failed: HTTP ${res.status} ${errorText}`
|
|
774
|
+
};
|
|
775
|
+
}
|
|
776
|
+
return { success: true };
|
|
777
|
+
} catch (error) {
|
|
778
|
+
return {
|
|
779
|
+
success: false,
|
|
780
|
+
error: error instanceof Error ? error.message : String(error)
|
|
781
|
+
};
|
|
782
|
+
}
|
|
783
|
+
}
|
|
563
784
|
});
|
|
564
785
|
|
|
565
786
|
// src/connectors/create-connector-sdk.ts
|
|
@@ -588,6 +809,7 @@ function resolveEnvVarOptional(entry, key) {
|
|
|
588
809
|
import { getContext } from "hono/context-storage";
|
|
589
810
|
import { getCookie } from "hono/cookie";
|
|
590
811
|
var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
|
|
812
|
+
var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
|
|
591
813
|
function normalizeHeaders(input) {
|
|
592
814
|
const out = {};
|
|
593
815
|
if (!input) return out;
|
|
@@ -596,6 +818,11 @@ function normalizeHeaders(input) {
|
|
|
596
818
|
});
|
|
597
819
|
return out;
|
|
598
820
|
}
|
|
821
|
+
function extractInputUrl(input) {
|
|
822
|
+
if (typeof input === "string") return input;
|
|
823
|
+
if (input instanceof URL) return input.href;
|
|
824
|
+
return input.url;
|
|
825
|
+
}
|
|
599
826
|
function createSandboxProxyFetch(connectionId) {
|
|
600
827
|
return async (input, init) => {
|
|
601
828
|
const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
|
|
@@ -605,10 +832,17 @@ function createSandboxProxyFetch(connectionId) {
|
|
|
605
832
|
"Connection proxy is not configured. Please check your deployment settings."
|
|
606
833
|
);
|
|
607
834
|
}
|
|
608
|
-
const originalUrl =
|
|
835
|
+
const originalUrl = extractInputUrl(input);
|
|
836
|
+
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
837
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
838
|
+
const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
839
|
+
return fetch(sessionUrl, {
|
|
840
|
+
method: "POST",
|
|
841
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
842
|
+
});
|
|
843
|
+
}
|
|
609
844
|
const originalMethod = init?.method ?? "GET";
|
|
610
845
|
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
611
|
-
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
612
846
|
const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
613
847
|
return fetch(proxyUrl, {
|
|
614
848
|
method: "POST",
|
|
@@ -634,10 +868,9 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
634
868
|
}
|
|
635
869
|
const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
|
|
636
870
|
const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
871
|
+
const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
637
872
|
return async (input, init) => {
|
|
638
|
-
const originalUrl =
|
|
639
|
-
const originalMethod = init?.method ?? "GET";
|
|
640
|
-
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
873
|
+
const originalUrl = extractInputUrl(input);
|
|
641
874
|
const c = getContext();
|
|
642
875
|
const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
|
|
643
876
|
if (!appSession) {
|
|
@@ -645,6 +878,14 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
645
878
|
"No authentication method available for connection proxy."
|
|
646
879
|
);
|
|
647
880
|
}
|
|
881
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
882
|
+
return fetch(sessionUrl, {
|
|
883
|
+
method: "POST",
|
|
884
|
+
headers: { Authorization: `Bearer ${appSession}` }
|
|
885
|
+
});
|
|
886
|
+
}
|
|
887
|
+
const originalMethod = init?.method ?? "GET";
|
|
888
|
+
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
648
889
|
return fetch(proxyUrl, {
|
|
649
890
|
method: "POST",
|
|
650
891
|
headers: {
|
|
@@ -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/anthropic/parameters.ts
|
|
57
|
+
init_parameter_definition();
|
|
46
58
|
var parameters = {
|
|
47
59
|
apiKey: new ParameterDefinition({
|
|
48
60
|
slug: "api-key",
|
|
@@ -91,6 +103,20 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
91
103
|
* `runSetupFlow` from `setup-flow.ts`.
|
|
92
104
|
*/
|
|
93
105
|
setup;
|
|
106
|
+
/**
|
|
107
|
+
* Opt-out of the default "verify before save" behavior on connection
|
|
108
|
+
* creation. The backend invokes `checkConnection` synchronously while
|
|
109
|
+
* creating the connection and aborts (no row inserted) if it fails — this
|
|
110
|
+
* flag disables that for connectors where the check cannot succeed pre-save:
|
|
111
|
+
*
|
|
112
|
+
* - `squadbase-db` populates `connection-url` only after Neon provisioning
|
|
113
|
+
* - OAuth connectors require an OAuth-aware proxyFetch keyed by the
|
|
114
|
+
* connectionId, which doesn't exist until the row is saved
|
|
115
|
+
*
|
|
116
|
+
* Exceptions are the explicit position; new credential-input connectors get
|
|
117
|
+
* the default verify-on-create behavior without opt-in.
|
|
118
|
+
*/
|
|
119
|
+
skipConnectionCheckOnCreate;
|
|
94
120
|
constructor(config) {
|
|
95
121
|
this.slug = config.slug;
|
|
96
122
|
this.authType = config.authType;
|
|
@@ -108,6 +134,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
108
134
|
this.query = config.query;
|
|
109
135
|
this.checkConnection = config.checkConnection;
|
|
110
136
|
this.setup = config.setup;
|
|
137
|
+
this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
|
|
111
138
|
}
|
|
112
139
|
get connectorKey() {
|
|
113
140
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
@@ -243,7 +270,39 @@ export default async function handler(c: Context) {
|
|
|
243
270
|
}
|
|
244
271
|
\`\`\``
|
|
245
272
|
},
|
|
246
|
-
tools
|
|
273
|
+
tools,
|
|
274
|
+
async checkConnection(params, _config) {
|
|
275
|
+
try {
|
|
276
|
+
const apiKey = params[parameters.apiKey.slug];
|
|
277
|
+
if (!apiKey) {
|
|
278
|
+
return {
|
|
279
|
+
success: false,
|
|
280
|
+
error: "Missing required parameter: api-key"
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
const res = await fetch("https://api.anthropic.com/v1/models", {
|
|
284
|
+
method: "GET",
|
|
285
|
+
headers: {
|
|
286
|
+
"x-api-key": apiKey,
|
|
287
|
+
"anthropic-version": "2023-06-01",
|
|
288
|
+
Accept: "application/json"
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
if (!res.ok) {
|
|
292
|
+
const errorText = await res.text().catch(() => res.statusText);
|
|
293
|
+
return {
|
|
294
|
+
success: false,
|
|
295
|
+
error: `Anthropic API failed: HTTP ${res.status} ${errorText}`
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
return { success: true };
|
|
299
|
+
} catch (error) {
|
|
300
|
+
return {
|
|
301
|
+
success: false,
|
|
302
|
+
error: error instanceof Error ? error.message : String(error)
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
}
|
|
247
306
|
});
|
|
248
307
|
|
|
249
308
|
// src/connectors/create-connector-sdk.ts
|
|
@@ -272,6 +331,7 @@ function resolveEnvVarOptional(entry, key) {
|
|
|
272
331
|
import { getContext } from "hono/context-storage";
|
|
273
332
|
import { getCookie } from "hono/cookie";
|
|
274
333
|
var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
|
|
334
|
+
var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
|
|
275
335
|
function normalizeHeaders(input) {
|
|
276
336
|
const out = {};
|
|
277
337
|
if (!input) return out;
|
|
@@ -280,6 +340,11 @@ function normalizeHeaders(input) {
|
|
|
280
340
|
});
|
|
281
341
|
return out;
|
|
282
342
|
}
|
|
343
|
+
function extractInputUrl(input) {
|
|
344
|
+
if (typeof input === "string") return input;
|
|
345
|
+
if (input instanceof URL) return input.href;
|
|
346
|
+
return input.url;
|
|
347
|
+
}
|
|
283
348
|
function createSandboxProxyFetch(connectionId) {
|
|
284
349
|
return async (input, init) => {
|
|
285
350
|
const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
|
|
@@ -289,10 +354,17 @@ function createSandboxProxyFetch(connectionId) {
|
|
|
289
354
|
"Connection proxy is not configured. Please check your deployment settings."
|
|
290
355
|
);
|
|
291
356
|
}
|
|
292
|
-
const originalUrl =
|
|
357
|
+
const originalUrl = extractInputUrl(input);
|
|
358
|
+
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
359
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
360
|
+
const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
361
|
+
return fetch(sessionUrl, {
|
|
362
|
+
method: "POST",
|
|
363
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
364
|
+
});
|
|
365
|
+
}
|
|
293
366
|
const originalMethod = init?.method ?? "GET";
|
|
294
367
|
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
295
|
-
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
296
368
|
const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
297
369
|
return fetch(proxyUrl, {
|
|
298
370
|
method: "POST",
|
|
@@ -318,10 +390,9 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
318
390
|
}
|
|
319
391
|
const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
|
|
320
392
|
const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
393
|
+
const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
321
394
|
return async (input, init) => {
|
|
322
|
-
const originalUrl =
|
|
323
|
-
const originalMethod = init?.method ?? "GET";
|
|
324
|
-
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
395
|
+
const originalUrl = extractInputUrl(input);
|
|
325
396
|
const c = getContext();
|
|
326
397
|
const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
|
|
327
398
|
if (!appSession) {
|
|
@@ -329,6 +400,14 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
329
400
|
"No authentication method available for connection proxy."
|
|
330
401
|
);
|
|
331
402
|
}
|
|
403
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
404
|
+
return fetch(sessionUrl, {
|
|
405
|
+
method: "POST",
|
|
406
|
+
headers: { Authorization: `Bearer ${appSession}` }
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
const originalMethod = init?.method ?? "GET";
|
|
410
|
+
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
332
411
|
return fetch(proxyUrl, {
|
|
333
412
|
method: "POST",
|
|
334
413
|
headers: {
|