@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
@@ -65,6 +65,28 @@ var ConnectorPlugin = class _ConnectorPlugin {
65
65
  tools;
66
66
  query;
67
67
  checkConnection;
68
+ /**
69
+ * SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
70
+ * implement this expose a step-by-step exploration flow (database/schema/
71
+ * table/etc. discovery) that the dashboard backend drives via the
72
+ * `/connections/:connectionId/setup` endpoint. Implement by delegating to
73
+ * `runSetupFlow` from `setup-flow.ts`.
74
+ */
75
+ setup;
76
+ /**
77
+ * Opt-out of the default "verify before save" behavior on connection
78
+ * creation. The backend invokes `checkConnection` synchronously while
79
+ * creating the connection and aborts (no row inserted) if it fails — this
80
+ * flag disables that for connectors where the check cannot succeed pre-save:
81
+ *
82
+ * - `squadbase-db` populates `connection-url` only after Neon provisioning
83
+ * - OAuth connectors require an OAuth-aware proxyFetch keyed by the
84
+ * connectionId, which doesn't exist until the row is saved
85
+ *
86
+ * Exceptions are the explicit position; new credential-input connectors get
87
+ * the default verify-on-create behavior without opt-in.
88
+ */
89
+ skipConnectionCheckOnCreate;
68
90
  constructor(config) {
69
91
  this.slug = config.slug;
70
92
  this.authType = config.authType;
@@ -81,6 +103,8 @@ var ConnectorPlugin = class _ConnectorPlugin {
81
103
  this.tools = config.tools;
82
104
  this.query = config.query;
83
105
  this.checkConnection = config.checkConnection;
106
+ this.setup = config.setup;
107
+ this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
84
108
  }
85
109
  get connectorKey() {
86
110
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -145,6 +169,71 @@ var ConnectorPlugin = class _ConnectorPlugin {
145
169
  }
146
170
  };
147
171
 
172
+ // ../connectors/src/setup-flow.ts
173
+ async function runSetupFlow(flow, params, ctx, config) {
174
+ const runtime = {
175
+ params,
176
+ language: ctx.language,
177
+ config
178
+ };
179
+ let state = flow.initialState();
180
+ let answerIdx = 0;
181
+ const pendingParameterUpdates = [];
182
+ for (const step of flow.steps) {
183
+ const ans = ctx.answers[answerIdx];
184
+ if (ans && ans.questionSlug === step.slug) {
185
+ state = step.applyAnswer(state, ans.answer);
186
+ if (step.toParameterUpdates) {
187
+ pendingParameterUpdates.push(...step.toParameterUpdates(state));
188
+ }
189
+ answerIdx += 1;
190
+ continue;
191
+ }
192
+ const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
193
+ if (step.type === "text") {
194
+ if (step.fetchOptions) {
195
+ const options2 = await step.fetchOptions(state, runtime);
196
+ if (options2.length === 0) {
197
+ continue;
198
+ }
199
+ }
200
+ return {
201
+ type: "nextQuestion",
202
+ questionSlug: step.slug,
203
+ question: step.question[ctx.language],
204
+ questionType: "text",
205
+ allowFreeText: resolvedAllowFreeText,
206
+ ...pendingParameterUpdates.length > 0 && {
207
+ parameterUpdates: pendingParameterUpdates
208
+ }
209
+ };
210
+ }
211
+ const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
212
+ if (options.length === 0) {
213
+ continue;
214
+ }
215
+ return {
216
+ type: "nextQuestion",
217
+ questionSlug: step.slug,
218
+ question: step.question[ctx.language],
219
+ questionType: step.type,
220
+ options,
221
+ allowFreeText: resolvedAllowFreeText,
222
+ ...pendingParameterUpdates.length > 0 && {
223
+ parameterUpdates: pendingParameterUpdates
224
+ }
225
+ };
226
+ }
227
+ const dataInvestigationResult = await flow.finalize(state, runtime);
228
+ return {
229
+ type: "fulfilled",
230
+ dataInvestigationResult,
231
+ ...pendingParameterUpdates.length > 0 && {
232
+ parameterUpdates: pendingParameterUpdates
233
+ }
234
+ };
235
+ }
236
+
148
237
  // ../connectors/src/auth-types.ts
149
238
  var AUTH_TYPES = {
150
239
  OAUTH: "oauth",
@@ -307,11 +396,83 @@ var shopifyOauthOnboarding = new ConnectorOnboarding({
307
396
  // ../connectors/src/connectors/shopify-oauth/parameters.ts
308
397
  var parameters = {};
309
398
 
399
+ // ../connectors/src/connectors/shopify-oauth/setup-flow.ts
400
+ var SHOPIFY_API_VERSION = "2024-10";
401
+ var SHOPIFY_OAUTH_SETUP_MAX_ENTITIES = 10;
402
+ var ENTITY_LABELS = {
403
+ products: { en: "Products", ja: "Products (\u5546\u54C1)" },
404
+ orders: { en: "Orders", ja: "Orders (\u6CE8\u6587)" },
405
+ customers: { en: "Customers", ja: "Customers (\u9867\u5BA2)" },
406
+ collections: { en: "Collections", ja: "Collections (\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3)" },
407
+ inventory: { en: "Inventory items", ja: "Inventory items (\u5728\u5EAB)" },
408
+ discounts: { en: "Discounts", ja: "Discounts (\u5272\u5F15)" }
409
+ };
410
+ var ENTITY_VALUES = [
411
+ "products",
412
+ "orders",
413
+ "customers",
414
+ "collections",
415
+ "inventory",
416
+ "discounts"
417
+ ];
418
+ var COUNT_PATHS = {
419
+ products: `/admin/api/${SHOPIFY_API_VERSION}/products/count.json`,
420
+ orders: `/admin/api/${SHOPIFY_API_VERSION}/orders/count.json?status=any`,
421
+ customers: `/admin/api/${SHOPIFY_API_VERSION}/customers/count.json`,
422
+ collections: `/admin/api/${SHOPIFY_API_VERSION}/custom_collections/count.json`,
423
+ inventory: null,
424
+ discounts: `/admin/api/${SHOPIFY_API_VERSION}/price_rules/count.json`
425
+ };
426
+ var shopifyOauthSetupFlow = {
427
+ initialState: () => ({}),
428
+ steps: [
429
+ {
430
+ slug: "entities",
431
+ type: "multiSelect",
432
+ question: {
433
+ 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",
434
+ en: "Select target entities (multi-select allowed)"
435
+ },
436
+ async fetchOptions(_state, rt) {
437
+ return ENTITY_VALUES.map((value) => ({
438
+ value,
439
+ label: ENTITY_LABELS[value][rt.language]
440
+ }));
441
+ },
442
+ applyAnswer: (state, answer) => ({ ...state, entities: answer })
443
+ }
444
+ ],
445
+ async finalize(state, rt) {
446
+ if (!state.entities) {
447
+ throw new Error("Shopify setup: incomplete state on finalize");
448
+ }
449
+ const selected = state.entities.filter(
450
+ (e) => ENTITY_VALUES.includes(e)
451
+ ).slice(0, SHOPIFY_OAUTH_SETUP_MAX_ENTITIES);
452
+ const sections = ["## Shopify", ""];
453
+ for (const entity of selected) {
454
+ const path2 = COUNT_PATHS[entity];
455
+ let count = "available";
456
+ if (path2) {
457
+ const res = await rt.config.proxyFetch(path2, { method: "GET" });
458
+ if (res.ok) {
459
+ const data = await res.json();
460
+ if (typeof data.count === "number") count = String(data.count);
461
+ }
462
+ }
463
+ sections.push(`### ${ENTITY_LABELS[entity].en}`, "");
464
+ sections.push(`Count: ${count}`, "");
465
+ }
466
+ return sections.join("\n");
467
+ }
468
+ };
469
+
310
470
  // ../connectors/src/connectors/shopify-oauth/index.ts
311
471
  var tools = { request: requestTool };
312
472
  var shopifyOauthConnector = new ConnectorPlugin({
313
473
  slug: "shopify",
314
474
  authType: AUTH_TYPES.OAUTH,
475
+ skipConnectionCheckOnCreate: true,
315
476
  name: "Shopify",
316
477
  description: "Connect to Shopify for e-commerce data including products, orders, and customers using OAuth.",
317
478
  iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/57KEjZCBskKgSxgKyU4Sm0/117d681a410f48dc36f97cdd9c0593c5/shopify-icon.svg",
@@ -424,6 +585,7 @@ const data = await res.json();
424
585
  \`\`\``
425
586
  },
426
587
  tools,
588
+ setup: (params, ctx, config) => runSetupFlow(shopifyOauthSetupFlow, params, ctx, config),
427
589
  async checkConnection(_params, config) {
428
590
  const { proxyFetch } = config;
429
591
  try {
@@ -473,6 +635,7 @@ function resolveEnvVarOptional(entry, key) {
473
635
  import { getContext } from "hono/context-storage";
474
636
  import { getCookie } from "hono/cookie";
475
637
  var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
638
+ var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
476
639
  function normalizeHeaders(input) {
477
640
  const out = {};
478
641
  if (!input) return out;
@@ -481,6 +644,11 @@ function normalizeHeaders(input) {
481
644
  });
482
645
  return out;
483
646
  }
647
+ function extractInputUrl(input) {
648
+ if (typeof input === "string") return input;
649
+ if (input instanceof URL) return input.href;
650
+ return input.url;
651
+ }
484
652
  function createSandboxProxyFetch(connectionId) {
485
653
  return async (input, init) => {
486
654
  const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
@@ -490,10 +658,17 @@ function createSandboxProxyFetch(connectionId) {
490
658
  "Connection proxy is not configured. Please check your deployment settings."
491
659
  );
492
660
  }
493
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
661
+ const originalUrl = extractInputUrl(input);
662
+ const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
663
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
664
+ const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
665
+ return fetch(sessionUrl, {
666
+ method: "POST",
667
+ headers: { Authorization: `Bearer ${token}` }
668
+ });
669
+ }
494
670
  const originalMethod = init?.method ?? "GET";
495
671
  const originalBody = init?.body ? JSON.parse(init.body) : void 0;
496
- const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
497
672
  const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
498
673
  return fetch(proxyUrl, {
499
674
  method: "POST",
@@ -519,10 +694,9 @@ function createDeployedAppProxyFetch(connectionId) {
519
694
  }
520
695
  const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
521
696
  const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
697
+ const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
522
698
  return async (input, init) => {
523
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
524
- const originalMethod = init?.method ?? "GET";
525
- const originalBody = init?.body ? JSON.parse(init.body) : void 0;
699
+ const originalUrl = extractInputUrl(input);
526
700
  const c = getContext();
527
701
  const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
528
702
  if (!appSession) {
@@ -530,6 +704,14 @@ function createDeployedAppProxyFetch(connectionId) {
530
704
  "No authentication method available for connection proxy."
531
705
  );
532
706
  }
707
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
708
+ return fetch(sessionUrl, {
709
+ method: "POST",
710
+ headers: { Authorization: `Bearer ${appSession}` }
711
+ });
712
+ }
713
+ const originalMethod = init?.method ?? "GET";
714
+ const originalBody = init?.body ? JSON.parse(init.body) : void 0;
533
715
  return fetch(proxyUrl, {
534
716
  method: "POST",
535
717
  headers: {