@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.
- package/CHANGELOG.md +33 -0
- package/dist/components/compound/effect-catalog/card.d.mts +22 -0
- package/dist/components/compound/effect-catalog/card.d.mts.map +1 -0
- package/dist/components/compound/effect-catalog/card.mjs +82 -0
- package/dist/components/compound/effect-catalog/card.mjs.map +1 -0
- package/dist/components/compound/effect-catalog/category-filter.d.mts +27 -0
- package/dist/components/compound/effect-catalog/category-filter.d.mts.map +1 -0
- package/dist/components/compound/effect-catalog/category-filter.mjs +61 -0
- package/dist/components/compound/effect-catalog/category-filter.mjs.map +1 -0
- package/dist/components/compound/effect-catalog/empty.d.mts +17 -0
- package/dist/components/compound/effect-catalog/empty.d.mts.map +1 -0
- package/dist/components/compound/effect-catalog/empty.mjs +29 -0
- package/dist/components/compound/effect-catalog/empty.mjs.map +1 -0
- package/dist/components/compound/effect-catalog/index.d.mts +6 -0
- package/dist/components/compound/effect-catalog/list.d.mts +19 -0
- package/dist/components/compound/effect-catalog/list.d.mts.map +1 -0
- package/dist/components/compound/effect-catalog/list.mjs +33 -0
- package/dist/components/compound/effect-catalog/list.mjs.map +1 -0
- package/dist/components/compound/effect-catalog/root.d.mts +31 -0
- package/dist/components/compound/effect-catalog/root.d.mts.map +1 -0
- package/dist/components/compound/effect-catalog/root.mjs +67 -0
- package/dist/components/compound/effect-catalog/root.mjs.map +1 -0
- package/dist/components/compound/effect-catalog/search-filter.d.mts +21 -0
- package/dist/components/compound/effect-catalog/search-filter.d.mts.map +1 -0
- package/dist/components/compound/effect-catalog/search-filter.mjs +47 -0
- package/dist/components/compound/effect-catalog/search-filter.mjs.map +1 -0
- package/dist/components/compound/pipe-catalog/card.mjs +1 -1
- package/dist/components/compound/pipe-catalog/category-filter.mjs +1 -1
- package/dist/components/compound/pipe-catalog/provider-filter.mjs +1 -1
- package/dist/components/compound/pipe-catalog/root.mjs +1 -1
- package/dist/components/compound/pipe-form/content.d.mts +6 -1
- package/dist/components/compound/pipe-form/content.d.mts.map +1 -1
- package/dist/components/compound/pipe-form/content.mjs +3 -2
- package/dist/components/compound/pipe-form/content.mjs.map +1 -1
- package/dist/components/compound/pipe-form/errors.d.mts.map +1 -1
- package/dist/components/compound/pipe-form/errors.mjs +5 -4
- package/dist/components/compound/pipe-form/errors.mjs.map +1 -1
- package/dist/components/compound/pipe-form/root.d.mts +3 -1
- package/dist/components/compound/pipe-form/root.d.mts.map +1 -1
- package/dist/components/compound/pipe-form/root.mjs +5 -3
- package/dist/components/compound/pipe-form/root.mjs.map +1 -1
- package/dist/components/compound/search-catalog/active-filters.mjs +1 -1
- package/dist/components/compound/search-catalog/category-filter.mjs +1 -1
- package/dist/components/compound/search-catalog/provider-filter.mjs +1 -1
- package/dist/components/compound/search-form/content.d.mts +6 -1
- package/dist/components/compound/search-form/content.d.mts.map +1 -1
- package/dist/components/compound/search-form/content.mjs +3 -2
- package/dist/components/compound/search-form/content.mjs.map +1 -1
- package/dist/components/compound/search-form/errors.d.mts.map +1 -1
- package/dist/components/compound/search-form/errors.mjs +5 -4
- package/dist/components/compound/search-form/errors.mjs.map +1 -1
- package/dist/components/compound/search-form/root.d.mts +3 -1
- package/dist/components/compound/search-form/root.d.mts.map +1 -1
- package/dist/components/compound/search-form/root.mjs +5 -3
- package/dist/components/compound/search-form/root.mjs.map +1 -1
- package/dist/components/compound/searches-catalog/active-filters.mjs +1 -1
- package/dist/components/compound/searches-catalog/category-filter.mjs +1 -1
- package/dist/components/compound/searches-catalog/provider-filter.mjs +1 -1
- package/dist/components/defaults/adapters/context-select-input.mjs +1 -1
- package/dist/components/defaults/adapters/context-select-input.mjs.map +1 -1
- package/dist/components/defaults/adapters/exact-range-input.mjs +1 -1
- package/dist/components/defaults/adapters/index.d.mts.map +1 -1
- package/dist/components/defaults/adapters/index.mjs +8 -5
- package/dist/components/defaults/adapters/index.mjs.map +1 -1
- package/dist/components/defaults/adapters/int-input.mjs.map +1 -1
- package/dist/components/defaults/adapters/json-extraction-input.mjs +1 -1
- package/dist/components/defaults/adapters/loose-object-input.mjs +111 -0
- package/dist/components/defaults/adapters/loose-object-input.mjs.map +1 -0
- package/dist/components/defaults/adapters/pipes-run-if-input.mjs +69 -56
- package/dist/components/defaults/adapters/pipes-run-if-input.mjs.map +1 -1
- package/dist/components/defaults/adapters/providers-input.mjs.map +1 -1
- package/dist/components/defaults/adapters/search-payload-input.mjs +18 -0
- package/dist/components/defaults/adapters/search-payload-input.mjs.map +1 -0
- package/dist/components/defaults/adapters/select-input.mjs +46 -27
- package/dist/components/defaults/adapters/select-input.mjs.map +1 -1
- package/dist/components/defaults/catalog/card-derived.d.mts +1 -1
- package/dist/components/defaults/catalog/card-derived.d.mts.map +1 -1
- package/dist/components/defaults/catalog/card-derived.mjs +12 -6
- package/dist/components/defaults/catalog/card-derived.mjs.map +1 -1
- package/dist/components/defaults/catalog/provider-avatars.mjs +3 -3
- package/dist/components/defaults/catalog/provider-avatars.mjs.map +1 -1
- package/dist/components/defaults/form/form-empty-state.mjs +23 -0
- package/dist/components/defaults/form/form-empty-state.mjs.map +1 -0
- package/dist/components/defaults/layout/field-wrapper.d.mts.map +1 -1
- package/dist/components/defaults/layout/field-wrapper.mjs +11 -5
- package/dist/components/defaults/layout/field-wrapper.mjs.map +1 -1
- package/dist/components/defaults/layout/group.mjs +1 -1
- package/dist/components/internal/LiquidEditor/LiquidEditor.mjs +2 -2
- package/dist/components/internal/LiquidEditor/LiquidEditor.mjs.map +1 -1
- package/dist/components/internal/form-level-errors.mjs +4 -3
- package/dist/components/internal/form-level-errors.mjs.map +1 -1
- package/dist/components/internal/icons.mjs +27 -1
- package/dist/components/internal/icons.mjs.map +1 -1
- package/dist/components/ui/alert.d.mts +47 -0
- package/dist/components/ui/alert.d.mts.map +1 -0
- package/dist/components/ui/alert.mjs +66 -0
- package/dist/components/ui/alert.mjs.map +1 -0
- package/dist/context/catalog-card-context.mjs +4 -2
- package/dist/context/catalog-card-context.mjs.map +1 -1
- package/dist/context/effect-catalog-card-context.d.mts +20 -0
- package/dist/context/effect-catalog-card-context.d.mts.map +1 -0
- package/dist/context/effect-catalog-card-context.mjs +13 -0
- package/dist/context/effect-catalog-card-context.mjs.map +1 -0
- package/dist/context/effect-catalog-context.d.mts +20 -0
- package/dist/context/effect-catalog-context.d.mts.map +1 -0
- package/dist/context/effect-catalog-context.mjs +13 -0
- package/dist/context/effect-catalog-context.mjs.map +1 -0
- package/dist/context/form-context.d.mts +21 -0
- package/dist/context/form-context.d.mts.map +1 -0
- package/dist/context/form-context.mjs +11 -1
- package/dist/context/form-context.mjs.map +1 -1
- package/dist/context/form-provider.d.mts +3 -1
- package/dist/context/form-provider.d.mts.map +1 -1
- package/dist/context/form-provider.mjs +8 -2
- package/dist/context/form-provider.mjs.map +1 -1
- package/dist/hooks/use-effect-catalog-table.d.mts +33 -0
- package/dist/hooks/use-effect-catalog-table.d.mts.map +1 -0
- package/dist/hooks/use-effect-catalog-table.mjs +104 -0
- package/dist/hooks/use-effect-catalog-table.mjs.map +1 -0
- package/dist/hooks/use-form-core.mjs +8 -5
- package/dist/hooks/use-form-core.mjs.map +1 -1
- package/dist/hooks/use-pipe-catalog-table.d.mts +8 -8
- package/dist/hooks/use-pipe-catalog-table.d.mts.map +1 -1
- package/dist/hooks/use-pipe-catalog-table.mjs +2 -2
- package/dist/hooks/use-pipe-catalog-table.mjs.map +1 -1
- package/dist/hooks/use-pipe-form.d.mts.map +1 -1
- package/dist/hooks/use-pipe-form.mjs +18 -19
- package/dist/hooks/use-pipe-form.mjs.map +1 -1
- package/dist/hooks/use-search-catalog-table.d.mts +6 -6
- package/dist/hooks/use-search-form.d.mts.map +1 -1
- package/dist/hooks/use-search-form.mjs +18 -18
- package/dist/hooks/use-search-form.mjs.map +1 -1
- package/dist/hooks/use-sheet-effect-form.d.mts +35 -0
- package/dist/hooks/use-sheet-effect-form.d.mts.map +1 -0
- package/dist/hooks/use-sheet-effect-form.mjs +103 -0
- package/dist/hooks/use-sheet-effect-form.mjs.map +1 -0
- package/dist/index.d.mts +15 -3
- package/dist/index.mjs +16 -4
- package/dist/styles/pipe0-form.css +1 -1
- package/dist/types/adapters.d.mts +22 -1
- package/dist/types/adapters.d.mts.map +1 -1
- package/dist/types/catalog-adapters.d.mts +23 -3
- package/dist/types/catalog-adapters.d.mts.map +1 -1
- package/dist/types/field-props.d.mts +15 -13
- package/dist/types/field-props.d.mts.map +1 -1
- package/dist/types/form-customization.d.mts +2 -25
- package/dist/utils/build-section-handlers.mjs +9 -75
- package/dist/utils/build-section-handlers.mjs.map +1 -1
- package/dist/utils/catalog-helpers.d.mts +1 -1
- package/dist/widgets/token-pricing-badge.d.mts +1 -0
- package/dist/widgets/token-pricing-badge.mjs +55 -0
- package/dist/widgets/token-pricing-badge.mjs.map +1 -0
- package/dist/widgets/widget-strip.d.mts.map +1 -1
- package/dist/widgets/widget-strip.mjs +1 -0
- package/dist/widgets/widget-strip.mjs.map +1 -1
- package/dist/widgets/widget-view.d.mts.map +1 -1
- package/dist/widgets/widget-view.mjs +6 -0
- package/dist/widgets/widget-view.mjs.map +1 -1
- package/package.json +15 -25
- package/dist/components/defaults/adapters/key-value-list-input.mjs +0 -102
- package/dist/components/defaults/adapters/key-value-list-input.mjs.map +0 -1
- package/dist/types/form-customization.d.mts.map +0 -1
|
@@ -1,25 +1,2 @@
|
|
|
1
|
-
import {
|
|
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.
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
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 {
|
|
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":";;;;
|
|
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"}
|
|
@@ -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":";;;;
|
|
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":"
|
|
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
|
|
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
|
-
"@
|
|
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
|
-
"@
|
|
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.
|
|
87
|
+
"@pipe0/base": "0.5.1"
|
|
88
88
|
},
|
|
89
89
|
"devDependencies": {
|
|
90
|
-
"@
|
|
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"}
|