@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,46 +1,57 @@
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/google-sheets/sdk/index.ts
46
57
  var SHEETS_BASE_URL = "https://sheets.googleapis.com/v4/spreadsheets";
@@ -191,6 +202,20 @@ var ConnectorPlugin = class _ConnectorPlugin {
191
202
  * `runSetupFlow` from `setup-flow.ts`.
192
203
  */
193
204
  setup;
205
+ /**
206
+ * Opt-out of the default "verify before save" behavior on connection
207
+ * creation. The backend invokes `checkConnection` synchronously while
208
+ * creating the connection and aborts (no row inserted) if it fails — this
209
+ * flag disables that for connectors where the check cannot succeed pre-save:
210
+ *
211
+ * - `squadbase-db` populates `connection-url` only after Neon provisioning
212
+ * - OAuth connectors require an OAuth-aware proxyFetch keyed by the
213
+ * connectionId, which doesn't exist until the row is saved
214
+ *
215
+ * Exceptions are the explicit position; new credential-input connectors get
216
+ * the default verify-on-create behavior without opt-in.
217
+ */
218
+ skipConnectionCheckOnCreate;
194
219
  constructor(config) {
195
220
  this.slug = config.slug;
196
221
  this.authType = config.authType;
@@ -208,6 +233,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
208
233
  this.query = config.query;
209
234
  this.checkConnection = config.checkConnection;
210
235
  this.setup = config.setup;
236
+ this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
211
237
  }
212
238
  get connectorKey() {
213
239
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -272,6 +298,51 @@ var ConnectorPlugin = class _ConnectorPlugin {
272
298
  }
273
299
  };
274
300
 
301
+ // ../connectors/src/setup-flow.ts
302
+ async function runSetupFlow(flow, params, ctx, config) {
303
+ const runtime = {
304
+ params,
305
+ language: ctx.language,
306
+ config
307
+ };
308
+ let state = flow.initialState();
309
+ let answerIdx = 0;
310
+ for (const step of flow.steps) {
311
+ const ans = ctx.answers[answerIdx];
312
+ if (ans && ans.questionSlug === step.slug) {
313
+ state = step.applyAnswer(state, ans.answer);
314
+ answerIdx += 1;
315
+ continue;
316
+ }
317
+ if (step.type === "text") {
318
+ return {
319
+ type: "nextQuestion",
320
+ questionSlug: step.slug,
321
+ question: step.question[ctx.language],
322
+ questionType: "text"
323
+ };
324
+ }
325
+ const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
326
+ if (options.length === 0) {
327
+ continue;
328
+ }
329
+ return {
330
+ type: "nextQuestion",
331
+ questionSlug: step.slug,
332
+ question: step.question[ctx.language],
333
+ questionType: step.type,
334
+ options
335
+ };
336
+ }
337
+ const dataInvestigationResult = await flow.finalize(state, runtime);
338
+ return { type: "fulfilled", dataInvestigationResult };
339
+ }
340
+ async function resolveSetupSelection(params) {
341
+ const { selected, allSentinel, fetchAll, limit } = params;
342
+ const resolved = selected.includes(allSentinel) ? await fetchAll() : selected.filter((v) => v !== allSentinel);
343
+ return resolved.slice(0, limit);
344
+ }
345
+
275
346
  // ../connectors/src/auth-types.ts
276
347
  var AUTH_TYPES = {
277
348
  OAUTH: "oauth",
@@ -470,7 +541,105 @@ var googleSheetsOnboarding = new ConnectorOnboarding({
470
541
  }
471
542
  });
472
543
 
544
+ // ../connectors/src/connectors/google-sheets/utils.ts
545
+ async function googleApiFetch(config, url) {
546
+ const res = await config.proxyFetch(url, { method: "GET" });
547
+ if (!res.ok) {
548
+ const text = await res.text().catch(() => res.statusText);
549
+ throw new Error(`Google API ${url} failed: HTTP ${res.status} ${text}`);
550
+ }
551
+ return await res.json();
552
+ }
553
+
554
+ // ../connectors/src/connectors/google-sheets/setup-flow.ts
555
+ var ALL_SPREADSHEETS = "__ALL_SPREADSHEETS__";
556
+ var GOOGLE_SHEETS_SETUP_MAX_SPREADSHEETS = 10;
557
+ var DRIVE_LIST_PAGE_SIZE = 50;
558
+ async function listSpreadsheets(config) {
559
+ const q = encodeURIComponent(
560
+ "mimeType='application/vnd.google-apps.spreadsheet' and trashed=false"
561
+ );
562
+ const url = `https://www.googleapis.com/drive/v3/files?q=${q}&pageSize=${DRIVE_LIST_PAGE_SIZE}&orderBy=modifiedTime%20desc&fields=files(id,name,modifiedTime)`;
563
+ const data = await googleApiFetch(config, url);
564
+ return data.files ?? [];
565
+ }
566
+ var googleSheetsSetupFlow = {
567
+ initialState: () => ({}),
568
+ steps: [
569
+ {
570
+ slug: "spreadsheets",
571
+ type: "multiSelect",
572
+ question: {
573
+ ja: "\u5BFE\u8C61\u306E\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
574
+ en: "Select target spreadsheets (multi-select allowed)"
575
+ },
576
+ async fetchOptions(_state, rt) {
577
+ const files = await listSpreadsheets(rt.config);
578
+ const fileOptions = files.map((f) => ({
579
+ value: f.id,
580
+ label: f.name
581
+ }));
582
+ return [
583
+ {
584
+ value: ALL_SPREADSHEETS,
585
+ label: rt.language === "ja" ? "\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306A\u3059\u3079\u3066\u306E\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8" : "All accessible spreadsheets"
586
+ },
587
+ ...fileOptions
588
+ ];
589
+ },
590
+ applyAnswer: (state, answer) => ({ ...state, spreadsheets: answer })
591
+ }
592
+ ],
593
+ async finalize(state, rt) {
594
+ if (!state.spreadsheets) {
595
+ throw new Error("Google Sheets setup: incomplete state on finalize");
596
+ }
597
+ const targetIds = await resolveSetupSelection({
598
+ selected: state.spreadsheets,
599
+ allSentinel: ALL_SPREADSHEETS,
600
+ fetchAll: async () => {
601
+ const files = await listSpreadsheets(rt.config);
602
+ return files.map((f) => f.id);
603
+ },
604
+ limit: GOOGLE_SHEETS_SETUP_MAX_SPREADSHEETS
605
+ });
606
+ const sections = ["## Google Sheets", ""];
607
+ if (targetIds.length === 0) {
608
+ sections.push(
609
+ rt.language === "ja" ? "\u5BFE\u8C61\u306E\u30B9\u30D7\u30EC\u30C3\u30C9\u30B7\u30FC\u30C8\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002" : "No spreadsheets selected."
610
+ );
611
+ return sections.join("\n");
612
+ }
613
+ for (const id of targetIds) {
614
+ const url = `https://sheets.googleapis.com/v4/spreadsheets/${encodeURIComponent(id)}?fields=spreadsheetId,properties(title),sheets(properties(title,sheetId,gridProperties))`;
615
+ const meta = await googleApiFetch(
616
+ rt.config,
617
+ url
618
+ );
619
+ const title = meta.properties?.title ?? id;
620
+ sections.push(`### Spreadsheet: ${title}`, "", `- ID: ${id}`, "");
621
+ const sheets = meta.sheets ?? [];
622
+ if (sheets.length === 0) {
623
+ sections.push("- (no sheet tabs)", "");
624
+ continue;
625
+ }
626
+ sections.push("| Sheet | Rows | Columns |");
627
+ sections.push("|-------|------|---------|");
628
+ for (const s of sheets) {
629
+ const p = s.properties ?? {};
630
+ const sheetTitle = p.title ?? "(untitled)";
631
+ const rows = p.gridProperties?.rowCount ?? "-";
632
+ const cols = p.gridProperties?.columnCount ?? "-";
633
+ sections.push(`| ${sheetTitle} | ${rows} | ${cols} |`);
634
+ }
635
+ sections.push("");
636
+ }
637
+ return sections.join("\n");
638
+ }
639
+ };
640
+
473
641
  // ../connectors/src/connectors/google-sheets/parameters.ts
642
+ init_parameter_definition();
474
643
  var parameters = {
475
644
  spreadsheetId: new ParameterDefinition({
476
645
  slug: "spreadsheet-id",
@@ -488,6 +657,7 @@ var tools = { request: requestTool };
488
657
  var googleSheetsConnector = new ConnectorPlugin({
489
658
  slug: "google-sheets",
490
659
  authType: AUTH_TYPES.OAUTH,
660
+ skipConnectionCheckOnCreate: true,
491
661
  name: "Google Sheets",
492
662
  description: "Connect to Google Sheets for read/write access via OAuth. Any spreadsheet the authenticated Google account can access is supported \u2014 the target spreadsheetId is passed per call.",
493
663
  iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/1UPQuggyiZmbb26CuaSr2h/032770e8739b183fa00b7625f024e536/google-sheets.svg",
@@ -653,7 +823,8 @@ await sheets.batchUpdate(spreadsheetId, [
653
823
  ]);
654
824
  \`\`\``
655
825
  },
656
- tools
826
+ tools,
827
+ setup: (params, ctx, config) => runSetupFlow(googleSheetsSetupFlow, params, ctx, config)
657
828
  });
658
829
 
659
830
  // src/connectors/create-connector-sdk.ts
@@ -682,6 +853,7 @@ function resolveEnvVarOptional(entry, key) {
682
853
  import { getContext } from "hono/context-storage";
683
854
  import { getCookie } from "hono/cookie";
684
855
  var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
856
+ var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
685
857
  function normalizeHeaders(input) {
686
858
  const out = {};
687
859
  if (!input) return out;
@@ -690,6 +862,11 @@ function normalizeHeaders(input) {
690
862
  });
691
863
  return out;
692
864
  }
865
+ function extractInputUrl(input) {
866
+ if (typeof input === "string") return input;
867
+ if (input instanceof URL) return input.href;
868
+ return input.url;
869
+ }
693
870
  function createSandboxProxyFetch(connectionId) {
694
871
  return async (input, init) => {
695
872
  const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
@@ -699,10 +876,17 @@ function createSandboxProxyFetch(connectionId) {
699
876
  "Connection proxy is not configured. Please check your deployment settings."
700
877
  );
701
878
  }
702
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
879
+ const originalUrl = extractInputUrl(input);
880
+ const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
881
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
882
+ const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
883
+ return fetch(sessionUrl, {
884
+ method: "POST",
885
+ headers: { Authorization: `Bearer ${token}` }
886
+ });
887
+ }
703
888
  const originalMethod = init?.method ?? "GET";
704
889
  const originalBody = init?.body ? JSON.parse(init.body) : void 0;
705
- const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
706
890
  const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
707
891
  return fetch(proxyUrl, {
708
892
  method: "POST",
@@ -728,10 +912,9 @@ function createDeployedAppProxyFetch(connectionId) {
728
912
  }
729
913
  const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
730
914
  const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
915
+ const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
731
916
  return async (input, init) => {
732
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
733
- const originalMethod = init?.method ?? "GET";
734
- const originalBody = init?.body ? JSON.parse(init.body) : void 0;
917
+ const originalUrl = extractInputUrl(input);
735
918
  const c = getContext();
736
919
  const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
737
920
  if (!appSession) {
@@ -739,6 +922,14 @@ function createDeployedAppProxyFetch(connectionId) {
739
922
  "No authentication method available for connection proxy."
740
923
  );
741
924
  }
925
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
926
+ return fetch(sessionUrl, {
927
+ method: "POST",
928
+ headers: { Authorization: `Bearer ${appSession}` }
929
+ });
930
+ }
931
+ const originalMethod = init?.method ?? "GET";
932
+ const originalBody = init?.body ? JSON.parse(init.body) : void 0;
742
933
  return fetch(proxyUrl, {
743
934
  method: "POST",
744
935
  headers: {
@@ -133,6 +133,20 @@ var ConnectorPlugin = class _ConnectorPlugin {
133
133
  * `runSetupFlow` from `setup-flow.ts`.
134
134
  */
135
135
  setup;
136
+ /**
137
+ * Opt-out of the default "verify before save" behavior on connection
138
+ * creation. The backend invokes `checkConnection` synchronously while
139
+ * creating the connection and aborts (no row inserted) if it fails — this
140
+ * flag disables that for connectors where the check cannot succeed pre-save:
141
+ *
142
+ * - `squadbase-db` populates `connection-url` only after Neon provisioning
143
+ * - OAuth connectors require an OAuth-aware proxyFetch keyed by the
144
+ * connectionId, which doesn't exist until the row is saved
145
+ *
146
+ * Exceptions are the explicit position; new credential-input connectors get
147
+ * the default verify-on-create behavior without opt-in.
148
+ */
149
+ skipConnectionCheckOnCreate;
136
150
  constructor(config) {
137
151
  this.slug = config.slug;
138
152
  this.authType = config.authType;
@@ -150,6 +164,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
150
164
  this.query = config.query;
151
165
  this.checkConnection = config.checkConnection;
152
166
  this.setup = config.setup;
167
+ this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
153
168
  }
154
169
  get connectorKey() {
155
170
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -214,6 +229,51 @@ var ConnectorPlugin = class _ConnectorPlugin {
214
229
  }
215
230
  };
216
231
 
232
+ // ../connectors/src/setup-flow.ts
233
+ async function runSetupFlow(flow, params, ctx, config) {
234
+ const runtime = {
235
+ params,
236
+ language: ctx.language,
237
+ config
238
+ };
239
+ let state = flow.initialState();
240
+ let answerIdx = 0;
241
+ for (const step of flow.steps) {
242
+ const ans = ctx.answers[answerIdx];
243
+ if (ans && ans.questionSlug === step.slug) {
244
+ state = step.applyAnswer(state, ans.answer);
245
+ answerIdx += 1;
246
+ continue;
247
+ }
248
+ if (step.type === "text") {
249
+ return {
250
+ type: "nextQuestion",
251
+ questionSlug: step.slug,
252
+ question: step.question[ctx.language],
253
+ questionType: "text"
254
+ };
255
+ }
256
+ const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
257
+ if (options.length === 0) {
258
+ continue;
259
+ }
260
+ return {
261
+ type: "nextQuestion",
262
+ questionSlug: step.slug,
263
+ question: step.question[ctx.language],
264
+ questionType: step.type,
265
+ options
266
+ };
267
+ }
268
+ const dataInvestigationResult = await flow.finalize(state, runtime);
269
+ return { type: "fulfilled", dataInvestigationResult };
270
+ }
271
+ async function resolveSetupSelection(params) {
272
+ const { selected, allSentinel, fetchAll, limit } = params;
273
+ const resolved = selected.includes(allSentinel) ? await fetchAll() : selected.filter((v) => v !== allSentinel);
274
+ return resolved.slice(0, limit);
275
+ }
276
+
217
277
  // ../connectors/src/auth-types.ts
218
278
  var AUTH_TYPES = {
219
279
  OAUTH: "oauth",
@@ -244,6 +304,89 @@ var googleSlidesOnboarding = new ConnectorOnboarding({
244
304
  }
245
305
  });
246
306
 
307
+ // ../connectors/src/connectors/google-slides/utils.ts
308
+ async function googleApiFetch(config, url) {
309
+ const res = await config.proxyFetch(url, { method: "GET" });
310
+ if (!res.ok) {
311
+ const text = await res.text().catch(() => res.statusText);
312
+ throw new Error(`Google Slides ${url} failed: HTTP ${res.status} ${text}`);
313
+ }
314
+ return await res.json();
315
+ }
316
+
317
+ // ../connectors/src/connectors/google-slides/setup-flow.ts
318
+ var ALL_PRESENTATIONS = "__ALL_PRESENTATIONS__";
319
+ var GOOGLE_SLIDES_SETUP_MAX_PRESENTATIONS = 10;
320
+ var DRIVE_LIST_PAGE_SIZE = 50;
321
+ async function listPresentations(config) {
322
+ const q = encodeURIComponent(
323
+ "mimeType='application/vnd.google-apps.presentation' and trashed=false"
324
+ );
325
+ const url = `https://www.googleapis.com/drive/v3/files?q=${q}&pageSize=${DRIVE_LIST_PAGE_SIZE}&orderBy=modifiedTime%20desc&fields=files(id,name,modifiedTime)`;
326
+ const data = await googleApiFetch(config, url);
327
+ return data.files ?? [];
328
+ }
329
+ var googleSlidesSetupFlow = {
330
+ initialState: () => ({}),
331
+ steps: [
332
+ {
333
+ slug: "presentations",
334
+ type: "multiSelect",
335
+ question: {
336
+ ja: "\u5BFE\u8C61\u306E\u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
337
+ en: "Select target presentations (multi-select allowed)"
338
+ },
339
+ async fetchOptions(_state, rt) {
340
+ const files = await listPresentations(rt.config);
341
+ return [
342
+ {
343
+ value: ALL_PRESENTATIONS,
344
+ label: rt.language === "ja" ? "\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306A\u3059\u3079\u3066\u306E\u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3" : "All accessible presentations"
345
+ },
346
+ ...files.map((f) => ({ value: f.id, label: f.name }))
347
+ ];
348
+ },
349
+ applyAnswer: (state, answer) => ({ ...state, presentations: answer })
350
+ }
351
+ ],
352
+ async finalize(state, rt) {
353
+ if (!state.presentations) {
354
+ throw new Error("Google Slides setup: incomplete state on finalize");
355
+ }
356
+ const targetIds = await resolveSetupSelection({
357
+ selected: state.presentations,
358
+ allSentinel: ALL_PRESENTATIONS,
359
+ fetchAll: async () => {
360
+ const files = await listPresentations(rt.config);
361
+ return files.map((f) => f.id);
362
+ },
363
+ limit: GOOGLE_SLIDES_SETUP_MAX_PRESENTATIONS
364
+ });
365
+ const sections = ["## Google Slides", ""];
366
+ if (targetIds.length === 0) {
367
+ sections.push(
368
+ rt.language === "ja" ? "\u5BFE\u8C61\u306E\u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002" : "No presentations selected."
369
+ );
370
+ return sections.join("\n");
371
+ }
372
+ for (const id of targetIds) {
373
+ const url = `https://slides.googleapis.com/v1/presentations/${encodeURIComponent(id)}?fields=presentationId,title,revisionId,slides(objectId)`;
374
+ const meta = await googleApiFetch(
375
+ rt.config,
376
+ url
377
+ );
378
+ const title = meta.title ?? id;
379
+ const slideCount = (meta.slides ?? []).length;
380
+ sections.push(`### Presentation: ${title}`, "");
381
+ sections.push(`- ID: ${id}`);
382
+ sections.push(`- Slides: ${slideCount}`);
383
+ if (meta.revisionId) sections.push(`- Revision: ${meta.revisionId}`);
384
+ sections.push("");
385
+ }
386
+ return sections.join("\n");
387
+ }
388
+ };
389
+
247
390
  // ../connectors/src/connectors/google-slides/parameters.ts
248
391
  var parameters = {};
249
392
 
@@ -374,6 +517,7 @@ var tools = { request: requestTool };
374
517
  var googleSlidesConnector = new ConnectorPlugin({
375
518
  slug: "google-slides",
376
519
  authType: AUTH_TYPES.OAUTH,
520
+ skipConnectionCheckOnCreate: true,
377
521
  name: "Google Slides",
378
522
  description: "Connect to Google Slides for presentation data access and creation using OAuth.",
379
523
  iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/4oyF4yTRpemMA43X49masx/e1582d25e3b4c9a63ba83df2147c1968/google_slide.png",
@@ -549,7 +693,8 @@ await slides.batchUpdate(presentationId, [
549
693
 
550
694
  \u30CF\u30F3\u30C9\u30E9\u306E\u30C6\u30B9\u30C8\u304C \`Connection proxy is not configured\` \u3067\u5931\u6557\u3059\u308B\u5834\u5408\u306F\u518D\u8A66\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u901A\u5E38\u306F\u30B5\u30F3\u30C9\u30DC\u30C3\u30AF\u30B9\u306E\u521D\u671F\u5316\u4E2D\u306B\u8D77\u304D\u307E\u3059\u3002SDK \u3092\u8AE6\u3081\u3066 OAuth \u30D7\u30ED\u30AD\u30B7\u306E URL \u3092\u81EA\u5206\u3067\u7D44\u307F\u7ACB\u3066\u308B\u3053\u3068\u306F **\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044**\u3002`
551
695
  },
552
- tools
696
+ tools,
697
+ setup: (params, ctx, config) => runSetupFlow(googleSlidesSetupFlow, params, ctx, config)
553
698
  });
554
699
 
555
700
  // src/connectors/create-connector-sdk.ts
@@ -578,6 +723,7 @@ function resolveEnvVarOptional(entry, key) {
578
723
  import { getContext } from "hono/context-storage";
579
724
  import { getCookie } from "hono/cookie";
580
725
  var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
726
+ var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
581
727
  function normalizeHeaders(input) {
582
728
  const out = {};
583
729
  if (!input) return out;
@@ -586,6 +732,11 @@ function normalizeHeaders(input) {
586
732
  });
587
733
  return out;
588
734
  }
735
+ function extractInputUrl(input) {
736
+ if (typeof input === "string") return input;
737
+ if (input instanceof URL) return input.href;
738
+ return input.url;
739
+ }
589
740
  function createSandboxProxyFetch(connectionId) {
590
741
  return async (input, init) => {
591
742
  const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
@@ -595,10 +746,17 @@ function createSandboxProxyFetch(connectionId) {
595
746
  "Connection proxy is not configured. Please check your deployment settings."
596
747
  );
597
748
  }
598
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
749
+ const originalUrl = extractInputUrl(input);
750
+ const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
751
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
752
+ const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
753
+ return fetch(sessionUrl, {
754
+ method: "POST",
755
+ headers: { Authorization: `Bearer ${token}` }
756
+ });
757
+ }
599
758
  const originalMethod = init?.method ?? "GET";
600
759
  const originalBody = init?.body ? JSON.parse(init.body) : void 0;
601
- const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
602
760
  const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
603
761
  return fetch(proxyUrl, {
604
762
  method: "POST",
@@ -624,10 +782,9 @@ function createDeployedAppProxyFetch(connectionId) {
624
782
  }
625
783
  const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
626
784
  const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
785
+ const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
627
786
  return async (input, init) => {
628
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
629
- const originalMethod = init?.method ?? "GET";
630
- const originalBody = init?.body ? JSON.parse(init.body) : void 0;
787
+ const originalUrl = extractInputUrl(input);
631
788
  const c = getContext();
632
789
  const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
633
790
  if (!appSession) {
@@ -635,6 +792,14 @@ function createDeployedAppProxyFetch(connectionId) {
635
792
  "No authentication method available for connection proxy."
636
793
  );
637
794
  }
795
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
796
+ return fetch(sessionUrl, {
797
+ method: "POST",
798
+ headers: { Authorization: `Bearer ${appSession}` }
799
+ });
800
+ }
801
+ const originalMethod = init?.method ?? "GET";
802
+ const originalBody = init?.body ? JSON.parse(init.body) : void 0;
638
803
  return fetch(proxyUrl, {
639
804
  method: "POST",
640
805
  headers: {