{"record":{"id":"a5c96cdbd5748db7","repo":"jackwener/OpenCLI","slug":"unsupported-non-uiverse-url-raw","errorCode":null,"errorMessage":"Unsupported non-Uiverse URL: ${raw}","messagePattern":"Unsupported non-Uiverse URL: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"clis/uiverse/_shared.js","lineNumber":25,"sourceCode":"const ROUTE_DATA_KEY = 'routes/$username.$friendlyId';\nconst CODE_DATA_KEY = 'routes/resource.post.code.$id';\nconst EXPORT_TARGET_BUTTON_LABELS = ['React', 'Vue', 'Svelte', 'Lit'];\n\nfunction trimPathSegment(value) {\n  return String(value || '').trim().replace(/^\\/+|\\/+$/g, '');\n}\n\nexport function parseComponentInput(input) {\n  const raw = String(input || '').trim();\n  if (!raw) {\n    throw new Error('Missing component input. Pass a full Uiverse URL or an author/slug identifier.');\n  }\n\n  let pathname = raw;\n  if (/^https?:\\/\\//i.test(raw)) {\n    const url = new URL(raw);\n    if (url.hostname !== 'uiverse.io' && url.hostname !== 'www.uiverse.io') {\n      throw new Error(`Unsupported non-Uiverse URL: ${raw}`);\n    }\n    pathname = url.pathname;\n  }\n\n  const cleaned = trimPathSegment(pathname);\n  const segments = cleaned.split('/').filter(Boolean);\n  if (segments.length !== 2) {\n    throw new Error(`Could not parse author/slug from input: ${raw}`);\n  }\n\n  const [username, slug] = segments;\n  if (!username || !slug) {\n    throw new Error(`Invalid component identifier: ${raw}. Expected author/slug.`);\n  }\n\n  return {\n    raw,\n    username,","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/uiverse/_shared.js#L7-L43","documentation":"Thrown by parseComponentInput when the input looks like an absolute http(s) URL but its hostname is neither uiverse.io nor www.uiverse.io. The tool only fetches components from uiverse.io and refuses other hosts up front.","triggerScenarios":"Passing a URL from another site (e.g. codepen.io/..., github.com/..., localhost:3000/...) to getPostDetails or a CLI command that parses component input; pasting a URL with a typo in the domain (uiverse.com, uiversei.io); passing a URL behind a different subdomain that is not exactly 'uiverse.io' or 'www.uiverse.io' (e.g. staging.uiverse.io).","commonSituations":"Copying a component link from a different playground (CodePen, CSS-tricks snippets); using a self-hosted Uiverse clone or mirror; DNS/hosts override sending uiverse.io elsewhere so you substitute an alternate URL; corporate proxy rewrites the domain.","solutions":["Use a canonical https://uiverse.io/author/slug URL instead of the alternate host","If the URL is from another site, find the equivalent component on uiverse.io and use its URL/author-slug","Check the hostname spelling — only uiverse.io and www.uiverse.io are accepted","Remove protocol-relative or proxy-prefixed hostnames; input must be a uiverse.io URL or bare author/slug"],"exampleFix":"// before\nawait getPostDetails(page, 'https://codepen.io/user/pen/abc');\n// after\nawait getPostDetails(page, 'https://uiverse.io/pravsingh/sky-button');","handlingStrategy":"validation","validationCode":"function isUiverseUrl(input) {\n  if (!/^https?:\\/\\//i.test(input)) return true; // bare author/slug is fine\n  const { hostname } = new URL(input);\n  return hostname === 'uiverse.io' || hostname === 'www.uiverse.io';\n}\nif (!isUiverseUrl(input)) input = `https://uiverse.io/${new URL(input).pathname}`; // or reject","typeGuard":"const isUiverseHost = (url) => {\n  try { const h = new URL(url).hostname; return h === 'uiverse.io' || h === 'www.uiverse.io'; }\n  catch { return false; }\n};","tryCatchPattern":"try {\n  const details = await getPostDetails(page, input);\n} catch (e) {\n  if (e.message.startsWith('Unsupported non-Uiverse URL')) {\n    console.error('Only uiverse.io URLs are supported; got:', input);\n    process.exit(2);\n  }\n  throw e;\n}","preventionTips":["Normalize foreign URLs to their uiverse.io equivalent before calling","Whitelist-host check in wrapper code before invoking the CLI","Watch for proxy/mirror hostnames in shared config","Prefer bare author/slug identifiers in scripts to avoid host issues entirely"],"tags":["input-validation","url-parsing","domain-restriction"],"backgroundTag":"unsupported-url-host","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}