@squadbase/vite-server 0.1.17-dev.24af54e → 0.1.17-dev.7408ec4

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 (73) hide show
  1. package/dist/cli/index.js +1682 -425
  2. package/dist/connectors/airtable-oauth.js +22 -3
  3. package/dist/connectors/airtable.js +22 -3
  4. package/dist/connectors/amplitude.js +22 -3
  5. package/dist/connectors/asana.js +22 -3
  6. package/dist/connectors/attio.js +22 -3
  7. package/dist/connectors/aws-billing.js +22 -3
  8. package/dist/connectors/azure-sql.js +25 -6
  9. package/dist/connectors/backlog-api-key.js +22 -3
  10. package/dist/connectors/clickup.js +22 -3
  11. package/dist/connectors/cosmosdb.js +22 -3
  12. package/dist/connectors/customerio.js +23 -4
  13. package/dist/connectors/dbt.js +22 -3
  14. package/dist/connectors/freshdesk.js +22 -3
  15. package/dist/connectors/freshsales.js +22 -3
  16. package/dist/connectors/freshservice.js +22 -3
  17. package/dist/connectors/gamma.js +24 -5
  18. package/dist/connectors/github.js +22 -3
  19. package/dist/connectors/gmail-oauth.js +22 -3
  20. package/dist/connectors/gmail.js +22 -3
  21. package/dist/connectors/google-ads.js +22 -3
  22. package/dist/connectors/google-analytics-oauth.js +22 -3
  23. package/dist/connectors/google-analytics.js +222 -68
  24. package/dist/connectors/google-audit-log.js +22 -3
  25. package/dist/connectors/google-calendar-oauth.js +22 -3
  26. package/dist/connectors/google-calendar.js +22 -3
  27. package/dist/connectors/google-docs.js +22 -3
  28. package/dist/connectors/google-drive.js +22 -3
  29. package/dist/connectors/google-search-console-oauth.js +22 -3
  30. package/dist/connectors/google-sheets.js +22 -3
  31. package/dist/connectors/google-slides.js +22 -3
  32. package/dist/connectors/grafana.js +22 -3
  33. package/dist/connectors/hubspot-oauth.js +22 -3
  34. package/dist/connectors/hubspot.js +22 -3
  35. package/dist/connectors/influxdb.js +22 -3
  36. package/dist/connectors/intercom-oauth.js +22 -3
  37. package/dist/connectors/intercom.js +22 -3
  38. package/dist/connectors/jdbc.js +22 -3
  39. package/dist/connectors/jira-api-key.js +22 -3
  40. package/dist/connectors/kintone-api-token.js +22 -3
  41. package/dist/connectors/kintone.js +22 -3
  42. package/dist/connectors/linear.js +22 -3
  43. package/dist/connectors/linkedin-ads.js +22 -3
  44. package/dist/connectors/mailchimp-oauth.js +22 -3
  45. package/dist/connectors/mailchimp.js +22 -3
  46. package/dist/connectors/meta-ads-oauth.js +22 -3
  47. package/dist/connectors/meta-ads.js +22 -3
  48. package/dist/connectors/mixpanel.js +22 -3
  49. package/dist/connectors/monday.js +22 -3
  50. package/dist/connectors/mongodb.js +22 -3
  51. package/dist/connectors/notion-oauth.js +22 -3
  52. package/dist/connectors/notion.js +22 -3
  53. package/dist/connectors/oracle.js +48 -14
  54. package/dist/connectors/outlook-oauth.js +22 -3
  55. package/dist/connectors/powerbi-oauth.js +303 -37
  56. package/dist/connectors/salesforce.js +22 -3
  57. package/dist/connectors/semrush.js +360 -46
  58. package/dist/connectors/sentry.js +22 -3
  59. package/dist/connectors/shopify-oauth.js +22 -3
  60. package/dist/connectors/shopify.js +22 -3
  61. package/dist/connectors/sqlserver.js +25 -6
  62. package/dist/connectors/stripe-api-key.js +22 -3
  63. package/dist/connectors/stripe-oauth.js +22 -3
  64. package/dist/connectors/supabase.js +25 -6
  65. package/dist/connectors/tableau.js +240 -78
  66. package/dist/connectors/tiktok-ads.js +22 -3
  67. package/dist/connectors/wix-store.js +22 -3
  68. package/dist/connectors/zendesk-oauth.js +22 -3
  69. package/dist/connectors/zendesk.js +22 -3
  70. package/dist/index.js +1682 -425
  71. package/dist/main.js +1682 -425
  72. package/dist/vite-plugin.js +1682 -425
  73. package/package.json +1 -1
@@ -611,19 +611,28 @@ async function runSetupFlow(flow, params, ctx, config) {
611
611
  };
612
612
  let state = flow.initialState();
613
613
  let answerIdx = 0;
614
+ const pendingParameterUpdates = [];
614
615
  for (const step of flow.steps) {
615
616
  const ans = ctx.answers[answerIdx];
616
617
  if (ans && ans.questionSlug === step.slug) {
617
618
  state = step.applyAnswer(state, ans.answer);
619
+ if (step.toParameterUpdates) {
620
+ pendingParameterUpdates.push(...step.toParameterUpdates(state));
621
+ }
618
622
  answerIdx += 1;
619
623
  continue;
620
624
  }
625
+ const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
621
626
  if (step.type === "text") {
622
627
  return {
623
628
  type: "nextQuestion",
624
629
  questionSlug: step.slug,
625
630
  question: step.question[ctx.language],
626
- questionType: "text"
631
+ questionType: "text",
632
+ allowFreeText: resolvedAllowFreeText,
633
+ ...pendingParameterUpdates.length > 0 && {
634
+ parameterUpdates: pendingParameterUpdates
635
+ }
627
636
  };
628
637
  }
629
638
  const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
@@ -635,11 +644,21 @@ async function runSetupFlow(flow, params, ctx, config) {
635
644
  questionSlug: step.slug,
636
645
  question: step.question[ctx.language],
637
646
  questionType: step.type,
638
- options
647
+ options,
648
+ allowFreeText: resolvedAllowFreeText,
649
+ ...pendingParameterUpdates.length > 0 && {
650
+ parameterUpdates: pendingParameterUpdates
651
+ }
639
652
  };
640
653
  }
641
654
  const dataInvestigationResult = await flow.finalize(state, runtime);
642
- return { type: "fulfilled", dataInvestigationResult };
655
+ return {
656
+ type: "fulfilled",
657
+ dataInvestigationResult,
658
+ ...pendingParameterUpdates.length > 0 && {
659
+ parameterUpdates: pendingParameterUpdates
660
+ }
661
+ };
643
662
  }
644
663
  async function resolveSetupSelection(params) {
645
664
  const { selected, allSentinel, fetchAll, limit } = params;
@@ -751,14 +770,15 @@ function isInternalOwner(name) {
751
770
  function quoteLiteral(value) {
752
771
  return "'" + value.replace(/'/g, "''") + "'";
753
772
  }
754
- async function fetchTableNames(params, owner) {
773
+ async function fetchTableAndViewNames(params, owner) {
755
774
  const rows = await runOracleSetupQuery(
756
775
  params,
757
- `SELECT TABLE_NAME FROM ALL_TABLES
758
- WHERE OWNER = ${quoteLiteral(owner)}
759
- ORDER BY TABLE_NAME`
776
+ `SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = ${quoteLiteral(owner)}
777
+ UNION
778
+ SELECT VIEW_NAME FROM ALL_VIEWS WHERE OWNER = ${quoteLiteral(owner)}
779
+ ORDER BY 1`
760
780
  );
761
- return rows.map((r) => String(r["TABLE_NAME"] ?? "")).filter((name) => name);
781
+ return rows.map((r) => String(r["TABLE_NAME"] ?? r["VIEW_NAME"] ?? "")).filter((name) => name);
762
782
  }
763
783
  var oracleSetupFlow = {
764
784
  initialState: () => ({}),
@@ -783,17 +803,17 @@ var oracleSetupFlow = {
783
803
  slug: "tables",
784
804
  type: "multiSelect",
785
805
  question: {
786
- ja: "\u5BFE\u8C61\u30C6\u30FC\u30D6\u30EB\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
787
- en: "Select target tables (multi-select allowed)"
806
+ ja: "\u5BFE\u8C61\u30C6\u30FC\u30D6\u30EB\u30FB\u30D3\u30E5\u30FC\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
807
+ en: "Select target tables and views (multi-select allowed)"
788
808
  },
789
809
  async fetchOptions(state, rt) {
790
810
  if (!state.owner) return [];
791
- const names = await fetchTableNames(rt.params, state.owner);
811
+ const names = await fetchTableAndViewNames(rt.params, state.owner);
792
812
  const tableOptions = names.map((value) => ({ value }));
793
813
  return [
794
814
  {
795
815
  value: ALL_TABLES,
796
- label: rt.language === "ja" ? "\u3059\u3079\u3066\u306E\u30C6\u30FC\u30D6\u30EB" : "All tables"
816
+ label: rt.language === "ja" ? "\u3059\u3079\u3066\u306E\u30C6\u30FC\u30D6\u30EB\u30FB\u30D3\u30E5\u30FC" : "All tables and views"
797
817
  },
798
818
  ...tableOptions
799
819
  ];
@@ -809,9 +829,22 @@ var oracleSetupFlow = {
809
829
  const targetTables = await resolveSetupSelection({
810
830
  selected: state.tables,
811
831
  allSentinel: ALL_TABLES,
812
- fetchAll: () => fetchTableNames(rt.params, owner),
832
+ fetchAll: () => fetchTableAndViewNames(rt.params, owner),
813
833
  limit: ORACLE_SETUP_MAX_TABLES
814
834
  });
835
+ const typeRows = targetTables.length > 0 ? await runOracleSetupQuery(
836
+ rt.params,
837
+ `SELECT OBJECT_NAME, OBJECT_TYPE FROM ALL_OBJECTS
838
+ WHERE OWNER = ${quoteLiteral(owner)}
839
+ AND OBJECT_NAME IN (${targetTables.map(quoteLiteral).join(", ")})
840
+ AND OBJECT_TYPE IN ('TABLE', 'VIEW')`
841
+ ) : [];
842
+ const typeMap = new Map(
843
+ typeRows.map((r) => [
844
+ String(r["OBJECT_NAME"] ?? ""),
845
+ String(r["OBJECT_TYPE"] ?? "TABLE")
846
+ ])
847
+ );
815
848
  const sections = [
816
849
  "## Oracle Database",
817
850
  "",
@@ -819,6 +852,7 @@ var oracleSetupFlow = {
819
852
  ""
820
853
  ];
821
854
  for (const table of targetTables) {
855
+ const heading = typeMap.get(table) === "VIEW" ? "View" : "Table";
822
856
  const cols = await runOracleSetupQuery(
823
857
  rt.params,
824
858
  `SELECT COLUMN_NAME, DATA_TYPE, NULLABLE, DATA_DEFAULT
@@ -827,7 +861,7 @@ var oracleSetupFlow = {
827
861
  AND TABLE_NAME = ${quoteLiteral(table)}
828
862
  ORDER BY COLUMN_ID`
829
863
  );
830
- sections.push(`#### Table: ${table}`, "");
864
+ sections.push(`#### ${heading}: ${table}`, "");
831
865
  sections.push("| Column | Type | Nullable | Default |");
832
866
  sections.push("|--------|------|----------|---------|");
833
867
  for (const c of cols) {
@@ -298,19 +298,28 @@ async function runSetupFlow(flow, params, ctx, config) {
298
298
  };
299
299
  let state = flow.initialState();
300
300
  let answerIdx = 0;
301
+ const pendingParameterUpdates = [];
301
302
  for (const step of flow.steps) {
302
303
  const ans = ctx.answers[answerIdx];
303
304
  if (ans && ans.questionSlug === step.slug) {
304
305
  state = step.applyAnswer(state, ans.answer);
306
+ if (step.toParameterUpdates) {
307
+ pendingParameterUpdates.push(...step.toParameterUpdates(state));
308
+ }
305
309
  answerIdx += 1;
306
310
  continue;
307
311
  }
312
+ const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
308
313
  if (step.type === "text") {
309
314
  return {
310
315
  type: "nextQuestion",
311
316
  questionSlug: step.slug,
312
317
  question: step.question[ctx.language],
313
- questionType: "text"
318
+ questionType: "text",
319
+ allowFreeText: resolvedAllowFreeText,
320
+ ...pendingParameterUpdates.length > 0 && {
321
+ parameterUpdates: pendingParameterUpdates
322
+ }
314
323
  };
315
324
  }
316
325
  const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
@@ -322,11 +331,21 @@ async function runSetupFlow(flow, params, ctx, config) {
322
331
  questionSlug: step.slug,
323
332
  question: step.question[ctx.language],
324
333
  questionType: step.type,
325
- options
334
+ options,
335
+ allowFreeText: resolvedAllowFreeText,
336
+ ...pendingParameterUpdates.length > 0 && {
337
+ parameterUpdates: pendingParameterUpdates
338
+ }
326
339
  };
327
340
  }
328
341
  const dataInvestigationResult = await flow.finalize(state, runtime);
329
- return { type: "fulfilled", dataInvestigationResult };
342
+ return {
343
+ type: "fulfilled",
344
+ dataInvestigationResult,
345
+ ...pendingParameterUpdates.length > 0 && {
346
+ parameterUpdates: pendingParameterUpdates
347
+ }
348
+ };
330
349
  }
331
350
  async function resolveSetupSelection(params) {
332
351
  const { selected, allSentinel, fetchAll, limit } = params;
@@ -256,19 +256,28 @@ async function runSetupFlow(flow, params, ctx, config) {
256
256
  };
257
257
  let state = flow.initialState();
258
258
  let answerIdx = 0;
259
+ const pendingParameterUpdates = [];
259
260
  for (const step of flow.steps) {
260
261
  const ans = ctx.answers[answerIdx];
261
262
  if (ans && ans.questionSlug === step.slug) {
262
263
  state = step.applyAnswer(state, ans.answer);
264
+ if (step.toParameterUpdates) {
265
+ pendingParameterUpdates.push(...step.toParameterUpdates(state));
266
+ }
263
267
  answerIdx += 1;
264
268
  continue;
265
269
  }
270
+ const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
266
271
  if (step.type === "text") {
267
272
  return {
268
273
  type: "nextQuestion",
269
274
  questionSlug: step.slug,
270
275
  question: step.question[ctx.language],
271
- questionType: "text"
276
+ questionType: "text",
277
+ allowFreeText: resolvedAllowFreeText,
278
+ ...pendingParameterUpdates.length > 0 && {
279
+ parameterUpdates: pendingParameterUpdates
280
+ }
272
281
  };
273
282
  }
274
283
  const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
@@ -280,11 +289,21 @@ async function runSetupFlow(flow, params, ctx, config) {
280
289
  questionSlug: step.slug,
281
290
  question: step.question[ctx.language],
282
291
  questionType: step.type,
283
- options
292
+ options,
293
+ allowFreeText: resolvedAllowFreeText,
294
+ ...pendingParameterUpdates.length > 0 && {
295
+ parameterUpdates: pendingParameterUpdates
296
+ }
284
297
  };
285
298
  }
286
299
  const dataInvestigationResult = await flow.finalize(state, runtime);
287
- return { type: "fulfilled", dataInvestigationResult };
300
+ return {
301
+ type: "fulfilled",
302
+ dataInvestigationResult,
303
+ ...pendingParameterUpdates.length > 0 && {
304
+ parameterUpdates: pendingParameterUpdates
305
+ }
306
+ };
288
307
  }
289
308
  async function resolveSetupSelection(params) {
290
309
  const { selected, allSentinel, fetchAll, limit } = params;
@@ -489,6 +508,10 @@ function apiFetch(proxyFetch, path2, init) {
489
508
 
490
509
  // ../connectors/src/connectors/powerbi-oauth/setup-flow.ts
491
510
  var ALL_WORKSPACES = "__ALL_WORKSPACES__";
511
+ var MY_WORKSPACE = "__MY_WORKSPACE__";
512
+ var ALL_DATASETS = "__ALL_DATASETS__";
513
+ var ALL_REPORTS = "__ALL_REPORTS__";
514
+ var ALL_DASHBOARDS = "__ALL_DASHBOARDS__";
492
515
  var POWERBI_SETUP_MAX_WORKSPACES = 10;
493
516
  var RESOURCE_DISPLAY_LIMIT = 25;
494
517
  var RESOURCE_DATASETS = "datasets";
@@ -504,14 +527,12 @@ async function listGroups(proxyFetch) {
504
527
  return data.value ?? [];
505
528
  }
506
529
  async function listResource(proxyFetch, groupId, resource) {
507
- const res = await apiFetch(
508
- proxyFetch,
509
- `/groups/${encodeURIComponent(groupId)}/${resource}`
510
- );
530
+ const path2 = groupId === MY_WORKSPACE ? `/${resource}` : `/groups/${encodeURIComponent(groupId)}/${resource}`;
531
+ const res = await apiFetch(proxyFetch, path2);
511
532
  if (!res.ok) {
512
533
  const body = await res.text().catch(() => res.statusText);
513
534
  throw new Error(
514
- `powerbi: list ${resource} for group ${groupId} failed (${res.status}): ${body}`
535
+ `powerbi: list ${resource} for ${groupId === MY_WORKSPACE ? "My workspace" : `group ${groupId}`} failed (${res.status}): ${body}`
515
536
  );
516
537
  }
517
538
  const data = await res.json();
@@ -520,6 +541,99 @@ async function listResource(proxyFetch, groupId, resource) {
520
541
  function resourceLabel(r) {
521
542
  return r.name ?? r.displayName ?? r.id ?? "(unknown)";
522
543
  }
544
+ var INTERNAL_TABLE_PREFIXES = [
545
+ "DateTableTemplate_",
546
+ "LocalDateTable_"
547
+ ];
548
+ function isInternalColumn(name) {
549
+ return /^RowNumber-[0-9A-Fa-f-]+$/.test(name);
550
+ }
551
+ async function fetchDatasetSchema(proxyFetch, wsId, datasetId) {
552
+ const pathPrefix = wsId === MY_WORKSPACE ? "" : `/groups/${encodeURIComponent(wsId)}`;
553
+ const daxQuery = 'EVALUATE SELECTCOLUMNS(COLUMNSTATISTICS(), "T", [Table Name], "C", [Column Name])';
554
+ const res = await apiFetch(
555
+ proxyFetch,
556
+ `${pathPrefix}/datasets/${encodeURIComponent(datasetId)}/executeQueries`,
557
+ {
558
+ method: "POST",
559
+ headers: { "Content-Type": "application/json" },
560
+ body: JSON.stringify({
561
+ queries: [{ query: daxQuery }],
562
+ serializerSettings: { includeNulls: true }
563
+ })
564
+ }
565
+ );
566
+ if (!res.ok) return /* @__PURE__ */ new Map();
567
+ const data = await res.json();
568
+ const rows = data.results?.[0]?.tables?.[0]?.rows ?? [];
569
+ const schema = /* @__PURE__ */ new Map();
570
+ for (const row of rows) {
571
+ const table = row["[T]"] ?? "";
572
+ const column = row["[C]"] ?? "";
573
+ if (!table || !column) continue;
574
+ if (INTERNAL_TABLE_PREFIXES.some((p) => table.startsWith(p))) continue;
575
+ if (isInternalColumn(column)) continue;
576
+ if (!schema.has(table)) schema.set(table, []);
577
+ schema.get(table).push(column);
578
+ }
579
+ return schema;
580
+ }
581
+ function workspaceName(wsId, groupById, language) {
582
+ if (wsId === MY_WORKSPACE) {
583
+ return language === "ja" ? "\u30DE\u30A4 \u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9" : "My workspace";
584
+ }
585
+ return groupById.get(wsId)?.name ?? wsId;
586
+ }
587
+ async function resolveWorkspaceIds(selected, proxyFetch) {
588
+ return resolveSetupSelection({
589
+ selected,
590
+ allSentinel: ALL_WORKSPACES,
591
+ fetchAll: async () => {
592
+ const groups = await listGroups(proxyFetch);
593
+ return [MY_WORKSPACE, ...groups.map((g) => g.id).filter(Boolean)];
594
+ },
595
+ limit: POWERBI_SETUP_MAX_WORKSPACES
596
+ });
597
+ }
598
+ function compoundKey(wsId, objectId) {
599
+ return `${wsId}:${objectId}`;
600
+ }
601
+ function parseCompoundKey(key) {
602
+ const idx = key.indexOf(":");
603
+ if (idx < 0) return { wsId: "", objectId: key };
604
+ return { wsId: key.slice(0, idx), objectId: key.slice(idx + 1) };
605
+ }
606
+ async function fetchObjectOptions(state, resource, allSentinel, allLabelJa, allLabelEn, rt) {
607
+ if (!state.workspaces?.length || !state.resources?.includes(resource))
608
+ return [];
609
+ const wsIds = await resolveWorkspaceIds(
610
+ state.workspaces,
611
+ rt.config.proxyFetch
612
+ );
613
+ const allGroups = await listGroups(rt.config.proxyFetch);
614
+ const groupById = new Map(allGroups.map((g) => [g.id, g]));
615
+ const multiWorkspace = wsIds.length > 1;
616
+ const options = [];
617
+ for (const wsId of wsIds) {
618
+ const wsLabel = workspaceName(wsId, groupById, rt.language);
619
+ const items = await listResource(rt.config.proxyFetch, wsId, resource);
620
+ for (const item of items) {
621
+ if (!item.id) continue;
622
+ options.push({
623
+ value: compoundKey(wsId, item.id),
624
+ label: multiWorkspace ? `${wsLabel} / ${resourceLabel(item)}` : resourceLabel(item)
625
+ });
626
+ }
627
+ }
628
+ if (options.length === 0) return [];
629
+ return [
630
+ {
631
+ value: allSentinel,
632
+ label: rt.language === "ja" ? allLabelJa : allLabelEn
633
+ },
634
+ ...options
635
+ ];
636
+ }
523
637
  var powerbiOauthSetupFlow = {
524
638
  initialState: () => ({}),
525
639
  steps: [
@@ -538,6 +652,10 @@ var powerbiOauthSetupFlow = {
538
652
  value: ALL_WORKSPACES,
539
653
  label: rt.language === "ja" ? "\u3059\u3079\u3066\u306E\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9" : "All workspaces"
540
654
  },
655
+ {
656
+ value: MY_WORKSPACE,
657
+ label: rt.language === "ja" ? "\u30DE\u30A4 \u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9" : "My workspace"
658
+ },
541
659
  ...options
542
660
  ];
543
661
  },
@@ -552,16 +670,82 @@ var powerbiOauthSetupFlow = {
552
670
  },
553
671
  async fetchOptions(state, rt) {
554
672
  if (!state.workspaces?.length) return [];
555
- const datasetsLabel = rt.language === "ja" ? "\u30C7\u30FC\u30BF\u30BB\u30C3\u30C8" : "Datasets";
556
- const reportsLabel = rt.language === "ja" ? "\u30EC\u30DD\u30FC\u30C8" : "Reports";
557
- const dashboardsLabel = rt.language === "ja" ? "\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9" : "Dashboards";
558
673
  return [
559
- { value: RESOURCE_DATASETS, label: datasetsLabel },
560
- { value: RESOURCE_REPORTS, label: reportsLabel },
561
- { value: RESOURCE_DASHBOARDS, label: dashboardsLabel }
674
+ {
675
+ value: RESOURCE_DATASETS,
676
+ label: rt.language === "ja" ? "\u30C7\u30FC\u30BF\u30BB\u30C3\u30C8" : "Datasets"
677
+ },
678
+ {
679
+ value: RESOURCE_REPORTS,
680
+ label: rt.language === "ja" ? "\u30EC\u30DD\u30FC\u30C8" : "Reports"
681
+ },
682
+ {
683
+ value: RESOURCE_DASHBOARDS,
684
+ label: rt.language === "ja" ? "\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9" : "Dashboards"
685
+ }
562
686
  ];
563
687
  },
564
688
  applyAnswer: (state, answer) => ({ ...state, resources: answer })
689
+ },
690
+ {
691
+ slug: "datasets",
692
+ type: "multiSelect",
693
+ question: {
694
+ ja: "\u4F7F\u7528\u3059\u308B\u30C7\u30FC\u30BF\u30BB\u30C3\u30C8\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
695
+ en: "Select the datasets you want to use (multi-select allowed)"
696
+ },
697
+ async fetchOptions(state, rt) {
698
+ return fetchObjectOptions(
699
+ state,
700
+ RESOURCE_DATASETS,
701
+ ALL_DATASETS,
702
+ "\u3059\u3079\u3066\u306E\u30C7\u30FC\u30BF\u30BB\u30C3\u30C8",
703
+ "All datasets",
704
+ rt
705
+ );
706
+ },
707
+ applyAnswer: (state, answer) => ({ ...state, selectedDatasets: answer })
708
+ },
709
+ {
710
+ slug: "reports",
711
+ type: "multiSelect",
712
+ question: {
713
+ ja: "\u4F7F\u7528\u3059\u308B\u30EC\u30DD\u30FC\u30C8\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
714
+ en: "Select the reports you want to use (multi-select allowed)"
715
+ },
716
+ async fetchOptions(state, rt) {
717
+ return fetchObjectOptions(
718
+ state,
719
+ RESOURCE_REPORTS,
720
+ ALL_REPORTS,
721
+ "\u3059\u3079\u3066\u306E\u30EC\u30DD\u30FC\u30C8",
722
+ "All reports",
723
+ rt
724
+ );
725
+ },
726
+ applyAnswer: (state, answer) => ({ ...state, selectedReports: answer })
727
+ },
728
+ {
729
+ slug: "dashboards",
730
+ type: "multiSelect",
731
+ question: {
732
+ ja: "\u4F7F\u7528\u3059\u308B\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
733
+ en: "Select the dashboards you want to use (multi-select allowed)"
734
+ },
735
+ async fetchOptions(state, rt) {
736
+ return fetchObjectOptions(
737
+ state,
738
+ RESOURCE_DASHBOARDS,
739
+ ALL_DASHBOARDS,
740
+ "\u3059\u3079\u3066\u306E\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9",
741
+ "All dashboards",
742
+ rt
743
+ );
744
+ },
745
+ applyAnswer: (state, answer) => ({
746
+ ...state,
747
+ selectedDashboards: answer
748
+ })
565
749
  }
566
750
  ],
567
751
  async finalize(state, rt) {
@@ -570,37 +754,119 @@ var powerbiOauthSetupFlow = {
570
754
  }
571
755
  const allGroups = await listGroups(rt.config.proxyFetch);
572
756
  const groupById = new Map(allGroups.map((g) => [g.id, g]));
573
- const targetIds = await resolveSetupSelection({
574
- selected: state.workspaces,
575
- allSentinel: ALL_WORKSPACES,
576
- fetchAll: async () => allGroups.map((g) => g.id).filter((id) => id),
577
- limit: POWERBI_SETUP_MAX_WORKSPACES
578
- });
757
+ const wsIds = await resolveWorkspaceIds(
758
+ state.workspaces,
759
+ rt.config.proxyFetch
760
+ );
579
761
  const selectedResources = new Set(state.resources);
762
+ async function resolveObjects(selected, allSentinel, resource) {
763
+ const byWorkspace = /* @__PURE__ */ new Map();
764
+ if (!selected || !selectedResources.has(resource)) return byWorkspace;
765
+ if (selected.includes(allSentinel)) {
766
+ for (const wsId of wsIds) {
767
+ const items = await listResource(
768
+ rt.config.proxyFetch,
769
+ wsId,
770
+ resource
771
+ );
772
+ const ids = items.map((i) => i.id).filter((id) => !!id);
773
+ if (ids.length > 0) byWorkspace.set(wsId, new Set(ids));
774
+ }
775
+ } else {
776
+ for (const key of selected) {
777
+ if (key === allSentinel) continue;
778
+ const { wsId, objectId } = parseCompoundKey(key);
779
+ if (!byWorkspace.has(wsId)) byWorkspace.set(wsId, /* @__PURE__ */ new Set());
780
+ byWorkspace.get(wsId).add(objectId);
781
+ }
782
+ }
783
+ return byWorkspace;
784
+ }
785
+ const datasetsByWs = await resolveObjects(
786
+ state.selectedDatasets,
787
+ ALL_DATASETS,
788
+ RESOURCE_DATASETS
789
+ );
790
+ const reportsByWs = await resolveObjects(
791
+ state.selectedReports,
792
+ ALL_REPORTS,
793
+ RESOURCE_REPORTS
794
+ );
795
+ const dashboardsByWs = await resolveObjects(
796
+ state.selectedDashboards,
797
+ ALL_DASHBOARDS,
798
+ RESOURCE_DASHBOARDS
799
+ );
800
+ const allWsIds = /* @__PURE__ */ new Set([
801
+ ...datasetsByWs.keys(),
802
+ ...reportsByWs.keys(),
803
+ ...dashboardsByWs.keys()
804
+ ]);
580
805
  const sections = ["## Power BI", ""];
581
- if (!targetIds.length) {
582
- sections.push("_No workspaces selected._", "");
806
+ if (allWsIds.size === 0) {
807
+ sections.push("_No resources selected._", "");
583
808
  return sections.join("\n");
584
809
  }
585
- for (const id of targetIds) {
586
- const group = groupById.get(id);
587
- const name = group?.name ?? id;
588
- sections.push(`### Workspace: ${name}`, "", `- id: \`${id}\``);
589
- for (const resource of [
590
- RESOURCE_DATASETS,
591
- RESOURCE_REPORTS,
592
- RESOURCE_DASHBOARDS
810
+ for (const wsId of wsIds) {
811
+ if (!allWsIds.has(wsId)) continue;
812
+ const name = workspaceName(wsId, groupById, rt.language);
813
+ sections.push(`### Workspace: ${name}`, "");
814
+ if (wsId !== MY_WORKSPACE) {
815
+ sections.push(`- id: \`${wsId}\``);
816
+ }
817
+ const datasetIds = datasetsByWs.get(wsId);
818
+ if (datasetIds?.size) {
819
+ const items = await listResource(
820
+ rt.config.proxyFetch,
821
+ wsId,
822
+ RESOURCE_DATASETS
823
+ );
824
+ const filtered = items.filter(
825
+ (item) => item.id && datasetIds.has(item.id)
826
+ );
827
+ for (const item of filtered.slice(0, RESOURCE_DISPLAY_LIMIT)) {
828
+ sections.push(`#### Dataset: ${resourceLabel(item)}`, "");
829
+ const schema = await fetchDatasetSchema(
830
+ rt.config.proxyFetch,
831
+ wsId,
832
+ item.id
833
+ );
834
+ if (schema.size > 0) {
835
+ for (const [table, columns] of schema) {
836
+ sections.push(`##### Table: ${table}`, "");
837
+ sections.push("| Column |");
838
+ sections.push("|--------|");
839
+ for (const col of columns) {
840
+ sections.push(`| ${col} |`);
841
+ }
842
+ sections.push("");
843
+ }
844
+ } else {
845
+ sections.push("_Schema not available._", "");
846
+ }
847
+ }
848
+ }
849
+ for (const [resource, selectedByWs, heading] of [
850
+ [RESOURCE_REPORTS, reportsByWs, "Reports"],
851
+ [RESOURCE_DASHBOARDS, dashboardsByWs, "Dashboards"]
593
852
  ]) {
594
- if (!selectedResources.has(resource)) continue;
595
- const items = await listResource(rt.config.proxyFetch, id, resource);
596
- const heading = resource === RESOURCE_DATASETS ? "Datasets" : resource === RESOURCE_REPORTS ? "Reports" : "Dashboards";
597
- sections.push(`- ${heading} (${items.length}):`);
598
- for (const item of items.slice(0, RESOURCE_DISPLAY_LIMIT)) {
853
+ const selectedIds = selectedByWs.get(wsId);
854
+ if (!selectedIds?.size) continue;
855
+ const items = await listResource(
856
+ rt.config.proxyFetch,
857
+ wsId,
858
+ resource
859
+ );
860
+ const filtered = items.filter(
861
+ (item) => item.id && selectedIds.has(item.id)
862
+ );
863
+ sections.push(`- ${heading} (${filtered.length}):`);
864
+ for (const item of filtered.slice(0, RESOURCE_DISPLAY_LIMIT)) {
599
865
  sections.push(` - ${resourceLabel(item)}`);
600
866
  }
601
- if (items.length > RESOURCE_DISPLAY_LIMIT) {
867
+ if (filtered.length > RESOURCE_DISPLAY_LIMIT) {
602
868
  sections.push(
603
- ` - \u2026and ${items.length - RESOURCE_DISPLAY_LIMIT} more`
869
+ ` - \u2026and ${filtered.length - RESOURCE_DISPLAY_LIMIT} more`
604
870
  );
605
871
  }
606
872
  }
@@ -397,19 +397,28 @@ async function runSetupFlow(flow, params, ctx, config) {
397
397
  };
398
398
  let state = flow.initialState();
399
399
  let answerIdx = 0;
400
+ const pendingParameterUpdates = [];
400
401
  for (const step of flow.steps) {
401
402
  const ans = ctx.answers[answerIdx];
402
403
  if (ans && ans.questionSlug === step.slug) {
403
404
  state = step.applyAnswer(state, ans.answer);
405
+ if (step.toParameterUpdates) {
406
+ pendingParameterUpdates.push(...step.toParameterUpdates(state));
407
+ }
404
408
  answerIdx += 1;
405
409
  continue;
406
410
  }
411
+ const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
407
412
  if (step.type === "text") {
408
413
  return {
409
414
  type: "nextQuestion",
410
415
  questionSlug: step.slug,
411
416
  question: step.question[ctx.language],
412
- questionType: "text"
417
+ questionType: "text",
418
+ allowFreeText: resolvedAllowFreeText,
419
+ ...pendingParameterUpdates.length > 0 && {
420
+ parameterUpdates: pendingParameterUpdates
421
+ }
413
422
  };
414
423
  }
415
424
  const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
@@ -421,11 +430,21 @@ async function runSetupFlow(flow, params, ctx, config) {
421
430
  questionSlug: step.slug,
422
431
  question: step.question[ctx.language],
423
432
  questionType: step.type,
424
- options
433
+ options,
434
+ allowFreeText: resolvedAllowFreeText,
435
+ ...pendingParameterUpdates.length > 0 && {
436
+ parameterUpdates: pendingParameterUpdates
437
+ }
425
438
  };
426
439
  }
427
440
  const dataInvestigationResult = await flow.finalize(state, runtime);
428
- return { type: "fulfilled", dataInvestigationResult };
441
+ return {
442
+ type: "fulfilled",
443
+ dataInvestigationResult,
444
+ ...pendingParameterUpdates.length > 0 && {
445
+ parameterUpdates: pendingParameterUpdates
446
+ }
447
+ };
429
448
  }
430
449
  async function resolveSetupSelection(params) {
431
450
  const { selected, allSentinel, fetchAll, limit } = params;