@pipe0/react 0.1.7 → 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 (162) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/components/compound/effect-catalog/card.d.mts +22 -0
  3. package/dist/components/compound/effect-catalog/card.d.mts.map +1 -0
  4. package/dist/components/compound/effect-catalog/card.mjs +82 -0
  5. package/dist/components/compound/effect-catalog/card.mjs.map +1 -0
  6. package/dist/components/compound/effect-catalog/category-filter.d.mts +27 -0
  7. package/dist/components/compound/effect-catalog/category-filter.d.mts.map +1 -0
  8. package/dist/components/compound/effect-catalog/category-filter.mjs +61 -0
  9. package/dist/components/compound/effect-catalog/category-filter.mjs.map +1 -0
  10. package/dist/components/compound/effect-catalog/empty.d.mts +17 -0
  11. package/dist/components/compound/effect-catalog/empty.d.mts.map +1 -0
  12. package/dist/components/compound/effect-catalog/empty.mjs +29 -0
  13. package/dist/components/compound/effect-catalog/empty.mjs.map +1 -0
  14. package/dist/components/compound/effect-catalog/index.d.mts +6 -0
  15. package/dist/components/compound/effect-catalog/list.d.mts +19 -0
  16. package/dist/components/compound/effect-catalog/list.d.mts.map +1 -0
  17. package/dist/components/compound/effect-catalog/list.mjs +33 -0
  18. package/dist/components/compound/effect-catalog/list.mjs.map +1 -0
  19. package/dist/components/compound/effect-catalog/root.d.mts +31 -0
  20. package/dist/components/compound/effect-catalog/root.d.mts.map +1 -0
  21. package/dist/components/compound/effect-catalog/root.mjs +67 -0
  22. package/dist/components/compound/effect-catalog/root.mjs.map +1 -0
  23. package/dist/components/compound/effect-catalog/search-filter.d.mts +21 -0
  24. package/dist/components/compound/effect-catalog/search-filter.d.mts.map +1 -0
  25. package/dist/components/compound/effect-catalog/search-filter.mjs +47 -0
  26. package/dist/components/compound/effect-catalog/search-filter.mjs.map +1 -0
  27. package/dist/components/compound/pipe-catalog/card.mjs +1 -1
  28. package/dist/components/compound/pipe-catalog/category-filter.mjs +1 -1
  29. package/dist/components/compound/pipe-catalog/provider-filter.mjs +1 -1
  30. package/dist/components/compound/pipe-catalog/root.mjs +1 -1
  31. package/dist/components/compound/pipe-form/content.d.mts +6 -1
  32. package/dist/components/compound/pipe-form/content.d.mts.map +1 -1
  33. package/dist/components/compound/pipe-form/content.mjs +3 -2
  34. package/dist/components/compound/pipe-form/content.mjs.map +1 -1
  35. package/dist/components/compound/pipe-form/errors.d.mts.map +1 -1
  36. package/dist/components/compound/pipe-form/errors.mjs +5 -4
  37. package/dist/components/compound/pipe-form/errors.mjs.map +1 -1
  38. package/dist/components/compound/pipe-form/root.d.mts +3 -1
  39. package/dist/components/compound/pipe-form/root.d.mts.map +1 -1
  40. package/dist/components/compound/pipe-form/root.mjs +5 -3
  41. package/dist/components/compound/pipe-form/root.mjs.map +1 -1
  42. package/dist/components/compound/search-catalog/active-filters.mjs +1 -1
  43. package/dist/components/compound/search-catalog/category-filter.mjs +1 -1
  44. package/dist/components/compound/search-catalog/provider-filter.mjs +1 -1
  45. package/dist/components/compound/search-form/content.d.mts +6 -1
  46. package/dist/components/compound/search-form/content.d.mts.map +1 -1
  47. package/dist/components/compound/search-form/content.mjs +3 -2
  48. package/dist/components/compound/search-form/content.mjs.map +1 -1
  49. package/dist/components/compound/search-form/errors.d.mts.map +1 -1
  50. package/dist/components/compound/search-form/errors.mjs +5 -4
  51. package/dist/components/compound/search-form/errors.mjs.map +1 -1
  52. package/dist/components/compound/search-form/root.d.mts +3 -1
  53. package/dist/components/compound/search-form/root.d.mts.map +1 -1
  54. package/dist/components/compound/search-form/root.mjs +5 -3
  55. package/dist/components/compound/search-form/root.mjs.map +1 -1
  56. package/dist/components/compound/searches-catalog/active-filters.mjs +1 -1
  57. package/dist/components/compound/searches-catalog/category-filter.mjs +1 -1
  58. package/dist/components/compound/searches-catalog/provider-filter.mjs +1 -1
  59. package/dist/components/defaults/adapters/context-select-input.mjs +1 -1
  60. package/dist/components/defaults/adapters/context-select-input.mjs.map +1 -1
  61. package/dist/components/defaults/adapters/exact-range-input.mjs +1 -1
  62. package/dist/components/defaults/adapters/index.d.mts.map +1 -1
  63. package/dist/components/defaults/adapters/index.mjs +8 -5
  64. package/dist/components/defaults/adapters/index.mjs.map +1 -1
  65. package/dist/components/defaults/adapters/int-input.mjs.map +1 -1
  66. package/dist/components/defaults/adapters/json-extraction-input.mjs +1 -1
  67. package/dist/components/defaults/adapters/loose-object-input.mjs +111 -0
  68. package/dist/components/defaults/adapters/loose-object-input.mjs.map +1 -0
  69. package/dist/components/defaults/adapters/pipes-run-if-input.mjs +69 -56
  70. package/dist/components/defaults/adapters/pipes-run-if-input.mjs.map +1 -1
  71. package/dist/components/defaults/adapters/providers-input.mjs.map +1 -1
  72. package/dist/components/defaults/adapters/search-payload-input.mjs +18 -0
  73. package/dist/components/defaults/adapters/search-payload-input.mjs.map +1 -0
  74. package/dist/components/defaults/adapters/select-input.mjs +46 -27
  75. package/dist/components/defaults/adapters/select-input.mjs.map +1 -1
  76. package/dist/components/defaults/catalog/card-derived.d.mts +1 -1
  77. package/dist/components/defaults/catalog/card-derived.d.mts.map +1 -1
  78. package/dist/components/defaults/catalog/card-derived.mjs +12 -6
  79. package/dist/components/defaults/catalog/card-derived.mjs.map +1 -1
  80. package/dist/components/defaults/catalog/provider-avatars.mjs +3 -3
  81. package/dist/components/defaults/catalog/provider-avatars.mjs.map +1 -1
  82. package/dist/components/defaults/form/form-empty-state.mjs +23 -0
  83. package/dist/components/defaults/form/form-empty-state.mjs.map +1 -0
  84. package/dist/components/defaults/layout/field-wrapper.d.mts.map +1 -1
  85. package/dist/components/defaults/layout/field-wrapper.mjs +11 -5
  86. package/dist/components/defaults/layout/field-wrapper.mjs.map +1 -1
  87. package/dist/components/defaults/layout/group.mjs +1 -1
  88. package/dist/components/internal/LiquidEditor/LiquidEditor.mjs +2 -2
  89. package/dist/components/internal/LiquidEditor/LiquidEditor.mjs.map +1 -1
  90. package/dist/components/internal/form-level-errors.mjs +4 -3
  91. package/dist/components/internal/form-level-errors.mjs.map +1 -1
  92. package/dist/components/internal/icons.mjs +27 -1
  93. package/dist/components/internal/icons.mjs.map +1 -1
  94. package/dist/components/ui/alert.d.mts +47 -0
  95. package/dist/components/ui/alert.d.mts.map +1 -0
  96. package/dist/components/ui/alert.mjs +66 -0
  97. package/dist/components/ui/alert.mjs.map +1 -0
  98. package/dist/context/catalog-card-context.mjs +4 -2
  99. package/dist/context/catalog-card-context.mjs.map +1 -1
  100. package/dist/context/effect-catalog-card-context.d.mts +20 -0
  101. package/dist/context/effect-catalog-card-context.d.mts.map +1 -0
  102. package/dist/context/effect-catalog-card-context.mjs +13 -0
  103. package/dist/context/effect-catalog-card-context.mjs.map +1 -0
  104. package/dist/context/effect-catalog-context.d.mts +20 -0
  105. package/dist/context/effect-catalog-context.d.mts.map +1 -0
  106. package/dist/context/effect-catalog-context.mjs +13 -0
  107. package/dist/context/effect-catalog-context.mjs.map +1 -0
  108. package/dist/context/form-context.d.mts +21 -0
  109. package/dist/context/form-context.d.mts.map +1 -0
  110. package/dist/context/form-context.mjs +11 -1
  111. package/dist/context/form-context.mjs.map +1 -1
  112. package/dist/context/form-provider.d.mts +3 -1
  113. package/dist/context/form-provider.d.mts.map +1 -1
  114. package/dist/context/form-provider.mjs +8 -2
  115. package/dist/context/form-provider.mjs.map +1 -1
  116. package/dist/hooks/use-effect-catalog-table.d.mts +33 -0
  117. package/dist/hooks/use-effect-catalog-table.d.mts.map +1 -0
  118. package/dist/hooks/use-effect-catalog-table.mjs +104 -0
  119. package/dist/hooks/use-effect-catalog-table.mjs.map +1 -0
  120. package/dist/hooks/use-form-core.mjs +8 -5
  121. package/dist/hooks/use-form-core.mjs.map +1 -1
  122. package/dist/hooks/use-pipe-catalog-table.d.mts +8 -8
  123. package/dist/hooks/use-pipe-catalog-table.d.mts.map +1 -1
  124. package/dist/hooks/use-pipe-catalog-table.mjs +2 -2
  125. package/dist/hooks/use-pipe-catalog-table.mjs.map +1 -1
  126. package/dist/hooks/use-pipe-form.d.mts.map +1 -1
  127. package/dist/hooks/use-pipe-form.mjs +18 -19
  128. package/dist/hooks/use-pipe-form.mjs.map +1 -1
  129. package/dist/hooks/use-search-catalog-table.d.mts +6 -6
  130. package/dist/hooks/use-search-form.d.mts.map +1 -1
  131. package/dist/hooks/use-search-form.mjs +18 -18
  132. package/dist/hooks/use-search-form.mjs.map +1 -1
  133. package/dist/hooks/use-sheet-effect-form.d.mts +35 -0
  134. package/dist/hooks/use-sheet-effect-form.d.mts.map +1 -0
  135. package/dist/hooks/use-sheet-effect-form.mjs +103 -0
  136. package/dist/hooks/use-sheet-effect-form.mjs.map +1 -0
  137. package/dist/index.d.mts +15 -3
  138. package/dist/index.mjs +16 -4
  139. package/dist/styles/pipe0-form.css +1 -1
  140. package/dist/types/adapters.d.mts +22 -1
  141. package/dist/types/adapters.d.mts.map +1 -1
  142. package/dist/types/catalog-adapters.d.mts +23 -3
  143. package/dist/types/catalog-adapters.d.mts.map +1 -1
  144. package/dist/types/field-props.d.mts +15 -13
  145. package/dist/types/field-props.d.mts.map +1 -1
  146. package/dist/types/form-customization.d.mts +2 -25
  147. package/dist/utils/build-section-handlers.mjs +9 -75
  148. package/dist/utils/build-section-handlers.mjs.map +1 -1
  149. package/dist/utils/catalog-helpers.d.mts +1 -1
  150. package/dist/widgets/token-pricing-badge.d.mts +1 -0
  151. package/dist/widgets/token-pricing-badge.mjs +55 -0
  152. package/dist/widgets/token-pricing-badge.mjs.map +1 -0
  153. package/dist/widgets/widget-strip.d.mts.map +1 -1
  154. package/dist/widgets/widget-strip.mjs +1 -0
  155. package/dist/widgets/widget-strip.mjs.map +1 -1
  156. package/dist/widgets/widget-view.d.mts.map +1 -1
  157. package/dist/widgets/widget-view.mjs +6 -0
  158. package/dist/widgets/widget-view.mjs.map +1 -1
  159. package/package.json +15 -25
  160. package/dist/components/defaults/adapters/key-value-list-input.mjs +0 -102
  161. package/dist/components/defaults/adapters/key-value-list-input.mjs.map +0 -1
  162. package/dist/types/form-customization.d.mts.map +0 -1
@@ -1,25 +1,2 @@
1
- import { IconKey, SectionKeys } from "@pipe0/base";
2
-
3
- //#region src/types/form-customization.d.ts
4
- interface SectionOverride {
5
- label?: string;
6
- description?: string;
7
- order?: number;
8
- }
9
- type SectionMap = Partial<Record<SectionKeys, SectionOverride | null>>;
10
- interface GroupOverride {
11
- label?: string;
12
- description?: string;
13
- order?: number;
14
- iconKey?: IconKey;
15
- defaultExpand?: boolean;
16
- }
17
- type GroupMap = Record<string, GroupOverride | null>;
18
- interface PathOverride {
19
- label?: string;
20
- description?: string;
21
- }
22
- type PathMap = Record<string, PathOverride | null>;
23
- //#endregion
24
- export { GroupMap, GroupOverride, PathMap, PathOverride, SectionMap, SectionOverride };
25
- //# sourceMappingURL=form-customization.d.mts.map
1
+ import { GroupMap, GroupOverride, PathMap, PathOverride, SectionMap, SectionOverride } from "@pipe0/base";
2
+ export { type GroupMap, type GroupOverride, type PathMap, type PathOverride, type SectionMap, type SectionOverride };
@@ -321,27 +321,12 @@ function buildExtras(meta, base, publicKey, loadingCtx) {
321
321
  else result.options = withMergedWidgets(m.suggestionsDef.options, m.suggestionsDef.widgets);
322
322
  return result;
323
323
  }
324
- if (inputGuards.key_value_list_input(meta)) {
325
- const rows = base.value ?? [];
326
- return {
327
- rows,
328
- addRow: () => base.setValue([...rows, {
329
- key: "",
330
- value: ""
331
- }]),
332
- removeRow: (index) => base.setValue(rows.filter((_, i) => i !== index)),
333
- setKey: (index, key) => base.setValue(rows.map((row, i) => i === index ? {
334
- ...row,
335
- key
336
- } : row)),
337
- setValue: (index, value) => base.setValue(rows.map((row, i) => i === index ? {
338
- ...row,
339
- value
340
- } : row)),
341
- searchSecrets: loadingCtx?.searchSecrets,
342
- searchConstants: loadingCtx?.searchConstants
343
- };
344
- }
324
+ if (inputGuards.loose_object_input(meta)) return {
325
+ value: base.value ?? {},
326
+ setObject: (next) => base.setValue(next),
327
+ searchSecrets: loadingCtx?.searchSecrets,
328
+ searchConstants: loadingCtx?.searchConstants
329
+ };
345
330
  if (inputGuards.prompt_input(meta) || inputGuards.template_input(meta)) return {
346
331
  searchSecrets: loadingCtx?.searchSecrets,
347
332
  searchConstants: loadingCtx?.searchConstants
@@ -363,7 +348,7 @@ function buildSectionHandles(formConfig, form, publicKey, loadingCtx) {
363
348
  const hasSubmitted = form.formState.isSubmitted;
364
349
  return formConfig.map((section) => {
365
350
  const groups = section.groups.map((group) => {
366
- const fields = group.fields.map((meta) => buildFieldProps(meta, form, publicKey, loadingCtx));
351
+ const fields = group.fields.filter((meta) => !(inputGuards.connector_input(meta) && meta.connectorMode === "disabled")).map((meta) => buildFieldProps(meta, form, publicKey, loadingCtx));
367
352
  const groupPathError = form.getFieldState(group.groupPath).error;
368
353
  const errorCount = hasSubmitted ? fields.filter((f) => f.error != null).length + (groupPathError ? 1 : 0) : 0;
369
354
  const setCount = fields.filter((f) => !isEmptyValue(f.value)).length;
@@ -379,67 +364,16 @@ function buildSectionHandles(formConfig, form, publicKey, loadingCtx) {
379
364
  setCount,
380
365
  dirtyCount
381
366
  };
382
- });
367
+ }).filter((group) => group.fields.length > 0);
383
368
  return {
384
369
  key: section.metadata.path,
385
370
  label: section.metadata.label,
386
371
  description: section.metadata.description,
387
372
  groups
388
373
  };
389
- });
390
- }
391
- function applyFormCustomization(sections, customization) {
392
- const { sectionMap, groupMap, pathMap } = customization;
393
- const hasSectionOverrides = Object.keys(sectionMap).length > 0;
394
- const hasGroupOverrides = Object.keys(groupMap).length > 0;
395
- const hasPathOverrides = Object.keys(pathMap).length > 0;
396
- if (!hasSectionOverrides && !hasGroupOverrides && !hasPathOverrides) return sections;
397
- return sections.filter((section) => sectionMap[section.key] !== null).map((section) => {
398
- const sectionOverride = sectionMap[section.key];
399
- const mergedSection = sectionOverride ? {
400
- ...section,
401
- label: sectionOverride.label ?? section.label,
402
- description: sectionOverride.description ?? section.description
403
- } : section;
404
- const groups = mergedSection.groups.filter((group) => groupMap[group.key] !== null).map((group) => {
405
- const groupOverride = groupMap[group.key];
406
- const mergedGroup = groupOverride ? {
407
- ...group,
408
- label: groupOverride.label ?? group.label,
409
- description: groupOverride.description ?? group.description,
410
- iconKey: groupOverride.iconKey ?? group.iconKey,
411
- defaultExpand: groupOverride.defaultExpand ?? group.defaultExpand
412
- } : group;
413
- const fields = mergedGroup.fields.filter((field) => pathMap[field.path] !== null).map((field) => {
414
- const fieldOverride = pathMap[field.path];
415
- if (!fieldOverride) return field;
416
- return {
417
- ...field,
418
- label: fieldOverride.label ?? field.label,
419
- description: fieldOverride.description ?? field.description
420
- };
421
- });
422
- const fieldErrorsBefore = group.fields.filter((f) => f.error != null).length;
423
- const groupPathErrors = group.errorCount - fieldErrorsBefore;
424
- const fieldErrorsAfter = fields.filter((f) => f.error != null).length;
425
- const errorCount = group.errorCount > 0 ? fieldErrorsAfter + groupPathErrors : 0;
426
- const setCount = fields.filter((f) => !isEmptyValue(f.value)).length;
427
- const dirtyCount = fields.filter((f) => f.dirty).length;
428
- return {
429
- ...mergedGroup,
430
- fields,
431
- errorCount,
432
- setCount,
433
- dirtyCount
434
- };
435
- }).filter((group) => group.fields.length > 0);
436
- return {
437
- ...mergedSection,
438
- groups
439
- };
440
374
  }).filter((section) => section.groups.length > 0);
441
375
  }
442
376
 
443
377
  //#endregion
444
- export { applyFormCustomization, buildSectionHandles };
378
+ export { buildSectionHandles };
445
379
  //# sourceMappingURL=build-section-handlers.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"build-section-handlers.mjs","names":[],"sources":["../../src/utils/build-section-handlers.ts"],"sourcesContent":["import type { FormSection, GeneratedInputMeta, SecretSuggestion, SectionKeys } from \"@pipe0/base\";\nimport { inputGuards } from \"@pipe0/base\";\nimport type { UseFormReturn } from \"react-hook-form\";\nimport type { FieldLoadState } from \"../hooks/use-form-core.js\";\nimport type {\n AnyFieldProps,\n ConstantSuggestion,\n GeneratedFieldProps,\n} from \"../types/field-props.js\";\nimport type { FormCustomizationState } from \"../types/form-customization.js\";\nimport type { FormGroupHandle, FormSectionHandle } from \"../types/form-handle.js\";\n\nexport interface FieldLoadingContext {\n /** Per-field load states for dynamic context_select_input fields, keyed by path. */\n fieldLoadStates: Record<string, FieldLoadState>;\n /**\n * Curried per-keystroke secrets searcher. Bundles the form-level\n * `environment` / `scopes` / `teamId` so adapters only need to pass the\n * user's typed query. Returns `[]` when no `getSecrets` resolver is wired.\n */\n searchSecrets?: (query: string) => Promise<SecretSuggestion[]>;\n /**\n * Curried per-keystroke constants searcher. Mirrors `searchSecrets`.\n * Returns `[]` when no `getConstants` resolver is wired.\n */\n searchConstants?: (query: string) => Promise<ConstantSuggestion[]>;\n}\n\n/**\n * Builds a fully-typed `GeneratedFieldProps` from raw metadata + form state.\n *\n * The returned object includes:\n * - Base props (kind, meta, value, setValue, error, etc.)\n * - Kind-specific extras (inputProps, options, toggle, etc.)\n */\nexport function buildFieldProps<Meta extends GeneratedInputMeta>(\n meta: Meta,\n form: UseFormReturn<Record<string, unknown>>,\n publicKey: string,\n loadingCtx?: FieldLoadingContext,\n): GeneratedFieldProps<Meta[\"type\"]> {\n const path = meta.path;\n const fieldState = form.getFieldState(path as any);\n const value = form.getValues(path as any);\n const id = `p0-field-${path.replace(/\\./g, \"-\")}`;\n\n const setValue = (v: unknown) =>\n form.setValue(path as any, v, {\n shouldDirty: true,\n shouldTouch: true,\n shouldValidate: true,\n });\n\n // Match the submit-gated behavior used everywhere else (group errorCount,\n // `useFieldError`): don't surface the field's error until the user has\n // attempted a submit. Otherwise `setValue`-triggered validation would\n // flash errors the moment the form is interacted with.\n const hasSubmitted = form.formState.isSubmitted;\n\n const loadState = loadingCtx?.fieldLoadStates?.[path];\n\n const base = {\n kind: meta.type,\n meta,\n form,\n path,\n label: meta.label ?? \"\",\n description: meta.description,\n info: meta.info,\n error: hasSubmitted ? fieldState.error?.message : undefined,\n touched: fieldState.isTouched,\n dirty: fieldState.isDirty,\n id,\n value,\n setValue,\n reset: () => form.resetField(path as any),\n disabled: loadState?.disabled ?? false,\n disabledReason: loadState?.disabledReason,\n };\n\n const extras = buildExtras(meta, { path, id, value, setValue }, publicKey, loadingCtx);\n\n return { ...base, ...extras } as unknown as GeneratedFieldProps<Meta[\"type\"]>;\n}\n\n// Re-export under old name for backward compat\nexport { buildFieldProps as buildFieldHandle };\n\ntype OptionLike = {\n value: string;\n label: string;\n widgets?: Record<string, Record<string, unknown>>;\n};\n\nfunction withMergedWidgets<T extends OptionLike>(\n options: T[],\n staticWidgets: Record<string, Record<string, unknown>> | undefined,\n): T[] {\n if (!staticWidgets) return options;\n return options.map((o) => ({\n ...o,\n widgets: { ...staticWidgets, ...(o.widgets ?? {}) },\n }));\n}\n\nfunction buildExtras(\n meta: GeneratedInputMeta,\n base: {\n path: string;\n id: string;\n value: unknown;\n setValue: (v: unknown) => void;\n },\n publicKey: string,\n loadingCtx?: FieldLoadingContext,\n): Record<string, unknown> {\n if (\n inputGuards.text_input(meta) ||\n inputGuards.int_input(meta) ||\n inputGuards.number_input(meta)\n ) {\n const isNumber = inputGuards.int_input(meta) || inputGuards.number_input(meta);\n return {\n inputProps: {\n type: isNumber ? \"number\" : (meta as any).inputType || \"text\",\n name: base.path,\n id: base.id,\n value: base.value != null ? String(base.value) : \"\",\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => {\n const v = e.target.value;\n base.setValue(isNumber ? (v === \"\" ? null : Number(v)) : v);\n },\n placeholder: meta.placeholder,\n step: inputGuards.number_input(meta) ? \"0.001\" : undefined,\n },\n };\n }\n\n if (inputGuards.textarea_input(meta)) {\n return {\n textareaProps: {\n name: base.path,\n id: base.id,\n value: (base.value as string) ?? \"\",\n onChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => base.setValue(e.target.value),\n placeholder: meta.placeholder,\n rows: meta.rows,\n },\n };\n }\n\n if (inputGuards.select_input(meta)) {\n return {\n options: meta.options ?? [],\n selectedValue: (base.value as string) ?? \"\",\n onSelect: (v: string) => base.setValue(v),\n };\n }\n\n if (inputGuards.context_select_input(meta)) {\n const loadState = loadingCtx?.fieldLoadStates?.[meta.path];\n return {\n options: meta.options ?? [],\n selectedValue: (base.value as string) ?? \"\",\n onSelect: (v: string) => base.setValue(v),\n pending: loadState?.status === \"loading\",\n suggestionsDisabled: loadState?.suggestionsDisabled ?? false,\n suggestionsDisabledReason: loadState?.suggestionsDisabledReason,\n };\n }\n\n if (inputGuards.tagged_text_input(meta)) {\n const loadState = loadingCtx?.fieldLoadStates?.[meta.path];\n return {\n options: meta.options ?? [],\n pending: loadState?.status === \"loading\",\n suggestionsDisabled: loadState?.suggestionsDisabled ?? false,\n suggestionsDisabledReason: loadState?.suggestionsDisabledReason,\n searchSecrets: loadingCtx?.searchSecrets,\n searchConstants: loadingCtx?.searchConstants,\n };\n }\n\n if (inputGuards.providers_input(meta)) {\n return {\n options: meta.options ?? [],\n };\n }\n\n if (inputGuards.multi_select_input(meta)) {\n const selected = (base.value as string[]) ?? [];\n return {\n options: meta.options ?? [],\n selected,\n onToggle: (v: string) =>\n base.setValue(selected.includes(v) ? selected.filter((s) => s !== v) : [...selected, v]),\n onClear: () => base.setValue([]),\n };\n }\n\n if (inputGuards.async_multi_select_input(meta)) {\n const selected = (base.value as string[]) ?? [];\n return {\n loadOptions: async (query: string) =>\n withMergedWidgets(\n await meta.optionsDef.options({ query, token: publicKey }),\n meta.optionsDef.widgets,\n ),\n selected,\n onToggle: (v: string) =>\n base.setValue(selected.includes(v) ? selected.filter((s) => s !== v) : [...selected, v]),\n onClear: () => base.setValue([]),\n };\n }\n\n if (inputGuards.boolean_input(meta) || inputGuards.nullable_boolean_input(meta)) {\n return {\n checked: base.value === true,\n isNull: base.value === null || base.value === undefined,\n toggle: () => base.setValue(base.value === true ? false : true),\n clear: () => base.setValue(null),\n };\n }\n\n if (\n inputGuards.include_exclude_input(meta) ||\n inputGuards.include_exclude_select_input(meta) ||\n inputGuards.async_include_exclude_select_input(meta)\n ) {\n const current = (base.value as {\n include: string[];\n exclude: string[];\n }) ?? { include: [], exclude: [] };\n const result: Record<string, unknown> = {\n include: {\n value: current.include,\n add: (v: string) => base.setValue({ ...current, include: [...current.include, v] }),\n remove: (v: string) =>\n base.setValue({\n ...current,\n include: current.include.filter((i) => i !== v),\n }),\n },\n exclude: {\n value: current.exclude,\n add: (v: string) => base.setValue({ ...current, exclude: [...current.exclude, v] }),\n remove: (v: string) =>\n base.setValue({\n ...current,\n exclude: current.exclude.filter((i) => i !== v),\n }),\n },\n };\n const m = meta as any;\n if (m.optionsDef?.options && typeof m.optionsDef.options === \"function\") {\n result.loadOptions = async (query: string) =>\n withMergedWidgets(\n await m.optionsDef.options({ query, token: publicKey }),\n m.optionsDef.widgets,\n );\n } else if (m.optionsDef?.options) {\n result.options = withMergedWidgets(m.optionsDef.options, m.optionsDef.widgets);\n }\n if (m.suggestionsDef?.options) {\n if (typeof m.suggestionsDef.options === \"function\") {\n result.loadOptions = async (query: string) =>\n withMergedWidgets(\n await m.suggestionsDef.options({ query, token: publicKey }),\n m.suggestionsDef.widgets,\n );\n } else {\n result.options = withMergedWidgets(m.suggestionsDef.options, m.suggestionsDef.widgets);\n }\n }\n return result;\n }\n\n if (inputGuards.range_input(meta)) {\n const current = (base.value as {\n from: number | null;\n to: number | null;\n }) ?? { from: null, to: null };\n return {\n from: {\n value: current.from,\n set: (v: number | null) => base.setValue({ ...current, from: v }),\n },\n to: {\n value: current.to,\n set: (v: number | null) => base.setValue({ ...current, to: v }),\n },\n };\n }\n\n if (inputGuards.date_range_input(meta)) {\n const current = (base.value as Record<string, string>) ?? {};\n return {\n from: {\n value: current.gte ?? current.gt ?? \"\",\n set: (v: string) => base.setValue({ ...current, gte: v }),\n },\n to: {\n value: current.lte ?? current.lt ?? \"\",\n set: (v: string) => base.setValue({ ...current, lte: v }),\n },\n };\n }\n\n if (inputGuards.exact_range_input(meta)) {\n const current = (base.value as Record<string, number | null>) ?? {};\n return {\n greaterThan: {\n operator: current.gt != null ? \"gt\" : \"gte\",\n value: current.gt ?? current.gte ?? null,\n setOperator: (op: string) => {\n const otherOp = op === \"gt\" ? \"gte\" : \"gt\";\n const val = current[otherOp] ?? current[op];\n const updated = { ...current };\n delete updated[otherOp];\n if (val != null) updated[op] = val;\n base.setValue(updated);\n },\n setValue: (v: number | null) => {\n const op = current.gt != null ? \"gt\" : \"gte\";\n const updated = { ...current };\n if (v != null) updated[op] = v;\n else delete updated[op];\n base.setValue(updated);\n },\n },\n lessThan: {\n operator: current.lt != null ? \"lt\" : \"lte\",\n value: current.lt ?? current.lte ?? null,\n setOperator: (op: string) => {\n const otherOp = op === \"lt\" ? \"lte\" : \"lt\";\n const val = current[otherOp] ?? current[op];\n const updated = { ...current };\n delete updated[otherOp];\n if (val != null) updated[op] = val;\n base.setValue(updated);\n },\n setValue: (v: number | null) => {\n const op = current.lt != null ? \"lt\" : \"lte\";\n const updated = { ...current };\n if (v != null) updated[op] = v;\n else delete updated[op];\n base.setValue(updated);\n },\n },\n };\n }\n\n if (inputGuards.min_max_int_input(meta)) {\n const current = (base.value as {\n min: number | null;\n max: number | null;\n }) ?? { min: null, max: null };\n return {\n from: {\n value: current.min,\n set: (v: number | null) => base.setValue({ ...current, min: v }),\n },\n to: {\n value: current.max,\n set: (v: number | null) => base.setValue({ ...current, max: v }),\n },\n };\n }\n\n if (inputGuards.multi_create_input(meta) || inputGuards.ordered_multi_create_input(meta)) {\n const items = (base.value as string[]) ?? [];\n const result: Record<string, unknown> = {\n items,\n add: (v: string) => base.setValue([...items, v]),\n remove: (v: string) => base.setValue(items.filter((i) => i !== v)),\n };\n if (inputGuards.ordered_multi_create_input(meta)) {\n result.reorder = (from: number, to: number) => {\n const next = [...items];\n const [moved] = next.splice(from, 1);\n next.splice(to, 0, moved);\n base.setValue(next);\n };\n }\n const m = meta as any;\n if (m.suggestionsDef?.options) {\n if (typeof m.suggestionsDef.options === \"function\") {\n result.loadOptions = async (query: string) =>\n withMergedWidgets(\n await m.suggestionsDef.options({ query, token: publicKey }),\n m.suggestionsDef.widgets,\n );\n } else {\n result.options = withMergedWidgets(m.suggestionsDef.options, m.suggestionsDef.widgets);\n }\n }\n return result;\n }\n\n if (inputGuards.tagged_ordered_multi_create_input(meta)) {\n const items = (base.value as string[]) ?? [];\n const result: Record<string, unknown> = {\n items,\n setItems: (next: string[]) => base.setValue(next),\n inputFields: meta.inputFields ?? [],\n };\n const m = meta as any;\n if (m.suggestionsDef?.options) {\n if (typeof m.suggestionsDef.options === \"function\") {\n result.loadOptions = async (query: string) =>\n withMergedWidgets(\n await m.suggestionsDef.options({ query, token: publicKey }),\n m.suggestionsDef.widgets,\n );\n } else {\n result.options = withMergedWidgets(m.suggestionsDef.options, m.suggestionsDef.widgets);\n }\n }\n return result;\n }\n\n if (inputGuards.key_value_list_input(meta)) {\n const rows = (base.value as Array<{ key: string; value: string }>) ?? [];\n return {\n rows,\n addRow: () => base.setValue([...rows, { key: \"\", value: \"\" }]),\n removeRow: (index: number) => base.setValue(rows.filter((_, i) => i !== index)),\n setKey: (index: number, key: string) =>\n base.setValue(rows.map((row, i) => (i === index ? { ...row, key } : row))),\n setValue: (index: number, value: string) =>\n base.setValue(rows.map((row, i) => (i === index ? { ...row, value } : row))),\n searchSecrets: loadingCtx?.searchSecrets,\n searchConstants: loadingCtx?.searchConstants,\n };\n }\n\n if (inputGuards.prompt_input(meta) || inputGuards.template_input(meta)) {\n return {\n searchSecrets: loadingCtx?.searchSecrets,\n searchConstants: loadingCtx?.searchConstants,\n };\n }\n\n // Remaining types need no extras beyond base\n return {};\n}\n\nfunction isEmptyValue(value: unknown): boolean {\n if (value === null || typeof value === \"undefined\") return true;\n if (typeof value === \"string\") return value === \"\";\n if (Array.isArray(value)) return value.length === 0;\n if (typeof value === \"object\") {\n const keys = Object.keys(value);\n if (keys.length === 0) return true;\n return keys.every((k) => isEmptyValue((value as Record<string, unknown>)[k]));\n }\n return false;\n}\n\nexport function buildSectionHandles(\n formConfig: FormSection[],\n form: UseFormReturn<Record<string, unknown>>,\n publicKey: string,\n loadingCtx?: FieldLoadingContext,\n): FormSectionHandle[] {\n // In onSubmit validation mode, don't flag groups as invalid until the\n // user has actually attempted a submit. This matches RHF's own field-level\n // behavior where `formState.errors` is only populated after the first\n // submit (and updated reactively thereafter per `reValidateMode`).\n const hasSubmitted = form.formState.isSubmitted;\n\n return formConfig.map((section) => {\n const groups: FormGroupHandle[] = section.groups.map((group) => {\n const fields = group.fields.map((meta) =>\n buildFieldProps(meta, form, publicKey, loadingCtx),\n ) as AnyFieldProps[];\n\n const groupPathError = form.getFieldState(group.groupPath as any).error;\n const errorCount = hasSubmitted\n ? fields.filter((f) => f.error != null).length + (groupPathError ? 1 : 0)\n : 0;\n const setCount = fields.filter((f) => !isEmptyValue(f.value)).length;\n const dirtyCount = fields.filter((f) => f.dirty).length;\n\n return {\n key: group.groupPath,\n label: group.label,\n description: group.description,\n iconKey: group.iconKey,\n defaultExpand: group.defaultExpand ?? false,\n fields,\n errorCount,\n setCount,\n dirtyCount,\n };\n });\n\n return {\n key: section.metadata.path,\n label: section.metadata.label,\n description: section.metadata.description,\n groups,\n };\n });\n}\n\nexport function applyFormCustomization(\n sections: FormSectionHandle[],\n customization: FormCustomizationState,\n): FormSectionHandle[] {\n const { sectionMap, groupMap, pathMap } = customization;\n\n const hasSectionOverrides = Object.keys(sectionMap).length > 0;\n const hasGroupOverrides = Object.keys(groupMap).length > 0;\n const hasPathOverrides = Object.keys(pathMap).length > 0;\n\n if (!hasSectionOverrides && !hasGroupOverrides && !hasPathOverrides) {\n return sections;\n }\n\n return sections\n .filter((section) => sectionMap[section.key as SectionKeys] !== null)\n .map((section) => {\n const sectionOverride = sectionMap[section.key as SectionKeys];\n const mergedSection = sectionOverride\n ? {\n ...section,\n label: sectionOverride.label ?? section.label,\n description: sectionOverride.description ?? section.description,\n }\n : section;\n\n const groups = mergedSection.groups\n .filter((group) => groupMap[group.key] !== null)\n .map((group) => {\n const groupOverride = groupMap[group.key];\n const mergedGroup = groupOverride\n ? {\n ...group,\n label: groupOverride.label ?? group.label,\n description: groupOverride.description ?? group.description,\n iconKey: groupOverride.iconKey ?? group.iconKey,\n defaultExpand: groupOverride.defaultExpand ?? group.defaultExpand,\n }\n : group;\n\n const fields = mergedGroup.fields\n .filter((field) => pathMap[field.path] !== null)\n .map((field) => {\n const fieldOverride = pathMap[field.path];\n if (!fieldOverride) return field;\n return {\n ...field,\n label: fieldOverride.label ?? field.label,\n description: fieldOverride.description ?? field.description,\n };\n });\n\n // Preserve the submit-gated error count from buildSectionHandles:\n // if the original group was not flagged, don't resurrect errors\n // here just because we recount post-filter. We must also preserve\n // the group-path portion of the count — errors that attach to the\n // group container (e.g. the required connector's nested\n // `connector.connections` failure) surface there, not on any\n // field's own `error`, so recounting field errors alone would drop\n // them. Recover that portion as `original total − original field\n // errors`, then re-add it after filtering removed fields.\n const fieldErrorsBefore = group.fields.filter((f) => f.error != null).length;\n const groupPathErrors = group.errorCount - fieldErrorsBefore;\n const fieldErrorsAfter = fields.filter((f) => f.error != null).length;\n const errorCount = group.errorCount > 0 ? fieldErrorsAfter + groupPathErrors : 0;\n const setCount = fields.filter((f) => !isEmptyValue(f.value)).length;\n const dirtyCount = fields.filter((f) => f.dirty).length;\n\n return { ...mergedGroup, fields, errorCount, setCount, dirtyCount };\n })\n .filter((group) => group.fields.length > 0);\n\n return { ...mergedSection, groups };\n })\n .filter((section) => section.groups.length > 0);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"build-section-handlers.mjs","names":[],"sources":["../../src/utils/build-section-handlers.ts"],"sourcesContent":["import type { FormSection, GeneratedInputMeta, SecretSuggestion } from \"@pipe0/base\";\nimport { inputGuards } from \"@pipe0/base\";\nimport type { UseFormReturn } from \"react-hook-form\";\nimport type { FieldLoadState } from \"../hooks/use-form-core.js\";\nimport type {\n AnyFieldProps,\n ConstantSuggestion,\n GeneratedFieldProps,\n} from \"../types/field-props.js\";\nimport type { FormGroupHandle, FormSectionHandle } from \"../types/form-handle.js\";\n\nexport interface FieldLoadingContext {\n /** Per-field load states for dynamic context_select_input fields, keyed by path. */\n fieldLoadStates: Record<string, FieldLoadState>;\n /**\n * Curried per-keystroke secrets searcher. Bundles the form-level\n * `environment` / `scopes` / `teamId` so adapters only need to pass the\n * user's typed query. Returns `[]` when no `getSecrets` resolver is wired.\n */\n searchSecrets?: (query: string) => Promise<SecretSuggestion[]>;\n /**\n * Curried per-keystroke constants searcher. Mirrors `searchSecrets`.\n * Returns `[]` when no `getConstants` resolver is wired.\n */\n searchConstants?: (query: string) => Promise<ConstantSuggestion[]>;\n}\n\n/**\n * Builds a fully-typed `GeneratedFieldProps` from raw metadata + form state.\n *\n * The returned object includes:\n * - Base props (kind, meta, value, setValue, error, etc.)\n * - Kind-specific extras (inputProps, options, toggle, etc.)\n */\nexport function buildFieldProps<Meta extends GeneratedInputMeta>(\n meta: Meta,\n form: UseFormReturn<Record<string, unknown>>,\n publicKey: string,\n loadingCtx?: FieldLoadingContext,\n): GeneratedFieldProps<Meta[\"type\"]> {\n const path = meta.path;\n const fieldState = form.getFieldState(path as any);\n const value = form.getValues(path as any);\n const id = `p0-field-${path.replace(/\\./g, \"-\")}`;\n\n const setValue = (v: unknown) =>\n form.setValue(path as any, v, {\n shouldDirty: true,\n shouldTouch: true,\n shouldValidate: true,\n });\n\n // Match the submit-gated behavior used everywhere else (group errorCount,\n // `useFieldError`): don't surface the field's error until the user has\n // attempted a submit. Otherwise `setValue`-triggered validation would\n // flash errors the moment the form is interacted with.\n const hasSubmitted = form.formState.isSubmitted;\n\n const loadState = loadingCtx?.fieldLoadStates?.[path];\n\n const base = {\n kind: meta.type,\n meta,\n form,\n path,\n label: meta.label ?? \"\",\n description: meta.description,\n info: meta.info,\n error: hasSubmitted ? fieldState.error?.message : undefined,\n touched: fieldState.isTouched,\n dirty: fieldState.isDirty,\n id,\n value,\n setValue,\n reset: () => form.resetField(path as any),\n disabled: loadState?.disabled ?? false,\n disabledReason: loadState?.disabledReason,\n };\n\n const extras = buildExtras(meta, { path, id, value, setValue }, publicKey, loadingCtx);\n\n return { ...base, ...extras } as unknown as GeneratedFieldProps<Meta[\"type\"]>;\n}\n\n// Re-export under old name for backward compat\nexport { buildFieldProps as buildFieldHandle };\n\ntype OptionLike = {\n value: string;\n label: string;\n widgets?: Record<string, Record<string, unknown>>;\n};\n\nfunction withMergedWidgets<T extends OptionLike>(\n options: T[],\n staticWidgets: Record<string, Record<string, unknown>> | undefined,\n): T[] {\n if (!staticWidgets) return options;\n return options.map((o) => ({\n ...o,\n widgets: { ...staticWidgets, ...(o.widgets ?? {}) },\n }));\n}\n\nfunction buildExtras(\n meta: GeneratedInputMeta,\n base: {\n path: string;\n id: string;\n value: unknown;\n setValue: (v: unknown) => void;\n },\n publicKey: string,\n loadingCtx?: FieldLoadingContext,\n): Record<string, unknown> {\n if (\n inputGuards.text_input(meta) ||\n inputGuards.int_input(meta) ||\n inputGuards.number_input(meta)\n ) {\n const isNumber = inputGuards.int_input(meta) || inputGuards.number_input(meta);\n return {\n inputProps: {\n type: isNumber ? \"number\" : (meta as any).inputType || \"text\",\n name: base.path,\n id: base.id,\n value: base.value != null ? String(base.value) : \"\",\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => {\n const v = e.target.value;\n base.setValue(isNumber ? (v === \"\" ? null : Number(v)) : v);\n },\n placeholder: meta.placeholder,\n step: inputGuards.number_input(meta) ? \"0.001\" : undefined,\n },\n };\n }\n\n if (inputGuards.textarea_input(meta)) {\n return {\n textareaProps: {\n name: base.path,\n id: base.id,\n value: (base.value as string) ?? \"\",\n onChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => base.setValue(e.target.value),\n placeholder: meta.placeholder,\n rows: meta.rows,\n },\n };\n }\n\n if (inputGuards.select_input(meta)) {\n return {\n options: meta.options ?? [],\n selectedValue: (base.value as string) ?? \"\",\n onSelect: (v: string) => base.setValue(v),\n };\n }\n\n if (inputGuards.context_select_input(meta)) {\n const loadState = loadingCtx?.fieldLoadStates?.[meta.path];\n return {\n options: meta.options ?? [],\n selectedValue: (base.value as string) ?? \"\",\n onSelect: (v: string) => base.setValue(v),\n pending: loadState?.status === \"loading\",\n suggestionsDisabled: loadState?.suggestionsDisabled ?? false,\n suggestionsDisabledReason: loadState?.suggestionsDisabledReason,\n };\n }\n\n if (inputGuards.tagged_text_input(meta)) {\n const loadState = loadingCtx?.fieldLoadStates?.[meta.path];\n return {\n options: meta.options ?? [],\n pending: loadState?.status === \"loading\",\n suggestionsDisabled: loadState?.suggestionsDisabled ?? false,\n suggestionsDisabledReason: loadState?.suggestionsDisabledReason,\n searchSecrets: loadingCtx?.searchSecrets,\n searchConstants: loadingCtx?.searchConstants,\n };\n }\n\n if (inputGuards.providers_input(meta)) {\n return {\n options: meta.options ?? [],\n };\n }\n\n if (inputGuards.multi_select_input(meta)) {\n const selected = (base.value as string[]) ?? [];\n return {\n options: meta.options ?? [],\n selected,\n onToggle: (v: string) =>\n base.setValue(selected.includes(v) ? selected.filter((s) => s !== v) : [...selected, v]),\n onClear: () => base.setValue([]),\n };\n }\n\n if (inputGuards.async_multi_select_input(meta)) {\n const selected = (base.value as string[]) ?? [];\n return {\n loadOptions: async (query: string) =>\n withMergedWidgets(\n await meta.optionsDef.options({ query, token: publicKey }),\n meta.optionsDef.widgets,\n ),\n selected,\n onToggle: (v: string) =>\n base.setValue(selected.includes(v) ? selected.filter((s) => s !== v) : [...selected, v]),\n onClear: () => base.setValue([]),\n };\n }\n\n if (inputGuards.boolean_input(meta) || inputGuards.nullable_boolean_input(meta)) {\n return {\n checked: base.value === true,\n isNull: base.value === null || base.value === undefined,\n toggle: () => base.setValue(base.value === true ? false : true),\n clear: () => base.setValue(null),\n };\n }\n\n if (\n inputGuards.include_exclude_input(meta) ||\n inputGuards.include_exclude_select_input(meta) ||\n inputGuards.async_include_exclude_select_input(meta)\n ) {\n const current = (base.value as {\n include: string[];\n exclude: string[];\n }) ?? { include: [], exclude: [] };\n const result: Record<string, unknown> = {\n include: {\n value: current.include,\n add: (v: string) => base.setValue({ ...current, include: [...current.include, v] }),\n remove: (v: string) =>\n base.setValue({\n ...current,\n include: current.include.filter((i) => i !== v),\n }),\n },\n exclude: {\n value: current.exclude,\n add: (v: string) => base.setValue({ ...current, exclude: [...current.exclude, v] }),\n remove: (v: string) =>\n base.setValue({\n ...current,\n exclude: current.exclude.filter((i) => i !== v),\n }),\n },\n };\n const m = meta as any;\n if (m.optionsDef?.options && typeof m.optionsDef.options === \"function\") {\n result.loadOptions = async (query: string) =>\n withMergedWidgets(\n await m.optionsDef.options({ query, token: publicKey }),\n m.optionsDef.widgets,\n );\n } else if (m.optionsDef?.options) {\n result.options = withMergedWidgets(m.optionsDef.options, m.optionsDef.widgets);\n }\n if (m.suggestionsDef?.options) {\n if (typeof m.suggestionsDef.options === \"function\") {\n result.loadOptions = async (query: string) =>\n withMergedWidgets(\n await m.suggestionsDef.options({ query, token: publicKey }),\n m.suggestionsDef.widgets,\n );\n } else {\n result.options = withMergedWidgets(m.suggestionsDef.options, m.suggestionsDef.widgets);\n }\n }\n return result;\n }\n\n if (inputGuards.range_input(meta)) {\n const current = (base.value as {\n from: number | null;\n to: number | null;\n }) ?? { from: null, to: null };\n return {\n from: {\n value: current.from,\n set: (v: number | null) => base.setValue({ ...current, from: v }),\n },\n to: {\n value: current.to,\n set: (v: number | null) => base.setValue({ ...current, to: v }),\n },\n };\n }\n\n if (inputGuards.date_range_input(meta)) {\n const current = (base.value as Record<string, string>) ?? {};\n return {\n from: {\n value: current.gte ?? current.gt ?? \"\",\n set: (v: string) => base.setValue({ ...current, gte: v }),\n },\n to: {\n value: current.lte ?? current.lt ?? \"\",\n set: (v: string) => base.setValue({ ...current, lte: v }),\n },\n };\n }\n\n if (inputGuards.exact_range_input(meta)) {\n const current = (base.value as Record<string, number | null>) ?? {};\n return {\n greaterThan: {\n operator: current.gt != null ? \"gt\" : \"gte\",\n value: current.gt ?? current.gte ?? null,\n setOperator: (op: string) => {\n const otherOp = op === \"gt\" ? \"gte\" : \"gt\";\n const val = current[otherOp] ?? current[op];\n const updated = { ...current };\n delete updated[otherOp];\n if (val != null) updated[op] = val;\n base.setValue(updated);\n },\n setValue: (v: number | null) => {\n const op = current.gt != null ? \"gt\" : \"gte\";\n const updated = { ...current };\n if (v != null) updated[op] = v;\n else delete updated[op];\n base.setValue(updated);\n },\n },\n lessThan: {\n operator: current.lt != null ? \"lt\" : \"lte\",\n value: current.lt ?? current.lte ?? null,\n setOperator: (op: string) => {\n const otherOp = op === \"lt\" ? \"lte\" : \"lt\";\n const val = current[otherOp] ?? current[op];\n const updated = { ...current };\n delete updated[otherOp];\n if (val != null) updated[op] = val;\n base.setValue(updated);\n },\n setValue: (v: number | null) => {\n const op = current.lt != null ? \"lt\" : \"lte\";\n const updated = { ...current };\n if (v != null) updated[op] = v;\n else delete updated[op];\n base.setValue(updated);\n },\n },\n };\n }\n\n if (inputGuards.min_max_int_input(meta)) {\n const current = (base.value as {\n min: number | null;\n max: number | null;\n }) ?? { min: null, max: null };\n return {\n from: {\n value: current.min,\n set: (v: number | null) => base.setValue({ ...current, min: v }),\n },\n to: {\n value: current.max,\n set: (v: number | null) => base.setValue({ ...current, max: v }),\n },\n };\n }\n\n if (inputGuards.multi_create_input(meta) || inputGuards.ordered_multi_create_input(meta)) {\n const items = (base.value as string[]) ?? [];\n const result: Record<string, unknown> = {\n items,\n add: (v: string) => base.setValue([...items, v]),\n remove: (v: string) => base.setValue(items.filter((i) => i !== v)),\n };\n if (inputGuards.ordered_multi_create_input(meta)) {\n result.reorder = (from: number, to: number) => {\n const next = [...items];\n const [moved] = next.splice(from, 1);\n next.splice(to, 0, moved);\n base.setValue(next);\n };\n }\n const m = meta as any;\n if (m.suggestionsDef?.options) {\n if (typeof m.suggestionsDef.options === \"function\") {\n result.loadOptions = async (query: string) =>\n withMergedWidgets(\n await m.suggestionsDef.options({ query, token: publicKey }),\n m.suggestionsDef.widgets,\n );\n } else {\n result.options = withMergedWidgets(m.suggestionsDef.options, m.suggestionsDef.widgets);\n }\n }\n return result;\n }\n\n if (inputGuards.tagged_ordered_multi_create_input(meta)) {\n const items = (base.value as string[]) ?? [];\n const result: Record<string, unknown> = {\n items,\n setItems: (next: string[]) => base.setValue(next),\n inputFields: meta.inputFields ?? [],\n };\n const m = meta as any;\n if (m.suggestionsDef?.options) {\n if (typeof m.suggestionsDef.options === \"function\") {\n result.loadOptions = async (query: string) =>\n withMergedWidgets(\n await m.suggestionsDef.options({ query, token: publicKey }),\n m.suggestionsDef.widgets,\n );\n } else {\n result.options = withMergedWidgets(m.suggestionsDef.options, m.suggestionsDef.widgets);\n }\n }\n return result;\n }\n\n if (inputGuards.loose_object_input(meta)) {\n const value = (base.value as Record<string, string>) ?? {};\n return {\n value,\n setObject: (next: Record<string, string>) => base.setValue(next),\n searchSecrets: loadingCtx?.searchSecrets,\n searchConstants: loadingCtx?.searchConstants,\n };\n }\n\n if (inputGuards.prompt_input(meta) || inputGuards.template_input(meta)) {\n return {\n searchSecrets: loadingCtx?.searchSecrets,\n searchConstants: loadingCtx?.searchConstants,\n };\n }\n\n // Remaining types need no extras beyond base\n return {};\n}\n\nfunction isEmptyValue(value: unknown): boolean {\n if (value === null || typeof value === \"undefined\") return true;\n if (typeof value === \"string\") return value === \"\";\n if (Array.isArray(value)) return value.length === 0;\n if (typeof value === \"object\") {\n const keys = Object.keys(value);\n if (keys.length === 0) return true;\n return keys.every((k) => isEmptyValue((value as Record<string, unknown>)[k]));\n }\n return false;\n}\n\nexport function buildSectionHandles(\n formConfig: FormSection[],\n form: UseFormReturn<Record<string, unknown>>,\n publicKey: string,\n loadingCtx?: FieldLoadingContext,\n): FormSectionHandle[] {\n // In onSubmit validation mode, don't flag groups as invalid until the\n // user has actually attempted a submit. This matches RHF's own field-level\n // behavior where `formState.errors` is only populated after the first\n // submit (and updated reactively thereafter per `reValidateMode`).\n const hasSubmitted = form.formState.isSubmitted;\n\n return formConfig\n .map((section) => {\n const groups: FormGroupHandle[] = section.groups\n .map((group) => {\n // Drop a connector field whose mode is \"disabled\" (custom connections\n // unsupported) — there's nothing to configure, so we hide the whole\n // group/section rather than render a \"not supported\" placeholder.\n const fields = group.fields\n .filter(\n (meta) => !(inputGuards.connector_input(meta) && meta.connectorMode === \"disabled\"),\n )\n .map((meta) => buildFieldProps(meta, form, publicKey, loadingCtx)) as AnyFieldProps[];\n\n const groupPathError = form.getFieldState(group.groupPath as any).error;\n const errorCount = hasSubmitted\n ? fields.filter((f) => f.error != null).length + (groupPathError ? 1 : 0)\n : 0;\n const setCount = fields.filter((f) => !isEmptyValue(f.value)).length;\n const dirtyCount = fields.filter((f) => f.dirty).length;\n\n return {\n key: group.groupPath,\n label: group.label,\n description: group.description,\n iconKey: group.iconKey,\n defaultExpand: group.defaultExpand ?? false,\n fields,\n errorCount,\n setCount,\n dirtyCount,\n };\n })\n .filter((group) => group.fields.length > 0);\n\n return {\n key: section.metadata.path,\n label: section.metadata.label,\n description: section.metadata.description,\n groups,\n };\n })\n .filter((section) => section.groups.length > 0);\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import * as _$react from "react";
2
- import * as _$lucide_react0 from "lucide-react";
3
2
  import { RecordFieldStatus, RecordFieldType } from "@pipe0/base";
3
+ import * as _$lucide_react0 from "lucide-react";
4
4
  import { FilterFn } from "@tanstack/react-table";
5
5
 
6
6
  //#region src/utils/catalog-helpers.d.ts
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1,55 @@
1
+ import { Tooltip, TooltipContent, TooltipTrigger } from "../components/ui/tooltip.mjs";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { Coins } from "lucide-react";
4
+
5
+ //#region src/widgets/token-pricing-badge.tsx
6
+ /** Trim floating-point noise to a few significant figures for display. */
7
+ function fmt(n) {
8
+ return Number(n.toPrecision(3));
9
+ }
10
+ /**
11
+ * Usage-based pricing badge for the LLM model picker. Inline it just reads
12
+ * "Usage-based"; the absolute per-billing-block (per `blockSize` tokens) input
13
+ * and output credit rates appear on hover.
14
+ */
15
+ function TokenPricingBadge({ inputPerBlock, outputPerBlock, blockSize }) {
16
+ return /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, { render: /* @__PURE__ */ jsxs("span", {
17
+ className: "pz:inline-flex pz:items-center pz:gap-1 pz:text-xs pz:text-muted-foreground pz:cursor-help pz:whitespace-nowrap",
18
+ children: [/* @__PURE__ */ jsx(Coins, { className: "pz:size-3" }), "Usage"]
19
+ }) }), /* @__PURE__ */ jsx(TooltipContent, {
20
+ side: "top",
21
+ align: "center",
22
+ children: /* @__PURE__ */ jsxs("div", {
23
+ className: "pz:text-xs pz:leading-snug pz:flex pz:flex-col pz:gap-0.5",
24
+ children: [
25
+ /* @__PURE__ */ jsxs("span", {
26
+ className: "pz:inline-flex pz:items-center pz:gap-1 pz:tabular-nums",
27
+ children: [
28
+ fmt(inputPerBlock),
29
+ " ",
30
+ /* @__PURE__ */ jsx(Coins, { className: "pz:size-3" }),
31
+ " / ",
32
+ blockSize,
33
+ " input tokens"
34
+ ]
35
+ }),
36
+ /* @__PURE__ */ jsxs("span", {
37
+ className: "pz:inline-flex pz:items-center pz:gap-1 pz:tabular-nums",
38
+ children: [
39
+ fmt(outputPerBlock),
40
+ " ",
41
+ /* @__PURE__ */ jsx(Coins, { className: "pz:size-3" }),
42
+ " / ",
43
+ blockSize,
44
+ " output tokens"
45
+ ]
46
+ }),
47
+ /* @__PURE__ */ jsx("span", { className: "pz:text-muted-foreground pz:mt-1" })
48
+ ]
49
+ })
50
+ })] });
51
+ }
52
+
53
+ //#endregion
54
+ export { TokenPricingBadge };
55
+ //# sourceMappingURL=token-pricing-badge.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-pricing-badge.mjs","names":[],"sources":["../../src/widgets/token-pricing-badge.tsx"],"sourcesContent":["import { Coins } from \"lucide-react\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"../components/ui/tooltip\";\n\n/** Trim floating-point noise to a few significant figures for display. */\nfunction fmt(n: number): number {\n return Number(n.toPrecision(3));\n}\n\n/**\n * Usage-based pricing badge for the LLM model picker. Inline it just reads\n * \"Usage-based\"; the absolute per-billing-block (per `blockSize` tokens) input\n * and output credit rates appear on hover.\n */\nexport function TokenPricingBadge({\n inputPerBlock,\n outputPerBlock,\n blockSize,\n}: {\n inputPerBlock: number;\n outputPerBlock: number;\n blockSize: number;\n}) {\n return (\n <Tooltip>\n <TooltipTrigger\n render={\n <span className=\"pz:inline-flex pz:items-center pz:gap-1 pz:text-xs pz:text-muted-foreground pz:cursor-help pz:whitespace-nowrap\">\n <Coins className=\"pz:size-3\" />\n Usage\n </span>\n }\n />\n <TooltipContent side=\"top\" align=\"center\">\n <div className=\"pz:text-xs pz:leading-snug pz:flex pz:flex-col pz:gap-0.5\">\n <span className=\"pz:inline-flex pz:items-center pz:gap-1 pz:tabular-nums\">\n {fmt(inputPerBlock)} <Coins className=\"pz:size-3\" /> / {blockSize} input tokens\n </span>\n <span className=\"pz:inline-flex pz:items-center pz:gap-1 pz:tabular-nums\">\n {fmt(outputPerBlock)} <Coins className=\"pz:size-3\" /> / {blockSize} output tokens\n </span>\n <span className=\"pz:text-muted-foreground pz:mt-1\"></span>\n </div>\n </TooltipContent>\n </Tooltip>\n );\n}\n"],"mappings":";;;;;;AAIA,SAAS,IAAI,GAAmB;AAC9B,QAAO,OAAO,EAAE,YAAY,EAAE,CAAC;;;;;;;AAQjC,SAAgB,kBAAkB,EAChC,eACA,gBACA,aAKC;AACD,QACE,qBAAC,SAAD,aACE,oBAAC,gBAAD,EACE,QACE,qBAAC,QAAD;EAAM,WAAU;YAAhB,CACE,oBAAC,OAAD,EAAO,WAAU,aAAc,WAE1B;KAET,GACF,oBAAC,gBAAD;EAAgB,MAAK;EAAM,OAAM;YAC/B,qBAAC,OAAD;GAAK,WAAU;aAAf;IACE,qBAAC,QAAD;KAAM,WAAU;eAAhB;MACG,IAAI,cAAc;MAAC;MAAC,oBAAC,OAAD,EAAO,WAAU,aAAc;;MAAI;MAAU;MAC7D;;IACP,qBAAC,QAAD;KAAM,WAAU;eAAhB;MACG,IAAI,eAAe;MAAC;MAAC,oBAAC,OAAD,EAAO,WAAU,aAAc;;MAAI;MAAU;MAC9D;;IACP,oBAAC,QAAD,EAAM,WAAU,oCAA0C;IACtD;;EACS,EACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"widget-strip.d.mts","names":[],"sources":["../../src/widgets/widget-strip.tsx"],"mappings":";;;;iBAcgB,WAAA,CAAA;EACd,OAAA;EACA,IAAA;EACA;AAAA;EAEA,OAAA,EAAS,aAAA;EACT,IAAA;EACA,SAAA;AAAA,IACD,oBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"widget-strip.d.mts","names":[],"sources":["../../src/widgets/widget-strip.tsx"],"mappings":";;;;iBAegB,WAAA,CAAA;EACd,OAAA;EACA,IAAA;EACA;AAAA;EAEA,OAAA,EAAS,aAAA;EACT,IAAA;EACA,SAAA;AAAA,IACD,oBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -10,6 +10,7 @@ const ORDER = [
10
10
  "emoji",
11
11
  "icon",
12
12
  "pricing",
13
+ "token_pricing",
13
14
  "field_type"
14
15
  ];
15
16
  function WidgetStrip({ widgets, size, className }) {
@@ -1 +1 @@
1
- {"version":3,"file":"widget-strip.mjs","names":[],"sources":["../../src/widgets/widget-strip.tsx"],"sourcesContent":["import type { Widget, WidgetsByKind } from \"@pipe0/base\";\nimport { WidgetView } from \"./widget-view.js\";\n\n/** Canonical render order for WidgetStrip. Kinds not in this list are rendered\n * after the listed ones in insertion order. Keep stable across consumers. */\nconst ORDER: (keyof WidgetsByKind)[] = [\n \"provider_logo\",\n \"logo_url\",\n \"emoji\",\n \"icon\",\n \"pricing\",\n \"field_type\",\n];\n\nexport function WidgetStrip({\n widgets,\n size,\n className,\n}: {\n widgets: WidgetsByKind | undefined;\n size?: number;\n className?: string;\n}) {\n if (!widgets) return null;\n\n const tagged: Widget[] = [];\n for (const kind of ORDER) {\n const payload = widgets[kind];\n if (payload) tagged.push({ kind, ...payload } as Widget);\n }\n\n if (tagged.length === 0) return null;\n\n return (\n <span className={className} style={{ display: \"inline-flex\", alignItems: \"center\", gap: 6 }}>\n {tagged.map((w, i) => (\n <WidgetView key={`${w.kind}-${i}`} widget={w} size={size} />\n ))}\n </span>\n );\n}\n"],"mappings":";;;;;;AAKA,MAAM,QAAiC;CACrC;CACA;CACA;CACA;CACA;CACA;CACD;AAED,SAAgB,YAAY,EAC1B,SACA,MACA,aAKC;AACD,KAAI,CAAC,QAAS,QAAO;CAErB,MAAM,SAAmB,EAAE;AAC3B,MAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,UAAU,QAAQ;AACxB,MAAI,QAAS,QAAO,KAAK;GAAE;GAAM,GAAG;GAAS,CAAW;;AAG1D,KAAI,OAAO,WAAW,EAAG,QAAO;AAEhC,QACE,oBAAC,QAAD;EAAiB;EAAW,OAAO;GAAE,SAAS;GAAe,YAAY;GAAU,KAAK;GAAG;YACxF,OAAO,KAAK,GAAG,MACd,oBAAC,YAAD;GAAmC,QAAQ;GAAS;GAAQ,EAA3C,GAAG,EAAE,KAAK,GAAG,IAA8B,CAC5D;EACG"}
1
+ {"version":3,"file":"widget-strip.mjs","names":[],"sources":["../../src/widgets/widget-strip.tsx"],"sourcesContent":["import type { Widget, WidgetsByKind } from \"@pipe0/base\";\nimport { WidgetView } from \"./widget-view.js\";\n\n/** Canonical render order for WidgetStrip. Kinds not in this list are rendered\n * after the listed ones in insertion order. Keep stable across consumers. */\nconst ORDER: (keyof WidgetsByKind)[] = [\n \"provider_logo\",\n \"logo_url\",\n \"emoji\",\n \"icon\",\n \"pricing\",\n \"token_pricing\",\n \"field_type\",\n];\n\nexport function WidgetStrip({\n widgets,\n size,\n className,\n}: {\n widgets: WidgetsByKind | undefined;\n size?: number;\n className?: string;\n}) {\n if (!widgets) return null;\n\n const tagged: Widget[] = [];\n for (const kind of ORDER) {\n const payload = widgets[kind];\n if (payload) tagged.push({ kind, ...payload } as Widget);\n }\n\n if (tagged.length === 0) return null;\n\n return (\n <span className={className} style={{ display: \"inline-flex\", alignItems: \"center\", gap: 6 }}>\n {tagged.map((w, i) => (\n <WidgetView key={`${w.kind}-${i}`} widget={w} size={size} />\n ))}\n </span>\n );\n}\n"],"mappings":";;;;;;AAKA,MAAM,QAAiC;CACrC;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,SAAgB,YAAY,EAC1B,SACA,MACA,aAKC;AACD,KAAI,CAAC,QAAS,QAAO;CAErB,MAAM,SAAmB,EAAE;AAC3B,MAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,UAAU,QAAQ;AACxB,MAAI,QAAS,QAAO,KAAK;GAAE;GAAM,GAAG;GAAS,CAAW;;AAG1D,KAAI,OAAO,WAAW,EAAG,QAAO;AAEhC,QACE,oBAAC,QAAD;EAAiB;EAAW,OAAO;GAAE,SAAS;GAAe,YAAY;GAAU,KAAK;GAAG;YACxF,OAAO,KAAK,GAAG,MACd,oBAAC,YAAD;GAAmC,QAAQ;GAAS;GAAQ,EAA3C,GAAG,EAAE,KAAK,GAAG,IAA8B,CAC5D;EACG"}
@@ -1 +1 @@
1
- {"version":3,"file":"widget-view.d.mts","names":[],"sources":["../../src/widgets/widget-view.tsx"],"mappings":";;;;iBAQgB,UAAA,CAAA;EAAa,MAAA;EAAQ;AAAA;EAAU,MAAA,EAAQ,MAAA;EAAQ,IAAA;AAAA,IAAe,oBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"widget-view.d.mts","names":[],"sources":["../../src/widgets/widget-view.tsx"],"mappings":";;;;iBASgB,UAAA,CAAA;EAAa,MAAA;EAAQ;AAAA;EAAU,MAAA,EAAQ,MAAA;EAAQ,IAAA;AAAA,IAAe,oBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -4,6 +4,7 @@ import { EmojiGlyph } from "./emoji-glyph.mjs";
4
4
  import { LogoUrl } from "./logo-url.mjs";
5
5
  import { PricingBadge } from "./pricing-badge.mjs";
6
6
  import { ProviderLogo } from "./provider-logo.mjs";
7
+ import { TokenPricingBadge } from "./token-pricing-badge.mjs";
7
8
  import { jsx } from "react/jsx-runtime";
8
9
 
9
10
  //#region src/widgets/widget-view.tsx
@@ -24,6 +25,11 @@ function WidgetView({ widget, size }) {
24
25
  size
25
26
  });
26
27
  case "pricing": return /* @__PURE__ */ jsx(PricingBadge, { credits: widget.credits });
28
+ case "token_pricing": return /* @__PURE__ */ jsx(TokenPricingBadge, {
29
+ inputPerBlock: widget.inputPerBlock,
30
+ outputPerBlock: widget.outputPerBlock,
31
+ blockSize: widget.blockSize
32
+ });
27
33
  case "field_type": return /* @__PURE__ */ jsx(FieldTypeBadge, {
28
34
  type: widget.type,
29
35
  format: widget.format
@@ -1 +1 @@
1
- {"version":3,"file":"widget-view.mjs","names":[],"sources":["../../src/widgets/widget-view.tsx"],"sourcesContent":["import type { Widget } from \"@pipe0/base\";\nimport { EmojiGlyph } from \"./emoji-glyph.js\";\nimport { FieldTypeBadge } from \"./field-type-badge.js\";\nimport { IconGlyph } from \"./icon-glyph.js\";\nimport { LogoUrl } from \"./logo-url.js\";\nimport { PricingBadge } from \"./pricing-badge.js\";\nimport { ProviderLogo } from \"./provider-logo.js\";\n\nexport function WidgetView({ widget, size }: { widget: Widget; size?: number }) {\n switch (widget.kind) {\n case \"provider_logo\":\n return <ProviderLogo provider={widget.provider} size={size} />;\n case \"emoji\":\n return <EmojiGlyph char={widget.char} />;\n case \"icon\":\n return <IconGlyph keyName={widget.key} size={size} />;\n case \"logo_url\":\n return <LogoUrl url={widget.url} alt={widget.alt} size={size} />;\n case \"pricing\":\n return <PricingBadge credits={widget.credits} />;\n case \"field_type\":\n return <FieldTypeBadge type={widget.type} format={widget.format} />;\n }\n}\n"],"mappings":";;;;;;;;;AAQA,SAAgB,WAAW,EAAE,QAAQ,QAA2C;AAC9E,SAAQ,OAAO,MAAf;EACE,KAAK,gBACH,QAAO,oBAAC,cAAD;GAAc,UAAU,OAAO;GAAgB;GAAQ;EAChE,KAAK,QACH,QAAO,oBAAC,YAAD,EAAY,MAAM,OAAO,MAAQ;EAC1C,KAAK,OACH,QAAO,oBAAC,WAAD;GAAW,SAAS,OAAO;GAAW;GAAQ;EACvD,KAAK,WACH,QAAO,oBAAC,SAAD;GAAS,KAAK,OAAO;GAAK,KAAK,OAAO;GAAW;GAAQ;EAClE,KAAK,UACH,QAAO,oBAAC,cAAD,EAAc,SAAS,OAAO,SAAW;EAClD,KAAK,aACH,QAAO,oBAAC,gBAAD;GAAgB,MAAM,OAAO;GAAM,QAAQ,OAAO;GAAU"}
1
+ {"version":3,"file":"widget-view.mjs","names":[],"sources":["../../src/widgets/widget-view.tsx"],"sourcesContent":["import type { Widget } from \"@pipe0/base\";\nimport { EmojiGlyph } from \"./emoji-glyph.js\";\nimport { FieldTypeBadge } from \"./field-type-badge.js\";\nimport { IconGlyph } from \"./icon-glyph.js\";\nimport { LogoUrl } from \"./logo-url.js\";\nimport { PricingBadge } from \"./pricing-badge.js\";\nimport { ProviderLogo } from \"./provider-logo.js\";\nimport { TokenPricingBadge } from \"./token-pricing-badge.js\";\n\nexport function WidgetView({ widget, size }: { widget: Widget; size?: number }) {\n switch (widget.kind) {\n case \"provider_logo\":\n return <ProviderLogo provider={widget.provider} size={size} />;\n case \"emoji\":\n return <EmojiGlyph char={widget.char} />;\n case \"icon\":\n return <IconGlyph keyName={widget.key} size={size} />;\n case \"logo_url\":\n return <LogoUrl url={widget.url} alt={widget.alt} size={size} />;\n case \"pricing\":\n return <PricingBadge credits={widget.credits} />;\n case \"token_pricing\":\n return (\n <TokenPricingBadge\n inputPerBlock={widget.inputPerBlock}\n outputPerBlock={widget.outputPerBlock}\n blockSize={widget.blockSize}\n />\n );\n case \"field_type\":\n return <FieldTypeBadge type={widget.type} format={widget.format} />;\n }\n}\n"],"mappings":";;;;;;;;;;AASA,SAAgB,WAAW,EAAE,QAAQ,QAA2C;AAC9E,SAAQ,OAAO,MAAf;EACE,KAAK,gBACH,QAAO,oBAAC,cAAD;GAAc,UAAU,OAAO;GAAgB;GAAQ;EAChE,KAAK,QACH,QAAO,oBAAC,YAAD,EAAY,MAAM,OAAO,MAAQ;EAC1C,KAAK,OACH,QAAO,oBAAC,WAAD;GAAW,SAAS,OAAO;GAAW;GAAQ;EACvD,KAAK,WACH,QAAO,oBAAC,SAAD;GAAS,KAAK,OAAO;GAAK,KAAK,OAAO;GAAW;GAAQ;EAClE,KAAK,UACH,QAAO,oBAAC,cAAD,EAAc,SAAS,OAAO,SAAW;EAClD,KAAK,gBACH,QACE,oBAAC,mBAAD;GACE,eAAe,OAAO;GACtB,gBAAgB,OAAO;GACvB,WAAW,OAAO;GAClB;EAEN,KAAK,aACH,QAAO,oBAAC,gBAAD;GAAgB,MAAM,OAAO;GAAM,QAAQ,OAAO;GAAU"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pipe0/react",
3
- "version": "0.1.7",
3
+ "version": "0.2.1",
4
4
  "description": "React component library for building forms and catalogs powered by pipe0 pipes and searches.",
5
5
  "license": "MIT",
6
6
  "author": "pipe0",
@@ -48,21 +48,11 @@
48
48
  "CHANGELOG.md"
49
49
  ],
50
50
  "peerDependencies": {
51
- "@dnd-kit/core": "^6.0.0",
52
- "@dnd-kit/sortable": "^10.0.0",
53
- "@dnd-kit/utilities": "^3.0.0",
54
- "@floating-ui/react": "^0.26.0 || ^0.27.0",
55
- "@hookform/resolvers": "^5.0.0",
56
- "@tanstack/react-table": "^8.0.0",
57
- "@tiptap/pm": "^2.12.0 || ^3.0.0",
58
- "@tiptap/react": "^2.12.0 || ^3.0.0",
59
- "@tiptap/starter-kit": "^2.12.0 || ^3.0.0",
60
- "@tiptap/suggestion": "^2.12.0 || ^3.0.0",
51
+ "@base-ui/react": "^1.3.0",
61
52
  "@types/react": "^18.0.0 || ^19.0.0",
62
53
  "@types/react-dom": "^18.0.0 || ^19.0.0",
63
54
  "react": "^18.0.0 || ^19.0.0",
64
55
  "react-dom": "^18.0.0 || ^19.0.0",
65
- "react-hook-form": "^7.0.0",
66
56
  "zod": "^4.0.0"
67
57
  },
68
58
  "peerDependenciesMeta": {
@@ -74,39 +64,39 @@
74
64
  }
75
65
  },
76
66
  "dependencies": {
77
- "@base-ui/react": "^1.3.0",
67
+ "@dnd-kit/core": "^6.3.1",
68
+ "@dnd-kit/sortable": "^10.0.0",
69
+ "@dnd-kit/utilities": "^3.2.2",
70
+ "@floating-ui/react": "^0.27.0",
71
+ "@hookform/resolvers": "^5.2.1",
78
72
  "@radix-ui/react-slot": "^1.2.2",
79
73
  "@tanstack/match-sorter-utils": "^8.19.4",
74
+ "@tanstack/react-table": "^8.21.3",
75
+ "@tiptap/pm": "^3.7.2",
76
+ "@tiptap/react": "^3.7.2",
77
+ "@tiptap/starter-kit": "^3.7.2",
78
+ "@tiptap/suggestion": "^3.7.2",
80
79
  "class-variance-authority": "^0.7.1",
81
80
  "clsx": "^2.1.1",
82
81
  "cmdk": "^1.1.1",
83
82
  "jsonata": "^2.1.0",
84
83
  "lucide-react": "^0.475.0",
84
+ "react-hook-form": "^7.62.0",
85
85
  "swr": "^2.4.1",
86
86
  "tailwind-merge": "^3.3.1",
87
- "@pipe0/base": "0.4.7"
87
+ "@pipe0/base": "0.5.1"
88
88
  },
89
89
  "devDependencies": {
90
- "@dnd-kit/core": "^6.3.1",
91
- "@dnd-kit/sortable": "^10.0.0",
92
- "@dnd-kit/utilities": "^3.2.2",
93
- "@floating-ui/react": "^0.26.0",
94
- "@hookform/resolvers": "^5.2.1",
90
+ "@base-ui/react": "^1.3.0",
95
91
  "@storybook/addon-docs": "^10.3.5",
96
92
  "@storybook/react-vite": "^10.3.5",
97
93
  "@tailwindcss/cli": "^4.2.3",
98
94
  "@tailwindcss/vite": "^4.1.11",
99
- "@tanstack/react-table": "^8.21.3",
100
- "@tiptap/pm": "^2.12.0",
101
- "@tiptap/react": "^2.12.0",
102
- "@tiptap/starter-kit": "^2.12.0",
103
- "@tiptap/suggestion": "^2.12.0",
104
95
  "@types/react": "^19.0.8",
105
96
  "@types/react-dom": "^19.0.3",
106
97
  "@vitejs/plugin-react": "^6.0.1",
107
98
  "react": "^19.0.0",
108
99
  "react-dom": "^19.0.0",
109
- "react-hook-form": "^7.62.0",
110
100
  "shadcn": "^4.2.0",
111
101
  "storybook": "^10.3.5",
112
102
  "tailwindcss": "^4.1.11",
@@ -1,102 +0,0 @@
1
- import { Button } from "../../ui/button.mjs";
2
- import { FieldLegend } from "../../internal/field-legend.mjs";
3
- import { LiquidEditor } from "../../internal/LiquidEditor/LiquidEditor.mjs";
4
- import { useState } from "react";
5
- import { jsx, jsxs } from "react/jsx-runtime";
6
- import { Plus, X } from "lucide-react";
7
-
8
- //#region src/components/defaults/adapters/key-value-list-input.tsx
9
- /**
10
- * Adapter for `pipesKeyValueListInput`. Each row's key and value cells use
11
- * `LiquidEditor` so they support `/` references (input fields + secrets +
12
- * constants in one picker). The kvl is used for things like HTTP headers
13
- * and query params where either column may legitimately reference a field
14
- * (e.g. a per-record `pageToken`) or a secret (e.g. an Authorization
15
- * value).
16
- *
17
- * The unified legend would otherwise render twice per row (once per
18
- * cell) — too noisy. The per-cell editors run with `hideLegend`; a
19
- * single legend renders once below the entire list.
20
- */
21
- function KeyValueListInputAdapter(field) {
22
- const { rows, addRow, removeRow, setKey, setValue, searchSecrets, searchConstants, meta } = field;
23
- const maxItems = meta.maxItems ?? 50;
24
- const canAdd = rows.length < maxItems;
25
- const [ids, setIds] = useState(() => rows.map(() => crypto.randomUUID()));
26
- if (ids.length < rows.length) setIds((prev) => [...prev, ...Array.from({ length: rows.length - prev.length }, () => crypto.randomUUID())]);
27
- const handleAdd = () => {
28
- setIds((prev) => [...prev, crypto.randomUUID()]);
29
- addRow();
30
- };
31
- const handleRemove = (index) => {
32
- setIds((prev) => prev.filter((_, i) => i !== index));
33
- removeRow(index);
34
- };
35
- return /* @__PURE__ */ jsxs("div", {
36
- "data-p0": "input",
37
- className: "pz:flex pz:flex-col pz:gap-2",
38
- children: [
39
- rows.length === 0 && /* @__PURE__ */ jsx("p", {
40
- className: "pz:text-xs pz:text-muted-foreground",
41
- children: meta.keyLabel ? `No ${meta.keyLabel.toLowerCase()}s yet.` : "No entries yet."
42
- }),
43
- rows.map((row, index) => /* @__PURE__ */ jsxs("div", {
44
- className: "pz:flex pz:items-start pz:gap-2",
45
- children: [
46
- /* @__PURE__ */ jsx("div", {
47
- className: "pz:basis-1/3 pz:rounded-md pz:border pz:border-input pz:bg-transparent",
48
- children: /* @__PURE__ */ jsx(LiquidEditor, {
49
- value: row.key,
50
- onChange: (v) => setKey(index, v),
51
- inputFields: meta.inputFields ?? [],
52
- searchSecrets,
53
- searchConstants,
54
- placeholder: meta.keyPlaceholder ?? meta.keyLabel ?? "Key",
55
- hideLegend: true
56
- })
57
- }),
58
- /* @__PURE__ */ jsx("div", {
59
- className: "pz:flex-1 pz:rounded-md pz:border pz:border-input pz:bg-transparent",
60
- children: /* @__PURE__ */ jsx(LiquidEditor, {
61
- value: row.value,
62
- onChange: (v) => setValue(index, v),
63
- inputFields: meta.inputFields ?? [],
64
- searchSecrets,
65
- searchConstants,
66
- placeholder: meta.valuePlaceholder ?? meta.valueLabel ?? "Value",
67
- hideLegend: true
68
- })
69
- }),
70
- /* @__PURE__ */ jsx(Button, {
71
- type: "button",
72
- variant: "ghost",
73
- size: "icon",
74
- "aria-label": "Remove row",
75
- onClick: () => handleRemove(index),
76
- children: /* @__PURE__ */ jsx(X, { className: "pz:size-4" })
77
- })
78
- ]
79
- }, ids[index])),
80
- rows.length > 0 && /* @__PURE__ */ jsx(FieldLegend, { entries: [{
81
- key: "/",
82
- label: "to insert a reference"
83
- }] }),
84
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(Button, {
85
- type: "button",
86
- variant: "outline",
87
- size: "sm",
88
- onClick: handleAdd,
89
- disabled: !canAdd,
90
- children: [
91
- /* @__PURE__ */ jsx(Plus, { className: "pz:size-4 pz:mr-1" }),
92
- "Add ",
93
- meta.keyLabel ?? "row"
94
- ]
95
- }) })
96
- ]
97
- });
98
- }
99
-
100
- //#endregion
101
- export { KeyValueListInputAdapter };
102
- //# sourceMappingURL=key-value-list-input.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"key-value-list-input.mjs","names":[],"sources":["../../../../src/components/defaults/adapters/key-value-list-input.tsx"],"sourcesContent":["import { Plus, X } from \"lucide-react\";\nimport { useState } from \"react\";\nimport type { FieldHandle } from \"../../../types/field-handle.js\";\nimport { FieldLegend } from \"../../internal/field-legend.js\";\nimport { LiquidEditor } from \"../../internal/LiquidEditor/LiquidEditor.js\";\nimport { Button } from \"../../ui/button.js\";\n\n/**\n * Adapter for `pipesKeyValueListInput`. Each row's key and value cells use\n * `LiquidEditor` so they support `/` references (input fields + secrets +\n * constants in one picker). The kvl is used for things like HTTP headers\n * and query params where either column may legitimately reference a field\n * (e.g. a per-record `pageToken`) or a secret (e.g. an Authorization\n * value).\n *\n * The unified legend would otherwise render twice per row (once per\n * cell) — too noisy. The per-cell editors run with `hideLegend`; a\n * single legend renders once below the entire list.\n */\nexport function KeyValueListInputAdapter(field: FieldHandle<\"key_value_list_input\">) {\n const { rows, addRow, removeRow, setKey, setValue, searchSecrets, searchConstants, meta } = field;\n const maxItems = meta.maxItems ?? 50;\n const canAdd = rows.length < maxItems;\n\n // Stable per-row identifiers, kept in lockstep with `rows`. The form value\n // is positional — `[{key, value}, ...]` — so reordering or removing the\n // row at index N would alias N's editor onto another row's content if we\n // keyed by index. We mirror mutations through `handleAdd`/`handleRemove`,\n // and lazily pad if `rows` was extended externally (e.g. form reset).\n const [ids, setIds] = useState<string[]>(() => rows.map(() => crypto.randomUUID()));\n if (ids.length < rows.length) {\n setIds((prev) => [\n ...prev,\n ...Array.from({ length: rows.length - prev.length }, () => crypto.randomUUID()),\n ]);\n }\n\n const handleAdd = () => {\n setIds((prev) => [...prev, crypto.randomUUID()]);\n addRow();\n };\n const handleRemove = (index: number) => {\n setIds((prev) => prev.filter((_, i) => i !== index));\n removeRow(index);\n };\n\n return (\n <div data-p0=\"input\" className=\"pz:flex pz:flex-col pz:gap-2\">\n {rows.length === 0 && (\n <p className=\"pz:text-xs pz:text-muted-foreground\">\n {meta.keyLabel ? `No ${meta.keyLabel.toLowerCase()}s yet.` : \"No entries yet.\"}\n </p>\n )}\n {rows.map((row, index) => (\n <div key={ids[index]} className=\"pz:flex pz:items-start pz:gap-2\">\n <div className=\"pz:basis-1/3 pz:rounded-md pz:border pz:border-input pz:bg-transparent\">\n <LiquidEditor\n value={row.key}\n onChange={(v) => setKey(index, v)}\n inputFields={meta.inputFields ?? []}\n searchSecrets={searchSecrets}\n searchConstants={searchConstants}\n placeholder={meta.keyPlaceholder ?? meta.keyLabel ?? \"Key\"}\n hideLegend\n />\n </div>\n <div className=\"pz:flex-1 pz:rounded-md pz:border pz:border-input pz:bg-transparent\">\n <LiquidEditor\n value={row.value}\n onChange={(v) => setValue(index, v)}\n inputFields={meta.inputFields ?? []}\n searchSecrets={searchSecrets}\n searchConstants={searchConstants}\n placeholder={meta.valuePlaceholder ?? meta.valueLabel ?? \"Value\"}\n hideLegend\n />\n </div>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n aria-label=\"Remove row\"\n onClick={() => handleRemove(index)}\n >\n <X className=\"pz:size-4\" />\n </Button>\n </div>\n ))}\n {rows.length > 0 && <FieldLegend entries={[{ key: \"/\", label: \"to insert a reference\" }]} />}\n <div>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={handleAdd} disabled={!canAdd}>\n <Plus className=\"pz:size-4 pz:mr-1\" />\n Add {meta.keyLabel ?? \"row\"}\n </Button>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,yBAAyB,OAA4C;CACnF,MAAM,EAAE,MAAM,QAAQ,WAAW,QAAQ,UAAU,eAAe,iBAAiB,SAAS;CAC5F,MAAM,WAAW,KAAK,YAAY;CAClC,MAAM,SAAS,KAAK,SAAS;CAO7B,MAAM,CAAC,KAAK,UAAU,eAAyB,KAAK,UAAU,OAAO,YAAY,CAAC,CAAC;AACnF,KAAI,IAAI,SAAS,KAAK,OACpB,SAAQ,SAAS,CACf,GAAG,MACH,GAAG,MAAM,KAAK,EAAE,QAAQ,KAAK,SAAS,KAAK,QAAQ,QAAQ,OAAO,YAAY,CAAC,CAChF,CAAC;CAGJ,MAAM,kBAAkB;AACtB,UAAQ,SAAS,CAAC,GAAG,MAAM,OAAO,YAAY,CAAC,CAAC;AAChD,UAAQ;;CAEV,MAAM,gBAAgB,UAAkB;AACtC,UAAQ,SAAS,KAAK,QAAQ,GAAG,MAAM,MAAM,MAAM,CAAC;AACpD,YAAU,MAAM;;AAGlB,QACE,qBAAC,OAAD;EAAK,WAAQ;EAAQ,WAAU;YAA/B;GACG,KAAK,WAAW,KACf,oBAAC,KAAD;IAAG,WAAU;cACV,KAAK,WAAW,MAAM,KAAK,SAAS,aAAa,CAAC,UAAU;IAC3D;GAEL,KAAK,KAAK,KAAK,UACd,qBAAC,OAAD;IAAsB,WAAU;cAAhC;KACE,oBAAC,OAAD;MAAK,WAAU;gBACb,oBAAC,cAAD;OACE,OAAO,IAAI;OACX,WAAW,MAAM,OAAO,OAAO,EAAE;OACjC,aAAa,KAAK,eAAe,EAAE;OACpB;OACE;OACjB,aAAa,KAAK,kBAAkB,KAAK,YAAY;OACrD;OACA;MACE;KACN,oBAAC,OAAD;MAAK,WAAU;gBACb,oBAAC,cAAD;OACE,OAAO,IAAI;OACX,WAAW,MAAM,SAAS,OAAO,EAAE;OACnC,aAAa,KAAK,eAAe,EAAE;OACpB;OACE;OACjB,aAAa,KAAK,oBAAoB,KAAK,cAAc;OACzD;OACA;MACE;KACN,oBAAC,QAAD;MACE,MAAK;MACL,SAAQ;MACR,MAAK;MACL,cAAW;MACX,eAAe,aAAa,MAAM;gBAElC,oBAAC,GAAD,EAAG,WAAU,aAAc;MACpB;KACL;MAhCI,IAAI,OAgCR,CACN;GACD,KAAK,SAAS,KAAK,oBAAC,aAAD,EAAa,SAAS,CAAC;IAAE,KAAK;IAAK,OAAO;IAAyB,CAAC,EAAI;GAC5F,oBAAC,OAAD,YACE,qBAAC,QAAD;IAAQ,MAAK;IAAS,SAAQ;IAAU,MAAK;IAAK,SAAS;IAAW,UAAU,CAAC;cAAjF;KACE,oBAAC,MAAD,EAAM,WAAU,qBAAsB;;KACjC,KAAK,YAAY;KACf;OACL;GACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"form-customization.d.mts","names":[],"sources":["../../src/types/form-customization.ts"],"mappings":";;;UAEiB,eAAA;EACf,KAAA;EACA,WAAA;EACA,KAAA;AAAA;AAAA,KAGU,UAAA,GAAa,OAAA,CAAQ,MAAA,CAAO,WAAA,EAAa,eAAA;AAAA,UAEpC,aAAA;EACf,KAAA;EACA,WAAA;EACA,KAAA;EACA,OAAA,GAAU,OAAA;EACV,aAAA;AAAA;AAAA,KAGU,QAAA,GAAW,MAAA,SAAe,aAAA;AAAA,UAErB,YAAA;EACf,KAAA;EACA,WAAA;AAAA;AAAA,KAGU,OAAA,GAAU,MAAA,SAAe,YAAA"}