forked from themesberg/flowbite-svelte
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinclude-files.js
More file actions
59 lines (50 loc) · 2.23 KB
/
Copy pathinclude-files.js
File metadata and controls
59 lines (50 loc) · 2.23 KB
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
import fs from "fs";
import path from "path";
export function includeFiles({ extensions = [], docsDir = "", examplesDir = "" } = {}) {
const docsRoot = path.resolve(docsDir);
const exampleRoot = path.resolve(examplesDir);
return {
name: "include-files",
markup({ content, filename }) {
if (!filename) return { code: content };
const { dir, name, ext } = path.parse(filename);
if (!extensions.includes(ext)) return { code: content };
const relativeDir = path.relative(docsRoot, dir);
// '../abc' skip files outside of docsRoot tree
if (relativeDir[0] === ".") return { code: content };
try {
const deps = new Set();
const processedContent = content.replace(/{#include\s+([^\s}]+)}/g, (match, filepath) => {
try {
// Resolve path relative to the examples tree and enforce containment
if (path.isAbsolute(filepath)) {
console.warn(`Absolute include paths are not allowed: ${filepath}`);
return `<!-- Absolute include paths are not allowed: ${filepath} -->`;
}
const fullPath = path.resolve(exampleRoot, relativeDir, name, filepath);
const isInside = path.relative(exampleRoot, fullPath);
if (isInside.startsWith("..") || path.isAbsolute(isInside)) {
console.warn(`Include path escapes examplesDir: ${fullPath}`);
return `<!-- Include path escapes examplesDir: ${filepath} -->`;
}
// Check if file exists
if (!fs.existsSync(fullPath)) {
console.warn(`Include file not found: ${fullPath}`);
return `<!-- File not found: ${filepath} -->`;
}
const fileContent = fs.readFileSync(fullPath, "utf-8");
deps.add(fullPath);
return `${fileContent}\n`;
} catch (error) {
console.error(`Error including file ${filepath}:`, error);
return `<!-- Error including file: ${filepath} -->`;
}
});
return { code: processedContent, dependencies: Array.from(deps) };
} catch (error) {
console.error("Error in include-files preprocessor:", error);
return { code: content };
}
}
};
}