@teamkeel/functions-runtime 0.414.4 → 0.414.5

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.
package/dist/index.cjs CHANGED
@@ -2421,20 +2421,30 @@ var markdown = /* @__PURE__ */ __name((options) => {
2421
2421
 
2422
2422
  // src/flows/ui/elements/display/table.ts
2423
2423
  var table = /* @__PURE__ */ __name((options) => {
2424
- const filteredData = options.columns ? options.data.map((item) => {
2425
- return Object.fromEntries(
2426
- Object.entries(item).filter(
2427
- ([key]) => options.columns?.includes(key)
2428
- )
2429
- );
2430
- }) : options.data;
2424
+ const { data, columns } = processTableData(options.data, options.columns);
2431
2425
  return {
2432
2426
  uiConfig: {
2433
2427
  __type: "ui.display.table",
2434
- data: filteredData || []
2428
+ data: data || [],
2429
+ columns: columns || []
2435
2430
  }
2436
2431
  };
2437
2432
  }, "table");
2433
+ var processTableData = /* @__PURE__ */ __name((data, columnsConfig) => {
2434
+ const filteredData = columnsConfig ? data.map((item) => {
2435
+ return Object.fromEntries(
2436
+ Object.entries(item).filter(
2437
+ ([key]) => columnsConfig?.includes(key)
2438
+ )
2439
+ );
2440
+ }) : data;
2441
+ const cols = Object.keys(filteredData[0] || {});
2442
+ const columns = cols.map((column, index) => ({
2443
+ name: column,
2444
+ index
2445
+ }));
2446
+ return { data: filteredData, columns };
2447
+ }, "processTableData");
2438
2448
 
2439
2449
  // src/flows/ui/elements/select/one.ts
2440
2450
  var selectOne = /* @__PURE__ */ __name((name, options) => {
@@ -2459,24 +2469,28 @@ var selectOne = /* @__PURE__ */ __name((name, options) => {
2459
2469
  async function page(options, data, action) {
2460
2470
  const content = options.content;
2461
2471
  let hasValidationErrors = false;
2462
- if (options.actions) {
2472
+ let validationError;
2473
+ if (options.actions && action !== null) {
2463
2474
  const isValidAction = options.actions.some((a) => {
2464
2475
  if (typeof a === "string") return a === action;
2465
2476
  return a && typeof a === "object" && "value" in a && a.value === action;
2466
2477
  });
2467
- hasValidationErrors = !isValidAction;
2478
+ if (!isValidAction) {
2479
+ hasValidationErrors = true;
2480
+ validationError = "invalid action";
2481
+ }
2468
2482
  }
2469
2483
  const contentUiConfig = await Promise.all(
2470
2484
  content.map(async (c) => {
2471
2485
  const isInput = "__type" in c && c.__type == "input";
2472
2486
  const hasData = data && c.uiConfig.name in data;
2473
2487
  if (isInput && hasData && c.validate) {
2474
- const validationError = await c.validate(data[c.uiConfig.name]);
2475
- if (typeof validationError === "string") {
2488
+ const validationError2 = await c.validate(data[c.uiConfig.name]);
2489
+ if (typeof validationError2 === "string") {
2476
2490
  hasValidationErrors = true;
2477
2491
  return {
2478
2492
  ...c.uiConfig,
2479
- validationError
2493
+ validationError: validationError2
2480
2494
  };
2481
2495
  }
2482
2496
  }
@@ -2497,7 +2511,9 @@ async function page(options, data, action) {
2497
2511
  a.mode = a.mode || "primary";
2498
2512
  }
2499
2513
  return a;
2500
- })
2514
+ }),
2515
+ hasValidationErrors,
2516
+ validationError
2501
2517
  },
2502
2518
  hasValidationErrors
2503
2519
  };
@@ -2632,6 +2648,79 @@ var keyValue = /* @__PURE__ */ __name((options) => {
2632
2648
  };
2633
2649
  }, "keyValue");
2634
2650
 
2651
+ // src/flows/ui/elements/select/table.ts
2652
+ var selectTable = /* @__PURE__ */ __name((name, options) => {
2653
+ const { data, columns } = processTableData(options.data, options.columns);
2654
+ return {
2655
+ __type: "input",
2656
+ uiConfig: {
2657
+ __type: "ui.select.table",
2658
+ name,
2659
+ data,
2660
+ columns,
2661
+ mode: options?.mode || "multi",
2662
+ optional: options?.optional || false,
2663
+ disabled: options?.disabled || false,
2664
+ helpText: options?.helpText
2665
+ },
2666
+ validate: options?.validate,
2667
+ getData: /* @__PURE__ */ __name((x) => x, "getData")
2668
+ };
2669
+ }, "selectTable");
2670
+
2671
+ // src/flows/ui/elements/input/dataGrid.ts
2672
+ var import_change_case2 = require("change-case");
2673
+ var dataGridInput = /* @__PURE__ */ __name((name, options) => {
2674
+ const { data } = processTableData(
2675
+ options.data,
2676
+ options.columns?.map((c) => c.key)
2677
+ );
2678
+ const inferType = /* @__PURE__ */ __name((key) => {
2679
+ const inferredTypeRaw = typeof data[0][key];
2680
+ const inferredTypeMap = {
2681
+ string: "text",
2682
+ number: "number",
2683
+ boolean: "boolean",
2684
+ bigint: "number",
2685
+ symbol: "text",
2686
+ undefined: "text",
2687
+ object: "text",
2688
+ function: "text"
2689
+ };
2690
+ return inferredTypeMap[inferredTypeRaw] ?? "text";
2691
+ }, "inferType");
2692
+ const columns = options.columns ? options.columns?.map((column, idx) => ({
2693
+ key: column.key,
2694
+ label: column.label || column.key,
2695
+ index: idx,
2696
+ type: column.type || inferType(column.key),
2697
+ editable: column.editable === void 0 ? column.type === "id" ? false : true : column.editable
2698
+ })) : Object.keys(data[0]).map((key, idx) => {
2699
+ return {
2700
+ index: idx,
2701
+ key,
2702
+ label: (0, import_change_case2.sentenceCase)(key),
2703
+ type: inferType(key),
2704
+ editable: true
2705
+ };
2706
+ });
2707
+ return {
2708
+ __type: "input",
2709
+ uiConfig: {
2710
+ __type: "ui.input.dataGrid",
2711
+ name,
2712
+ data,
2713
+ columns,
2714
+ helpText: options?.helpText,
2715
+ allowAddRows: options?.allowAddRows ?? false,
2716
+ allowDeleteRows: options?.allowDeleteRows ?? false
2717
+ },
2718
+ validate: options?.validate,
2719
+ // TODO have some built in validation that checks the types of the response
2720
+ getData: /* @__PURE__ */ __name((x) => x, "getData")
2721
+ };
2722
+ }, "dataGridInput");
2723
+
2635
2724
  // src/flows/index.ts
2636
2725
  var STEP_STATUS = /* @__PURE__ */ ((STEP_STATUS2) => {
2637
2726
  STEP_STATUS2["NEW"] = "NEW";
@@ -2659,7 +2748,12 @@ function createFlowContext(runId, data, action, spanId, ctx) {
2659
2748
  env: ctx.env,
2660
2749
  now: ctx.now,
2661
2750
  secrets: ctx.secrets,
2662
- complete: /* @__PURE__ */ __name((options) => options, "complete"),
2751
+ complete: /* @__PURE__ */ __name((options) => {
2752
+ return {
2753
+ __type: "ui.complete",
2754
+ ...options
2755
+ };
2756
+ }, "complete"),
2663
2757
  step: /* @__PURE__ */ __name(async (name, optionsOrFn, fn) => {
2664
2758
  const options = typeof optionsOrFn === "function" ? {} : optionsOrFn;
2665
2759
  const actualFn = typeof optionsOrFn === "function" ? optionsOrFn : fn;
@@ -2806,7 +2900,8 @@ function createFlowContext(runId, data, action, spanId, ctx) {
2806
2900
  inputs: {
2807
2901
  text: textInput,
2808
2902
  number: numberInput,
2809
- boolean: booleanInput
2903
+ boolean: booleanInput,
2904
+ dataGrid: dataGridInput
2810
2905
  },
2811
2906
  display: {
2812
2907
  divider,
@@ -2821,7 +2916,8 @@ function createFlowContext(runId, data, action, spanId, ctx) {
2821
2916
  keyValue
2822
2917
  },
2823
2918
  select: {
2824
- one: selectOne
2919
+ one: selectOne,
2920
+ table: selectTable
2825
2921
  }
2826
2922
  }
2827
2923
  };
@@ -2843,26 +2939,25 @@ __name(withTimeout, "withTimeout");
2843
2939
 
2844
2940
  // src/flows/ui/complete.ts
2845
2941
  async function complete(options) {
2846
- const content = options.content;
2942
+ const content = options.content || [];
2847
2943
  const contentUiConfig = await Promise.all(
2848
2944
  content.map(async (c) => {
2849
2945
  return c.uiConfig;
2850
2946
  })
2851
2947
  );
2852
2948
  return {
2853
- complete: {
2854
- __type: "ui.complete",
2855
- stage: options.stage,
2856
- title: options.title,
2857
- description: options.description,
2858
- content: contentUiConfig
2859
- }
2949
+ __type: "ui.complete",
2950
+ stage: options.stage,
2951
+ title: options.title,
2952
+ description: options.description,
2953
+ content: contentUiConfig || [],
2954
+ autoClose: options.autoClose
2860
2955
  };
2861
2956
  }
2862
2957
  __name(complete, "complete");
2863
2958
 
2864
2959
  // src/handleFlow.ts
2865
- var import_change_case2 = require("change-case");
2960
+ var import_change_case3 = require("change-case");
2866
2961
  async function handleFlow(request, config) {
2867
2962
  const activeContext = opentelemetry6.propagation.extract(
2868
2963
  opentelemetry6.context.active(),
@@ -2906,7 +3001,7 @@ async function handleFlow(request, config) {
2906
3001
  const rawFlowConfig = flows[request.method].config;
2907
3002
  flowConfig = {
2908
3003
  ...rawFlowConfig,
2909
- title: rawFlowConfig.title || (0, import_change_case2.sentenceCase)(request.method || "flow"),
3004
+ title: rawFlowConfig.title || (0, import_change_case3.sentenceCase)(request.method || "flow"),
2910
3005
  stages: rawFlowConfig.stages?.map((stage) => {
2911
3006
  if (typeof stage === "string") {
2912
3007
  return {
@@ -2961,7 +3056,8 @@ async function handleFlow(request, config) {
2961
3056
  }
2962
3057
  let ui = null;
2963
3058
  let data = null;
2964
- if (response && typeof response == "object" && "content" in response) {
3059
+ if (response && typeof response == "object" && "__type" in response && response.__type === "ui.complete") {
3060
+ ui = await complete(response);
2965
3061
  const completeStep = await db.selectFrom("keel.flow_step").where("run_id", "=", runId).where("type", "=", "COMPLETE" /* COMPLETE */).selectAll().executeTakeFirst();
2966
3062
  if (!completeStep) {
2967
3063
  await db.insertInto("keel.flow_step").values({
@@ -2971,10 +3067,10 @@ async function handleFlow(request, config) {
2971
3067
  status: "COMPLETED" /* COMPLETED */,
2972
3068
  type: "COMPLETE" /* COMPLETE */,
2973
3069
  startTime: /* @__PURE__ */ new Date(),
2974
- endTime: /* @__PURE__ */ new Date()
3070
+ endTime: /* @__PURE__ */ new Date(),
3071
+ ui: JSON.stringify(ui)
2975
3072
  }).returningAll().executeTakeFirst();
2976
3073
  }
2977
- ui = (await complete(response)).complete;
2978
3074
  data = response.data;
2979
3075
  } else if (response) {
2980
3076
  data = response;
@@ -2983,8 +3079,7 @@ async function handleFlow(request, config) {
2983
3079
  runId,
2984
3080
  runCompleted: true,
2985
3081
  data,
2986
- config: flowConfig,
2987
- ui
3082
+ config: flowConfig
2988
3083
  });
2989
3084
  } catch (e) {
2990
3085
  if (e instanceof Error) {