All files / src url.ts

100% Statements 19/19
100% Branches 10/10
100% Functions 1/1
100% Lines 19/19

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                                                              1x   1x 1x 1x 1x 1x     12x   12x 12x   12x 12x 12x   12x 4x 4x 4x 3x   4x     12x    
/**
 * URL/env parsing that mirrors the legacy `multi/main.ls` preamble.
 *
 *   BasePath = '.' normally.
 *     If location.href contains `(127.0.0.1|localhost|*.local):8080`, BasePath
 *     becomes `http://127.0.0.1:8000` (dev Vite → same-origin EtherCalc API).
 *     If any `?auth=` param exists and BasePath is `.`, it is bumped to `..`
 *     (the page moves one path segment deeper once we push history).
 *
 *   Index (room name) = capture from `/=<index>` URL; fallback `foobar`.
 *
 *   IsReadOnly = true when `auth=0` appears anywhere in the href.
 *     When `?auth=` is present in the query, IsReadOnly narrows to match only
 *     `?auth=0` (not the bare substring).
 *
 *   Suffix = ''
 *     When `?auth=` is in the query, Suffix becomes `/view` (readonly) or
 *     `/edit` (writable). The legacy code also pushes this suffix into the
 *     history via `pushState` so reloads keep the suffix.
 */
 
export interface MultiEnv {
  readonly basePath: string;
  readonly index: string;
  readonly isReadOnly: boolean;
  readonly suffix: '' | '/view' | '/edit';
  /** Path the UI should push into window.history.pushState. Null = no push. */
  readonly pushStatePath: string | null;
}
 
/** Fallback room name when the URL doesn't match the `/=<room>` pattern. */
export const DEFAULT_INDEX = 'foobar';
 
const DEV_HOST_RE = /(?:127\.0\.0\.1|localhost|\.local):8080/;
const INDEX_RE = /\/=([^_][^/?]*)(?:\?.*)?$/;
const AUTH_IN_HREF_RE = /auth=0/;
const AUTH_QUERY_RE = /\?auth=/;
const AUTH_IS_ZERO_RE = /\??auth=0/;
 
export function parseMultiEnv(loc: { href: string; search: string }): MultiEnv {
  let basePath: string = DEV_HOST_RE.test(loc.href) ? 'http://127.0.0.1:8000' : '.';
 
  const indexMatch = INDEX_RE.exec(loc.href);
  const index = indexMatch ? (indexMatch[1] as string) : DEFAULT_INDEX;
 
  let isReadOnly = AUTH_IN_HREF_RE.test(loc.href);
  let suffix: MultiEnv['suffix'] = '';
  let pushStatePath: string | null = null;
 
  if (AUTH_QUERY_RE.test(loc.search)) {
    isReadOnly = AUTH_IS_ZERO_RE.test(loc.search);
    suffix = isReadOnly ? '/view' : '/edit';
    if (basePath === '.') {
      basePath = '..';
    }
    pushStatePath = `./=${index}${suffix}`;
  }
 
  return { basePath, index, isReadOnly, suffix, pushStatePath };
}