@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.
Files changed (77) hide show
  1. package/dist/cli/index.js +12128 -934
  2. package/dist/connectors/airtable-oauth.js +248 -46
  3. package/dist/connectors/airtable.js +285 -51
  4. package/dist/connectors/amplitude.js +288 -47
  5. package/dist/connectors/anthropic.js +126 -47
  6. package/dist/connectors/asana.js +293 -49
  7. package/dist/connectors/attio.js +268 -49
  8. package/dist/connectors/aws-billing.js +253 -46
  9. package/dist/connectors/azure-sql.js +387 -102
  10. package/dist/connectors/backlog-api-key.js +283 -47
  11. package/dist/connectors/clickup.js +304 -49
  12. package/dist/connectors/cosmosdb.js +271 -50
  13. package/dist/connectors/customerio.js +285 -47
  14. package/dist/connectors/dbt.js +306 -47
  15. package/dist/connectors/freshdesk.js +308 -53
  16. package/dist/connectors/freshsales.js +299 -52
  17. package/dist/connectors/freshservice.js +327 -53
  18. package/dist/connectors/gamma.js +293 -52
  19. package/dist/connectors/gemini.js +125 -47
  20. package/dist/connectors/github.js +352 -49
  21. package/dist/connectors/gmail-oauth.js +170 -7
  22. package/dist/connectors/gmail.js +316 -47
  23. package/dist/connectors/google-ads.js +254 -46
  24. package/dist/connectors/google-analytics-oauth.js +276 -46
  25. package/dist/connectors/google-analytics.js +378 -49
  26. package/dist/connectors/google-audit-log.js +404 -47
  27. package/dist/connectors/google-calendar-oauth.js +225 -46
  28. package/dist/connectors/google-calendar.js +325 -47
  29. package/dist/connectors/google-docs.js +186 -6
  30. package/dist/connectors/google-drive.js +228 -5
  31. package/dist/connectors/google-search-console-oauth.js +222 -46
  32. package/dist/connectors/google-sheets.js +238 -47
  33. package/dist/connectors/google-slides.js +171 -6
  34. package/dist/connectors/grafana.js +298 -49
  35. package/dist/connectors/hubspot-oauth.js +174 -5
  36. package/dist/connectors/hubspot.js +272 -49
  37. package/dist/connectors/influxdb.js +382 -51
  38. package/dist/connectors/intercom-oauth.js +176 -5
  39. package/dist/connectors/intercom.js +268 -49
  40. package/dist/connectors/jdbc.js +728 -110
  41. package/dist/connectors/jira-api-key.js +292 -47
  42. package/dist/connectors/kintone-api-token.js +247 -47
  43. package/dist/connectors/kintone.js +294 -47
  44. package/dist/connectors/linear.js +296 -49
  45. package/dist/connectors/linkedin-ads.js +234 -50
  46. package/dist/connectors/mailchimp-oauth.js +234 -46
  47. package/dist/connectors/mailchimp.js +286 -49
  48. package/dist/connectors/meta-ads-oauth.js +239 -48
  49. package/dist/connectors/meta-ads.js +251 -50
  50. package/dist/connectors/mixpanel.js +304 -47
  51. package/dist/connectors/monday.js +326 -49
  52. package/dist/connectors/mongodb.js +285 -57
  53. package/dist/connectors/notion-oauth.js +197 -5
  54. package/dist/connectors/notion.js +289 -51
  55. package/dist/connectors/openai.js +125 -47
  56. package/dist/connectors/oracle.js +405 -103
  57. package/dist/connectors/outlook-oauth.js +170 -5
  58. package/dist/connectors/powerbi-oauth.js +217 -5
  59. package/dist/connectors/salesforce.js +350 -49
  60. package/dist/connectors/semrush.js +280 -49
  61. package/dist/connectors/sentry.js +255 -50
  62. package/dist/connectors/shopify-oauth.js +153 -5
  63. package/dist/connectors/shopify.js +323 -47
  64. package/dist/connectors/sqlserver.js +381 -102
  65. package/dist/connectors/stripe-api-key.js +235 -46
  66. package/dist/connectors/stripe-oauth.js +168 -5
  67. package/dist/connectors/supabase.js +269 -48
  68. package/dist/connectors/tableau.js +337 -206
  69. package/dist/connectors/tiktok-ads.js +245 -48
  70. package/dist/connectors/wix-store.js +286 -49
  71. package/dist/connectors/zendesk-oauth.js +205 -5
  72. package/dist/connectors/zendesk.js +324 -47
  73. package/dist/index.d.ts +149 -1
  74. package/dist/index.js +18297 -6886
  75. package/dist/main.js +12785 -1382
  76. package/dist/vite-plugin.js +12140 -936
  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/cosmosdb/parameters.ts
57
+ init_parameter_definition();
46
58
  var parameters = {
47
59
  endpoint: new ParameterDefinition({
48
60
  slug: "endpoint",
@@ -116,7 +128,7 @@ function createClient(params) {
116
128
  throw new Error(msg.replaceAll(key, "***"));
117
129
  }
118
130
  }
119
- async function listContainers() {
131
+ async function listContainers2() {
120
132
  try {
121
133
  const db = await getDatabase();
122
134
  const { resources } = await db.containers.readAll().fetchAll();
@@ -129,7 +141,7 @@ function createClient(params) {
129
141
  throw new Error(msg.replaceAll(key, "***"));
130
142
  }
131
143
  }
132
- return { query: runQuery, listContainers };
144
+ return { query: runQuery, listContainers: listContainers2 };
133
145
  }
134
146
  function extractPartitionKeyPaths(partitionKey) {
135
147
  if (!partitionKey || typeof partitionKey !== "object") return void 0;
@@ -205,6 +217,20 @@ var ConnectorPlugin = class _ConnectorPlugin {
205
217
  * `runSetupFlow` from `setup-flow.ts`.
206
218
  */
207
219
  setup;
220
+ /**
221
+ * Opt-out of the default "verify before save" behavior on connection
222
+ * creation. The backend invokes `checkConnection` synchronously while
223
+ * creating the connection and aborts (no row inserted) if it fails — this
224
+ * flag disables that for connectors where the check cannot succeed pre-save:
225
+ *
226
+ * - `squadbase-db` populates `connection-url` only after Neon provisioning
227
+ * - OAuth connectors require an OAuth-aware proxyFetch keyed by the
228
+ * connectionId, which doesn't exist until the row is saved
229
+ *
230
+ * Exceptions are the explicit position; new credential-input connectors get
231
+ * the default verify-on-create behavior without opt-in.
232
+ */
233
+ skipConnectionCheckOnCreate;
208
234
  constructor(config) {
209
235
  this.slug = config.slug;
210
236
  this.authType = config.authType;
@@ -222,6 +248,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
222
248
  this.query = config.query;
223
249
  this.checkConnection = config.checkConnection;
224
250
  this.setup = config.setup;
251
+ this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
225
252
  }
226
253
  get connectorKey() {
227
254
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -286,6 +313,51 @@ var ConnectorPlugin = class _ConnectorPlugin {
286
313
  }
287
314
  };
288
315
 
316
+ // ../connectors/src/setup-flow.ts
317
+ async function runSetupFlow(flow, params, ctx, config) {
318
+ const runtime = {
319
+ params,
320
+ language: ctx.language,
321
+ config
322
+ };
323
+ let state = flow.initialState();
324
+ let answerIdx = 0;
325
+ for (const step of flow.steps) {
326
+ const ans = ctx.answers[answerIdx];
327
+ if (ans && ans.questionSlug === step.slug) {
328
+ state = step.applyAnswer(state, ans.answer);
329
+ answerIdx += 1;
330
+ continue;
331
+ }
332
+ if (step.type === "text") {
333
+ return {
334
+ type: "nextQuestion",
335
+ questionSlug: step.slug,
336
+ question: step.question[ctx.language],
337
+ questionType: "text"
338
+ };
339
+ }
340
+ const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
341
+ if (options.length === 0) {
342
+ continue;
343
+ }
344
+ return {
345
+ type: "nextQuestion",
346
+ questionSlug: step.slug,
347
+ question: step.question[ctx.language],
348
+ questionType: step.type,
349
+ options
350
+ };
351
+ }
352
+ const dataInvestigationResult = await flow.finalize(state, runtime);
353
+ return { type: "fulfilled", dataInvestigationResult };
354
+ }
355
+ async function resolveSetupSelection(params) {
356
+ const { selected, allSentinel, fetchAll, limit } = params;
357
+ const resolved = selected.includes(allSentinel) ? await fetchAll() : selected.filter((v) => v !== allSentinel);
358
+ return resolved.slice(0, limit);
359
+ }
360
+
289
361
  // ../connectors/src/auth-types.ts
290
362
  var AUTH_TYPES = {
291
363
  OAUTH: "oauth",
@@ -310,6 +382,134 @@ var cosmosdbOnboarding = new ConnectorOnboarding({
310
382
  }
311
383
  });
312
384
 
385
+ // ../connectors/src/connectors/cosmosdb/utils.ts
386
+ async function withClient(params, op) {
387
+ const { CosmosClient } = await import("@azure/cosmos");
388
+ const client = new CosmosClient({
389
+ endpoint: params[parameters.endpoint.slug],
390
+ key: params[parameters.key.slug]
391
+ });
392
+ try {
393
+ return await op(client);
394
+ } finally {
395
+ client.dispose?.();
396
+ }
397
+ }
398
+ async function listContainers(params) {
399
+ return withClient(params, async (client) => {
400
+ const database = params[parameters.database.slug];
401
+ const db = client.database(database);
402
+ const { resources } = await db.containers.readAll().fetchAll();
403
+ return resources.map((c) => ({
404
+ id: c.id,
405
+ partitionKey: extractPartitionKeyPaths2(c.partitionKey)
406
+ }));
407
+ });
408
+ }
409
+ function extractPartitionKeyPaths2(partitionKey) {
410
+ if (!partitionKey || typeof partitionKey !== "object") return void 0;
411
+ const paths = partitionKey.paths;
412
+ if (!Array.isArray(paths)) return void 0;
413
+ return paths.filter((p) => typeof p === "string");
414
+ }
415
+ async function sampleContainerShape(params, container) {
416
+ return withClient(params, async (client) => {
417
+ const database = params[parameters.database.slug];
418
+ const it = client.database(database).container(container).items.query(
419
+ { query: "SELECT TOP 1 * FROM c" },
420
+ { maxItemCount: 1 }
421
+ );
422
+ const { resources } = await it.fetchNext();
423
+ const doc = resources[0];
424
+ if (!doc) return [];
425
+ return Object.entries(doc).map(([field, value]) => ({
426
+ field,
427
+ type: cosmosFieldType(value)
428
+ }));
429
+ });
430
+ }
431
+ function cosmosFieldType(value) {
432
+ if (value === null) return "null";
433
+ if (Array.isArray(value)) return "array";
434
+ if (value instanceof Date) return "date";
435
+ if (typeof value === "object") return "object";
436
+ return typeof value;
437
+ }
438
+
439
+ // ../connectors/src/connectors/cosmosdb/setup-flow.ts
440
+ var ALL_CONTAINERS = "__ALL_CONTAINERS__";
441
+ var COSMOSDB_SETUP_MAX_CONTAINERS = 20;
442
+ var cosmosdbSetupFlow = {
443
+ initialState: () => ({}),
444
+ steps: [
445
+ {
446
+ slug: "containers",
447
+ type: "multiSelect",
448
+ question: {
449
+ ja: "\u5BFE\u8C61\u30B3\u30F3\u30C6\u30CA\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
450
+ en: "Select target containers (multi-select allowed)"
451
+ },
452
+ async fetchOptions(_state, rt) {
453
+ const containers = await listContainers(rt.params);
454
+ const options = containers.map((c) => ({
455
+ value: c.id,
456
+ label: c.partitionKey && c.partitionKey.length > 0 ? `${c.id} (partitionKey: ${c.partitionKey.join(", ")})` : c.id
457
+ }));
458
+ return [
459
+ {
460
+ value: ALL_CONTAINERS,
461
+ label: rt.language === "ja" ? "\u3059\u3079\u3066\u306E\u30B3\u30F3\u30C6\u30CA" : "All containers"
462
+ },
463
+ ...options
464
+ ];
465
+ },
466
+ applyAnswer: (state, answer) => ({ ...state, containers: answer })
467
+ }
468
+ ],
469
+ async finalize(state, rt) {
470
+ if (!state.containers) {
471
+ throw new Error("Cosmos DB setup: incomplete state on finalize");
472
+ }
473
+ const database = rt.params[parameters.database.slug];
474
+ const targetContainers = await resolveSetupSelection({
475
+ selected: state.containers,
476
+ allSentinel: ALL_CONTAINERS,
477
+ fetchAll: async () => {
478
+ const all = await listContainers(rt.params);
479
+ return all.map((c) => c.id);
480
+ },
481
+ limit: COSMOSDB_SETUP_MAX_CONTAINERS
482
+ });
483
+ const allContainers = await listContainers(rt.params);
484
+ const partitionKeyById = new Map(
485
+ allContainers.map((c) => [c.id, c.partitionKey])
486
+ );
487
+ const sections = [
488
+ "## Azure Cosmos DB",
489
+ "",
490
+ `### Database: ${database}`,
491
+ ""
492
+ ];
493
+ for (const container of targetContainers) {
494
+ const fields = await sampleContainerShape(rt.params, container);
495
+ const pk = partitionKeyById.get(container);
496
+ const pkSuffix = pk && pk.length > 0 ? ` (partitionKey: ${pk.join(", ")})` : "";
497
+ sections.push(`#### Container: ${container}${pkSuffix}`, "");
498
+ if (fields.length === 0) {
499
+ sections.push("_(empty container \u2014 no sample item available)_", "");
500
+ continue;
501
+ }
502
+ sections.push("| Field | Sampled Type |");
503
+ sections.push("|-------|--------------|");
504
+ for (const f of fields) {
505
+ sections.push(`| ${f.field} | ${f.type} |`);
506
+ }
507
+ sections.push("");
508
+ }
509
+ return sections.join("\n");
510
+ }
511
+ };
512
+
313
513
  // ../connectors/src/connectors/cosmosdb/tools/list-containers.ts
314
514
  import { z } from "zod";
315
515
  var inputSchema = z.object({
@@ -364,7 +564,7 @@ After listing containers, use the query tool to sample items and understand each
364
564
  success: true,
365
565
  containers: resources.map((c) => ({
366
566
  id: c.id,
367
- partitionKey: extractPartitionKeyPaths2(c.partitionKey)
567
+ partitionKey: extractPartitionKeyPaths3(c.partitionKey)
368
568
  }))
369
569
  };
370
570
  } catch (err) {
@@ -374,7 +574,7 @@ After listing containers, use the query tool to sample items and understand each
374
574
  }
375
575
  }
376
576
  });
377
- function extractPartitionKeyPaths2(partitionKey) {
577
+ function extractPartitionKeyPaths3(partitionKey) {
378
578
  if (!partitionKey || typeof partitionKey !== "object") return void 0;
379
579
  const paths = partitionKey.paths;
380
580
  if (!Array.isArray(paths)) return void 0;
@@ -582,6 +782,7 @@ export default async function handler(_c: Context) {
582
782
  - \u7D50\u679C\u4EF6\u6570\u306F\u5FC5\u305A \`TOP n\` \u3067\u5236\u9650\u3057\u3001\u53EF\u80FD\u3067\u3042\u308C\u3070 \`partitionKey\` \u3067\u5358\u4E00\u30D1\u30FC\u30C6\u30A3\u30B7\u30E7\u30F3\u306B\u30B9\u30B3\u30FC\u30D7\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u30AF\u30ED\u30B9\u30D1\u30FC\u30C6\u30A3\u30B7\u30E7\u30F3\u30AF\u30A8\u30EA\u306F RU \u3092\u591A\u304F\u6D88\u8CBB\u3057\u307E\u3059\uFF09\u3002`
583
783
  },
584
784
  tools,
785
+ setup: (params, ctx, config) => runSetupFlow(cosmosdbSetupFlow, params, ctx, config),
585
786
  async checkConnection(params, _config) {
586
787
  try {
587
788
  const { CosmosClient } = await import("@azure/cosmos");
@@ -629,6 +830,7 @@ function resolveEnvVarOptional(entry, key) {
629
830
  import { getContext } from "hono/context-storage";
630
831
  import { getCookie } from "hono/cookie";
631
832
  var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
833
+ var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
632
834
  function normalizeHeaders(input) {
633
835
  const out = {};
634
836
  if (!input) return out;
@@ -637,6 +839,11 @@ function normalizeHeaders(input) {
637
839
  });
638
840
  return out;
639
841
  }
842
+ function extractInputUrl(input) {
843
+ if (typeof input === "string") return input;
844
+ if (input instanceof URL) return input.href;
845
+ return input.url;
846
+ }
640
847
  function createSandboxProxyFetch(connectionId) {
641
848
  return async (input, init) => {
642
849
  const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
@@ -646,10 +853,17 @@ function createSandboxProxyFetch(connectionId) {
646
853
  "Connection proxy is not configured. Please check your deployment settings."
647
854
  );
648
855
  }
649
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
856
+ const originalUrl = extractInputUrl(input);
857
+ const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
858
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
859
+ const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
860
+ return fetch(sessionUrl, {
861
+ method: "POST",
862
+ headers: { Authorization: `Bearer ${token}` }
863
+ });
864
+ }
650
865
  const originalMethod = init?.method ?? "GET";
651
866
  const originalBody = init?.body ? JSON.parse(init.body) : void 0;
652
- const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
653
867
  const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
654
868
  return fetch(proxyUrl, {
655
869
  method: "POST",
@@ -675,10 +889,9 @@ function createDeployedAppProxyFetch(connectionId) {
675
889
  }
676
890
  const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
677
891
  const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
892
+ const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
678
893
  return async (input, init) => {
679
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
680
- const originalMethod = init?.method ?? "GET";
681
- const originalBody = init?.body ? JSON.parse(init.body) : void 0;
894
+ const originalUrl = extractInputUrl(input);
682
895
  const c = getContext();
683
896
  const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
684
897
  if (!appSession) {
@@ -686,6 +899,14 @@ function createDeployedAppProxyFetch(connectionId) {
686
899
  "No authentication method available for connection proxy."
687
900
  );
688
901
  }
902
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
903
+ return fetch(sessionUrl, {
904
+ method: "POST",
905
+ headers: { Authorization: `Bearer ${appSession}` }
906
+ });
907
+ }
908
+ const originalMethod = init?.method ?? "GET";
909
+ const originalBody = init?.body ? JSON.parse(init.body) : void 0;
689
910
  return fetch(proxyUrl, {
690
911
  method: "POST",
691
912
  headers: {