forked from webiny/docs.webiny.com
-
Notifications
You must be signed in to change notification settings - Fork 0
/
AssetResolver.js
83 lines (73 loc) · 3.14 KB
/
AssetResolver.js
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
const { red } = require("chalk");
const path = require("path");
const fs = require("fs-extra");
const pretry = require("p-retry");
const versions = require("./src/data/versions.json");
const pages = require("./src/data/pages.json");
function rootify(filePath) {
return filePath.replace(process.cwd(), "");
}
/**
* This plugin rewrites asset paths to simulate inheritance. This means that assets are not duplicated, but instead,
* if several versions of the article are identical, they will all reference the same asset (image, video, etc.).
*/
module.exports.AssetResolver = class AssetResolver {
constructor() {
this.pages = Object.values(pages).flat();
}
apply(resolver) {
const target = resolver.ensureHook("resolve");
resolver
.getHook("before-resolve")
.tapAsync("ResolveFallback", async (request, resolveContext, callback) => {
if (this.isApplicable(request)) {
const obj = Object.assign({}, request, {
request: await pretry(() => this.resolveRequest(request), { retries: 5 })
});
resolver.doResolve(target, obj, null, resolveContext, callback);
} else {
return callback();
}
});
}
isApplicable(request) {
const isMdx = request.context?.issuer?.endsWith(".mdx");
if (!isMdx) {
return false;
}
return request.request.startsWith("./") || request.request.startsWith("../");
}
getSourcePage(issuer) {
const fullPath = issuer.replace(process.cwd() + "/src/pages", "").replace(".mdx", "");
return this.pages.find(page => page.fullPath === fullPath);
}
async resolveRequest(request) {
const { allVersions, latestVersion } = versions;
const page = this.getSourcePage(request.context.issuer);
if (!page) {
throw Error(`Unable to resolve page: ${request.context.issuer}`);
}
const realVersion = page?.version === "latest" ? latestVersion : page.version;
const possibleVersions = allVersions
.slice(allVersions.indexOf(realVersion))
.concat("shared");
// Try resolving every version, starting with the current page version.
// Versions are ordered in descending order by default.
// console.log(`Resolving asset "${blue(request.request)}" from "${blue(page.fullPath)}"`);
for (const version of possibleVersions) {
const versionFreePath = page.relativePath.match(/\/(?:\d+\.\d+\.\w+\/)?(.*)/)[1];
const pageDir = path.dirname(
path.join(process.cwd(), "src", "docs", version, versionFreePath)
);
const assetPath = path.join(pageDir, request.request);
if (fs.pathExistsSync(assetPath)) {
// console.log(`\t ✅ ${green(rootify(assetPath))}`);
return assetPath;
} else {
// console.log(`\t - ${gray(rootify(assetPath))}`);
}
}
console.log(`\t ❌ ${red(rootify(assetPath))}`);
return request.request;
}
};