@pipe0/react 0.2.0 → 0.2.1

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 (98) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/components/compound/pipe-form/errors.d.mts.map +1 -1
  3. package/dist/components/compound/pipe-form/errors.mjs +5 -4
  4. package/dist/components/compound/pipe-form/errors.mjs.map +1 -1
  5. package/dist/components/compound/pipe-form/root.d.mts +3 -1
  6. package/dist/components/compound/pipe-form/root.d.mts.map +1 -1
  7. package/dist/components/compound/pipe-form/root.mjs +5 -3
  8. package/dist/components/compound/pipe-form/root.mjs.map +1 -1
  9. package/dist/components/compound/search-form/errors.d.mts.map +1 -1
  10. package/dist/components/compound/search-form/errors.mjs +5 -4
  11. package/dist/components/compound/search-form/errors.mjs.map +1 -1
  12. package/dist/components/compound/search-form/root.d.mts +3 -1
  13. package/dist/components/compound/search-form/root.d.mts.map +1 -1
  14. package/dist/components/compound/search-form/root.mjs +5 -3
  15. package/dist/components/compound/search-form/root.mjs.map +1 -1
  16. package/dist/components/defaults/adapters/context-select-input.mjs +1 -1
  17. package/dist/components/defaults/adapters/context-select-input.mjs.map +1 -1
  18. package/dist/components/defaults/adapters/index.d.mts.map +1 -1
  19. package/dist/components/defaults/adapters/index.mjs +8 -5
  20. package/dist/components/defaults/adapters/index.mjs.map +1 -1
  21. package/dist/components/defaults/adapters/int-input.mjs.map +1 -1
  22. package/dist/components/defaults/adapters/loose-object-input.mjs +111 -0
  23. package/dist/components/defaults/adapters/loose-object-input.mjs.map +1 -0
  24. package/dist/components/defaults/adapters/pipes-run-if-input.mjs +68 -55
  25. package/dist/components/defaults/adapters/pipes-run-if-input.mjs.map +1 -1
  26. package/dist/components/defaults/adapters/providers-input.mjs.map +1 -1
  27. package/dist/components/defaults/adapters/search-payload-input.mjs +18 -0
  28. package/dist/components/defaults/adapters/search-payload-input.mjs.map +1 -0
  29. package/dist/components/defaults/adapters/select-input.mjs +46 -27
  30. package/dist/components/defaults/adapters/select-input.mjs.map +1 -1
  31. package/dist/components/defaults/catalog/card-derived.d.mts +1 -1
  32. package/dist/components/defaults/catalog/card-derived.d.mts.map +1 -1
  33. package/dist/components/defaults/catalog/card-derived.mjs +6 -2
  34. package/dist/components/defaults/catalog/card-derived.mjs.map +1 -1
  35. package/dist/components/defaults/layout/field-wrapper.d.mts.map +1 -1
  36. package/dist/components/defaults/layout/field-wrapper.mjs +11 -5
  37. package/dist/components/defaults/layout/field-wrapper.mjs.map +1 -1
  38. package/dist/components/defaults/layout/group.mjs +1 -1
  39. package/dist/components/internal/LiquidEditor/LiquidEditor.mjs.map +1 -1
  40. package/dist/components/internal/form-level-errors.mjs +4 -3
  41. package/dist/components/internal/form-level-errors.mjs.map +1 -1
  42. package/dist/components/internal/icons.mjs +27 -1
  43. package/dist/components/internal/icons.mjs.map +1 -1
  44. package/dist/components/ui/alert.d.mts +47 -0
  45. package/dist/components/ui/alert.d.mts.map +1 -0
  46. package/dist/components/ui/alert.mjs +66 -0
  47. package/dist/components/ui/alert.mjs.map +1 -0
  48. package/dist/context/form-context.d.mts +21 -0
  49. package/dist/context/form-context.d.mts.map +1 -0
  50. package/dist/context/form-context.mjs +11 -1
  51. package/dist/context/form-context.mjs.map +1 -1
  52. package/dist/context/form-provider.d.mts +3 -1
  53. package/dist/context/form-provider.d.mts.map +1 -1
  54. package/dist/context/form-provider.mjs +8 -2
  55. package/dist/context/form-provider.mjs.map +1 -1
  56. package/dist/hooks/use-effect-catalog-table.d.mts.map +1 -1
  57. package/dist/hooks/use-effect-catalog-table.mjs +2 -2
  58. package/dist/hooks/use-effect-catalog-table.mjs.map +1 -1
  59. package/dist/hooks/use-form-core.mjs +7 -4
  60. package/dist/hooks/use-form-core.mjs.map +1 -1
  61. package/dist/hooks/use-pipe-catalog-table.d.mts +8 -8
  62. package/dist/hooks/use-pipe-catalog-table.d.mts.map +1 -1
  63. package/dist/hooks/use-pipe-catalog-table.mjs +2 -2
  64. package/dist/hooks/use-pipe-catalog-table.mjs.map +1 -1
  65. package/dist/hooks/use-pipe-form.d.mts.map +1 -1
  66. package/dist/hooks/use-pipe-form.mjs +18 -19
  67. package/dist/hooks/use-pipe-form.mjs.map +1 -1
  68. package/dist/hooks/use-search-catalog-table.d.mts +6 -6
  69. package/dist/hooks/use-search-form.d.mts.map +1 -1
  70. package/dist/hooks/use-search-form.mjs +18 -18
  71. package/dist/hooks/use-search-form.mjs.map +1 -1
  72. package/dist/hooks/use-sheet-effect-form.d.mts.map +1 -1
  73. package/dist/hooks/use-sheet-effect-form.mjs +18 -19
  74. package/dist/hooks/use-sheet-effect-form.mjs.map +1 -1
  75. package/dist/index.d.mts +4 -2
  76. package/dist/index.mjs +3 -1
  77. package/dist/styles/pipe0-form.css +1 -1
  78. package/dist/types/adapters.d.mts +22 -1
  79. package/dist/types/adapters.d.mts.map +1 -1
  80. package/dist/types/catalog-adapters.d.mts +1 -1
  81. package/dist/types/field-props.d.mts +15 -13
  82. package/dist/types/field-props.d.mts.map +1 -1
  83. package/dist/types/form-customization.d.mts +2 -25
  84. package/dist/utils/build-section-handlers.mjs +7 -73
  85. package/dist/utils/build-section-handlers.mjs.map +1 -1
  86. package/dist/widgets/token-pricing-badge.d.mts +1 -0
  87. package/dist/widgets/token-pricing-badge.mjs +55 -0
  88. package/dist/widgets/token-pricing-badge.mjs.map +1 -0
  89. package/dist/widgets/widget-strip.d.mts.map +1 -1
  90. package/dist/widgets/widget-strip.mjs +1 -0
  91. package/dist/widgets/widget-strip.mjs.map +1 -1
  92. package/dist/widgets/widget-view.d.mts.map +1 -1
  93. package/dist/widgets/widget-view.mjs +6 -0
  94. package/dist/widgets/widget-view.mjs.map +1 -1
  95. package/package.json +2 -2
  96. package/dist/components/defaults/adapters/key-value-list-input.mjs +0 -102
  97. package/dist/components/defaults/adapters/key-value-list-input.mjs.map +0 -1
  98. package/dist/types/form-customization.d.mts.map +0 -1
@@ -1,4 +1,4 @@
1
- import { FieldAdapterMap, FormClassNames } from "../types/adapters.mjs";
1
+ import { FieldAdapterMap, FormClassNames, FormComponents } from "../types/adapters.mjs";
2
2
  import { ReactNode } from "react";
3
3
  import * as _$react_jsx_runtime0 from "react/jsx-runtime";
4
4
 
@@ -16,6 +16,7 @@ declare function FormRoot({
16
16
  interface FormProviderProps {
17
17
  classNames?: FormClassNames;
18
18
  adapters?: FieldAdapterMap;
19
+ components?: FormComponents;
19
20
  children: ReactNode;
20
21
  }
21
22
  /**
@@ -34,6 +35,7 @@ interface FormProviderProps {
34
35
  declare function FormProvider({
35
36
  classNames,
36
37
  adapters,
38
+ components,
37
39
  children
38
40
  }: FormProviderProps): _$react_jsx_runtime0.JSX.Element;
39
41
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"form-provider.d.mts","names":[],"sources":["../../src/context/form-provider.tsx"],"mappings":";;;;;;;;AAUA;;iBAAgB,QAAA,CAAA;EAAW;AAAA;EAAc,QAAA,EAAU,SAAA;AAAA,IAAW,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,UAI7C,iBAAA;EACf,UAAA,GAAa,cAAA;EACb,QAAA,GAAW,eAAA;EACX,QAAA,EAAU,SAAA;AAAA;;;;;;;AAHZ;;;;;;;iBAmBgB,YAAA,CAAA;EAAe,UAAA;EAAY,QAAA;EAAU;AAAA,GAAY,iBAAA,GAAiB,oBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"form-provider.d.mts","names":[],"sources":["../../src/context/form-provider.tsx"],"mappings":";;;;;;;;AAUA;;iBAAgB,QAAA,CAAA;EAAW;AAAA;EAAc,QAAA,EAAU,SAAA;AAAA,IAAW,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,UAI7C,iBAAA;EACf,UAAA,GAAa,cAAA;EACb,QAAA,GAAW,eAAA;EACX,UAAA,GAAa,cAAA;EACb,QAAA,EAAU,SAAA;AAAA;;;;;;AAJZ;;;;;;;;iBAoBgB,YAAA,CAAA;EAAe,UAAA;EAAY,QAAA;EAAU,UAAA;EAAY;AAAA,GAAY,iBAAA,GAAiB,oBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -25,7 +25,7 @@ function FormRoot({ children }) {
25
25
  * </FormProvider>
26
26
  * ```
27
27
  */
28
- function FormProvider({ classNames, adapters, children }) {
28
+ function FormProvider({ classNames, adapters, components, children }) {
29
29
  const parent = useFormConfig();
30
30
  const merged = useMemo(() => ({
31
31
  classNames: {
@@ -35,12 +35,18 @@ function FormProvider({ classNames, adapters, children }) {
35
35
  adapters: {
36
36
  ...parent.adapters,
37
37
  ...adapters
38
+ },
39
+ components: {
40
+ ...parent.components,
41
+ ...components
38
42
  }
39
43
  }), [
40
44
  parent.classNames,
41
45
  parent.adapters,
46
+ parent.components,
42
47
  classNames,
43
- adapters
48
+ adapters,
49
+ components
44
50
  ]);
45
51
  return /* @__PURE__ */ jsx(FormConfigContext.Provider, {
46
52
  value: merged,
@@ -1 +1 @@
1
- {"version":3,"file":"form-provider.mjs","names":[],"sources":["../../src/context/form-provider.tsx"],"sourcesContent":["import { type ReactNode, useMemo } from \"react\";\nimport { TooltipProvider } from \"../components/ui/tooltip.js\";\nimport type { FieldAdapterMap, FormClassNames } from \"../types/adapters.js\";\nimport { FormConfigContext, useFormConfig } from \"./form-context.js\";\n\n/**\n * Root-level providers required by any form component tree (tooltips, etc.).\n * Always mounted by `<PipeForm>` and `<SearchForm>` at the outermost layer,\n * independent of the optional customization `FormProvider`.\n */\nexport function FormRoot({ children }: { children: ReactNode }) {\n return <TooltipProvider>{children}</TooltipProvider>;\n}\n\nexport interface FormProviderProps {\n classNames?: FormClassNames;\n adapters?: FieldAdapterMap;\n children: ReactNode;\n}\n\n/**\n * Provides customization context to `<PipeForm>` and `<SearchForm>`.\n * Providers nest — inner overrides outer.\n *\n * ```tsx\n * <FormProvider\n * classNames={{ label: \"font-bold\" }}\n * adapters={{ text_input: (f) => <MyInput {...f.inputProps} /> }}\n * >\n * <PipeForm ... />\n * </FormProvider>\n * ```\n */\nexport function FormProvider({ classNames, adapters, children }: FormProviderProps) {\n const parent = useFormConfig();\n\n const merged = useMemo(\n () => ({\n classNames: { ...parent.classNames, ...classNames },\n adapters: { ...parent.adapters, ...adapters },\n }),\n [parent.classNames, parent.adapters, classNames, adapters],\n );\n\n return <FormConfigContext.Provider value={merged}>{children}</FormConfigContext.Provider>;\n}\n"],"mappings":";;;;;;;;;;;AAUA,SAAgB,SAAS,EAAE,YAAqC;AAC9D,QAAO,oBAAC,iBAAD,EAAkB,UAA2B;;;;;;;;;;;;;;;AAsBtD,SAAgB,aAAa,EAAE,YAAY,UAAU,YAA+B;CAClF,MAAM,SAAS,eAAe;CAE9B,MAAM,SAAS,eACN;EACL,YAAY;GAAE,GAAG,OAAO;GAAY,GAAG;GAAY;EACnD,UAAU;GAAE,GAAG,OAAO;GAAU,GAAG;GAAU;EAC9C,GACD;EAAC,OAAO;EAAY,OAAO;EAAU;EAAY;EAAS,CAC3D;AAED,QAAO,oBAAC,kBAAkB,UAAnB;EAA4B,OAAO;EAAS;EAAsC"}
1
+ {"version":3,"file":"form-provider.mjs","names":[],"sources":["../../src/context/form-provider.tsx"],"sourcesContent":["import { type ReactNode, useMemo } from \"react\";\nimport { TooltipProvider } from \"../components/ui/tooltip.js\";\nimport type { FieldAdapterMap, FormClassNames, FormComponents } from \"../types/adapters.js\";\nimport { FormConfigContext, useFormConfig } from \"./form-context.js\";\n\n/**\n * Root-level providers required by any form component tree (tooltips, etc.).\n * Always mounted by `<PipeForm>` and `<SearchForm>` at the outermost layer,\n * independent of the optional customization `FormProvider`.\n */\nexport function FormRoot({ children }: { children: ReactNode }) {\n return <TooltipProvider>{children}</TooltipProvider>;\n}\n\nexport interface FormProviderProps {\n classNames?: FormClassNames;\n adapters?: FieldAdapterMap;\n components?: FormComponents;\n children: ReactNode;\n}\n\n/**\n * Provides customization context to `<PipeForm>` and `<SearchForm>`.\n * Providers nest — inner overrides outer.\n *\n * ```tsx\n * <FormProvider\n * classNames={{ label: \"font-bold\" }}\n * adapters={{ text_input: (f) => <MyInput {...f.inputProps} /> }}\n * >\n * <PipeForm ... />\n * </FormProvider>\n * ```\n */\nexport function FormProvider({ classNames, adapters, components, children }: FormProviderProps) {\n const parent = useFormConfig();\n\n const merged = useMemo(\n () => ({\n classNames: { ...parent.classNames, ...classNames },\n adapters: { ...parent.adapters, ...adapters },\n components: { ...parent.components, ...components },\n }),\n [parent.classNames, parent.adapters, parent.components, classNames, adapters, components],\n );\n\n return <FormConfigContext.Provider value={merged}>{children}</FormConfigContext.Provider>;\n}\n"],"mappings":";;;;;;;;;;;AAUA,SAAgB,SAAS,EAAE,YAAqC;AAC9D,QAAO,oBAAC,iBAAD,EAAkB,UAA2B;;;;;;;;;;;;;;;AAuBtD,SAAgB,aAAa,EAAE,YAAY,UAAU,YAAY,YAA+B;CAC9F,MAAM,SAAS,eAAe;CAE9B,MAAM,SAAS,eACN;EACL,YAAY;GAAE,GAAG,OAAO;GAAY,GAAG;GAAY;EACnD,UAAU;GAAE,GAAG,OAAO;GAAU,GAAG;GAAU;EAC7C,YAAY;GAAE,GAAG,OAAO;GAAY,GAAG;GAAY;EACpD,GACD;EAAC,OAAO;EAAY,OAAO;EAAU,OAAO;EAAY;EAAY;EAAU;EAAW,CAC1F;AAED,QAAO,oBAAC,kBAAkB,UAAnB;EAA4B,OAAO;EAAS;EAAsC"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-effect-catalog-table.d.mts","names":[],"sources":["../../src/hooks/use-effect-catalog-table.ts"],"mappings":";;;;;;;iBAoCgB,qBAAA,CACd,MAAA;EACE,oBAAA,GAAuB,YAAA;;;AAF3B;;EAOI,MAAA,IAAU,KAAA,EAAO,2BAAA;AAAA;;;;cA6EL,mBAAA;WAA4B,cAAA;EAAA;;;;;sBA9BjC,mBAAA;;yCAAmB,OAAA,CAAA,cAAA;AAAA;AAAA,KAiFlB,2BAAA,GAA8B,UAAA,QAAkB,qBAAA"}
1
+ {"version":3,"file":"use-effect-catalog-table.d.mts","names":[],"sources":["../../src/hooks/use-effect-catalog-table.ts"],"mappings":";;;;;;;iBAqCgB,qBAAA,CACd,MAAA;EACE,oBAAA,GAAuB,YAAA;;;AAF3B;;EAOI,MAAA,IAAU,KAAA,EAAO,2BAAA;AAAA;;;;cA+EL,mBAAA;WAA4B,cAAA;EAAA;;;;;sBAhCjC,mBAAA;;yCAAmB,OAAA,CAAA,cAAA;AAAA;AAAA,KAmFlB,2BAAA,GAA8B,UAAA,QAAkB,qBAAA"}
@@ -1,7 +1,7 @@
1
1
  import { fuzzyFilter } from "../utils/catalog-helpers.mjs";
2
2
  import { useDebounce } from "./use-debounce.mjs";
3
3
  import { useCallback, useMemo, useState } from "react";
4
- import { getInitialSheetEffectTableData, getLowestSheetEffectCreditAmount } from "@pipe0/base";
4
+ import { getInitialSheetEffectTableData, getLowestSheetEffectCreditAmount, isTokenBilledOperations } from "@pipe0/base";
5
5
  import { createColumnHelper, getCoreRowModel, getFilteredRowModel, useReactTable } from "@tanstack/react-table";
6
6
 
7
7
  //#region src/hooks/use-effect-catalog-table.ts
@@ -58,7 +58,7 @@ function useEffectCatalogTable(config = {}) {
58
58
  provider,
59
59
  providers: entry.managedProviders.length ? entry.managedProviders : [provider],
60
60
  startingCreditAmount: getLowestSheetEffectCreditAmount(entry),
61
- costMode: "per_result",
61
+ costMode: isTokenBilledOperations(entry.billableOperations) ? "usage" : "per_result",
62
62
  selectionMode: entry.selectionMode,
63
63
  entry
64
64
  };
@@ -1 +1 @@
1
- {"version":3,"file":"use-effect-catalog-table.mjs","names":[],"sources":["../../src/hooks/use-effect-catalog-table.ts"],"sourcesContent":["import {\n getInitialSheetEffectTableData,\n getLowestSheetEffectCreditAmount,\n type ProviderName,\n type SheetEffectCatalogTableData,\n type SheetEffectCategory,\n} from \"@pipe0/base\";\nimport {\n type ColumnFilter,\n createColumnHelper,\n getCoreRowModel,\n getFilteredRowModel,\n useReactTable,\n} from \"@tanstack/react-table\";\nimport { useCallback, useMemo, useState } from \"react\";\nimport type { EffectCardData } from \"../types/catalog-adapters.js\";\nimport { fuzzyFilter } from \"../utils/catalog-helpers.js\";\nimport { useDebounce } from \"./use-debounce.js\";\n\nconst columnHelper = createColumnHelper<SheetEffectCatalogTableData>();\n\nconst columns = [\n columnHelper.accessor(\"effectId\", {\n filterFn: \"includesString\",\n enableGlobalFilter: true,\n }),\n columnHelper.accessor(\"description\", {\n filterFn: \"fuzzy\" as any,\n enableGlobalFilter: true,\n }),\n columnHelper.accessor(\"label\", {\n filterFn: \"includesString\",\n enableGlobalFilter: true,\n }),\n];\n\nexport function useEffectCatalogTable(\n config: {\n initialColumnFilters?: ColumnFilter[];\n /**\n * Optional predicate to pre-filter the catalog (e.g. by `selectionMode`\n * for the current row selection). Memoize it to keep the table stable.\n */\n filter?: (entry: SheetEffectCatalogTableData) => boolean;\n } = {},\n) {\n const [category, setCategory] = useState<SheetEffectCategory | null>(null);\n const { initialColumnFilters = [] as ColumnFilter[], filter } = config;\n\n // Baseline (config.filter applied, but no category / global filter). Drives\n // the stable category-button counts so the row doesn't jump.\n const baselineTableData = useMemo(\n () =>\n filter ? getInitialSheetEffectTableData().filter(filter) : getInitialSheetEffectTableData(),\n [filter],\n );\n\n const initialEffectTableData = useMemo(\n () =>\n category\n ? baselineTableData.filter((e) => (e.categories ?? []).includes(category))\n : baselineTableData,\n [baselineTableData, category],\n );\n\n const table = useReactTable({\n columns,\n data: initialEffectTableData,\n getCoreRowModel: getCoreRowModel(),\n getFilteredRowModel: getFilteredRowModel(),\n globalFilterFn: fuzzyFilter,\n filterFns: {\n fuzzy: fuzzyFilter,\n },\n getColumnCanGlobalFilter: (column) => column.columnDef.enableGlobalFilter !== false,\n initialState: {\n columnFilters: initialColumnFilters,\n pagination: {\n pageSize: 10,\n },\n },\n });\n\n const [globalFilterInput, setGlobalFilterInput, setGlobalFilterImmediately] = useDebounce((v) => {\n if (v === table.getState().globalFilter) return;\n table.setGlobalFilter(v);\n if (v) setCategory(null);\n });\n\n const handleCategoryChange = useCallback(\n (next: SheetEffectCategory | null) => {\n setCategory(next);\n setGlobalFilterImmediately(\"\");\n },\n [setGlobalFilterImmediately],\n );\n\n const rows = table.getRowModel().rows;\n const cards = useMemo<EffectCardData[]>(\n () =>\n rows.map((row) => {\n const entry = row.original;\n const provider = (entry.managedProviders[0] ?? \"pipe0\") as ProviderName;\n return {\n effectId: entry.effectId,\n baseEffect: entry.baseEffect,\n label: entry.label,\n description: entry.description,\n provider,\n providers: entry.managedProviders.length ? entry.managedProviders : [provider],\n startingCreditAmount: getLowestSheetEffectCreditAmount(entry),\n costMode: \"per_result\" as const,\n selectionMode: entry.selectionMode,\n entry,\n };\n }),\n [rows],\n );\n\n const cardsByCategory = useMemo<\n { category: SheetEffectCategory; cards: EffectCardData[] }[]\n >(() => {\n const groups = new Map<SheetEffectCategory, EffectCardData[]>();\n for (const card of cards) {\n const cats = (card.entry.categories ?? []) as SheetEffectCategory[];\n for (const cat of cats) {\n const arr = groups.get(cat);\n if (arr) arr.push(card);\n else groups.set(cat, [card]);\n }\n }\n return Array.from(groups, ([category, group]) => ({ category, cards: group }));\n }, [cards]);\n\n const categoryCounts = useMemo<Partial<Record<SheetEffectCategory, number>>>(() => {\n const counts: Partial<Record<SheetEffectCategory, number>> = {};\n for (const card of cards) {\n for (const cat of (card.entry.categories ?? []) as SheetEffectCategory[]) {\n counts[cat] = (counts[cat] ?? 0) + 1;\n }\n }\n return counts;\n }, [cards]);\n\n // Stable counts based on the baseline (no category / global filter applied).\n const baselineCardCount = baselineTableData.length;\n const baselineCategoryCounts = useMemo<Partial<Record<SheetEffectCategory, number>>>(() => {\n const counts: Partial<Record<SheetEffectCategory, number>> = {};\n for (const entry of baselineTableData) {\n for (const cat of (entry.categories ?? []) as SheetEffectCategory[]) {\n counts[cat] = (counts[cat] ?? 0) + 1;\n }\n }\n return counts;\n }, [baselineTableData]);\n\n return {\n table,\n cards,\n cardsByCategory,\n categoryCounts,\n baselineCardCount,\n baselineCategoryCounts,\n\n category,\n setCategory: handleCategoryChange,\n globalFilterInput,\n setGlobalFilterInput,\n };\n}\n\nexport type UseEffectCatalogTableReturn = ReturnType<typeof useEffectCatalogTable>;\n"],"mappings":";;;;;;;AAmBA,MAAM,eAAe,oBAAiD;AAEtE,MAAM,UAAU;CACd,aAAa,SAAS,YAAY;EAChC,UAAU;EACV,oBAAoB;EACrB,CAAC;CACF,aAAa,SAAS,eAAe;EACnC,UAAU;EACV,oBAAoB;EACrB,CAAC;CACF,aAAa,SAAS,SAAS;EAC7B,UAAU;EACV,oBAAoB;EACrB,CAAC;CACH;AAED,SAAgB,sBACd,SAOI,EAAE,EACN;CACA,MAAM,CAAC,UAAU,eAAe,SAAqC,KAAK;CAC1E,MAAM,EAAE,uBAAuB,EAAE,EAAoB,WAAW;CAIhE,MAAM,oBAAoB,cAEtB,SAAS,gCAAgC,CAAC,OAAO,OAAO,GAAG,gCAAgC,EAC7F,CAAC,OAAO,CACT;CAUD,MAAM,QAAQ,cAAc;EAC1B;EACA,MAV6B,cAE3B,WACI,kBAAkB,QAAQ,OAAO,EAAE,cAAc,EAAE,EAAE,SAAS,SAAS,CAAC,GACxE,mBACN,CAAC,mBAAmB,SAAS,CAC9B;EAKC,iBAAiB,iBAAiB;EAClC,qBAAqB,qBAAqB;EAC1C,gBAAgB;EAChB,WAAW,EACT,OAAO,aACR;EACD,2BAA2B,WAAW,OAAO,UAAU,uBAAuB;EAC9E,cAAc;GACZ,eAAe;GACf,YAAY,EACV,UAAU,IACX;GACF;EACF,CAAC;CAEF,MAAM,CAAC,mBAAmB,sBAAsB,8BAA8B,aAAa,MAAM;AAC/F,MAAI,MAAM,MAAM,UAAU,CAAC,aAAc;AACzC,QAAM,gBAAgB,EAAE;AACxB,MAAI,EAAG,aAAY,KAAK;GACxB;CAEF,MAAM,uBAAuB,aAC1B,SAAqC;AACpC,cAAY,KAAK;AACjB,6BAA2B,GAAG;IAEhC,CAAC,2BAA2B,CAC7B;CAED,MAAM,OAAO,MAAM,aAAa,CAAC;CACjC,MAAM,QAAQ,cAEV,KAAK,KAAK,QAAQ;EAChB,MAAM,QAAQ,IAAI;EAClB,MAAM,WAAY,MAAM,iBAAiB,MAAM;AAC/C,SAAO;GACL,UAAU,MAAM;GAChB,YAAY,MAAM;GAClB,OAAO,MAAM;GACb,aAAa,MAAM;GACnB;GACA,WAAW,MAAM,iBAAiB,SAAS,MAAM,mBAAmB,CAAC,SAAS;GAC9E,sBAAsB,iCAAiC,MAAM;GAC7D,UAAU;GACV,eAAe,MAAM;GACrB;GACD;GACD,EACJ,CAAC,KAAK,CACP;AAuCD,QAAO;EACL;EACA;EACA,iBAxCsB,cAEhB;GACN,MAAM,yBAAS,IAAI,KAA4C;AAC/D,QAAK,MAAM,QAAQ,OAAO;IACxB,MAAM,OAAQ,KAAK,MAAM,cAAc,EAAE;AACzC,SAAK,MAAM,OAAO,MAAM;KACtB,MAAM,MAAM,OAAO,IAAI,IAAI;AAC3B,SAAI,IAAK,KAAI,KAAK,KAAK;SAClB,QAAO,IAAI,KAAK,CAAC,KAAK,CAAC;;;AAGhC,UAAO,MAAM,KAAK,SAAS,CAAC,UAAU,YAAY;IAAE;IAAU,OAAO;IAAO,EAAE;KAC7E,CAAC,MAAM,CAAC;EA4BT,gBA1BqB,cAA4D;GACjF,MAAM,SAAuD,EAAE;AAC/D,QAAK,MAAM,QAAQ,MACjB,MAAK,MAAM,OAAQ,KAAK,MAAM,cAAc,EAAE,CAC5C,QAAO,QAAQ,OAAO,QAAQ,KAAK;AAGvC,UAAO;KACN,CAAC,MAAM,CAAC;EAmBT,mBAhBwB,kBAAkB;EAiB1C,wBAhB6B,cAA4D;GACzF,MAAM,SAAuD,EAAE;AAC/D,QAAK,MAAM,SAAS,kBAClB,MAAK,MAAM,OAAQ,MAAM,cAAc,EAAE,CACvC,QAAO,QAAQ,OAAO,QAAQ,KAAK;AAGvC,UAAO;KACN,CAAC,kBAAkB,CAAC;EAUrB;EACA,aAAa;EACb;EACA;EACD"}
1
+ {"version":3,"file":"use-effect-catalog-table.mjs","names":[],"sources":["../../src/hooks/use-effect-catalog-table.ts"],"sourcesContent":["import {\n getInitialSheetEffectTableData,\n getLowestSheetEffectCreditAmount,\n isTokenBilledOperations,\n type ProviderName,\n type SheetEffectCatalogTableData,\n type SheetEffectCategory,\n} from \"@pipe0/base\";\nimport {\n type ColumnFilter,\n createColumnHelper,\n getCoreRowModel,\n getFilteredRowModel,\n useReactTable,\n} from \"@tanstack/react-table\";\nimport { useCallback, useMemo, useState } from \"react\";\nimport type { EffectCardData } from \"../types/catalog-adapters.js\";\nimport { fuzzyFilter } from \"../utils/catalog-helpers.js\";\nimport { useDebounce } from \"./use-debounce.js\";\n\nconst columnHelper = createColumnHelper<SheetEffectCatalogTableData>();\n\nconst columns = [\n columnHelper.accessor(\"effectId\", {\n filterFn: \"includesString\",\n enableGlobalFilter: true,\n }),\n columnHelper.accessor(\"description\", {\n filterFn: \"fuzzy\" as any,\n enableGlobalFilter: true,\n }),\n columnHelper.accessor(\"label\", {\n filterFn: \"includesString\",\n enableGlobalFilter: true,\n }),\n];\n\nexport function useEffectCatalogTable(\n config: {\n initialColumnFilters?: ColumnFilter[];\n /**\n * Optional predicate to pre-filter the catalog (e.g. by `selectionMode`\n * for the current row selection). Memoize it to keep the table stable.\n */\n filter?: (entry: SheetEffectCatalogTableData) => boolean;\n } = {},\n) {\n const [category, setCategory] = useState<SheetEffectCategory | null>(null);\n const { initialColumnFilters = [] as ColumnFilter[], filter } = config;\n\n // Baseline (config.filter applied, but no category / global filter). Drives\n // the stable category-button counts so the row doesn't jump.\n const baselineTableData = useMemo(\n () =>\n filter ? getInitialSheetEffectTableData().filter(filter) : getInitialSheetEffectTableData(),\n [filter],\n );\n\n const initialEffectTableData = useMemo(\n () =>\n category\n ? baselineTableData.filter((e) => (e.categories ?? []).includes(category))\n : baselineTableData,\n [baselineTableData, category],\n );\n\n const table = useReactTable({\n columns,\n data: initialEffectTableData,\n getCoreRowModel: getCoreRowModel(),\n getFilteredRowModel: getFilteredRowModel(),\n globalFilterFn: fuzzyFilter,\n filterFns: {\n fuzzy: fuzzyFilter,\n },\n getColumnCanGlobalFilter: (column) => column.columnDef.enableGlobalFilter !== false,\n initialState: {\n columnFilters: initialColumnFilters,\n pagination: {\n pageSize: 10,\n },\n },\n });\n\n const [globalFilterInput, setGlobalFilterInput, setGlobalFilterImmediately] = useDebounce((v) => {\n if (v === table.getState().globalFilter) return;\n table.setGlobalFilter(v);\n if (v) setCategory(null);\n });\n\n const handleCategoryChange = useCallback(\n (next: SheetEffectCategory | null) => {\n setCategory(next);\n setGlobalFilterImmediately(\"\");\n },\n [setGlobalFilterImmediately],\n );\n\n const rows = table.getRowModel().rows;\n const cards = useMemo<EffectCardData[]>(\n () =>\n rows.map((row) => {\n const entry = row.original;\n const provider = (entry.managedProviders[0] ?? \"pipe0\") as ProviderName;\n return {\n effectId: entry.effectId,\n baseEffect: entry.baseEffect,\n label: entry.label,\n description: entry.description,\n provider,\n providers: entry.managedProviders.length ? entry.managedProviders : [provider],\n startingCreditAmount: getLowestSheetEffectCreditAmount(entry),\n costMode: isTokenBilledOperations(entry.billableOperations)\n ? (\"usage\" as const)\n : (\"per_result\" as const),\n selectionMode: entry.selectionMode,\n entry,\n };\n }),\n [rows],\n );\n\n const cardsByCategory = useMemo<\n { category: SheetEffectCategory; cards: EffectCardData[] }[]\n >(() => {\n const groups = new Map<SheetEffectCategory, EffectCardData[]>();\n for (const card of cards) {\n const cats = (card.entry.categories ?? []) as SheetEffectCategory[];\n for (const cat of cats) {\n const arr = groups.get(cat);\n if (arr) arr.push(card);\n else groups.set(cat, [card]);\n }\n }\n return Array.from(groups, ([category, group]) => ({ category, cards: group }));\n }, [cards]);\n\n const categoryCounts = useMemo<Partial<Record<SheetEffectCategory, number>>>(() => {\n const counts: Partial<Record<SheetEffectCategory, number>> = {};\n for (const card of cards) {\n for (const cat of (card.entry.categories ?? []) as SheetEffectCategory[]) {\n counts[cat] = (counts[cat] ?? 0) + 1;\n }\n }\n return counts;\n }, [cards]);\n\n // Stable counts based on the baseline (no category / global filter applied).\n const baselineCardCount = baselineTableData.length;\n const baselineCategoryCounts = useMemo<Partial<Record<SheetEffectCategory, number>>>(() => {\n const counts: Partial<Record<SheetEffectCategory, number>> = {};\n for (const entry of baselineTableData) {\n for (const cat of (entry.categories ?? []) as SheetEffectCategory[]) {\n counts[cat] = (counts[cat] ?? 0) + 1;\n }\n }\n return counts;\n }, [baselineTableData]);\n\n return {\n table,\n cards,\n cardsByCategory,\n categoryCounts,\n baselineCardCount,\n baselineCategoryCounts,\n\n category,\n setCategory: handleCategoryChange,\n globalFilterInput,\n setGlobalFilterInput,\n };\n}\n\nexport type UseEffectCatalogTableReturn = ReturnType<typeof useEffectCatalogTable>;\n"],"mappings":"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"}
@@ -139,10 +139,13 @@ function useFormCore(options) {
139
139
  const r = slotResults[key];
140
140
  if (r == null) continue;
141
141
  const prev = prevResultsRef.current[key];
142
- if (slot.slotId === "field" && r.disabled && prev != null && !prev.disabled) form.setValue(slot.fieldPath, "", {
143
- shouldDirty: true,
144
- shouldTouch: true
145
- });
142
+ if (slot.slotId === "field" && r.disabled && prev != null && !prev.disabled) {
143
+ const def = getPathValue(defaultValues, slot.fieldPath);
144
+ form.setValue(slot.fieldPath, def === void 0 ? "" : def, {
145
+ shouldDirty: true,
146
+ shouldTouch: true
147
+ });
148
+ }
146
149
  if (slot.slotId === "suggestions" && resolvers?.getFieldContext) {
147
150
  if (r.disabled) {
148
151
  delete lastFiredSigRef.current[slot.fieldPath];
@@ -1 +1 @@
1
- {"version":3,"file":"use-form-core.mjs","names":[],"sources":["../../src/hooks/use-form-core.ts"],"sourcesContent":["import { zodResolver } from \"@hookform/resolvers/zod\";\nimport type {\n EnabledIf,\n EnabledResult,\n FormResolvers,\n FormSection,\n FormStore,\n GeneratedInputMeta,\n PipesEnvironment,\n ProviderName,\n} from \"@pipe0/base\";\nimport {\n type Dispatch,\n type SetStateAction,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { type FieldValues, type UseFormReturn, useForm } from \"react-hook-form\";\nimport type { AnyFieldProps, ConstantSuggestion, SecretSuggestion } from \"../types/field-props.js\";\nimport type { FormSectionHandle } from \"../types/form-handle.js\";\nimport { buildSectionHandles } from \"../utils/build-section-handlers.js\";\nimport { mergeFormStores } from \"../utils/merge-form-stores.js\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport type ResourceStatus = \"idle\" | \"loading\" | \"ready\" | \"error\";\n\nexport type SlotId = \"field\" | \"suggestions\";\n\nexport type FieldEnabledState = {\n disabled: boolean;\n reason?: string;\n};\n\nexport type FieldLoadState = {\n status: ResourceStatus;\n /** Field-level disabled (from `meta.enabledIf`). */\n disabled: boolean;\n /** Field-level disabled reason. */\n disabledReason?: string;\n /** Suggestions sub-feature gate (from `optionsDef.enabledIf`). */\n suggestionsDisabled: boolean;\n /** Suggestions sub-feature reason. */\n suggestionsDisabledReason?: string;\n};\n\nexport interface UseFormCoreOptions<T extends FieldValues> {\n pipeOrSearchId: string;\n kind: \"pipe\" | \"search\" | \"effect\";\n schema: any;\n publicKey: string;\n defaultValues?: T;\n formConfig: FormSection[];\n resolvers?: FormResolvers;\n store: FormStore;\n setStore: Dispatch<SetStateAction<FormStore>>;\n environment?: PipesEnvironment;\n /**\n * Form-level scope tags. Bundled into every `resolvers.getSecrets` call so\n * the backend can return only the secrets allowed in the declared scopes\n * (intersection on top of cascade visibility).\n */\n scopes?: string[];\n /**\n * Current team context. Bundled into every `resolvers.getSecrets` call so\n * the backend can restrict team-level secrets to exactly this team.\n */\n teamId?: string;\n}\n\nexport interface UseFormCoreReturn<T extends FieldValues> {\n connectionsStatus: ResourceStatus;\n /** Map of field path → load state for dynamic context_select_input fields. */\n fieldLoadStates: Record<string, FieldLoadState>;\n /** Subset of `fieldLoadStates` where `status === \"error\"`. RHF-style. */\n fieldLoaderErrors: Record<string, FieldLoadState>;\n /** Subset of `fieldLoadStates` where `status === \"loading\"`. RHF-style. */\n loadingFieldLoaders: Record<string, FieldLoadState>;\n /** True when any field loader has errored. */\n hasFieldLoaderError: boolean;\n /** True when any field loader is currently loading. */\n isFieldLoaderLoading: boolean;\n form: UseFormReturn<T, any, any>;\n sections: FormSectionHandle[];\n fields: AnyFieldProps[];\n reset: (values?: T) => void;\n}\n\ntype EnabledSlot = {\n fieldPath: string;\n slotId: SlotId;\n enabledIf: EnabledIf;\n /** Only present for \"suggestions\" slots — used to drive option fetching. */\n optionsDef?: {\n requires: { connection?: ProviderName; fields?: readonly string[] };\n };\n};\n\nfunction collectEnabledSlots(formConfig: FormSection[]): EnabledSlot[] {\n const out: EnabledSlot[] = [];\n for (const section of formConfig) {\n for (const group of section.groups) {\n for (const field of group.fields as GeneratedInputMeta[]) {\n if (field.enabledIf) {\n out.push({\n fieldPath: field.path,\n slotId: \"field\",\n enabledIf: field.enabledIf,\n });\n }\n const supportsOptionsDef =\n field.type === \"context_select_input\" || field.type === \"tagged_text_input\";\n if (supportsOptionsDef && \"optionsDef\" in field && field.optionsDef) {\n const optionsDef = field.optionsDef as EnabledSlot[\"optionsDef\"] & {\n enabledIf?: EnabledIf;\n };\n if (optionsDef?.enabledIf) {\n out.push({\n fieldPath: field.path,\n slotId: \"suggestions\",\n enabledIf: optionsDef.enabledIf,\n optionsDef,\n });\n } else {\n // Even without a sub-feature enabledIf, we still need to track\n // this field as having a fetchable suggestions slot — it's\n // always enabled and the fetch fires on every value change.\n out.push({\n fieldPath: field.path,\n slotId: \"suggestions\",\n enabledIf: () => ({ disabled: false }),\n optionsDef,\n });\n }\n }\n }\n }\n }\n return out;\n}\n\nfunction getPathValue(obj: unknown, path: string): unknown {\n const parts = path.split(\".\");\n let cur: any = obj;\n for (const part of parts) {\n if (cur == null) return undefined;\n cur = cur[part];\n }\n return cur;\n}\n\nfunction evalSlot(slot: EnabledSlot, payload: unknown): EnabledResult {\n return slot.enabledIf(payload);\n}\n\n// ---------------------------------------------------------------------------\n// Hook\n// ---------------------------------------------------------------------------\n\nexport function useFormCore<T extends FieldValues>(\n options: UseFormCoreOptions<T>,\n): UseFormCoreReturn<T> {\n const {\n schema,\n publicKey,\n defaultValues,\n formConfig,\n resolvers,\n pipeOrSearchId,\n kind,\n setStore,\n environment = \"production\",\n scopes,\n teamId,\n } = options;\n\n // Stable signature for `scopes` so its identity doesn't churn the effect\n // dep across renders when callers pass a fresh array literal each time.\n const scopesKey = useMemo(() => (scopes ? JSON.stringify(scopes) : \"\"), [scopes]);\n\n // --- Per-resource status ---\n const [connectionsStatus, setConnectionsStatus] = useState<ResourceStatus>(\n resolvers?.getConnections ? \"loading\" : \"idle\",\n );\n const [fieldLoadStates, setFieldLoadStates] = useState<Record<string, FieldLoadState>>({});\n\n // --- Form ---\n const form = useForm<T>({\n resolver: zodResolver(schema),\n defaultValues: defaultValues as any,\n });\n\n // --- Helpers ---\n const mergeStore = useCallback(\n (incoming: FormStore) => setStore((old) => mergeFormStores(old, incoming)),\n [setStore],\n );\n\n // --- Effect 1: Load connections ---\n useEffect(() => {\n if (!resolvers?.getConnections) {\n setConnectionsStatus(\"idle\");\n return;\n }\n\n let cancelled = false;\n setConnectionsStatus(\"loading\");\n\n Promise.resolve(resolvers.getConnections({ id: pipeOrSearchId, environment }))\n .then((conns) => {\n if (cancelled) return;\n\n mergeStore({\n field_options: {\n connections: {\n options: conns.map((c) => ({\n label: c.public_id,\n value: c.public_id,\n widgets: {\n provider_logo: { provider: c.provider as ProviderName },\n },\n })),\n },\n },\n });\n\n setConnectionsStatus(\"ready\");\n })\n .catch(() => {\n if (!cancelled) setConnectionsStatus(\"error\");\n });\n\n return () => {\n cancelled = true;\n };\n }, [pipeOrSearchId, environment, resolvers?.getConnections, mergeStore]);\n\n // --- Curried secrets search ---\n // Each keystroke in the reference picker fires this with the latest query.\n // The picker handles debounce + race-correctness; here we just bundle in\n // form-level args (environment / scopes / teamId) and call the resolver.\n // No caching: every call hits the resolver. Returns [] if no resolver.\n const getSecretsResolver = resolvers?.getSecrets;\n const searchSecrets = useCallback(\n async (query: string): Promise<SecretSuggestion[]> => {\n if (!getSecretsResolver) return [];\n return Promise.resolve(getSecretsResolver({ query, environment, scopes, teamId }));\n },\n // `scopesKey` is the stable serialization of `scopes`; depending on the\n // raw array would churn the callback identity on every parent render.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [getSecretsResolver, environment, scopesKey, teamId],\n );\n\n // --- Curried constants search ---\n // Mirrors `searchSecrets` exactly. Same per-keystroke contract, same\n // form-level arg bundling. Returns [] when no resolver is wired.\n const getConstantsResolver = resolvers?.getConstants;\n const searchConstants = useCallback(\n async (query: string): Promise<ConstantSuggestion[]> => {\n if (!getConstantsResolver) return [];\n return Promise.resolve(getConstantsResolver({ query, environment, scopes, teamId }));\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [getConstantsResolver, environment, scopesKey, teamId],\n );\n\n // --- Effect 2: Evaluate enabledIf slots + drive context_select fetching ---\n const slots = useMemo(() => collectEnabledSlots(formConfig), [formConfig]);\n\n // Subscribe to all form value changes so resolvers re-evaluate.\n const watchedValues = form.watch();\n\n // Evaluate every slot against the current payload. Keep the result\n // serialized so the effect's deps stay stable across reference-identical\n // re-renders.\n const slotResults = useMemo(() => {\n const out: Record<string, EnabledResult> = {};\n for (const slot of slots) {\n out[`${slot.fieldPath}::${slot.slotId}`] = evalSlot(slot, watchedValues);\n }\n return out;\n }, [slots, watchedValues]);\n const slotResultsSig = useMemo(() => JSON.stringify(slotResults), [slotResults]);\n\n // Track previous results so we can detect enabled→disabled transitions\n // (drives field-value clearing) and last-fired fetch signatures.\n const prevResultsRef = useRef<Record<string, EnabledResult>>({});\n const lastFiredSigRef = useRef<Record<string, string>>({});\n\n useEffect(() => {\n if (slots.length === 0) return;\n\n let cancelled = false;\n const nextLoadStates: Record<string, FieldLoadState> = {\n ...fieldLoadStates,\n };\n\n // Group slot results by field path for the load-state map.\n const byField: Record<string, { field?: EnabledResult; suggestions?: EnabledResult }> = {};\n for (const slot of slots) {\n const r = slotResults[`${slot.fieldPath}::${slot.slotId}`];\n if (r == null) continue;\n byField[slot.fieldPath] ??= {};\n byField[slot.fieldPath][slot.slotId] = r;\n }\n\n for (const slot of slots) {\n const key = `${slot.fieldPath}::${slot.slotId}`;\n const r = slotResults[key];\n if (r == null) continue;\n const prev = prevResultsRef.current[key];\n\n // Field-slot only: clear value on enabled→disabled transition.\n if (slot.slotId === \"field\" && r.disabled && prev != null && !prev.disabled) {\n form.setValue(slot.fieldPath as any, \"\" as any, {\n shouldDirty: true,\n shouldTouch: true,\n });\n }\n\n // Suggestions-slot: drive the existing context_select_input fetch.\n if (slot.slotId === \"suggestions\" && resolvers?.getFieldContext) {\n // If suggestions are gated, skip the fetch and reset dedupe so\n // re-enabling re-fires.\n if (r.disabled) {\n delete lastFiredSigRef.current[slot.fieldPath];\n continue;\n }\n\n // Resolve the connection for the legacy `requires.connection`\n // (still needed to pick the right secret for the fetch).\n const watchedConnections = (\n watchedValues as {\n connector?: { connections?: { connection?: string }[] };\n }\n )?.connector?.connections;\n const required = slot.optionsDef?.requires;\n\n let connectionId: string | undefined;\n if (required?.connection) {\n const match = watchedConnections?.find((c) =>\n c?.connection?.startsWith(`${required.connection}_`),\n );\n connectionId = match?.connection;\n // No matching connection — can't fetch, even if enabledIf passed.\n if (!connectionId) continue;\n }\n\n // Per-field signature for dedupe.\n const perFieldSig = JSON.stringify({\n connectionId,\n deps: required?.fields?.map((d) => getPathValue(watchedValues, d)) ?? [],\n });\n if (lastFiredSigRef.current[slot.fieldPath] === perFieldSig) continue;\n lastFiredSigRef.current[slot.fieldPath] = perFieldSig;\n\n // Mark loading for this field's fetch.\n const existing = nextLoadStates[slot.fieldPath];\n nextLoadStates[slot.fieldPath] = {\n status: \"loading\",\n disabled: existing?.disabled ?? false,\n disabledReason: existing?.disabledReason,\n suggestionsDisabled: false,\n suggestionsDisabledReason: undefined,\n };\n\n const idKey = kind === \"search\" ? \"search_id\" : kind === \"effect\" ? \"effect_id\" : \"pipe_id\";\n\n Promise.resolve(\n resolvers.getFieldContext({\n fieldPath: slot.fieldPath,\n query: \"\",\n payload: {\n ...(watchedValues as Record<string, unknown>),\n [idKey]: pipeOrSearchId,\n },\n }),\n )\n .then((incoming: FormStore) => {\n if (cancelled) return;\n mergeStore(incoming);\n setFieldLoadStates((s) => ({\n ...s,\n [slot.fieldPath]: {\n ...(s[slot.fieldPath] ?? {\n disabled: false,\n suggestionsDisabled: false,\n }),\n status: \"ready\",\n },\n }));\n })\n .catch(() => {\n if (cancelled) return;\n setFieldLoadStates((s) => ({\n ...s,\n [slot.fieldPath]: {\n ...(s[slot.fieldPath] ?? {\n disabled: false,\n suggestionsDisabled: false,\n }),\n status: \"error\",\n },\n }));\n });\n }\n }\n\n // Reflect the latest enabledIf evaluation into fieldLoadStates so the\n // adapters and field-wrapper can render the disabled state.\n for (const fieldPath of Object.keys(byField)) {\n const { field: fieldR, suggestions: sugR } = byField[fieldPath]!;\n const prevState = nextLoadStates[fieldPath];\n nextLoadStates[fieldPath] = {\n status: prevState?.status ?? \"idle\",\n disabled: fieldR == null ? (prevState?.disabled ?? false) : fieldR.disabled,\n disabledReason: fieldR == null ? prevState?.disabledReason : fieldR.message,\n suggestionsDisabled:\n sugR == null ? (prevState?.suggestionsDisabled ?? false) : sugR.disabled,\n suggestionsDisabledReason:\n sugR == null ? prevState?.suggestionsDisabledReason : sugR.message,\n };\n }\n\n setFieldLoadStates(nextLoadStates);\n prevResultsRef.current = slotResults;\n\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [slotResultsSig, slots, pipeOrSearchId]);\n\n // --- Sections & fields ---\n const isSubmitted = form.formState.isSubmitted;\n const formErrors = form.formState.errors;\n\n // `watchedValues` and `formErrors` must be in the dep array: field handles\n // bake `form.getValues(path)` snapshots into `field.value` / textareaProps /\n // selectedValue, and adapters render those as controlled inputs. Without\n // these deps, the memo never refreshes on keystrokes and the controlled\n // inputs snap back to their stale snapshot — typing/selecting appears to\n // do nothing. See FieldRenderer's memo comment for the intended contract.\n const sections = useMemo(\n () =>\n buildSectionHandles(formConfig, form as any, publicKey, {\n fieldLoadStates,\n searchSecrets,\n searchConstants,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n formConfig,\n form,\n publicKey,\n fieldLoadStates,\n isSubmitted,\n searchSecrets,\n searchConstants,\n watchedValues,\n formErrors,\n ],\n );\n\n const fields = useMemo(\n () => sections.flatMap((s) => s.groups.flatMap((g) => g.fields)),\n [sections],\n );\n\n const { fieldLoaderErrors, loadingFieldLoaders, hasFieldLoaderError, isFieldLoaderLoading } =\n useMemo(() => {\n const errors: Record<string, FieldLoadState> = {};\n const loading: Record<string, FieldLoadState> = {};\n for (const [path, state] of Object.entries(fieldLoadStates)) {\n if (state.status === \"error\") errors[path] = state;\n else if (state.status === \"loading\") loading[path] = state;\n }\n return {\n fieldLoaderErrors: errors,\n loadingFieldLoaders: loading,\n hasFieldLoaderError: Object.keys(errors).length > 0,\n isFieldLoaderLoading: Object.keys(loading).length > 0,\n };\n }, [fieldLoadStates]);\n\n return {\n connectionsStatus,\n fieldLoadStates,\n fieldLoaderErrors,\n loadingFieldLoaders,\n hasFieldLoaderError,\n isFieldLoaderLoading,\n form,\n sections,\n fields,\n reset: form.reset,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-form-core.mjs","names":[],"sources":["../../src/hooks/use-form-core.ts"],"sourcesContent":["import { zodResolver } from \"@hookform/resolvers/zod\";\nimport type {\n EnabledIf,\n EnabledResult,\n FormResolvers,\n FormSection,\n FormStore,\n GeneratedInputMeta,\n PipesEnvironment,\n ProviderName,\n} from \"@pipe0/base\";\nimport {\n type Dispatch,\n type SetStateAction,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { type FieldValues, type UseFormReturn, useForm } from \"react-hook-form\";\nimport type { AnyFieldProps, ConstantSuggestion, SecretSuggestion } from \"../types/field-props.js\";\nimport type { FormSectionHandle } from \"../types/form-handle.js\";\nimport { buildSectionHandles } from \"../utils/build-section-handlers.js\";\nimport { mergeFormStores } from \"../utils/merge-form-stores.js\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport type ResourceStatus = \"idle\" | \"loading\" | \"ready\" | \"error\";\n\nexport type SlotId = \"field\" | \"suggestions\";\n\nexport type FieldEnabledState = {\n disabled: boolean;\n reason?: string;\n};\n\nexport type FieldLoadState = {\n status: ResourceStatus;\n /** Field-level disabled (from `meta.enabledIf`). */\n disabled: boolean;\n /** Field-level disabled reason. */\n disabledReason?: string;\n /** Suggestions sub-feature gate (from `optionsDef.enabledIf`). */\n suggestionsDisabled: boolean;\n /** Suggestions sub-feature reason. */\n suggestionsDisabledReason?: string;\n};\n\nexport interface UseFormCoreOptions<T extends FieldValues> {\n pipeOrSearchId: string;\n kind: \"pipe\" | \"search\" | \"effect\";\n schema: any;\n publicKey: string;\n defaultValues?: T;\n formConfig: FormSection[];\n resolvers?: FormResolvers;\n store: FormStore;\n setStore: Dispatch<SetStateAction<FormStore>>;\n environment?: PipesEnvironment;\n /**\n * Form-level scope tags. Bundled into every `resolvers.getSecrets` call so\n * the backend can return only the secrets allowed in the declared scopes\n * (intersection on top of cascade visibility).\n */\n scopes?: string[];\n /**\n * Current team context. Bundled into every `resolvers.getSecrets` call so\n * the backend can restrict team-level secrets to exactly this team.\n */\n teamId?: string;\n}\n\nexport interface UseFormCoreReturn<T extends FieldValues> {\n connectionsStatus: ResourceStatus;\n /** Map of field path → load state for dynamic context_select_input fields. */\n fieldLoadStates: Record<string, FieldLoadState>;\n /** Subset of `fieldLoadStates` where `status === \"error\"`. RHF-style. */\n fieldLoaderErrors: Record<string, FieldLoadState>;\n /** Subset of `fieldLoadStates` where `status === \"loading\"`. RHF-style. */\n loadingFieldLoaders: Record<string, FieldLoadState>;\n /** True when any field loader has errored. */\n hasFieldLoaderError: boolean;\n /** True when any field loader is currently loading. */\n isFieldLoaderLoading: boolean;\n form: UseFormReturn<T, any, any>;\n sections: FormSectionHandle[];\n fields: AnyFieldProps[];\n reset: (values?: T) => void;\n}\n\ntype EnabledSlot = {\n fieldPath: string;\n slotId: SlotId;\n enabledIf: EnabledIf;\n /** Only present for \"suggestions\" slots — used to drive option fetching. */\n optionsDef?: {\n requires: { connection?: ProviderName; fields?: readonly string[] };\n };\n};\n\nfunction collectEnabledSlots(formConfig: FormSection[]): EnabledSlot[] {\n const out: EnabledSlot[] = [];\n for (const section of formConfig) {\n for (const group of section.groups) {\n for (const field of group.fields as GeneratedInputMeta[]) {\n if (field.enabledIf) {\n out.push({\n fieldPath: field.path,\n slotId: \"field\",\n enabledIf: field.enabledIf,\n });\n }\n const supportsOptionsDef =\n field.type === \"context_select_input\" || field.type === \"tagged_text_input\";\n if (supportsOptionsDef && \"optionsDef\" in field && field.optionsDef) {\n const optionsDef = field.optionsDef as EnabledSlot[\"optionsDef\"] & {\n enabledIf?: EnabledIf;\n };\n if (optionsDef?.enabledIf) {\n out.push({\n fieldPath: field.path,\n slotId: \"suggestions\",\n enabledIf: optionsDef.enabledIf,\n optionsDef,\n });\n } else {\n // Even without a sub-feature enabledIf, we still need to track\n // this field as having a fetchable suggestions slot — it's\n // always enabled and the fetch fires on every value change.\n out.push({\n fieldPath: field.path,\n slotId: \"suggestions\",\n enabledIf: () => ({ disabled: false }),\n optionsDef,\n });\n }\n }\n }\n }\n }\n return out;\n}\n\nfunction getPathValue(obj: unknown, path: string): unknown {\n const parts = path.split(\".\");\n let cur: any = obj;\n for (const part of parts) {\n if (cur == null) return undefined;\n cur = cur[part];\n }\n return cur;\n}\n\nfunction evalSlot(slot: EnabledSlot, payload: unknown): EnabledResult {\n return slot.enabledIf(payload);\n}\n\n// ---------------------------------------------------------------------------\n// Hook\n// ---------------------------------------------------------------------------\n\nexport function useFormCore<T extends FieldValues>(\n options: UseFormCoreOptions<T>,\n): UseFormCoreReturn<T> {\n const {\n schema,\n publicKey,\n defaultValues,\n formConfig,\n resolvers,\n pipeOrSearchId,\n kind,\n setStore,\n environment = \"production\",\n scopes,\n teamId,\n } = options;\n\n // Stable signature for `scopes` so its identity doesn't churn the effect\n // dep across renders when callers pass a fresh array literal each time.\n const scopesKey = useMemo(() => (scopes ? JSON.stringify(scopes) : \"\"), [scopes]);\n\n // --- Per-resource status ---\n const [connectionsStatus, setConnectionsStatus] = useState<ResourceStatus>(\n resolvers?.getConnections ? \"loading\" : \"idle\",\n );\n const [fieldLoadStates, setFieldLoadStates] = useState<Record<string, FieldLoadState>>({});\n\n // --- Form ---\n const form = useForm<T>({\n resolver: zodResolver(schema),\n defaultValues: defaultValues as any,\n });\n\n // --- Helpers ---\n const mergeStore = useCallback(\n (incoming: FormStore) => setStore((old) => mergeFormStores(old, incoming)),\n [setStore],\n );\n\n // --- Effect 1: Load connections ---\n useEffect(() => {\n if (!resolvers?.getConnections) {\n setConnectionsStatus(\"idle\");\n return;\n }\n\n let cancelled = false;\n setConnectionsStatus(\"loading\");\n\n Promise.resolve(resolvers.getConnections({ id: pipeOrSearchId, environment }))\n .then((conns) => {\n if (cancelled) return;\n\n mergeStore({\n field_options: {\n connections: {\n options: conns.map((c) => ({\n label: c.public_id,\n value: c.public_id,\n widgets: {\n provider_logo: { provider: c.provider as ProviderName },\n },\n })),\n },\n },\n });\n\n setConnectionsStatus(\"ready\");\n })\n .catch(() => {\n if (!cancelled) setConnectionsStatus(\"error\");\n });\n\n return () => {\n cancelled = true;\n };\n }, [pipeOrSearchId, environment, resolvers?.getConnections, mergeStore]);\n\n // --- Curried secrets search ---\n // Each keystroke in the reference picker fires this with the latest query.\n // The picker handles debounce + race-correctness; here we just bundle in\n // form-level args (environment / scopes / teamId) and call the resolver.\n // No caching: every call hits the resolver. Returns [] if no resolver.\n const getSecretsResolver = resolvers?.getSecrets;\n const searchSecrets = useCallback(\n async (query: string): Promise<SecretSuggestion[]> => {\n if (!getSecretsResolver) return [];\n return Promise.resolve(getSecretsResolver({ query, environment, scopes, teamId }));\n },\n // `scopesKey` is the stable serialization of `scopes`; depending on the\n // raw array would churn the callback identity on every parent render.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [getSecretsResolver, environment, scopesKey, teamId],\n );\n\n // --- Curried constants search ---\n // Mirrors `searchSecrets` exactly. Same per-keystroke contract, same\n // form-level arg bundling. Returns [] when no resolver is wired.\n const getConstantsResolver = resolvers?.getConstants;\n const searchConstants = useCallback(\n async (query: string): Promise<ConstantSuggestion[]> => {\n if (!getConstantsResolver) return [];\n return Promise.resolve(getConstantsResolver({ query, environment, scopes, teamId }));\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [getConstantsResolver, environment, scopesKey, teamId],\n );\n\n // --- Effect 2: Evaluate enabledIf slots + drive context_select fetching ---\n const slots = useMemo(() => collectEnabledSlots(formConfig), [formConfig]);\n\n // Subscribe to all form value changes so resolvers re-evaluate.\n const watchedValues = form.watch();\n\n // Evaluate every slot against the current payload. Keep the result\n // serialized so the effect's deps stay stable across reference-identical\n // re-renders.\n const slotResults = useMemo(() => {\n const out: Record<string, EnabledResult> = {};\n for (const slot of slots) {\n out[`${slot.fieldPath}::${slot.slotId}`] = evalSlot(slot, watchedValues);\n }\n return out;\n }, [slots, watchedValues]);\n const slotResultsSig = useMemo(() => JSON.stringify(slotResults), [slotResults]);\n\n // Track previous results so we can detect enabled→disabled transitions\n // (drives field-value clearing) and last-fired fetch signatures.\n const prevResultsRef = useRef<Record<string, EnabledResult>>({});\n const lastFiredSigRef = useRef<Record<string, string>>({});\n\n useEffect(() => {\n if (slots.length === 0) return;\n\n let cancelled = false;\n const nextLoadStates: Record<string, FieldLoadState> = {\n ...fieldLoadStates,\n };\n\n // Group slot results by field path for the load-state map.\n const byField: Record<string, { field?: EnabledResult; suggestions?: EnabledResult }> = {};\n for (const slot of slots) {\n const r = slotResults[`${slot.fieldPath}::${slot.slotId}`];\n if (r == null) continue;\n byField[slot.fieldPath] ??= {};\n byField[slot.fieldPath][slot.slotId] = r;\n }\n\n for (const slot of slots) {\n const key = `${slot.fieldPath}::${slot.slotId}`;\n const r = slotResults[key];\n if (r == null) continue;\n const prev = prevResultsRef.current[key];\n\n // Field-slot only: on enabled→disabled, reset the value to the field's\n // configured default (from the seeded defaultValues) rather than `\"\"`.\n // `\"\"` is invalid for non-string fields — e.g. a gated boolean fails\n // `z.boolean()` and a nullable int's `null` default would coerce to `0`.\n // Fall back to `\"\"` only when there's NO default at the path, so explicit\n // `null`/`false` defaults survive (this resets an optional int back to\n // empty when its gate turns off).\n if (slot.slotId === \"field\" && r.disabled && prev != null && !prev.disabled) {\n const def = getPathValue(defaultValues, slot.fieldPath);\n form.setValue(slot.fieldPath as any, (def === undefined ? \"\" : def) as any, {\n shouldDirty: true,\n shouldTouch: true,\n });\n }\n\n // Suggestions-slot: drive the existing context_select_input fetch.\n if (slot.slotId === \"suggestions\" && resolvers?.getFieldContext) {\n // If suggestions are gated, skip the fetch and reset dedupe so\n // re-enabling re-fires.\n if (r.disabled) {\n delete lastFiredSigRef.current[slot.fieldPath];\n continue;\n }\n\n // Resolve the connection for the legacy `requires.connection`\n // (still needed to pick the right secret for the fetch).\n const watchedConnections = (\n watchedValues as {\n connector?: { connections?: { connection?: string }[] };\n }\n )?.connector?.connections;\n const required = slot.optionsDef?.requires;\n\n let connectionId: string | undefined;\n if (required?.connection) {\n const match = watchedConnections?.find((c) =>\n c?.connection?.startsWith(`${required.connection}_`),\n );\n connectionId = match?.connection;\n // No matching connection — can't fetch, even if enabledIf passed.\n if (!connectionId) continue;\n }\n\n // Per-field signature for dedupe.\n const perFieldSig = JSON.stringify({\n connectionId,\n deps: required?.fields?.map((d) => getPathValue(watchedValues, d)) ?? [],\n });\n if (lastFiredSigRef.current[slot.fieldPath] === perFieldSig) continue;\n lastFiredSigRef.current[slot.fieldPath] = perFieldSig;\n\n // Mark loading for this field's fetch.\n const existing = nextLoadStates[slot.fieldPath];\n nextLoadStates[slot.fieldPath] = {\n status: \"loading\",\n disabled: existing?.disabled ?? false,\n disabledReason: existing?.disabledReason,\n suggestionsDisabled: false,\n suggestionsDisabledReason: undefined,\n };\n\n const idKey = kind === \"search\" ? \"search_id\" : kind === \"effect\" ? \"effect_id\" : \"pipe_id\";\n\n Promise.resolve(\n resolvers.getFieldContext({\n fieldPath: slot.fieldPath,\n query: \"\",\n payload: {\n ...(watchedValues as Record<string, unknown>),\n [idKey]: pipeOrSearchId,\n },\n }),\n )\n .then((incoming: FormStore) => {\n if (cancelled) return;\n mergeStore(incoming);\n setFieldLoadStates((s) => ({\n ...s,\n [slot.fieldPath]: {\n ...(s[slot.fieldPath] ?? {\n disabled: false,\n suggestionsDisabled: false,\n }),\n status: \"ready\",\n },\n }));\n })\n .catch(() => {\n if (cancelled) return;\n setFieldLoadStates((s) => ({\n ...s,\n [slot.fieldPath]: {\n ...(s[slot.fieldPath] ?? {\n disabled: false,\n suggestionsDisabled: false,\n }),\n status: \"error\",\n },\n }));\n });\n }\n }\n\n // Reflect the latest enabledIf evaluation into fieldLoadStates so the\n // adapters and field-wrapper can render the disabled state.\n for (const fieldPath of Object.keys(byField)) {\n const { field: fieldR, suggestions: sugR } = byField[fieldPath]!;\n const prevState = nextLoadStates[fieldPath];\n nextLoadStates[fieldPath] = {\n status: prevState?.status ?? \"idle\",\n disabled: fieldR == null ? (prevState?.disabled ?? false) : fieldR.disabled,\n disabledReason: fieldR == null ? prevState?.disabledReason : fieldR.message,\n suggestionsDisabled:\n sugR == null ? (prevState?.suggestionsDisabled ?? false) : sugR.disabled,\n suggestionsDisabledReason:\n sugR == null ? prevState?.suggestionsDisabledReason : sugR.message,\n };\n }\n\n setFieldLoadStates(nextLoadStates);\n prevResultsRef.current = slotResults;\n\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [slotResultsSig, slots, pipeOrSearchId]);\n\n // --- Sections & fields ---\n const isSubmitted = form.formState.isSubmitted;\n const formErrors = form.formState.errors;\n\n // `watchedValues` and `formErrors` must be in the dep array: field handles\n // bake `form.getValues(path)` snapshots into `field.value` / textareaProps /\n // selectedValue, and adapters render those as controlled inputs. Without\n // these deps, the memo never refreshes on keystrokes and the controlled\n // inputs snap back to their stale snapshot — typing/selecting appears to\n // do nothing. See FieldRenderer's memo comment for the intended contract.\n const sections = useMemo(\n () =>\n buildSectionHandles(formConfig, form as any, publicKey, {\n fieldLoadStates,\n searchSecrets,\n searchConstants,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n formConfig,\n form,\n publicKey,\n fieldLoadStates,\n isSubmitted,\n searchSecrets,\n searchConstants,\n watchedValues,\n formErrors,\n ],\n );\n\n const fields = useMemo(\n () => sections.flatMap((s) => s.groups.flatMap((g) => g.fields)),\n [sections],\n );\n\n const { fieldLoaderErrors, loadingFieldLoaders, hasFieldLoaderError, isFieldLoaderLoading } =\n useMemo(() => {\n const errors: Record<string, FieldLoadState> = {};\n const loading: Record<string, FieldLoadState> = {};\n for (const [path, state] of Object.entries(fieldLoadStates)) {\n if (state.status === \"error\") errors[path] = state;\n else if (state.status === \"loading\") loading[path] = state;\n }\n return {\n fieldLoaderErrors: errors,\n loadingFieldLoaders: loading,\n hasFieldLoaderError: Object.keys(errors).length > 0,\n isFieldLoaderLoading: Object.keys(loading).length > 0,\n };\n }, [fieldLoadStates]);\n\n return {\n connectionsStatus,\n fieldLoadStates,\n fieldLoaderErrors,\n loadingFieldLoaders,\n hasFieldLoaderError,\n isFieldLoaderLoading,\n form,\n sections,\n fields,\n reset: form.reset,\n };\n}\n"],"mappings":"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"}
@@ -32,14 +32,14 @@ declare function usePipeCatalogTable(config?: {
32
32
  removeColumnFilter: (id: "inputFields" | "outputFields" | "tags" | "providers") => void;
33
33
  resetFilters: () => void;
34
34
  getColumnFilterValue: (id: "inputFields" | "outputFields" | "tags" | "providers") => string;
35
- sortedInputFieldEntries: [string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "company:identity:crustdata@1" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:extract:parallel@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "person:devprofileurl:profileurl:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]][];
36
- sortedOutputFieldEntries: [string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "company:identity:crustdata@1" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:extract:parallel@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "person:devprofileurl:profileurl:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]][];
37
- sortedTagEntries: [string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "company:identity:crustdata@1" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:extract:parallel@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "person:devprofileurl:profileurl:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]][];
38
- sortedProviderEntries: [string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "company:identity:crustdata@1" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:extract:parallel@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "person:devprofileurl:profileurl:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]][];
39
- pipeIdsByInputField: Record<string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "company:identity:crustdata@1" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:extract:parallel@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "person:devprofileurl:profileurl:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]>;
40
- pipeIdsByOutputField: Record<string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "company:identity:crustdata@1" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:extract:parallel@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "person:devprofileurl:profileurl:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]>;
41
- pipeIdsByProvider: Record<string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "company:identity:crustdata@1" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:extract:parallel@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "person:devprofileurl:profileurl:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]>;
42
- pipeIdsByTag: Record<string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "company:identity:crustdata@1" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:extract:parallel@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "person:devprofileurl:profileurl:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]>;
35
+ sortedInputFieldEntries: [string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "lead:enroll:lemlist@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "company:identity:crustdata@1" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:extract:parallel@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:content:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "person:devprofileurl:profileurl:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]][];
36
+ sortedOutputFieldEntries: [string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "lead:enroll:lemlist@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "company:identity:crustdata@1" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:extract:parallel@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:content:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "person:devprofileurl:profileurl:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]][];
37
+ sortedTagEntries: [string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "lead:enroll:lemlist@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "company:identity:crustdata@1" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:extract:parallel@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:content:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "person:devprofileurl:profileurl:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]][];
38
+ sortedProviderEntries: [string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "lead:enroll:lemlist@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "company:identity:crustdata@1" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:extract:parallel@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:content:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "person:devprofileurl:profileurl:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]][];
39
+ pipeIdsByInputField: Record<string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "lead:enroll:lemlist@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "company:identity:crustdata@1" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:extract:parallel@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:content:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "person:devprofileurl:profileurl:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]>;
40
+ pipeIdsByOutputField: Record<string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "lead:enroll:lemlist@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "company:identity:crustdata@1" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:extract:parallel@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:content:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "person:devprofileurl:profileurl:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]>;
41
+ pipeIdsByProvider: Record<string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "lead:enroll:lemlist@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "company:identity:crustdata@1" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:extract:parallel@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:content:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "person:devprofileurl:profileurl:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]>;
42
+ pipeIdsByTag: Record<string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "lead:enroll:lemlist@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "company:identity:crustdata@1" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:extract:parallel@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:content:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "person:devprofileurl:profileurl:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]>;
43
43
  };
44
44
  type UsePipeCatalogTableReturn = ReturnType<typeof usePipeCatalogTable>;
45
45
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"use-pipe-catalog-table.d.mts","names":[],"sources":["../../src/hooks/use-pipe-catalog-table.ts"],"mappings":";;;;;;;KA2BY,iBAAA,GAAoB,MAAA,SAAe,MAAA;AAAA,KACnC,kBAAA,GAAqB,MAAA,SAAe,MAAA;AAAA,iBA6ChC,mBAAA,CACd,MAAA;EACE,oBAAA,GAAuB,YAAA;EAhDf;;;;EAqDR,MAAA,GAAS,aAAA;AAAA;;;;cA6HiC,YAAA;WAAqB,YAAA;EAAA;;;;;0BA/DpD,YAAA;;yCAAY,OAAA,CAAA,cAAA;+EARmC,KAAA;;;;;;;;;;;;;KAoJlD,yBAAA,GAA4B,UAAA,QAAkB,mBAAA"}
1
+ {"version":3,"file":"use-pipe-catalog-table.d.mts","names":[],"sources":["../../src/hooks/use-pipe-catalog-table.ts"],"mappings":";;;;;;;KA4BY,iBAAA,GAAoB,MAAA,SAAe,MAAA;AAAA,KACnC,kBAAA,GAAqB,MAAA,SAAe,MAAA;AAAA,iBA6ChC,mBAAA,CACd,MAAA;EACE,oBAAA,GAAuB,YAAA;EAhDf;;;;EAqDR,MAAA,GAAS,aAAA;AAAA;;;;cA+HiC,YAAA;WAAqB,YAAA;EAAA;;;;;0BAjEpD,YAAA;;yCAAY,OAAA,CAAA,cAAA;+EARmC,KAAA;;;;;;;;;;;;;KAsJlD,yBAAA,GAA4B,UAAA,QAAkB,mBAAA"}
@@ -1,7 +1,7 @@
1
1
  import { fuzzyFilter } from "../utils/catalog-helpers.mjs";
2
2
  import { useDebounce } from "./use-debounce.mjs";
3
3
  import { useCallback, useMemo, useState } from "react";
4
- import { collectRequirementFields, filterPipeEntries, getDefaultOutputFields, getDefaultPipeProviders, getInitialTableData, getLowestPipeCreditAmount, getStartingCostPerPipesProvider, getTableDataAggregates } from "@pipe0/base";
4
+ import { collectRequirementFields, filterPipeEntries, getDefaultOutputFields, getDefaultPipeProviders, getInitialTableData, getLowestPipeCreditAmount, getStartingCostPerPipesProvider, getTableDataAggregates, isTokenBilledOperations } from "@pipe0/base";
5
5
  import { createColumnHelper, getCoreRowModel, getFilteredRowModel, useReactTable } from "@tanstack/react-table";
6
6
 
7
7
  //#region src/hooks/use-pipe-catalog-table.ts
@@ -103,7 +103,7 @@ function usePipeCatalogTable(config = {}) {
103
103
  providers,
104
104
  startingCostPerProvider: getStartingCostPerPipesProvider(latestEntry.pipeId),
105
105
  startingCreditAmount: getLowestPipeCreditAmount(latestEntry),
106
- costMode: "per_result",
106
+ costMode: isTokenBilledOperations(latestEntry.billableOperations) ? "usage" : "per_result",
107
107
  defaultInputFields: latestEntry.defaultInputRequirement ? collectRequirementFields(latestEntry.defaultInputRequirement).map(({ field }) => ({ name: field.name })) : [],
108
108
  defaultOutputFields: getDefaultOutputFields(latestEntry) ?? [],
109
109
  docPath: latestEntry.docPath,
@@ -1 +1 @@
1
- {"version":3,"file":"use-pipe-catalog-table.mjs","names":[],"sources":["../../src/hooks/use-pipe-catalog-table.ts"],"sourcesContent":["import {\n type CatalogFilter,\n collectRequirementFields,\n filterPipeEntries,\n getDefaultOutputFields,\n getDefaultPipeProviders,\n getInitialTableData,\n getLowestPipeCreditAmount,\n getStartingCostPerPipesProvider,\n getTableDataAggregates,\n type PipeCatalogEntry,\n type PipeCategory,\n type PipeEntryWithLatestVersion,\n type PipeId,\n} from \"@pipe0/base\";\nimport {\n type ColumnFilter,\n createColumnHelper,\n getCoreRowModel,\n getFilteredRowModel,\n useReactTable,\n} from \"@tanstack/react-table\";\nimport { useCallback, useMemo, useState } from \"react\";\nimport type { PipeCardData } from \"../types/catalog-adapters.js\";\nimport { fuzzyFilter } from \"../utils/catalog-helpers.js\";\nimport { useDebounce } from \"./use-debounce.js\";\n\nexport type InputFieldEntries = Record<string, PipeId[]>;\nexport type OutputFieldEntries = Record<string, PipeId[]>;\n\nconst columnHelper = createColumnHelper<PipeEntryWithLatestVersion>();\n\nconst columns = [\n columnHelper.accessor(\"pipeId\", {\n filterFn: \"includesString\",\n enableGlobalFilter: true,\n }),\n columnHelper.accessor(\"label\", {\n filterFn: \"fuzzy\" as any,\n enableGlobalFilter: true,\n }),\n columnHelper.accessor(\"description\", {\n filterFn: \"fuzzy\" as any,\n enableGlobalFilter: true,\n }),\n columnHelper.accessor(\n (row) =>\n row.defaultInputRequirement\n ? collectRequirementFields(row.defaultInputRequirement).map(({ field }) => field.name)\n : [],\n {\n id: \"inputFields\",\n filterFn: \"arrIncludes\",\n enableGlobalFilter: false,\n },\n ),\n columnHelper.accessor((row) => getDefaultOutputFields(row) || [], {\n id: \"outputFields\",\n filterFn: \"arrIncludes\",\n enableGlobalFilter: false,\n }),\n columnHelper.accessor((row) => row.tags || [], {\n id: \"tags\",\n filterFn: \"arrIncludes\",\n enableGlobalFilter: true,\n }),\n columnHelper.accessor((row) => getDefaultPipeProviders(row.pipeId) || [], {\n id: \"providers\",\n filterFn: \"arrIncludes\",\n enableGlobalFilter: true,\n }),\n];\n\nexport function usePipeCatalogTable(\n config: {\n initialColumnFilters?: ColumnFilter[];\n /**\n * Optional whitelist/blacklist of pipes and providers. Memoize to avoid\n * recomputing the table data on every render.\n */\n filter?: CatalogFilter;\n } = {},\n) {\n const [category, setCategory] = useState<PipeCategory | null>(null);\n const { initialColumnFilters = [] as ColumnFilter[], filter } = config;\n\n const initialTableData = useMemo(\n () => filterPipeEntries(getInitialTableData(category), filter),\n [category, filter],\n );\n\n // Baseline (config.filter applied, but no category / column / global filter).\n // Drives the stable category-button counts so the row doesn't jump when the\n // user changes a filter.\n const baselineTableData = useMemo(\n () => filterPipeEntries(getInitialTableData(null), filter),\n [filter],\n );\n\n const table = useReactTable({\n columns,\n data: initialTableData,\n getCoreRowModel: getCoreRowModel(),\n getFilteredRowModel: getFilteredRowModel(),\n globalFilterFn: fuzzyFilter,\n filterFns: {\n fuzzy: fuzzyFilter,\n },\n getColumnCanGlobalFilter: (column) => column.columnDef.enableGlobalFilter !== false,\n initialState: {\n columnFilters: initialColumnFilters,\n pagination: {\n pageSize: 10,\n },\n },\n });\n\n const columnFilters = table.getState().columnFilters;\n\n const aggregates = useMemo(\n () => getTableDataAggregates(initialTableData, category),\n [category, initialTableData],\n );\n\n const [globalFilterInput, setGlobalFilterInput, setGlobalFilterImmediately] = useDebounce((v) => {\n if (v === table.getState().globalFilter) return;\n table.setGlobalFilter(v);\n if (v) {\n setCategory(null);\n table.setColumnFilters([]);\n }\n });\n\n const addColumnFilter = useCallback(\n (id: \"inputFields\" | \"outputFields\" | \"tags\" | \"providers\", value: string) => {\n setGlobalFilterImmediately(\"\");\n table.setColumnFilters([{ id, value }]);\n },\n [setGlobalFilterImmediately, table],\n );\n\n const handleCategoryChange = useCallback(\n (category: PipeCategory | null) => {\n setCategory(category);\n table.setColumnFilters([]);\n setGlobalFilterImmediately(\"\");\n },\n [table, setGlobalFilterImmediately],\n );\n\n const resetFilters = useCallback(() => {\n setGlobalFilterImmediately(\"\");\n setCategory(null);\n }, [setGlobalFilterImmediately]);\n\n const removeColumnFilter = useCallback(\n (id: \"inputFields\" | \"outputFields\" | \"tags\" | \"providers\") => {\n table.getColumn(id)?.setFilterValue(null);\n },\n [table],\n );\n\n const getColumnFilterValue = useCallback(\n (id: \"inputFields\" | \"outputFields\" | \"tags\" | \"providers\") => {\n const res = columnFilters.find((f) => f.id === id)?.value;\n return res as string;\n },\n [columnFilters],\n );\n\n // Pre-compute card display data so consumers don't have to. Memoized on\n // the filtered rows + aggregate map (both stable references from tanstack).\n const rows = table.getRowModel().rows;\n const cards = useMemo<PipeCardData[]>(\n () =>\n rows.map((row) => {\n const entry = row.original;\n const latestEntry = (aggregates.pipeEntriesByBasePipe[entry.basePipe]?.[0] ??\n entry) as PipeCatalogEntry & { pipeId: PipeId };\n const providers = getDefaultPipeProviders(latestEntry.pipeId);\n return {\n pipeId: latestEntry.pipeId,\n basePipe: entry.basePipe,\n label: entry.label,\n description: entry.description,\n providers,\n startingCostPerProvider: getStartingCostPerPipesProvider(latestEntry.pipeId),\n startingCreditAmount: getLowestPipeCreditAmount(latestEntry),\n costMode: \"per_result\",\n defaultInputFields: latestEntry.defaultInputRequirement\n ? collectRequirementFields(latestEntry.defaultInputRequirement).map(({ field }) => ({\n name: field.name,\n }))\n : [],\n defaultOutputFields: getDefaultOutputFields(latestEntry) ?? [],\n docPath: latestEntry.docPath,\n entry,\n latestEntry,\n };\n }),\n [rows, aggregates.pipeEntriesByBasePipe],\n );\n\n // Group cards by category. Pipes can belong to multiple categories — they\n // appear once per matching category. Order: insertion (first-seen).\n const cardsByCategory = useMemo<{ category: PipeCategory; cards: PipeCardData[] }[]>(() => {\n const groups = new Map<PipeCategory, PipeCardData[]>();\n for (const card of cards) {\n const cats = (card.entry.categories ?? []) as PipeCategory[];\n for (const cat of cats) {\n const arr = groups.get(cat);\n if (arr) arr.push(card);\n else groups.set(cat, [card]);\n }\n }\n return Array.from(groups, ([category, group]) => ({\n category,\n cards: group,\n }));\n }, [cards]);\n\n // Count of cards per category (a pipe in N categories counts N times).\n const categoryCounts = useMemo<Partial<Record<PipeCategory, number>>>(() => {\n const counts: Partial<Record<PipeCategory, number>> = {};\n for (const card of cards) {\n const cats = (card.entry.categories ?? []) as PipeCategory[];\n for (const cat of cats) {\n counts[cat] = (counts[cat] ?? 0) + 1;\n }\n }\n return counts;\n }, [cards]);\n\n // Stable counts based on the baseline (no category / column / global filter\n // applied). Use these to render category-selector counts that don't jump as\n // the user clicks around.\n const baselineCardCount = baselineTableData.length;\n const baselineCategoryCounts = useMemo<Partial<Record<PipeCategory, number>>>(() => {\n const counts: Partial<Record<PipeCategory, number>> = {};\n for (const entry of baselineTableData) {\n const cats = (entry.categories ?? []) as PipeCategory[];\n for (const cat of cats) {\n counts[cat] = (counts[cat] ?? 0) + 1;\n }\n }\n return counts;\n }, [baselineTableData]);\n\n return {\n table,\n cards,\n cardsByCategory,\n categoryCounts,\n baselineCardCount,\n baselineCategoryCounts,\n\n // category + global filter\n category,\n setCategory: handleCategoryChange,\n globalFilterInput,\n setGlobalFilterInput,\n\n // mutators\n addColumnFilter,\n removeColumnFilter,\n resetFilters,\n getColumnFilterValue,\n\n // aggregates for filter UI\n sortedInputFieldEntries: aggregates.sortedInputFieldEntries,\n sortedOutputFieldEntries: aggregates.sortedOutputFieldEntries,\n sortedTagEntries: aggregates.sortedTagEntries,\n sortedProviderEntries: aggregates.sortedProviderEntries,\n\n // reverse indexes (power-user / inverted-filter UX)\n pipeIdsByInputField: aggregates.pipeIdsByInputField,\n pipeIdsByOutputField: aggregates.pipeIdsByOutputField,\n pipeIdsByProvider: aggregates.pipeIdsByProvider,\n pipeIdsByTag: aggregates.pipeIdsByTag,\n };\n}\n\nexport type UsePipeCatalogTableReturn = ReturnType<typeof usePipeCatalogTable>;\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-pipe-catalog-table.mjs","names":[],"sources":["../../src/hooks/use-pipe-catalog-table.ts"],"sourcesContent":["import {\n type CatalogFilter,\n collectRequirementFields,\n filterPipeEntries,\n getDefaultOutputFields,\n getDefaultPipeProviders,\n getInitialTableData,\n getLowestPipeCreditAmount,\n getStartingCostPerPipesProvider,\n getTableDataAggregates,\n isTokenBilledOperations,\n type PipeCatalogEntry,\n type PipeCategory,\n type PipeEntryWithLatestVersion,\n type PipeId,\n} from \"@pipe0/base\";\nimport {\n type ColumnFilter,\n createColumnHelper,\n getCoreRowModel,\n getFilteredRowModel,\n useReactTable,\n} from \"@tanstack/react-table\";\nimport { useCallback, useMemo, useState } from \"react\";\nimport type { PipeCardData } from \"../types/catalog-adapters.js\";\nimport { fuzzyFilter } from \"../utils/catalog-helpers.js\";\nimport { useDebounce } from \"./use-debounce.js\";\n\nexport type InputFieldEntries = Record<string, PipeId[]>;\nexport type OutputFieldEntries = Record<string, PipeId[]>;\n\nconst columnHelper = createColumnHelper<PipeEntryWithLatestVersion>();\n\nconst columns = [\n columnHelper.accessor(\"pipeId\", {\n filterFn: \"includesString\",\n enableGlobalFilter: true,\n }),\n columnHelper.accessor(\"label\", {\n filterFn: \"fuzzy\" as any,\n enableGlobalFilter: true,\n }),\n columnHelper.accessor(\"description\", {\n filterFn: \"fuzzy\" as any,\n enableGlobalFilter: true,\n }),\n columnHelper.accessor(\n (row) =>\n row.defaultInputRequirement\n ? collectRequirementFields(row.defaultInputRequirement).map(({ field }) => field.name)\n : [],\n {\n id: \"inputFields\",\n filterFn: \"arrIncludes\",\n enableGlobalFilter: false,\n },\n ),\n columnHelper.accessor((row) => getDefaultOutputFields(row) || [], {\n id: \"outputFields\",\n filterFn: \"arrIncludes\",\n enableGlobalFilter: false,\n }),\n columnHelper.accessor((row) => row.tags || [], {\n id: \"tags\",\n filterFn: \"arrIncludes\",\n enableGlobalFilter: true,\n }),\n columnHelper.accessor((row) => getDefaultPipeProviders(row.pipeId) || [], {\n id: \"providers\",\n filterFn: \"arrIncludes\",\n enableGlobalFilter: true,\n }),\n];\n\nexport function usePipeCatalogTable(\n config: {\n initialColumnFilters?: ColumnFilter[];\n /**\n * Optional whitelist/blacklist of pipes and providers. Memoize to avoid\n * recomputing the table data on every render.\n */\n filter?: CatalogFilter;\n } = {},\n) {\n const [category, setCategory] = useState<PipeCategory | null>(null);\n const { initialColumnFilters = [] as ColumnFilter[], filter } = config;\n\n const initialTableData = useMemo(\n () => filterPipeEntries(getInitialTableData(category), filter),\n [category, filter],\n );\n\n // Baseline (config.filter applied, but no category / column / global filter).\n // Drives the stable category-button counts so the row doesn't jump when the\n // user changes a filter.\n const baselineTableData = useMemo(\n () => filterPipeEntries(getInitialTableData(null), filter),\n [filter],\n );\n\n const table = useReactTable({\n columns,\n data: initialTableData,\n getCoreRowModel: getCoreRowModel(),\n getFilteredRowModel: getFilteredRowModel(),\n globalFilterFn: fuzzyFilter,\n filterFns: {\n fuzzy: fuzzyFilter,\n },\n getColumnCanGlobalFilter: (column) => column.columnDef.enableGlobalFilter !== false,\n initialState: {\n columnFilters: initialColumnFilters,\n pagination: {\n pageSize: 10,\n },\n },\n });\n\n const columnFilters = table.getState().columnFilters;\n\n const aggregates = useMemo(\n () => getTableDataAggregates(initialTableData, category),\n [category, initialTableData],\n );\n\n const [globalFilterInput, setGlobalFilterInput, setGlobalFilterImmediately] = useDebounce((v) => {\n if (v === table.getState().globalFilter) return;\n table.setGlobalFilter(v);\n if (v) {\n setCategory(null);\n table.setColumnFilters([]);\n }\n });\n\n const addColumnFilter = useCallback(\n (id: \"inputFields\" | \"outputFields\" | \"tags\" | \"providers\", value: string) => {\n setGlobalFilterImmediately(\"\");\n table.setColumnFilters([{ id, value }]);\n },\n [setGlobalFilterImmediately, table],\n );\n\n const handleCategoryChange = useCallback(\n (category: PipeCategory | null) => {\n setCategory(category);\n table.setColumnFilters([]);\n setGlobalFilterImmediately(\"\");\n },\n [table, setGlobalFilterImmediately],\n );\n\n const resetFilters = useCallback(() => {\n setGlobalFilterImmediately(\"\");\n setCategory(null);\n }, [setGlobalFilterImmediately]);\n\n const removeColumnFilter = useCallback(\n (id: \"inputFields\" | \"outputFields\" | \"tags\" | \"providers\") => {\n table.getColumn(id)?.setFilterValue(null);\n },\n [table],\n );\n\n const getColumnFilterValue = useCallback(\n (id: \"inputFields\" | \"outputFields\" | \"tags\" | \"providers\") => {\n const res = columnFilters.find((f) => f.id === id)?.value;\n return res as string;\n },\n [columnFilters],\n );\n\n // Pre-compute card display data so consumers don't have to. Memoized on\n // the filtered rows + aggregate map (both stable references from tanstack).\n const rows = table.getRowModel().rows;\n const cards = useMemo<PipeCardData[]>(\n () =>\n rows.map((row) => {\n const entry = row.original;\n const latestEntry = (aggregates.pipeEntriesByBasePipe[entry.basePipe]?.[0] ??\n entry) as PipeCatalogEntry & { pipeId: PipeId };\n const providers = getDefaultPipeProviders(latestEntry.pipeId);\n return {\n pipeId: latestEntry.pipeId,\n basePipe: entry.basePipe,\n label: entry.label,\n description: entry.description,\n providers,\n startingCostPerProvider: getStartingCostPerPipesProvider(latestEntry.pipeId),\n startingCreditAmount: getLowestPipeCreditAmount(latestEntry),\n costMode: isTokenBilledOperations(latestEntry.billableOperations)\n ? \"usage\"\n : \"per_result\",\n defaultInputFields: latestEntry.defaultInputRequirement\n ? collectRequirementFields(latestEntry.defaultInputRequirement).map(({ field }) => ({\n name: field.name,\n }))\n : [],\n defaultOutputFields: getDefaultOutputFields(latestEntry) ?? [],\n docPath: latestEntry.docPath,\n entry,\n latestEntry,\n };\n }),\n [rows, aggregates.pipeEntriesByBasePipe],\n );\n\n // Group cards by category. Pipes can belong to multiple categories — they\n // appear once per matching category. Order: insertion (first-seen).\n const cardsByCategory = useMemo<{ category: PipeCategory; cards: PipeCardData[] }[]>(() => {\n const groups = new Map<PipeCategory, PipeCardData[]>();\n for (const card of cards) {\n const cats = (card.entry.categories ?? []) as PipeCategory[];\n for (const cat of cats) {\n const arr = groups.get(cat);\n if (arr) arr.push(card);\n else groups.set(cat, [card]);\n }\n }\n return Array.from(groups, ([category, group]) => ({\n category,\n cards: group,\n }));\n }, [cards]);\n\n // Count of cards per category (a pipe in N categories counts N times).\n const categoryCounts = useMemo<Partial<Record<PipeCategory, number>>>(() => {\n const counts: Partial<Record<PipeCategory, number>> = {};\n for (const card of cards) {\n const cats = (card.entry.categories ?? []) as PipeCategory[];\n for (const cat of cats) {\n counts[cat] = (counts[cat] ?? 0) + 1;\n }\n }\n return counts;\n }, [cards]);\n\n // Stable counts based on the baseline (no category / column / global filter\n // applied). Use these to render category-selector counts that don't jump as\n // the user clicks around.\n const baselineCardCount = baselineTableData.length;\n const baselineCategoryCounts = useMemo<Partial<Record<PipeCategory, number>>>(() => {\n const counts: Partial<Record<PipeCategory, number>> = {};\n for (const entry of baselineTableData) {\n const cats = (entry.categories ?? []) as PipeCategory[];\n for (const cat of cats) {\n counts[cat] = (counts[cat] ?? 0) + 1;\n }\n }\n return counts;\n }, [baselineTableData]);\n\n return {\n table,\n cards,\n cardsByCategory,\n categoryCounts,\n baselineCardCount,\n baselineCategoryCounts,\n\n // category + global filter\n category,\n setCategory: handleCategoryChange,\n globalFilterInput,\n setGlobalFilterInput,\n\n // mutators\n addColumnFilter,\n removeColumnFilter,\n resetFilters,\n getColumnFilterValue,\n\n // aggregates for filter UI\n sortedInputFieldEntries: aggregates.sortedInputFieldEntries,\n sortedOutputFieldEntries: aggregates.sortedOutputFieldEntries,\n sortedTagEntries: aggregates.sortedTagEntries,\n sortedProviderEntries: aggregates.sortedProviderEntries,\n\n // reverse indexes (power-user / inverted-filter UX)\n pipeIdsByInputField: aggregates.pipeIdsByInputField,\n pipeIdsByOutputField: aggregates.pipeIdsByOutputField,\n pipeIdsByProvider: aggregates.pipeIdsByProvider,\n pipeIdsByTag: aggregates.pipeIdsByTag,\n };\n}\n\nexport type UsePipeCatalogTableReturn = ReturnType<typeof usePipeCatalogTable>;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-pipe-form.d.mts","names":[],"sources":["../../src/hooks/use-pipe-form.ts"],"mappings":";;;;;;UAwBiB,kBAAA;EACf,MAAA,EAAQ,MAAA;EACR,SAAA;EACA,aAAA,GAAgB,WAAA;EAChB,SAAA,GAAY,aAAA;EACZ,eAAA;IAAoB,SAAA;IAAmB,QAAA;EAAA;EACvC,iBAAA,GAAoB,iBAAA;EACpB,KAAA,GAAQ,SAAA;EAUE;;;;;EAJV,UAAA,GAAa,UAAA;EAVb;EAYA,QAAA,GAAW,QAAA;EAXX;EAaA,OAAA,GAAU,OAAA;EAZV;;;;EAiBA,MAAA;EAfA;;;;EAoBA,MAAA;AAAA;AAAA,iBAGc,WAAA,CAAY,OAAA,EAAS,kBAAA,GAAqB,eAAA"}
1
+ {"version":3,"file":"use-pipe-form.d.mts","names":[],"sources":["../../src/hooks/use-pipe-form.ts"],"mappings":";;;;;;UAkBiB,kBAAA;EACf,MAAA,EAAQ,MAAA;EACR,SAAA;EACA,aAAA,GAAgB,WAAA;EAChB,SAAA,GAAY,aAAA;EACZ,eAAA;IAAoB,SAAA;IAAmB,QAAA;EAAA;EACvC,iBAAA,GAAoB,iBAAA;EACpB,KAAA,GAAQ,SAAA;EAUE;;;;;EAJV,UAAA,GAAa,UAAA;EAVb;EAYA,QAAA,GAAW,QAAA;EAXX;EAaA,OAAA,GAAU,OAAA;EAZV;;;;EAiBA,MAAA;EAfA;;;;EAoBA,MAAA;AAAA;AAAA,iBAGc,WAAA,CAAY,OAAA,EAAS,kBAAA,GAAqB,eAAA"}
@@ -1,5 +1,4 @@
1
1
  import { asFormHandle } from "../utils/internal-form.mjs";
2
- import { applyFormCustomization } from "../utils/build-section-handlers.mjs";
3
2
  import { useFormCore } from "./use-form-core.mjs";
4
3
  import { useMemo, useState } from "react";
5
4
  import { getPipeDefaultPayload, getPipePayloadFormConfig, getPipePayloadSchema } from "@pipe0/base";
@@ -9,6 +8,7 @@ function usePipeForm(options) {
9
8
  const { pipeId, publicKey, defaultValues, resolvers, validationContext, store: defaultFormStore, sectionMap, groupMap, pathMap, scopes, teamId } = options;
10
9
  const schema = useMemo(() => getPipePayloadSchema(pipeId), [pipeId]);
11
10
  const [store, setStore] = useState(defaultFormStore ?? { field_options: {} });
11
+ const hasGetConnections = resolvers?.getConnections != null;
12
12
  const core = useFormCore({
13
13
  pipeOrSearchId: pipeId,
14
14
  kind: "pipe",
@@ -24,34 +24,33 @@ function usePipeForm(options) {
24
24
  pipePayload: defaultPayload,
25
25
  store,
26
26
  validationContext,
27
- formResolvers: resolvers
27
+ formResolvers: resolvers,
28
+ customization: {
29
+ sectionMap,
30
+ groupMap: hasGetConnections ? groupMap : {
31
+ ...groupMap,
32
+ connector: null
33
+ },
34
+ pathMap
35
+ }
28
36
  });
29
37
  }, [
30
38
  pipeId,
31
- defaultValues,
32
39
  validationContext,
33
- store
40
+ store,
41
+ JSON.stringify({
42
+ sectionMap,
43
+ groupMap,
44
+ pathMap,
45
+ hasGetConnections
46
+ })
34
47
  ]),
35
48
  resolvers,
36
49
  environment: validationContext?.environment,
37
50
  scopes,
38
51
  teamId
39
52
  });
40
- const hasGetConnections = resolvers?.getConnections != null;
41
- const customization = useMemo(() => ({
42
- sectionMap: hasGetConnections ? sectionMap ?? {} : {
43
- ...sectionMap ?? {},
44
- connector: null
45
- },
46
- groupMap: groupMap ?? {},
47
- pathMap: pathMap ?? {}
48
- }), [
49
- sectionMap,
50
- groupMap,
51
- pathMap,
52
- hasGetConnections
53
- ]);
54
- const sections = useMemo(() => applyFormCustomization(core.sections, customization), [core.sections, customization]);
53
+ const sections = core.sections;
55
54
  const fields = useMemo(() => sections.flatMap((s) => s.groups.flatMap((g) => g.fields)), [sections]);
56
55
  const fieldPaths = useMemo(() => new Set(sections.flatMap((s) => s.groups.flatMap((g) => g.fields.map((f) => f.path)))), [sections]);
57
56
  return useMemo(() => ({