@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/stripe-api-key/parameters.ts
|
|
57
|
+
init_parameter_definition();
|
|
46
58
|
var parameters = {
|
|
47
59
|
apiKey: new ParameterDefinition({
|
|
48
60
|
slug: "api-key",
|
|
@@ -141,6 +153,20 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
141
153
|
* `runSetupFlow` from `setup-flow.ts`.
|
|
142
154
|
*/
|
|
143
155
|
setup;
|
|
156
|
+
/**
|
|
157
|
+
* Opt-out of the default "verify before save" behavior on connection
|
|
158
|
+
* creation. The backend invokes `checkConnection` synchronously while
|
|
159
|
+
* creating the connection and aborts (no row inserted) if it fails — this
|
|
160
|
+
* flag disables that for connectors where the check cannot succeed pre-save:
|
|
161
|
+
*
|
|
162
|
+
* - `squadbase-db` populates `connection-url` only after Neon provisioning
|
|
163
|
+
* - OAuth connectors require an OAuth-aware proxyFetch keyed by the
|
|
164
|
+
* connectionId, which doesn't exist until the row is saved
|
|
165
|
+
*
|
|
166
|
+
* Exceptions are the explicit position; new credential-input connectors get
|
|
167
|
+
* the default verify-on-create behavior without opt-in.
|
|
168
|
+
*/
|
|
169
|
+
skipConnectionCheckOnCreate;
|
|
144
170
|
constructor(config) {
|
|
145
171
|
this.slug = config.slug;
|
|
146
172
|
this.authType = config.authType;
|
|
@@ -158,6 +184,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
158
184
|
this.query = config.query;
|
|
159
185
|
this.checkConnection = config.checkConnection;
|
|
160
186
|
this.setup = config.setup;
|
|
187
|
+
this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
|
|
161
188
|
}
|
|
162
189
|
get connectorKey() {
|
|
163
190
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
@@ -222,6 +249,46 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
222
249
|
}
|
|
223
250
|
};
|
|
224
251
|
|
|
252
|
+
// ../connectors/src/setup-flow.ts
|
|
253
|
+
async function runSetupFlow(flow, params, ctx, config) {
|
|
254
|
+
const runtime = {
|
|
255
|
+
params,
|
|
256
|
+
language: ctx.language,
|
|
257
|
+
config
|
|
258
|
+
};
|
|
259
|
+
let state = flow.initialState();
|
|
260
|
+
let answerIdx = 0;
|
|
261
|
+
for (const step of flow.steps) {
|
|
262
|
+
const ans = ctx.answers[answerIdx];
|
|
263
|
+
if (ans && ans.questionSlug === step.slug) {
|
|
264
|
+
state = step.applyAnswer(state, ans.answer);
|
|
265
|
+
answerIdx += 1;
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
if (step.type === "text") {
|
|
269
|
+
return {
|
|
270
|
+
type: "nextQuestion",
|
|
271
|
+
questionSlug: step.slug,
|
|
272
|
+
question: step.question[ctx.language],
|
|
273
|
+
questionType: "text"
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
|
|
277
|
+
if (options.length === 0) {
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
return {
|
|
281
|
+
type: "nextQuestion",
|
|
282
|
+
questionSlug: step.slug,
|
|
283
|
+
question: step.question[ctx.language],
|
|
284
|
+
questionType: step.type,
|
|
285
|
+
options
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
const dataInvestigationResult = await flow.finalize(state, runtime);
|
|
289
|
+
return { type: "fulfilled", dataInvestigationResult };
|
|
290
|
+
}
|
|
291
|
+
|
|
225
292
|
// ../connectors/src/auth-types.ts
|
|
226
293
|
var AUTH_TYPES = {
|
|
227
294
|
OAUTH: "oauth",
|
|
@@ -361,6 +428,107 @@ var stripeApiKeyOnboarding = new ConnectorOnboarding({
|
|
|
361
428
|
}
|
|
362
429
|
});
|
|
363
430
|
|
|
431
|
+
// ../connectors/src/connectors/stripe-api-key/utils.ts
|
|
432
|
+
var BASE_URL3 = "https://api.stripe.com";
|
|
433
|
+
async function apiFetch(params, path2, init) {
|
|
434
|
+
const apiKey = params[parameters.apiKey.slug];
|
|
435
|
+
if (!apiKey) {
|
|
436
|
+
throw new Error("stripe-api-key: missing required parameter: api-key");
|
|
437
|
+
}
|
|
438
|
+
const url = `${BASE_URL3}${path2.startsWith("/") ? "" : "/"}${path2}`;
|
|
439
|
+
const headers = new Headers(init?.headers);
|
|
440
|
+
headers.set("Authorization", `Bearer ${apiKey}`);
|
|
441
|
+
return fetch(url, { ...init, headers });
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// ../connectors/src/connectors/stripe-api-key/setup-flow.ts
|
|
445
|
+
var STRIPE_SETUP_MAX_ENTITIES = 10;
|
|
446
|
+
var ENTITY_LABELS = {
|
|
447
|
+
customers: { en: "Customers", ja: "Customers (\u9867\u5BA2)" },
|
|
448
|
+
charges: { en: "Charges", ja: "Charges (\u652F\u6255\u3044)" },
|
|
449
|
+
invoices: { en: "Invoices", ja: "Invoices (\u8ACB\u6C42\u66F8)" },
|
|
450
|
+
subscriptions: {
|
|
451
|
+
en: "Subscriptions",
|
|
452
|
+
ja: "Subscriptions (\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3)"
|
|
453
|
+
},
|
|
454
|
+
products: { en: "Products", ja: "Products (\u5546\u54C1)" },
|
|
455
|
+
prices: { en: "Prices", ja: "Prices (\u4FA1\u683C)" },
|
|
456
|
+
payouts: { en: "Payouts", ja: "Payouts (\u652F\u6255\u3044)" },
|
|
457
|
+
refunds: { en: "Refunds", ja: "Refunds (\u8FD4\u91D1)" },
|
|
458
|
+
disputes: { en: "Disputes", ja: "Disputes (\u7570\u8B70)" },
|
|
459
|
+
paymentIntents: {
|
|
460
|
+
en: "Payment intents",
|
|
461
|
+
ja: "Payment intents (\u652F\u6255\u3044\u30A4\u30F3\u30C6\u30F3\u30C8)"
|
|
462
|
+
}
|
|
463
|
+
};
|
|
464
|
+
var ENTITY_PATHS = {
|
|
465
|
+
customers: "/v1/customers?limit=1",
|
|
466
|
+
charges: "/v1/charges?limit=1",
|
|
467
|
+
invoices: "/v1/invoices?limit=1",
|
|
468
|
+
subscriptions: "/v1/subscriptions?limit=1",
|
|
469
|
+
products: "/v1/products?limit=1",
|
|
470
|
+
prices: "/v1/prices?limit=1",
|
|
471
|
+
payouts: "/v1/payouts?limit=1",
|
|
472
|
+
refunds: "/v1/refunds?limit=1",
|
|
473
|
+
disputes: "/v1/disputes?limit=1",
|
|
474
|
+
paymentIntents: "/v1/payment_intents?limit=1"
|
|
475
|
+
};
|
|
476
|
+
var ENTITY_VALUES = Object.keys(ENTITY_PATHS);
|
|
477
|
+
async function defaultFetchEntity(params, path2) {
|
|
478
|
+
return apiFetch(params, path2);
|
|
479
|
+
}
|
|
480
|
+
function createStripeSetupFlow(fetchEntity = defaultFetchEntity, labelPrefix = "Stripe") {
|
|
481
|
+
return {
|
|
482
|
+
initialState: () => ({}),
|
|
483
|
+
steps: [
|
|
484
|
+
{
|
|
485
|
+
slug: "entities",
|
|
486
|
+
type: "multiSelect",
|
|
487
|
+
question: {
|
|
488
|
+
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",
|
|
489
|
+
en: "Select target entities (multi-select allowed)"
|
|
490
|
+
},
|
|
491
|
+
async fetchOptions(_state, rt) {
|
|
492
|
+
return ENTITY_VALUES.map((value) => ({
|
|
493
|
+
value,
|
|
494
|
+
label: ENTITY_LABELS[value][rt.language]
|
|
495
|
+
}));
|
|
496
|
+
},
|
|
497
|
+
applyAnswer: (state, answer) => ({ ...state, entities: answer })
|
|
498
|
+
}
|
|
499
|
+
],
|
|
500
|
+
async finalize(state, rt) {
|
|
501
|
+
if (!state.entities) {
|
|
502
|
+
throw new Error("Stripe setup: incomplete state on finalize");
|
|
503
|
+
}
|
|
504
|
+
const selected = state.entities.filter(
|
|
505
|
+
(e) => ENTITY_VALUES.includes(e)
|
|
506
|
+
).slice(0, STRIPE_SETUP_MAX_ENTITIES);
|
|
507
|
+
const sections = [`## ${labelPrefix}`, ""];
|
|
508
|
+
for (const entity of selected) {
|
|
509
|
+
let count = "available";
|
|
510
|
+
const res = await fetchEntity(rt.params, ENTITY_PATHS[entity]);
|
|
511
|
+
if (res.ok) {
|
|
512
|
+
const data = await res.json();
|
|
513
|
+
if (Array.isArray(data.data) && data.data.length === 0) {
|
|
514
|
+
count = "0";
|
|
515
|
+
} else if (data.has_more === false) {
|
|
516
|
+
count = String(data.data?.length ?? 1);
|
|
517
|
+
} else if (Array.isArray(data.data)) {
|
|
518
|
+
count = "1+ (paginated)";
|
|
519
|
+
}
|
|
520
|
+
} else {
|
|
521
|
+
count = "unavailable";
|
|
522
|
+
}
|
|
523
|
+
sections.push(`### ${ENTITY_LABELS[entity].en}`, "");
|
|
524
|
+
sections.push(`Status: ${count}`, "");
|
|
525
|
+
}
|
|
526
|
+
return sections.join("\n");
|
|
527
|
+
}
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
var stripeApiKeySetupFlow = createStripeSetupFlow();
|
|
531
|
+
|
|
364
532
|
// ../connectors/src/connectors/stripe-api-key/index.ts
|
|
365
533
|
var tools = { request: requestTool };
|
|
366
534
|
var stripeApiKeyConnector = new ConnectorPlugin({
|
|
@@ -478,6 +646,7 @@ const data = await res.json();
|
|
|
478
646
|
\`\`\``
|
|
479
647
|
},
|
|
480
648
|
tools,
|
|
649
|
+
setup: (params, ctx, config) => runSetupFlow(stripeApiKeySetupFlow, params, ctx, config),
|
|
481
650
|
async checkConnection(params) {
|
|
482
651
|
try {
|
|
483
652
|
const apiKey = params["api-key"];
|
|
@@ -534,6 +703,7 @@ function resolveEnvVarOptional(entry, key) {
|
|
|
534
703
|
import { getContext } from "hono/context-storage";
|
|
535
704
|
import { getCookie } from "hono/cookie";
|
|
536
705
|
var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
|
|
706
|
+
var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
|
|
537
707
|
function normalizeHeaders(input) {
|
|
538
708
|
const out = {};
|
|
539
709
|
if (!input) return out;
|
|
@@ -542,6 +712,11 @@ function normalizeHeaders(input) {
|
|
|
542
712
|
});
|
|
543
713
|
return out;
|
|
544
714
|
}
|
|
715
|
+
function extractInputUrl(input) {
|
|
716
|
+
if (typeof input === "string") return input;
|
|
717
|
+
if (input instanceof URL) return input.href;
|
|
718
|
+
return input.url;
|
|
719
|
+
}
|
|
545
720
|
function createSandboxProxyFetch(connectionId) {
|
|
546
721
|
return async (input, init) => {
|
|
547
722
|
const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
|
|
@@ -551,10 +726,17 @@ function createSandboxProxyFetch(connectionId) {
|
|
|
551
726
|
"Connection proxy is not configured. Please check your deployment settings."
|
|
552
727
|
);
|
|
553
728
|
}
|
|
554
|
-
const originalUrl =
|
|
729
|
+
const originalUrl = extractInputUrl(input);
|
|
730
|
+
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
731
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
732
|
+
const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
733
|
+
return fetch(sessionUrl, {
|
|
734
|
+
method: "POST",
|
|
735
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
736
|
+
});
|
|
737
|
+
}
|
|
555
738
|
const originalMethod = init?.method ?? "GET";
|
|
556
739
|
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
557
|
-
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
558
740
|
const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
559
741
|
return fetch(proxyUrl, {
|
|
560
742
|
method: "POST",
|
|
@@ -580,10 +762,9 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
580
762
|
}
|
|
581
763
|
const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
|
|
582
764
|
const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
765
|
+
const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
583
766
|
return async (input, init) => {
|
|
584
|
-
const originalUrl =
|
|
585
|
-
const originalMethod = init?.method ?? "GET";
|
|
586
|
-
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
767
|
+
const originalUrl = extractInputUrl(input);
|
|
587
768
|
const c = getContext();
|
|
588
769
|
const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
|
|
589
770
|
if (!appSession) {
|
|
@@ -591,6 +772,14 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
591
772
|
"No authentication method available for connection proxy."
|
|
592
773
|
);
|
|
593
774
|
}
|
|
775
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
776
|
+
return fetch(sessionUrl, {
|
|
777
|
+
method: "POST",
|
|
778
|
+
headers: { Authorization: `Bearer ${appSession}` }
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
const originalMethod = init?.method ?? "GET";
|
|
782
|
+
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
594
783
|
return fetch(proxyUrl, {
|
|
595
784
|
method: "POST",
|
|
596
785
|
headers: {
|
|
@@ -75,6 +75,20 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
75
75
|
* `runSetupFlow` from `setup-flow.ts`.
|
|
76
76
|
*/
|
|
77
77
|
setup;
|
|
78
|
+
/**
|
|
79
|
+
* Opt-out of the default "verify before save" behavior on connection
|
|
80
|
+
* creation. The backend invokes `checkConnection` synchronously while
|
|
81
|
+
* creating the connection and aborts (no row inserted) if it fails — this
|
|
82
|
+
* flag disables that for connectors where the check cannot succeed pre-save:
|
|
83
|
+
*
|
|
84
|
+
* - `squadbase-db` populates `connection-url` only after Neon provisioning
|
|
85
|
+
* - OAuth connectors require an OAuth-aware proxyFetch keyed by the
|
|
86
|
+
* connectionId, which doesn't exist until the row is saved
|
|
87
|
+
*
|
|
88
|
+
* Exceptions are the explicit position; new credential-input connectors get
|
|
89
|
+
* the default verify-on-create behavior without opt-in.
|
|
90
|
+
*/
|
|
91
|
+
skipConnectionCheckOnCreate;
|
|
78
92
|
constructor(config) {
|
|
79
93
|
this.slug = config.slug;
|
|
80
94
|
this.authType = config.authType;
|
|
@@ -92,6 +106,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
92
106
|
this.query = config.query;
|
|
93
107
|
this.checkConnection = config.checkConnection;
|
|
94
108
|
this.setup = config.setup;
|
|
109
|
+
this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
|
|
95
110
|
}
|
|
96
111
|
get connectorKey() {
|
|
97
112
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
@@ -156,6 +171,46 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
156
171
|
}
|
|
157
172
|
};
|
|
158
173
|
|
|
174
|
+
// ../connectors/src/setup-flow.ts
|
|
175
|
+
async function runSetupFlow(flow, params, ctx, config) {
|
|
176
|
+
const runtime = {
|
|
177
|
+
params,
|
|
178
|
+
language: ctx.language,
|
|
179
|
+
config
|
|
180
|
+
};
|
|
181
|
+
let state = flow.initialState();
|
|
182
|
+
let answerIdx = 0;
|
|
183
|
+
for (const step of flow.steps) {
|
|
184
|
+
const ans = ctx.answers[answerIdx];
|
|
185
|
+
if (ans && ans.questionSlug === step.slug) {
|
|
186
|
+
state = step.applyAnswer(state, ans.answer);
|
|
187
|
+
answerIdx += 1;
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
if (step.type === "text") {
|
|
191
|
+
return {
|
|
192
|
+
type: "nextQuestion",
|
|
193
|
+
questionSlug: step.slug,
|
|
194
|
+
question: step.question[ctx.language],
|
|
195
|
+
questionType: "text"
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
|
|
199
|
+
if (options.length === 0) {
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
return {
|
|
203
|
+
type: "nextQuestion",
|
|
204
|
+
questionSlug: step.slug,
|
|
205
|
+
question: step.question[ctx.language],
|
|
206
|
+
questionType: step.type,
|
|
207
|
+
options
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
const dataInvestigationResult = await flow.finalize(state, runtime);
|
|
211
|
+
return { type: "fulfilled", dataInvestigationResult };
|
|
212
|
+
}
|
|
213
|
+
|
|
159
214
|
// ../connectors/src/auth-types.ts
|
|
160
215
|
var AUTH_TYPES = {
|
|
161
216
|
OAUTH: "oauth",
|
|
@@ -319,11 +374,98 @@ var stripeOnboarding = new ConnectorOnboarding({
|
|
|
319
374
|
// ../connectors/src/connectors/stripe-oauth/parameters.ts
|
|
320
375
|
var parameters = {};
|
|
321
376
|
|
|
377
|
+
// ../connectors/src/connectors/stripe-oauth/setup-flow.ts
|
|
378
|
+
var BASE_URL3 = "https://api.stripe.com";
|
|
379
|
+
var STRIPE_OAUTH_SETUP_MAX_ENTITIES = 10;
|
|
380
|
+
var ENTITY_LABELS = {
|
|
381
|
+
customers: { en: "Customers", ja: "Customers (\u9867\u5BA2)" },
|
|
382
|
+
charges: { en: "Charges", ja: "Charges (\u652F\u6255\u3044)" },
|
|
383
|
+
invoices: { en: "Invoices", ja: "Invoices (\u8ACB\u6C42\u66F8)" },
|
|
384
|
+
subscriptions: {
|
|
385
|
+
en: "Subscriptions",
|
|
386
|
+
ja: "Subscriptions (\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3)"
|
|
387
|
+
},
|
|
388
|
+
products: { en: "Products", ja: "Products (\u5546\u54C1)" },
|
|
389
|
+
prices: { en: "Prices", ja: "Prices (\u4FA1\u683C)" },
|
|
390
|
+
payouts: { en: "Payouts", ja: "Payouts (\u652F\u6255\u3044)" },
|
|
391
|
+
refunds: { en: "Refunds", ja: "Refunds (\u8FD4\u91D1)" },
|
|
392
|
+
disputes: { en: "Disputes", ja: "Disputes (\u7570\u8B70)" },
|
|
393
|
+
paymentIntents: {
|
|
394
|
+
en: "Payment intents",
|
|
395
|
+
ja: "Payment intents (\u652F\u6255\u3044\u30A4\u30F3\u30C6\u30F3\u30C8)"
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
var ENTITY_PATHS = {
|
|
399
|
+
customers: "/v1/customers?limit=1",
|
|
400
|
+
charges: "/v1/charges?limit=1",
|
|
401
|
+
invoices: "/v1/invoices?limit=1",
|
|
402
|
+
subscriptions: "/v1/subscriptions?limit=1",
|
|
403
|
+
products: "/v1/products?limit=1",
|
|
404
|
+
prices: "/v1/prices?limit=1",
|
|
405
|
+
payouts: "/v1/payouts?limit=1",
|
|
406
|
+
refunds: "/v1/refunds?limit=1",
|
|
407
|
+
disputes: "/v1/disputes?limit=1",
|
|
408
|
+
paymentIntents: "/v1/payment_intents?limit=1"
|
|
409
|
+
};
|
|
410
|
+
var ENTITY_VALUES = Object.keys(ENTITY_PATHS);
|
|
411
|
+
var stripeOauthSetupFlow = {
|
|
412
|
+
initialState: () => ({}),
|
|
413
|
+
steps: [
|
|
414
|
+
{
|
|
415
|
+
slug: "entities",
|
|
416
|
+
type: "multiSelect",
|
|
417
|
+
question: {
|
|
418
|
+
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",
|
|
419
|
+
en: "Select target entities (multi-select allowed)"
|
|
420
|
+
},
|
|
421
|
+
async fetchOptions(_state, rt) {
|
|
422
|
+
return ENTITY_VALUES.map((value) => ({
|
|
423
|
+
value,
|
|
424
|
+
label: ENTITY_LABELS[value][rt.language]
|
|
425
|
+
}));
|
|
426
|
+
},
|
|
427
|
+
applyAnswer: (state, answer) => ({ ...state, entities: answer })
|
|
428
|
+
}
|
|
429
|
+
],
|
|
430
|
+
async finalize(state, rt) {
|
|
431
|
+
if (!state.entities) {
|
|
432
|
+
throw new Error("Stripe setup: incomplete state on finalize");
|
|
433
|
+
}
|
|
434
|
+
const selected = state.entities.filter(
|
|
435
|
+
(e) => ENTITY_VALUES.includes(e)
|
|
436
|
+
).slice(0, STRIPE_OAUTH_SETUP_MAX_ENTITIES);
|
|
437
|
+
const sections = ["## Stripe", ""];
|
|
438
|
+
for (const entity of selected) {
|
|
439
|
+
let count = "available";
|
|
440
|
+
const res = await rt.config.proxyFetch(
|
|
441
|
+
`${BASE_URL3}${ENTITY_PATHS[entity]}`,
|
|
442
|
+
{ method: "GET" }
|
|
443
|
+
);
|
|
444
|
+
if (res.ok) {
|
|
445
|
+
const data = await res.json();
|
|
446
|
+
if (Array.isArray(data.data) && data.data.length === 0) {
|
|
447
|
+
count = "0";
|
|
448
|
+
} else if (data.has_more === false) {
|
|
449
|
+
count = String(data.data?.length ?? 1);
|
|
450
|
+
} else if (Array.isArray(data.data)) {
|
|
451
|
+
count = "1+ (paginated)";
|
|
452
|
+
}
|
|
453
|
+
} else {
|
|
454
|
+
count = "unavailable";
|
|
455
|
+
}
|
|
456
|
+
sections.push(`### ${ENTITY_LABELS[entity].en}`, "");
|
|
457
|
+
sections.push(`Status: ${count}`, "");
|
|
458
|
+
}
|
|
459
|
+
return sections.join("\n");
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
|
|
322
463
|
// ../connectors/src/connectors/stripe-oauth/index.ts
|
|
323
464
|
var tools = { request: requestTool };
|
|
324
465
|
var stripeOauthConnector = new ConnectorPlugin({
|
|
325
466
|
slug: "stripe",
|
|
326
467
|
authType: AUTH_TYPES.OAUTH,
|
|
468
|
+
skipConnectionCheckOnCreate: true,
|
|
327
469
|
name: "Stripe",
|
|
328
470
|
description: "Connect to Stripe for payment, customer, and subscription data using OAuth.",
|
|
329
471
|
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/2QNK0u2doqp41uL0POS4Ks/7a92367e2388ec77c7f4ada143606f9a/stripe.jpeg",
|
|
@@ -440,6 +582,7 @@ const data = await res.json();
|
|
|
440
582
|
\`\`\``
|
|
441
583
|
},
|
|
442
584
|
tools,
|
|
585
|
+
setup: (params, ctx, config) => runSetupFlow(stripeOauthSetupFlow, params, ctx, config),
|
|
443
586
|
async checkConnection(_params, config) {
|
|
444
587
|
const { proxyFetch } = config;
|
|
445
588
|
try {
|
|
@@ -489,6 +632,7 @@ function resolveEnvVarOptional(entry, key) {
|
|
|
489
632
|
import { getContext } from "hono/context-storage";
|
|
490
633
|
import { getCookie } from "hono/cookie";
|
|
491
634
|
var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
|
|
635
|
+
var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
|
|
492
636
|
function normalizeHeaders(input) {
|
|
493
637
|
const out = {};
|
|
494
638
|
if (!input) return out;
|
|
@@ -497,6 +641,11 @@ function normalizeHeaders(input) {
|
|
|
497
641
|
});
|
|
498
642
|
return out;
|
|
499
643
|
}
|
|
644
|
+
function extractInputUrl(input) {
|
|
645
|
+
if (typeof input === "string") return input;
|
|
646
|
+
if (input instanceof URL) return input.href;
|
|
647
|
+
return input.url;
|
|
648
|
+
}
|
|
500
649
|
function createSandboxProxyFetch(connectionId) {
|
|
501
650
|
return async (input, init) => {
|
|
502
651
|
const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
|
|
@@ -506,10 +655,17 @@ function createSandboxProxyFetch(connectionId) {
|
|
|
506
655
|
"Connection proxy is not configured. Please check your deployment settings."
|
|
507
656
|
);
|
|
508
657
|
}
|
|
509
|
-
const originalUrl =
|
|
658
|
+
const originalUrl = extractInputUrl(input);
|
|
659
|
+
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
660
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
661
|
+
const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
662
|
+
return fetch(sessionUrl, {
|
|
663
|
+
method: "POST",
|
|
664
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
665
|
+
});
|
|
666
|
+
}
|
|
510
667
|
const originalMethod = init?.method ?? "GET";
|
|
511
668
|
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
512
|
-
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
513
669
|
const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
514
670
|
return fetch(proxyUrl, {
|
|
515
671
|
method: "POST",
|
|
@@ -535,10 +691,9 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
535
691
|
}
|
|
536
692
|
const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
|
|
537
693
|
const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
694
|
+
const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
538
695
|
return async (input, init) => {
|
|
539
|
-
const originalUrl =
|
|
540
|
-
const originalMethod = init?.method ?? "GET";
|
|
541
|
-
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
696
|
+
const originalUrl = extractInputUrl(input);
|
|
542
697
|
const c = getContext();
|
|
543
698
|
const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
|
|
544
699
|
if (!appSession) {
|
|
@@ -546,6 +701,14 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
546
701
|
"No authentication method available for connection proxy."
|
|
547
702
|
);
|
|
548
703
|
}
|
|
704
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
705
|
+
return fetch(sessionUrl, {
|
|
706
|
+
method: "POST",
|
|
707
|
+
headers: { Authorization: `Bearer ${appSession}` }
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
const originalMethod = init?.method ?? "GET";
|
|
711
|
+
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
549
712
|
return fetch(proxyUrl, {
|
|
550
713
|
method: "POST",
|
|
551
714
|
headers: {
|