@flanksource/clicky-ui 0.3.18 → 0.3.19

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 (191) hide show
  1. package/dist/components/ComboboxMenu.cjs +5 -1
  2. package/dist/components/ComboboxMenu.cjs.map +1 -1
  3. package/dist/components/ComboboxMenu.d.ts.map +1 -1
  4. package/dist/components/ComboboxMenu.js +5 -1
  5. package/dist/components/ComboboxMenu.js.map +1 -1
  6. package/dist/components/EndpointSelector.model.cjs +96 -0
  7. package/dist/components/EndpointSelector.model.cjs.map +1 -0
  8. package/dist/components/EndpointSelector.model.d.ts +2 -0
  9. package/dist/components/EndpointSelector.model.d.ts.map +1 -1
  10. package/dist/components/EndpointSelector.model.js +96 -0
  11. package/dist/components/EndpointSelector.model.js.map +1 -0
  12. package/dist/components/FilterBar.cjs +52 -2
  13. package/dist/components/FilterBar.cjs.map +1 -1
  14. package/dist/components/FilterBar.d.ts +20 -2
  15. package/dist/components/FilterBar.d.ts.map +1 -1
  16. package/dist/components/FilterBar.js +52 -2
  17. package/dist/components/FilterBar.js.map +1 -1
  18. package/dist/components/JSONPathField.cjs +87 -66
  19. package/dist/components/JSONPathField.cjs.map +1 -1
  20. package/dist/components/JSONPathField.d.ts +26 -9
  21. package/dist/components/JSONPathField.d.ts.map +1 -1
  22. package/dist/components/JSONPathField.js +88 -67
  23. package/dist/components/JSONPathField.js.map +1 -1
  24. package/dist/components/JSONPathPlayground.cjs +225 -0
  25. package/dist/components/JSONPathPlayground.cjs.map +1 -0
  26. package/dist/components/JSONPathPlayground.d.ts +59 -0
  27. package/dist/components/JSONPathPlayground.d.ts.map +1 -0
  28. package/dist/components/JSONPathPlayground.js +225 -0
  29. package/dist/components/JSONPathPlayground.js.map +1 -0
  30. package/dist/components/OnePasswordSelector.cjs +178 -0
  31. package/dist/components/OnePasswordSelector.cjs.map +1 -0
  32. package/dist/components/OnePasswordSelector.d.ts +8 -0
  33. package/dist/components/OnePasswordSelector.d.ts.map +1 -0
  34. package/dist/components/OnePasswordSelector.js +178 -0
  35. package/dist/components/OnePasswordSelector.js.map +1 -0
  36. package/dist/components/OnePasswordSelector.model.cjs +31 -0
  37. package/dist/components/OnePasswordSelector.model.cjs.map +1 -0
  38. package/dist/components/OnePasswordSelector.model.d.ts +27 -0
  39. package/dist/components/OnePasswordSelector.model.d.ts.map +1 -0
  40. package/dist/components/OnePasswordSelector.model.js +31 -0
  41. package/dist/components/OnePasswordSelector.model.js.map +1 -0
  42. package/dist/components/SecretFormField.cjs +142 -0
  43. package/dist/components/SecretFormField.cjs.map +1 -0
  44. package/dist/components/SecretFormField.d.ts +9 -0
  45. package/dist/components/SecretFormField.d.ts.map +1 -0
  46. package/dist/components/SecretFormField.js +142 -0
  47. package/dist/components/SecretFormField.js.map +1 -0
  48. package/dist/components/SecretKeySelector.cjs +20 -14
  49. package/dist/components/SecretKeySelector.cjs.map +1 -1
  50. package/dist/components/SecretKeySelector.d.ts +4 -1
  51. package/dist/components/SecretKeySelector.d.ts.map +1 -1
  52. package/dist/components/SecretKeySelector.js +20 -14
  53. package/dist/components/SecretKeySelector.js.map +1 -1
  54. package/dist/components/TreePickerField.cjs +55 -29
  55. package/dist/components/TreePickerField.cjs.map +1 -1
  56. package/dist/components/TreePickerField.d.ts +10 -1
  57. package/dist/components/TreePickerField.d.ts.map +1 -1
  58. package/dist/components/TreePickerField.js +56 -30
  59. package/dist/components/TreePickerField.js.map +1 -1
  60. package/dist/components/combobox-types.d.ts +9 -0
  61. package/dist/components/combobox-types.d.ts.map +1 -1
  62. package/dist/components/filter-bar-utils.cjs +7 -0
  63. package/dist/components/filter-bar-utils.cjs.map +1 -1
  64. package/dist/components/filter-bar-utils.d.ts.map +1 -1
  65. package/dist/components/filter-bar-utils.js +7 -0
  66. package/dist/components/filter-bar-utils.js.map +1 -1
  67. package/dist/components/jotai-bindings-core.cjs.map +1 -1
  68. package/dist/components/jotai-bindings-core.d.ts +4 -1
  69. package/dist/components/jotai-bindings-core.d.ts.map +1 -1
  70. package/dist/components/jotai-bindings-core.js.map +1 -1
  71. package/dist/components/json-schema-form-render.cjs +2 -1
  72. package/dist/components/json-schema-form-render.cjs.map +1 -1
  73. package/dist/components/json-schema-form-render.d.ts.map +1 -1
  74. package/dist/components/json-schema-form-render.js +2 -1
  75. package/dist/components/json-schema-form-render.js.map +1 -1
  76. package/dist/components/json-schema-form-types.d.ts +9 -0
  77. package/dist/components/json-schema-form-types.d.ts.map +1 -1
  78. package/dist/components/jsonPathTree.cjs +189 -0
  79. package/dist/components/jsonPathTree.cjs.map +1 -0
  80. package/dist/components/jsonPathTree.d.ts +92 -0
  81. package/dist/components/jsonPathTree.d.ts.map +1 -0
  82. package/dist/components/jsonPathTree.js +189 -0
  83. package/dist/components/jsonPathTree.js.map +1 -0
  84. package/dist/components/secret-form-extension.cjs +30 -0
  85. package/dist/components/secret-form-extension.cjs.map +1 -0
  86. package/dist/components/secret-form-extension.d.ts +23 -0
  87. package/dist/components/secret-form-extension.d.ts.map +1 -0
  88. package/dist/components/secret-form-extension.js +30 -0
  89. package/dist/components/secret-form-extension.js.map +1 -0
  90. package/dist/components.cjs +16 -0
  91. package/dist/components.cjs.map +1 -1
  92. package/dist/components.d.ts +6 -0
  93. package/dist/components.d.ts.map +1 -1
  94. package/dist/components.js +16 -0
  95. package/dist/components.js.map +1 -1
  96. package/dist/data/TaskExecDetails.cjs +40 -0
  97. package/dist/data/TaskExecDetails.cjs.map +1 -0
  98. package/dist/data/TaskExecDetails.d.ts +5 -0
  99. package/dist/data/TaskExecDetails.d.ts.map +1 -0
  100. package/dist/data/TaskExecDetails.js +40 -0
  101. package/dist/data/TaskExecDetails.js.map +1 -0
  102. package/dist/data/TaskProgress.cjs +9 -3
  103. package/dist/data/TaskProgress.cjs.map +1 -1
  104. package/dist/data/TaskProgress.d.ts.map +1 -1
  105. package/dist/data/TaskProgress.js +9 -3
  106. package/dist/data/TaskProgress.js.map +1 -1
  107. package/dist/data/TaskSnapshot.cjs.map +1 -1
  108. package/dist/data/TaskSnapshot.d.ts +12 -1
  109. package/dist/data/TaskSnapshot.d.ts.map +1 -1
  110. package/dist/data/TaskSnapshot.js.map +1 -1
  111. package/dist/data/TreeNode.cjs +3 -0
  112. package/dist/data/TreeNode.cjs.map +1 -1
  113. package/dist/data/TreeNode.d.ts.map +1 -1
  114. package/dist/data/TreeNode.js +3 -0
  115. package/dist/data/TreeNode.js.map +1 -1
  116. package/dist/data/data-table-filter-values.cjs +20 -0
  117. package/dist/data/data-table-filter-values.cjs.map +1 -1
  118. package/dist/data/data-table-filter-values.d.ts +16 -0
  119. package/dist/data/data-table-filter-values.d.ts.map +1 -1
  120. package/dist/data/data-table-filter-values.js +20 -0
  121. package/dist/data/data-table-filter-values.js.map +1 -1
  122. package/dist/data/data-table-server-filters.cjs +23 -29
  123. package/dist/data/data-table-server-filters.cjs.map +1 -1
  124. package/dist/data/data-table-server-filters.d.ts.map +1 -1
  125. package/dist/data/data-table-server-filters.js +21 -27
  126. package/dist/data/data-table-server-filters.js.map +1 -1
  127. package/dist/data/query-browser/QueryBrowser.cjs +129 -157
  128. package/dist/data/query-browser/QueryBrowser.cjs.map +1 -1
  129. package/dist/data/query-browser/QueryBrowser.d.ts +1 -71
  130. package/dist/data/query-browser/QueryBrowser.d.ts.map +1 -1
  131. package/dist/data/query-browser/QueryBrowser.editor.cjs +88 -0
  132. package/dist/data/query-browser/QueryBrowser.editor.cjs.map +1 -0
  133. package/dist/data/query-browser/QueryBrowser.editor.d.ts +12 -0
  134. package/dist/data/query-browser/QueryBrowser.editor.d.ts.map +1 -0
  135. package/dist/data/query-browser/QueryBrowser.editor.js +88 -0
  136. package/dist/data/query-browser/QueryBrowser.editor.js.map +1 -0
  137. package/dist/data/query-browser/QueryBrowser.js +130 -158
  138. package/dist/data/query-browser/QueryBrowser.js.map +1 -1
  139. package/dist/data/query-browser/QueryBrowser.types.cjs +11 -0
  140. package/dist/data/query-browser/QueryBrowser.types.cjs.map +1 -0
  141. package/dist/data/query-browser/QueryBrowser.types.d.ts +92 -0
  142. package/dist/data/query-browser/QueryBrowser.types.d.ts.map +1 -0
  143. package/dist/data/query-browser/QueryBrowser.types.js +11 -0
  144. package/dist/data/query-browser/QueryBrowser.types.js.map +1 -0
  145. package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.cjs +56 -0
  146. package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.cjs.map +1 -0
  147. package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.d.ts +5 -0
  148. package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.d.ts.map +1 -0
  149. package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.js +56 -0
  150. package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.js.map +1 -0
  151. package/dist/data/query-browser/QueryBrowserResults.cjs +80 -0
  152. package/dist/data/query-browser/QueryBrowserResults.cjs.map +1 -0
  153. package/dist/data/query-browser/QueryBrowserResults.d.ts +16 -0
  154. package/dist/data/query-browser/QueryBrowserResults.d.ts.map +1 -0
  155. package/dist/data/query-browser/QueryBrowserResults.js +80 -0
  156. package/dist/data/query-browser/QueryBrowserResults.js.map +1 -0
  157. package/dist/data/query-browser/index.d.ts +2 -1
  158. package/dist/data/query-browser/index.d.ts.map +1 -1
  159. package/dist/data/task-exec-details.cjs +9 -0
  160. package/dist/data/task-exec-details.cjs.map +1 -0
  161. package/dist/data/task-exec-details.d.ts +3 -0
  162. package/dist/data/task-exec-details.d.ts.map +1 -0
  163. package/dist/data/task-exec-details.js +9 -0
  164. package/dist/data/task-exec-details.js.map +1 -0
  165. package/dist/data/version-info.cjs +3 -3
  166. package/dist/data/version-info.js +3 -3
  167. package/dist/data.cjs +2 -0
  168. package/dist/data.cjs.map +1 -1
  169. package/dist/data.d.ts +1 -1
  170. package/dist/data.d.ts.map +1 -1
  171. package/dist/data.js +2 -0
  172. package/dist/data.js.map +1 -1
  173. package/dist/index.cjs +18 -0
  174. package/dist/index.cjs.map +1 -1
  175. package/dist/index.js +18 -0
  176. package/dist/index.js.map +1 -1
  177. package/dist/rpc/FilterForm.cjs +20 -0
  178. package/dist/rpc/FilterForm.cjs.map +1 -1
  179. package/dist/rpc/FilterForm.js +20 -0
  180. package/dist/rpc/FilterForm.js.map +1 -1
  181. package/dist/rpc/formMetadata.cjs +34 -0
  182. package/dist/rpc/formMetadata.cjs.map +1 -1
  183. package/dist/rpc/formMetadata.d.ts.map +1 -1
  184. package/dist/rpc/formMetadata.js +35 -1
  185. package/dist/rpc/formMetadata.js.map +1 -1
  186. package/dist/rpc/types.cjs.map +1 -1
  187. package/dist/rpc/types.d.ts +9 -1
  188. package/dist/rpc/types.d.ts.map +1 -1
  189. package/dist/rpc/types.js.map +1 -1
  190. package/dist/styles.css +1 -1
  191. package/package.json +1 -1
@@ -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 FilterBarRangeProps,\n FilterBarSearchProps,\n} from \"../components/FilterBar\";\nimport type { DataTablePagination } from \"../data/DataTable\";\nimport {\n parseMultiFilterValue,\n serializeMultiFilterValue,\n splitCommaValues,\n} from \"../data/data-table-filter-values\";\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 limitValue: string;\n setLimit: (next: string) => void;\n\n // Offset paging, when the operation declares an offset parameter. Absent for\n // a surface that cannot name a position past its first page — a profile with\n // no total order, say. Such a surface still sizes its page and still reports\n // how many rows it is showing of how many; it just cannot step.\n offsetParam?: string;\n offsetValue?: string;\n setOffset?: (next: string) => void;\n\n // Cursor paging, when the operation declares a cursor parameter. Present\n // alongside limit/offset rather than instead of them: an operation can serve\n // both, and which one a page uses is decided per request.\n cursorParam?: string;\n cursorValue?: string;\n setCursor?: (next: string) => void;\n};\n\nexport type ParameterFormConfig = {\n filters: FilterBarFilter[];\n search?: FilterBarSearchProps;\n timeRange?: FilterBarRangeProps;\n pagination?: ParameterPagination;\n};\n// LookupSearch fetches the options of one filter matching `query`, server-side.\n// It is what a truncated option set is reachable through: the head the lookup\n// returned is only the first page of a larger distinct set, and everything past\n// it is found by typing rather than by scrolling.\nexport type LookupSearch = (\n filterKey: string,\n query: string,\n) => Promise<{ value: string; label: string; title?: string }[]>;\n\nexport type ParameterFormOptions = {\n includeLocations?: OpenAPIParameter[\"in\"][];\n lookup?: OperationLookupResponse | undefined;\n lockedValues?: ParameterValues | undefined;\n hideLocked?: boolean;\n // Wired only into filters the server marked truncated: one that fully\n // enumerated needs no round trip to search what is already in the browser.\n lookupSearch?: LookupSearch | undefined;\n};\n\n// A truncated set has to say so even where nothing can search it: the footer\n// telling the user 350 values are missing is what stops a partial list reading\n// as the whole answer.\nfunction truncationProps(filter: OperationLookupFilter) {\n if (!filter.truncated) return {};\n return { truncated: true, ...(filter.total !== undefined ? { total: filter.total } : {}) };\n}\n\n// Server-side search applies only when the server said it withheld options. A\n// filter whose set arrived whole is searched in the browser, which is both\n// faster and exactly as complete.\nfunction searchProps(\n filter: OperationLookupFilter,\n key: string,\n search: LookupSearch | undefined,\n) {\n if (!filter.truncated) return {};\n return {\n ...truncationProps(filter),\n ...(search ? { onSearch: (query: string) => search(key, query) } : {}),\n };\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\n// OFFSET_DEPTH_LIMIT is where offset paging stops being available and a cursor\n// takes over. It exists because backends refuse a deep offset outright —\n// OpenSearch's default result window is 10,000 — so this is the one place that\n// decides the changeover rather than each surface discovering the refusal for\n// itself. Below it, page-number jumps stay available; past it there is nothing\n// to jump with, because a cursor names a position rather than a page.\nexport const OFFSET_DEPTH_LIMIT = 10_000;\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 const served = response?.pagination;\n const setCursor = pagination.setCursor;\n const setOffset = pagination.setOffset;\n\n return {\n page,\n pageSize,\n ...(served?.total !== undefined ? { total: served.total } : {}),\n ...(served?.totalRelation !== undefined ? { totalRelation: served.totalRelation } : {}),\n ...(served?.hasMore !== undefined ? { hasMore: served.hasMore } : {}),\n // Cursor mode needs both halves: a parameter to send the cursor on, and a\n // cursor to send. An operation that declares one without the server minting\n // the other pages by offset, which is correct and merely slower.\n //\n // Which mode applies is depth, not preference: a walk already under way\n // continues, and a shallow page keeps its jump controls until the next one\n // would cross OFFSET_DEPTH_LIMIT — the point past which the offset would be\n // refused anyway.\n ...(setCursor &&\n (pagination.cursorValue ||\n (served?.nextCursor && offset + pageSize >= OFFSET_DEPTH_LIMIT))\n ? {\n cursor: {\n ...(pagination.cursorValue ? { current: pagination.cursorValue } : {}),\n ...(served?.nextCursor ? { next: served.nextCursor } : {}),\n onCursorChange: (next: string | undefined) => {\n // Offset and cursor are two disagreeing positions in one request,\n // so taking the cursor means dropping the offset.\n setOffset?.(\"0\");\n setCursor(next ?? \"\");\n },\n },\n }\n : {}),\n // Offered only when there is somewhere to step to. A surface with no offset\n // parameter still counts and still resizes, but naming page two would be\n // naming a page the server will refuse.\n ...(setOffset\n ? {\n onPageChange: (next: number) => {\n if (positiveInt(pagination.limitValue) == null) {\n pagination.setLimit(String(pageSize));\n }\n setCursor?.(\"\");\n setOffset(String(Math.max(next, 0) * pageSize));\n },\n }\n : {}),\n onPageSizeChange: (next: number) => {\n pagination.setLimit(String(next));\n // A cursor names a position in a page of the old size, so resizing the\n // page invalidates it and the walk restarts.\n setCursor?.(\"\");\n 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 // A cursor is an opaque server-minted token, so it is never a filter chip a\n // user could type into — it is only ever echoed back from a previous page.\n const cursorParam = parameters.find((p) => p[\"x-clicky\"]?.role === \"cursor\");\n const paginationOmitNames = new Set<string>();\n if (limitParam) paginationOmitNames.add(limitParam.name);\n if (offsetParam) paginationOmitNames.add(offsetParam.name);\n if (cursorParam) paginationOmitNames.add(cursorParam.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 // rewind returns the caller to the first page whenever the result set itself\n // changes. Both positions have to go: an offset into the old rows names\n // different rows in the new ones, and a cursor minted under the old filters\n // is rejected by the server outright rather than silently reinterpreted.\n const rewind = (next: ParameterValues): ParameterValues => ({\n ...next,\n ...(offsetParam ? { [offsetParam.name]: \"0\" } : {}),\n ...(cursorParam ? { [cursorParam.name]: \"\" } : {}),\n });\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 // Only an explicit placeholder is rendered — never synthesize one. The\n // field already carries `label`, so a fallback placeholder is redundant\n // and generic defaults (e.g. \"value-1, value-2\") read as fake data.\n const placeholder = parameterPlaceholder(param);\n const placeholderProp = placeholder !== undefined ? { placeholder } : {};\n const onChange = (next: string | boolean) => {\n if (disabled) return;\n const stringValue = typeof next === \"boolean\" ? (next ? \"true\" : \"false\") : next;\n setValues((current) => rewind({ ...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 ...searchProps(lookupFilter, param.name, options.lookupSearch),\n onChange: (next) =>\n setValues((current) =>\n rewind({ ...current, [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 // Reported, not searched: this control's onSearch hands the query back\n // to the consumer to refetch and re-feed `options`, which is a\n // different contract from the one searchProps satisfies.\n ...truncationProps(lookupFilter),\n ...placeholderProp,\n onChange: (next) =>\n setValues((current) => rewind({ ...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 ...placeholderProp,\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 ...placeholderProp,\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) => rewind({ ...current, [searchParam.name]: next }));\n },\n ...(searchPlaceholder ? { placeholder: searchPlaceholder } : {}),\n ariaLabel: lookupFilters[searchParam.name]?.label ?? titleCase(searchParam.name),\n };\n }\n // Gated on the limit alone. An operation that caps its rows can report how\n // many of how many it is showing and can resize the cap, both of which are\n // independent of being able to step to a second page — and gating the whole\n // footer on the offset is what made a surface without one report \"100 of 100\"\n // while the server was answering with a total of 12,558.\n if (limitParam) {\n config.pagination = {\n limitParam: limitParam.name,\n limitValue: values[limitParam.name] ?? \"\",\n setLimit: (next) => setValues((current) => ({ ...current, [limitParam.name]: next })),\n ...(offsetParam\n ? {\n offsetParam: offsetParam.name,\n offsetValue: values[offsetParam.name] ?? \"\",\n setOffset: (next: string) =>\n setValues((current) => ({ ...current, [offsetParam.name]: next })),\n }\n : {}),\n ...(cursorParam\n ? {\n cursorParam: cursorParam.name,\n cursorValue: values[cursorParam.name] ?? \"\",\n setCursor: (next: string) =>\n setValues((current) => ({ ...current, [cursorParam.name]: next })),\n }\n : {}),\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 rewind({ ...current, [rangeStart.name]: from, [rangeEnd.name]: to }),\n ),\n ...(rangeMeta?.presets ? { presets: rangeMeta.presets } : {}),\n timeEnabled: rangeMeta?.timeEnabled ?? false,\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\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\nexport function 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 FilterBarRangeProps,\n FilterBarSearchProps,\n} from \"../components/FilterBar\";\nimport type { DataTablePagination } from \"../data/DataTable\";\nimport {\n parseBoundsValue,\n parseMultiFilterValue,\n serializeBoundsValue,\n serializeMultiFilterValue,\n splitCommaValues,\n} from \"../data/data-table-filter-values\";\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 limitValue: string;\n setLimit: (next: string) => void;\n\n // Offset paging, when the operation declares an offset parameter. Absent for\n // a surface that cannot name a position past its first page — a profile with\n // no total order, say. Such a surface still sizes its page and still reports\n // how many rows it is showing of how many; it just cannot step.\n offsetParam?: string;\n offsetValue?: string;\n setOffset?: (next: string) => void;\n\n // Cursor paging, when the operation declares a cursor parameter. Present\n // alongside limit/offset rather than instead of them: an operation can serve\n // both, and which one a page uses is decided per request.\n cursorParam?: string;\n cursorValue?: string;\n setCursor?: (next: string) => void;\n};\n\nexport type ParameterFormConfig = {\n filters: FilterBarFilter[];\n search?: FilterBarSearchProps;\n timeRange?: FilterBarRangeProps;\n pagination?: ParameterPagination;\n};\n// LookupSearch fetches the options of one filter matching `query`, server-side.\n// It is what a truncated option set is reachable through: the head the lookup\n// returned is only the first page of a larger distinct set, and everything past\n// it is found by typing rather than by scrolling.\nexport type LookupSearch = (\n filterKey: string,\n query: string,\n) => Promise<{ value: string; label: string; title?: string }[]>;\n\nexport type ParameterFormOptions = {\n includeLocations?: OpenAPIParameter[\"in\"][];\n lookup?: OperationLookupResponse | undefined;\n lockedValues?: ParameterValues | undefined;\n hideLocked?: boolean;\n // Wired only into filters the server marked truncated: one that fully\n // enumerated needs no round trip to search what is already in the browser.\n lookupSearch?: LookupSearch | undefined;\n};\n\n// A truncated set has to say so even where nothing can search it: the footer\n// telling the user 350 values are missing is what stops a partial list reading\n// as the whole answer.\nfunction truncationProps(filter: OperationLookupFilter) {\n if (!filter.truncated) return {};\n return { truncated: true, ...(filter.total !== undefined ? { total: filter.total } : {}) };\n}\n\n// Server-side search applies only when the server said it withheld options. A\n// filter whose set arrived whole is searched in the browser, which is both\n// faster and exactly as complete.\nfunction searchProps(\n filter: OperationLookupFilter,\n key: string,\n search: LookupSearch | undefined,\n) {\n if (!filter.truncated) return {};\n return {\n ...truncationProps(filter),\n ...(search ? { onSearch: (query: string) => search(key, query) } : {}),\n };\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\n// OFFSET_DEPTH_LIMIT is where offset paging stops being available and a cursor\n// takes over. It exists because backends refuse a deep offset outright —\n// OpenSearch's default result window is 10,000 — so this is the one place that\n// decides the changeover rather than each surface discovering the refusal for\n// itself. Below it, page-number jumps stay available; past it there is nothing\n// to jump with, because a cursor names a position rather than a page.\nexport const OFFSET_DEPTH_LIMIT = 10_000;\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 const served = response?.pagination;\n const setCursor = pagination.setCursor;\n const setOffset = pagination.setOffset;\n\n return {\n page,\n pageSize,\n ...(served?.total !== undefined ? { total: served.total } : {}),\n ...(served?.totalRelation !== undefined ? { totalRelation: served.totalRelation } : {}),\n ...(served?.hasMore !== undefined ? { hasMore: served.hasMore } : {}),\n // Cursor mode needs both halves: a parameter to send the cursor on, and a\n // cursor to send. An operation that declares one without the server minting\n // the other pages by offset, which is correct and merely slower.\n //\n // Which mode applies is depth, not preference: a walk already under way\n // continues, and a shallow page keeps its jump controls until the next one\n // would cross OFFSET_DEPTH_LIMIT — the point past which the offset would be\n // refused anyway.\n ...(setCursor &&\n (pagination.cursorValue ||\n (served?.nextCursor && offset + pageSize >= OFFSET_DEPTH_LIMIT))\n ? {\n cursor: {\n ...(pagination.cursorValue ? { current: pagination.cursorValue } : {}),\n ...(served?.nextCursor ? { next: served.nextCursor } : {}),\n onCursorChange: (next: string | undefined) => {\n // Offset and cursor are two disagreeing positions in one request,\n // so taking the cursor means dropping the offset.\n setOffset?.(\"0\");\n setCursor(next ?? \"\");\n },\n },\n }\n : {}),\n // Offered only when there is somewhere to step to. A surface with no offset\n // parameter still counts and still resizes, but naming page two would be\n // naming a page the server will refuse.\n ...(setOffset\n ? {\n onPageChange: (next: number) => {\n if (positiveInt(pagination.limitValue) == null) {\n pagination.setLimit(String(pageSize));\n }\n setCursor?.(\"\");\n setOffset(String(Math.max(next, 0) * pageSize));\n },\n }\n : {}),\n onPageSizeChange: (next: number) => {\n pagination.setLimit(String(next));\n // A cursor names a position in a page of the old size, so resizing the\n // page invalidates it and the walk restarts.\n setCursor?.(\"\");\n 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 // A cursor is an opaque server-minted token, so it is never a filter chip a\n // user could type into — it is only ever echoed back from a previous page.\n const cursorParam = parameters.find((p) => p[\"x-clicky\"]?.role === \"cursor\");\n const paginationOmitNames = new Set<string>();\n if (limitParam) paginationOmitNames.add(limitParam.name);\n if (offsetParam) paginationOmitNames.add(offsetParam.name);\n if (cursorParam) paginationOmitNames.add(cursorParam.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 // rewind returns the caller to the first page whenever the result set itself\n // changes. Both positions have to go: an offset into the old rows names\n // different rows in the new ones, and a cursor minted under the old filters\n // is rejected by the server outright rather than silently reinterpreted.\n const rewind = (next: ParameterValues): ParameterValues => ({\n ...next,\n ...(offsetParam ? { [offsetParam.name]: \"0\" } : {}),\n ...(cursorParam ? { [cursorParam.name]: \"\" } : {}),\n });\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 // Only an explicit placeholder is rendered — never synthesize one. The\n // field already carries `label`, so a fallback placeholder is redundant\n // and generic defaults (e.g. \"value-1, value-2\") read as fake data.\n const placeholder = parameterPlaceholder(param);\n const placeholderProp = placeholder !== undefined ? { placeholder } : {};\n const onChange = (next: string | boolean) => {\n if (disabled) return;\n const stringValue = typeof next === \"boolean\" ? (next ? \"true\" : \"false\") : next;\n setValues((current) => rewind({ ...current, [param.name]: stringValue }));\n };\n\n const schema = param.schema;\n const lookupFilter = lookupFilters[param.name];\n\n // Both edges of a range travel under one parameter, so the control is built\n // from that parameter alone rather than from the from/to pair below.\n if (lookupFilter?.type === \"date-range\" && param.in === \"query\") {\n const bounds = parseBoundsValue(value);\n emitFilters.push({\n key: param.name,\n kind: \"date-range\",\n label,\n disabled,\n ...(bounds.min !== undefined ? { from: bounds.min } : {}),\n ...(bounds.max !== undefined ? { to: bounds.max } : {}),\n ...(lookupFilter.presets ? { presets: lookupFilter.presets } : {}),\n timeEnabled: lookupFilter.timeEnabled ?? true,\n ...(lookupFilter.timeZone ? { timeZone: lookupFilter.timeZone } : {}),\n ...(lookupFilter.timeZones ? { timeZones: lookupFilter.timeZones } : {}),\n onApply: (from: string, to: string) => {\n if (disabled) return;\n setValues((current) =>\n rewind({ ...current, [param.name]: serializeBoundsValue({ min: from, max: to }) }),\n );\n },\n });\n continue;\n }\n\n // An exact-value selection with nothing to enumerate. It shares the\n // multi-filter grammar, so the raw string is written through unchanged:\n // \"a,b\" is two values and \"!a\" excludes one, exactly as picking them would.\n if (lookupFilter?.type === \"value\" && param.in === \"query\") {\n emitFilters.push({\n key: param.name,\n kind: \"text\",\n label,\n value,\n disabled,\n ...placeholderProp,\n onChange: (next) => onChange(next),\n });\n continue;\n }\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 ...searchProps(lookupFilter, param.name, options.lookupSearch),\n onChange: (next) =>\n setValues((current) =>\n rewind({ ...current, [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 // Reported, not searched: this control's onSearch hands the query back\n // to the consumer to refetch and re-feed `options`, which is a\n // different contract from the one searchProps satisfies.\n ...truncationProps(lookupFilter),\n ...placeholderProp,\n onChange: (next) =>\n setValues((current) => rewind({ ...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 ...placeholderProp,\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 ...placeholderProp,\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) => rewind({ ...current, [searchParam.name]: next }));\n },\n ...(searchPlaceholder ? { placeholder: searchPlaceholder } : {}),\n ariaLabel: lookupFilters[searchParam.name]?.label ?? titleCase(searchParam.name),\n };\n }\n // Gated on the limit alone. An operation that caps its rows can report how\n // many of how many it is showing and can resize the cap, both of which are\n // independent of being able to step to a second page — and gating the whole\n // footer on the offset is what made a surface without one report \"100 of 100\"\n // while the server was answering with a total of 12,558.\n if (limitParam) {\n config.pagination = {\n limitParam: limitParam.name,\n limitValue: values[limitParam.name] ?? \"\",\n setLimit: (next) => setValues((current) => ({ ...current, [limitParam.name]: next })),\n ...(offsetParam\n ? {\n offsetParam: offsetParam.name,\n offsetValue: values[offsetParam.name] ?? \"\",\n setOffset: (next: string) =>\n setValues((current) => ({ ...current, [offsetParam.name]: next })),\n }\n : {}),\n ...(cursorParam\n ? {\n cursorParam: cursorParam.name,\n cursorValue: values[cursorParam.name] ?? \"\",\n setCursor: (next: string) =>\n setValues((current) => ({ ...current, [cursorParam.name]: next })),\n }\n : {}),\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 rewind({ ...current, [rangeStart.name]: from, [rangeEnd.name]: to }),\n ),\n ...(rangeMeta?.presets ? { presets: rangeMeta.presets } : {}),\n timeEnabled: rangeMeta?.timeEnabled ?? false,\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\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\nexport function 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":";;;AA8EA,SAAS,gBAAgB,QAA+B;AACtD,MAAI,CAAC,OAAO,UAAW,QAAO,CAAA;AAC9B,SAAO,EAAE,WAAW,MAAM,GAAI,OAAO,UAAU,SAAY,EAAE,OAAO,OAAO,MAAA,IAAU,CAAA,EAAC;AACxF;AAKA,SAAS,YACP,QACA,KACA,QACA;AACA,MAAI,CAAC,OAAO,UAAW,QAAO,CAAA;AAC9B,SAAO;AAAA,IACL,GAAG,gBAAgB,MAAM;AAAA,IACzB,GAAI,SAAS,EAAE,UAAU,CAAC,UAAkB,OAAO,KAAK,KAAK,MAAM,CAAA;AAAA,EAAC;AAExE;AAEO,SAAS,UAAU,OAAe;AACvC,SAAO,MACJ,MAAM,MAAM,EACZ,OAAO,OAAO,EACd,IAAI,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,gBAAgB,KAAK,MAAM,CAAC,CAAC,EAC1D,KAAK,GAAG;AACb;AAEO,SAAS,yBAAyB,OAAyB,QAAwB;;AACxF,MAAI,OAAO,kBAAkB,SAAS,MAAM,OAAO,WAAW,CAAC,MAAM,UAAU;AAC7E,WAAO;AAAA,EACT;AACA,QAAM,WAAW,MAAM,OAAO,SAAS,KAAK;AAC5C,QAAM,UAAQ,WAAM,WAAN,mBAAc,YAAW;AACvC,MAAI,OAAO,UAAU,WAAW;AAC9B,WAAO,QAAQ,SAAS;AAAA,EAC1B;AACA,MAAI,MAAM,QAAQ,KAAK,KAAM,SAAS,QAAQ,OAAO,UAAU,UAAW;AACxE,WAAO;AAAA,EACT;AACA,MAAI,SAAS,MAAM;AACjB,WAAO;AAAA,EACT;AACA,SAAO,OAAO,KAAK;AACrB;AAEO,SAAS,4BACd,YACA,QACA,eAAgC,CAAA,GAChC,gBAAiC,IAChB;AACjB,QAAM,SAAS,OAAO;AAAA,IACpB,WAAW,IAAI,CAAC,UAAU,CAAC,MAAM,MAAM,yBAAyB,OAAO,MAAM,CAAC,CAAC;AAAA,EAAA;AAEjF,SAAO,EAAE,GAAG,QAAQ,GAAG,eAAe,GAAG,aAAA;AAC3C;AAQO,MAAM,qBAAqB;AAE3B,SAAS,4BACd,YACA,UACiC;;AACjC,MAAI,CAAC,WAAY,QAAO;AAExB,QAAM,WAAW,YAAY,WAAW,UAAU,OAAK,0CAAU,eAAV,mBAAsB,UAAS;AACtF,QAAM,SAAS,eAAe,WAAW,WAAW,OAAK,0CAAU,eAAV,mBAAsB,WAAU;AACzF,QAAM,OAAO,KAAK,MAAM,SAAS,QAAQ;AACzC,QAAM,SAAS,qCAAU;AACzB,QAAM,YAAY,WAAW;AAC7B,QAAM,YAAY,WAAW;AAE7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,IAAI,iCAAQ,WAAU,SAAY,EAAE,OAAO,OAAO,MAAA,IAAU,CAAA;AAAA,IAC5D,IAAI,iCAAQ,mBAAkB,SAAY,EAAE,eAAe,OAAO,cAAA,IAAkB,CAAA;AAAA,IACpF,IAAI,iCAAQ,aAAY,SAAY,EAAE,SAAS,OAAO,QAAA,IAAY,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASlE,GAAI,cACH,WAAW,gBACT,iCAAQ,eAAc,SAAS,YAAY,sBAC1C;AAAA,MACE,QAAQ;AAAA,QACN,GAAI,WAAW,cAAc,EAAE,SAAS,WAAW,YAAA,IAAgB,CAAA;AAAA,QACnE,IAAI,iCAAQ,cAAa,EAAE,MAAM,OAAO,WAAA,IAAe,CAAA;AAAA,QACvD,gBAAgB,CAAC,SAA6B;AAG5C,iDAAY;AACZ,oBAAU,QAAQ,EAAE;AAAA,QACtB;AAAA,MAAA;AAAA,IACF,IAEF,CAAA;AAAA;AAAA;AAAA;AAAA,IAIJ,GAAI,YACA;AAAA,MACE,cAAc,CAAC,SAAiB;AAC9B,YAAI,YAAY,WAAW,UAAU,KAAK,MAAM;AAC9C,qBAAW,SAAS,OAAO,QAAQ,CAAC;AAAA,QACtC;AACA,+CAAY;AACZ,kBAAU,OAAO,KAAK,IAAI,MAAM,CAAC,IAAI,QAAQ,CAAC;AAAA,MAChD;AAAA,IAAA,IAEF,CAAA;AAAA,IACJ,kBAAkB,CAAC,SAAiB;AAClC,iBAAW,SAAS,OAAO,IAAI,CAAC;AAGhC,6CAAY;AACZ,6CAAY;AAAA,IACd;AAAA,EAAA;AAEJ;AAEO,SAAS,qBAAqB,QAAyB;AAC5D,SAAO,OAAO,YAAY,OAAO,QAAQ,MAAM,EAAE,OAAO,CAAC,CAAA,EAAG,KAAK,MAAM,UAAU,EAAE,CAAC;AACtF;AAEO,SAAS,oBACd,QACA,YACiB;AACjB,QAAM,kBAAkB,IAAI;AAAA,IAC1B,WACG,OAAO,CAAC,UAAU,MAAM,OAAO,UAAU,kBAAkB,KAAK,CAAC,EACjE,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,EAAA;AAEtB,QAAM,SAA0B,CAAA;AAChC,QAAM,OAAiB,CAAA;AAEvB,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,QAAI,CAAC,MAAO;AACZ,QAAI,gBAAgB,IAAI,GAAG,GAAG;AAC5B,WAAK,KAAK,KAAK;AAAA,IACjB,OAAO;AACL,aAAO,GAAG,IAAI;AAAA,IAChB;AAAA,EACF;AAEA,MAAI,KAAK,SAAS,GAAG;AACnB,WAAO,OAAO,KAAK,KAAK,GAAG;AAAA,EAC7B;AAEA,SAAO;AACT;AAEO,SAAS,uBACd,YACA,QACA,WACA,UAAgC,CAAA,GACX;;AACrB,QAAM,cAAiC,CAAA;AACvC,QAAM,kBAAgB,aAAQ,WAAR,mBAAgB,YAAW,CAAA;AACjD,QAAM,mBAAmB,IAAI,IAAI,QAAQ,oBAAoB,CAAC,QAAQ,SAAS,QAAQ,CAAC;AACxF,QAAM,eAAe,QAAQ,gBAAgB,CAAA;AAC7C,QAAM,aAAa,QAAQ,cAAc;AAOzC,QAAM,aAAa,WAAW,KAAK,CAAC;;AAAM,aAAAA,MAAA,EAAE,UAAU,MAAZ,gBAAAA,IAAe,UAAS;AAAA,GAAO;AACzE,QAAM,cAAc,WAAW,KAAK,CAAC;;AAAM,aAAAA,MAAA,EAAE,UAAU,MAAZ,gBAAAA,IAAe,UAAS;AAAA,GAAQ;AAG3E,QAAM,cAAc,WAAW,KAAK,CAAC;;AAAM,aAAAA,MAAA,EAAE,UAAU,MAAZ,gBAAAA,IAAe,UAAS;AAAA,GAAQ;AAC3E,QAAM,0CAA0B,IAAA;AAChC,MAAI,WAAY,qBAAoB,IAAI,WAAW,IAAI;AACvD,MAAI,YAAa,qBAAoB,IAAI,YAAY,IAAI;AACzD,MAAI,YAAa,qBAAoB,IAAI,YAAY,IAAI;AAIzD,QAAM,cAAc,WAAW;AAAA,IAC7B,CAAC,MAAA;;AAAM,eAAAA,MAAA,EAAE,UAAU,MAAZ,gBAAAA,IAAe,UAAS,YAAY,iBAAiB,IAAI,EAAE,EAAE;AAAA;AAAA,EAAA;AAEtE,QAAM,YAAY,IAAI,IAAI,mBAAmB;AAC7C,MAAI,YAAa,WAAU,IAAI,YAAY,IAAI;AAM/C,QAAM,SAAS,CAAC,UAA4C;AAAA,IAC1D,GAAG;AAAA,IACH,GAAI,cAAc,EAAE,CAAC,YAAY,IAAI,GAAG,IAAA,IAAQ,CAAA;AAAA,IAChD,GAAI,cAAc,EAAE,CAAC,YAAY,IAAI,GAAG,GAAA,IAAO,CAAA;AAAA,EAAC;AAKlD,QAAM,iBAAiB,WAAW,KAAK,CAAC;;AAAM,aAAAA,MAAA,EAAE,UAAU,MAAZ,gBAAAA,IAAe,UAAS;AAAA,GAAW;AACjF,QAAM,eAAe,WAAW,KAAK,CAAC;;AAAM,aAAAA,MAAA,EAAE,UAAU,MAAZ,gBAAAA,IAAe,UAAS;AAAA,GAAS;AAC7E,QAAM,aACJ,kBACA,WAAW;AAAA,IACT,CAAC,UAAA;;AACC,8BAAiB,IAAI,MAAM,EAAE,KAC7B,MAAM,OAAO,aACbA,MAAA,cAAc,MAAM,IAAI,MAAxB,gBAAAA,IAA2B,UAAS;AAAA;AAAA,EAAA;AAE1C,QAAM,WACJ,gBACA,WAAW;AAAA,IACT,CAAC,UAAA;;AACC,8BAAiB,IAAI,MAAM,EAAE,KAC7B,MAAM,OAAO,aACbA,MAAA,cAAc,MAAM,IAAI,MAAxB,gBAAAA,IAA2B,UAAS;AAAA;AAAA,EAAA;AAE1C,QAAM,eAAe,cAAc,QAAQ,YAAY;AAEvD,aAAW,SAAS,YAAY;AAC9B,QAAI,CAAC,iBAAiB,IAAI,MAAM,EAAE,EAAG;AACrC,QAAI,UAAU,IAAI,MAAM,IAAI,EAAG;AAC/B,QAAI,iBAAiB,MAAM,UAAS,yCAAY,SAAQ,MAAM,UAAS,qCAAU,QAAO;AACtF;AAAA,IACF;AAEA,UAAM,WAAW,OAAO,UAAU,eAAe,KAAK,cAAc,MAAM,IAAI;AAC9E,QAAI,YAAY,WAAY;AAC5B,UAAM,QAAQ,WAAY,aAAa,MAAM,IAAI,KAAK,KAAO,OAAO,MAAM,IAAI,KAAK;AACnF,UAAM,UAAQ,mBAAc,MAAM,IAAI,MAAxB,mBAA2B,UAAS,UAAU,MAAM,IAAI;AAItE,UAAM,cAAc,qBAAqB,KAAK;AAC9C,UAAM,kBAAkB,gBAAgB,SAAY,EAAE,YAAA,IAAgB,CAAA;AACtE,UAAM,WAAW,CAAC,SAA2B;AAC3C,UAAI,SAAU;AACd,YAAM,cAAc,OAAO,SAAS,YAAa,OAAO,SAAS,UAAW;AAC5E,gBAAU,CAAC,YAAY,OAAO,EAAE,GAAG,SAAS,CAAC,MAAM,IAAI,GAAG,YAAA,CAAa,CAAC;AAAA,IAC1E;AAEA,UAAM,SAAS,MAAM;AACrB,UAAM,eAAe,cAAc,MAAM,IAAI;AAI7C,SAAI,6CAAc,UAAS,gBAAgB,MAAM,OAAO,SAAS;AAC/D,YAAM,SAAS,iBAAiB,KAAK;AACrC,kBAAY,KAAK;AAAA,QACf,KAAK,MAAM;AAAA,QACX,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA,GAAI,OAAO,QAAQ,SAAY,EAAE,MAAM,OAAO,IAAA,IAAQ,CAAA;AAAA,QACtD,GAAI,OAAO,QAAQ,SAAY,EAAE,IAAI,OAAO,IAAA,IAAQ,CAAA;AAAA,QACpD,GAAI,aAAa,UAAU,EAAE,SAAS,aAAa,QAAA,IAAY,CAAA;AAAA,QAC/D,aAAa,aAAa,eAAe;AAAA,QACzC,GAAI,aAAa,WAAW,EAAE,UAAU,aAAa,SAAA,IAAa,CAAA;AAAA,QAClE,GAAI,aAAa,YAAY,EAAE,WAAW,aAAa,UAAA,IAAc,CAAA;AAAA,QACrE,SAAS,CAAC,MAAc,OAAe;AACrC,cAAI,SAAU;AACd;AAAA,YAAU,CAAC,YACT,OAAO,EAAE,GAAG,SAAS,CAAC,MAAM,IAAI,GAAG,qBAAqB,EAAE,KAAK,MAAM,KAAK,GAAA,CAAI,GAAG;AAAA,UAAA;AAAA,QAErF;AAAA,MAAA,CACD;AACD;AAAA,IACF;AAKA,SAAI,6CAAc,UAAS,WAAW,MAAM,OAAO,SAAS;AAC1D,kBAAY,KAAK;AAAA,QACf,KAAK,MAAM;AAAA,QACX,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,QACA,GAAG;AAAA,QACH,UAAU,CAAC,SAAS,SAAS,IAAI;AAAA,MAAA,CAClC;AACD;AAAA,IACF;AAEA,SAAI,6CAAc,UAAS,kBAAkB,MAAM,OAAO,SAAS;AACjE,kBAAY,KAAK;AAAA,QACf,KAAK,MAAM;AAAA,QACX,MAAM;AAAA,QACN;AAAA,QACA,OAAO,sBAAsB,KAAK;AAAA,QAClC;AAAA,QACA,SAAS,4BAA4B,YAAY;AAAA,QACjD,GAAG,YAAY,cAAc,MAAM,MAAM,QAAQ,YAAY;AAAA,QAC7D,UAAU,CAAC,SACT;AAAA,UAAU,CAAC,YACT,OAAO,EAAE,GAAG,SAAS,CAAC,MAAM,IAAI,GAAG,0BAA0B,IAAI,GAAG;AAAA,QAAA;AAAA,MACtE,CACH;AACD;AAAA,IACF;AAEA,QAAI,iCAAQ,MAAM;AAChB,kBAAY,KAAK;AAAA,QACf,KAAK,MAAM;AAAA,QACX,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,QACA,SAAS,OAAO,KAAK,IAAI,CAAC,UAAU;AAAA,UAClC,OAAO,OAAO,IAAI;AAAA,UAClB,OAAO,OAAO,IAAI;AAAA,QAAA,EAClB;AAAA,QACF,UAAU,CAAC,SAAS,SAAS,IAAI;AAAA,MAAA,CAClC;AACD;AAAA,IACF;AAEA,SAAI,6CAAc,UAAS,WAAU,iCAAQ,UAAS,WAAW;AAC/D,kBAAY,KAAK;AAAA,QACf,KAAK,MAAM;AAAA,QACX,MAAM;AAAA,QACN;AAAA,QACA,OAAO,UAAU;AAAA,QACjB;AAAA,QACA,UAAU,CAAC,SAAS,SAAS,IAAI;AAAA,MAAA,CAClC;AACD;AAAA,IACF;AAEA,QAAI,gBAAgB,QAAQ,MAAM,OAAO,SAAS;AAChD,UAAI,aAAa,OAAO;AACtB,oBAAY,KAAK;AAAA,UACf,KAAK,MAAM;AAAA,UACX,MAAM;AAAA,UACN;AAAA,UACA,OAAO,iBAAiB,KAAK;AAAA,UAC7B;AAAA,UACA,SAAS,4BAA4B,YAAY;AAAA;AAAA;AAAA;AAAA,UAIjD,GAAG,gBAAgB,YAAY;AAAA,UAC/B,GAAG;AAAA,UACH,UAAU,CAAC,SACT,UAAU,CAAC,YAAY,OAAO,EAAE,GAAG,SAAS,CAAC,MAAM,IAAI,GAAG,KAAK,KAAK,GAAG,EAAA,CAAG,CAAC;AAAA,QAAA,CAC9E;AACD;AAAA,MACF;AAEA,kBAAY,KAAK;AAAA,QACf,KAAK,MAAM;AAAA,QACX,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,QACA,SAAS,4BAA4B,YAAY;AAAA,QACjD,GAAG;AAAA,QACH,WACE,aAAa,SAAS,WAClB,WACA,aAAa,SAAS,SACpB,SACA;AAAA,QACR,UAAU,CAAC,SAAS,SAAS,IAAI;AAAA,MAAA,CAClC;AACD;AAAA,IACF;AAEA,gBAAY,KAAK;AAAA,MACf,KAAK,MAAM;AAAA,MACX,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG;AAAA,MACH,UAAU,CAAC,SAAS,SAAS,IAAI;AAAA,IAAA,CAClC;AAAA,EACH;AAEA,QAAM,SAA8B,EAAE,SAAS,YAAA;AAC/C,MAAI,aAAa;AACf,UAAM,iBAAiB,OAAO,UAAU,eAAe,KAAK,cAAc,YAAY,IAAI;AAC1F,UAAM,cAAc,iBACf,aAAa,YAAY,IAAI,KAAK,KAClC,OAAO,YAAY,IAAI,KAAK;AACjC,UAAM,oBAAoB,qBAAqB,WAAW;AAC1D,WAAO,SAAS;AAAA,MACd,OAAO;AAAA,MACP,UAAU,CAAC,SAAS;AAClB,YAAI,eAAgB;AACpB,kBAAU,CAAC,YAAY,OAAO,EAAE,GAAG,SAAS,CAAC,YAAY,IAAI,GAAG,KAAA,CAAM,CAAC;AAAA,MACzE;AAAA,MACA,GAAI,oBAAoB,EAAE,aAAa,kBAAA,IAAsB,CAAA;AAAA,MAC7D,aAAW,mBAAc,YAAY,IAAI,MAA9B,mBAAiC,UAAS,UAAU,YAAY,IAAI;AAAA,IAAA;AAAA,EAEnF;AAMA,MAAI,YAAY;AACd,WAAO,aAAa;AAAA,MAClB,YAAY,WAAW;AAAA,MACvB,YAAY,OAAO,WAAW,IAAI,KAAK;AAAA,MACvC,UAAU,CAAC,SAAS,UAAU,CAAC,aAAa,EAAE,GAAG,SAAS,CAAC,WAAW,IAAI,GAAG,OAAO;AAAA,MACpF,GAAI,cACA;AAAA,QACE,aAAa,YAAY;AAAA,QACzB,aAAa,OAAO,YAAY,IAAI,KAAK;AAAA,QACzC,WAAW,CAAC,SACV,UAAU,CAAC,aAAa,EAAE,GAAG,SAAS,CAAC,YAAY,IAAI,GAAG,OAAO;AAAA,MAAA,IAErE,CAAA;AAAA,MACJ,GAAI,cACA;AAAA,QACE,aAAa,YAAY;AAAA,QACzB,aAAa,OAAO,YAAY,IAAI,KAAK;AAAA,QACzC,WAAW,CAAC,SACV,UAAU,CAAC,aAAa,EAAE,GAAG,SAAS,CAAC,YAAY,IAAI,GAAG,OAAO;AAAA,MAAA,IAErE,CAAA;AAAA,IAAC;AAAA,EAET;AACA,MAAI,gBAAgB,cAAc,QAAQ,YAAY,MAAM;AAC1D,UAAM,iBAAiB,cAAc,WAAW,IAAI;AACpD,UAAM,eAAe,cAAc,SAAS,IAAI;AAChD,UAAM,YAAY,kBAAkB;AACpC,WAAO,YAAY;AAAA,MACjB,MAAM,OAAO,WAAW,IAAI,KAAK;AAAA,MACjC,IAAI,OAAO,SAAS,IAAI,KAAK;AAAA,MAC7B,SAAS,CAAC,MAAM,OACd;AAAA,QAAU,CAAC,YACT,OAAO,EAAE,GAAG,SAAS,CAAC,WAAW,IAAI,GAAG,MAAM,CAAC,SAAS,IAAI,GAAG,IAAI;AAAA,MAAA;AAAA,MAEvE,IAAI,uCAAW,WAAU,EAAE,SAAS,UAAU,QAAA,IAAY,CAAA;AAAA,MAC1D,cAAa,uCAAW,gBAAe;AAAA,MACvC,IAAI,uCAAW,YAAW,EAAE,UAAU,UAAU,SAAA,IAAa,CAAA;AAAA,MAC7D,IAAI,uCAAW,aAAY,EAAE,WAAW,UAAU,UAAA,IAAc,CAAA;AAAA,MAChE,GAAI,WAAW,cAAc,EAAE,iBAAiB,WAAW,YAAA,IAAgB,CAAA;AAAA,MAC3E,GAAI,SAAS,cAAc,EAAE,eAAe,SAAS,YAAA,IAAgB,CAAA;AAAA,IAAC;AAAA,EAE1E;AAEA,SAAO;AACT;AAEO,SAAS,mBAAsB,OAAU,SAAiB;AAC/D,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAEhD,YAAU,MAAM;AACd,UAAM,YAAY,OAAO,WAAW,MAAM,aAAa,KAAK,GAAG,OAAO;AACtE,WAAO,MAAM,OAAO,aAAa,SAAS;AAAA,EAC5C,GAAG,CAAC,SAAS,KAAK,CAAC;AAEnB,SAAO;AACT;AAEA,SAAS,YAAY,OAA+C;AAClE,QAAM,SAAS,SAAS,SAAS,IAAI,EAAE;AACvC,SAAO,OAAO,SAAS,MAAM,KAAK,SAAS,IAAI,SAAS;AAC1D;AAEA,SAAS,eAAe,OAA+C;AACrE,QAAM,SAAS,SAAS,SAAS,IAAI,EAAE;AACvC,SAAO,OAAO,SAAS,MAAM,KAAK,UAAU,IAAI,SAAS;AAC3D;AAEO,SAAS,4BAA4B,QAA+B;AACzE,QAAM,6BAAa,IAAA;AAEnB,aAAW,CAAC,OAAO,IAAI,KAAK,OAAO,QAAQ,OAAO,WAAW,CAAA,CAAE,GAAG;AAChE,WAAO,IAAI,OAAO;AAAA,MAChB,OAAO,sBAAsB,IAAI,KAAK;AAAA,MACtC,OAAO,sBAAsB,IAAI,KAAK;AAAA,IAAA,CACvC;AAAA,EACH;AAEA,aAAW,CAAC,OAAO,IAAI,KAAK,OAAO,QAAQ,OAAO,YAAY,CAAA,CAAE,GAAG;AACjE,QAAI,CAAC,OAAO,IAAI,KAAK,GAAG;AACtB,aAAO,IAAI,OAAO;AAAA,QAChB,OAAO,sBAAsB,IAAI,KAAK;AAAA,QACtC,OAAO,sBAAsB,IAAI,KAAK;AAAA,MAAA,CACvC;AAAA,IACH;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,OAAO,QAAA,CAAS,EAAE,IAAI,CAAC,CAAC,OAAO,IAAI,OAAO;AAAA,IAC1D;AAAA,IACA,OAAO,KAAK,SAAS;AAAA,IACrB,OAAO,KAAK,SAAS;AAAA,EAAA,EACrB;AACJ;AASA,SAAS,sBAAsB,MAAsD;AACnF,MAAI,QAAQ,KAAM,QAAO;AACzB,MAAI,KAAK,MAAO,QAAO,KAAK;AAC5B,MAAI,KAAK,KAAM,QAAO,KAAK;AAC3B,UAAQ,KAAK,YAAY,CAAA,GAAI,IAAI,CAAC,UAAU,sBAAsB,KAAK,CAAC,EAAE,KAAK,EAAE;AACnF;"}
@@ -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 // totalRelation says whether total is a count or a lower bound. A backend\n // that stops counting past a threshold reports \"gte\", and rendering that as\n // a count would state a number nobody promised.\n totalRelation?: \"eq\" | \"gte\";\n\n // hasMore is the server's answer, not an inference from the page length: a\n // short page and the end of the data are different facts.\n hasMore?: boolean;\n\n // nextCursor resumes after this page. Opaque — it is passed back unchanged\n // and never parsed, because a client that can read one can forge one.\n nextCursor?: string;\n\n // truncated reports that the server stopped short of the whole result, so a\n // partial answer is never rendered as a complete one.\n truncated?: boolean;\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 items?: OpenAPISchema;\n oneOf?: OpenAPISchema[];\n additionalProperties?: OpenAPISchema | boolean;\n nullable?: boolean;\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// \"cursor\" — carry the opaque position the previous page returned\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 | \"cursor\"\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(\n param: OpenAPIParameter,\n): 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 icon?: 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 /** Opaque icon name emitted by the backend (x-clicky-icon), resolved to a glyph in the UI. */\n icon?: string;\n /**\n * Hierarchy position within `parent`, \"/\"-separated (x-clicky-path) — e.g.\n * \"jms/incoming/disbursements\". The backend has already applied whatever\n * delimiter its own naming convention uses, so the UI never guesses one.\n * Absent — the default — means the parent group renders as a flat list.\n */\n path?: 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 group?: string;\n toolHints?: ClickyToolHints;\n export?: ClickyExportMeta;\n}\n\nexport interface ClickyExportMeta {\n formats?: string[];\n scopes?: Array<\"page\" | \"all\">;\n allRowsMode?: \"streaming\" | \"buffered\";\n formatMaxRows?: Record<string, number>;\n}\n\nexport interface ClickyToolHints {\n title?: string;\n readOnlyHint?: boolean;\n destructiveHint?: boolean;\n idempotentHint?: boolean;\n openWorldHint?: boolean;\n icon?: string;\n group?: string;\n parent?: string;\n defaultPermission?: \"on\" | \"ask\" | \"off\" | \"auto\";\n strict?: boolean;\n}\n\nexport type OperationLookupFilterType =\n | \"bool\"\n | \"number\"\n | \"date\"\n | \"from\"\n | \"to\"\n | \"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<\n { label: string; from: string; to: string } | TimeRangePresetGroup\n >;\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 (\n p.name === \"args\" ||\n p.description?.toLowerCase().includes(\"positional argument\") === true\n );\n}\n"],"names":[],"mappings":";;AAsGO,SAAS,qBACd,OACoB;AACpB,SAAO,MAAM,sBAAsB,KAAK,MAAM;AAChD;AA4HO,SAAS,kBAAkB,GAA8B;;AAC9D,SACE,EAAE,SAAS,YACX,OAAE,gBAAF,mBAAe,cAAc,SAAS,4BAA2B;AAErE;;;"}
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 // totalRelation says whether total is a count or a lower bound. A backend\n // that stops counting past a threshold reports \"gte\", and rendering that as\n // a count would state a number nobody promised.\n totalRelation?: \"eq\" | \"gte\";\n\n // hasMore is the server's answer, not an inference from the page length: a\n // short page and the end of the data are different facts.\n hasMore?: boolean;\n\n // nextCursor resumes after this page. Opaque — it is passed back unchanged\n // and never parsed, because a client that can read one can forge one.\n nextCursor?: string;\n\n // truncated reports that the server stopped short of the whole result, so a\n // partial answer is never rendered as a complete one.\n truncated?: boolean;\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 items?: OpenAPISchema;\n oneOf?: OpenAPISchema[];\n additionalProperties?: OpenAPISchema | boolean;\n nullable?: boolean;\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// \"cursor\" — carry the opaque position the previous page returned\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 | \"cursor\"\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(\n param: OpenAPIParameter,\n): 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 icon?: 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 /** Opaque icon name emitted by the backend (x-clicky-icon), resolved to a glyph in the UI. */\n icon?: string;\n /**\n * Hierarchy position within `parent`, \"/\"-separated (x-clicky-path) — e.g.\n * \"jms/incoming/disbursements\". The backend has already applied whatever\n * delimiter its own naming convention uses, so the UI never guesses one.\n * Absent — the default — means the parent group renders as a flat list.\n */\n path?: 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 group?: string;\n toolHints?: ClickyToolHints;\n export?: ClickyExportMeta;\n}\n\nexport interface ClickyExportMeta {\n formats?: string[];\n scopes?: Array<\"page\" | \"all\">;\n allRowsMode?: \"streaming\" | \"buffered\";\n formatMaxRows?: Record<string, number>;\n}\n\nexport interface ClickyToolHints {\n title?: string;\n readOnlyHint?: boolean;\n destructiveHint?: boolean;\n idempotentHint?: boolean;\n openWorldHint?: boolean;\n icon?: string;\n group?: string;\n parent?: string;\n defaultPermission?: \"on\" | \"ask\" | \"off\" | \"auto\";\n strict?: boolean;\n}\n\nexport type OperationLookupFilterType =\n | \"bool\"\n | \"number\"\n | \"date\"\n /** Both edges of a range under one parameter, as \">=from,<=to\". */\n | \"date-range\"\n | \"from\"\n | \"to\"\n | \"multi-filter\"\n /**\n * An exact-value selection with nothing to enumerate — a UUID column, say.\n * Same wire grammar as \"multi-filter\"; typed rather than picked, because a\n * dropdown over identifiers is a page of the rows.\n */\n | \"value\";\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<\n { label: string; from: string; to: string } | TimeRangePresetGroup\n >;\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 (\n p.name === \"args\" ||\n p.description?.toLowerCase().includes(\"positional argument\") === true\n );\n}\n"],"names":[],"mappings":";;AAsGO,SAAS,qBACd,OACoB;AACpB,SAAO,MAAM,sBAAsB,KAAK,MAAM;AAChD;AAoIO,SAAS,kBAAkB,GAA8B;;AAC9D,SACE,EAAE,SAAS,YACX,OAAE,gBAAF,mBAAe,cAAc,SAAS,4BAA2B;AAErE;;;"}
@@ -156,7 +156,15 @@ export interface ClickyToolHints {
156
156
  defaultPermission?: "on" | "ask" | "off" | "auto";
157
157
  strict?: boolean;
158
158
  }
159
- export type OperationLookupFilterType = "bool" | "number" | "date" | "from" | "to" | "multi-filter";
159
+ export type OperationLookupFilterType = "bool" | "number" | "date"
160
+ /** Both edges of a range under one parameter, as ">=from,<=to". */
161
+ | "date-range" | "from" | "to" | "multi-filter"
162
+ /**
163
+ * An exact-value selection with nothing to enumerate — a UUID column, say.
164
+ * Same wire grammar as "multi-filter"; typed rather than picked, because a
165
+ * dropdown over identifiers is a page of the rows.
166
+ */
167
+ | "value";
160
168
  export interface OperationLookupFilter {
161
169
  label?: string;
162
170
  options?: Record<string, ClickyNode>;
@@ -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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"}
@@ -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 // totalRelation says whether total is a count or a lower bound. A backend\n // that stops counting past a threshold reports \"gte\", and rendering that as\n // a count would state a number nobody promised.\n totalRelation?: \"eq\" | \"gte\";\n\n // hasMore is the server's answer, not an inference from the page length: a\n // short page and the end of the data are different facts.\n hasMore?: boolean;\n\n // nextCursor resumes after this page. Opaque — it is passed back unchanged\n // and never parsed, because a client that can read one can forge one.\n nextCursor?: string;\n\n // truncated reports that the server stopped short of the whole result, so a\n // partial answer is never rendered as a complete one.\n truncated?: boolean;\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 items?: OpenAPISchema;\n oneOf?: OpenAPISchema[];\n additionalProperties?: OpenAPISchema | boolean;\n nullable?: boolean;\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// \"cursor\" — carry the opaque position the previous page returned\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 | \"cursor\"\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(\n param: OpenAPIParameter,\n): 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 icon?: 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 /** Opaque icon name emitted by the backend (x-clicky-icon), resolved to a glyph in the UI. */\n icon?: string;\n /**\n * Hierarchy position within `parent`, \"/\"-separated (x-clicky-path) — e.g.\n * \"jms/incoming/disbursements\". The backend has already applied whatever\n * delimiter its own naming convention uses, so the UI never guesses one.\n * Absent — the default — means the parent group renders as a flat list.\n */\n path?: 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 group?: string;\n toolHints?: ClickyToolHints;\n export?: ClickyExportMeta;\n}\n\nexport interface ClickyExportMeta {\n formats?: string[];\n scopes?: Array<\"page\" | \"all\">;\n allRowsMode?: \"streaming\" | \"buffered\";\n formatMaxRows?: Record<string, number>;\n}\n\nexport interface ClickyToolHints {\n title?: string;\n readOnlyHint?: boolean;\n destructiveHint?: boolean;\n idempotentHint?: boolean;\n openWorldHint?: boolean;\n icon?: string;\n group?: string;\n parent?: string;\n defaultPermission?: \"on\" | \"ask\" | \"off\" | \"auto\";\n strict?: boolean;\n}\n\nexport type OperationLookupFilterType =\n | \"bool\"\n | \"number\"\n | \"date\"\n | \"from\"\n | \"to\"\n | \"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<\n { label: string; from: string; to: string } | TimeRangePresetGroup\n >;\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 (\n p.name === \"args\" ||\n p.description?.toLowerCase().includes(\"positional argument\") === true\n );\n}\n"],"names":[],"mappings":"AAsGO,SAAS,qBACd,OACoB;AACpB,SAAO,MAAM,sBAAsB,KAAK,MAAM;AAChD;AA4HO,SAAS,kBAAkB,GAA8B;AAhIzD;AAiIL,SACE,EAAE,SAAS,YACX,OAAE,gBAAF,mBAAe,cAAc,SAAS,4BAA2B;AAErE;"}
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 // totalRelation says whether total is a count or a lower bound. A backend\n // that stops counting past a threshold reports \"gte\", and rendering that as\n // a count would state a number nobody promised.\n totalRelation?: \"eq\" | \"gte\";\n\n // hasMore is the server's answer, not an inference from the page length: a\n // short page and the end of the data are different facts.\n hasMore?: boolean;\n\n // nextCursor resumes after this page. Opaque — it is passed back unchanged\n // and never parsed, because a client that can read one can forge one.\n nextCursor?: string;\n\n // truncated reports that the server stopped short of the whole result, so a\n // partial answer is never rendered as a complete one.\n truncated?: boolean;\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 items?: OpenAPISchema;\n oneOf?: OpenAPISchema[];\n additionalProperties?: OpenAPISchema | boolean;\n nullable?: boolean;\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// \"cursor\" — carry the opaque position the previous page returned\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 | \"cursor\"\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(\n param: OpenAPIParameter,\n): 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 icon?: 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 /** Opaque icon name emitted by the backend (x-clicky-icon), resolved to a glyph in the UI. */\n icon?: string;\n /**\n * Hierarchy position within `parent`, \"/\"-separated (x-clicky-path) — e.g.\n * \"jms/incoming/disbursements\". The backend has already applied whatever\n * delimiter its own naming convention uses, so the UI never guesses one.\n * Absent — the default — means the parent group renders as a flat list.\n */\n path?: 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 group?: string;\n toolHints?: ClickyToolHints;\n export?: ClickyExportMeta;\n}\n\nexport interface ClickyExportMeta {\n formats?: string[];\n scopes?: Array<\"page\" | \"all\">;\n allRowsMode?: \"streaming\" | \"buffered\";\n formatMaxRows?: Record<string, number>;\n}\n\nexport interface ClickyToolHints {\n title?: string;\n readOnlyHint?: boolean;\n destructiveHint?: boolean;\n idempotentHint?: boolean;\n openWorldHint?: boolean;\n icon?: string;\n group?: string;\n parent?: string;\n defaultPermission?: \"on\" | \"ask\" | \"off\" | \"auto\";\n strict?: boolean;\n}\n\nexport type OperationLookupFilterType =\n | \"bool\"\n | \"number\"\n | \"date\"\n /** Both edges of a range under one parameter, as \">=from,<=to\". */\n | \"date-range\"\n | \"from\"\n | \"to\"\n | \"multi-filter\"\n /**\n * An exact-value selection with nothing to enumerate — a UUID column, say.\n * Same wire grammar as \"multi-filter\"; typed rather than picked, because a\n * dropdown over identifiers is a page of the rows.\n */\n | \"value\";\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<\n { label: string; from: string; to: string } | TimeRangePresetGroup\n >;\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 (\n p.name === \"args\" ||\n p.description?.toLowerCase().includes(\"positional argument\") === true\n );\n}\n"],"names":[],"mappings":"AAsGO,SAAS,qBACd,OACoB;AACpB,SAAO,MAAM,sBAAsB,KAAK,MAAM;AAChD;AAoIO,SAAS,kBAAkB,GAA8B;AAxIzD;AAyIL,SACE,EAAE,SAAS,YACX,OAAE,gBAAF,mBAAe,cAAc,SAAS,4BAA2B;AAErE;"}