1import { assert } from "@std/assert";2import {3 ArrValue,4 type ImportResolver,5 ObjValue,6 setErrorFactory,7 State,8 Val,9 ValKind,10} from "./lib/jsonnet_web.js";1112export interface JrsonnetFrame {13 desc: string;14 path?: string;15 line?: number;16 column?: number;17}1819export class JrsonnetError extends Error {20 override name = "JrsonnetError" as const;21 frames: JrsonnetFrame[];2223 constructor(message: string, frames: JrsonnetFrame[], cause?: unknown) {24 super(message, cause !== undefined ? { cause } : undefined);25 this.frames = frames;26 }27}2829setErrorFactory(30 (message: string, frames: JrsonnetFrame[], cause: unknown) =>31 new JrsonnetError(message, frames, cause),32);3334export { ArrValue, type ImportResolver, ObjValue, State, Val, ValKind };3536export class FetchImportResolver implements ImportResolver {37 constructor(base: URL | string) {38 this.#base = new URL(base);39 }4041 #base: URL;42 #resolution = new Map<string, string>();43 #bytes = new Map<string, Uint8Array>();4445 async resolveFrom(from: string | undefined, path: string): Promise<string> {46 const base = from !== undefined ? from : this.#base;47 const requestStr = new URL(path, base).toString();4849 const cached = this.#resolution.get(requestStr);50 if (cached !== undefined) return cached;5152 const resp = await fetch(requestStr);53 if (!resp.ok) {54 throw new Error(55 `fetch ${requestStr}: HTTP ${resp.status} ${resp.statusText}`,56 );57 }58 const canonical = resp.url;59 if (!this.#bytes.has(canonical)) {60 this.#bytes.set(canonical, await resp.bytes());61 }62 this.#resolution.set(requestStr, canonical);63 return canonical;64 }6566 loadFileContents(resolved: string): Promise<Uint8Array> {67 const bytes = this.#bytes.get(resolved);68 assert(bytes, `not loaded: ${resolved}`);69 return Promise.resolve(bytes);70 }71}