@squadbase/vite-server 0.1.17-dev.24af54e → 0.1.17-dev.3b633bb

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/dist/cli/index.js +1681 -449
  2. package/dist/connectors/airtable-oauth.js +28 -3
  3. package/dist/connectors/airtable.js +28 -3
  4. package/dist/connectors/amplitude.js +28 -3
  5. package/dist/connectors/asana.js +28 -3
  6. package/dist/connectors/attio.js +28 -3
  7. package/dist/connectors/aws-billing.js +28 -3
  8. package/dist/connectors/azure-sql.js +31 -6
  9. package/dist/connectors/backlog-api-key.js +28 -3
  10. package/dist/connectors/clickup.js +28 -3
  11. package/dist/connectors/cosmosdb.js +28 -3
  12. package/dist/connectors/customerio.js +29 -4
  13. package/dist/connectors/dbt.js +28 -3
  14. package/dist/connectors/freshdesk.js +28 -3
  15. package/dist/connectors/freshsales.js +28 -3
  16. package/dist/connectors/freshservice.js +28 -3
  17. package/dist/connectors/gamma.js +30 -5
  18. package/dist/connectors/github.js +28 -3
  19. package/dist/connectors/gmail-oauth.js +28 -3
  20. package/dist/connectors/gmail.js +28 -3
  21. package/dist/connectors/google-ads.js +28 -3
  22. package/dist/connectors/google-analytics-oauth.js +28 -3
  23. package/dist/connectors/google-analytics.js +227 -105
  24. package/dist/connectors/google-audit-log.js +28 -3
  25. package/dist/connectors/google-calendar-oauth.js +28 -3
  26. package/dist/connectors/google-calendar.js +28 -3
  27. package/dist/connectors/google-docs.js +28 -3
  28. package/dist/connectors/google-drive.js +28 -3
  29. package/dist/connectors/google-search-console-oauth.js +28 -3
  30. package/dist/connectors/google-sheets.js +28 -3
  31. package/dist/connectors/google-slides.js +28 -3
  32. package/dist/connectors/grafana.js +28 -3
  33. package/dist/connectors/hubspot-oauth.js +28 -3
  34. package/dist/connectors/hubspot.js +28 -3
  35. package/dist/connectors/influxdb.js +28 -3
  36. package/dist/connectors/intercom-oauth.js +28 -3
  37. package/dist/connectors/intercom.js +28 -3
  38. package/dist/connectors/jdbc.js +28 -3
  39. package/dist/connectors/jira-api-key.js +28 -3
  40. package/dist/connectors/kintone-api-token.js +28 -3
  41. package/dist/connectors/kintone.js +28 -3
  42. package/dist/connectors/linear.js +28 -3
  43. package/dist/connectors/linkedin-ads.js +28 -3
  44. package/dist/connectors/mailchimp-oauth.js +28 -3
  45. package/dist/connectors/mailchimp.js +28 -3
  46. package/dist/connectors/meta-ads-oauth.js +28 -3
  47. package/dist/connectors/meta-ads.js +28 -3
  48. package/dist/connectors/mixpanel.js +28 -3
  49. package/dist/connectors/monday.js +28 -3
  50. package/dist/connectors/mongodb.js +28 -3
  51. package/dist/connectors/notion-oauth.js +28 -3
  52. package/dist/connectors/notion.js +28 -3
  53. package/dist/connectors/oracle.js +54 -14
  54. package/dist/connectors/outlook-oauth.js +28 -3
  55. package/dist/connectors/powerbi-oauth.js +309 -37
  56. package/dist/connectors/salesforce.js +28 -3
  57. package/dist/connectors/semrush.js +366 -46
  58. package/dist/connectors/sentry.js +28 -3
  59. package/dist/connectors/shopify-oauth.js +28 -3
  60. package/dist/connectors/shopify.js +28 -3
  61. package/dist/connectors/sqlserver.js +31 -6
  62. package/dist/connectors/stripe-api-key.js +28 -3
  63. package/dist/connectors/stripe-oauth.js +28 -3
  64. package/dist/connectors/supabase.js +31 -6
  65. package/dist/connectors/tableau.js +246 -78
  66. package/dist/connectors/tiktok-ads.js +28 -3
  67. package/dist/connectors/wix-store.js +28 -3
  68. package/dist/connectors/zendesk-oauth.js +28 -3
  69. package/dist/connectors/zendesk.js +28 -3
  70. package/dist/index.js +1681 -449
  71. package/dist/main.js +1681 -449
  72. package/dist/vite-plugin.js +1681 -449
  73. package/package.json +1 -1
@@ -398,19 +398,34 @@ async function runSetupFlow(flow, params, ctx, config) {
398
398
  };
399
399
  let state = flow.initialState();
400
400
  let answerIdx = 0;
401
+ const pendingParameterUpdates = [];
401
402
  for (const step of flow.steps) {
402
403
  const ans = ctx.answers[answerIdx];
403
404
  if (ans && ans.questionSlug === step.slug) {
404
405
  state = step.applyAnswer(state, ans.answer);
406
+ if (step.toParameterUpdates) {
407
+ pendingParameterUpdates.push(...step.toParameterUpdates(state));
408
+ }
405
409
  answerIdx += 1;
406
410
  continue;
407
411
  }
412
+ const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
408
413
  if (step.type === "text") {
414
+ if (step.fetchOptions) {
415
+ const options2 = await step.fetchOptions(state, runtime);
416
+ if (options2.length === 0) {
417
+ continue;
418
+ }
419
+ }
409
420
  return {
410
421
  type: "nextQuestion",
411
422
  questionSlug: step.slug,
412
423
  question: step.question[ctx.language],
413
- questionType: "text"
424
+ questionType: "text",
425
+ allowFreeText: resolvedAllowFreeText,
426
+ ...pendingParameterUpdates.length > 0 && {
427
+ parameterUpdates: pendingParameterUpdates
428
+ }
414
429
  };
415
430
  }
416
431
  const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
@@ -422,11 +437,21 @@ async function runSetupFlow(flow, params, ctx, config) {
422
437
  questionSlug: step.slug,
423
438
  question: step.question[ctx.language],
424
439
  questionType: step.type,
425
- options
440
+ options,
441
+ allowFreeText: resolvedAllowFreeText,
442
+ ...pendingParameterUpdates.length > 0 && {
443
+ parameterUpdates: pendingParameterUpdates
444
+ }
426
445
  };
427
446
  }
428
447
  const dataInvestigationResult = await flow.finalize(state, runtime);
429
- return { type: "fulfilled", dataInvestigationResult };
448
+ return {
449
+ type: "fulfilled",
450
+ dataInvestigationResult,
451
+ ...pendingParameterUpdates.length > 0 && {
452
+ parameterUpdates: pendingParameterUpdates
453
+ }
454
+ };
430
455
  }
431
456
 
432
457
  // ../connectors/src/auth-types.ts
@@ -428,19 +428,34 @@ async function runSetupFlow(flow, params, ctx, config) {
428
428
  };
429
429
  let state = flow.initialState();
430
430
  let answerIdx = 0;
431
+ const pendingParameterUpdates = [];
431
432
  for (const step of flow.steps) {
432
433
  const ans = ctx.answers[answerIdx];
433
434
  if (ans && ans.questionSlug === step.slug) {
434
435
  state = step.applyAnswer(state, ans.answer);
436
+ if (step.toParameterUpdates) {
437
+ pendingParameterUpdates.push(...step.toParameterUpdates(state));
438
+ }
435
439
  answerIdx += 1;
436
440
  continue;
437
441
  }
442
+ const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
438
443
  if (step.type === "text") {
444
+ if (step.fetchOptions) {
445
+ const options2 = await step.fetchOptions(state, runtime);
446
+ if (options2.length === 0) {
447
+ continue;
448
+ }
449
+ }
439
450
  return {
440
451
  type: "nextQuestion",
441
452
  questionSlug: step.slug,
442
453
  question: step.question[ctx.language],
443
- questionType: "text"
454
+ questionType: "text",
455
+ allowFreeText: resolvedAllowFreeText,
456
+ ...pendingParameterUpdates.length > 0 && {
457
+ parameterUpdates: pendingParameterUpdates
458
+ }
444
459
  };
445
460
  }
446
461
  const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
@@ -452,11 +467,21 @@ async function runSetupFlow(flow, params, ctx, config) {
452
467
  questionSlug: step.slug,
453
468
  question: step.question[ctx.language],
454
469
  questionType: step.type,
455
- options
470
+ options,
471
+ allowFreeText: resolvedAllowFreeText,
472
+ ...pendingParameterUpdates.length > 0 && {
473
+ parameterUpdates: pendingParameterUpdates
474
+ }
456
475
  };
457
476
  }
458
477
  const dataInvestigationResult = await flow.finalize(state, runtime);
459
- return { type: "fulfilled", dataInvestigationResult };
478
+ return {
479
+ type: "fulfilled",
480
+ dataInvestigationResult,
481
+ ...pendingParameterUpdates.length > 0 && {
482
+ parameterUpdates: pendingParameterUpdates
483
+ }
484
+ };
460
485
  }
461
486
  async function resolveSetupSelection(params) {
462
487
  const { selected, allSentinel, fetchAll, limit } = params;
@@ -333,19 +333,34 @@ async function runSetupFlow(flow, params, ctx, config) {
333
333
  };
334
334
  let state = flow.initialState();
335
335
  let answerIdx = 0;
336
+ const pendingParameterUpdates = [];
336
337
  for (const step of flow.steps) {
337
338
  const ans = ctx.answers[answerIdx];
338
339
  if (ans && ans.questionSlug === step.slug) {
339
340
  state = step.applyAnswer(state, ans.answer);
341
+ if (step.toParameterUpdates) {
342
+ pendingParameterUpdates.push(...step.toParameterUpdates(state));
343
+ }
340
344
  answerIdx += 1;
341
345
  continue;
342
346
  }
347
+ const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
343
348
  if (step.type === "text") {
349
+ if (step.fetchOptions) {
350
+ const options2 = await step.fetchOptions(state, runtime);
351
+ if (options2.length === 0) {
352
+ continue;
353
+ }
354
+ }
344
355
  return {
345
356
  type: "nextQuestion",
346
357
  questionSlug: step.slug,
347
358
  question: step.question[ctx.language],
348
- questionType: "text"
359
+ questionType: "text",
360
+ allowFreeText: resolvedAllowFreeText,
361
+ ...pendingParameterUpdates.length > 0 && {
362
+ parameterUpdates: pendingParameterUpdates
363
+ }
349
364
  };
350
365
  }
351
366
  const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
@@ -357,11 +372,21 @@ async function runSetupFlow(flow, params, ctx, config) {
357
372
  questionSlug: step.slug,
358
373
  question: step.question[ctx.language],
359
374
  questionType: step.type,
360
- options
375
+ options,
376
+ allowFreeText: resolvedAllowFreeText,
377
+ ...pendingParameterUpdates.length > 0 && {
378
+ parameterUpdates: pendingParameterUpdates
379
+ }
361
380
  };
362
381
  }
363
382
  const dataInvestigationResult = await flow.finalize(state, runtime);
364
- return { type: "fulfilled", dataInvestigationResult };
383
+ return {
384
+ type: "fulfilled",
385
+ dataInvestigationResult,
386
+ ...pendingParameterUpdates.length > 0 && {
387
+ parameterUpdates: pendingParameterUpdates
388
+ }
389
+ };
365
390
  }
366
391
  async function resolveSetupSelection(params) {
367
392
  const { selected, allSentinel, fetchAll, limit } = params;
@@ -184,19 +184,34 @@ async function runSetupFlow(flow, params, ctx, config) {
184
184
  };
185
185
  let state = flow.initialState();
186
186
  let answerIdx = 0;
187
+ const pendingParameterUpdates = [];
187
188
  for (const step of flow.steps) {
188
189
  const ans = ctx.answers[answerIdx];
189
190
  if (ans && ans.questionSlug === step.slug) {
190
191
  state = step.applyAnswer(state, ans.answer);
192
+ if (step.toParameterUpdates) {
193
+ pendingParameterUpdates.push(...step.toParameterUpdates(state));
194
+ }
191
195
  answerIdx += 1;
192
196
  continue;
193
197
  }
198
+ const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
194
199
  if (step.type === "text") {
200
+ if (step.fetchOptions) {
201
+ const options2 = await step.fetchOptions(state, runtime);
202
+ if (options2.length === 0) {
203
+ continue;
204
+ }
205
+ }
195
206
  return {
196
207
  type: "nextQuestion",
197
208
  questionSlug: step.slug,
198
209
  question: step.question[ctx.language],
199
- questionType: "text"
210
+ questionType: "text",
211
+ allowFreeText: resolvedAllowFreeText,
212
+ ...pendingParameterUpdates.length > 0 && {
213
+ parameterUpdates: pendingParameterUpdates
214
+ }
200
215
  };
201
216
  }
202
217
  const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
@@ -208,11 +223,21 @@ async function runSetupFlow(flow, params, ctx, config) {
208
223
  questionSlug: step.slug,
209
224
  question: step.question[ctx.language],
210
225
  questionType: step.type,
211
- options
226
+ options,
227
+ allowFreeText: resolvedAllowFreeText,
228
+ ...pendingParameterUpdates.length > 0 && {
229
+ parameterUpdates: pendingParameterUpdates
230
+ }
212
231
  };
213
232
  }
214
233
  const dataInvestigationResult = await flow.finalize(state, runtime);
215
- return { type: "fulfilled", dataInvestigationResult };
234
+ return {
235
+ type: "fulfilled",
236
+ dataInvestigationResult,
237
+ ...pendingParameterUpdates.length > 0 && {
238
+ parameterUpdates: pendingParameterUpdates
239
+ }
240
+ };
216
241
  }
217
242
  async function resolveSetupSelection(params) {
218
243
  const { selected, allSentinel, fetchAll, limit } = params;
@@ -348,19 +348,34 @@ async function runSetupFlow(flow, params, ctx, config) {
348
348
  };
349
349
  let state = flow.initialState();
350
350
  let answerIdx = 0;
351
+ const pendingParameterUpdates = [];
351
352
  for (const step of flow.steps) {
352
353
  const ans = ctx.answers[answerIdx];
353
354
  if (ans && ans.questionSlug === step.slug) {
354
355
  state = step.applyAnswer(state, ans.answer);
356
+ if (step.toParameterUpdates) {
357
+ pendingParameterUpdates.push(...step.toParameterUpdates(state));
358
+ }
355
359
  answerIdx += 1;
356
360
  continue;
357
361
  }
362
+ const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
358
363
  if (step.type === "text") {
364
+ if (step.fetchOptions) {
365
+ const options2 = await step.fetchOptions(state, runtime);
366
+ if (options2.length === 0) {
367
+ continue;
368
+ }
369
+ }
359
370
  return {
360
371
  type: "nextQuestion",
361
372
  questionSlug: step.slug,
362
373
  question: step.question[ctx.language],
363
- questionType: "text"
374
+ questionType: "text",
375
+ allowFreeText: resolvedAllowFreeText,
376
+ ...pendingParameterUpdates.length > 0 && {
377
+ parameterUpdates: pendingParameterUpdates
378
+ }
364
379
  };
365
380
  }
366
381
  const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
@@ -372,11 +387,21 @@ async function runSetupFlow(flow, params, ctx, config) {
372
387
  questionSlug: step.slug,
373
388
  question: step.question[ctx.language],
374
389
  questionType: step.type,
375
- options
390
+ options,
391
+ allowFreeText: resolvedAllowFreeText,
392
+ ...pendingParameterUpdates.length > 0 && {
393
+ parameterUpdates: pendingParameterUpdates
394
+ }
376
395
  };
377
396
  }
378
397
  const dataInvestigationResult = await flow.finalize(state, runtime);
379
- return { type: "fulfilled", dataInvestigationResult };
398
+ return {
399
+ type: "fulfilled",
400
+ dataInvestigationResult,
401
+ ...pendingParameterUpdates.length > 0 && {
402
+ parameterUpdates: pendingParameterUpdates
403
+ }
404
+ };
380
405
  }
381
406
  async function resolveSetupSelection(params) {
382
407
  const { selected, allSentinel, fetchAll, limit } = params;
@@ -611,19 +611,34 @@ 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") {
627
+ if (step.fetchOptions) {
628
+ const options2 = await step.fetchOptions(state, runtime);
629
+ if (options2.length === 0) {
630
+ continue;
631
+ }
632
+ }
622
633
  return {
623
634
  type: "nextQuestion",
624
635
  questionSlug: step.slug,
625
636
  question: step.question[ctx.language],
626
- questionType: "text"
637
+ questionType: "text",
638
+ allowFreeText: resolvedAllowFreeText,
639
+ ...pendingParameterUpdates.length > 0 && {
640
+ parameterUpdates: pendingParameterUpdates
641
+ }
627
642
  };
628
643
  }
629
644
  const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
@@ -635,11 +650,21 @@ async function runSetupFlow(flow, params, ctx, config) {
635
650
  questionSlug: step.slug,
636
651
  question: step.question[ctx.language],
637
652
  questionType: step.type,
638
- options
653
+ options,
654
+ allowFreeText: resolvedAllowFreeText,
655
+ ...pendingParameterUpdates.length > 0 && {
656
+ parameterUpdates: pendingParameterUpdates
657
+ }
639
658
  };
640
659
  }
641
660
  const dataInvestigationResult = await flow.finalize(state, runtime);
642
- return { type: "fulfilled", dataInvestigationResult };
661
+ return {
662
+ type: "fulfilled",
663
+ dataInvestigationResult,
664
+ ...pendingParameterUpdates.length > 0 && {
665
+ parameterUpdates: pendingParameterUpdates
666
+ }
667
+ };
643
668
  }
644
669
  async function resolveSetupSelection(params) {
645
670
  const { selected, allSentinel, fetchAll, limit } = params;
@@ -751,14 +776,15 @@ function isInternalOwner(name) {
751
776
  function quoteLiteral(value) {
752
777
  return "'" + value.replace(/'/g, "''") + "'";
753
778
  }
754
- async function fetchTableNames(params, owner) {
779
+ async function fetchTableAndViewNames(params, owner) {
755
780
  const rows = await runOracleSetupQuery(
756
781
  params,
757
- `SELECT TABLE_NAME FROM ALL_TABLES
758
- WHERE OWNER = ${quoteLiteral(owner)}
759
- ORDER BY TABLE_NAME`
782
+ `SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = ${quoteLiteral(owner)}
783
+ UNION
784
+ SELECT VIEW_NAME FROM ALL_VIEWS WHERE OWNER = ${quoteLiteral(owner)}
785
+ ORDER BY 1`
760
786
  );
761
- return rows.map((r) => String(r["TABLE_NAME"] ?? "")).filter((name) => name);
787
+ return rows.map((r) => String(r["TABLE_NAME"] ?? r["VIEW_NAME"] ?? "")).filter((name) => name);
762
788
  }
763
789
  var oracleSetupFlow = {
764
790
  initialState: () => ({}),
@@ -783,17 +809,17 @@ var oracleSetupFlow = {
783
809
  slug: "tables",
784
810
  type: "multiSelect",
785
811
  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)"
812
+ 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",
813
+ en: "Select target tables and views (multi-select allowed)"
788
814
  },
789
815
  async fetchOptions(state, rt) {
790
816
  if (!state.owner) return [];
791
- const names = await fetchTableNames(rt.params, state.owner);
817
+ const names = await fetchTableAndViewNames(rt.params, state.owner);
792
818
  const tableOptions = names.map((value) => ({ value }));
793
819
  return [
794
820
  {
795
821
  value: ALL_TABLES,
796
- label: rt.language === "ja" ? "\u3059\u3079\u3066\u306E\u30C6\u30FC\u30D6\u30EB" : "All tables"
822
+ label: rt.language === "ja" ? "\u3059\u3079\u3066\u306E\u30C6\u30FC\u30D6\u30EB\u30FB\u30D3\u30E5\u30FC" : "All tables and views"
797
823
  },
798
824
  ...tableOptions
799
825
  ];
@@ -809,9 +835,22 @@ var oracleSetupFlow = {
809
835
  const targetTables = await resolveSetupSelection({
810
836
  selected: state.tables,
811
837
  allSentinel: ALL_TABLES,
812
- fetchAll: () => fetchTableNames(rt.params, owner),
838
+ fetchAll: () => fetchTableAndViewNames(rt.params, owner),
813
839
  limit: ORACLE_SETUP_MAX_TABLES
814
840
  });
841
+ const typeRows = targetTables.length > 0 ? await runOracleSetupQuery(
842
+ rt.params,
843
+ `SELECT OBJECT_NAME, OBJECT_TYPE FROM ALL_OBJECTS
844
+ WHERE OWNER = ${quoteLiteral(owner)}
845
+ AND OBJECT_NAME IN (${targetTables.map(quoteLiteral).join(", ")})
846
+ AND OBJECT_TYPE IN ('TABLE', 'VIEW')`
847
+ ) : [];
848
+ const typeMap = new Map(
849
+ typeRows.map((r) => [
850
+ String(r["OBJECT_NAME"] ?? ""),
851
+ String(r["OBJECT_TYPE"] ?? "TABLE")
852
+ ])
853
+ );
815
854
  const sections = [
816
855
  "## Oracle Database",
817
856
  "",
@@ -819,6 +858,7 @@ var oracleSetupFlow = {
819
858
  ""
820
859
  ];
821
860
  for (const table of targetTables) {
861
+ const heading = typeMap.get(table) === "VIEW" ? "View" : "Table";
822
862
  const cols = await runOracleSetupQuery(
823
863
  rt.params,
824
864
  `SELECT COLUMN_NAME, DATA_TYPE, NULLABLE, DATA_DEFAULT
@@ -827,7 +867,7 @@ var oracleSetupFlow = {
827
867
  AND TABLE_NAME = ${quoteLiteral(table)}
828
868
  ORDER BY COLUMN_ID`
829
869
  );
830
- sections.push(`#### Table: ${table}`, "");
870
+ sections.push(`#### ${heading}: ${table}`, "");
831
871
  sections.push("| Column | Type | Nullable | Default |");
832
872
  sections.push("|--------|------|----------|---------|");
833
873
  for (const c of cols) {
@@ -298,19 +298,34 @@ 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") {
314
+ if (step.fetchOptions) {
315
+ const options2 = await step.fetchOptions(state, runtime);
316
+ if (options2.length === 0) {
317
+ continue;
318
+ }
319
+ }
309
320
  return {
310
321
  type: "nextQuestion",
311
322
  questionSlug: step.slug,
312
323
  question: step.question[ctx.language],
313
- questionType: "text"
324
+ questionType: "text",
325
+ allowFreeText: resolvedAllowFreeText,
326
+ ...pendingParameterUpdates.length > 0 && {
327
+ parameterUpdates: pendingParameterUpdates
328
+ }
314
329
  };
315
330
  }
316
331
  const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
@@ -322,11 +337,21 @@ async function runSetupFlow(flow, params, ctx, config) {
322
337
  questionSlug: step.slug,
323
338
  question: step.question[ctx.language],
324
339
  questionType: step.type,
325
- options
340
+ options,
341
+ allowFreeText: resolvedAllowFreeText,
342
+ ...pendingParameterUpdates.length > 0 && {
343
+ parameterUpdates: pendingParameterUpdates
344
+ }
326
345
  };
327
346
  }
328
347
  const dataInvestigationResult = await flow.finalize(state, runtime);
329
- return { type: "fulfilled", dataInvestigationResult };
348
+ return {
349
+ type: "fulfilled",
350
+ dataInvestigationResult,
351
+ ...pendingParameterUpdates.length > 0 && {
352
+ parameterUpdates: pendingParameterUpdates
353
+ }
354
+ };
330
355
  }
331
356
  async function resolveSetupSelection(params) {
332
357
  const { selected, allSentinel, fetchAll, limit } = params;