Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quarto-dev
GitHub Repository: quarto-dev/quarto-cli
Path: blob/main/src/core/deno/import-maps.ts
3583 views
1
/*
2
* import-maps.ts
3
*
4
* Copyright (C) 2022 Posit Software, PBC
5
*
6
*/
7
8
import { join } from "../../deno_ral/path.ts";
9
import { mergeConfigs } from "../config.ts";
10
11
const fixPath = (path: string, prefix: string) => {
12
if (prefix === "") {
13
return path;
14
}
15
if (path.startsWith("./")) {
16
//if (path.startsWith("./") && !path.endsWith("/")) {
17
return "./" + join(prefix, path.slice(2));
18
} else if (path.startsWith("../")) {
19
return `./${prefix}/${path}`;
20
}
21
return path;
22
};
23
24
function resolveImports(
25
imports: Record<string, string>,
26
): Record<string, string> {
27
const resolvedImport: Record<string, string> = {};
28
const importList = Object.entries(imports);
29
for (const [key, value] of importList) {
30
let good = false;
31
let repeat = 0;
32
let result = value;
33
do {
34
repeat++;
35
let foundK: string | undefined = undefined;
36
let foundV: string | undefined = undefined;
37
for (const [newK, newV] of importList) {
38
if (result.startsWith(newK)) {
39
if (!foundK || foundK.length < newK.length) {
40
foundK = newK;
41
foundV = newV;
42
}
43
}
44
}
45
if (foundK && foundV) {
46
result = `${foundV}${result.slice(foundK.length)}`;
47
} else {
48
if (
49
result.startsWith("./") && !result.endsWith("/") &&
50
!result.endsWith(".js") && !result.endsWith(".ts")
51
) {
52
result = result + ".js";
53
}
54
resolvedImport[key] = result;
55
good = true;
56
break;
57
}
58
} while (repeat < importList.length);
59
if (!good) {
60
throw new Error("circular import prefixes can't be resolved");
61
}
62
}
63
return resolvedImport;
64
}
65
66
function objectMap<T, U>(
67
obj: Record<string, T>,
68
f: (v: T) => U,
69
): Record<string, U> {
70
return Object.fromEntries(Object.entries(obj).map(([key, v]) => [key, f(v)]));
71
}
72
73
function objectMapReKey<T, U>(
74
obj: Record<string, T>,
75
f: (key: string, v: T) => [string, U],
76
): Record<string, U> {
77
return Object.fromEntries(Object.entries(obj).map(([key, v]) => f(key, v)));
78
}
79
80
function fixMap(map: Record<string, string>, prefix: string) {
81
return objectMap(map, (v) => fixPath(v, prefix));
82
}
83
84
function fixMapReKey(map: Record<string, string>, prefix: string) {
85
return objectMapReKey(
86
map,
87
(key, v) => [fixPath(key, prefix), fixPath(v, prefix)],
88
);
89
}
90
91
export function mergeImportMaps(
92
// deno-lint-ignore no-explicit-any
93
...entries: { importMap: any; prefix: string }[]
94
) {
95
let imports: Record<string, string> = {};
96
let scopes: Record<string, Record<string, string>> = {};
97
98
for (const { importMap, prefix } of entries) {
99
imports = mergeConfigs(imports, fixMap(importMap.imports || {}, prefix));
100
scopes = mergeConfigs(
101
scopes,
102
objectMapReKey(
103
importMap.scopes || {},
104
// deno-lint-ignore no-explicit-any
105
(key: string, v: any) => [fixPath(key, prefix), fixMapReKey(v, prefix)],
106
),
107
);
108
}
109
return {
110
imports: resolveImports(imports),
111
scopes,
112
};
113
}
114
115