UNPKG

@jsenv/import-map

Version:
140 lines (117 loc) 3.3 kB
import { assertImportMap } from "./internal/assertImportMap.js" import { tryUrlResolution } from "./internal/tryUrlResolution.js" import { resolveSpecifier } from "./resolveSpecifier.js" import { sortImports, sortScopes } from "./sortImportMap.js" export const normalizeImportMap = (importMap, baseUrl) => { assertImportMap(importMap) if (!isStringOrUrl(baseUrl)) { throw new TypeError(formulateBaseUrlMustBeStringOrUrl({ baseUrl })) } const { imports, scopes } = importMap return { imports: imports ? normalizeMappings(imports, baseUrl) : undefined, scopes: scopes ? normalizeScopes(scopes, baseUrl) : undefined, } } const isStringOrUrl = (value) => { if (typeof value === "string") { return true } if (typeof URL === "function" && value instanceof URL) { return true } return false } const normalizeMappings = (mappings, baseUrl) => { const mappingsNormalized = {} Object.keys(mappings).forEach((specifier) => { const address = mappings[specifier] if (typeof address !== "string") { console.warn( formulateAddressMustBeAString({ address, specifier, }), ) return } const specifierResolved = resolveSpecifier(specifier, baseUrl) || specifier const addressUrl = tryUrlResolution(address, baseUrl) if (addressUrl === null) { console.warn( formulateAdressResolutionFailed({ address, baseUrl, specifier, }), ) return } if (specifier.endsWith("/") && !addressUrl.endsWith("/")) { console.warn( formulateAddressUrlRequiresTrailingSlash({ addressUrl, address, specifier, }), ) return } mappingsNormalized[specifierResolved] = addressUrl }) return sortImports(mappingsNormalized) } const normalizeScopes = (scopes, baseUrl) => { const scopesNormalized = {} Object.keys(scopes).forEach((scopeSpecifier) => { const scopeMappings = scopes[scopeSpecifier] const scopeUrl = tryUrlResolution(scopeSpecifier, baseUrl) if (scopeUrl === null) { console.warn( formulateScopeResolutionFailed({ scope: scopeSpecifier, baseUrl, }), ) return } const scopeValueNormalized = normalizeMappings(scopeMappings, baseUrl) scopesNormalized[scopeUrl] = scopeValueNormalized }) return sortScopes(scopesNormalized) } const formulateBaseUrlMustBeStringOrUrl = ({ baseUrl }) => `baseUrl must be a string or an url. --- base url --- ${baseUrl}` const formulateAddressMustBeAString = ({ specifier, address }) => `Address must be a string. --- address --- ${address} --- specifier --- ${specifier}` const formulateAdressResolutionFailed = ({ address, baseUrl, specifier, }) => `Address url resolution failed. --- address --- ${address} --- base url --- ${baseUrl} --- specifier --- ${specifier}` const formulateAddressUrlRequiresTrailingSlash = ({ addressURL, address, specifier, }) => `Address must end with /. --- address url --- ${addressURL} --- address --- ${address} --- specifier --- ${specifier}` const formulateScopeResolutionFailed = ({ scope, baseUrl }) => `Scope url resolution failed. --- scope --- ${scope} --- base url --- ${baseUrl}`