| 1 | export function virtualFiles( |
| 2 | map: Record< |
| 3 | string, |
| 4 | | string |
| 5 | | esbuild.OnLoadResult |
| 6 | | (() => Awaitable<string | esbuild.OnLoadResult>) |
| 7 | >, |
| 8 | ) { |
| 9 | return { |
| 10 | name: "clover vfs", |
| 11 | setup(b) { |
| 12 | b.onResolve( |
| 13 | { |
| 14 | filter: new RegExp( |
| 15 | `^(?:${ |
| 16 | Object.keys(map).map((file) => string.escapeRegExp(file)).join( |
| 17 | "|", |
| 18 | ) |
| 19 | })\$`, |
| 20 | ), |
| 21 | }, |
| 22 | ({ path }) => ({ path, namespace: "vfs" }), |
| 23 | ); |
| 24 | b.onLoad( |
| 25 | { filter: /./, namespace: "vfs" }, |
| 26 | async ({ path }) => { |
| 27 | let entry = map[path]; |
| 28 | if (typeof entry === "function") entry = await entry(); |
| 29 | return ({ |
| 30 | resolveDir: ".", |
| 31 | loader: "ts", |
| 32 | ...typeof entry === "string" ? { contents: entry } : entry, |
| 33 | }); |
| 34 | }, |
| 35 | ); |
| 36 | }, |
| 37 | } satisfies esbuild.Plugin; |
| 38 | } |
| 39 | |
| 40 | export function banFiles( |
| 41 | files: string[], |
| 42 | ) { |
| 43 | return { |
| 44 | name: "clover vfs", |
| 45 | setup(b) { |
| 46 | b.onResolve( |
| 47 | { |
| 48 | filter: new RegExp( |
| 49 | `^(?:${files.map((file) => string.escapeRegExp(file)).join("|")})\$`, |
| 50 | ), |
| 51 | }, |
| 52 | ({ path, importer }) => { |
| 53 | throw new Error( |
| 54 | `Loading ${path} (from ${importer}) is banned!`, |
| 55 | ); |
| 56 | }, |
| 57 | ); |
| 58 | }, |
| 59 | } satisfies esbuild.Plugin; |
| 60 | } |
| 61 | |
| 62 | export function markoViaBuildCache(): esbuild.Plugin { |
| 63 | return { |
| 64 | name: "marko via build cache", |
| 65 | setup(b) { |
| 66 | b.onLoad( |
| 67 | { filter: /\.marko$|\.mdo$/ }, |
| 68 | async ({ path: file }) => { |
| 69 | const cacheEntry = markoCache.get(file); |
| 70 | if (!cacheEntry) { |
| 71 | if (!fs.existsSync(file)) { |
| 72 | console.warn(`File does not exist: ${file}`); |
| 73 | } |
| 74 | throw new Error("Marko file not in cache: " + file); |
| 75 | } |
| 76 | return ({ |
| 77 | loader: "ts", |
| 78 | contents: cacheEntry.src, |
| 79 | resolveDir: path.dirname(file), |
| 80 | }); |
| 81 | }, |
| 82 | ); |
| 83 | }, |
| 84 | }; |
| 85 | } |
| 86 | |
| 87 | export function isIgnoredSource(source: string) { |
| 88 | return source.includes("<define:") |
| 89 | || source.startsWith("vfs:") |
| 90 | || source.startsWith("dropped:") |
| 91 | || source.includes("node_modules"); |
| 92 | } |
| 93 | |
| 94 | import * as fs from "#sitegen/fs"; |
| 95 | import * as string from "@clo/lib/string"; |
| 96 | import * as esbuild from "esbuild"; |
| 97 | import * as path from "node:path"; |
| 98 | import * as hot from "./hot.ts"; |
| 99 | import { markoCache } from "./marko.ts"; |