All files / src uri.ts

100% Statements 26/26
100% Branches 13/13
100% Functions 2/2
100% Lines 26/26

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64                2x 2x                                                 2x 3582x 3582x 3582x 3582x 1008x 1008x 1008x 6x 1008x 1002x 1002x 3582x 2574x 2574x 2574x 3582x 9x 9x 3573x 3573x           2x 1047x 1047x  
/**
 * `file::group` URI parsing — a line-for-line mirror of `metacooler.uri`.
 *
 * The same syntax addresses an mmetacool entry, names a file in an error
 * message and serialises into the URL hash (spec §3.5), so all three agree by
 * construction rather than by convention.
 */
 
import { ViewerError } from './errors'
import { pyRepr } from './format'
 
/** A URI split into the file it names and the HDF5 group inside it. */
export interface ParsedUri {
  /** File path, exactly as written (never resolved or normalised). */
  path: string
  /** Absolute HDF5 group path; `'/'` for a plain `.metacool`. */
  group: string
}
 
/**
 * Split `file::group` into its two halves.
 *
 * ```
 * f.metacool                 → { path: 'f.metacool',  group: '/' }
 * f.mmetacool::entries/rep1  → { path: 'f.mmetacool', group: '/entries/rep1' }
 * f.mmetacool::              → { path: 'f.mmetacool', group: '/' }
 * ```
 *
 * Both halves are trimmed and the group is forced absolute, matching
 * `parse_uri`. Only the *first* `::` splits, so a group path may itself
 * contain one.
 *
 * @throws ViewerError `bad-uri` when the file half is empty (`''`, `'::g'`).
 */
export function parseUri(raw: string): ParsedUri {
  const sep = raw.indexOf('::')
  let path: string
  let group: string
  if (sep !== -1) {
    path = raw.slice(0, sep).trim()
    const groupPart = raw.slice(sep + 2).trim()
    if (!groupPart || groupPart === '/') {
      group = '/'
    } else {
      group = groupPart.startsWith('/') ? groupPart : `/${groupPart}`
    }
  } else {
    path = raw.trim()
    group = '/'
  }
  if (!path) {
    throw new ViewerError('bad-uri', `URI has an empty file path: ${pyRepr(raw)}`, { uri: raw })
  }
  return { path, group }
}
 
/**
 * Rebuild a URI from its halves. The inverse of {@link parseUri} for every
 * input it accepts, so a round-trip through the URL hash is stable.
 */
export function formatUri(path: string, group: string): string {
  return group === '/' ? path : `${path}::${group}`
}