@flanksource/clicky-ui 0.2.12 → 0.2.14

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 (173) hide show
  1. package/dist/components/Combobox.cjs +47 -33
  2. package/dist/components/Combobox.cjs.map +1 -1
  3. package/dist/components/Combobox.d.ts +12 -0
  4. package/dist/components/Combobox.d.ts.map +1 -1
  5. package/dist/components/Combobox.js +48 -34
  6. package/dist/components/Combobox.js.map +1 -1
  7. package/dist/components/IconButton.cjs +26 -0
  8. package/dist/components/IconButton.cjs.map +1 -0
  9. package/dist/components/IconButton.d.ts +25 -0
  10. package/dist/components/IconButton.d.ts.map +1 -0
  11. package/dist/components/IconButton.js +26 -0
  12. package/dist/components/IconButton.js.map +1 -0
  13. package/dist/components/SecretKeySelector.cjs +151 -0
  14. package/dist/components/SecretKeySelector.cjs.map +1 -0
  15. package/dist/components/SecretKeySelector.d.ts +51 -0
  16. package/dist/components/SecretKeySelector.d.ts.map +1 -0
  17. package/dist/components/SecretKeySelector.js +151 -0
  18. package/dist/components/SecretKeySelector.js.map +1 -0
  19. package/dist/components/WorkloadPicker.cjs +144 -0
  20. package/dist/components/WorkloadPicker.cjs.map +1 -0
  21. package/dist/components/WorkloadPicker.d.ts +52 -0
  22. package/dist/components/WorkloadPicker.d.ts.map +1 -0
  23. package/dist/components/WorkloadPicker.js +144 -0
  24. package/dist/components/WorkloadPicker.js.map +1 -0
  25. package/dist/components/icon-menu-picker.cjs +83 -112
  26. package/dist/components/icon-menu-picker.cjs.map +1 -1
  27. package/dist/components/icon-menu-picker.d.ts.map +1 -1
  28. package/dist/components/icon-menu-picker.js +85 -114
  29. package/dist/components/icon-menu-picker.js.map +1 -1
  30. package/dist/components.cjs +10 -0
  31. package/dist/components.cjs.map +1 -1
  32. package/dist/components.d.ts +3 -0
  33. package/dist/components.d.ts.map +1 -1
  34. package/dist/components.js +11 -1
  35. package/dist/components.js.map +1 -1
  36. package/dist/data/Clicky.cjs +1 -1
  37. package/dist/data/Clicky.cjs.map +1 -1
  38. package/dist/data/Clicky.js +1 -1
  39. package/dist/data/Clicky.js.map +1 -1
  40. package/dist/data/TimeseriesCoreBars.cjs +8 -1
  41. package/dist/data/TimeseriesCoreBars.cjs.map +1 -1
  42. package/dist/data/TimeseriesCoreBars.d.ts.map +1 -1
  43. package/dist/data/TimeseriesCoreBars.js +8 -1
  44. package/dist/data/TimeseriesCoreBars.js.map +1 -1
  45. package/dist/data/Version.cjs +42 -0
  46. package/dist/data/Version.cjs.map +1 -0
  47. package/dist/data/Version.d.ts +36 -0
  48. package/dist/data/Version.d.ts.map +1 -0
  49. package/dist/data/Version.js +42 -0
  50. package/dist/data/Version.js.map +1 -0
  51. package/dist/data/test-runner/TestDetailPanel.cjs +165 -0
  52. package/dist/data/test-runner/TestDetailPanel.cjs.map +1 -0
  53. package/dist/data/test-runner/TestDetailPanel.d.ts +7 -0
  54. package/dist/data/test-runner/TestDetailPanel.d.ts.map +1 -0
  55. package/dist/data/test-runner/TestDetailPanel.js +165 -0
  56. package/dist/data/test-runner/TestDetailPanel.js.map +1 -0
  57. package/dist/data/test-runner/TestFailureDetail.cjs +78 -0
  58. package/dist/data/test-runner/TestFailureDetail.cjs.map +1 -0
  59. package/dist/data/test-runner/TestFailureDetail.d.ts +14 -0
  60. package/dist/data/test-runner/TestFailureDetail.d.ts.map +1 -0
  61. package/dist/data/test-runner/TestFailureDetail.js +78 -0
  62. package/dist/data/test-runner/TestFailureDetail.js.map +1 -0
  63. package/dist/data/test-runner/TestFilterBar.cjs +108 -0
  64. package/dist/data/test-runner/TestFilterBar.cjs.map +1 -0
  65. package/dist/data/test-runner/TestFilterBar.d.ts +15 -0
  66. package/dist/data/test-runner/TestFilterBar.d.ts.map +1 -0
  67. package/dist/data/test-runner/TestFilterBar.js +108 -0
  68. package/dist/data/test-runner/TestFilterBar.js.map +1 -0
  69. package/dist/data/test-runner/TestRunSummary.cjs +81 -0
  70. package/dist/data/test-runner/TestRunSummary.cjs.map +1 -0
  71. package/dist/data/test-runner/TestRunSummary.d.ts +19 -0
  72. package/dist/data/test-runner/TestRunSummary.d.ts.map +1 -0
  73. package/dist/data/test-runner/TestRunSummary.js +81 -0
  74. package/dist/data/test-runner/TestRunSummary.js.map +1 -0
  75. package/dist/data/test-runner/TestRunner.cjs +143 -0
  76. package/dist/data/test-runner/TestRunner.cjs.map +1 -0
  77. package/dist/data/test-runner/TestRunner.d.ts +42 -0
  78. package/dist/data/test-runner/TestRunner.d.ts.map +1 -0
  79. package/dist/data/test-runner/TestRunner.fixtures.d.ts +26 -0
  80. package/dist/data/test-runner/TestRunner.fixtures.d.ts.map +1 -0
  81. package/dist/data/test-runner/TestRunner.js +143 -0
  82. package/dist/data/test-runner/TestRunner.js.map +1 -0
  83. package/dist/data/test-runner/TestTree.cjs +42 -0
  84. package/dist/data/test-runner/TestTree.cjs.map +1 -0
  85. package/dist/data/test-runner/TestTree.d.ts +9 -0
  86. package/dist/data/test-runner/TestTree.d.ts.map +1 -0
  87. package/dist/data/test-runner/TestTree.js +42 -0
  88. package/dist/data/test-runner/TestTree.js.map +1 -0
  89. package/dist/data/test-runner/TestTreeNode.cjs +99 -0
  90. package/dist/data/test-runner/TestTreeNode.cjs.map +1 -0
  91. package/dist/data/test-runner/TestTreeNode.d.ts +12 -0
  92. package/dist/data/test-runner/TestTreeNode.d.ts.map +1 -0
  93. package/dist/data/test-runner/TestTreeNode.js +99 -0
  94. package/dist/data/test-runner/TestTreeNode.js.map +1 -0
  95. package/dist/data/test-runner/adapter.cjs +57 -0
  96. package/dist/data/test-runner/adapter.cjs.map +1 -0
  97. package/dist/data/test-runner/adapter.d.ts +60 -0
  98. package/dist/data/test-runner/adapter.d.ts.map +1 -0
  99. package/dist/data/test-runner/adapter.js +57 -0
  100. package/dist/data/test-runner/adapter.js.map +1 -0
  101. package/dist/data/test-runner/context.cjs +15 -0
  102. package/dist/data/test-runner/context.cjs.map +1 -0
  103. package/dist/data/test-runner/context.d.ts +40 -0
  104. package/dist/data/test-runner/context.d.ts.map +1 -0
  105. package/dist/data/test-runner/context.js +15 -0
  106. package/dist/data/test-runner/context.js.map +1 -0
  107. package/dist/data/test-runner/filterState.cjs +47 -0
  108. package/dist/data/test-runner/filterState.cjs.map +1 -0
  109. package/dist/data/test-runner/filterState.d.ts +14 -0
  110. package/dist/data/test-runner/filterState.d.ts.map +1 -0
  111. package/dist/data/test-runner/filterState.js +47 -0
  112. package/dist/data/test-runner/filterState.js.map +1 -0
  113. package/dist/data/test-runner/frameworkIcon.cjs +27 -0
  114. package/dist/data/test-runner/frameworkIcon.cjs.map +1 -0
  115. package/dist/data/test-runner/frameworkIcon.d.ts +3 -0
  116. package/dist/data/test-runner/frameworkIcon.d.ts.map +1 -0
  117. package/dist/data/test-runner/frameworkIcon.js +27 -0
  118. package/dist/data/test-runner/frameworkIcon.js.map +1 -0
  119. package/dist/data/test-runner/index.d.ts +14 -0
  120. package/dist/data/test-runner/index.d.ts.map +1 -0
  121. package/dist/data/test-runner/status.cjs +234 -0
  122. package/dist/data/test-runner/status.cjs.map +1 -0
  123. package/dist/data/test-runner/status.d.ts +52 -0
  124. package/dist/data/test-runner/status.d.ts.map +1 -0
  125. package/dist/data/test-runner/status.js +234 -0
  126. package/dist/data/test-runner/status.js.map +1 -0
  127. package/dist/data/test-runner/types.d.ts +148 -0
  128. package/dist/data/test-runner/types.d.ts.map +1 -0
  129. package/dist/data/version-info.cjs +26 -0
  130. package/dist/data/version-info.cjs.map +1 -0
  131. package/dist/data/version-info.d.ts +11 -0
  132. package/dist/data/version-info.d.ts.map +1 -0
  133. package/dist/data/version-info.js +26 -0
  134. package/dist/data/version-info.js.map +1 -0
  135. package/dist/data.cjs +49 -0
  136. package/dist/data.cjs.map +1 -1
  137. package/dist/data.d.ts +3 -0
  138. package/dist/data.d.ts.map +1 -1
  139. package/dist/data.js +50 -1
  140. package/dist/data.js.map +1 -1
  141. package/dist/index.cjs +59 -0
  142. package/dist/index.cjs.map +1 -1
  143. package/dist/index.js +60 -1
  144. package/dist/index.js.map +1 -1
  145. package/dist/overlay/DropdownMenu.cjs +57 -30
  146. package/dist/overlay/DropdownMenu.cjs.map +1 -1
  147. package/dist/overlay/DropdownMenu.d.ts.map +1 -1
  148. package/dist/overlay/DropdownMenu.js +57 -30
  149. package/dist/overlay/DropdownMenu.js.map +1 -1
  150. package/dist/overlay/Modal.cjs +62 -6
  151. package/dist/overlay/Modal.cjs.map +1 -1
  152. package/dist/overlay/Modal.d.ts +19 -1
  153. package/dist/overlay/Modal.d.ts.map +1 -1
  154. package/dist/overlay/Modal.js +62 -6
  155. package/dist/overlay/Modal.js.map +1 -1
  156. package/dist/rpc/CommandForm.cjs +2 -2
  157. package/dist/rpc/CommandForm.cjs.map +1 -1
  158. package/dist/rpc/CommandForm.d.ts.map +1 -1
  159. package/dist/rpc/CommandForm.js +3 -3
  160. package/dist/rpc/CommandForm.js.map +1 -1
  161. package/dist/rpc/formMetadata.cjs +5 -4
  162. package/dist/rpc/formMetadata.cjs.map +1 -1
  163. package/dist/rpc/formMetadata.d.ts.map +1 -1
  164. package/dist/rpc/formMetadata.js +6 -5
  165. package/dist/rpc/formMetadata.js.map +1 -1
  166. package/dist/rpc/types.cjs +4 -0
  167. package/dist/rpc/types.cjs.map +1 -1
  168. package/dist/rpc/types.d.ts +10 -0
  169. package/dist/rpc/types.d.ts.map +1 -1
  170. package/dist/rpc/types.js +5 -1
  171. package/dist/rpc/types.js.map +1 -1
  172. package/dist/styles.css +1 -1
  173. package/package.json +3 -1
@@ -1 +1 @@
1
- {"version":3,"file":"CommandForm.js","sources":["../../src/rpc/CommandForm.tsx"],"sourcesContent":["import { useReducer, type FormEvent, type KeyboardEvent, type ReactNode } from \"react\";\nimport { Button } from \"../components/button\";\nimport { Icon } from \"../data/Icon\";\nimport { UiClose } from \"../icons\";\nimport { isPositionalParam, type OpenAPIParameter } from \"./types\";\n\nexport type CommandFormProps = {\n parameters: OpenAPIParameter[];\n onExecute: (params: Record<string, string>, headers: Record<string, string>) => void;\n isPending: boolean;\n method: string;\n path: string;\n accept: string;\n initialValues?: Record<string, string>;\n};\n\ntype FormState = Record<string, string>;\ntype FormAction = { name: string; value: string };\n\nfunction formReducer(state: FormState, action: FormAction): FormState {\n return { ...state, [action.name]: action.value };\n}\n\nexport function CommandForm({\n parameters,\n onExecute,\n isPending,\n method: _method,\n path,\n accept,\n initialValues,\n}: CommandFormProps) {\n const [values, dispatch] = useReducer(\n formReducer,\n { parameters, path, initialValues },\n ({ parameters: params, path: formPath, initialValues: overrides }) =>\n buildInitialState(normalizeParameters(params, formPath), formPath, overrides),\n );\n\n const formParameters = normalizeParameters(parameters, path);\n const visibleParams = formParameters.filter((p) => !(p.in === \"path\" && initialValues?.[p.name]));\n const positionalNames = new Set(formParameters.filter(isPositionalParam).map((p) => p.name));\n const inlineLayout = visibleParams.length >= INLINE_LAYOUT_THRESHOLD;\n\n function handleSubmit(event: FormEvent) {\n event.preventDefault();\n const params: Record<string, string> = {};\n const args: string[] = [];\n for (const param of formParameters) {\n const value = submitValue(param, values[param.name]);\n if (value == null) continue;\n if (positionalNames.has(param.name)) {\n args.push(...splitArgsValue(value));\n } else {\n params[param.name] = value;\n }\n }\n if (args.length > 0) params.args = args.join(\",\");\n onExecute(params, { Accept: accept });\n }\n\n return (\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n {visibleParams.length > 0 && (\n <div className={inlineLayout ? \"grid gap-2\" : \"grid gap-4\"}>\n {visibleParams.map((param) => (\n <ParameterField\n key={param.name}\n param={param}\n value={values[param.name] || \"\"}\n inline={inlineLayout}\n onChange={(value) => dispatch({ name: param.name, value })}\n />\n ))}\n </div>\n )}\n\n <div\n className={\n inlineLayout\n ? \"sticky bottom-0 z-10 -mx-2 flex justify-end border-t border-border bg-background/95 px-2 py-3 backdrop-blur-sm\"\n : \"flex justify-end\"\n }\n >\n <Button type=\"submit\" disabled={isPending}>\n {isPending ? \"Executing...\" : \"Execute\"}\n </Button>\n </div>\n </form>\n );\n}\n\nconst INLINE_LAYOUT_THRESHOLD = 6;\n\nfunction ParameterField({\n param,\n value,\n inline,\n onChange,\n}: {\n param: OpenAPIParameter;\n value: string;\n inline: boolean;\n onChange: (value: string) => void;\n}) {\n const schema = param.schema;\n const fieldId = `param-${param.name}`;\n\n if (isMultiValueParam(param)) {\n return (\n <FieldWrapper param={param} fieldId={fieldId} inline={inline}>\n <TagInput\n id={fieldId}\n value={value}\n placeholder={param.description || param.name}\n onChange={onChange}\n />\n </FieldWrapper>\n );\n }\n\n if (schema?.enum) {\n return (\n <FieldWrapper param={param} fieldId={fieldId} inline={inline}>\n <select\n id={fieldId}\n value={value}\n className={inputClassName}\n onChange={(event) => onChange(event.target.value)}\n >\n <option value=\"\">Select {param.name}</option>\n {schema.enum.map((v) => (\n <option key={String(v)} value={String(v)}>\n {String(v)}\n </option>\n ))}\n </select>\n </FieldWrapper>\n );\n }\n\n if (schema?.type === \"boolean\") {\n const checkbox = (\n <input\n id={fieldId}\n type=\"checkbox\"\n className=\"h-4 w-4 accent-primary\"\n checked={value === \"true\"}\n onChange={(event) => onChange(event.target.checked ? \"true\" : \"false\")}\n />\n );\n if (inline) {\n return (\n <FieldWrapper param={param} fieldId={fieldId} inline>\n <div className=\"flex h-9 items-center\">{checkbox}</div>\n </FieldWrapper>\n );\n }\n return (\n <div className=\"flex items-center gap-2\">\n {checkbox}\n <label htmlFor={fieldId} className=\"text-sm font-medium\">\n {param.name}\n {param.required && <span className=\"text-destructive\"> *</span>}\n </label>\n {param.description && (\n <span className=\"text-xs text-muted-foreground\">{param.description}</span>\n )}\n </div>\n );\n }\n\n if (isDateParam(param)) {\n const dateTime = schema?.format === \"date-time\";\n return (\n <FieldWrapper param={param} fieldId={fieldId} inline={inline}>\n <div className=\"flex gap-2\">\n <input\n id={fieldId}\n type={dateTime ? \"datetime-local\" : \"date\"}\n value={dateInputValue(value, dateTime)}\n className={inputClassName}\n onChange={(event) => onChange(dateOutputValue(event.target.value, dateTime))}\n />\n {value && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n aria-label={`Clear ${param.name}`}\n onClick={() => onChange(\"\")}\n >\n <Icon icon={UiClose} />\n </Button>\n )}\n </div>\n </FieldWrapper>\n );\n }\n\n const inputType = schema?.type === \"integer\" || schema?.type === \"number\" ? \"number\" : \"text\";\n\n return (\n <FieldWrapper param={param} fieldId={fieldId} inline={inline}>\n <input\n id={fieldId}\n type={inputType}\n value={value}\n className={inputClassName}\n onChange={(event) => onChange(event.target.value)}\n placeholder={\n schema?.default != null ? String(schema.default) : param.description || param.name\n }\n />\n </FieldWrapper>\n );\n}\n\nfunction TagInput({\n id,\n value,\n placeholder,\n onChange,\n}: {\n id: string;\n value: string;\n placeholder: string;\n onChange: (value: string) => void;\n}) {\n const tags = parseTags(value);\n\n function commit(raw: string, input: HTMLInputElement) {\n const next = raw\n .split(\",\")\n .map((part) => part.trim())\n .filter(Boolean);\n if (next.length === 0) return;\n onChange(serializeTags([...tags, ...next]));\n input.value = \"\";\n }\n\n function remove(index: number) {\n onChange(serializeTags(tags.filter((_, i) => i !== index)));\n }\n\n function handleKeyDown(event: KeyboardEvent<HTMLInputElement>) {\n const input = event.currentTarget;\n if (event.key === \"Enter\" || event.key === \",\") {\n event.preventDefault();\n commit(input.value, input);\n return;\n }\n if (event.key === \"Backspace\" && input.value === \"\" && tags.length > 0) {\n remove(tags.length - 1);\n }\n }\n\n return (\n <div className=\"flex min-h-9 flex-wrap items-center gap-1.5 rounded-md border border-input bg-transparent px-2 py-1 shadow-sm\">\n {tags.map((tag, index) => (\n <span\n key={`${tag}-${index}`}\n className=\"inline-flex h-6 max-w-full items-center gap-1 rounded-md bg-muted px-2 text-xs\"\n >\n <span className=\"truncate\">{tag}</span>\n <button\n type=\"button\"\n className=\"text-muted-foreground hover:text-foreground\"\n aria-label={`Remove ${tag}`}\n onClick={() => remove(index)}\n >\n <Icon icon={UiClose} />\n </button>\n </span>\n ))}\n <input\n id={id}\n className=\"min-w-32 flex-1 bg-transparent px-1 py-1 text-sm outline-none\"\n placeholder={tags.length === 0 ? placeholder : \"\"}\n onKeyDown={handleKeyDown}\n onBlur={(event) => commit(event.currentTarget.value, event.currentTarget)}\n />\n </div>\n );\n}\n\nfunction FieldWrapper({\n param,\n fieldId,\n inline,\n children,\n}: {\n param: OpenAPIParameter;\n fieldId: string;\n inline?: boolean;\n children: ReactNode;\n}) {\n const label = (\n <label htmlFor={fieldId} className=\"text-sm font-medium\">\n {param.name}\n {param.required && <span className=\"text-destructive\"> *</span>}\n </label>\n );\n\n if (inline) {\n return (\n <div className=\"grid grid-cols-[10rem_1fr] items-start gap-x-3 gap-y-0.5\">\n <div className=\"flex h-9 items-center\">{label}</div>\n <div className=\"min-w-0\">{children}</div>\n {param.description && (\n <p className=\"col-start-2 text-xs text-muted-foreground\">{param.description}</p>\n )}\n </div>\n );\n }\n\n return (\n <div className=\"space-y-1.5\">\n {label}\n {children}\n {param.description && <p className=\"text-xs text-muted-foreground\">{param.description}</p>}\n </div>\n );\n}\n\nexport function normalizeParameters(\n parameters: OpenAPIParameter[],\n path: string,\n): OpenAPIParameter[] {\n const pathParams = pathParamNames(path);\n const firstPathParam = pathParams[0];\n const seen = new Set(parameters.map((param) => param.name));\n const normalized = parameters.filter(\n (param) => !(param.name === \"args\" && firstPathParam != null && !seen.has(firstPathParam)),\n );\n for (const name of pathParams) {\n if (seen.has(name)) continue;\n normalized.unshift({\n name,\n in: \"path\",\n required: true,\n description: \"Path parameter\",\n schema: { type: \"string\" },\n });\n }\n return normalized;\n}\n\nexport function pathParamNames(path: string): string[] {\n return [...path.matchAll(/\\{([^}]+)\\}/g)]\n .map((match) => match[1])\n .filter((name): name is string => Boolean(name));\n}\n\nfunction buildInitialState(\n parameters: OpenAPIParameter[],\n path: string,\n overrides?: Record<string, string>,\n): FormState {\n const state: FormState = {};\n for (const p of parameters) {\n state[p.name] = initialParamValue(p, overrides?.[p.name]);\n }\n for (const name of pathParamNames(path)) {\n if (state[name] == null) {\n state[name] = overrides?.[name] ?? \"\";\n }\n }\n return state;\n}\n\nfunction initialParamValue(param: OpenAPIParameter, override: string | undefined): string {\n if (override != null) return sanitizeInitialValue(param, override);\n const value = param.schema?.default;\n if (value == null) return \"\";\n return sanitizeInitialValue(param, String(value));\n}\n\nfunction sanitizeInitialValue(param: OpenAPIParameter, value: string): string {\n const trimmed = value.trim();\n if (trimmed === \"[]\" || trimmed === \"null\") return \"\";\n if (isDateParam(param) && isZeroDate(trimmed)) return \"\";\n return value;\n}\n\nexport function submitValue(param: OpenAPIParameter, value: string | undefined): string | null {\n const trimmed = (value ?? \"\").trim();\n if (!trimmed || trimmed === \"[]\" || trimmed === \"null\") return null;\n if (isDateParam(param) && isZeroDate(trimmed)) return null;\n return trimmed;\n}\n\nfunction splitArgsValue(value: string): string[] {\n try {\n const parsed = JSON.parse(value);\n if (Array.isArray(parsed)) return parsed.map(String).filter(Boolean);\n } catch {\n // Use comma splitting below.\n }\n return value\n .split(\",\")\n .map((part) => part.trim())\n .filter(Boolean);\n}\n\nfunction isMultiValueParam(param: OpenAPIParameter): boolean {\n const text = `${param.name} ${param.description ?? \"\"}`.toLowerCase();\n return (\n param.schema?.type === \"array\" ||\n String(param.schema?.default ?? \"\") === \"[]\" ||\n text.includes(\"repeatable\")\n );\n}\n\nfunction parseTags(value: string): string[] {\n const trimmed = value.trim();\n if (!trimmed || trimmed === \"[]\" || trimmed === \"null\") return [];\n try {\n const parsed = JSON.parse(trimmed);\n if (Array.isArray(parsed)) return parsed.map(String).filter(Boolean);\n } catch {\n // Fall back to comma-delimited tags below.\n }\n return trimmed\n .split(\",\")\n .map((part) => part.trim())\n .filter(Boolean);\n}\n\nfunction serializeTags(tags: string[]): string {\n return tags.join(\",\");\n}\n\nfunction isDateParam(param: OpenAPIParameter): boolean {\n const format = param.schema?.format?.toLowerCase();\n const text = `${param.name} ${param.description ?? \"\"}`.toLowerCase();\n return format === \"date\" || format === \"date-time\" || text.includes(\"date\");\n}\n\nfunction isZeroDate(value: string): boolean {\n return value.startsWith(\"0001-01-01\") || value === \"0001-01-01\";\n}\n\nfunction dateInputValue(value: string, dateTime: boolean): string {\n if (!value || value.startsWith(\"0001-01-01\")) return \"\";\n if (!dateTime) return value.slice(0, 10);\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) return value.slice(0, 16);\n const offset = parsed.getTimezoneOffset() * 60_000;\n return new Date(parsed.getTime() - offset).toISOString().slice(0, 16);\n}\n\nfunction dateOutputValue(value: string, dateTime: boolean): string {\n if (!value) return \"\";\n if (!dateTime) return value;\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) return value;\n return parsed.toISOString();\n}\n\nconst inputClassName =\n \"h-9 w-full min-w-0 rounded-md border border-input bg-background px-2 text-sm text-foreground outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:bg-muted/40 focus-visible:ring-2 focus-visible:ring-ring\";\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CommandForm.js","sources":["../../src/rpc/CommandForm.tsx"],"sourcesContent":["import { useReducer, type FormEvent, type KeyboardEvent, type ReactNode } from \"react\";\nimport { Button } from \"../components/button\";\nimport { Icon } from \"../data/Icon\";\nimport { UiClose } from \"../icons\";\nimport {\n isPositionalParam,\n parameterPlaceholder,\n type OpenAPIParameter,\n} from \"./types\";\n\nexport type CommandFormProps = {\n parameters: OpenAPIParameter[];\n onExecute: (params: Record<string, string>, headers: Record<string, string>) => void;\n isPending: boolean;\n method: string;\n path: string;\n accept: string;\n initialValues?: Record<string, string>;\n};\n\ntype FormState = Record<string, string>;\ntype FormAction = { name: string; value: string };\n\nfunction formReducer(state: FormState, action: FormAction): FormState {\n return { ...state, [action.name]: action.value };\n}\n\nexport function CommandForm({\n parameters,\n onExecute,\n isPending,\n method: _method,\n path,\n accept,\n initialValues,\n}: CommandFormProps) {\n const [values, dispatch] = useReducer(\n formReducer,\n { parameters, path, initialValues },\n ({ parameters: params, path: formPath, initialValues: overrides }) =>\n buildInitialState(normalizeParameters(params, formPath), formPath, overrides),\n );\n\n const formParameters = normalizeParameters(parameters, path);\n const visibleParams = formParameters.filter((p) => !(p.in === \"path\" && initialValues?.[p.name]));\n const positionalNames = new Set(formParameters.filter(isPositionalParam).map((p) => p.name));\n const inlineLayout = visibleParams.length >= INLINE_LAYOUT_THRESHOLD;\n\n function handleSubmit(event: FormEvent) {\n event.preventDefault();\n const params: Record<string, string> = {};\n const args: string[] = [];\n for (const param of formParameters) {\n const value = submitValue(param, values[param.name]);\n if (value == null) continue;\n if (positionalNames.has(param.name)) {\n args.push(...splitArgsValue(value));\n } else {\n params[param.name] = value;\n }\n }\n if (args.length > 0) params.args = args.join(\",\");\n onExecute(params, { Accept: accept });\n }\n\n return (\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n {visibleParams.length > 0 && (\n <div className={inlineLayout ? \"grid gap-2\" : \"grid gap-4\"}>\n {visibleParams.map((param) => (\n <ParameterField\n key={param.name}\n param={param}\n value={values[param.name] || \"\"}\n inline={inlineLayout}\n onChange={(value) => dispatch({ name: param.name, value })}\n />\n ))}\n </div>\n )}\n\n <div\n className={\n inlineLayout\n ? \"sticky bottom-0 z-10 -mx-2 flex justify-end border-t border-border bg-background/95 px-2 py-3 backdrop-blur-sm\"\n : \"flex justify-end\"\n }\n >\n <Button type=\"submit\" disabled={isPending}>\n {isPending ? \"Executing...\" : \"Execute\"}\n </Button>\n </div>\n </form>\n );\n}\n\nconst INLINE_LAYOUT_THRESHOLD = 6;\n\nfunction ParameterField({\n param,\n value,\n inline,\n onChange,\n}: {\n param: OpenAPIParameter;\n value: string;\n inline: boolean;\n onChange: (value: string) => void;\n}) {\n const schema = param.schema;\n const fieldId = `param-${param.name}`;\n\n if (isMultiValueParam(param)) {\n return (\n <FieldWrapper param={param} fieldId={fieldId} inline={inline}>\n <TagInput\n id={fieldId}\n value={value}\n placeholder={parameterPlaceholder(param) || param.name}\n onChange={onChange}\n />\n </FieldWrapper>\n );\n }\n\n if (schema?.enum) {\n return (\n <FieldWrapper param={param} fieldId={fieldId} inline={inline}>\n <select\n id={fieldId}\n value={value}\n className={inputClassName}\n onChange={(event) => onChange(event.target.value)}\n >\n <option value=\"\">Select {param.name}</option>\n {schema.enum.map((v) => (\n <option key={String(v)} value={String(v)}>\n {String(v)}\n </option>\n ))}\n </select>\n </FieldWrapper>\n );\n }\n\n if (schema?.type === \"boolean\") {\n const checkbox = (\n <input\n id={fieldId}\n type=\"checkbox\"\n className=\"h-4 w-4 accent-primary\"\n checked={value === \"true\"}\n onChange={(event) => onChange(event.target.checked ? \"true\" : \"false\")}\n />\n );\n if (inline) {\n return (\n <FieldWrapper param={param} fieldId={fieldId} inline>\n <div className=\"flex h-9 items-center\">{checkbox}</div>\n </FieldWrapper>\n );\n }\n return (\n <div className=\"flex items-center gap-2\">\n {checkbox}\n <label htmlFor={fieldId} className=\"text-sm font-medium\">\n {param.name}\n {param.required && <span className=\"text-destructive\"> *</span>}\n </label>\n {param.description && (\n <span className=\"text-xs text-muted-foreground\">{param.description}</span>\n )}\n </div>\n );\n }\n\n if (isDateParam(param)) {\n const dateTime = schema?.format === \"date-time\";\n return (\n <FieldWrapper param={param} fieldId={fieldId} inline={inline}>\n <div className=\"flex gap-2\">\n <input\n id={fieldId}\n type={dateTime ? \"datetime-local\" : \"date\"}\n value={dateInputValue(value, dateTime)}\n className={inputClassName}\n onChange={(event) => onChange(dateOutputValue(event.target.value, dateTime))}\n />\n {value && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n aria-label={`Clear ${param.name}`}\n onClick={() => onChange(\"\")}\n >\n <Icon icon={UiClose} />\n </Button>\n )}\n </div>\n </FieldWrapper>\n );\n }\n\n const inputType = schema?.type === \"integer\" || schema?.type === \"number\" ? \"number\" : \"text\";\n\n return (\n <FieldWrapper param={param} fieldId={fieldId} inline={inline}>\n <input\n id={fieldId}\n type={inputType}\n value={value}\n className={inputClassName}\n onChange={(event) => onChange(event.target.value)}\n placeholder={\n schema?.default != null\n ? String(schema.default)\n : parameterPlaceholder(param) || param.name\n }\n />\n </FieldWrapper>\n );\n}\n\nfunction TagInput({\n id,\n value,\n placeholder,\n onChange,\n}: {\n id: string;\n value: string;\n placeholder: string;\n onChange: (value: string) => void;\n}) {\n const tags = parseTags(value);\n\n function commit(raw: string, input: HTMLInputElement) {\n const next = raw\n .split(\",\")\n .map((part) => part.trim())\n .filter(Boolean);\n if (next.length === 0) return;\n onChange(serializeTags([...tags, ...next]));\n input.value = \"\";\n }\n\n function remove(index: number) {\n onChange(serializeTags(tags.filter((_, i) => i !== index)));\n }\n\n function handleKeyDown(event: KeyboardEvent<HTMLInputElement>) {\n const input = event.currentTarget;\n if (event.key === \"Enter\" || event.key === \",\") {\n event.preventDefault();\n commit(input.value, input);\n return;\n }\n if (event.key === \"Backspace\" && input.value === \"\" && tags.length > 0) {\n remove(tags.length - 1);\n }\n }\n\n return (\n <div className=\"flex min-h-9 flex-wrap items-center gap-1.5 rounded-md border border-input bg-transparent px-2 py-1 shadow-sm\">\n {tags.map((tag, index) => (\n <span\n key={`${tag}-${index}`}\n className=\"inline-flex h-6 max-w-full items-center gap-1 rounded-md bg-muted px-2 text-xs\"\n >\n <span className=\"truncate\">{tag}</span>\n <button\n type=\"button\"\n className=\"text-muted-foreground hover:text-foreground\"\n aria-label={`Remove ${tag}`}\n onClick={() => remove(index)}\n >\n <Icon icon={UiClose} />\n </button>\n </span>\n ))}\n <input\n id={id}\n className=\"min-w-32 flex-1 bg-transparent px-1 py-1 text-sm outline-none\"\n placeholder={tags.length === 0 ? placeholder : \"\"}\n onKeyDown={handleKeyDown}\n onBlur={(event) => commit(event.currentTarget.value, event.currentTarget)}\n />\n </div>\n );\n}\n\nfunction FieldWrapper({\n param,\n fieldId,\n inline,\n children,\n}: {\n param: OpenAPIParameter;\n fieldId: string;\n inline?: boolean;\n children: ReactNode;\n}) {\n const label = (\n <label htmlFor={fieldId} className=\"text-sm font-medium\">\n {param.name}\n {param.required && <span className=\"text-destructive\"> *</span>}\n </label>\n );\n\n if (inline) {\n return (\n <div className=\"grid grid-cols-[10rem_1fr] items-start gap-x-3 gap-y-0.5\">\n <div className=\"flex h-9 items-center\">{label}</div>\n <div className=\"min-w-0\">{children}</div>\n {param.description && (\n <p className=\"col-start-2 text-xs text-muted-foreground\">{param.description}</p>\n )}\n </div>\n );\n }\n\n return (\n <div className=\"space-y-1.5\">\n {label}\n {children}\n {param.description && <p className=\"text-xs text-muted-foreground\">{param.description}</p>}\n </div>\n );\n}\n\nexport function normalizeParameters(\n parameters: OpenAPIParameter[],\n path: string,\n): OpenAPIParameter[] {\n const pathParams = pathParamNames(path);\n const firstPathParam = pathParams[0];\n const seen = new Set(parameters.map((param) => param.name));\n const normalized = parameters.filter(\n (param) => !(param.name === \"args\" && firstPathParam != null && !seen.has(firstPathParam)),\n );\n for (const name of pathParams) {\n if (seen.has(name)) continue;\n normalized.unshift({\n name,\n in: \"path\",\n required: true,\n description: \"Path parameter\",\n schema: { type: \"string\" },\n });\n }\n return normalized;\n}\n\nexport function pathParamNames(path: string): string[] {\n return [...path.matchAll(/\\{([^}]+)\\}/g)]\n .map((match) => match[1])\n .filter((name): name is string => Boolean(name));\n}\n\nfunction buildInitialState(\n parameters: OpenAPIParameter[],\n path: string,\n overrides?: Record<string, string>,\n): FormState {\n const state: FormState = {};\n for (const p of parameters) {\n state[p.name] = initialParamValue(p, overrides?.[p.name]);\n }\n for (const name of pathParamNames(path)) {\n if (state[name] == null) {\n state[name] = overrides?.[name] ?? \"\";\n }\n }\n return state;\n}\n\nfunction initialParamValue(param: OpenAPIParameter, override: string | undefined): string {\n if (override != null) return sanitizeInitialValue(param, override);\n const value = param.schema?.default;\n if (value == null) return \"\";\n return sanitizeInitialValue(param, String(value));\n}\n\nfunction sanitizeInitialValue(param: OpenAPIParameter, value: string): string {\n const trimmed = value.trim();\n if (trimmed === \"[]\" || trimmed === \"null\") return \"\";\n if (isDateParam(param) && isZeroDate(trimmed)) return \"\";\n return value;\n}\n\nexport function submitValue(param: OpenAPIParameter, value: string | undefined): string | null {\n const trimmed = (value ?? \"\").trim();\n if (!trimmed || trimmed === \"[]\" || trimmed === \"null\") return null;\n if (isDateParam(param) && isZeroDate(trimmed)) return null;\n return trimmed;\n}\n\nfunction splitArgsValue(value: string): string[] {\n try {\n const parsed = JSON.parse(value);\n if (Array.isArray(parsed)) return parsed.map(String).filter(Boolean);\n } catch {\n // Use comma splitting below.\n }\n return value\n .split(\",\")\n .map((part) => part.trim())\n .filter(Boolean);\n}\n\nfunction isMultiValueParam(param: OpenAPIParameter): boolean {\n const text = `${param.name} ${param.description ?? \"\"}`.toLowerCase();\n return (\n param.schema?.type === \"array\" ||\n String(param.schema?.default ?? \"\") === \"[]\" ||\n text.includes(\"repeatable\")\n );\n}\n\nfunction parseTags(value: string): string[] {\n const trimmed = value.trim();\n if (!trimmed || trimmed === \"[]\" || trimmed === \"null\") return [];\n try {\n const parsed = JSON.parse(trimmed);\n if (Array.isArray(parsed)) return parsed.map(String).filter(Boolean);\n } catch {\n // Fall back to comma-delimited tags below.\n }\n return trimmed\n .split(\",\")\n .map((part) => part.trim())\n .filter(Boolean);\n}\n\nfunction serializeTags(tags: string[]): string {\n return tags.join(\",\");\n}\n\nfunction isDateParam(param: OpenAPIParameter): boolean {\n const format = param.schema?.format?.toLowerCase();\n const text = `${param.name} ${param.description ?? \"\"}`.toLowerCase();\n return format === \"date\" || format === \"date-time\" || text.includes(\"date\");\n}\n\nfunction isZeroDate(value: string): boolean {\n return value.startsWith(\"0001-01-01\") || value === \"0001-01-01\";\n}\n\nfunction dateInputValue(value: string, dateTime: boolean): string {\n if (!value || value.startsWith(\"0001-01-01\")) return \"\";\n if (!dateTime) return value.slice(0, 10);\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) return value.slice(0, 16);\n const offset = parsed.getTimezoneOffset() * 60_000;\n return new Date(parsed.getTime() - offset).toISOString().slice(0, 16);\n}\n\nfunction dateOutputValue(value: string, dateTime: boolean): string {\n if (!value) return \"\";\n if (!dateTime) return value;\n const parsed = new Date(value);\n if (Number.isNaN(parsed.getTime())) return value;\n return parsed.toISOString();\n}\n\nconst inputClassName =\n \"h-9 w-full min-w-0 rounded-md border border-input bg-background px-2 text-sm text-foreground outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:bg-muted/40 focus-visible:ring-2 focus-visible:ring-ring\";\n"],"names":[],"mappings":"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"}
@@ -187,7 +187,7 @@ function parametersToFormConfig(parameters, values, setValues, options = {}) {
187
187
  value: splitCommaValues(value),
188
188
  disabled,
189
189
  options: lookupOptionsToFieldOptions(lookupFilter),
190
- placeholder: param.description ?? "value-1, value-2",
190
+ placeholder: types.parameterPlaceholder(param) ?? "value-1, value-2",
191
191
  onChange: (next) => setValues((current) => ({ ...current, [param.name]: next.join(",") }))
192
192
  });
193
193
  continue;
@@ -199,7 +199,7 @@ function parametersToFormConfig(parameters, values, setValues, options = {}) {
199
199
  value,
200
200
  disabled,
201
201
  options: lookupOptionsToFieldOptions(lookupFilter),
202
- placeholder: param.description ?? label,
202
+ placeholder: types.parameterPlaceholder(param) ?? label,
203
203
  inputType: lookupFilter.type === "number" ? "number" : lookupFilter.type === "date" ? "date" : "text",
204
204
  onChange: (next) => onChange(next)
205
205
  });
@@ -211,7 +211,7 @@ function parametersToFormConfig(parameters, values, setValues, options = {}) {
211
211
  label,
212
212
  value,
213
213
  disabled,
214
- placeholder: param.description ?? label,
214
+ placeholder: types.parameterPlaceholder(param) ?? label,
215
215
  onChange: (next) => onChange(next)
216
216
  });
217
217
  }
@@ -219,13 +219,14 @@ function parametersToFormConfig(parameters, values, setValues, options = {}) {
219
219
  if (searchParam) {
220
220
  const searchDisabled = Object.prototype.hasOwnProperty.call(lockedValues, searchParam.name);
221
221
  const searchValue = searchDisabled ? lockedValues[searchParam.name] ?? "" : values[searchParam.name] ?? "";
222
+ const searchPlaceholder = types.parameterPlaceholder(searchParam);
222
223
  config.search = {
223
224
  value: searchValue,
224
225
  onChange: (next) => {
225
226
  if (searchDisabled) return;
226
227
  setValues((current) => ({ ...current, [searchParam.name]: next }));
227
228
  },
228
- ...searchParam.description ? { placeholder: searchParam.description } : {},
229
+ ...searchPlaceholder ? { placeholder: searchPlaceholder } : {},
229
230
  ariaLabel: ((_c = lookupFilters[searchParam.name]) == null ? void 0 : _c.label) ?? titleCase(searchParam.name)
230
231
  };
231
232
  }
@@ -1 +1 @@
1
- {"version":3,"file":"formMetadata.cjs","sources":["../../src/rpc/formMetadata.ts"],"sourcesContent":["import { useEffect, useState, type Dispatch, type SetStateAction } from \"react\";\nimport type {\n FilterBarFilter,\n FilterBarMultiFilterMode,\n FilterBarRangeProps,\n FilterBarSearchProps,\n} from \"../components/FilterBar\";\nimport type { DataTablePagination } from \"../data/DataTable\";\nimport type {\n ExecutionResponse,\n OpenAPIParameter,\n OperationLookupFilter,\n OperationLookupResponse,\n} from \"./types\";\nimport { isPositionalParam } from \"./types\";\n\nexport type ParameterValues = Record<string, string>;\nexport type ParameterValuesSetter = Dispatch<SetStateAction<ParameterValues>>;\n\n// ParameterPagination plumbs limit/offset query parameters into the\n// DataTable's pagination footer. The UI exposes both as the\n// {pageSize, pageIndex} tuple but here we keep raw string limit/offset\n// values so the executor sees exactly what the operation declared.\nexport type ParameterPagination = {\n limitParam: string; // parameter name on the operation, e.g. \"limit\"\n offsetParam: string;\n limitValue: string;\n offsetValue: string;\n setLimit: (next: string) => void;\n setOffset: (next: string) => void;\n};\n\nexport type ParameterFormConfig = {\n filters: FilterBarFilter[];\n search?: FilterBarSearchProps;\n timeRange?: FilterBarRangeProps;\n pagination?: ParameterPagination;\n};\nexport type ParameterFormOptions = {\n includeLocations?: OpenAPIParameter[\"in\"][];\n lookup?: OperationLookupResponse | undefined;\n lockedValues?: ParameterValues | undefined;\n hideLocked?: boolean;\n};\n\nexport function titleCase(value: string) {\n return value\n .split(/[-_]/)\n .filter(Boolean)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(\" \");\n}\n\nexport function defaultValueForParameter(param: OpenAPIParameter, method: string): string {\n if (method.toUpperCase() === \"GET\" && param.in === \"query\" && !param.required) {\n return \"\";\n }\n const fallback = param.in === \"path\" ? \"\" : undefined;\n const value = param.schema?.default ?? fallback;\n if (typeof value === \"boolean\") {\n return value ? \"true\" : \"false\";\n }\n if (Array.isArray(value) || (value != null && typeof value === \"object\")) {\n return \"\";\n }\n if (value == null) {\n return \"\";\n }\n return String(value);\n}\n\nexport function buildInitialParameterValues(\n parameters: OpenAPIParameter[],\n method: string,\n lockedValues: ParameterValues = {},\n initialValues: ParameterValues = {},\n): ParameterValues {\n const values = Object.fromEntries(\n parameters.map((param) => [param.name, defaultValueForParameter(param, method)]),\n );\n return { ...values, ...initialValues, ...lockedValues };\n}\n\nexport function dataTablePaginationFromForm(\n pagination: ParameterPagination | undefined,\n response: Pick<ExecutionResponse, \"pagination\"> | null | undefined,\n): DataTablePagination | undefined {\n if (!pagination) return undefined;\n\n const pageSize = positiveInt(pagination.limitValue) ?? response?.pagination?.limit ?? 25;\n const offset = nonNegativeInt(pagination.offsetValue) ?? response?.pagination?.offset ?? 0;\n const page = Math.floor(offset / pageSize);\n\n return {\n page,\n pageSize,\n ...(response?.pagination?.total !== undefined ? { total: response.pagination.total } : {}),\n onPageChange: (next: number) => {\n if (positiveInt(pagination.limitValue) == null) {\n pagination.setLimit(String(pageSize));\n }\n pagination.setOffset(String(Math.max(next, 0) * pageSize));\n },\n onPageSizeChange: (next: number) => {\n pagination.setLimit(String(next));\n pagination.setOffset(\"0\");\n },\n };\n}\n\nexport function pruneParameterValues(values: ParameterValues) {\n return Object.fromEntries(Object.entries(values).filter(([, value]) => value !== \"\"));\n}\n\nexport function packParameterValues(\n values: ParameterValues,\n parameters: OpenAPIParameter[],\n): ParameterValues {\n const positionalNames = new Set(\n parameters\n .filter((param) => param.in !== \"path\" && isPositionalParam(param))\n .map((p) => p.name),\n );\n const params: ParameterValues = {};\n const args: string[] = [];\n\n for (const [key, value] of Object.entries(values)) {\n if (!value) continue;\n if (positionalNames.has(key)) {\n args.push(value);\n } else {\n params[key] = value;\n }\n }\n\n if (args.length > 0) {\n params.args = args.join(\",\");\n }\n\n return params;\n}\n\nexport function parametersToFormConfig(\n parameters: OpenAPIParameter[],\n values: ParameterValues,\n setValues: ParameterValuesSetter,\n options: ParameterFormOptions = {},\n): ParameterFormConfig {\n const emitFilters: FilterBarFilter[] = [];\n const lookupFilters = options.lookup?.filters ?? {};\n const includeLocations = new Set(options.includeLocations ?? [\"path\", \"query\", \"header\"]);\n const lockedValues = options.lockedValues ?? {};\n const hideLocked = options.hideLocked ?? false;\n\n // Pull limit/offset out of the filter loop entirely — they drive pagination,\n // not filter pills. Roles come from server-side `paramRole` (see\n // clicky/rpc/openapi.go); the older \"named limit on a GET\" heuristic is\n // intentionally not duplicated here so the server stays the single source\n // of truth for parameter classification.\n const limitParam = parameters.find((p) => p[\"x-clicky\"]?.role === \"limit\");\n const offsetParam = parameters.find((p) => p[\"x-clicky\"]?.role === \"offset\");\n const paginationOmitNames = new Set<string>();\n if (limitParam) paginationOmitNames.add(limitParam.name);\n if (offsetParam) paginationOmitNames.add(offsetParam.name);\n\n // The search-role param drives the FilterBar's dedicated search input rather\n // than a filter chip; pull it out of the chip loop the same way pagination is.\n const searchParam = parameters.find(\n (p) => p[\"x-clicky\"]?.role === \"search\" && includeLocations.has(p.in),\n );\n const omitNames = new Set(paginationOmitNames);\n if (searchParam) omitNames.add(searchParam.name);\n\n // Time-range first looks for server-stamped roles, then falls back to the\n // existing lookup-driven \"from\"/\"to\" detection so older specs keep working.\n const roleRangeStart = parameters.find((p) => p[\"x-clicky\"]?.role === \"time-from\");\n const roleRangeEnd = parameters.find((p) => p[\"x-clicky\"]?.role === \"time-to\");\n const rangeStart =\n roleRangeStart ??\n parameters.find(\n (param) =>\n includeLocations.has(param.in) &&\n param.in === \"query\" &&\n lookupFilters[param.name]?.type === \"from\",\n );\n const rangeEnd =\n roleRangeEnd ??\n parameters.find(\n (param) =>\n includeLocations.has(param.in) &&\n param.in === \"query\" &&\n lookupFilters[param.name]?.type === \"to\",\n );\n const hasTimeRange = rangeStart != null && rangeEnd != null;\n\n for (const param of parameters) {\n if (!includeLocations.has(param.in)) continue;\n if (omitNames.has(param.name)) continue;\n if (hasTimeRange && (param.name === rangeStart?.name || param.name === rangeEnd?.name)) {\n continue;\n }\n\n const disabled = Object.prototype.hasOwnProperty.call(lockedValues, param.name);\n if (disabled && hideLocked) continue;\n const value = disabled ? (lockedValues[param.name] ?? \"\") : (values[param.name] ?? \"\");\n const label = lookupFilters[param.name]?.label ?? titleCase(param.name);\n const onChange = (next: string | boolean) => {\n if (disabled) return;\n const stringValue = typeof next === \"boolean\" ? (next ? \"true\" : \"false\") : next;\n setValues((current) => ({ ...current, [param.name]: stringValue }));\n };\n\n const schema = param.schema;\n const lookupFilter = lookupFilters[param.name];\n\n if (lookupFilter?.type === \"multi-filter\" && param.in === \"query\") {\n emitFilters.push({\n key: param.name,\n kind: \"multi\",\n label,\n value: parseMultiFilterValue(value),\n disabled,\n options: lookupOptionsToFieldOptions(lookupFilter),\n onChange: (next) =>\n setValues((current) => ({\n ...current,\n [param.name]: serializeMultiFilterValue(next),\n })),\n });\n continue;\n }\n\n if (schema?.enum) {\n emitFilters.push({\n key: param.name,\n kind: \"enum\",\n label,\n value,\n disabled,\n options: schema.enum.map((item) => ({\n value: String(item),\n label: String(item),\n })),\n onChange: (next) => onChange(next),\n });\n continue;\n }\n\n if (lookupFilter?.type === \"bool\" || schema?.type === \"boolean\") {\n emitFilters.push({\n key: param.name,\n kind: \"boolean\",\n label,\n value: value === \"true\",\n disabled,\n onChange: (next) => onChange(next),\n });\n continue;\n }\n\n if (lookupFilter != null && param.in === \"query\") {\n if (lookupFilter.multi) {\n emitFilters.push({\n key: param.name,\n kind: \"lookup-multi\",\n label,\n value: splitCommaValues(value),\n disabled,\n options: lookupOptionsToFieldOptions(lookupFilter),\n placeholder: param.description ?? \"value-1, value-2\",\n onChange: (next) =>\n setValues((current) => ({ ...current, [param.name]: next.join(\",\") })),\n });\n continue;\n }\n\n emitFilters.push({\n key: param.name,\n kind: \"lookup\",\n label,\n value,\n disabled,\n options: lookupOptionsToFieldOptions(lookupFilter),\n placeholder: param.description ?? label,\n inputType:\n lookupFilter.type === \"number\"\n ? \"number\"\n : lookupFilter.type === \"date\"\n ? \"date\"\n : \"text\",\n onChange: (next) => onChange(next),\n });\n continue;\n }\n\n emitFilters.push({\n key: param.name,\n kind: \"text\",\n label,\n value,\n disabled,\n placeholder: param.description ?? label,\n onChange: (next) => onChange(next),\n });\n }\n\n const config: ParameterFormConfig = { filters: emitFilters };\n if (searchParam) {\n const searchDisabled = Object.prototype.hasOwnProperty.call(lockedValues, searchParam.name);\n const searchValue = searchDisabled\n ? (lockedValues[searchParam.name] ?? \"\")\n : (values[searchParam.name] ?? \"\");\n config.search = {\n value: searchValue,\n onChange: (next) => {\n if (searchDisabled) return;\n setValues((current) => ({ ...current, [searchParam.name]: next }));\n },\n ...(searchParam.description ? { placeholder: searchParam.description } : {}),\n ariaLabel: lookupFilters[searchParam.name]?.label ?? titleCase(searchParam.name),\n };\n }\n if (limitParam && offsetParam) {\n config.pagination = {\n limitParam: limitParam.name,\n offsetParam: offsetParam.name,\n limitValue: values[limitParam.name] ?? \"\",\n offsetValue: values[offsetParam.name] ?? \"\",\n setLimit: (next) => setValues((current) => ({ ...current, [limitParam.name]: next })),\n setOffset: (next) => setValues((current) => ({ ...current, [offsetParam.name]: next })),\n };\n }\n if (hasTimeRange && rangeStart != null && rangeEnd != null) {\n const rangeStartMeta = lookupFilters[rangeStart.name];\n const rangeEndMeta = lookupFilters[rangeEnd.name];\n const rangeMeta = rangeStartMeta ?? rangeEndMeta;\n config.timeRange = {\n from: values[rangeStart.name] ?? \"\",\n to: values[rangeEnd.name] ?? \"\",\n onApply: (from, to) =>\n setValues((current) => ({\n ...current,\n [rangeStart.name]: from,\n [rangeEnd.name]: to,\n })),\n ...(rangeMeta?.presets ? { presets: rangeMeta.presets } : {}),\n ...(rangeMeta?.timeEnabled !== undefined ? { timeEnabled: rangeMeta.timeEnabled } : {}),\n ...(rangeMeta?.timeZone ? { timeZone: rangeMeta.timeZone } : {}),\n ...(rangeMeta?.timeZones ? { timeZones: rangeMeta.timeZones } : {}),\n ...(rangeStart.description ? { fromPlaceholder: rangeStart.description } : {}),\n ...(rangeEnd.description ? { toPlaceholder: rangeEnd.description } : {}),\n };\n }\n\n return config;\n}\n\nexport function useDebouncedRecord<T>(value: T, delayMs: number) {\n const [debounced, setDebounced] = useState(value);\n\n useEffect(() => {\n const timeoutId = window.setTimeout(() => setDebounced(value), delayMs);\n return () => window.clearTimeout(timeoutId);\n }, [delayMs, value]);\n\n return debounced;\n}\n\nexport function parseMultiFilterValue(value: string): Record<string, FilterBarMultiFilterMode> {\n const parsed: Record<string, FilterBarMultiFilterMode> = {};\n for (const item of splitCommaValues(value)) {\n if (item.startsWith(\"!\") && item.length > 1) {\n parsed[item.slice(1)] = \"exclude\";\n } else {\n parsed[item] = \"include\";\n }\n }\n return parsed;\n}\n\nexport function serializeMultiFilterValue(value: Record<string, FilterBarMultiFilterMode>): string {\n return Object.entries(value)\n .flatMap(([key, mode]) => {\n if (mode === \"include\") return [key];\n if (mode === \"exclude\") return [`!${key}`];\n return [];\n })\n .join(\",\");\n}\n\nfunction splitCommaValues(value: string) {\n return value\n .split(\",\")\n .map((item) => item.trim())\n .filter(Boolean);\n}\n\nfunction positiveInt(value: string | undefined): number | undefined {\n const parsed = parseInt(value ?? \"\", 10);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;\n}\n\nfunction nonNegativeInt(value: string | undefined): number | undefined {\n const parsed = parseInt(value ?? \"\", 10);\n return Number.isFinite(parsed) && parsed >= 0 ? parsed : undefined;\n}\n\nfunction lookupOptionsToFieldOptions(filter: OperationLookupFilter) {\n const merged = new Map<string, { label?: string; title?: string }>();\n\n for (const [value, node] of Object.entries(filter.options ?? {})) {\n merged.set(value, {\n label: clickyNodeToPlainText(node) || value,\n title: clickyNodeToPlainText(node) || value,\n });\n }\n\n for (const [value, node] of Object.entries(filter.selected ?? {})) {\n if (!merged.has(value)) {\n merged.set(value, {\n label: clickyNodeToPlainText(node) || value,\n title: clickyNodeToPlainText(node) || value,\n });\n }\n }\n\n return Array.from(merged.entries()).map(([value, meta]) => ({\n value,\n label: meta.label ?? value,\n title: meta.title ?? value,\n }));\n}\n\ntype PlainTextClickyNode = {\n plain?: string;\n text?: string;\n children?: PlainTextClickyNode[];\n tooltip?: { plain?: string; text?: string };\n};\n\nfunction clickyNodeToPlainText(node: PlainTextClickyNode | null | undefined): string {\n if (node == null) return \"\";\n if (node.plain) return node.plain;\n if (node.text) return node.text;\n return (node.children ?? []).map((child) => clickyNodeToPlainText(child)).join(\"\");\n}\n"],"names":["isPositionalParam","_a","useState","useEffect"],"mappings":"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"}
1
+ {"version":3,"file":"formMetadata.cjs","sources":["../../src/rpc/formMetadata.ts"],"sourcesContent":["import { useEffect, useState, type Dispatch, type SetStateAction } from \"react\";\nimport type {\n FilterBarFilter,\n FilterBarMultiFilterMode,\n FilterBarRangeProps,\n FilterBarSearchProps,\n} from \"../components/FilterBar\";\nimport type { DataTablePagination } from \"../data/DataTable\";\nimport type {\n ExecutionResponse,\n OpenAPIParameter,\n OperationLookupFilter,\n OperationLookupResponse,\n} from \"./types\";\nimport { isPositionalParam, parameterPlaceholder } from \"./types\";\n\nexport type ParameterValues = Record<string, string>;\nexport type ParameterValuesSetter = Dispatch<SetStateAction<ParameterValues>>;\n\n// ParameterPagination plumbs limit/offset query parameters into the\n// DataTable's pagination footer. The UI exposes both as the\n// {pageSize, pageIndex} tuple but here we keep raw string limit/offset\n// values so the executor sees exactly what the operation declared.\nexport type ParameterPagination = {\n limitParam: string; // parameter name on the operation, e.g. \"limit\"\n offsetParam: string;\n limitValue: string;\n offsetValue: string;\n setLimit: (next: string) => void;\n setOffset: (next: string) => void;\n};\n\nexport type ParameterFormConfig = {\n filters: FilterBarFilter[];\n search?: FilterBarSearchProps;\n timeRange?: FilterBarRangeProps;\n pagination?: ParameterPagination;\n};\nexport type ParameterFormOptions = {\n includeLocations?: OpenAPIParameter[\"in\"][];\n lookup?: OperationLookupResponse | undefined;\n lockedValues?: ParameterValues | undefined;\n hideLocked?: boolean;\n};\n\nexport function titleCase(value: string) {\n return value\n .split(/[-_]/)\n .filter(Boolean)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(\" \");\n}\n\nexport function defaultValueForParameter(param: OpenAPIParameter, method: string): string {\n if (method.toUpperCase() === \"GET\" && param.in === \"query\" && !param.required) {\n return \"\";\n }\n const fallback = param.in === \"path\" ? \"\" : undefined;\n const value = param.schema?.default ?? fallback;\n if (typeof value === \"boolean\") {\n return value ? \"true\" : \"false\";\n }\n if (Array.isArray(value) || (value != null && typeof value === \"object\")) {\n return \"\";\n }\n if (value == null) {\n return \"\";\n }\n return String(value);\n}\n\nexport function buildInitialParameterValues(\n parameters: OpenAPIParameter[],\n method: string,\n lockedValues: ParameterValues = {},\n initialValues: ParameterValues = {},\n): ParameterValues {\n const values = Object.fromEntries(\n parameters.map((param) => [param.name, defaultValueForParameter(param, method)]),\n );\n return { ...values, ...initialValues, ...lockedValues };\n}\n\nexport function dataTablePaginationFromForm(\n pagination: ParameterPagination | undefined,\n response: Pick<ExecutionResponse, \"pagination\"> | null | undefined,\n): DataTablePagination | undefined {\n if (!pagination) return undefined;\n\n const pageSize = positiveInt(pagination.limitValue) ?? response?.pagination?.limit ?? 25;\n const offset = nonNegativeInt(pagination.offsetValue) ?? response?.pagination?.offset ?? 0;\n const page = Math.floor(offset / pageSize);\n\n return {\n page,\n pageSize,\n ...(response?.pagination?.total !== undefined ? { total: response.pagination.total } : {}),\n onPageChange: (next: number) => {\n if (positiveInt(pagination.limitValue) == null) {\n pagination.setLimit(String(pageSize));\n }\n pagination.setOffset(String(Math.max(next, 0) * pageSize));\n },\n onPageSizeChange: (next: number) => {\n pagination.setLimit(String(next));\n pagination.setOffset(\"0\");\n },\n };\n}\n\nexport function pruneParameterValues(values: ParameterValues) {\n return Object.fromEntries(Object.entries(values).filter(([, value]) => value !== \"\"));\n}\n\nexport function packParameterValues(\n values: ParameterValues,\n parameters: OpenAPIParameter[],\n): ParameterValues {\n const positionalNames = new Set(\n parameters\n .filter((param) => param.in !== \"path\" && isPositionalParam(param))\n .map((p) => p.name),\n );\n const params: ParameterValues = {};\n const args: string[] = [];\n\n for (const [key, value] of Object.entries(values)) {\n if (!value) continue;\n if (positionalNames.has(key)) {\n args.push(value);\n } else {\n params[key] = value;\n }\n }\n\n if (args.length > 0) {\n params.args = args.join(\",\");\n }\n\n return params;\n}\n\nexport function parametersToFormConfig(\n parameters: OpenAPIParameter[],\n values: ParameterValues,\n setValues: ParameterValuesSetter,\n options: ParameterFormOptions = {},\n): ParameterFormConfig {\n const emitFilters: FilterBarFilter[] = [];\n const lookupFilters = options.lookup?.filters ?? {};\n const includeLocations = new Set(options.includeLocations ?? [\"path\", \"query\", \"header\"]);\n const lockedValues = options.lockedValues ?? {};\n const hideLocked = options.hideLocked ?? false;\n\n // Pull limit/offset out of the filter loop entirely — they drive pagination,\n // not filter pills. Roles come from server-side `paramRole` (see\n // clicky/rpc/openapi.go); the older \"named limit on a GET\" heuristic is\n // intentionally not duplicated here so the server stays the single source\n // of truth for parameter classification.\n const limitParam = parameters.find((p) => p[\"x-clicky\"]?.role === \"limit\");\n const offsetParam = parameters.find((p) => p[\"x-clicky\"]?.role === \"offset\");\n const paginationOmitNames = new Set<string>();\n if (limitParam) paginationOmitNames.add(limitParam.name);\n if (offsetParam) paginationOmitNames.add(offsetParam.name);\n\n // The search-role param drives the FilterBar's dedicated search input rather\n // than a filter chip; pull it out of the chip loop the same way pagination is.\n const searchParam = parameters.find(\n (p) => p[\"x-clicky\"]?.role === \"search\" && includeLocations.has(p.in),\n );\n const omitNames = new Set(paginationOmitNames);\n if (searchParam) omitNames.add(searchParam.name);\n\n // Time-range first looks for server-stamped roles, then falls back to the\n // existing lookup-driven \"from\"/\"to\" detection so older specs keep working.\n const roleRangeStart = parameters.find((p) => p[\"x-clicky\"]?.role === \"time-from\");\n const roleRangeEnd = parameters.find((p) => p[\"x-clicky\"]?.role === \"time-to\");\n const rangeStart =\n roleRangeStart ??\n parameters.find(\n (param) =>\n includeLocations.has(param.in) &&\n param.in === \"query\" &&\n lookupFilters[param.name]?.type === \"from\",\n );\n const rangeEnd =\n roleRangeEnd ??\n parameters.find(\n (param) =>\n includeLocations.has(param.in) &&\n param.in === \"query\" &&\n lookupFilters[param.name]?.type === \"to\",\n );\n const hasTimeRange = rangeStart != null && rangeEnd != null;\n\n for (const param of parameters) {\n if (!includeLocations.has(param.in)) continue;\n if (omitNames.has(param.name)) continue;\n if (hasTimeRange && (param.name === rangeStart?.name || param.name === rangeEnd?.name)) {\n continue;\n }\n\n const disabled = Object.prototype.hasOwnProperty.call(lockedValues, param.name);\n if (disabled && hideLocked) continue;\n const value = disabled ? (lockedValues[param.name] ?? \"\") : (values[param.name] ?? \"\");\n const label = lookupFilters[param.name]?.label ?? titleCase(param.name);\n const onChange = (next: string | boolean) => {\n if (disabled) return;\n const stringValue = typeof next === \"boolean\" ? (next ? \"true\" : \"false\") : next;\n setValues((current) => ({ ...current, [param.name]: stringValue }));\n };\n\n const schema = param.schema;\n const lookupFilter = lookupFilters[param.name];\n\n if (lookupFilter?.type === \"multi-filter\" && param.in === \"query\") {\n emitFilters.push({\n key: param.name,\n kind: \"multi\",\n label,\n value: parseMultiFilterValue(value),\n disabled,\n options: lookupOptionsToFieldOptions(lookupFilter),\n onChange: (next) =>\n setValues((current) => ({\n ...current,\n [param.name]: serializeMultiFilterValue(next),\n })),\n });\n continue;\n }\n\n if (schema?.enum) {\n emitFilters.push({\n key: param.name,\n kind: \"enum\",\n label,\n value,\n disabled,\n options: schema.enum.map((item) => ({\n value: String(item),\n label: String(item),\n })),\n onChange: (next) => onChange(next),\n });\n continue;\n }\n\n if (lookupFilter?.type === \"bool\" || schema?.type === \"boolean\") {\n emitFilters.push({\n key: param.name,\n kind: \"boolean\",\n label,\n value: value === \"true\",\n disabled,\n onChange: (next) => onChange(next),\n });\n continue;\n }\n\n if (lookupFilter != null && param.in === \"query\") {\n if (lookupFilter.multi) {\n emitFilters.push({\n key: param.name,\n kind: \"lookup-multi\",\n label,\n value: splitCommaValues(value),\n disabled,\n options: lookupOptionsToFieldOptions(lookupFilter),\n placeholder: parameterPlaceholder(param) ?? \"value-1, value-2\",\n onChange: (next) =>\n setValues((current) => ({ ...current, [param.name]: next.join(\",\") })),\n });\n continue;\n }\n\n emitFilters.push({\n key: param.name,\n kind: \"lookup\",\n label,\n value,\n disabled,\n options: lookupOptionsToFieldOptions(lookupFilter),\n placeholder: parameterPlaceholder(param) ?? label,\n inputType:\n lookupFilter.type === \"number\"\n ? \"number\"\n : lookupFilter.type === \"date\"\n ? \"date\"\n : \"text\",\n onChange: (next) => onChange(next),\n });\n continue;\n }\n\n emitFilters.push({\n key: param.name,\n kind: \"text\",\n label,\n value,\n disabled,\n placeholder: parameterPlaceholder(param) ?? label,\n onChange: (next) => onChange(next),\n });\n }\n\n const config: ParameterFormConfig = { filters: emitFilters };\n if (searchParam) {\n const searchDisabled = Object.prototype.hasOwnProperty.call(lockedValues, searchParam.name);\n const searchValue = searchDisabled\n ? (lockedValues[searchParam.name] ?? \"\")\n : (values[searchParam.name] ?? \"\");\n const searchPlaceholder = parameterPlaceholder(searchParam);\n config.search = {\n value: searchValue,\n onChange: (next) => {\n if (searchDisabled) return;\n setValues((current) => ({ ...current, [searchParam.name]: next }));\n },\n ...(searchPlaceholder ? { placeholder: searchPlaceholder } : {}),\n ariaLabel: lookupFilters[searchParam.name]?.label ?? titleCase(searchParam.name),\n };\n }\n if (limitParam && offsetParam) {\n config.pagination = {\n limitParam: limitParam.name,\n offsetParam: offsetParam.name,\n limitValue: values[limitParam.name] ?? \"\",\n offsetValue: values[offsetParam.name] ?? \"\",\n setLimit: (next) => setValues((current) => ({ ...current, [limitParam.name]: next })),\n setOffset: (next) => setValues((current) => ({ ...current, [offsetParam.name]: next })),\n };\n }\n if (hasTimeRange && rangeStart != null && rangeEnd != null) {\n const rangeStartMeta = lookupFilters[rangeStart.name];\n const rangeEndMeta = lookupFilters[rangeEnd.name];\n const rangeMeta = rangeStartMeta ?? rangeEndMeta;\n config.timeRange = {\n from: values[rangeStart.name] ?? \"\",\n to: values[rangeEnd.name] ?? \"\",\n onApply: (from, to) =>\n setValues((current) => ({\n ...current,\n [rangeStart.name]: from,\n [rangeEnd.name]: to,\n })),\n ...(rangeMeta?.presets ? { presets: rangeMeta.presets } : {}),\n ...(rangeMeta?.timeEnabled !== undefined ? { timeEnabled: rangeMeta.timeEnabled } : {}),\n ...(rangeMeta?.timeZone ? { timeZone: rangeMeta.timeZone } : {}),\n ...(rangeMeta?.timeZones ? { timeZones: rangeMeta.timeZones } : {}),\n ...(rangeStart.description ? { fromPlaceholder: rangeStart.description } : {}),\n ...(rangeEnd.description ? { toPlaceholder: rangeEnd.description } : {}),\n };\n }\n\n return config;\n}\n\nexport function useDebouncedRecord<T>(value: T, delayMs: number) {\n const [debounced, setDebounced] = useState(value);\n\n useEffect(() => {\n const timeoutId = window.setTimeout(() => setDebounced(value), delayMs);\n return () => window.clearTimeout(timeoutId);\n }, [delayMs, value]);\n\n return debounced;\n}\n\nexport function parseMultiFilterValue(value: string): Record<string, FilterBarMultiFilterMode> {\n const parsed: Record<string, FilterBarMultiFilterMode> = {};\n for (const item of splitCommaValues(value)) {\n if (item.startsWith(\"!\") && item.length > 1) {\n parsed[item.slice(1)] = \"exclude\";\n } else {\n parsed[item] = \"include\";\n }\n }\n return parsed;\n}\n\nexport function serializeMultiFilterValue(value: Record<string, FilterBarMultiFilterMode>): string {\n return Object.entries(value)\n .flatMap(([key, mode]) => {\n if (mode === \"include\") return [key];\n if (mode === \"exclude\") return [`!${key}`];\n return [];\n })\n .join(\",\");\n}\n\nfunction splitCommaValues(value: string) {\n return value\n .split(\",\")\n .map((item) => item.trim())\n .filter(Boolean);\n}\n\nfunction positiveInt(value: string | undefined): number | undefined {\n const parsed = parseInt(value ?? \"\", 10);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;\n}\n\nfunction nonNegativeInt(value: string | undefined): number | undefined {\n const parsed = parseInt(value ?? \"\", 10);\n return Number.isFinite(parsed) && parsed >= 0 ? parsed : undefined;\n}\n\nfunction lookupOptionsToFieldOptions(filter: OperationLookupFilter) {\n const merged = new Map<string, { label?: string; title?: string }>();\n\n for (const [value, node] of Object.entries(filter.options ?? {})) {\n merged.set(value, {\n label: clickyNodeToPlainText(node) || value,\n title: clickyNodeToPlainText(node) || value,\n });\n }\n\n for (const [value, node] of Object.entries(filter.selected ?? {})) {\n if (!merged.has(value)) {\n merged.set(value, {\n label: clickyNodeToPlainText(node) || value,\n title: clickyNodeToPlainText(node) || value,\n });\n }\n }\n\n return Array.from(merged.entries()).map(([value, meta]) => ({\n value,\n label: meta.label ?? value,\n title: meta.title ?? value,\n }));\n}\n\ntype PlainTextClickyNode = {\n plain?: string;\n text?: string;\n children?: PlainTextClickyNode[];\n tooltip?: { plain?: string; text?: string };\n};\n\nfunction clickyNodeToPlainText(node: PlainTextClickyNode | null | undefined): string {\n if (node == null) return \"\";\n if (node.plain) return node.plain;\n if (node.text) return node.text;\n return (node.children ?? []).map((child) => clickyNodeToPlainText(child)).join(\"\");\n}\n"],"names":["isPositionalParam","_a","parameterPlaceholder","useState","useEffect"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"formMetadata.d.ts","sourceRoot":"","sources":["../../src/rpc/formMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,QAAQ,EAAE,KAAK,cAAc,EAAE,MAAM,OAAO,CAAC;AAChF,OAAO,KAAK,EACV,eAAe,EACf,wBAAwB,EACxB,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,KAAK,EACV,iBAAiB,EACjB,gBAAgB,EAEhB,uBAAuB,EACxB,MAAM,SAAS,CAAC;AAGjB,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACrD,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC;AAM9E,MAAM,MAAM,mBAAmB,GAAG;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC,UAAU,CAAC,EAAE,mBAAmB,CAAC;CAClC,CAAC;AACF,MAAM,MAAM,oBAAoB,GAAG;IACjC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;IAC5C,MAAM,CAAC,EAAE,uBAAuB,GAAG,SAAS,CAAC;IAC7C,YAAY,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC;IAC3C,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,UAMtC;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAgBxF;AAED,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,gBAAgB,EAAE,EAC9B,MAAM,EAAE,MAAM,EACd,YAAY,GAAE,eAAoB,EAClC,aAAa,GAAE,eAAoB,GAClC,eAAe,CAKjB;AAED,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,mBAAmB,GAAG,SAAS,EAC3C,QAAQ,EAAE,IAAI,CAAC,iBAAiB,EAAE,YAAY,CAAC,GAAG,IAAI,GAAG,SAAS,GACjE,mBAAmB,GAAG,SAAS,CAsBjC;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,eAAe;;EAE3D;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,eAAe,EACvB,UAAU,EAAE,gBAAgB,EAAE,GAC7B,eAAe,CAuBjB;AAED,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,gBAAgB,EAAE,EAC9B,MAAM,EAAE,eAAe,EACvB,SAAS,EAAE,qBAAqB,EAChC,OAAO,GAAE,oBAAyB,GACjC,mBAAmB,CAgNrB;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,KAS9D;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAU7F;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,GAAG,MAAM,CAQjG"}
1
+ {"version":3,"file":"formMetadata.d.ts","sourceRoot":"","sources":["../../src/rpc/formMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,QAAQ,EAAE,KAAK,cAAc,EAAE,MAAM,OAAO,CAAC;AAChF,OAAO,KAAK,EACV,eAAe,EACf,wBAAwB,EACxB,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,KAAK,EACV,iBAAiB,EACjB,gBAAgB,EAEhB,uBAAuB,EACxB,MAAM,SAAS,CAAC;AAGjB,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACrD,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC;AAM9E,MAAM,MAAM,mBAAmB,GAAG;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC,UAAU,CAAC,EAAE,mBAAmB,CAAC;CAClC,CAAC;AACF,MAAM,MAAM,oBAAoB,GAAG;IACjC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;IAC5C,MAAM,CAAC,EAAE,uBAAuB,GAAG,SAAS,CAAC;IAC7C,YAAY,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC;IAC3C,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,UAMtC;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAgBxF;AAED,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,gBAAgB,EAAE,EAC9B,MAAM,EAAE,MAAM,EACd,YAAY,GAAE,eAAoB,EAClC,aAAa,GAAE,eAAoB,GAClC,eAAe,CAKjB;AAED,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,mBAAmB,GAAG,SAAS,EAC3C,QAAQ,EAAE,IAAI,CAAC,iBAAiB,EAAE,YAAY,CAAC,GAAG,IAAI,GAAG,SAAS,GACjE,mBAAmB,GAAG,SAAS,CAsBjC;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,eAAe;;EAE3D;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,eAAe,EACvB,UAAU,EAAE,gBAAgB,EAAE,GAC7B,eAAe,CAuBjB;AAED,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,gBAAgB,EAAE,EAC9B,MAAM,EAAE,eAAe,EACvB,SAAS,EAAE,qBAAqB,EAChC,OAAO,GAAE,oBAAyB,GACjC,mBAAmB,CAiNrB;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,KAS9D;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAU7F;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,GAAG,MAAM,CAQjG"}
@@ -1,5 +1,5 @@
1
1
  import { useState, useEffect } from "react";
2
- import { isPositionalParam } from "./types.js";
2
+ import { isPositionalParam, parameterPlaceholder } from "./types.js";
3
3
  function titleCase(value) {
4
4
  return value.split(/[-_]/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
5
5
  }
@@ -185,7 +185,7 @@ function parametersToFormConfig(parameters, values, setValues, options = {}) {
185
185
  value: splitCommaValues(value),
186
186
  disabled,
187
187
  options: lookupOptionsToFieldOptions(lookupFilter),
188
- placeholder: param.description ?? "value-1, value-2",
188
+ placeholder: parameterPlaceholder(param) ?? "value-1, value-2",
189
189
  onChange: (next) => setValues((current) => ({ ...current, [param.name]: next.join(",") }))
190
190
  });
191
191
  continue;
@@ -197,7 +197,7 @@ function parametersToFormConfig(parameters, values, setValues, options = {}) {
197
197
  value,
198
198
  disabled,
199
199
  options: lookupOptionsToFieldOptions(lookupFilter),
200
- placeholder: param.description ?? label,
200
+ placeholder: parameterPlaceholder(param) ?? label,
201
201
  inputType: lookupFilter.type === "number" ? "number" : lookupFilter.type === "date" ? "date" : "text",
202
202
  onChange: (next) => onChange(next)
203
203
  });
@@ -209,7 +209,7 @@ function parametersToFormConfig(parameters, values, setValues, options = {}) {
209
209
  label,
210
210
  value,
211
211
  disabled,
212
- placeholder: param.description ?? label,
212
+ placeholder: parameterPlaceholder(param) ?? label,
213
213
  onChange: (next) => onChange(next)
214
214
  });
215
215
  }
@@ -217,13 +217,14 @@ function parametersToFormConfig(parameters, values, setValues, options = {}) {
217
217
  if (searchParam) {
218
218
  const searchDisabled = Object.prototype.hasOwnProperty.call(lockedValues, searchParam.name);
219
219
  const searchValue = searchDisabled ? lockedValues[searchParam.name] ?? "" : values[searchParam.name] ?? "";
220
+ const searchPlaceholder = parameterPlaceholder(searchParam);
220
221
  config.search = {
221
222
  value: searchValue,
222
223
  onChange: (next) => {
223
224
  if (searchDisabled) return;
224
225
  setValues((current) => ({ ...current, [searchParam.name]: next }));
225
226
  },
226
- ...searchParam.description ? { placeholder: searchParam.description } : {},
227
+ ...searchPlaceholder ? { placeholder: searchPlaceholder } : {},
227
228
  ariaLabel: ((_c = lookupFilters[searchParam.name]) == null ? void 0 : _c.label) ?? titleCase(searchParam.name)
228
229
  };
229
230
  }
@@ -1 +1 @@
1
- {"version":3,"file":"formMetadata.js","sources":["../../src/rpc/formMetadata.ts"],"sourcesContent":["import { useEffect, useState, type Dispatch, type SetStateAction } from \"react\";\nimport type {\n FilterBarFilter,\n FilterBarMultiFilterMode,\n FilterBarRangeProps,\n FilterBarSearchProps,\n} from \"../components/FilterBar\";\nimport type { DataTablePagination } from \"../data/DataTable\";\nimport type {\n ExecutionResponse,\n OpenAPIParameter,\n OperationLookupFilter,\n OperationLookupResponse,\n} from \"./types\";\nimport { isPositionalParam } from \"./types\";\n\nexport type ParameterValues = Record<string, string>;\nexport type ParameterValuesSetter = Dispatch<SetStateAction<ParameterValues>>;\n\n// ParameterPagination plumbs limit/offset query parameters into the\n// DataTable's pagination footer. The UI exposes both as the\n// {pageSize, pageIndex} tuple but here we keep raw string limit/offset\n// values so the executor sees exactly what the operation declared.\nexport type ParameterPagination = {\n limitParam: string; // parameter name on the operation, e.g. \"limit\"\n offsetParam: string;\n limitValue: string;\n offsetValue: string;\n setLimit: (next: string) => void;\n setOffset: (next: string) => void;\n};\n\nexport type ParameterFormConfig = {\n filters: FilterBarFilter[];\n search?: FilterBarSearchProps;\n timeRange?: FilterBarRangeProps;\n pagination?: ParameterPagination;\n};\nexport type ParameterFormOptions = {\n includeLocations?: OpenAPIParameter[\"in\"][];\n lookup?: OperationLookupResponse | undefined;\n lockedValues?: ParameterValues | undefined;\n hideLocked?: boolean;\n};\n\nexport function titleCase(value: string) {\n return value\n .split(/[-_]/)\n .filter(Boolean)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(\" \");\n}\n\nexport function defaultValueForParameter(param: OpenAPIParameter, method: string): string {\n if (method.toUpperCase() === \"GET\" && param.in === \"query\" && !param.required) {\n return \"\";\n }\n const fallback = param.in === \"path\" ? \"\" : undefined;\n const value = param.schema?.default ?? fallback;\n if (typeof value === \"boolean\") {\n return value ? \"true\" : \"false\";\n }\n if (Array.isArray(value) || (value != null && typeof value === \"object\")) {\n return \"\";\n }\n if (value == null) {\n return \"\";\n }\n return String(value);\n}\n\nexport function buildInitialParameterValues(\n parameters: OpenAPIParameter[],\n method: string,\n lockedValues: ParameterValues = {},\n initialValues: ParameterValues = {},\n): ParameterValues {\n const values = Object.fromEntries(\n parameters.map((param) => [param.name, defaultValueForParameter(param, method)]),\n );\n return { ...values, ...initialValues, ...lockedValues };\n}\n\nexport function dataTablePaginationFromForm(\n pagination: ParameterPagination | undefined,\n response: Pick<ExecutionResponse, \"pagination\"> | null | undefined,\n): DataTablePagination | undefined {\n if (!pagination) return undefined;\n\n const pageSize = positiveInt(pagination.limitValue) ?? response?.pagination?.limit ?? 25;\n const offset = nonNegativeInt(pagination.offsetValue) ?? response?.pagination?.offset ?? 0;\n const page = Math.floor(offset / pageSize);\n\n return {\n page,\n pageSize,\n ...(response?.pagination?.total !== undefined ? { total: response.pagination.total } : {}),\n onPageChange: (next: number) => {\n if (positiveInt(pagination.limitValue) == null) {\n pagination.setLimit(String(pageSize));\n }\n pagination.setOffset(String(Math.max(next, 0) * pageSize));\n },\n onPageSizeChange: (next: number) => {\n pagination.setLimit(String(next));\n pagination.setOffset(\"0\");\n },\n };\n}\n\nexport function pruneParameterValues(values: ParameterValues) {\n return Object.fromEntries(Object.entries(values).filter(([, value]) => value !== \"\"));\n}\n\nexport function packParameterValues(\n values: ParameterValues,\n parameters: OpenAPIParameter[],\n): ParameterValues {\n const positionalNames = new Set(\n parameters\n .filter((param) => param.in !== \"path\" && isPositionalParam(param))\n .map((p) => p.name),\n );\n const params: ParameterValues = {};\n const args: string[] = [];\n\n for (const [key, value] of Object.entries(values)) {\n if (!value) continue;\n if (positionalNames.has(key)) {\n args.push(value);\n } else {\n params[key] = value;\n }\n }\n\n if (args.length > 0) {\n params.args = args.join(\",\");\n }\n\n return params;\n}\n\nexport function parametersToFormConfig(\n parameters: OpenAPIParameter[],\n values: ParameterValues,\n setValues: ParameterValuesSetter,\n options: ParameterFormOptions = {},\n): ParameterFormConfig {\n const emitFilters: FilterBarFilter[] = [];\n const lookupFilters = options.lookup?.filters ?? {};\n const includeLocations = new Set(options.includeLocations ?? [\"path\", \"query\", \"header\"]);\n const lockedValues = options.lockedValues ?? {};\n const hideLocked = options.hideLocked ?? false;\n\n // Pull limit/offset out of the filter loop entirely — they drive pagination,\n // not filter pills. Roles come from server-side `paramRole` (see\n // clicky/rpc/openapi.go); the older \"named limit on a GET\" heuristic is\n // intentionally not duplicated here so the server stays the single source\n // of truth for parameter classification.\n const limitParam = parameters.find((p) => p[\"x-clicky\"]?.role === \"limit\");\n const offsetParam = parameters.find((p) => p[\"x-clicky\"]?.role === \"offset\");\n const paginationOmitNames = new Set<string>();\n if (limitParam) paginationOmitNames.add(limitParam.name);\n if (offsetParam) paginationOmitNames.add(offsetParam.name);\n\n // The search-role param drives the FilterBar's dedicated search input rather\n // than a filter chip; pull it out of the chip loop the same way pagination is.\n const searchParam = parameters.find(\n (p) => p[\"x-clicky\"]?.role === \"search\" && includeLocations.has(p.in),\n );\n const omitNames = new Set(paginationOmitNames);\n if (searchParam) omitNames.add(searchParam.name);\n\n // Time-range first looks for server-stamped roles, then falls back to the\n // existing lookup-driven \"from\"/\"to\" detection so older specs keep working.\n const roleRangeStart = parameters.find((p) => p[\"x-clicky\"]?.role === \"time-from\");\n const roleRangeEnd = parameters.find((p) => p[\"x-clicky\"]?.role === \"time-to\");\n const rangeStart =\n roleRangeStart ??\n parameters.find(\n (param) =>\n includeLocations.has(param.in) &&\n param.in === \"query\" &&\n lookupFilters[param.name]?.type === \"from\",\n );\n const rangeEnd =\n roleRangeEnd ??\n parameters.find(\n (param) =>\n includeLocations.has(param.in) &&\n param.in === \"query\" &&\n lookupFilters[param.name]?.type === \"to\",\n );\n const hasTimeRange = rangeStart != null && rangeEnd != null;\n\n for (const param of parameters) {\n if (!includeLocations.has(param.in)) continue;\n if (omitNames.has(param.name)) continue;\n if (hasTimeRange && (param.name === rangeStart?.name || param.name === rangeEnd?.name)) {\n continue;\n }\n\n const disabled = Object.prototype.hasOwnProperty.call(lockedValues, param.name);\n if (disabled && hideLocked) continue;\n const value = disabled ? (lockedValues[param.name] ?? \"\") : (values[param.name] ?? \"\");\n const label = lookupFilters[param.name]?.label ?? titleCase(param.name);\n const onChange = (next: string | boolean) => {\n if (disabled) return;\n const stringValue = typeof next === \"boolean\" ? (next ? \"true\" : \"false\") : next;\n setValues((current) => ({ ...current, [param.name]: stringValue }));\n };\n\n const schema = param.schema;\n const lookupFilter = lookupFilters[param.name];\n\n if (lookupFilter?.type === \"multi-filter\" && param.in === \"query\") {\n emitFilters.push({\n key: param.name,\n kind: \"multi\",\n label,\n value: parseMultiFilterValue(value),\n disabled,\n options: lookupOptionsToFieldOptions(lookupFilter),\n onChange: (next) =>\n setValues((current) => ({\n ...current,\n [param.name]: serializeMultiFilterValue(next),\n })),\n });\n continue;\n }\n\n if (schema?.enum) {\n emitFilters.push({\n key: param.name,\n kind: \"enum\",\n label,\n value,\n disabled,\n options: schema.enum.map((item) => ({\n value: String(item),\n label: String(item),\n })),\n onChange: (next) => onChange(next),\n });\n continue;\n }\n\n if (lookupFilter?.type === \"bool\" || schema?.type === \"boolean\") {\n emitFilters.push({\n key: param.name,\n kind: \"boolean\",\n label,\n value: value === \"true\",\n disabled,\n onChange: (next) => onChange(next),\n });\n continue;\n }\n\n if (lookupFilter != null && param.in === \"query\") {\n if (lookupFilter.multi) {\n emitFilters.push({\n key: param.name,\n kind: \"lookup-multi\",\n label,\n value: splitCommaValues(value),\n disabled,\n options: lookupOptionsToFieldOptions(lookupFilter),\n placeholder: param.description ?? \"value-1, value-2\",\n onChange: (next) =>\n setValues((current) => ({ ...current, [param.name]: next.join(\",\") })),\n });\n continue;\n }\n\n emitFilters.push({\n key: param.name,\n kind: \"lookup\",\n label,\n value,\n disabled,\n options: lookupOptionsToFieldOptions(lookupFilter),\n placeholder: param.description ?? label,\n inputType:\n lookupFilter.type === \"number\"\n ? \"number\"\n : lookupFilter.type === \"date\"\n ? \"date\"\n : \"text\",\n onChange: (next) => onChange(next),\n });\n continue;\n }\n\n emitFilters.push({\n key: param.name,\n kind: \"text\",\n label,\n value,\n disabled,\n placeholder: param.description ?? label,\n onChange: (next) => onChange(next),\n });\n }\n\n const config: ParameterFormConfig = { filters: emitFilters };\n if (searchParam) {\n const searchDisabled = Object.prototype.hasOwnProperty.call(lockedValues, searchParam.name);\n const searchValue = searchDisabled\n ? (lockedValues[searchParam.name] ?? \"\")\n : (values[searchParam.name] ?? \"\");\n config.search = {\n value: searchValue,\n onChange: (next) => {\n if (searchDisabled) return;\n setValues((current) => ({ ...current, [searchParam.name]: next }));\n },\n ...(searchParam.description ? { placeholder: searchParam.description } : {}),\n ariaLabel: lookupFilters[searchParam.name]?.label ?? titleCase(searchParam.name),\n };\n }\n if (limitParam && offsetParam) {\n config.pagination = {\n limitParam: limitParam.name,\n offsetParam: offsetParam.name,\n limitValue: values[limitParam.name] ?? \"\",\n offsetValue: values[offsetParam.name] ?? \"\",\n setLimit: (next) => setValues((current) => ({ ...current, [limitParam.name]: next })),\n setOffset: (next) => setValues((current) => ({ ...current, [offsetParam.name]: next })),\n };\n }\n if (hasTimeRange && rangeStart != null && rangeEnd != null) {\n const rangeStartMeta = lookupFilters[rangeStart.name];\n const rangeEndMeta = lookupFilters[rangeEnd.name];\n const rangeMeta = rangeStartMeta ?? rangeEndMeta;\n config.timeRange = {\n from: values[rangeStart.name] ?? \"\",\n to: values[rangeEnd.name] ?? \"\",\n onApply: (from, to) =>\n setValues((current) => ({\n ...current,\n [rangeStart.name]: from,\n [rangeEnd.name]: to,\n })),\n ...(rangeMeta?.presets ? { presets: rangeMeta.presets } : {}),\n ...(rangeMeta?.timeEnabled !== undefined ? { timeEnabled: rangeMeta.timeEnabled } : {}),\n ...(rangeMeta?.timeZone ? { timeZone: rangeMeta.timeZone } : {}),\n ...(rangeMeta?.timeZones ? { timeZones: rangeMeta.timeZones } : {}),\n ...(rangeStart.description ? { fromPlaceholder: rangeStart.description } : {}),\n ...(rangeEnd.description ? { toPlaceholder: rangeEnd.description } : {}),\n };\n }\n\n return config;\n}\n\nexport function useDebouncedRecord<T>(value: T, delayMs: number) {\n const [debounced, setDebounced] = useState(value);\n\n useEffect(() => {\n const timeoutId = window.setTimeout(() => setDebounced(value), delayMs);\n return () => window.clearTimeout(timeoutId);\n }, [delayMs, value]);\n\n return debounced;\n}\n\nexport function parseMultiFilterValue(value: string): Record<string, FilterBarMultiFilterMode> {\n const parsed: Record<string, FilterBarMultiFilterMode> = {};\n for (const item of splitCommaValues(value)) {\n if (item.startsWith(\"!\") && item.length > 1) {\n parsed[item.slice(1)] = \"exclude\";\n } else {\n parsed[item] = \"include\";\n }\n }\n return parsed;\n}\n\nexport function serializeMultiFilterValue(value: Record<string, FilterBarMultiFilterMode>): string {\n return Object.entries(value)\n .flatMap(([key, mode]) => {\n if (mode === \"include\") return [key];\n if (mode === \"exclude\") return [`!${key}`];\n return [];\n })\n .join(\",\");\n}\n\nfunction splitCommaValues(value: string) {\n return value\n .split(\",\")\n .map((item) => item.trim())\n .filter(Boolean);\n}\n\nfunction positiveInt(value: string | undefined): number | undefined {\n const parsed = parseInt(value ?? \"\", 10);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;\n}\n\nfunction nonNegativeInt(value: string | undefined): number | undefined {\n const parsed = parseInt(value ?? \"\", 10);\n return Number.isFinite(parsed) && parsed >= 0 ? parsed : undefined;\n}\n\nfunction lookupOptionsToFieldOptions(filter: OperationLookupFilter) {\n const merged = new Map<string, { label?: string; title?: string }>();\n\n for (const [value, node] of Object.entries(filter.options ?? {})) {\n merged.set(value, {\n label: clickyNodeToPlainText(node) || value,\n title: clickyNodeToPlainText(node) || value,\n });\n }\n\n for (const [value, node] of Object.entries(filter.selected ?? {})) {\n if (!merged.has(value)) {\n merged.set(value, {\n label: clickyNodeToPlainText(node) || value,\n title: clickyNodeToPlainText(node) || value,\n });\n }\n }\n\n return Array.from(merged.entries()).map(([value, meta]) => ({\n value,\n label: meta.label ?? value,\n title: meta.title ?? value,\n }));\n}\n\ntype PlainTextClickyNode = {\n plain?: string;\n text?: string;\n children?: PlainTextClickyNode[];\n tooltip?: { plain?: string; text?: string };\n};\n\nfunction clickyNodeToPlainText(node: PlainTextClickyNode | null | undefined): string {\n if (node == null) return \"\";\n if (node.plain) return node.plain;\n if (node.text) return node.text;\n return (node.children ?? []).map((child) => clickyNodeToPlainText(child)).join(\"\");\n}\n"],"names":["_a"],"mappings":"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"}
1
+ {"version":3,"file":"formMetadata.js","sources":["../../src/rpc/formMetadata.ts"],"sourcesContent":["import { useEffect, useState, type Dispatch, type SetStateAction } from \"react\";\nimport type {\n FilterBarFilter,\n FilterBarMultiFilterMode,\n FilterBarRangeProps,\n FilterBarSearchProps,\n} from \"../components/FilterBar\";\nimport type { DataTablePagination } from \"../data/DataTable\";\nimport type {\n ExecutionResponse,\n OpenAPIParameter,\n OperationLookupFilter,\n OperationLookupResponse,\n} from \"./types\";\nimport { isPositionalParam, parameterPlaceholder } from \"./types\";\n\nexport type ParameterValues = Record<string, string>;\nexport type ParameterValuesSetter = Dispatch<SetStateAction<ParameterValues>>;\n\n// ParameterPagination plumbs limit/offset query parameters into the\n// DataTable's pagination footer. The UI exposes both as the\n// {pageSize, pageIndex} tuple but here we keep raw string limit/offset\n// values so the executor sees exactly what the operation declared.\nexport type ParameterPagination = {\n limitParam: string; // parameter name on the operation, e.g. \"limit\"\n offsetParam: string;\n limitValue: string;\n offsetValue: string;\n setLimit: (next: string) => void;\n setOffset: (next: string) => void;\n};\n\nexport type ParameterFormConfig = {\n filters: FilterBarFilter[];\n search?: FilterBarSearchProps;\n timeRange?: FilterBarRangeProps;\n pagination?: ParameterPagination;\n};\nexport type ParameterFormOptions = {\n includeLocations?: OpenAPIParameter[\"in\"][];\n lookup?: OperationLookupResponse | undefined;\n lockedValues?: ParameterValues | undefined;\n hideLocked?: boolean;\n};\n\nexport function titleCase(value: string) {\n return value\n .split(/[-_]/)\n .filter(Boolean)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(\" \");\n}\n\nexport function defaultValueForParameter(param: OpenAPIParameter, method: string): string {\n if (method.toUpperCase() === \"GET\" && param.in === \"query\" && !param.required) {\n return \"\";\n }\n const fallback = param.in === \"path\" ? \"\" : undefined;\n const value = param.schema?.default ?? fallback;\n if (typeof value === \"boolean\") {\n return value ? \"true\" : \"false\";\n }\n if (Array.isArray(value) || (value != null && typeof value === \"object\")) {\n return \"\";\n }\n if (value == null) {\n return \"\";\n }\n return String(value);\n}\n\nexport function buildInitialParameterValues(\n parameters: OpenAPIParameter[],\n method: string,\n lockedValues: ParameterValues = {},\n initialValues: ParameterValues = {},\n): ParameterValues {\n const values = Object.fromEntries(\n parameters.map((param) => [param.name, defaultValueForParameter(param, method)]),\n );\n return { ...values, ...initialValues, ...lockedValues };\n}\n\nexport function dataTablePaginationFromForm(\n pagination: ParameterPagination | undefined,\n response: Pick<ExecutionResponse, \"pagination\"> | null | undefined,\n): DataTablePagination | undefined {\n if (!pagination) return undefined;\n\n const pageSize = positiveInt(pagination.limitValue) ?? response?.pagination?.limit ?? 25;\n const offset = nonNegativeInt(pagination.offsetValue) ?? response?.pagination?.offset ?? 0;\n const page = Math.floor(offset / pageSize);\n\n return {\n page,\n pageSize,\n ...(response?.pagination?.total !== undefined ? { total: response.pagination.total } : {}),\n onPageChange: (next: number) => {\n if (positiveInt(pagination.limitValue) == null) {\n pagination.setLimit(String(pageSize));\n }\n pagination.setOffset(String(Math.max(next, 0) * pageSize));\n },\n onPageSizeChange: (next: number) => {\n pagination.setLimit(String(next));\n pagination.setOffset(\"0\");\n },\n };\n}\n\nexport function pruneParameterValues(values: ParameterValues) {\n return Object.fromEntries(Object.entries(values).filter(([, value]) => value !== \"\"));\n}\n\nexport function packParameterValues(\n values: ParameterValues,\n parameters: OpenAPIParameter[],\n): ParameterValues {\n const positionalNames = new Set(\n parameters\n .filter((param) => param.in !== \"path\" && isPositionalParam(param))\n .map((p) => p.name),\n );\n const params: ParameterValues = {};\n const args: string[] = [];\n\n for (const [key, value] of Object.entries(values)) {\n if (!value) continue;\n if (positionalNames.has(key)) {\n args.push(value);\n } else {\n params[key] = value;\n }\n }\n\n if (args.length > 0) {\n params.args = args.join(\",\");\n }\n\n return params;\n}\n\nexport function parametersToFormConfig(\n parameters: OpenAPIParameter[],\n values: ParameterValues,\n setValues: ParameterValuesSetter,\n options: ParameterFormOptions = {},\n): ParameterFormConfig {\n const emitFilters: FilterBarFilter[] = [];\n const lookupFilters = options.lookup?.filters ?? {};\n const includeLocations = new Set(options.includeLocations ?? [\"path\", \"query\", \"header\"]);\n const lockedValues = options.lockedValues ?? {};\n const hideLocked = options.hideLocked ?? false;\n\n // Pull limit/offset out of the filter loop entirely — they drive pagination,\n // not filter pills. Roles come from server-side `paramRole` (see\n // clicky/rpc/openapi.go); the older \"named limit on a GET\" heuristic is\n // intentionally not duplicated here so the server stays the single source\n // of truth for parameter classification.\n const limitParam = parameters.find((p) => p[\"x-clicky\"]?.role === \"limit\");\n const offsetParam = parameters.find((p) => p[\"x-clicky\"]?.role === \"offset\");\n const paginationOmitNames = new Set<string>();\n if (limitParam) paginationOmitNames.add(limitParam.name);\n if (offsetParam) paginationOmitNames.add(offsetParam.name);\n\n // The search-role param drives the FilterBar's dedicated search input rather\n // than a filter chip; pull it out of the chip loop the same way pagination is.\n const searchParam = parameters.find(\n (p) => p[\"x-clicky\"]?.role === \"search\" && includeLocations.has(p.in),\n );\n const omitNames = new Set(paginationOmitNames);\n if (searchParam) omitNames.add(searchParam.name);\n\n // Time-range first looks for server-stamped roles, then falls back to the\n // existing lookup-driven \"from\"/\"to\" detection so older specs keep working.\n const roleRangeStart = parameters.find((p) => p[\"x-clicky\"]?.role === \"time-from\");\n const roleRangeEnd = parameters.find((p) => p[\"x-clicky\"]?.role === \"time-to\");\n const rangeStart =\n roleRangeStart ??\n parameters.find(\n (param) =>\n includeLocations.has(param.in) &&\n param.in === \"query\" &&\n lookupFilters[param.name]?.type === \"from\",\n );\n const rangeEnd =\n roleRangeEnd ??\n parameters.find(\n (param) =>\n includeLocations.has(param.in) &&\n param.in === \"query\" &&\n lookupFilters[param.name]?.type === \"to\",\n );\n const hasTimeRange = rangeStart != null && rangeEnd != null;\n\n for (const param of parameters) {\n if (!includeLocations.has(param.in)) continue;\n if (omitNames.has(param.name)) continue;\n if (hasTimeRange && (param.name === rangeStart?.name || param.name === rangeEnd?.name)) {\n continue;\n }\n\n const disabled = Object.prototype.hasOwnProperty.call(lockedValues, param.name);\n if (disabled && hideLocked) continue;\n const value = disabled ? (lockedValues[param.name] ?? \"\") : (values[param.name] ?? \"\");\n const label = lookupFilters[param.name]?.label ?? titleCase(param.name);\n const onChange = (next: string | boolean) => {\n if (disabled) return;\n const stringValue = typeof next === \"boolean\" ? (next ? \"true\" : \"false\") : next;\n setValues((current) => ({ ...current, [param.name]: stringValue }));\n };\n\n const schema = param.schema;\n const lookupFilter = lookupFilters[param.name];\n\n if (lookupFilter?.type === \"multi-filter\" && param.in === \"query\") {\n emitFilters.push({\n key: param.name,\n kind: \"multi\",\n label,\n value: parseMultiFilterValue(value),\n disabled,\n options: lookupOptionsToFieldOptions(lookupFilter),\n onChange: (next) =>\n setValues((current) => ({\n ...current,\n [param.name]: serializeMultiFilterValue(next),\n })),\n });\n continue;\n }\n\n if (schema?.enum) {\n emitFilters.push({\n key: param.name,\n kind: \"enum\",\n label,\n value,\n disabled,\n options: schema.enum.map((item) => ({\n value: String(item),\n label: String(item),\n })),\n onChange: (next) => onChange(next),\n });\n continue;\n }\n\n if (lookupFilter?.type === \"bool\" || schema?.type === \"boolean\") {\n emitFilters.push({\n key: param.name,\n kind: \"boolean\",\n label,\n value: value === \"true\",\n disabled,\n onChange: (next) => onChange(next),\n });\n continue;\n }\n\n if (lookupFilter != null && param.in === \"query\") {\n if (lookupFilter.multi) {\n emitFilters.push({\n key: param.name,\n kind: \"lookup-multi\",\n label,\n value: splitCommaValues(value),\n disabled,\n options: lookupOptionsToFieldOptions(lookupFilter),\n placeholder: parameterPlaceholder(param) ?? \"value-1, value-2\",\n onChange: (next) =>\n setValues((current) => ({ ...current, [param.name]: next.join(\",\") })),\n });\n continue;\n }\n\n emitFilters.push({\n key: param.name,\n kind: \"lookup\",\n label,\n value,\n disabled,\n options: lookupOptionsToFieldOptions(lookupFilter),\n placeholder: parameterPlaceholder(param) ?? label,\n inputType:\n lookupFilter.type === \"number\"\n ? \"number\"\n : lookupFilter.type === \"date\"\n ? \"date\"\n : \"text\",\n onChange: (next) => onChange(next),\n });\n continue;\n }\n\n emitFilters.push({\n key: param.name,\n kind: \"text\",\n label,\n value,\n disabled,\n placeholder: parameterPlaceholder(param) ?? label,\n onChange: (next) => onChange(next),\n });\n }\n\n const config: ParameterFormConfig = { filters: emitFilters };\n if (searchParam) {\n const searchDisabled = Object.prototype.hasOwnProperty.call(lockedValues, searchParam.name);\n const searchValue = searchDisabled\n ? (lockedValues[searchParam.name] ?? \"\")\n : (values[searchParam.name] ?? \"\");\n const searchPlaceholder = parameterPlaceholder(searchParam);\n config.search = {\n value: searchValue,\n onChange: (next) => {\n if (searchDisabled) return;\n setValues((current) => ({ ...current, [searchParam.name]: next }));\n },\n ...(searchPlaceholder ? { placeholder: searchPlaceholder } : {}),\n ariaLabel: lookupFilters[searchParam.name]?.label ?? titleCase(searchParam.name),\n };\n }\n if (limitParam && offsetParam) {\n config.pagination = {\n limitParam: limitParam.name,\n offsetParam: offsetParam.name,\n limitValue: values[limitParam.name] ?? \"\",\n offsetValue: values[offsetParam.name] ?? \"\",\n setLimit: (next) => setValues((current) => ({ ...current, [limitParam.name]: next })),\n setOffset: (next) => setValues((current) => ({ ...current, [offsetParam.name]: next })),\n };\n }\n if (hasTimeRange && rangeStart != null && rangeEnd != null) {\n const rangeStartMeta = lookupFilters[rangeStart.name];\n const rangeEndMeta = lookupFilters[rangeEnd.name];\n const rangeMeta = rangeStartMeta ?? rangeEndMeta;\n config.timeRange = {\n from: values[rangeStart.name] ?? \"\",\n to: values[rangeEnd.name] ?? \"\",\n onApply: (from, to) =>\n setValues((current) => ({\n ...current,\n [rangeStart.name]: from,\n [rangeEnd.name]: to,\n })),\n ...(rangeMeta?.presets ? { presets: rangeMeta.presets } : {}),\n ...(rangeMeta?.timeEnabled !== undefined ? { timeEnabled: rangeMeta.timeEnabled } : {}),\n ...(rangeMeta?.timeZone ? { timeZone: rangeMeta.timeZone } : {}),\n ...(rangeMeta?.timeZones ? { timeZones: rangeMeta.timeZones } : {}),\n ...(rangeStart.description ? { fromPlaceholder: rangeStart.description } : {}),\n ...(rangeEnd.description ? { toPlaceholder: rangeEnd.description } : {}),\n };\n }\n\n return config;\n}\n\nexport function useDebouncedRecord<T>(value: T, delayMs: number) {\n const [debounced, setDebounced] = useState(value);\n\n useEffect(() => {\n const timeoutId = window.setTimeout(() => setDebounced(value), delayMs);\n return () => window.clearTimeout(timeoutId);\n }, [delayMs, value]);\n\n return debounced;\n}\n\nexport function parseMultiFilterValue(value: string): Record<string, FilterBarMultiFilterMode> {\n const parsed: Record<string, FilterBarMultiFilterMode> = {};\n for (const item of splitCommaValues(value)) {\n if (item.startsWith(\"!\") && item.length > 1) {\n parsed[item.slice(1)] = \"exclude\";\n } else {\n parsed[item] = \"include\";\n }\n }\n return parsed;\n}\n\nexport function serializeMultiFilterValue(value: Record<string, FilterBarMultiFilterMode>): string {\n return Object.entries(value)\n .flatMap(([key, mode]) => {\n if (mode === \"include\") return [key];\n if (mode === \"exclude\") return [`!${key}`];\n return [];\n })\n .join(\",\");\n}\n\nfunction splitCommaValues(value: string) {\n return value\n .split(\",\")\n .map((item) => item.trim())\n .filter(Boolean);\n}\n\nfunction positiveInt(value: string | undefined): number | undefined {\n const parsed = parseInt(value ?? \"\", 10);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;\n}\n\nfunction nonNegativeInt(value: string | undefined): number | undefined {\n const parsed = parseInt(value ?? \"\", 10);\n return Number.isFinite(parsed) && parsed >= 0 ? parsed : undefined;\n}\n\nfunction lookupOptionsToFieldOptions(filter: OperationLookupFilter) {\n const merged = new Map<string, { label?: string; title?: string }>();\n\n for (const [value, node] of Object.entries(filter.options ?? {})) {\n merged.set(value, {\n label: clickyNodeToPlainText(node) || value,\n title: clickyNodeToPlainText(node) || value,\n });\n }\n\n for (const [value, node] of Object.entries(filter.selected ?? {})) {\n if (!merged.has(value)) {\n merged.set(value, {\n label: clickyNodeToPlainText(node) || value,\n title: clickyNodeToPlainText(node) || value,\n });\n }\n }\n\n return Array.from(merged.entries()).map(([value, meta]) => ({\n value,\n label: meta.label ?? value,\n title: meta.title ?? value,\n }));\n}\n\ntype PlainTextClickyNode = {\n plain?: string;\n text?: string;\n children?: PlainTextClickyNode[];\n tooltip?: { plain?: string; text?: string };\n};\n\nfunction clickyNodeToPlainText(node: PlainTextClickyNode | null | undefined): string {\n if (node == null) return \"\";\n if (node.plain) return node.plain;\n if (node.text) return node.text;\n return (node.children ?? []).map((child) => clickyNodeToPlainText(child)).join(\"\");\n}\n"],"names":["_a"],"mappings":"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"}
@@ -1,8 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ function parameterPlaceholder(param) {
4
+ return param["x-clicky-placeholder"] ?? param.placeholder;
5
+ }
3
6
  function isPositionalParam(p) {
4
7
  var _a;
5
8
  return p.name === "args" || ((_a = p.description) == null ? void 0 : _a.toLowerCase().includes("positional argument")) === true;
6
9
  }
7
10
  exports.isPositionalParam = isPositionalParam;
11
+ exports.parameterPlaceholder = parameterPlaceholder;
8
12
  //# sourceMappingURL=types.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.cjs","sources":["../../src/rpc/types.ts"],"sourcesContent":["import type { ClickyNode } from \"../data/Clicky\";\nimport type { TimeRangePresetGroup } from \"../components/TimeRange\";\n\nexport interface ExecutionRequest {\n args?: string[];\n flags?: Record<string, string>;\n}\n\nexport interface ExecutionPagination {\n total?: number;\n limit?: number;\n offset?: number;\n}\n\nexport interface ExecutionResponse {\n success: boolean;\n message?: string;\n output?: string;\n stdout?: string;\n stderr?: string;\n exit_code: number;\n error?: string;\n cli?: string;\n input?: ExecutionRequest;\n contentType?: string;\n requestUrl?: string;\n responseHeaders?: Record<string, string>;\n pagination?: ExecutionPagination;\n blob?: Blob;\n parsed?: unknown;\n}\n\nexport interface OpenAPISchema {\n type?: string;\n format?: string;\n default?: unknown;\n enum?: unknown[];\n description?: string;\n properties?: Record<string, OpenAPISchema>;\n}\n\n// ClickyParameterRole tells the UI which widget owns a parameter:\n// \"search\" — render as the FilterBar's dedicated search input\n// \"filter\" — render as a FilterBar chip on the DataTable\n// \"limit\" — feed into DataTable pagination's pageSize\n// \"offset\" — feed into DataTable pagination's page (or skip)\n// \"time-from\" — left edge of a time-range picker\n// \"time-to\" — right edge of a time-range picker\n// Set server-side by clicky's converter (see paramRole in clicky/rpc/openapi.go).\nexport type ClickyParameterRole =\n | \"search\"\n | \"filter\"\n | \"limit\"\n | \"offset\"\n | \"time-from\"\n | \"time-to\";\n\nexport interface ClickyParameterMeta {\n role?: ClickyParameterRole;\n}\n\nexport interface OpenAPIParameter {\n name: string;\n in: \"query\" | \"path\" | \"header\";\n description?: string;\n required?: boolean;\n schema?: OpenAPISchema;\n \"x-clicky\"?: ClickyParameterMeta;\n}\n\nexport interface OpenAPIOperation {\n tags?: string[];\n summary?: string;\n description?: string;\n operationId?: string;\n parameters?: OpenAPIParameter[];\n requestBody?: {\n content?: Record<string, { schema?: OpenAPISchema }>;\n };\n responses: Record<string, unknown>;\n \"x-clicky\"?: ClickyOperationMeta;\n}\n\nexport interface OpenAPISpec {\n openapi: string;\n info: { title: string; description?: string; version: string };\n paths: Record<string, Record<string, OpenAPIOperation>>;\n tags?: Array<{ name: string; description?: string }>;\n \"x-clicky\"?: ClickySpecMeta;\n}\n\nexport interface ResolvedOperation {\n path: string;\n method: string;\n operation: OpenAPIOperation;\n}\n\nexport interface DomainDefinition {\n key: string;\n title: string;\n description: string;\n emptyTitle?: string;\n emptyDescription?: string;\n}\n\nexport interface ClickySpecMeta {\n surfaces?: ClickySurface[];\n}\n\nexport interface ClickySurface {\n key: string;\n entity: string;\n title: string;\n parent?: string;\n admin?: boolean;\n description?: string;\n}\n\nexport interface ClickyOperationMeta {\n command?: string;\n surface?: string;\n verb: \"list\" | \"get\" | \"create\" | \"update\" | \"delete\" | \"action\";\n scope: \"collection\" | \"entity\";\n actionName?: string;\n idParam?: string;\n supportsLookup?: boolean;\n supportsFilterMode?: boolean;\n}\n\nexport type OperationLookupFilterType = \"bool\" | \"number\" | \"date\" | \"from\" | \"to\" | \"multi-filter\";\n\nexport interface OperationLookupFilter {\n label?: string;\n options?: Record<string, ClickyNode>;\n selected?: Record<string, ClickyNode>;\n multi?: boolean;\n type?: OperationLookupFilterType;\n /** True when `options` is only the head of a larger set (server-side capped). */\n truncated?: boolean;\n /** True distinct count behind a truncated option set; drives \"… and N more\". */\n total?: number;\n presets?: Array<{ label: string; from: string; to: string } | TimeRangePresetGroup>;\n timeEnabled?: boolean;\n timeZone?: string;\n timeZones?: string[];\n}\n\nexport interface OperationLookupResponse {\n filters: Record<string, OperationLookupFilter>;\n}\n\nexport function isPositionalParam(p: OpenAPIParameter): boolean {\n return p.name === \"args\" || p.description?.toLowerCase().includes(\"positional argument\") === true;\n}\n"],"names":[],"mappings":";;AAuJO,SAAS,kBAAkB,GAA8B;;AAC9D,SAAO,EAAE,SAAS,YAAU,OAAE,gBAAF,mBAAe,cAAc,SAAS,4BAA2B;AAC/F;;"}
1
+ {"version":3,"file":"types.cjs","sources":["../../src/rpc/types.ts"],"sourcesContent":["import type { ClickyNode } from \"../data/Clicky\";\nimport type { TimeRangePresetGroup } from \"../components/TimeRange\";\n\nexport interface ExecutionRequest {\n args?: string[];\n flags?: Record<string, string>;\n}\n\nexport interface ExecutionPagination {\n total?: number;\n limit?: number;\n offset?: number;\n}\n\nexport interface ExecutionResponse {\n success: boolean;\n message?: string;\n output?: string;\n stdout?: string;\n stderr?: string;\n exit_code: number;\n error?: string;\n cli?: string;\n input?: ExecutionRequest;\n contentType?: string;\n requestUrl?: string;\n responseHeaders?: Record<string, string>;\n pagination?: ExecutionPagination;\n blob?: Blob;\n parsed?: unknown;\n}\n\nexport interface OpenAPISchema {\n type?: string;\n format?: string;\n default?: unknown;\n enum?: unknown[];\n description?: string;\n properties?: Record<string, OpenAPISchema>;\n}\n\n// ClickyParameterRole tells the UI which widget owns a parameter:\n// \"search\" — render as the FilterBar's dedicated search input\n// \"filter\" — render as a FilterBar chip on the DataTable\n// \"limit\" — feed into DataTable pagination's pageSize\n// \"offset\" — feed into DataTable pagination's page (or skip)\n// \"time-from\" — left edge of a time-range picker\n// \"time-to\" — right edge of a time-range picker\n// Set server-side by clicky's converter (see paramRole in clicky/rpc/openapi.go).\nexport type ClickyParameterRole =\n | \"search\"\n | \"filter\"\n | \"limit\"\n | \"offset\"\n | \"time-from\"\n | \"time-to\";\n\nexport interface ClickyParameterMeta {\n role?: ClickyParameterRole;\n}\n\nexport interface OpenAPIParameter {\n name: string;\n in: \"query\" | \"path\" | \"header\";\n description?: string;\n required?: boolean;\n schema?: OpenAPISchema;\n /** Hint text shown inside the empty input. Distinct from `description`,\n * which is help text and must NOT be used as a placeholder. */\n placeholder?: string;\n \"x-clicky\"?: ClickyParameterMeta;\n /** Vendor-extension placeholder, set server-side by clicky's converter.\n * Takes precedence over `placeholder` when both are present. */\n \"x-clicky-placeholder\"?: string;\n}\n\n/** Resolves the input placeholder for a parameter, drawing ONLY from explicit\n * placeholder fields — never from `description` (help text). Returns undefined\n * when no placeholder is declared so callers can apply their own fallback. */\nexport function parameterPlaceholder(param: OpenAPIParameter): string | undefined {\n return param[\"x-clicky-placeholder\"] ?? param.placeholder;\n}\n\nexport interface OpenAPIOperation {\n tags?: string[];\n summary?: string;\n description?: string;\n operationId?: string;\n parameters?: OpenAPIParameter[];\n requestBody?: {\n content?: Record<string, { schema?: OpenAPISchema }>;\n };\n responses: Record<string, unknown>;\n \"x-clicky\"?: ClickyOperationMeta;\n}\n\nexport interface OpenAPISpec {\n openapi: string;\n info: { title: string; description?: string; version: string };\n paths: Record<string, Record<string, OpenAPIOperation>>;\n tags?: Array<{ name: string; description?: string }>;\n \"x-clicky\"?: ClickySpecMeta;\n}\n\nexport interface ResolvedOperation {\n path: string;\n method: string;\n operation: OpenAPIOperation;\n}\n\nexport interface DomainDefinition {\n key: string;\n title: string;\n description: string;\n emptyTitle?: string;\n emptyDescription?: string;\n}\n\nexport interface ClickySpecMeta {\n surfaces?: ClickySurface[];\n}\n\nexport interface ClickySurface {\n key: string;\n entity: string;\n title: string;\n parent?: string;\n admin?: boolean;\n description?: string;\n}\n\nexport interface ClickyOperationMeta {\n command?: string;\n surface?: string;\n verb: \"list\" | \"get\" | \"create\" | \"update\" | \"delete\" | \"action\";\n scope: \"collection\" | \"entity\";\n actionName?: string;\n idParam?: string;\n supportsLookup?: boolean;\n supportsFilterMode?: boolean;\n}\n\nexport type OperationLookupFilterType = \"bool\" | \"number\" | \"date\" | \"from\" | \"to\" | \"multi-filter\";\n\nexport interface OperationLookupFilter {\n label?: string;\n options?: Record<string, ClickyNode>;\n selected?: Record<string, ClickyNode>;\n multi?: boolean;\n type?: OperationLookupFilterType;\n /** True when `options` is only the head of a larger set (server-side capped). */\n truncated?: boolean;\n /** True distinct count behind a truncated option set; drives \"… and N more\". */\n total?: number;\n presets?: Array<{ label: string; from: string; to: string } | TimeRangePresetGroup>;\n timeEnabled?: boolean;\n timeZone?: string;\n timeZones?: string[];\n}\n\nexport interface OperationLookupResponse {\n filters: Record<string, OperationLookupFilter>;\n}\n\nexport function isPositionalParam(p: OpenAPIParameter): boolean {\n return p.name === \"args\" || p.description?.toLowerCase().includes(\"positional argument\") === true;\n}\n"],"names":[],"mappings":";;AA+EO,SAAS,qBAAqB,OAA6C;AAChF,SAAO,MAAM,sBAAsB,KAAK,MAAM;AAChD;AAmFO,SAAS,kBAAkB,GAA8B;;AAC9D,SAAO,EAAE,SAAS,YAAU,OAAE,gBAAF,mBAAe,cAAc,SAAS,4BAA2B;AAC/F;;;"}
@@ -44,8 +44,18 @@ export interface OpenAPIParameter {
44
44
  description?: string;
45
45
  required?: boolean;
46
46
  schema?: OpenAPISchema;
47
+ /** Hint text shown inside the empty input. Distinct from `description`,
48
+ * which is help text and must NOT be used as a placeholder. */
49
+ placeholder?: string;
47
50
  "x-clicky"?: ClickyParameterMeta;
51
+ /** Vendor-extension placeholder, set server-side by clicky's converter.
52
+ * Takes precedence over `placeholder` when both are present. */
53
+ "x-clicky-placeholder"?: string;
48
54
  }
55
+ /** Resolves the input placeholder for a parameter, drawing ONLY from explicit
56
+ * placeholder fields — never from `description` (help text). Returns undefined
57
+ * when no placeholder is declared so callers can apply their own fallback. */
58
+ export declare function parameterPlaceholder(param: OpenAPIParameter): string | undefined;
49
59
  export interface OpenAPIOperation {
50
60
  tags?: string[];
51
61
  summary?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/rpc/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/rpc/types.ts"],"names":[],"mappings":"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"}
package/dist/rpc/types.js CHANGED
@@ -1,8 +1,12 @@
1
+ function parameterPlaceholder(param) {
2
+ return param["x-clicky-placeholder"] ?? param.placeholder;
3
+ }
1
4
  function isPositionalParam(p) {
2
5
  var _a;
3
6
  return p.name === "args" || ((_a = p.description) == null ? void 0 : _a.toLowerCase().includes("positional argument")) === true;
4
7
  }
5
8
  export {
6
- isPositionalParam
9
+ isPositionalParam,
10
+ parameterPlaceholder
7
11
  };
8
12
  //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sources":["../../src/rpc/types.ts"],"sourcesContent":["import type { ClickyNode } from \"../data/Clicky\";\nimport type { TimeRangePresetGroup } from \"../components/TimeRange\";\n\nexport interface ExecutionRequest {\n args?: string[];\n flags?: Record<string, string>;\n}\n\nexport interface ExecutionPagination {\n total?: number;\n limit?: number;\n offset?: number;\n}\n\nexport interface ExecutionResponse {\n success: boolean;\n message?: string;\n output?: string;\n stdout?: string;\n stderr?: string;\n exit_code: number;\n error?: string;\n cli?: string;\n input?: ExecutionRequest;\n contentType?: string;\n requestUrl?: string;\n responseHeaders?: Record<string, string>;\n pagination?: ExecutionPagination;\n blob?: Blob;\n parsed?: unknown;\n}\n\nexport interface OpenAPISchema {\n type?: string;\n format?: string;\n default?: unknown;\n enum?: unknown[];\n description?: string;\n properties?: Record<string, OpenAPISchema>;\n}\n\n// ClickyParameterRole tells the UI which widget owns a parameter:\n// \"search\" — render as the FilterBar's dedicated search input\n// \"filter\" — render as a FilterBar chip on the DataTable\n// \"limit\" — feed into DataTable pagination's pageSize\n// \"offset\" — feed into DataTable pagination's page (or skip)\n// \"time-from\" — left edge of a time-range picker\n// \"time-to\" — right edge of a time-range picker\n// Set server-side by clicky's converter (see paramRole in clicky/rpc/openapi.go).\nexport type ClickyParameterRole =\n | \"search\"\n | \"filter\"\n | \"limit\"\n | \"offset\"\n | \"time-from\"\n | \"time-to\";\n\nexport interface ClickyParameterMeta {\n role?: ClickyParameterRole;\n}\n\nexport interface OpenAPIParameter {\n name: string;\n in: \"query\" | \"path\" | \"header\";\n description?: string;\n required?: boolean;\n schema?: OpenAPISchema;\n \"x-clicky\"?: ClickyParameterMeta;\n}\n\nexport interface OpenAPIOperation {\n tags?: string[];\n summary?: string;\n description?: string;\n operationId?: string;\n parameters?: OpenAPIParameter[];\n requestBody?: {\n content?: Record<string, { schema?: OpenAPISchema }>;\n };\n responses: Record<string, unknown>;\n \"x-clicky\"?: ClickyOperationMeta;\n}\n\nexport interface OpenAPISpec {\n openapi: string;\n info: { title: string; description?: string; version: string };\n paths: Record<string, Record<string, OpenAPIOperation>>;\n tags?: Array<{ name: string; description?: string }>;\n \"x-clicky\"?: ClickySpecMeta;\n}\n\nexport interface ResolvedOperation {\n path: string;\n method: string;\n operation: OpenAPIOperation;\n}\n\nexport interface DomainDefinition {\n key: string;\n title: string;\n description: string;\n emptyTitle?: string;\n emptyDescription?: string;\n}\n\nexport interface ClickySpecMeta {\n surfaces?: ClickySurface[];\n}\n\nexport interface ClickySurface {\n key: string;\n entity: string;\n title: string;\n parent?: string;\n admin?: boolean;\n description?: string;\n}\n\nexport interface ClickyOperationMeta {\n command?: string;\n surface?: string;\n verb: \"list\" | \"get\" | \"create\" | \"update\" | \"delete\" | \"action\";\n scope: \"collection\" | \"entity\";\n actionName?: string;\n idParam?: string;\n supportsLookup?: boolean;\n supportsFilterMode?: boolean;\n}\n\nexport type OperationLookupFilterType = \"bool\" | \"number\" | \"date\" | \"from\" | \"to\" | \"multi-filter\";\n\nexport interface OperationLookupFilter {\n label?: string;\n options?: Record<string, ClickyNode>;\n selected?: Record<string, ClickyNode>;\n multi?: boolean;\n type?: OperationLookupFilterType;\n /** True when `options` is only the head of a larger set (server-side capped). */\n truncated?: boolean;\n /** True distinct count behind a truncated option set; drives \"… and N more\". */\n total?: number;\n presets?: Array<{ label: string; from: string; to: string } | TimeRangePresetGroup>;\n timeEnabled?: boolean;\n timeZone?: string;\n timeZones?: string[];\n}\n\nexport interface OperationLookupResponse {\n filters: Record<string, OperationLookupFilter>;\n}\n\nexport function isPositionalParam(p: OpenAPIParameter): boolean {\n return p.name === \"args\" || p.description?.toLowerCase().includes(\"positional argument\") === true;\n}\n"],"names":[],"mappings":"AAuJO,SAAS,kBAAkB,GAA8B;AAAzD;AACL,SAAO,EAAE,SAAS,YAAU,OAAE,gBAAF,mBAAe,cAAc,SAAS,4BAA2B;AAC/F;"}
1
+ {"version":3,"file":"types.js","sources":["../../src/rpc/types.ts"],"sourcesContent":["import type { ClickyNode } from \"../data/Clicky\";\nimport type { TimeRangePresetGroup } from \"../components/TimeRange\";\n\nexport interface ExecutionRequest {\n args?: string[];\n flags?: Record<string, string>;\n}\n\nexport interface ExecutionPagination {\n total?: number;\n limit?: number;\n offset?: number;\n}\n\nexport interface ExecutionResponse {\n success: boolean;\n message?: string;\n output?: string;\n stdout?: string;\n stderr?: string;\n exit_code: number;\n error?: string;\n cli?: string;\n input?: ExecutionRequest;\n contentType?: string;\n requestUrl?: string;\n responseHeaders?: Record<string, string>;\n pagination?: ExecutionPagination;\n blob?: Blob;\n parsed?: unknown;\n}\n\nexport interface OpenAPISchema {\n type?: string;\n format?: string;\n default?: unknown;\n enum?: unknown[];\n description?: string;\n properties?: Record<string, OpenAPISchema>;\n}\n\n// ClickyParameterRole tells the UI which widget owns a parameter:\n// \"search\" — render as the FilterBar's dedicated search input\n// \"filter\" — render as a FilterBar chip on the DataTable\n// \"limit\" — feed into DataTable pagination's pageSize\n// \"offset\" — feed into DataTable pagination's page (or skip)\n// \"time-from\" — left edge of a time-range picker\n// \"time-to\" — right edge of a time-range picker\n// Set server-side by clicky's converter (see paramRole in clicky/rpc/openapi.go).\nexport type ClickyParameterRole =\n | \"search\"\n | \"filter\"\n | \"limit\"\n | \"offset\"\n | \"time-from\"\n | \"time-to\";\n\nexport interface ClickyParameterMeta {\n role?: ClickyParameterRole;\n}\n\nexport interface OpenAPIParameter {\n name: string;\n in: \"query\" | \"path\" | \"header\";\n description?: string;\n required?: boolean;\n schema?: OpenAPISchema;\n /** Hint text shown inside the empty input. Distinct from `description`,\n * which is help text and must NOT be used as a placeholder. */\n placeholder?: string;\n \"x-clicky\"?: ClickyParameterMeta;\n /** Vendor-extension placeholder, set server-side by clicky's converter.\n * Takes precedence over `placeholder` when both are present. */\n \"x-clicky-placeholder\"?: string;\n}\n\n/** Resolves the input placeholder for a parameter, drawing ONLY from explicit\n * placeholder fields — never from `description` (help text). Returns undefined\n * when no placeholder is declared so callers can apply their own fallback. */\nexport function parameterPlaceholder(param: OpenAPIParameter): string | undefined {\n return param[\"x-clicky-placeholder\"] ?? param.placeholder;\n}\n\nexport interface OpenAPIOperation {\n tags?: string[];\n summary?: string;\n description?: string;\n operationId?: string;\n parameters?: OpenAPIParameter[];\n requestBody?: {\n content?: Record<string, { schema?: OpenAPISchema }>;\n };\n responses: Record<string, unknown>;\n \"x-clicky\"?: ClickyOperationMeta;\n}\n\nexport interface OpenAPISpec {\n openapi: string;\n info: { title: string; description?: string; version: string };\n paths: Record<string, Record<string, OpenAPIOperation>>;\n tags?: Array<{ name: string; description?: string }>;\n \"x-clicky\"?: ClickySpecMeta;\n}\n\nexport interface ResolvedOperation {\n path: string;\n method: string;\n operation: OpenAPIOperation;\n}\n\nexport interface DomainDefinition {\n key: string;\n title: string;\n description: string;\n emptyTitle?: string;\n emptyDescription?: string;\n}\n\nexport interface ClickySpecMeta {\n surfaces?: ClickySurface[];\n}\n\nexport interface ClickySurface {\n key: string;\n entity: string;\n title: string;\n parent?: string;\n admin?: boolean;\n description?: string;\n}\n\nexport interface ClickyOperationMeta {\n command?: string;\n surface?: string;\n verb: \"list\" | \"get\" | \"create\" | \"update\" | \"delete\" | \"action\";\n scope: \"collection\" | \"entity\";\n actionName?: string;\n idParam?: string;\n supportsLookup?: boolean;\n supportsFilterMode?: boolean;\n}\n\nexport type OperationLookupFilterType = \"bool\" | \"number\" | \"date\" | \"from\" | \"to\" | \"multi-filter\";\n\nexport interface OperationLookupFilter {\n label?: string;\n options?: Record<string, ClickyNode>;\n selected?: Record<string, ClickyNode>;\n multi?: boolean;\n type?: OperationLookupFilterType;\n /** True when `options` is only the head of a larger set (server-side capped). */\n truncated?: boolean;\n /** True distinct count behind a truncated option set; drives \"… and N more\". */\n total?: number;\n presets?: Array<{ label: string; from: string; to: string } | TimeRangePresetGroup>;\n timeEnabled?: boolean;\n timeZone?: string;\n timeZones?: string[];\n}\n\nexport interface OperationLookupResponse {\n filters: Record<string, OperationLookupFilter>;\n}\n\nexport function isPositionalParam(p: OpenAPIParameter): boolean {\n return p.name === \"args\" || p.description?.toLowerCase().includes(\"positional argument\") === true;\n}\n"],"names":[],"mappings":"AA+EO,SAAS,qBAAqB,OAA6C;AAChF,SAAO,MAAM,sBAAsB,KAAK,MAAM;AAChD;AAmFO,SAAS,kBAAkB,GAA8B;AArFzD;AAsFL,SAAO,EAAE,SAAS,YAAU,OAAE,gBAAF,mBAAe,cAAc,SAAS,4BAA2B;AAC/F;"}