@squadbase/vite-server 0.1.12-dev.a9ac647 → 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.
Files changed (77) hide show
  1. package/dist/cli/index.js +12374 -883
  2. package/dist/connectors/airtable-oauth.js +257 -46
  3. package/dist/connectors/airtable.js +294 -51
  4. package/dist/connectors/amplitude.js +297 -47
  5. package/dist/connectors/anthropic.js +135 -47
  6. package/dist/connectors/asana.js +302 -49
  7. package/dist/connectors/attio.js +277 -49
  8. package/dist/connectors/aws-billing.js +262 -46
  9. package/dist/connectors/azure-sql.js +396 -102
  10. package/dist/connectors/backlog-api-key.js +292 -47
  11. package/dist/connectors/clickup.js +313 -49
  12. package/dist/connectors/cosmosdb.js +280 -50
  13. package/dist/connectors/customerio.js +294 -47
  14. package/dist/connectors/dbt.js +315 -47
  15. package/dist/connectors/freshdesk.js +317 -53
  16. package/dist/connectors/freshsales.js +308 -52
  17. package/dist/connectors/freshservice.js +336 -53
  18. package/dist/connectors/gamma.js +302 -52
  19. package/dist/connectors/gemini.js +134 -47
  20. package/dist/connectors/github.js +361 -49
  21. package/dist/connectors/gmail-oauth.js +179 -7
  22. package/dist/connectors/gmail.js +325 -47
  23. package/dist/connectors/google-ads.js +263 -46
  24. package/dist/connectors/google-analytics-oauth.js +285 -46
  25. package/dist/connectors/google-analytics.js +387 -49
  26. package/dist/connectors/google-audit-log.js +413 -47
  27. package/dist/connectors/google-calendar-oauth.js +234 -46
  28. package/dist/connectors/google-calendar.js +334 -47
  29. package/dist/connectors/google-docs.js +195 -6
  30. package/dist/connectors/google-drive.js +237 -5
  31. package/dist/connectors/google-search-console-oauth.js +231 -46
  32. package/dist/connectors/google-sheets.js +247 -47
  33. package/dist/connectors/google-slides.js +180 -6
  34. package/dist/connectors/grafana.js +307 -49
  35. package/dist/connectors/hubspot-oauth.js +183 -5
  36. package/dist/connectors/hubspot.js +281 -49
  37. package/dist/connectors/influxdb.js +391 -51
  38. package/dist/connectors/intercom-oauth.js +185 -5
  39. package/dist/connectors/intercom.js +277 -49
  40. package/dist/connectors/jdbc.js +737 -110
  41. package/dist/connectors/jira-api-key.js +301 -47
  42. package/dist/connectors/kintone-api-token.js +256 -47
  43. package/dist/connectors/kintone.js +303 -47
  44. package/dist/connectors/linear.js +305 -49
  45. package/dist/connectors/linkedin-ads.js +243 -50
  46. package/dist/connectors/mailchimp-oauth.js +243 -46
  47. package/dist/connectors/mailchimp.js +295 -49
  48. package/dist/connectors/meta-ads-oauth.js +248 -48
  49. package/dist/connectors/meta-ads.js +260 -50
  50. package/dist/connectors/mixpanel.js +313 -47
  51. package/dist/connectors/monday.js +335 -49
  52. package/dist/connectors/mongodb.js +294 -57
  53. package/dist/connectors/notion-oauth.js +206 -5
  54. package/dist/connectors/notion.js +298 -51
  55. package/dist/connectors/openai.js +134 -47
  56. package/dist/connectors/oracle.js +414 -103
  57. package/dist/connectors/outlook-oauth.js +179 -5
  58. package/dist/connectors/powerbi-oauth.js +226 -5
  59. package/dist/connectors/salesforce.js +359 -49
  60. package/dist/connectors/semrush.js +289 -49
  61. package/dist/connectors/sentry.js +264 -50
  62. package/dist/connectors/shopify-oauth.js +162 -5
  63. package/dist/connectors/shopify.js +332 -47
  64. package/dist/connectors/sqlserver.js +390 -102
  65. package/dist/connectors/stripe-api-key.js +244 -46
  66. package/dist/connectors/stripe-oauth.js +177 -5
  67. package/dist/connectors/supabase.js +278 -48
  68. package/dist/connectors/tableau.js +389 -184
  69. package/dist/connectors/tiktok-ads.js +254 -48
  70. package/dist/connectors/wix-store.js +295 -49
  71. package/dist/connectors/zendesk-oauth.js +214 -5
  72. package/dist/connectors/zendesk.js +333 -47
  73. package/dist/index.d.ts +149 -1
  74. package/dist/index.js +13677 -1969
  75. package/dist/main.js +13627 -1927
  76. package/dist/vite-plugin.js +12391 -890
  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/linear/parameters.ts
57
+ init_parameter_definition();
46
58
  var parameters = {
47
59
  apiKey: new ParameterDefinition({
48
60
  slug: "api-key",
@@ -207,6 +219,28 @@ var ConnectorPlugin = class _ConnectorPlugin {
207
219
  tools;
208
220
  query;
209
221
  checkConnection;
222
+ /**
223
+ * SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
224
+ * implement this expose a step-by-step exploration flow (database/schema/
225
+ * table/etc. discovery) that the dashboard backend drives via the
226
+ * `/connections/:connectionId/setup` endpoint. Implement by delegating to
227
+ * `runSetupFlow` from `setup-flow.ts`.
228
+ */
229
+ setup;
230
+ /**
231
+ * Opt-out of the default "verify before save" behavior on connection
232
+ * creation. The backend invokes `checkConnection` synchronously while
233
+ * creating the connection and aborts (no row inserted) if it fails — this
234
+ * flag disables that for connectors where the check cannot succeed pre-save:
235
+ *
236
+ * - `squadbase-db` populates `connection-url` only after Neon provisioning
237
+ * - OAuth connectors require an OAuth-aware proxyFetch keyed by the
238
+ * connectionId, which doesn't exist until the row is saved
239
+ *
240
+ * Exceptions are the explicit position; new credential-input connectors get
241
+ * the default verify-on-create behavior without opt-in.
242
+ */
243
+ skipConnectionCheckOnCreate;
210
244
  constructor(config) {
211
245
  this.slug = config.slug;
212
246
  this.authType = config.authType;
@@ -223,6 +257,8 @@ var ConnectorPlugin = class _ConnectorPlugin {
223
257
  this.tools = config.tools;
224
258
  this.query = config.query;
225
259
  this.checkConnection = config.checkConnection;
260
+ this.setup = config.setup;
261
+ this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
226
262
  }
227
263
  get connectorKey() {
228
264
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -287,6 +323,51 @@ var ConnectorPlugin = class _ConnectorPlugin {
287
323
  }
288
324
  };
289
325
 
326
+ // ../connectors/src/setup-flow.ts
327
+ async function runSetupFlow(flow, params, ctx, config) {
328
+ const runtime = {
329
+ params,
330
+ language: ctx.language,
331
+ config
332
+ };
333
+ let state = flow.initialState();
334
+ let answerIdx = 0;
335
+ for (const step of flow.steps) {
336
+ const ans = ctx.answers[answerIdx];
337
+ if (ans && ans.questionSlug === step.slug) {
338
+ state = step.applyAnswer(state, ans.answer);
339
+ answerIdx += 1;
340
+ continue;
341
+ }
342
+ if (step.type === "text") {
343
+ return {
344
+ type: "nextQuestion",
345
+ questionSlug: step.slug,
346
+ question: step.question[ctx.language],
347
+ questionType: "text"
348
+ };
349
+ }
350
+ const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
351
+ if (options.length === 0) {
352
+ continue;
353
+ }
354
+ return {
355
+ type: "nextQuestion",
356
+ questionSlug: step.slug,
357
+ question: step.question[ctx.language],
358
+ questionType: step.type,
359
+ options
360
+ };
361
+ }
362
+ const dataInvestigationResult = await flow.finalize(state, runtime);
363
+ return { type: "fulfilled", dataInvestigationResult };
364
+ }
365
+ async function resolveSetupSelection(params) {
366
+ const { selected, allSentinel, fetchAll, limit } = params;
367
+ const resolved = selected.includes(allSentinel) ? await fetchAll() : selected.filter((v) => v !== allSentinel);
368
+ return resolved.slice(0, limit);
369
+ }
370
+
290
371
  // ../connectors/src/auth-types.ts
291
372
  var AUTH_TYPES = {
292
373
  OAUTH: "oauth",
@@ -313,9 +394,122 @@ var linearOnboarding = new ConnectorOnboarding({
313
394
  }
314
395
  });
315
396
 
397
+ // ../connectors/src/connectors/linear/utils.ts
398
+ var BASE_URL2 = "https://api.linear.app/graphql";
399
+ async function gqlFetch(params, query, variables) {
400
+ const apiKey = params[parameters.apiKey.slug];
401
+ if (!apiKey) {
402
+ throw new Error("linear: missing required parameter: api-key");
403
+ }
404
+ const body = { query };
405
+ if (variables) body.variables = variables;
406
+ const res = await fetch(BASE_URL2, {
407
+ method: "POST",
408
+ headers: {
409
+ Authorization: apiKey,
410
+ "Content-Type": "application/json"
411
+ },
412
+ body: JSON.stringify(body)
413
+ });
414
+ if (!res.ok) {
415
+ const text = await res.text().catch(() => res.statusText);
416
+ throw new Error(`linear: GraphQL request failed (${res.status}): ${text}`);
417
+ }
418
+ const json = await res.json();
419
+ if (json.errors && json.errors.length > 0) {
420
+ const messages = json.errors.map((e) => e.message).join("; ");
421
+ if (!json.data) {
422
+ throw new Error(`linear: GraphQL error: ${messages}`);
423
+ }
424
+ }
425
+ return json.data ?? {};
426
+ }
427
+
428
+ // ../connectors/src/connectors/linear/setup-flow.ts
429
+ var ALL_TEAMS = "__ALL_TEAMS__";
430
+ var LINEAR_SETUP_MAX_TEAMS = 20;
431
+ async function listTeams(params) {
432
+ const data = await gqlFetch(params, `query { teams { nodes { id key name } } }`);
433
+ return data.teams?.nodes ?? [];
434
+ }
435
+ async function getTeamDetail(params, teamId) {
436
+ const data = await gqlFetch(
437
+ params,
438
+ `query($id: String!) {
439
+ team(id: $id) {
440
+ id key name description
441
+ states { nodes { id name type } }
442
+ members { nodes { id } }
443
+ }
444
+ }`,
445
+ { id: teamId }
446
+ );
447
+ return data.team ?? null;
448
+ }
449
+ var linearSetupFlow = {
450
+ initialState: () => ({}),
451
+ steps: [
452
+ {
453
+ slug: "teams",
454
+ type: "multiSelect",
455
+ question: {
456
+ ja: "\u5BFE\u8C61\u306E\u30C1\u30FC\u30E0\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
457
+ en: "Select target teams (multi-select allowed)"
458
+ },
459
+ async fetchOptions(_state, rt) {
460
+ const teams = await listTeams(rt.params);
461
+ const teamOptions = teams.filter((t) => t.id && t.name).map((t) => ({ value: t.id, label: `${t.name} (${t.key})` }));
462
+ return [
463
+ {
464
+ value: ALL_TEAMS,
465
+ label: rt.language === "ja" ? "\u3059\u3079\u3066\u306E\u30C1\u30FC\u30E0" : "All teams"
466
+ },
467
+ ...teamOptions
468
+ ];
469
+ },
470
+ applyAnswer: (state, answer) => ({ ...state, teams: answer })
471
+ }
472
+ ],
473
+ async finalize(state, rt) {
474
+ if (!state.teams) {
475
+ throw new Error("Linear setup: incomplete state on finalize");
476
+ }
477
+ const targetIds = await resolveSetupSelection({
478
+ selected: state.teams,
479
+ allSentinel: ALL_TEAMS,
480
+ fetchAll: async () => {
481
+ const teams = await listTeams(rt.params);
482
+ return teams.map((t) => t.id).filter((id) => id);
483
+ },
484
+ limit: LINEAR_SETUP_MAX_TEAMS
485
+ });
486
+ const sections = ["## Linear", ""];
487
+ for (const teamId of targetIds) {
488
+ const detail = await getTeamDetail(rt.params, teamId);
489
+ if (!detail) {
490
+ sections.push(`### Team: ${teamId}`, "", "_Not found._", "");
491
+ continue;
492
+ }
493
+ sections.push(`### Team: ${detail.name} (${detail.key})`, "");
494
+ if (detail.description) {
495
+ sections.push(detail.description, "");
496
+ }
497
+ const states = detail.states?.nodes ?? [];
498
+ const memberCount = detail.members?.nodes?.length ?? 0;
499
+ sections.push(`- Member count: ${memberCount}`);
500
+ sections.push(`- Workflow states (${states.length}):`);
501
+ for (const s of states) {
502
+ sections.push(` - ${s.name} (${s.type})`);
503
+ }
504
+ sections.push("");
505
+ }
506
+ return sections.join("\n");
507
+ }
508
+ };
509
+
316
510
  // ../connectors/src/connectors/linear/tools/request.ts
317
511
  import { z } from "zod";
318
- var BASE_URL2 = "https://api.linear.app/graphql";
512
+ var BASE_URL3 = "https://api.linear.app/graphql";
319
513
  var REQUEST_TIMEOUT_MS = 6e4;
320
514
  var inputSchema = z.object({
321
515
  toolUseIntent: z.string().optional().describe(
@@ -365,7 +559,7 @@ Archived resources are hidden by default; pass includeArchived: true in query ar
365
559
  try {
366
560
  const body = { query };
367
561
  if (variables) body.variables = variables;
368
- const response = await fetch(BASE_URL2, {
562
+ const response = await fetch(BASE_URL3, {
369
563
  method: "POST",
370
564
  headers: {
371
565
  Authorization: apiKey,
@@ -539,7 +733,49 @@ export default async function handler(c: Context) {
539
733
  - \`mutation { issueUpdate(id: "...", input: { stateId: "..." }) { success issue { id title state { name } } } }\` \u2014 Issue\u66F4\u65B0
540
734
  - \`mutation { commentCreate(input: { issueId: "...", body: "..." }) { success comment { id body } } }\` \u2014 \u30B3\u30E1\u30F3\u30C8\u8FFD\u52A0`
541
735
  },
542
- tools
736
+ tools,
737
+ setup: (params, ctx, config) => runSetupFlow(linearSetupFlow, params, ctx, config),
738
+ async checkConnection(params, _config) {
739
+ try {
740
+ const apiKey = params[parameters.apiKey.slug];
741
+ if (!apiKey) {
742
+ return {
743
+ success: false,
744
+ error: "Missing required parameter: api-key"
745
+ };
746
+ }
747
+ const res = await fetch("https://api.linear.app/graphql", {
748
+ method: "POST",
749
+ headers: {
750
+ Authorization: apiKey,
751
+ "Content-Type": "application/json",
752
+ Accept: "application/json"
753
+ },
754
+ body: JSON.stringify({ query: "query { viewer { id } }" })
755
+ });
756
+ if (!res.ok) {
757
+ const errorText = await res.text().catch(() => res.statusText);
758
+ return {
759
+ success: false,
760
+ error: `Linear API failed: HTTP ${res.status} ${errorText}`
761
+ };
762
+ }
763
+ const body = await res.json().catch(() => null);
764
+ if (body?.errors && body.errors.length > 0) {
765
+ const msg = body.errors.map((e) => e.message ?? "unknown error").join("; ");
766
+ return {
767
+ success: false,
768
+ error: `Linear GraphQL errors: ${msg}`
769
+ };
770
+ }
771
+ return { success: true };
772
+ } catch (error) {
773
+ return {
774
+ success: false,
775
+ error: error instanceof Error ? error.message : String(error)
776
+ };
777
+ }
778
+ }
543
779
  });
544
780
 
545
781
  // src/connectors/create-connector-sdk.ts
@@ -568,6 +804,7 @@ function resolveEnvVarOptional(entry, key) {
568
804
  import { getContext } from "hono/context-storage";
569
805
  import { getCookie } from "hono/cookie";
570
806
  var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
807
+ var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
571
808
  function normalizeHeaders(input) {
572
809
  const out = {};
573
810
  if (!input) return out;
@@ -576,6 +813,11 @@ function normalizeHeaders(input) {
576
813
  });
577
814
  return out;
578
815
  }
816
+ function extractInputUrl(input) {
817
+ if (typeof input === "string") return input;
818
+ if (input instanceof URL) return input.href;
819
+ return input.url;
820
+ }
579
821
  function createSandboxProxyFetch(connectionId) {
580
822
  return async (input, init) => {
581
823
  const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
@@ -585,10 +827,17 @@ function createSandboxProxyFetch(connectionId) {
585
827
  "Connection proxy is not configured. Please check your deployment settings."
586
828
  );
587
829
  }
588
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
830
+ const originalUrl = extractInputUrl(input);
831
+ const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
832
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
833
+ const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
834
+ return fetch(sessionUrl, {
835
+ method: "POST",
836
+ headers: { Authorization: `Bearer ${token}` }
837
+ });
838
+ }
589
839
  const originalMethod = init?.method ?? "GET";
590
840
  const originalBody = init?.body ? JSON.parse(init.body) : void 0;
591
- const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
592
841
  const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
593
842
  return fetch(proxyUrl, {
594
843
  method: "POST",
@@ -614,10 +863,9 @@ function createDeployedAppProxyFetch(connectionId) {
614
863
  }
615
864
  const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
616
865
  const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
866
+ const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
617
867
  return async (input, init) => {
618
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
619
- const originalMethod = init?.method ?? "GET";
620
- const originalBody = init?.body ? JSON.parse(init.body) : void 0;
868
+ const originalUrl = extractInputUrl(input);
621
869
  const c = getContext();
622
870
  const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
623
871
  if (!appSession) {
@@ -625,6 +873,14 @@ function createDeployedAppProxyFetch(connectionId) {
625
873
  "No authentication method available for connection proxy."
626
874
  );
627
875
  }
876
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
877
+ return fetch(sessionUrl, {
878
+ method: "POST",
879
+ headers: { Authorization: `Bearer ${appSession}` }
880
+ });
881
+ }
882
+ const originalMethod = init?.method ?? "GET";
883
+ const originalBody = init?.body ? JSON.parse(init.body) : void 0;
628
884
  return fetch(proxyUrl, {
629
885
  method: "POST",
630
886
  headers: {