@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.
Files changed (77) hide show
  1. package/dist/cli/index.js +14375 -1652
  2. package/dist/connectors/airtable-oauth.js +282 -46
  3. package/dist/connectors/airtable.js +319 -51
  4. package/dist/connectors/amplitude.js +322 -47
  5. package/dist/connectors/anthropic.js +135 -47
  6. package/dist/connectors/asana.js +327 -49
  7. package/dist/connectors/attio.js +302 -49
  8. package/dist/connectors/aws-billing.js +287 -46
  9. package/dist/connectors/azure-sql.js +421 -102
  10. package/dist/connectors/backlog-api-key.js +317 -47
  11. package/dist/connectors/clickup.js +338 -49
  12. package/dist/connectors/cosmosdb.js +305 -50
  13. package/dist/connectors/customerio.js +319 -47
  14. package/dist/connectors/dbt.js +340 -47
  15. package/dist/connectors/freshdesk.js +342 -53
  16. package/dist/connectors/freshsales.js +333 -52
  17. package/dist/connectors/freshservice.js +361 -53
  18. package/dist/connectors/gamma.js +327 -52
  19. package/dist/connectors/gemini.js +134 -47
  20. package/dist/connectors/github.js +386 -49
  21. package/dist/connectors/gmail-oauth.js +204 -7
  22. package/dist/connectors/gmail.js +350 -47
  23. package/dist/connectors/google-ads.js +288 -46
  24. package/dist/connectors/google-analytics-oauth.js +310 -46
  25. package/dist/connectors/google-analytics.js +547 -87
  26. package/dist/connectors/google-audit-log.js +438 -47
  27. package/dist/connectors/google-calendar-oauth.js +259 -46
  28. package/dist/connectors/google-calendar.js +359 -47
  29. package/dist/connectors/google-docs.js +220 -6
  30. package/dist/connectors/google-drive.js +262 -5
  31. package/dist/connectors/google-search-console-oauth.js +256 -46
  32. package/dist/connectors/google-sheets.js +272 -47
  33. package/dist/connectors/google-slides.js +205 -6
  34. package/dist/connectors/grafana.js +332 -49
  35. package/dist/connectors/hubspot-oauth.js +208 -5
  36. package/dist/connectors/hubspot.js +306 -49
  37. package/dist/connectors/influxdb.js +416 -51
  38. package/dist/connectors/intercom-oauth.js +210 -5
  39. package/dist/connectors/intercom.js +302 -49
  40. package/dist/connectors/jdbc.js +762 -110
  41. package/dist/connectors/jira-api-key.js +326 -47
  42. package/dist/connectors/kintone-api-token.js +281 -47
  43. package/dist/connectors/kintone.js +328 -47
  44. package/dist/connectors/linear.js +330 -49
  45. package/dist/connectors/linkedin-ads.js +268 -50
  46. package/dist/connectors/mailchimp-oauth.js +268 -46
  47. package/dist/connectors/mailchimp.js +320 -49
  48. package/dist/connectors/meta-ads-oauth.js +273 -48
  49. package/dist/connectors/meta-ads.js +285 -50
  50. package/dist/connectors/mixpanel.js +338 -47
  51. package/dist/connectors/monday.js +360 -49
  52. package/dist/connectors/mongodb.js +319 -57
  53. package/dist/connectors/notion-oauth.js +231 -5
  54. package/dist/connectors/notion.js +323 -51
  55. package/dist/connectors/openai.js +134 -47
  56. package/dist/connectors/oracle.js +454 -103
  57. package/dist/connectors/outlook-oauth.js +204 -5
  58. package/dist/connectors/powerbi-oauth.js +498 -5
  59. package/dist/connectors/salesforce.js +384 -49
  60. package/dist/connectors/semrush.js +609 -49
  61. package/dist/connectors/sentry.js +289 -50
  62. package/dist/connectors/shopify-oauth.js +187 -5
  63. package/dist/connectors/shopify.js +357 -47
  64. package/dist/connectors/sqlserver.js +415 -102
  65. package/dist/connectors/stripe-api-key.js +269 -46
  66. package/dist/connectors/stripe-oauth.js +202 -5
  67. package/dist/connectors/supabase.js +303 -48
  68. package/dist/connectors/tableau.js +536 -163
  69. package/dist/connectors/tiktok-ads.js +279 -48
  70. package/dist/connectors/wix-store.js +320 -49
  71. package/dist/connectors/zendesk-oauth.js +239 -5
  72. package/dist/connectors/zendesk.js +358 -47
  73. package/dist/index.d.ts +149 -1
  74. package/dist/index.js +15057 -2117
  75. package/dist/main.js +15005 -2073
  76. package/dist/vite-plugin.js +14752 -2019
  77. 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 = 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;
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/kintone/parameters.ts
57
+ init_parameter_definition();
46
58
  var parameters = {
47
59
  baseUrl: new ParameterDefinition({
48
60
  slug: "base-url",
@@ -201,6 +213,28 @@ var ConnectorPlugin = class _ConnectorPlugin {
201
213
  tools;
202
214
  query;
203
215
  checkConnection;
216
+ /**
217
+ * SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
218
+ * implement this expose a step-by-step exploration flow (database/schema/
219
+ * table/etc. discovery) that the dashboard backend drives via the
220
+ * `/connections/:connectionId/setup` endpoint. Implement by delegating to
221
+ * `runSetupFlow` from `setup-flow.ts`.
222
+ */
223
+ setup;
224
+ /**
225
+ * Opt-out of the default "verify before save" behavior on connection
226
+ * creation. The backend invokes `checkConnection` synchronously while
227
+ * creating the connection and aborts (no row inserted) if it fails — this
228
+ * flag disables that for connectors where the check cannot succeed pre-save:
229
+ *
230
+ * - `squadbase-db` populates `connection-url` only after Neon provisioning
231
+ * - OAuth connectors require an OAuth-aware proxyFetch keyed by the
232
+ * connectionId, which doesn't exist until the row is saved
233
+ *
234
+ * Exceptions are the explicit position; new credential-input connectors get
235
+ * the default verify-on-create behavior without opt-in.
236
+ */
237
+ skipConnectionCheckOnCreate;
204
238
  constructor(config) {
205
239
  this.slug = config.slug;
206
240
  this.authType = config.authType;
@@ -217,6 +251,8 @@ var ConnectorPlugin = class _ConnectorPlugin {
217
251
  this.tools = config.tools;
218
252
  this.query = config.query;
219
253
  this.checkConnection = config.checkConnection;
254
+ this.setup = config.setup;
255
+ this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
220
256
  }
221
257
  get connectorKey() {
222
258
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -281,6 +317,76 @@ var ConnectorPlugin = class _ConnectorPlugin {
281
317
  }
282
318
  };
283
319
 
320
+ // ../connectors/src/setup-flow.ts
321
+ async function runSetupFlow(flow, params, ctx, config) {
322
+ const runtime = {
323
+ params,
324
+ language: ctx.language,
325
+ config
326
+ };
327
+ let state = flow.initialState();
328
+ let answerIdx = 0;
329
+ const pendingParameterUpdates = [];
330
+ for (const step of flow.steps) {
331
+ const ans = ctx.answers[answerIdx];
332
+ if (ans && ans.questionSlug === step.slug) {
333
+ state = step.applyAnswer(state, ans.answer);
334
+ if (step.toParameterUpdates) {
335
+ pendingParameterUpdates.push(...step.toParameterUpdates(state));
336
+ }
337
+ answerIdx += 1;
338
+ continue;
339
+ }
340
+ const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
341
+ if (step.type === "text") {
342
+ if (step.fetchOptions) {
343
+ const options2 = await step.fetchOptions(state, runtime);
344
+ if (options2.length === 0) {
345
+ continue;
346
+ }
347
+ }
348
+ return {
349
+ type: "nextQuestion",
350
+ questionSlug: step.slug,
351
+ question: step.question[ctx.language],
352
+ questionType: "text",
353
+ allowFreeText: resolvedAllowFreeText,
354
+ ...pendingParameterUpdates.length > 0 && {
355
+ parameterUpdates: pendingParameterUpdates
356
+ }
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
+ allowFreeText: resolvedAllowFreeText,
370
+ ...pendingParameterUpdates.length > 0 && {
371
+ parameterUpdates: pendingParameterUpdates
372
+ }
373
+ };
374
+ }
375
+ const dataInvestigationResult = await flow.finalize(state, runtime);
376
+ return {
377
+ type: "fulfilled",
378
+ dataInvestigationResult,
379
+ ...pendingParameterUpdates.length > 0 && {
380
+ parameterUpdates: pendingParameterUpdates
381
+ }
382
+ };
383
+ }
384
+ async function resolveSetupSelection(params) {
385
+ const { selected, allSentinel, fetchAll, limit } = params;
386
+ const resolved = selected.includes(allSentinel) ? await fetchAll() : selected.filter((v) => v !== allSentinel);
387
+ return resolved.slice(0, limit);
388
+ }
389
+
284
390
  // ../connectors/src/auth-types.ts
285
391
  var AUTH_TYPES = {
286
392
  OAUTH: "oauth",
@@ -303,6 +409,122 @@ var kintoneOnboarding = new ConnectorOnboarding({
303
409
  }
304
410
  });
305
411
 
412
+ // ../connectors/src/connectors/kintone/utils.ts
413
+ async function apiFetch(params, path2, init) {
414
+ const baseUrl = params[parameters.baseUrl.slug];
415
+ const username = params[parameters.username.slug];
416
+ const password = params[parameters.password.slug];
417
+ if (!baseUrl || !username || !password) {
418
+ throw new Error(
419
+ "kintone: missing required parameter(s): base-url, username, password"
420
+ );
421
+ }
422
+ const authToken = Buffer.from(`${username}:${password}`).toString("base64");
423
+ const normalizedPath = path2.replace(/^\/+/, "");
424
+ const url = `${baseUrl.replace(/\/+$/, "")}/k/v1/${normalizedPath}`;
425
+ const headers = new Headers(init?.headers);
426
+ headers.set("X-Cybozu-Authorization", authToken);
427
+ if (init?.body && !headers.has("Content-Type")) {
428
+ headers.set("Content-Type", "application/json");
429
+ }
430
+ return fetch(url, { ...init, headers });
431
+ }
432
+
433
+ // ../connectors/src/connectors/kintone/setup-flow.ts
434
+ var ALL_APPS = "__ALL_APPS__";
435
+ var KINTONE_SETUP_MAX_APPS = 20;
436
+ async function listApps(params) {
437
+ const results = [];
438
+ let offset = 0;
439
+ for (let i = 0; i < 20; i++) {
440
+ const res = await apiFetch(
441
+ params,
442
+ `apps.json?limit=100&offset=${offset}`
443
+ );
444
+ if (!res.ok) {
445
+ const text = await res.text().catch(() => res.statusText);
446
+ throw new Error(`kintone: listApps failed (${res.status}): ${text}`);
447
+ }
448
+ const data = await res.json();
449
+ const apps = data.apps ?? [];
450
+ for (const a of apps) results.push(a);
451
+ if (apps.length < 100) break;
452
+ offset += apps.length;
453
+ }
454
+ return results;
455
+ }
456
+ async function getFormFields(params, appId) {
457
+ const res = await apiFetch(
458
+ params,
459
+ `app/form/fields.json?app=${encodeURIComponent(appId)}`
460
+ );
461
+ if (!res.ok) {
462
+ const text = await res.text().catch(() => res.statusText);
463
+ throw new Error(
464
+ `kintone: getFormFields ${appId} failed (${res.status}): ${text}`
465
+ );
466
+ }
467
+ return await res.json();
468
+ }
469
+ var kintoneSetupFlow = {
470
+ initialState: () => ({}),
471
+ steps: [
472
+ {
473
+ slug: "apps",
474
+ type: "multiSelect",
475
+ question: {
476
+ ja: "\u5BFE\u8C61\u306Ekintone\u30A2\u30D7\u30EA\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
477
+ en: "Select target kintone apps (multi-select allowed)"
478
+ },
479
+ async fetchOptions(_state, rt) {
480
+ const apps = await listApps(rt.params);
481
+ const appOptions = apps.filter((a) => a.appId && a.name).map((a) => ({ value: String(a.appId), label: a.name }));
482
+ return [
483
+ {
484
+ value: ALL_APPS,
485
+ label: rt.language === "ja" ? "\u3059\u3079\u3066\u306E\u30A2\u30D7\u30EA" : "All apps"
486
+ },
487
+ ...appOptions
488
+ ];
489
+ },
490
+ applyAnswer: (state, answer) => ({ ...state, apps: answer })
491
+ }
492
+ ],
493
+ async finalize(state, rt) {
494
+ if (!state.apps) {
495
+ throw new Error("kintone setup: incomplete state on finalize");
496
+ }
497
+ const allApps = await listApps(rt.params);
498
+ const appById = new Map(allApps.map((a) => [String(a.appId), a]));
499
+ const targetIds = await resolveSetupSelection({
500
+ selected: state.apps,
501
+ allSentinel: ALL_APPS,
502
+ fetchAll: async () => allApps.map((a) => String(a.appId)).filter((id) => id),
503
+ limit: KINTONE_SETUP_MAX_APPS
504
+ });
505
+ const sections = ["## kintone", ""];
506
+ for (const appId of targetIds) {
507
+ const app = appById.get(appId);
508
+ const heading = app ? `${app.name} (id: ${appId})` : `id: ${appId}`;
509
+ sections.push(`### App: ${heading}`, "");
510
+ if (app?.description) {
511
+ sections.push(app.description, "");
512
+ }
513
+ const fields = await getFormFields(rt.params, appId);
514
+ sections.push("| Field code | Label | Type | Required |");
515
+ sections.push("|------------|-------|------|----------|");
516
+ for (const [code, def] of Object.entries(fields.properties ?? {})) {
517
+ const escapedLabel = (def.label ?? "").replace(/\|/g, "\\|");
518
+ sections.push(
519
+ `| ${code} | ${escapedLabel || "-"} | ${def.type} | ${def.required ? "yes" : "no"} |`
520
+ );
521
+ }
522
+ sections.push("");
523
+ }
524
+ return sections.join("\n");
525
+ }
526
+ };
527
+
306
528
  // ../connectors/src/connectors/kintone/tools/request.ts
307
529
  import { z } from "zod";
308
530
  var REQUEST_TIMEOUT_MS = 6e4;
@@ -523,7 +745,46 @@ export default async function handler(c: Context) {
523
745
  - \u5236\u9650: \`limit 100 offset 0\`
524
746
  - \u6587\u5B57\u5217: \`like "\u90E8\u5206\u4E00\u81F4"\``
525
747
  },
526
- tools
748
+ tools,
749
+ setup: (params, ctx, config) => runSetupFlow(kintoneSetupFlow, params, ctx, config),
750
+ async checkConnection(params, _config) {
751
+ const baseUrl = params[parameters.baseUrl.slug];
752
+ const username = params[parameters.username.slug];
753
+ const password = params[parameters.password.slug];
754
+ if (!baseUrl || !username || !password) {
755
+ return {
756
+ success: false,
757
+ error: `Missing required parameters: ${parameters.baseUrl.slug}, ${parameters.username.slug}, and ${parameters.password.slug}`
758
+ };
759
+ }
760
+ try {
761
+ const authToken = Buffer.from(`${username}:${password}`).toString(
762
+ "base64"
763
+ );
764
+ const url = `${baseUrl.replace(/\/+$/, "")}/k/v1/apps.json`;
765
+ const res = await fetch(url, {
766
+ method: "GET",
767
+ headers: {
768
+ "X-Cybozu-Authorization": authToken,
769
+ Accept: "application/json"
770
+ }
771
+ });
772
+ if (!res.ok) {
773
+ const data = await res.json().catch(() => null);
774
+ const message = data?.message ?? `HTTP ${res.status} ${res.statusText}`;
775
+ return {
776
+ success: false,
777
+ error: `kintone API failed: ${message}`
778
+ };
779
+ }
780
+ return { success: true };
781
+ } catch (error) {
782
+ return {
783
+ success: false,
784
+ error: error instanceof Error ? error.message : String(error)
785
+ };
786
+ }
787
+ }
527
788
  });
528
789
 
529
790
  // src/connectors/create-connector-sdk.ts
@@ -552,6 +813,7 @@ function resolveEnvVarOptional(entry, key) {
552
813
  import { getContext } from "hono/context-storage";
553
814
  import { getCookie } from "hono/cookie";
554
815
  var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
816
+ var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
555
817
  function normalizeHeaders(input) {
556
818
  const out = {};
557
819
  if (!input) return out;
@@ -560,6 +822,11 @@ function normalizeHeaders(input) {
560
822
  });
561
823
  return out;
562
824
  }
825
+ function extractInputUrl(input) {
826
+ if (typeof input === "string") return input;
827
+ if (input instanceof URL) return input.href;
828
+ return input.url;
829
+ }
563
830
  function createSandboxProxyFetch(connectionId) {
564
831
  return async (input, init) => {
565
832
  const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
@@ -569,10 +836,17 @@ function createSandboxProxyFetch(connectionId) {
569
836
  "Connection proxy is not configured. Please check your deployment settings."
570
837
  );
571
838
  }
572
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
839
+ const originalUrl = extractInputUrl(input);
840
+ const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
841
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
842
+ const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
843
+ return fetch(sessionUrl, {
844
+ method: "POST",
845
+ headers: { Authorization: `Bearer ${token}` }
846
+ });
847
+ }
573
848
  const originalMethod = init?.method ?? "GET";
574
849
  const originalBody = init?.body ? JSON.parse(init.body) : void 0;
575
- const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
576
850
  const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
577
851
  return fetch(proxyUrl, {
578
852
  method: "POST",
@@ -598,10 +872,9 @@ function createDeployedAppProxyFetch(connectionId) {
598
872
  }
599
873
  const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
600
874
  const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
875
+ const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
601
876
  return async (input, init) => {
602
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
603
- const originalMethod = init?.method ?? "GET";
604
- const originalBody = init?.body ? JSON.parse(init.body) : void 0;
877
+ const originalUrl = extractInputUrl(input);
605
878
  const c = getContext();
606
879
  const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
607
880
  if (!appSession) {
@@ -609,6 +882,14 @@ function createDeployedAppProxyFetch(connectionId) {
609
882
  "No authentication method available for connection proxy."
610
883
  );
611
884
  }
885
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
886
+ return fetch(sessionUrl, {
887
+ method: "POST",
888
+ headers: { Authorization: `Bearer ${appSession}` }
889
+ });
890
+ }
891
+ const originalMethod = init?.method ?? "GET";
892
+ const originalBody = init?.body ? JSON.parse(init.body) : void 0;
612
893
  return fetch(proxyUrl, {
613
894
  method: "POST",
614
895
  headers: {