@petrarca/sonnet-core 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,16 +1,28 @@
1
1
  # @petrarca/sonnet-core
2
2
 
3
- Foundation utilities for the Petrarca Sonnet component library. This is the leaf package -- all other Sonnet packages depend on it.
3
+ Foundation utilities for the Petrarca Sonnet component library. Leaf package
4
+ all other Sonnet packages depend on it.
4
5
 
5
6
  ## Entry points
6
7
 
7
8
  | Import | What |
8
9
  |---|---|
9
- | `@petrarca/sonnet-core` | Utility functions (`cn`, `isEqual`, `formatDateTime`, `normalizeError`, logging, etc.) |
10
+ | `@petrarca/sonnet-core` | `cn`, `isEqual`, `formatDateTime`, `normalizeError`, logging |
10
11
  | `@petrarca/sonnet-core/schema` | JSON Schema types, resolution, validation, diffing |
11
- | `@petrarca/sonnet-core/search` | Filter expression types and helpers (`FilterExpr`, `buildListParams`, etc.) |
12
- | `@petrarca/sonnet-core/hooks` | React hooks (`useClipboard`, `useDisclosure`, `useFormState`, `useEntityOptions`) |
13
- | `@petrarca/sonnet-core/entityOptions` | Entity option fetcher context and factory for async select/autocomplete |
12
+ | `@petrarca/sonnet-core/search` | Filter expression types (`FilterExpr`, `buildListParams`) |
13
+ | `@petrarca/sonnet-core/hooks` | React hooks (see below) |
14
+ | `@petrarca/sonnet-core/entityOptions` | Entity option fetcher context for async select/autocomplete |
15
+
16
+ ## Hooks
17
+
18
+ | Hook | Purpose |
19
+ |---|---|
20
+ | `useClipboard` | Copy text to clipboard with copied-state timeout |
21
+ | `useDisclosure` | Boolean open/close/toggle state |
22
+ | `useFormState` | Generic form state with dirty tracking |
23
+ | `useEntityOptions` | Async entity fetching for select/autocomplete components |
24
+ | `useResizablePanel` | Drag-to-resize panel width |
25
+ | `useTreeExpansion` | Expand/collapse state for `TreeView` components |
14
26
 
15
27
  ## Install
16
28
 
@@ -20,4 +32,4 @@ pnpm add @petrarca/sonnet-core
20
32
 
21
33
  ## License
22
34
 
23
- Apache 2.0
35
+ See [LICENSE.md](../../LICENSE.md).
package/dist/index.d.ts CHANGED
@@ -136,5 +136,14 @@ interface PageResult<T> {
136
136
  data: T[];
137
137
  meta: PageMeta;
138
138
  }
139
+ /**
140
+ * Wrap a full array as a single-page PageResult.
141
+ *
142
+ * Bridges "regular" (un-paginated) list APIs that return a bare array into the
143
+ * PageResult envelope that paginated consumers (e.g. EntityTable) expect. The
144
+ * whole array is treated as one complete page: total = length, offset = 0, and
145
+ * no next/prev page. Use for small lists served without server-side pagination.
146
+ */
147
+ declare function toPageResult<T>(rows: T[]): PageResult<T>;
139
148
 
140
- export { FORM_ITEM_ID_FIELD, JSON_CSS_VARIABLES, type NormalizedError, type OffsetRange, type PageMeta, type PageResult, cn, copyTextToClipboard, devLog, errorLog, escapeHtml, formatDate, formatDateTime, formatDateTimeTz, formatJsonValue, formatNumber, formatNumberCompact, generateId, infoLog, isEqual, normalizeError, pluralize, resolvePointerRanges, snakeCaseToTitleCase, useComposedRefs, warnLog };
149
+ export { FORM_ITEM_ID_FIELD, JSON_CSS_VARIABLES, type NormalizedError, type OffsetRange, type PageMeta, type PageResult, cn, copyTextToClipboard, devLog, errorLog, escapeHtml, formatDate, formatDateTime, formatDateTimeTz, formatJsonValue, formatNumber, formatNumberCompact, generateId, infoLog, isEqual, normalizeError, pluralize, resolvePointerRanges, snakeCaseToTitleCase, toPageResult, useComposedRefs, warnLog };
package/dist/index.js CHANGED
@@ -377,6 +377,20 @@ function resolvePointerRanges(json, pointers) {
377
377
  ranges.sort((a, b) => a.from - b.from);
378
378
  return ranges;
379
379
  }
380
+
381
+ // src/pagination.ts
382
+ function toPageResult(rows) {
383
+ return {
384
+ data: rows,
385
+ meta: {
386
+ total: rows.length,
387
+ limit: rows.length,
388
+ offset: 0,
389
+ has_next: false,
390
+ has_prev: false
391
+ }
392
+ };
393
+ }
380
394
  export {
381
395
  FORM_ITEM_ID_FIELD,
382
396
  JSON_CSS_VARIABLES,
@@ -398,6 +412,7 @@ export {
398
412
  pluralize,
399
413
  resolvePointerRanges,
400
414
  snakeCaseToTitleCase_default as snakeCaseToTitleCase,
415
+ toPageResult,
401
416
  useComposedRefs,
402
417
  warnLog
403
418
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/format.ts","../src/jsonUtils.ts","../src/utils/copyTextToClipboard.tsx","../src/utils/snakeCaseToTitleCase.ts","../src/errorNormalizer.ts","../src/compose-refs.ts","../src/resolvePointerRanges.ts"],"sourcesContent":["// Reusable formatting utilities.\n// Thin wrappers around Intl for consistent output across the app.\n\nconst numberFormatter = new Intl.NumberFormat(undefined, {\n maximumFractionDigits: 0,\n});\n\nexport function formatNumber(\n value: number | string | undefined | null,\n): string {\n if (value === null || value === undefined) return \"0\";\n const num = typeof value === \"string\" ? Number(value) : value;\n if (!Number.isFinite(num)) return String(value);\n return numberFormatter.format(num as number);\n}\n\nexport function formatNumberCompact(\n value: number | string | undefined | null,\n): string {\n if (value === null || value === undefined) return \"0\";\n const num = typeof value === \"string\" ? Number(value) : value;\n if (!Number.isFinite(num)) return String(value);\n return new Intl.NumberFormat(undefined, {\n notation: \"compact\",\n maximumFractionDigits: 1,\n }).format(num as number);\n}\n\n/** Format an ISO 8601 string as a short date (e.g. \"Jan 15, 2026\"). */\nexport function formatDate(iso: string | null | undefined): string {\n if (!iso) return \"\\u2014\";\n return new Date(iso).toLocaleDateString(undefined, {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n });\n}\n\n/** Format an ISO 8601 string as date + time (e.g. \"Jan 15, 2026, 09:32 AM\"). */\nexport function formatDateTime(iso: string | null | undefined): string {\n if (!iso) return \"\\u2014\";\n return new Date(iso).toLocaleString(undefined, {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n });\n}\n\n/**\n * Format a timezone-aware ISO 8601 string preserving the original offset.\n *\n * Parses the date/time components and offset directly from the string so\n * the emitter's local time and offset are shown exactly as recorded --\n * independent of the viewer's timezone.\n *\n * Examples:\n * \"2026-02-22T10:00:00+01:00\" -> \"22 Feb 2026 at 10:00 +01:00\"\n * \"2026-02-22T09:00:00Z\" -> \"22 Feb 2026 at 09:00 UTC\"\n */\nexport function formatDateTimeTz(iso: string | null | undefined): string {\n if (!iso) return \"\\u2014\";\n\n // Match ISO 8601: date, time (HH:MM), optional seconds, offset or Z.\n const match = iso.match(\n /^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2})(?::\\d{2}(?:\\.\\d+)?)?(Z|[+-]\\d{2}:\\d{2})$/,\n );\n if (!match) return iso;\n\n const [, year, month, day, hour, minute, rawOffset] = match;\n\n const months = [\n \"Jan\",\n \"Feb\",\n \"Mar\",\n \"Apr\",\n \"May\",\n \"Jun\",\n \"Jul\",\n \"Aug\",\n \"Sep\",\n \"Oct\",\n \"Nov\",\n \"Dec\",\n ];\n const monthName = months[parseInt(month, 10) - 1];\n const offset = rawOffset === \"Z\" ? \"UTC\" : rawOffset;\n\n return `${parseInt(day, 10)} ${monthName} ${year} at ${hour}:${minute} ${offset}`;\n}\n\n/** Return \"{count} {word}\" with the word pluralized when count != 1. */\nexport function pluralize(count: number, word: string): string {\n return `${count} ${word}${count !== 1 ? \"s\" : \"\"}`;\n}\n","/**\n * Escapes HTML characters to prevent XSS and rendering issues\n */\nexport function escapeHtml(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n}\n\n/**\n * Formats a JSON value into colored HTML with proper syntax highlighting\n * @param value - The value to format (any JSON-serializable type)\n * @param indent - Current indentation level for nested objects/arrays\n * @returns HTML string with syntax highlighting\n */\nfunction jsonSpan(cssVar: string, content: string): string {\n return `<span style=\"color: var(${cssVar})\">${content}</span>`;\n}\n\nfunction formatPrimitive(value: unknown): string | null {\n if (value === null) return jsonSpan(\"--json-null\", \"null\");\n if (typeof value === \"undefined\") return jsonSpan(\"--json-null\", \"undefined\");\n if (typeof value === \"boolean\")\n return jsonSpan(\"--json-boolean\", String(value));\n if (typeof value === \"number\")\n return jsonSpan(\"--json-number\", String(value));\n if (typeof value === \"string\")\n return jsonSpan(\"--json-string\", `\"${escapeHtml(value)}\"`);\n return null;\n}\n\nfunction formatArray(value: unknown[], indent: number): string {\n if (value.length === 0) return jsonSpan(\"--json-punctuation\", \"[]\");\n const indentStr = \" \".repeat(indent);\n const items = value\n .map((item) => `${indentStr} ${formatJsonValue(item, indent + 1)}`)\n .join(\",\\n\");\n return `${jsonSpan(\"--json-punctuation\", \"[\")}\\n${items}\\n${indentStr}${jsonSpan(\"--json-punctuation\", \"]\")}`;\n}\n\nfunction formatObject(value: object, indent: number): string {\n const entries = Object.entries(value);\n if (entries.length === 0) return jsonSpan(\"--json-punctuation\", \"{}\");\n const indentStr = \" \".repeat(indent);\n const items = entries\n .map(\n ([key, val]) =>\n `${indentStr} ${jsonSpan(\"--json-key\", `\"${escapeHtml(key)}\"`)}${jsonSpan(\"--json-punctuation\", \":\")} ${formatJsonValue(val, indent + 1)}`,\n )\n .join(\",\\n\");\n return `${jsonSpan(\"--json-punctuation\", \"{\")}\\n${items}\\n${indentStr}${jsonSpan(\"--json-punctuation\", \"}\")}`;\n}\n\nexport function formatJsonValue(value: unknown, indent = 0): string {\n const primitive = formatPrimitive(value);\n if (primitive !== null) return primitive;\n if (Array.isArray(value)) return formatArray(value, indent);\n if (typeof value === \"object\" && value !== null)\n return formatObject(value, indent);\n return jsonSpan(\"--json-fallback\", escapeHtml(String(value)));\n}\n\n/**\n * CSS custom properties for JSON syntax highlighting colors\n */\nexport const JSON_CSS_VARIABLES = {\n \"--json-key\": \"#2563eb\",\n \"--json-string\": \"#16a34a\",\n \"--json-number\": \"#ea580c\",\n \"--json-boolean\": \"#2563eb\",\n \"--json-null\": \"#64748b\",\n \"--json-punctuation\": \"#475569\",\n \"--json-fallback\": \"#6b7280\",\n} as const;\n","/**\n * Copy text to the system clipboard.\n *\n * Optionally calls `onSuccess` after a successful write. The caller\n * provides its own notification mechanism (e.g. `notification.success`\n * from the shell API) to keep this utility free of sonner or any other\n * toast dependency.\n */\nexport async function copyTextToClipboard(\n text: string,\n options?: { onSuccess?: (message: string) => void },\n): Promise<void> {\n await navigator.clipboard.writeText(text);\n options?.onSuccess?.(`${text} copied to clipboard`);\n}\n","function snakeCaseToTitleCase(snakeCase: string): string {\n const words = snakeCase.split(\"_\");\n const titleCaseWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(),\n );\n return titleCaseWords.join(\" \");\n}\n\nexport default snakeCaseToTitleCase;\n","/**\n * Error normalizer -- extract typed error info from any thrown value.\n *\n * Generic utility with no framework dependencies. Handles standard\n * Error objects and Axios-shaped error responses via duck-typing\n * (no axios import required).\n */\n\nexport interface NormalizedError {\n message: string;\n status?: number;\n details?: string[];\n}\n\n/**\n * Normalize any thrown value into a structured error object.\n *\n * Handles:\n * - Axios-shaped errors (duck-typed via `isAxiosError` property)\n * - Standard Error objects\n * - Arbitrary values (stringified)\n */\n// Extract validation detail messages from a FastAPI-style detail array.\nfunction extractDetailMessages(detail: unknown[]): string[] {\n const msgs: string[] = [];\n for (const item of detail) {\n if (\n item &&\n typeof item === \"object\" &&\n typeof (item as Record<string, unknown>).msg === \"string\"\n ) {\n msgs.push((item as Record<string, unknown>).msg as string);\n }\n }\n return msgs;\n}\n\n// Extract message and details from an Axios-like response data payload.\nfunction extractFromResponseData(\n data: unknown,\n fallback: string,\n): { message: string; details: string[] } {\n if (typeof data === \"string\") return { message: data, details: [] };\n if (typeof data !== \"object\" || data === null)\n return { message: fallback, details: [] };\n\n const d = data as Record<string, unknown>;\n if (typeof d.detail === \"string\") return { message: d.detail, details: [] };\n if (Array.isArray(d.detail)) {\n const details = extractDetailMessages(d.detail);\n return { message: details.length ? details.join(\"; \") : fallback, details };\n }\n if (typeof d.error === \"string\") return { message: d.error, details: [] };\n return { message: fallback, details: [] };\n}\n\n// Normalize an Axios-like error into a structured error object.\nfunction normalizeAxiosError(err: AxiosLikeError): NormalizedError {\n const status = err.response?.status;\n const { message, details } = extractFromResponseData(\n err.response?.data,\n err.message,\n );\n return { message, status, details: details.length ? details : undefined };\n}\n\nexport function normalizeError(err: unknown): NormalizedError {\n if (isAxiosLikeError(err)) return normalizeAxiosError(err);\n if (err instanceof Error) return { message: err.message };\n return { message: String(err) };\n}\n\n// Duck-type check for Axios-like errors.\ninterface AxiosLikeError {\n isAxiosError: true;\n message: string;\n response?: {\n status?: number;\n data?: unknown;\n };\n}\n\nfunction isAxiosLikeError(err: unknown): err is AxiosLikeError {\n return (\n err !== null &&\n typeof err === \"object\" &&\n \"isAxiosError\" in err &&\n (err as Record<string, unknown>).isAxiosError === true\n );\n}\n","import * as React from \"react\";\n\ntype PossibleRef<T> = React.Ref<T> | undefined;\n\n/**\n * Set a given ref to a given value\n * This utility takes care of different types of refs: callback refs and RefObject(s)\n */\nfunction setRef<T>(ref: PossibleRef<T>, value: T) {\n if (typeof ref === \"function\") {\n return ref(value);\n }\n\n if (ref !== null && ref !== undefined) {\n ref.current = value;\n }\n}\n\n/**\n * A utility to compose multiple refs together\n * Accepts callback refs and RefObject(s)\n */\nfunction composeRefs<T>(...refs: PossibleRef<T>[]): React.RefCallback<T> {\n return (node) => {\n let hasCleanup = false;\n const cleanups = refs.map((ref) => {\n const cleanup = setRef(ref, node);\n if (!hasCleanup && typeof cleanup === \"function\") {\n hasCleanup = true;\n }\n return cleanup;\n });\n\n // React <19 will log an error to the console if a callback ref returns a\n // value. We don't use ref cleanups internally so this will only happen if a\n // user's ref callback returns a value, which we only expect if they are\n // using the cleanup functionality added in React 19.\n if (hasCleanup) {\n return () => {\n for (let i = 0; i < cleanups.length; i++) {\n const cleanup = cleanups[i];\n if (typeof cleanup === \"function\") {\n cleanup();\n } else {\n setRef(refs[i], null);\n }\n }\n };\n }\n };\n}\n\n/**\n * A custom hook that composes multiple refs.\n * Accepts callback refs and RefObject(s).\n */\nfunction useComposedRefs<T>(...refs: PossibleRef<T>[]): React.RefCallback<T> {\n // Store the latest refs in a mutable ref so the stable callback always\n // sees the current values without needing a dynamic dependency array.\n const refsRef = React.useRef(refs);\n React.useEffect(() => {\n refsRef.current = refs;\n });\n\n return React.useCallback((node: T) => {\n composeRefs(...refsRef.current)(node);\n }, []);\n}\n\nexport { composeRefs, useComposedRefs };\n","/**\n * Resolve JSON Pointer (RFC 6901) paths to character offset ranges\n * within a formatted JSON string.\n *\n * Given a JSON string and a list of JSON Pointers, returns the\n * [from, to] byte ranges covering the *value* of each pointer.\n * The range includes the full value (object braces, array brackets,\n * string quotes, nested content) so the user can freely edit\n * everything inside.\n *\n * Zero external dependencies — pure TypeScript.\n * Maps to @petrarca/sonnet-core on extraction.\n */\n\nexport interface OffsetRange {\n /** JSON Pointer that was resolved */\n pointer: string;\n /** Start character offset (inclusive) */\n from: number;\n /** End character offset (exclusive) */\n to: number;\n}\n\n/**\n * Unescape a JSON Pointer token per RFC 6901:\n * ~1 -> /\n * ~0 -> ~\n */\nfunction unescapeToken(token: string): string {\n return token.replace(/~1/g, \"/\").replace(/~0/g, \"~\");\n}\n\n/**\n * Parse a JSON Pointer string into an array of unescaped tokens.\n * \"\" returns [] (root document, per RFC 6901)\n * \"/\" returns [] (sentinel for \"entire document\" -- treated as root)\n * \"/a/b\" returns [\"a\", \"b\"]\n */\nfunction parsePointer(pointer: string): string[] {\n if (pointer === \"\" || pointer === \"/\") return [];\n if (!pointer.startsWith(\"/\")) {\n throw new Error(`Invalid JSON Pointer: \"${pointer}\" (must start with /)`);\n }\n return pointer.slice(1).split(\"/\").map(unescapeToken);\n}\n\n/**\n * Find the character offset range of a value at the given path\n * within a JSON string. Walks the string character by character\n * to find the key, then captures the full value range.\n */\n/** Mutable cursor for walking a JSON string character by character. */\ninterface Cursor {\n pos: number;\n json: string;\n}\n\nfunction skipWs(c: Cursor): void {\n while (c.pos < c.json.length && /\\s/.test(c.json[c.pos])) c.pos++;\n}\n\nfunction skipString(c: Cursor): number {\n c.pos++; // skip opening \"\n while (c.pos < c.json.length) {\n if (c.json[c.pos] === \"\\\\\") {\n c.pos += 2;\n continue;\n }\n if (c.json[c.pos] === '\"') {\n c.pos++;\n return c.pos;\n }\n c.pos++;\n }\n return c.pos;\n}\n\nfunction skipContainer(c: Cursor, open: string, close: string): number {\n c.pos++; // skip opening bracket\n skipWs(c);\n if (c.json[c.pos] === close) {\n c.pos++;\n return c.pos;\n }\n while (c.pos < c.json.length) {\n if (open === \"{\") {\n skipValue(c); // key\n skipWs(c);\n if (c.json[c.pos] === \":\") c.pos++;\n }\n skipValue(c);\n skipWs(c);\n if (c.json[c.pos] === \",\") {\n c.pos++;\n skipWs(c);\n continue;\n }\n if (c.json[c.pos] === close) {\n c.pos++;\n return c.pos;\n }\n break;\n }\n return c.pos;\n}\n\nfunction skipValue(c: Cursor): number {\n skipWs(c);\n if (c.pos >= c.json.length) return c.pos;\n const ch = c.json[c.pos];\n if (ch === '\"') return skipString(c);\n if (ch === \"{\") return skipContainer(c, \"{\", \"}\");\n if (ch === \"[\") return skipContainer(c, \"[\", \"]\");\n // Number, bool, null -- consume until delimiter\n while (c.pos < c.json.length && !/[,\\]}\\s]/.test(c.json[c.pos])) c.pos++;\n return c.pos;\n}\n\n/** Read and return the next JSON string key, advancing past the closing quote. */\nfunction readKey(c: Cursor): string {\n const keyStart = c.pos + 1;\n c.pos++;\n while (c.pos < c.json.length) {\n if (c.json[c.pos] === \"\\\\\") {\n c.pos += 2;\n continue;\n }\n if (c.json[c.pos] === '\"') break;\n c.pos++;\n }\n const key = c.json.slice(keyStart, c.pos);\n c.pos++; // skip closing \"\n return key;\n}\n\n/** Navigate into a JSON object to the value at `token`. */\nfunction navigateObject(c: Cursor, token: string): boolean {\n c.pos++; // skip {\n skipWs(c);\n while (c.pos < c.json.length && c.json[c.pos] !== \"}\") {\n if (c.json[c.pos] !== '\"') return false;\n const key = readKey(c);\n skipWs(c);\n if (c.json[c.pos] === \":\") c.pos++;\n skipWs(c);\n if (key === token) return true;\n skipValue(c);\n skipWs(c);\n if (c.json[c.pos] === \",\") {\n c.pos++;\n skipWs(c);\n }\n }\n return false;\n}\n\n/** Navigate into a JSON array to the element at `index`. */\nfunction navigateArray(c: Cursor, index: number): boolean {\n c.pos++; // skip [\n skipWs(c);\n for (let j = 0; j < index; j++) {\n if (c.pos >= c.json.length || c.json[c.pos] === \"]\") return false;\n skipValue(c);\n skipWs(c);\n if (c.json[c.pos] === \",\") {\n c.pos++;\n skipWs(c);\n }\n }\n return true;\n}\n\nfunction findValueRange(\n json: string,\n tokens: string[],\n): { from: number; to: number } | null {\n const c: Cursor = { pos: 0, json };\n\n for (const token of tokens) {\n skipWs(c);\n if (c.json[c.pos] === \"{\") {\n if (!navigateObject(c, token)) return null;\n } else if (c.json[c.pos] === \"[\") {\n const index = parseInt(token, 10);\n if (isNaN(index) || !navigateArray(c, index)) return null;\n } else {\n return null;\n }\n }\n\n skipWs(c);\n const from = c.pos;\n const to = skipValue(c);\n return { from, to };\n}\n\n/**\n * Resolve a list of JSON Pointers to character offset ranges.\n *\n * @param json - The formatted JSON string\n * @param pointers - Array of JSON Pointer strings (e.g. \"/metadata\", \"/definitions/Patient\")\n * @returns Array of resolved ranges sorted by position (unresolvable pointers are silently skipped)\n */\nexport function resolvePointerRanges(\n json: string,\n pointers: string[],\n): OffsetRange[] {\n const ranges: OffsetRange[] = [];\n\n for (const pointer of pointers) {\n const tokens = parsePointer(pointer);\n const range = findValueRange(json, tokens);\n if (range) {\n ranges.push({ pointer, from: range.from, to: range.to });\n }\n }\n\n // Sort by position so consumers can walk ranges in document order\n ranges.sort((a, b) => a.from - b.from);\n return ranges;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/format.ts","../src/jsonUtils.ts","../src/utils/copyTextToClipboard.tsx","../src/utils/snakeCaseToTitleCase.ts","../src/errorNormalizer.ts","../src/compose-refs.ts","../src/resolvePointerRanges.ts","../src/pagination.ts"],"sourcesContent":["// Reusable formatting utilities.\n// Thin wrappers around Intl for consistent output across the app.\n\nconst numberFormatter = new Intl.NumberFormat(undefined, {\n maximumFractionDigits: 0,\n});\n\nexport function formatNumber(\n value: number | string | undefined | null,\n): string {\n if (value === null || value === undefined) return \"0\";\n const num = typeof value === \"string\" ? Number(value) : value;\n if (!Number.isFinite(num)) return String(value);\n return numberFormatter.format(num as number);\n}\n\nexport function formatNumberCompact(\n value: number | string | undefined | null,\n): string {\n if (value === null || value === undefined) return \"0\";\n const num = typeof value === \"string\" ? Number(value) : value;\n if (!Number.isFinite(num)) return String(value);\n return new Intl.NumberFormat(undefined, {\n notation: \"compact\",\n maximumFractionDigits: 1,\n }).format(num as number);\n}\n\n/** Format an ISO 8601 string as a short date (e.g. \"Jan 15, 2026\"). */\nexport function formatDate(iso: string | null | undefined): string {\n if (!iso) return \"\\u2014\";\n return new Date(iso).toLocaleDateString(undefined, {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n });\n}\n\n/** Format an ISO 8601 string as date + time (e.g. \"Jan 15, 2026, 09:32 AM\"). */\nexport function formatDateTime(iso: string | null | undefined): string {\n if (!iso) return \"\\u2014\";\n return new Date(iso).toLocaleString(undefined, {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n });\n}\n\n/**\n * Format a timezone-aware ISO 8601 string preserving the original offset.\n *\n * Parses the date/time components and offset directly from the string so\n * the emitter's local time and offset are shown exactly as recorded --\n * independent of the viewer's timezone.\n *\n * Examples:\n * \"2026-02-22T10:00:00+01:00\" -> \"22 Feb 2026 at 10:00 +01:00\"\n * \"2026-02-22T09:00:00Z\" -> \"22 Feb 2026 at 09:00 UTC\"\n */\nexport function formatDateTimeTz(iso: string | null | undefined): string {\n if (!iso) return \"\\u2014\";\n\n // Match ISO 8601: date, time (HH:MM), optional seconds, offset or Z.\n const match = iso.match(\n /^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2})(?::\\d{2}(?:\\.\\d+)?)?(Z|[+-]\\d{2}:\\d{2})$/,\n );\n if (!match) return iso;\n\n const [, year, month, day, hour, minute, rawOffset] = match;\n\n const months = [\n \"Jan\",\n \"Feb\",\n \"Mar\",\n \"Apr\",\n \"May\",\n \"Jun\",\n \"Jul\",\n \"Aug\",\n \"Sep\",\n \"Oct\",\n \"Nov\",\n \"Dec\",\n ];\n const monthName = months[parseInt(month, 10) - 1];\n const offset = rawOffset === \"Z\" ? \"UTC\" : rawOffset;\n\n return `${parseInt(day, 10)} ${monthName} ${year} at ${hour}:${minute} ${offset}`;\n}\n\n/** Return \"{count} {word}\" with the word pluralized when count != 1. */\nexport function pluralize(count: number, word: string): string {\n return `${count} ${word}${count !== 1 ? \"s\" : \"\"}`;\n}\n","/**\n * Escapes HTML characters to prevent XSS and rendering issues\n */\nexport function escapeHtml(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n}\n\n/**\n * Formats a JSON value into colored HTML with proper syntax highlighting\n * @param value - The value to format (any JSON-serializable type)\n * @param indent - Current indentation level for nested objects/arrays\n * @returns HTML string with syntax highlighting\n */\nfunction jsonSpan(cssVar: string, content: string): string {\n return `<span style=\"color: var(${cssVar})\">${content}</span>`;\n}\n\nfunction formatPrimitive(value: unknown): string | null {\n if (value === null) return jsonSpan(\"--json-null\", \"null\");\n if (typeof value === \"undefined\") return jsonSpan(\"--json-null\", \"undefined\");\n if (typeof value === \"boolean\")\n return jsonSpan(\"--json-boolean\", String(value));\n if (typeof value === \"number\")\n return jsonSpan(\"--json-number\", String(value));\n if (typeof value === \"string\")\n return jsonSpan(\"--json-string\", `\"${escapeHtml(value)}\"`);\n return null;\n}\n\nfunction formatArray(value: unknown[], indent: number): string {\n if (value.length === 0) return jsonSpan(\"--json-punctuation\", \"[]\");\n const indentStr = \" \".repeat(indent);\n const items = value\n .map((item) => `${indentStr} ${formatJsonValue(item, indent + 1)}`)\n .join(\",\\n\");\n return `${jsonSpan(\"--json-punctuation\", \"[\")}\\n${items}\\n${indentStr}${jsonSpan(\"--json-punctuation\", \"]\")}`;\n}\n\nfunction formatObject(value: object, indent: number): string {\n const entries = Object.entries(value);\n if (entries.length === 0) return jsonSpan(\"--json-punctuation\", \"{}\");\n const indentStr = \" \".repeat(indent);\n const items = entries\n .map(\n ([key, val]) =>\n `${indentStr} ${jsonSpan(\"--json-key\", `\"${escapeHtml(key)}\"`)}${jsonSpan(\"--json-punctuation\", \":\")} ${formatJsonValue(val, indent + 1)}`,\n )\n .join(\",\\n\");\n return `${jsonSpan(\"--json-punctuation\", \"{\")}\\n${items}\\n${indentStr}${jsonSpan(\"--json-punctuation\", \"}\")}`;\n}\n\nexport function formatJsonValue(value: unknown, indent = 0): string {\n const primitive = formatPrimitive(value);\n if (primitive !== null) return primitive;\n if (Array.isArray(value)) return formatArray(value, indent);\n if (typeof value === \"object\" && value !== null)\n return formatObject(value, indent);\n return jsonSpan(\"--json-fallback\", escapeHtml(String(value)));\n}\n\n/**\n * CSS custom properties for JSON syntax highlighting colors\n */\nexport const JSON_CSS_VARIABLES = {\n \"--json-key\": \"#2563eb\",\n \"--json-string\": \"#16a34a\",\n \"--json-number\": \"#ea580c\",\n \"--json-boolean\": \"#2563eb\",\n \"--json-null\": \"#64748b\",\n \"--json-punctuation\": \"#475569\",\n \"--json-fallback\": \"#6b7280\",\n} as const;\n","/**\n * Copy text to the system clipboard.\n *\n * Optionally calls `onSuccess` after a successful write. The caller\n * provides its own notification mechanism (e.g. `notification.success`\n * from the shell API) to keep this utility free of sonner or any other\n * toast dependency.\n */\nexport async function copyTextToClipboard(\n text: string,\n options?: { onSuccess?: (message: string) => void },\n): Promise<void> {\n await navigator.clipboard.writeText(text);\n options?.onSuccess?.(`${text} copied to clipboard`);\n}\n","function snakeCaseToTitleCase(snakeCase: string): string {\n const words = snakeCase.split(\"_\");\n const titleCaseWords = words.map(\n (word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(),\n );\n return titleCaseWords.join(\" \");\n}\n\nexport default snakeCaseToTitleCase;\n","/**\n * Error normalizer -- extract typed error info from any thrown value.\n *\n * Generic utility with no framework dependencies. Handles standard\n * Error objects and Axios-shaped error responses via duck-typing\n * (no axios import required).\n */\n\nexport interface NormalizedError {\n message: string;\n status?: number;\n details?: string[];\n}\n\n/**\n * Normalize any thrown value into a structured error object.\n *\n * Handles:\n * - Axios-shaped errors (duck-typed via `isAxiosError` property)\n * - Standard Error objects\n * - Arbitrary values (stringified)\n */\n// Extract validation detail messages from a FastAPI-style detail array.\nfunction extractDetailMessages(detail: unknown[]): string[] {\n const msgs: string[] = [];\n for (const item of detail) {\n if (\n item &&\n typeof item === \"object\" &&\n typeof (item as Record<string, unknown>).msg === \"string\"\n ) {\n msgs.push((item as Record<string, unknown>).msg as string);\n }\n }\n return msgs;\n}\n\n// Extract message and details from an Axios-like response data payload.\nfunction extractFromResponseData(\n data: unknown,\n fallback: string,\n): { message: string; details: string[] } {\n if (typeof data === \"string\") return { message: data, details: [] };\n if (typeof data !== \"object\" || data === null)\n return { message: fallback, details: [] };\n\n const d = data as Record<string, unknown>;\n if (typeof d.detail === \"string\") return { message: d.detail, details: [] };\n if (Array.isArray(d.detail)) {\n const details = extractDetailMessages(d.detail);\n return { message: details.length ? details.join(\"; \") : fallback, details };\n }\n if (typeof d.error === \"string\") return { message: d.error, details: [] };\n return { message: fallback, details: [] };\n}\n\n// Normalize an Axios-like error into a structured error object.\nfunction normalizeAxiosError(err: AxiosLikeError): NormalizedError {\n const status = err.response?.status;\n const { message, details } = extractFromResponseData(\n err.response?.data,\n err.message,\n );\n return { message, status, details: details.length ? details : undefined };\n}\n\nexport function normalizeError(err: unknown): NormalizedError {\n if (isAxiosLikeError(err)) return normalizeAxiosError(err);\n if (err instanceof Error) return { message: err.message };\n return { message: String(err) };\n}\n\n// Duck-type check for Axios-like errors.\ninterface AxiosLikeError {\n isAxiosError: true;\n message: string;\n response?: {\n status?: number;\n data?: unknown;\n };\n}\n\nfunction isAxiosLikeError(err: unknown): err is AxiosLikeError {\n return (\n err !== null &&\n typeof err === \"object\" &&\n \"isAxiosError\" in err &&\n (err as Record<string, unknown>).isAxiosError === true\n );\n}\n","import * as React from \"react\";\n\ntype PossibleRef<T> = React.Ref<T> | undefined;\n\n/**\n * Set a given ref to a given value\n * This utility takes care of different types of refs: callback refs and RefObject(s)\n */\nfunction setRef<T>(ref: PossibleRef<T>, value: T) {\n if (typeof ref === \"function\") {\n return ref(value);\n }\n\n if (ref !== null && ref !== undefined) {\n ref.current = value;\n }\n}\n\n/**\n * A utility to compose multiple refs together\n * Accepts callback refs and RefObject(s)\n */\nfunction composeRefs<T>(...refs: PossibleRef<T>[]): React.RefCallback<T> {\n return (node) => {\n let hasCleanup = false;\n const cleanups = refs.map((ref) => {\n const cleanup = setRef(ref, node);\n if (!hasCleanup && typeof cleanup === \"function\") {\n hasCleanup = true;\n }\n return cleanup;\n });\n\n // React <19 will log an error to the console if a callback ref returns a\n // value. We don't use ref cleanups internally so this will only happen if a\n // user's ref callback returns a value, which we only expect if they are\n // using the cleanup functionality added in React 19.\n if (hasCleanup) {\n return () => {\n for (let i = 0; i < cleanups.length; i++) {\n const cleanup = cleanups[i];\n if (typeof cleanup === \"function\") {\n cleanup();\n } else {\n setRef(refs[i], null);\n }\n }\n };\n }\n };\n}\n\n/**\n * A custom hook that composes multiple refs.\n * Accepts callback refs and RefObject(s).\n */\nfunction useComposedRefs<T>(...refs: PossibleRef<T>[]): React.RefCallback<T> {\n // Store the latest refs in a mutable ref so the stable callback always\n // sees the current values without needing a dynamic dependency array.\n const refsRef = React.useRef(refs);\n React.useEffect(() => {\n refsRef.current = refs;\n });\n\n return React.useCallback((node: T) => {\n composeRefs(...refsRef.current)(node);\n }, []);\n}\n\nexport { composeRefs, useComposedRefs };\n","/**\n * Resolve JSON Pointer (RFC 6901) paths to character offset ranges\n * within a formatted JSON string.\n *\n * Given a JSON string and a list of JSON Pointers, returns the\n * [from, to] byte ranges covering the *value* of each pointer.\n * The range includes the full value (object braces, array brackets,\n * string quotes, nested content) so the user can freely edit\n * everything inside.\n *\n * Zero external dependencies — pure TypeScript.\n * Maps to @petrarca/sonnet-core on extraction.\n */\n\nexport interface OffsetRange {\n /** JSON Pointer that was resolved */\n pointer: string;\n /** Start character offset (inclusive) */\n from: number;\n /** End character offset (exclusive) */\n to: number;\n}\n\n/**\n * Unescape a JSON Pointer token per RFC 6901:\n * ~1 -> /\n * ~0 -> ~\n */\nfunction unescapeToken(token: string): string {\n return token.replace(/~1/g, \"/\").replace(/~0/g, \"~\");\n}\n\n/**\n * Parse a JSON Pointer string into an array of unescaped tokens.\n * \"\" returns [] (root document, per RFC 6901)\n * \"/\" returns [] (sentinel for \"entire document\" -- treated as root)\n * \"/a/b\" returns [\"a\", \"b\"]\n */\nfunction parsePointer(pointer: string): string[] {\n if (pointer === \"\" || pointer === \"/\") return [];\n if (!pointer.startsWith(\"/\")) {\n throw new Error(`Invalid JSON Pointer: \"${pointer}\" (must start with /)`);\n }\n return pointer.slice(1).split(\"/\").map(unescapeToken);\n}\n\n/**\n * Find the character offset range of a value at the given path\n * within a JSON string. Walks the string character by character\n * to find the key, then captures the full value range.\n */\n/** Mutable cursor for walking a JSON string character by character. */\ninterface Cursor {\n pos: number;\n json: string;\n}\n\nfunction skipWs(c: Cursor): void {\n while (c.pos < c.json.length && /\\s/.test(c.json[c.pos])) c.pos++;\n}\n\nfunction skipString(c: Cursor): number {\n c.pos++; // skip opening \"\n while (c.pos < c.json.length) {\n if (c.json[c.pos] === \"\\\\\") {\n c.pos += 2;\n continue;\n }\n if (c.json[c.pos] === '\"') {\n c.pos++;\n return c.pos;\n }\n c.pos++;\n }\n return c.pos;\n}\n\nfunction skipContainer(c: Cursor, open: string, close: string): number {\n c.pos++; // skip opening bracket\n skipWs(c);\n if (c.json[c.pos] === close) {\n c.pos++;\n return c.pos;\n }\n while (c.pos < c.json.length) {\n if (open === \"{\") {\n skipValue(c); // key\n skipWs(c);\n if (c.json[c.pos] === \":\") c.pos++;\n }\n skipValue(c);\n skipWs(c);\n if (c.json[c.pos] === \",\") {\n c.pos++;\n skipWs(c);\n continue;\n }\n if (c.json[c.pos] === close) {\n c.pos++;\n return c.pos;\n }\n break;\n }\n return c.pos;\n}\n\nfunction skipValue(c: Cursor): number {\n skipWs(c);\n if (c.pos >= c.json.length) return c.pos;\n const ch = c.json[c.pos];\n if (ch === '\"') return skipString(c);\n if (ch === \"{\") return skipContainer(c, \"{\", \"}\");\n if (ch === \"[\") return skipContainer(c, \"[\", \"]\");\n // Number, bool, null -- consume until delimiter\n while (c.pos < c.json.length && !/[,\\]}\\s]/.test(c.json[c.pos])) c.pos++;\n return c.pos;\n}\n\n/** Read and return the next JSON string key, advancing past the closing quote. */\nfunction readKey(c: Cursor): string {\n const keyStart = c.pos + 1;\n c.pos++;\n while (c.pos < c.json.length) {\n if (c.json[c.pos] === \"\\\\\") {\n c.pos += 2;\n continue;\n }\n if (c.json[c.pos] === '\"') break;\n c.pos++;\n }\n const key = c.json.slice(keyStart, c.pos);\n c.pos++; // skip closing \"\n return key;\n}\n\n/** Navigate into a JSON object to the value at `token`. */\nfunction navigateObject(c: Cursor, token: string): boolean {\n c.pos++; // skip {\n skipWs(c);\n while (c.pos < c.json.length && c.json[c.pos] !== \"}\") {\n if (c.json[c.pos] !== '\"') return false;\n const key = readKey(c);\n skipWs(c);\n if (c.json[c.pos] === \":\") c.pos++;\n skipWs(c);\n if (key === token) return true;\n skipValue(c);\n skipWs(c);\n if (c.json[c.pos] === \",\") {\n c.pos++;\n skipWs(c);\n }\n }\n return false;\n}\n\n/** Navigate into a JSON array to the element at `index`. */\nfunction navigateArray(c: Cursor, index: number): boolean {\n c.pos++; // skip [\n skipWs(c);\n for (let j = 0; j < index; j++) {\n if (c.pos >= c.json.length || c.json[c.pos] === \"]\") return false;\n skipValue(c);\n skipWs(c);\n if (c.json[c.pos] === \",\") {\n c.pos++;\n skipWs(c);\n }\n }\n return true;\n}\n\nfunction findValueRange(\n json: string,\n tokens: string[],\n): { from: number; to: number } | null {\n const c: Cursor = { pos: 0, json };\n\n for (const token of tokens) {\n skipWs(c);\n if (c.json[c.pos] === \"{\") {\n if (!navigateObject(c, token)) return null;\n } else if (c.json[c.pos] === \"[\") {\n const index = parseInt(token, 10);\n if (isNaN(index) || !navigateArray(c, index)) return null;\n } else {\n return null;\n }\n }\n\n skipWs(c);\n const from = c.pos;\n const to = skipValue(c);\n return { from, to };\n}\n\n/**\n * Resolve a list of JSON Pointers to character offset ranges.\n *\n * @param json - The formatted JSON string\n * @param pointers - Array of JSON Pointer strings (e.g. \"/metadata\", \"/definitions/Patient\")\n * @returns Array of resolved ranges sorted by position (unresolvable pointers are silently skipped)\n */\nexport function resolvePointerRanges(\n json: string,\n pointers: string[],\n): OffsetRange[] {\n const ranges: OffsetRange[] = [];\n\n for (const pointer of pointers) {\n const tokens = parsePointer(pointer);\n const range = findValueRange(json, tokens);\n if (range) {\n ranges.push({ pointer, from: range.from, to: range.to });\n }\n }\n\n // Sort by position so consumers can walk ranges in document order\n ranges.sort((a, b) => a.from - b.from);\n return ranges;\n}\n","/**\n * Pagination types for paginated list responses.\n *\n * Generic shapes with no application-specific content.\n * Extractable to @petrarca/sonnet-core: no app-specific imports.\n */\n\n/** Pagination metadata included in paginated list responses. */\nexport interface PageMeta {\n total: number;\n limit: number;\n offset: number;\n has_next: boolean;\n has_prev: boolean;\n}\n\n/** Paginated list response envelope. */\nexport interface PageResult<T> {\n data: T[];\n meta: PageMeta;\n}\n\n/**\n * Wrap a full array as a single-page PageResult.\n *\n * Bridges \"regular\" (un-paginated) list APIs that return a bare array into the\n * PageResult envelope that paginated consumers (e.g. EntityTable) expect. The\n * whole array is treated as one complete page: total = length, offset = 0, and\n * no next/prev page. Use for small lists served without server-side pagination.\n */\nexport function toPageResult<T>(rows: T[]): PageResult<T> {\n return {\n data: rows,\n meta: {\n total: rows.length,\n limit: rows.length,\n offset: 0,\n has_next: false,\n has_prev: false,\n },\n };\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@petrarca/sonnet-core",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Shared utilities, schema tools, and hooks for the Petrarca Sonnet component library",
5
5
  "license": "Apache-2.0",
6
6
  "publishConfig": {