@rohal12/twee-ts 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/twee-ts.js +47 -32
- package/dist/bin/twee-ts.js.map +1 -1
- package/dist/{diagnostic-text-BRddVulf.cjs → diagnostic-text-Bj-UQ0Jl.cjs} +4283 -3739
- package/dist/diagnostic-text-Bj-UQ0Jl.cjs.map +1 -0
- package/dist/{diagnostic-text-CebYCTPQ.js → diagnostic-text-DMVZfBh9.js} +4260 -3770
- package/dist/diagnostic-text-DMVZfBh9.js.map +1 -0
- package/dist/index.cjs +4 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +3 -3
- package/dist/{lint-VayZI_jp.js → lint-BkpfLGuP.js} +3 -3
- package/dist/{lint-VayZI_jp.js.map → lint-BkpfLGuP.js.map} +1 -1
- package/dist/plugins/rollup.cjs +9 -4
- package/dist/plugins/rollup.cjs.map +1 -1
- package/dist/plugins/rollup.d.cts +6 -0
- package/dist/plugins/rollup.d.ts +6 -0
- package/dist/plugins/rollup.js +9 -4
- package/dist/plugins/rollup.js.map +1 -1
- package/dist/plugins/vite.cjs +453 -154
- package/dist/plugins/vite.cjs.map +1 -1
- package/dist/plugins/vite.js +453 -154
- package/dist/plugins/vite.js.map +1 -1
- package/dist/{watch-targets-C0Anuw17.cjs → watch-targets-BrEYmUwU.cjs} +84 -16
- package/dist/watch-targets-BrEYmUwU.cjs.map +1 -0
- package/dist/{watch-targets-BI7jYrwa.js → watch-targets-DzvPyWDo.js} +79 -17
- package/dist/watch-targets-DzvPyWDo.js.map +1 -0
- package/package.json +2 -2
- package/dist/diagnostic-text-BRddVulf.cjs.map +0 -1
- package/dist/diagnostic-text-CebYCTPQ.js.map +0 -1
- package/dist/watch-targets-BI7jYrwa.js.map +0 -1
- package/dist/watch-targets-C0Anuw17.cjs.map +0 -1
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
/*! @rohal12/twee-ts (Unlicense). Bundles third-party code under its own licence: see THIRD_PARTY_NOTICES. */
|
|
2
|
-
const require_diagnostic_text = require("./diagnostic-text-
|
|
2
|
+
const require_diagnostic_text = require("./diagnostic-text-Bj-UQ0Jl.cjs");
|
|
3
3
|
let node_path = require("node:path");
|
|
4
4
|
let node_fs = require("node:fs");
|
|
5
5
|
//#region src/plugins/diagnostics.ts
|
|
6
|
+
/**
|
|
7
|
+
* How the build plugins turn compile results into bundler errors and warnings.
|
|
8
|
+
*/
|
|
9
|
+
/** Text assembled here is already escaped; its diagnostic separators must survive outer reporters. */
|
|
10
|
+
var ReportedError = class extends Error {};
|
|
6
11
|
/** Returns the warnings; throws a LocatedError when the compile reported errors. */
|
|
7
12
|
function splitDiagnostics(result) {
|
|
8
13
|
const errors = result.diagnostics.filter((d) => d.level === "error");
|
|
9
14
|
if (errors.length === 0) return result.diagnostics.filter((d) => d.level === "warning");
|
|
10
|
-
const error = new
|
|
15
|
+
const error = new ReportedError(errors.map(require_diagnostic_text.formatDiagnostic).join("\n"));
|
|
11
16
|
const [first] = errors;
|
|
12
17
|
if (first?.file) {
|
|
13
|
-
|
|
18
|
+
const file = require_diagnostic_text.escapeTerminalControls(first.file);
|
|
19
|
+
error.id = file;
|
|
14
20
|
error.loc = {
|
|
15
|
-
file
|
|
21
|
+
file,
|
|
16
22
|
line: first.line ?? 1,
|
|
17
23
|
column: 1
|
|
18
24
|
};
|
|
@@ -21,25 +27,81 @@ function splitDiagnostics(result) {
|
|
|
21
27
|
}
|
|
22
28
|
/** An error thrown by the compiler or bundler, with a TweeTsError's error diagnostics folded into its message. */
|
|
23
29
|
function fatalError(e) {
|
|
24
|
-
if (e instanceof
|
|
25
|
-
|
|
26
|
-
|
|
30
|
+
if (e instanceof ReportedError) return e;
|
|
31
|
+
if (e instanceof require_diagnostic_text.TweeTsError) return new ReportedError([...e.diagnostics.filter((d) => d.level === "error").map(require_diagnostic_text.formatDiagnostic), require_diagnostic_text.escapeTerminalControls(e.message)].join("\n"));
|
|
32
|
+
const message = require_diagnostic_text.escapeTerminalControls(e instanceof Error ? e.message : String(e));
|
|
33
|
+
const located = e instanceof Error ? e : void 0;
|
|
34
|
+
const id = typeof located?.id === "string" ? require_diagnostic_text.escapeTerminalControls(located.id) : void 0;
|
|
35
|
+
const loc = located?.loc;
|
|
36
|
+
const file = typeof loc?.file === "string" ? require_diagnostic_text.escapeTerminalControls(loc.file) : void 0;
|
|
37
|
+
if (message === located?.message && id === located.id && file === loc?.file) return located;
|
|
38
|
+
const error = new ReportedError(message);
|
|
39
|
+
if (id !== void 0) error.id = id;
|
|
40
|
+
if (loc !== void 0 && file !== void 0) error.loc = {
|
|
41
|
+
...loc,
|
|
42
|
+
file
|
|
43
|
+
};
|
|
44
|
+
return error;
|
|
45
|
+
}
|
|
46
|
+
/** Files covered by directory-only entry watches, including directory links, without following cycles. */
|
|
47
|
+
function* entryFolderFiles(paths) {
|
|
48
|
+
const visited = /* @__PURE__ */ new Set();
|
|
49
|
+
function* walk(path, root) {
|
|
50
|
+
let names;
|
|
51
|
+
try {
|
|
52
|
+
const stat = (0, node_fs.statSync)(path);
|
|
53
|
+
if (!stat.isDirectory()) {
|
|
54
|
+
if (!root && stat.isFile()) yield path;
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const key = require_diagnostic_text.identify(path).key;
|
|
58
|
+
if (visited.has(key)) return;
|
|
59
|
+
visited.add(key);
|
|
60
|
+
names = (0, node_fs.readdirSync)(path);
|
|
61
|
+
} catch (e) {
|
|
62
|
+
const code = e instanceof Error && "code" in e ? e.code : void 0;
|
|
63
|
+
if (code === "ENOENT" || code === "ENOTDIR" || code === "ELOOP") return;
|
|
64
|
+
throw new Error(`Cannot inspect entry watch path ${path}: ${e instanceof Error ? e.message : String(e)}`, { cause: e });
|
|
65
|
+
}
|
|
66
|
+
for (const name of names) yield* walk((0, node_path.join)(path, name), false);
|
|
27
67
|
}
|
|
28
|
-
|
|
68
|
+
for (const path of paths) yield* walk(path, true);
|
|
29
69
|
}
|
|
30
70
|
/**
|
|
31
71
|
* Compiles the story for a plugin, leaving out what a build writes (`outputs`).
|
|
32
72
|
* `writesStory` is whether the story goes to a file (a build, not the dev server): a story path in `outputs`
|
|
33
73
|
* that holds an authored file of a source folder then fails the compile (`OUTPUT_IS_INPUT`), as a named output
|
|
34
|
-
* does.
|
|
74
|
+
* does. `entryFiles` are physical inputs (files or watched directories) the story must also never replace.
|
|
75
|
+
* Throws a LocatedError when the compile fails or reports errors.
|
|
35
76
|
*/
|
|
36
|
-
async function compileStory(options, outputs, cache, writesStory = false) {
|
|
77
|
+
async function compileStory(options, outputs, cache, writesStory = false, entryFiles = []) {
|
|
78
|
+
const inputs = [...entryFiles].map((path) => ({
|
|
79
|
+
role: "entry",
|
|
80
|
+
path
|
|
81
|
+
}));
|
|
82
|
+
const checkEntry = () => {
|
|
83
|
+
if (!writesStory) return;
|
|
84
|
+
const output = require_diagnostic_text.outputPaths({
|
|
85
|
+
files: outputs.stories ?? [],
|
|
86
|
+
dirs: []
|
|
87
|
+
}, "snapshot");
|
|
88
|
+
require_diagnostic_text.checkNamedInputs(inputs, output, []);
|
|
89
|
+
for (const path of entryFolderFiles(inputs.map((input) => input.path))) {
|
|
90
|
+
if (!output.isFile(path) || require_diagnostic_text.isOwnOutput(path) || require_diagnostic_text.isPreviousBuild(path)) continue;
|
|
91
|
+
require_diagnostic_text.checkNamedInputs([{
|
|
92
|
+
role: "entry",
|
|
93
|
+
path
|
|
94
|
+
}], output, []);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
37
97
|
let result;
|
|
38
98
|
try {
|
|
99
|
+
checkEntry();
|
|
39
100
|
result = await require_diagnostic_text.compileForOutputFile(options, writesStory ? outputs : {
|
|
40
101
|
files: outputs.files,
|
|
41
102
|
dirs: outputs.dirs
|
|
42
103
|
}, cache);
|
|
104
|
+
checkEntry();
|
|
43
105
|
} catch (e) {
|
|
44
106
|
throw fatalError(e);
|
|
45
107
|
}
|
|
@@ -240,7 +302,7 @@ function checkOptions(kind, options) {
|
|
|
240
302
|
}
|
|
241
303
|
/** Absolute forward-slash path of a path given relative to the working directory. */
|
|
242
304
|
function absolute(path) {
|
|
243
|
-
return toPosix(
|
|
305
|
+
return toPosix(require_diagnostic_text.absolutePathSpelling(path));
|
|
244
306
|
}
|
|
245
307
|
/**
|
|
246
308
|
* How the compiler spells `file` when it finds it by walking each source it is inside: the source
|
|
@@ -251,7 +313,7 @@ function spellingsUnderSources(file, sources) {
|
|
|
251
313
|
const real = require_diagnostic_text.identify(file).canonical;
|
|
252
314
|
return sources.flatMap((source) => {
|
|
253
315
|
const below = (0, node_path.relative)(require_diagnostic_text.identify(source).canonical, real);
|
|
254
|
-
return below === ".." || below.startsWith(`..${node_path.sep}`) || (0, node_path.isAbsolute)(below) ? [] : [(
|
|
316
|
+
return below === ".." || below.startsWith(`..${node_path.sep}`) || (0, node_path.isAbsolute)(below) ? [] : [`${absolute(source)}/${toPosix(below)}`];
|
|
255
317
|
});
|
|
256
318
|
}
|
|
257
319
|
/**
|
|
@@ -272,7 +334,7 @@ function resolvePluginOptions(kind, options) {
|
|
|
272
334
|
format,
|
|
273
335
|
outputFilename: options.outputFilename ?? "index.html",
|
|
274
336
|
compileOptions,
|
|
275
|
-
entry: entry === void 0 ? void 0 :
|
|
337
|
+
entry: entry === void 0 ? void 0 : require_diagnostic_text.absolutePathSpelling(entry),
|
|
276
338
|
inputs: [...sources.map(absolute), ...notExcludable],
|
|
277
339
|
excluded: (file) => exclude.length > 0 && [file, ...spellingsUnderSources(file, sources)].some((spelling) => require_diagnostic_text.isExcluded(spelling, exclude)) && !notExcludable.some((path) => require_diagnostic_text.isSameOrInside(file, path)),
|
|
278
340
|
compile: (inline = []) => ({
|
|
@@ -433,8 +495,8 @@ const MAX_LINK_HOPS = 40;
|
|
|
433
495
|
function linksOnTheWay(path) {
|
|
434
496
|
const links = [];
|
|
435
497
|
/** The names of a path or a link's target below its root; `..` is kept for the walk to take. */
|
|
436
|
-
const names = (text, root) => text.slice(root.length).split(/[/\\]/).filter((name) => name !== "" && name !== ".");
|
|
437
|
-
const start =
|
|
498
|
+
const names = (text, root) => text.slice(root.length).split(node_path.sep === "\\" ? /[/\\]/ : "/").filter((name) => name !== "" && name !== ".");
|
|
499
|
+
const start = require_diagnostic_text.absolutePathSpelling(path);
|
|
438
500
|
let reached = (0, node_path.parse)(start).root;
|
|
439
501
|
let rest = names(start, reached);
|
|
440
502
|
for (let hops = 0; rest.length > 0 && hops <= MAX_LINK_HOPS;) {
|
|
@@ -505,6 +567,12 @@ Object.defineProperty(exports, "createOutputRecord", {
|
|
|
505
567
|
return createOutputRecord;
|
|
506
568
|
}
|
|
507
569
|
});
|
|
570
|
+
Object.defineProperty(exports, "emittedFilePath", {
|
|
571
|
+
enumerable: true,
|
|
572
|
+
get: function() {
|
|
573
|
+
return emittedFilePath;
|
|
574
|
+
}
|
|
575
|
+
});
|
|
508
576
|
Object.defineProperty(exports, "fatalError", {
|
|
509
577
|
enumerable: true,
|
|
510
578
|
get: function() {
|
|
@@ -572,4 +640,4 @@ Object.defineProperty(exports, "watchTargets", {
|
|
|
572
640
|
}
|
|
573
641
|
});
|
|
574
642
|
|
|
575
|
-
//# sourceMappingURL=watch-targets-
|
|
643
|
+
//# sourceMappingURL=watch-targets-BrEYmUwU.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch-targets-BrEYmUwU.cjs","names":["formatDiagnostic","escapeTerminalControls","TweeTsError","statSync","identify","readdirSync","join","outputPaths","isOwnOutput","isPreviousBuild","compileForOutputFile","identify","isKeyInside","sep","dirname","resolve","TweeTsError","parseVersion","isRecord","compileOptionErrors","absolutePathSpelling","identify","relative","sep","isAbsolute","isExcluded","isSameOrInside","realPathOf","statSync","walkedEntry","readdirSync","join","existsSync","dirname","sep","absolutePathSpelling","parse","lstatSync","readlinkSync","isAbsolute"],"sources":["../src/plugins/diagnostics.ts","../src/plugins/paths.ts","../src/plugins/options.ts","../src/plugins/watch-targets.ts"],"sourcesContent":["/**\n * How the build plugins turn compile results into bundler errors and warnings.\n */\nimport { readdirSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { CompileOptions, CompileResult, Diagnostic, FileCacheEntry } from '../types.js';\nimport { isOwnOutput } from '../atomic-write.js';\nimport { checkNamedInputs, compileForOutputFile } from '../compiler.js';\nimport { escapeTerminalControls, formatDiagnostic } from '../diagnostic-text.js';\nimport { TweeTsError } from '../errors.js';\nimport type { BuildOutputs } from '../filesystem.js';\nimport { isPreviousBuild, outputPaths } from '../filesystem.js';\nimport { identify } from '../path-identity.js';\n\n/** An error carrying the file and line the bundler reports (and Vite shows in its overlay). */\nexport interface LocatedError extends Error {\n id?: string;\n loc?: { file: string; line: number; column: number };\n}\n\n/** Text assembled here is already escaped; its diagnostic separators must survive outer reporters. */\nclass ReportedError extends Error {}\n\n/** Returns the warnings; throws a LocatedError when the compile reported errors. */\nexport function splitDiagnostics(result: Readonly<CompileResult>): Diagnostic[] {\n const errors = result.diagnostics.filter((d) => d.level === 'error');\n if (errors.length === 0) return result.diagnostics.filter((d) => d.level === 'warning');\n const error: LocatedError = new ReportedError(errors.map(formatDiagnostic).join('\\n'));\n const [first] = errors;\n if (first?.file) {\n const file = escapeTerminalControls(first.file);\n error.id = file;\n error.loc = { file, line: first.line ?? 1, column: 1 };\n }\n throw error;\n}\n\n/** An error thrown by the compiler or bundler, with a TweeTsError's error diagnostics folded into its message. */\nexport function fatalError(e: unknown): LocatedError {\n if (e instanceof ReportedError) return e;\n if (e instanceof TweeTsError) {\n const errors = e.diagnostics.filter((d) => d.level === 'error').map(formatDiagnostic);\n return new ReportedError([...errors, escapeTerminalControls(e.message)].join('\\n'));\n }\n const message = escapeTerminalControls(e instanceof Error ? e.message : String(e));\n const located: LocatedError | undefined = e instanceof Error ? e : undefined;\n const id = typeof located?.id === 'string' ? escapeTerminalControls(located.id) : undefined;\n const loc = located?.loc;\n const file = typeof loc?.file === 'string' ? escapeTerminalControls(loc.file) : undefined;\n if (message === located?.message && id === located.id && file === loc?.file) return located;\n const error: LocatedError = new ReportedError(message);\n if (id !== undefined) error.id = id;\n if (loc !== undefined && file !== undefined) error.loc = { ...loc, file };\n return error;\n}\n\n/** A compiled story: its HTML, and its warnings as the plugins report them. */\nexport interface CompiledStory {\n readonly output: string;\n readonly warnings: readonly string[];\n}\n\n/** Files covered by directory-only entry watches, including directory links, without following cycles. */\nfunction* entryFolderFiles(paths: Iterable<string>): Generator<string> {\n const visited = new Set<string>();\n function* walk(path: string, root: boolean): Generator<string> {\n let names: string[];\n try {\n const stat = statSync(path);\n if (!stat.isDirectory()) {\n if (!root && stat.isFile()) yield path;\n return;\n }\n const key = identify(path).key;\n if (visited.has(key)) return;\n visited.add(key);\n names = readdirSync(path);\n } catch (e) {\n const code = e instanceof Error && 'code' in e ? e.code : undefined;\n // A missing target or a link loop supplied no bytes. A searchable directory may still supply a known\n // file when it cannot be listed, so permission and I/O failures must stop output verification.\n if (code === 'ENOENT' || code === 'ENOTDIR' || code === 'ELOOP') return;\n throw new Error(`Cannot inspect entry watch path ${path}: ${e instanceof Error ? e.message : String(e)}`, {\n cause: e,\n });\n }\n for (const name of names) yield* walk(join(path, name), false);\n }\n for (const path of paths) yield* walk(path, true);\n}\n\n/**\n * Compiles the story for a plugin, leaving out what a build writes (`outputs`).\n * `writesStory` is whether the story goes to a file (a build, not the dev server): a story path in `outputs`\n * that holds an authored file of a source folder then fails the compile (`OUTPUT_IS_INPUT`), as a named output\n * does. `entryFiles` are physical inputs (files or watched directories) the story must also never replace.\n * Throws a LocatedError when the compile fails or reports errors.\n */\nexport async function compileStory(\n options: CompileOptions,\n outputs: BuildOutputs,\n cache?: Map<string, FileCacheEntry>,\n writesStory = false,\n entryFiles: Iterable<string> = [],\n): Promise<CompiledStory> {\n const inputs = [...entryFiles].map((path) => ({ role: 'entry' as const, path }));\n // Only the story is protected here; overwriting bundler chunks and assets follows the bundler's policy.\n // Re-read identities after compilation too: awaiting a format may let an output link change targets.\n const checkEntry = (): void => {\n if (!writesStory) return;\n const output = outputPaths({ files: outputs.stories ?? [], dirs: [] }, 'snapshot');\n checkNamedInputs(inputs, output, []);\n for (const path of entryFolderFiles(inputs.map((input) => input.path))) {\n // A watched directory includes prior generated stories too; they remain replaceable, as in source folders.\n if (!output.isFile(path) || isOwnOutput(path) || isPreviousBuild(path)) continue;\n checkNamedInputs([{ role: 'entry', path }], output, []);\n }\n };\n let result: CompileResult;\n try {\n checkEntry();\n result = await compileForOutputFile(\n options,\n writesStory ? outputs : { files: outputs.files, dirs: outputs.dirs },\n cache,\n );\n checkEntry();\n } catch (e) {\n throw fatalError(e);\n }\n return { output: result.output, warnings: splitDiagnostics(result).map(formatDiagnostic) };\n}\n","/**\n * Path helpers for the bundler plugins. Watchers and bundlers spell one file\n * differently: macOS FSEvents reports /private/var/… for a file under /var/…,\n * Vite resolves module ids through symbolic links, Windows keeps a short 8.3\n * folder name (C:\\Users\\RUNNER~1) where another tool gives the long one, and\n * a case-insensitive volume takes any letter case. So the plugins compare\n * files by their identity key (see path-identity.ts), and spell a path they\n * hand a watcher by its canonical (real) path.\n */\nimport { dirname, resolve, sep } from 'node:path';\nimport type { BuildOutputs } from '../filesystem.js';\nimport { identify, isKeyInside } from '../path-identity.js';\n\n/** The real path of `path`, with forward slashes: how the Vite plugin spells a path it hands a watcher. */\nexport function canonicalPath(path: string): string {\n return toPosix(identify(path).canonical);\n}\n\n/** The key a file is compared by: two paths name the same file exactly when their keys are equal. */\nexport function fileKey(path: string): string {\n return identify(path).key;\n}\n\n/** Whether the file with key `key` is one of the folders (or files) with keys `within`, or inside one. */\nexport function keyWithin(key: string, within: readonly string[]): boolean {\n return within.some((outer) => isKeyInside(key, outer, sep));\n}\n\n/** The output settings that say where a bundle is written, as Rollup and Vite pass them to generateBundle. */\nexport interface OutputLocation {\n readonly dir?: string | undefined;\n readonly file?: string | undefined;\n}\n\n/**\n * The absolute path a bundle writes the file it emits as `fileName` to: inside\n * `output.dir`, or next to `output.file`, either resolved against the working\n * directory, as the bundler resolves them. Undefined when the output names\n * neither, as for a bundle only generated in memory.\n */\nexport function emittedFilePath(output: OutputLocation, fileName: string): string | undefined {\n const dir = output.dir ?? (output.file === undefined ? undefined : dirname(output.file));\n return dir === undefined ? undefined : resolve(dir, fileName);\n}\n\n/**\n * The locations a bundler's `output` option names: one output's settings or an\n * array of them, as a config gives them. Outputs that name neither `dir` nor\n * `file`, and anything that isn't an output's settings, are left out.\n */\nexport function outputLocations(option: unknown): OutputLocation[] {\n return (Array.isArray(option) ? option : [option]).flatMap((output: unknown): OutputLocation[] => {\n if (typeof output !== 'object' || output === null) return [];\n const dir: unknown = 'dir' in output ? output.dir : undefined;\n const file: unknown = 'file' in output ? output.file : undefined;\n const location = {\n ...(typeof dir === 'string' ? { dir } : {}),\n ...(typeof file === 'string' ? { file } : {}),\n };\n return location.dir === undefined && location.file === undefined ? [] : [location];\n });\n}\n\n/**\n * Every path the builds of one plugin instance write, gathered from what the\n * bundler reports: each output's location (`output.dir`, `output.file`, the\n * story inside it) and the files of each bundle written there. It is kept across\n * builds, so a compile also leaves out what another output of the same build\n * writes, before or after it, and files an earlier build wrote that the current\n * one doesn't (an old hashed chunk).\n */\nexport interface OutputRecord {\n /** Records an output location: its folder, its file, and the story it writes. */\n addLocation(output: OutputLocation): void;\n /** Records the files a bundle writes to `output`, by output file name. */\n addFiles(output: OutputLocation, fileNames: Iterable<string>): void;\n /** Every path recorded so far: `output.dir` folders as folders, the rest as files, the stories among them marked. */\n outputs(): BuildOutputs;\n}\n\n/** An empty OutputRecord for a plugin that writes its story as `storyFileName`. */\nexport function createOutputRecord(storyFileName: string): OutputRecord {\n const files = new Set<string>();\n const stories = new Set<string>();\n const dirs = new Set<string>();\n const addFiles = (output: OutputLocation, fileNames: Iterable<string>): void => {\n for (const fileName of fileNames) {\n const path = emittedFilePath(output, fileName);\n if (path !== undefined) files.add(path);\n }\n };\n return {\n addLocation(output) {\n if (output.dir !== undefined) dirs.add(resolve(output.dir));\n if (output.file !== undefined) files.add(resolve(output.file));\n addFiles(output, [storyFileName]);\n const story = emittedFilePath(output, storyFileName);\n if (story !== undefined) stories.add(story);\n },\n addFiles,\n outputs: () => ({ files: [...files], stories: [...stories], dirs: [...dirs] }),\n };\n}\n\n/**\n * The path with the platform's separators turned into forward slashes. Only Windows has a backslash separator;\n * on POSIX a backslash is an ordinary filename character and stays one.\n */\nexport function toPosix(path: string): string {\n return sep === '\\\\' ? path.replaceAll('\\\\', '/') : path;\n}\n\n/**\n * Whether `file` is a temporary copy of a Vite config file. Vite writes one next\n * to the config file each time it loads it (when no node_modules folder is\n * above the config, and always under Deno), then deletes it.\n */\nexport function isViteConfigTemp(file: string): boolean {\n return /\\.timestamp-\\d+-[0-9a-f]*\\.mjs$/.test(file);\n}\n","/**\n * The options both bundler plugins take, checked once where the plugin is\n * created and turned into what the plugin works with: the compile options of a\n * build, the files whose changes rebuild the story, and which of them\n * `compileOptions.exclude` leaves out. The Vite and the Rollup plugin share this,\n * so the same options mean the same thing in both.\n */\nimport { isAbsolute, relative, sep } from 'node:path';\nimport type { CompileOptions, InlineSource } from '../types.js';\nimport { TweeTsError } from '../errors.js';\nimport { isExcluded } from '../filesystem.js';\nimport { absolutePathSpelling, identify, isSameOrInside } from '../path-identity.js';\nimport { toPosix } from './paths.js';\nimport { parseVersion } from '../semver.js';\nimport { isRecord } from '../util.js';\nimport { compileOptionErrors } from '../compile-options.js';\n\n/**\n * The compile options a plugin passes on to the compiler. `sources` and\n * `formatId` come from the plugin's own `sources` and `format` options, so they\n * are not accepted here.\n */\nexport type PluginCompileOptions = Omit<Partial<CompileOptions>, 'sources' | 'formatId'>;\n\n/** The options both plugins take. */\nexport interface SharedPluginOptions {\n /**\n * Source directories/files to compile, relative to the working directory. The plugins take paths only: a\n * bundler watches files, so the inline sources `compile()` accepts are not supported here.\n */\n sources: readonly string[];\n /** Story format ID (`formatId` in the compile options). */\n format?: string | undefined;\n /**\n * Output file name, relative to the output folder: names separated by forward\n * slashes, without a `.` or `..` segment. Default: 'index.html'.\n */\n outputFilename?: string | undefined;\n /** Additional compile options. Set `sources` and `format` with the options above, not here. */\n compileOptions?: PluginCompileOptions | undefined;\n}\n\n/** The options the Vite plugin takes on top of the shared ones. */\ninterface EntryOption {\n entry?: string | undefined;\n}\n\n/** Which plugin the options are for, which decides the option names it accepts. */\nexport type PluginKind = 'vite' | 'rollup';\n\n/** The option names each plugin accepts. */\nconst OPTION_NAMES: Readonly<Record<PluginKind, readonly string[]>> = {\n rollup: ['sources', 'format', 'outputFilename', 'compileOptions'],\n vite: ['sources', 'format', 'outputFilename', 'compileOptions', 'entry'],\n};\n\n/** The compile options each plugin sets from an option of its own, by that option's name. */\nconst PLUGIN_SET_COMPILE_OPTIONS: readonly (readonly [string, string])[] = [\n ['sources', 'sources'],\n ['formatId', 'format'],\n];\n\n/** The options, checked and resolved. */\nexport interface ResolvedPluginOptions {\n /** The sources as given: the compiler reads them, and `exclude` globs match against them. */\n readonly sources: readonly string[];\n readonly format: string | undefined;\n readonly outputFilename: string;\n readonly compileOptions: Readonly<PluginCompileOptions>;\n /** The entry, absolute (Vite only). */\n readonly entry: string | undefined;\n /**\n * The paths whose changes rebuild the story, absolute and with forward\n * slashes: the sources, the head file and the modules.\n */\n readonly inputs: readonly string[];\n /** Whether `compileOptions.exclude` leaves a file (absolute, forward slashes) out of the story. */\n readonly excluded: (file: string) => boolean;\n /** The compile options of one build, with `inline` sources after the user's. */\n readonly compile: (inline?: readonly InlineSource[]) => CompileOptions;\n}\n\nfunction fail(kind: PluginKind, message: string): never {\n throw new TweeTsError(`twee-ts ${kind} plugin: ${message}`, [], { code: 'INVALID_OPTIONS' });\n}\n\n/** The oldest Vite the plugin works with (the `vite` peer dependency). */\nconst MINIMUM_VITE_MAJOR = 8;\n\n/**\n * Throws a TweeTsError (`INVALID_OPTIONS`) that names twee-ts and the Vite version when Vite is older than the\n * plugin supports, instead of the obscure failure an older Vite gives (a missing `index.html`, say). A version\n * that is not a SemVer version (a custom build) is accepted.\n */\nexport function checkViteVersion(viteVersion: string): void {\n const parsed = parseVersion(viteVersion);\n if (parsed === null) return;\n if (parsed.major < MINIMUM_VITE_MAJOR) {\n fail(\n 'vite',\n `Vite ${viteVersion} is not supported; the plugin needs Vite ${MINIMUM_VITE_MAJOR} or newer. ` +\n 'Upgrade Vite, or use an older twee-ts release for this Vite.',\n );\n }\n}\n\n/**\n * Characters a file name can't hold on every file system (Windows rejects\n * `<>:\"|?*`, the control characters and `\\`), and those a URL path reads\n * differently from the file name (`#`, `?`, `%`).\n */\nconst UNPORTABLE = /[\\u0000-\\u001f\\u007f<>:\"|?*#%\\\\]/;\n\n/** Names Windows reserves for devices, with or without an extension. */\nconst WINDOWS_DEVICE = /^(con|prn|aux|nul|com[0-9¹²³]|lpt[0-9¹²³])(\\..*)?$/i;\n\n/**\n * Why `name` can't be an output file name, or undefined when it can. It must be\n * a relative path: names separated by forward slashes, none of them empty, `.`\n * or `..`, nor one a file system or a URL would read differently. The bundler\n * writes it inside the output folder, and the dev server serves it at the same\n * path under the base URL.\n */\nexport function outputFilenameProblem(name: string): string | undefined {\n if (name === '') return 'it is empty';\n if (UNPORTABLE.test(name)) return 'it holds a character that is not portable in a file name or URL path';\n if (name.startsWith('/')) return 'it is an absolute path';\n const segments = name.split('/');\n if (segments.includes('')) return 'it has an empty name between slashes, or ends with a slash';\n if (segments.some((segment) => segment === '.' || segment === '..')) return 'it has a \".\" or \"..\" segment';\n if (segments.some((segment) => segment.endsWith('.') || segment.endsWith(' '))) {\n return 'a name in it ends with \".\" or a space, which Windows drops';\n }\n if (segments.some((segment) => WINDOWS_DEVICE.test(segment))) return 'a name in it is reserved on Windows';\n return undefined;\n}\n\nfunction checkString(kind: PluginKind, value: unknown, name: string): void {\n if (value !== undefined && (typeof value !== 'string' || value === '')) {\n fail(kind, `\\`${name}\\` must be a non-empty string.`);\n }\n}\n\nfunction checkStringList(kind: PluginKind, value: unknown, name: string): void {\n if (!Array.isArray(value) || value.some((item) => typeof item !== 'string' || item === '')) {\n fail(kind, `\\`${name}\\` must be an array of non-empty strings.`);\n }\n}\n\n/**\n * Checks the options as a JavaScript caller may pass them, whatever their type\n * says: an object with only the accepted option names, each of the right type.\n */\nfunction checkOptions(kind: PluginKind, options: unknown): void {\n if (!isRecord(options)) fail(kind, 'the options must be an object.');\n const accepted = OPTION_NAMES[kind];\n const unknown = Object.keys(options).filter((key) => !accepted.includes(key));\n if (unknown.length > 0) {\n const names = unknown.map((key) => `\\`${key}\\``).join(', ');\n fail(kind, `unknown option ${names}; the options are ${accepted.join(', ')}.`);\n }\n checkStringList(kind, options['sources'], 'sources');\n for (const name of ['format', 'outputFilename', 'entry']) checkString(kind, options[name], name);\n const outputFilename = options['outputFilename'];\n const problem = typeof outputFilename === 'string' ? outputFilenameProblem(outputFilename) : undefined;\n if (problem !== undefined) {\n fail(kind, `\\`outputFilename\\` ${JSON.stringify(outputFilename)} can't be used: ${problem}.`);\n }\n const compileOptions = options['compileOptions'];\n if (compileOptions === undefined) return;\n if (!isRecord(compileOptions)) fail(kind, '`compileOptions` must be an object.');\n for (const [key, own] of PLUGIN_SET_COMPILE_OPTIONS) {\n if (Object.hasOwn(compileOptions, key)) {\n fail(kind, `\\`compileOptions.${key}\\` is not accepted; set the plugin's \\`${own}\\` option instead.`);\n }\n }\n // The compiler's own check, so a compile option holds the same values here as in compile() and the config file.\n const errors = compileOptionErrors(compileOptions, [], 'compileOptions.');\n if (errors.length > 0) fail(kind, errors.join(' '));\n}\n\n/** Absolute forward-slash path of a path given relative to the working directory. */\nfunction absolute(path: string): string {\n return toPosix(absolutePathSpelling(path));\n}\n\n/**\n * How the compiler spells `file` when it finds it by walking each source it is inside: the source\n * as given, then the file's path below it. A watcher may report the real path of a file the sources\n * (and so the exclude globs) reach through a link, which the globs would otherwise not match.\n */\nfunction spellingsUnderSources(file: string, sources: readonly string[]): string[] {\n const real = identify(file).canonical;\n return sources.flatMap((source) => {\n const below = relative(identify(source).canonical, real);\n const outside = below === '..' || below.startsWith(`..${sep}`) || isAbsolute(below);\n return outside ? [] : [`${absolute(source)}/${toPosix(below)}`];\n });\n}\n\n/**\n * Checks a plugin's options and resolves them. Throws a TweeTsError naming the\n * option for anything outside what the plugin supports: an unknown option, a\n * value of the wrong type, `compileOptions.sources` or `compileOptions.formatId`\n * (the plugin's `sources` and `format` set them), or an output file name that\n * is not a plain relative path.\n */\nexport function resolvePluginOptions(\n kind: PluginKind,\n options: Readonly<SharedPluginOptions & EntryOption>,\n): ResolvedPluginOptions {\n checkOptions(kind, options);\n const { sources, format, entry } = options;\n const compileOptions: Readonly<PluginCompileOptions> = { ...options.compileOptions };\n const { headFile, modules = [], exclude = [] } = compileOptions;\n const notExcludable = [...(headFile === undefined ? [] : [headFile]), ...modules].map(absolute);\n return {\n sources: [...sources],\n format,\n outputFilename: options.outputFilename ?? 'index.html',\n compileOptions,\n entry: entry === undefined ? undefined : absolutePathSpelling(entry),\n inputs: [...sources.map(absolute), ...notExcludable],\n // `exclude` never applies to the head file and the modules.\n excluded: (file) =>\n exclude.length > 0 &&\n [file, ...spellingsUnderSources(file, sources)].some((spelling) => isExcluded(spelling, exclude)) &&\n !notExcludable.some((path) => isSameOrInside(file, path)),\n compile: (inline = []) => ({ ...compileOptions, sources: [...sources, ...inline], formatId: format }),\n };\n}\n","/**\n * What a bundler's watch mode (`rollup --watch`, `vite build --watch`) is told\n * to watch for the story, whose inputs the plugins read outside the module\n * graph. Rollup's watcher and the Rolldown watcher of later Vite 8 releases\n * watch a registered folder recursively; earlier ones see only the folder's own\n * entries. So every path is registered on its own as well.\n */\nimport { existsSync, lstatSync, readdirSync, readlinkSync, statSync } from 'node:fs';\nimport { dirname, isAbsolute, join, parse, sep } from 'node:path';\nimport { absolutePathSpelling } from '../path-identity.js';\nimport { realPathOf, walkedEntry } from '../filesystem.js';\nimport type { OutputPaths } from '../filesystem.js';\nimport { toPosix } from './paths.js';\n\n/**\n * How a target is spelt: as reached from the input (`given`, what Rollup's\n * watcher reports back), or by its real path (`real`, forward slashes), which\n * Vite's watchers report (macOS FSEvents reports a file under /var as under\n * /private/var, its real path).\n */\nexport type TargetSpelling = 'given' | 'real';\n\n/** What walking one path found: the paths to register for it, and whether the path itself is among them. */\ninterface Walked {\n readonly targets: readonly string[];\n readonly whole: boolean;\n}\n\nconst NOTHING: Walked = { targets: [], whole: false };\n\n/** What the build watch is to watch for the inputs: the paths to register, and the links the inputs are reached through. */\nexport interface WatchPlan {\n /** The paths to register with the bundler's watcher (forward slashes). */\n readonly targets: string[];\n /**\n * Every link the inputs are reached through, as authored (platform paths): each hop of a chain of links, the links\n * among the folders above an input and the links below a source folder that source discovery follows. A watcher\n * that follows links watches the end of a chain, and does not report that a link was pointed elsewhere.\n */\n readonly links: string[];\n /**\n * With `given` spelling, the real path of each target (platform paths). A watcher that follows links keeps watching\n * what a target led to when it was registered, also after a link on the way leads elsewhere, so a target whose real\n * path changed is registered by its new real path as well.\n */\n readonly reals: ReadonlyMap<string, string>;\n}\n\n/**\n * The paths to register for the inputs (forward-slash paths): every file under\n * them that source discovery reads, but those `skip` returns true for, and no\n * path the build writes (`outputs`). With `real` spelling, each link an input is reached through is registered as\n * authored too, every hop of a chain of links (see linksOnTheWay), but those that lead to a folder holding an output.\n *\n * A folder is registered, with what it holds, only when watching it reports\n * nothing the story leaves out: nothing below it is skipped (an `exclude`\n * match), is an output or holds one, or is a link to a folder (which source\n * discovery doesn't follow, and which may lead to the output). Of any other\n * folder only what it holds is registered, minus those, so writing the outputs\n * or editing an excluded file starts no build. A file added straight to such a folder is read at the next build\n * something else starts. An input that can't be read is registered as it is\n * (unless it is an output folder), so its creation may start a build; below an\n * input, what can't be read is left out, as source discovery leaves it out.\n */\nexport function watchTargets(\n inputs: readonly string[],\n skip: (file: string) => boolean,\n outputs: OutputPaths,\n spelling: TargetSpelling,\n): string[] {\n return watchPlan(inputs, skip, outputs, spelling).targets;\n}\n\n/** What watchTargets registers for the inputs, and the links they are reached through. */\nexport function watchPlan(\n inputs: readonly string[],\n skip: (file: string) => boolean,\n outputs: OutputPaths,\n spelling: TargetSpelling,\n): WatchPlan {\n const links = new Set<string>();\n /** Every link on the way to `path`, noted; those registered by real path are the ones that lead to no output. */\n const hopsOf = (path: string): string[] => {\n const hops = linksOnTheWay(path);\n for (const hop of hops) links.add(hop);\n return hops.filter((hop) => !outputs.holds(realPathOf(hop))).map(toPosix);\n };\n // By real path, each link a path is reached through is also registered as authored, every hop of a chain: replacing\n // a link changes what the input is, and only its own location sees that. A path below a folder is reached through\n // the links of the input above it, so only the links it is itself are looked for.\n // As given, a path is registered once: Rollup's watcher follows a link, watches what it leads to when the path is\n // first registered, and reports a change by the name it was given. The real path of each is noted, since a path that\n // leads elsewhere later is watched from there again (see WatchPlan.reals).\n const reals = new Map<string, string>();\n const spell = (path: string, real: string, isRoot: boolean): string[] => {\n if (spelling === 'real') return [toPosix(real), ...(isRoot || isLink(path) ? hopsOf(path) : [])];\n // A link found while walking a folder, to a file the build reads, is among the links the inputs are reached\n // through, each hop of its chain: pointing one elsewhere changes the story (#443). Links source discovery leaves\n // out (to a folder, to a file the build writes, to nothing) never get here, and are not watched (#160).\n if (!isRoot && isLink(path)) for (const hop of linksOnTheWay(path)) links.add(hop);\n // Rollup's watcher fails with an error nobody handles for a path that is a loop of links.\n if (isLoop(path)) return [];\n if (!isLoop(real)) reals.set(path, real);\n return [path];\n };\n const walk = (path: string, real: string, isRoot: boolean): Walked => {\n if (outputs.isFile(real) || (!isRoot && outputs.isDir(real))) return NOTHING;\n let entry;\n let names;\n try {\n entry = isRoot ? { stat: statSync(path), real } : walkedEntry(path, real);\n if (entry === undefined || outputs.isFile(entry.real)) return NOTHING;\n if (!entry.stat.isDirectory()) {\n return skip(path) ? NOTHING : { targets: spell(path, entry.real, isRoot), whole: true };\n }\n names = readdirSync(path);\n } catch {\n return isRoot && !outputs.isDir(real) ? { targets: spell(path, real, isRoot), whole: true } : NOTHING;\n }\n const folder = entry.real;\n const children = names.map((name) => walk(`${path}/${name}`, join(folder, name), false));\n const held = children.flatMap((child) => child.targets);\n const whole = !outputs.holds(folder) && children.every((child) => child.whole);\n return whole ? { targets: [...spell(path, folder, isRoot), ...held], whole } : { targets: held, whole };\n };\n const targets = inputs.flatMap((input) => {\n for (const link of linksOnTheWay(input)) links.add(link);\n return [\n ...(spelling === 'real' ? ancestorLinks(input, outputs) : []),\n ...walk(input, realPathOf(input), true).targets,\n ];\n });\n return { targets: [...new Set(targets)], links: [...links], reals };\n}\n\n/**\n * The paths to register, besides the real paths of the files a bundle read, so that the build watch sees what\n * changes how the entry's imports resolve: for each spelling (absolute) of an import that reaches a file through\n * links, every link on the way (see linksOnTheWay), the links a link leads through too (replacing any of them changes\n * the file the import reads); and for a spelling\n * that reaches nothing, the nearest folder that exists, where creating the file shows (a bundle that failed for a\n * missing import). A folder that holds a build output is left out, since the watcher would report what the build\n * writes there and rebuild for ever: a file created straight in it is read with the next build something else starts.\n */\nexport function importWatchTargets(authored: Iterable<string>, outputs: OutputPaths): string[] {\n const targets = new Set<string>();\n const missing: string[] = [];\n for (const spelling of authored) {\n if (existsSync(spelling)) {\n if (toPosix(realPathOf(spelling)) === toPosix(spelling)) continue;\n for (const link of linksOnTheWay(spelling)) if (!outputs.holds(realPathOf(link))) targets.add(toPosix(link));\n continue;\n }\n missing.push(spelling);\n }\n for (const folder of missingImportFolders(missing)) {\n if (!outputs.holds(realPathOf(folder))) targets.add(toPosix(folder));\n }\n return [...targets];\n}\n\n/**\n * The nearest folder that exists, for each of the paths in `authored` that reaches nothing: where creating that\n * file (or the folders above it) shows. Of a path that exists there is none, and neither is the root of a file\n * system (an absolute import such as `/missing.js`, which Vite reads from the project root first), which no watcher\n * is asked to watch whole.\n */\nexport function missingImportFolders(authored: Iterable<string>): string[] {\n const folders = new Set<string>();\n for (const spelling of authored) {\n if (existsSync(spelling)) continue;\n let folder = dirname(spelling);\n while (!existsSync(folder) && dirname(folder) !== folder) folder = dirname(folder);\n if (existsSync(folder) && dirname(folder) !== folder) folders.add(folder);\n }\n return [...folders];\n}\n\n/**\n * The links among the folders above `path`, as authored (forward slashes), every hop of a chain, in the order they are\n * followed. Replacing one of them changes what the input is, and only its own location sees that. A link directly in\n * the root of the file system (`/var` on macOS) is the system's own alias and is left out, as is a link to a folder that\n * holds a build output, since watching it whole would rebuild for what the build writes.\n */\nfunction ancestorLinks(path: string, outputs: OutputPaths): string[] {\n return linksOnTheWay(dirname(path))\n .filter((link) => !outputs.holds(realPathOf(link)))\n .map(toPosix);\n}\n\n/** How many links the file system follows for one path before it gives up (ELOOP on Linux). */\nconst MAX_LINK_HOPS = 40;\n\n/**\n * Every link the file system follows to reach `path`, in the order it follows them: each link along the path, and\n * along the target each one leads to, so every hop of a link to a link (a chain) is there. A link directly in the\n * root of the file system (`/var` on macOS) is the system's own alias and is left out. The walk ends where a name\n * reaches nothing, or after as many hops as the file system follows.\n */\nexport function linksOnTheWay(path: string): string[] {\n const links: string[] = [];\n /** The names of a path or a link's target below its root; `..` is kept for the walk to take. */\n const names = (text: string, root: string): string[] =>\n text\n .slice(root.length)\n .split(sep === '\\\\' ? /[/\\\\]/ : '/')\n .filter((name) => name !== '' && name !== '.');\n const start = absolutePathSpelling(path);\n let reached = parse(start).root;\n let rest = names(start, reached);\n for (let hops = 0; rest.length > 0 && hops <= MAX_LINK_HOPS;) {\n const [name = '', ...more] = rest;\n rest = more;\n if (name === '..') {\n // Up from where the links before it led, as the file system takes it.\n reached = dirname(reached);\n continue;\n }\n const next = join(reached, name);\n let target: string | undefined;\n try {\n target = lstatSync(next).isSymbolicLink() ? readlinkSync(next) : undefined;\n } catch {\n break; // Reaches nothing.\n }\n if (target === undefined) {\n reached = next;\n continue;\n }\n hops += 1;\n if (dirname(next) !== dirname(dirname(next))) links.push(next);\n // A relative target goes on from the folder that holds the link; an absolute one from its root.\n const root = isAbsolute(target) ? parse(target).root : '';\n if (root !== '') reached = root;\n rest = [...names(target, root), ...rest];\n }\n return links;\n}\n\n/** Whether `path` is a loop of links, which the file system gives up following (ELOOP). */\nfunction isLoop(path: string): boolean {\n try {\n statSync(path);\n return false;\n } catch (error) {\n return error instanceof Error && Reflect.get(error, 'code') === 'ELOOP';\n }\n}\n\n/** Whether `path` is a symbolic link (or a Windows junction); a path that can't be read is none. */\nfunction isLink(path: string): boolean {\n try {\n return lstatSync(path).isSymbolicLink();\n } catch {\n return false;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
/*! @rohal12/twee-ts (Unlicense). Bundles third-party code under its own licence: see THIRD_PARTY_NOTICES. */
|
|
2
|
-
import {
|
|
2
|
+
import { Mt as isRecord, W as isOwnOutput, at as outputPaths, ct as absolutePathSpelling, dt as isSameOrInside, et as parseVersion, f as compileOptionErrors, it as isPreviousBuild, lt as identify, n as formatDiagnostic, o as compileForOutputFile, ot as realPathOf, r as checkNamedInputs, rt as isExcluded, st as walkedEntry, t as escapeTerminalControls, ut as isKeyInside, wt as TweeTsError } from "./diagnostic-text-DMVZfBh9.js";
|
|
3
3
|
import { dirname, isAbsolute, join, parse, relative, resolve, sep } from "node:path";
|
|
4
4
|
import { existsSync, lstatSync, readdirSync, readlinkSync, statSync } from "node:fs";
|
|
5
5
|
//#region src/plugins/diagnostics.ts
|
|
6
|
+
/**
|
|
7
|
+
* How the build plugins turn compile results into bundler errors and warnings.
|
|
8
|
+
*/
|
|
9
|
+
/** Text assembled here is already escaped; its diagnostic separators must survive outer reporters. */
|
|
10
|
+
var ReportedError = class extends Error {};
|
|
6
11
|
/** Returns the warnings; throws a LocatedError when the compile reported errors. */
|
|
7
12
|
function splitDiagnostics(result) {
|
|
8
13
|
const errors = result.diagnostics.filter((d) => d.level === "error");
|
|
9
14
|
if (errors.length === 0) return result.diagnostics.filter((d) => d.level === "warning");
|
|
10
|
-
const error = new
|
|
15
|
+
const error = new ReportedError(errors.map(formatDiagnostic).join("\n"));
|
|
11
16
|
const [first] = errors;
|
|
12
17
|
if (first?.file) {
|
|
13
|
-
|
|
18
|
+
const file = escapeTerminalControls(first.file);
|
|
19
|
+
error.id = file;
|
|
14
20
|
error.loc = {
|
|
15
|
-
file
|
|
21
|
+
file,
|
|
16
22
|
line: first.line ?? 1,
|
|
17
23
|
column: 1
|
|
18
24
|
};
|
|
@@ -21,25 +27,81 @@ function splitDiagnostics(result) {
|
|
|
21
27
|
}
|
|
22
28
|
/** An error thrown by the compiler or bundler, with a TweeTsError's error diagnostics folded into its message. */
|
|
23
29
|
function fatalError(e) {
|
|
24
|
-
if (e instanceof
|
|
25
|
-
|
|
26
|
-
|
|
30
|
+
if (e instanceof ReportedError) return e;
|
|
31
|
+
if (e instanceof TweeTsError) return new ReportedError([...e.diagnostics.filter((d) => d.level === "error").map(formatDiagnostic), escapeTerminalControls(e.message)].join("\n"));
|
|
32
|
+
const message = escapeTerminalControls(e instanceof Error ? e.message : String(e));
|
|
33
|
+
const located = e instanceof Error ? e : void 0;
|
|
34
|
+
const id = typeof located?.id === "string" ? escapeTerminalControls(located.id) : void 0;
|
|
35
|
+
const loc = located?.loc;
|
|
36
|
+
const file = typeof loc?.file === "string" ? escapeTerminalControls(loc.file) : void 0;
|
|
37
|
+
if (message === located?.message && id === located.id && file === loc?.file) return located;
|
|
38
|
+
const error = new ReportedError(message);
|
|
39
|
+
if (id !== void 0) error.id = id;
|
|
40
|
+
if (loc !== void 0 && file !== void 0) error.loc = {
|
|
41
|
+
...loc,
|
|
42
|
+
file
|
|
43
|
+
};
|
|
44
|
+
return error;
|
|
45
|
+
}
|
|
46
|
+
/** Files covered by directory-only entry watches, including directory links, without following cycles. */
|
|
47
|
+
function* entryFolderFiles(paths) {
|
|
48
|
+
const visited = /* @__PURE__ */ new Set();
|
|
49
|
+
function* walk(path, root) {
|
|
50
|
+
let names;
|
|
51
|
+
try {
|
|
52
|
+
const stat = statSync(path);
|
|
53
|
+
if (!stat.isDirectory()) {
|
|
54
|
+
if (!root && stat.isFile()) yield path;
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const key = identify(path).key;
|
|
58
|
+
if (visited.has(key)) return;
|
|
59
|
+
visited.add(key);
|
|
60
|
+
names = readdirSync(path);
|
|
61
|
+
} catch (e) {
|
|
62
|
+
const code = e instanceof Error && "code" in e ? e.code : void 0;
|
|
63
|
+
if (code === "ENOENT" || code === "ENOTDIR" || code === "ELOOP") return;
|
|
64
|
+
throw new Error(`Cannot inspect entry watch path ${path}: ${e instanceof Error ? e.message : String(e)}`, { cause: e });
|
|
65
|
+
}
|
|
66
|
+
for (const name of names) yield* walk(join(path, name), false);
|
|
27
67
|
}
|
|
28
|
-
|
|
68
|
+
for (const path of paths) yield* walk(path, true);
|
|
29
69
|
}
|
|
30
70
|
/**
|
|
31
71
|
* Compiles the story for a plugin, leaving out what a build writes (`outputs`).
|
|
32
72
|
* `writesStory` is whether the story goes to a file (a build, not the dev server): a story path in `outputs`
|
|
33
73
|
* that holds an authored file of a source folder then fails the compile (`OUTPUT_IS_INPUT`), as a named output
|
|
34
|
-
* does.
|
|
74
|
+
* does. `entryFiles` are physical inputs (files or watched directories) the story must also never replace.
|
|
75
|
+
* Throws a LocatedError when the compile fails or reports errors.
|
|
35
76
|
*/
|
|
36
|
-
async function compileStory(options, outputs, cache, writesStory = false) {
|
|
77
|
+
async function compileStory(options, outputs, cache, writesStory = false, entryFiles = []) {
|
|
78
|
+
const inputs = [...entryFiles].map((path) => ({
|
|
79
|
+
role: "entry",
|
|
80
|
+
path
|
|
81
|
+
}));
|
|
82
|
+
const checkEntry = () => {
|
|
83
|
+
if (!writesStory) return;
|
|
84
|
+
const output = outputPaths({
|
|
85
|
+
files: outputs.stories ?? [],
|
|
86
|
+
dirs: []
|
|
87
|
+
}, "snapshot");
|
|
88
|
+
checkNamedInputs(inputs, output, []);
|
|
89
|
+
for (const path of entryFolderFiles(inputs.map((input) => input.path))) {
|
|
90
|
+
if (!output.isFile(path) || isOwnOutput(path) || isPreviousBuild(path)) continue;
|
|
91
|
+
checkNamedInputs([{
|
|
92
|
+
role: "entry",
|
|
93
|
+
path
|
|
94
|
+
}], output, []);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
37
97
|
let result;
|
|
38
98
|
try {
|
|
99
|
+
checkEntry();
|
|
39
100
|
result = await compileForOutputFile(options, writesStory ? outputs : {
|
|
40
101
|
files: outputs.files,
|
|
41
102
|
dirs: outputs.dirs
|
|
42
103
|
}, cache);
|
|
104
|
+
checkEntry();
|
|
43
105
|
} catch (e) {
|
|
44
106
|
throw fatalError(e);
|
|
45
107
|
}
|
|
@@ -240,7 +302,7 @@ function checkOptions(kind, options) {
|
|
|
240
302
|
}
|
|
241
303
|
/** Absolute forward-slash path of a path given relative to the working directory. */
|
|
242
304
|
function absolute(path) {
|
|
243
|
-
return toPosix(
|
|
305
|
+
return toPosix(absolutePathSpelling(path));
|
|
244
306
|
}
|
|
245
307
|
/**
|
|
246
308
|
* How the compiler spells `file` when it finds it by walking each source it is inside: the source
|
|
@@ -251,7 +313,7 @@ function spellingsUnderSources(file, sources) {
|
|
|
251
313
|
const real = identify(file).canonical;
|
|
252
314
|
return sources.flatMap((source) => {
|
|
253
315
|
const below = relative(identify(source).canonical, real);
|
|
254
|
-
return below === ".." || below.startsWith(`..${sep}`) || isAbsolute(below) ? [] : [
|
|
316
|
+
return below === ".." || below.startsWith(`..${sep}`) || isAbsolute(below) ? [] : [`${absolute(source)}/${toPosix(below)}`];
|
|
255
317
|
});
|
|
256
318
|
}
|
|
257
319
|
/**
|
|
@@ -272,7 +334,7 @@ function resolvePluginOptions(kind, options) {
|
|
|
272
334
|
format,
|
|
273
335
|
outputFilename: options.outputFilename ?? "index.html",
|
|
274
336
|
compileOptions,
|
|
275
|
-
entry: entry === void 0 ? void 0 :
|
|
337
|
+
entry: entry === void 0 ? void 0 : absolutePathSpelling(entry),
|
|
276
338
|
inputs: [...sources.map(absolute), ...notExcludable],
|
|
277
339
|
excluded: (file) => exclude.length > 0 && [file, ...spellingsUnderSources(file, sources)].some((spelling) => isExcluded(spelling, exclude)) && !notExcludable.some((path) => isSameOrInside(file, path)),
|
|
278
340
|
compile: (inline = []) => ({
|
|
@@ -433,8 +495,8 @@ const MAX_LINK_HOPS = 40;
|
|
|
433
495
|
function linksOnTheWay(path) {
|
|
434
496
|
const links = [];
|
|
435
497
|
/** The names of a path or a link's target below its root; `..` is kept for the walk to take. */
|
|
436
|
-
const names = (text, root) => text.slice(root.length).split(/[/\\]/).filter((name) => name !== "" && name !== ".");
|
|
437
|
-
const start =
|
|
498
|
+
const names = (text, root) => text.slice(root.length).split(sep === "\\" ? /[/\\]/ : "/").filter((name) => name !== "" && name !== ".");
|
|
499
|
+
const start = absolutePathSpelling(path);
|
|
438
500
|
let reached = parse(start).root;
|
|
439
501
|
let rest = names(start, reached);
|
|
440
502
|
for (let hops = 0; rest.length > 0 && hops <= MAX_LINK_HOPS;) {
|
|
@@ -481,6 +543,6 @@ function isLink(path) {
|
|
|
481
543
|
}
|
|
482
544
|
}
|
|
483
545
|
//#endregion
|
|
484
|
-
export { checkViteVersion as a, createOutputRecord as c,
|
|
546
|
+
export { checkViteVersion as a, createOutputRecord as c, isViteConfigTemp as d, keyWithin as f, fatalError as g, compileStory as h, watchTargets as i, emittedFilePath as l, toPosix as m, missingImportFolders as n, resolvePluginOptions as o, outputLocations as p, watchPlan as r, canonicalPath as s, importWatchTargets as t, fileKey as u };
|
|
485
547
|
|
|
486
|
-
//# sourceMappingURL=watch-targets-
|
|
548
|
+
//# sourceMappingURL=watch-targets-DzvPyWDo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch-targets-DzvPyWDo.js","names":[],"sources":["../src/plugins/diagnostics.ts","../src/plugins/paths.ts","../src/plugins/options.ts","../src/plugins/watch-targets.ts"],"sourcesContent":["/**\n * How the build plugins turn compile results into bundler errors and warnings.\n */\nimport { readdirSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { CompileOptions, CompileResult, Diagnostic, FileCacheEntry } from '../types.js';\nimport { isOwnOutput } from '../atomic-write.js';\nimport { checkNamedInputs, compileForOutputFile } from '../compiler.js';\nimport { escapeTerminalControls, formatDiagnostic } from '../diagnostic-text.js';\nimport { TweeTsError } from '../errors.js';\nimport type { BuildOutputs } from '../filesystem.js';\nimport { isPreviousBuild, outputPaths } from '../filesystem.js';\nimport { identify } from '../path-identity.js';\n\n/** An error carrying the file and line the bundler reports (and Vite shows in its overlay). */\nexport interface LocatedError extends Error {\n id?: string;\n loc?: { file: string; line: number; column: number };\n}\n\n/** Text assembled here is already escaped; its diagnostic separators must survive outer reporters. */\nclass ReportedError extends Error {}\n\n/** Returns the warnings; throws a LocatedError when the compile reported errors. */\nexport function splitDiagnostics(result: Readonly<CompileResult>): Diagnostic[] {\n const errors = result.diagnostics.filter((d) => d.level === 'error');\n if (errors.length === 0) return result.diagnostics.filter((d) => d.level === 'warning');\n const error: LocatedError = new ReportedError(errors.map(formatDiagnostic).join('\\n'));\n const [first] = errors;\n if (first?.file) {\n const file = escapeTerminalControls(first.file);\n error.id = file;\n error.loc = { file, line: first.line ?? 1, column: 1 };\n }\n throw error;\n}\n\n/** An error thrown by the compiler or bundler, with a TweeTsError's error diagnostics folded into its message. */\nexport function fatalError(e: unknown): LocatedError {\n if (e instanceof ReportedError) return e;\n if (e instanceof TweeTsError) {\n const errors = e.diagnostics.filter((d) => d.level === 'error').map(formatDiagnostic);\n return new ReportedError([...errors, escapeTerminalControls(e.message)].join('\\n'));\n }\n const message = escapeTerminalControls(e instanceof Error ? e.message : String(e));\n const located: LocatedError | undefined = e instanceof Error ? e : undefined;\n const id = typeof located?.id === 'string' ? escapeTerminalControls(located.id) : undefined;\n const loc = located?.loc;\n const file = typeof loc?.file === 'string' ? escapeTerminalControls(loc.file) : undefined;\n if (message === located?.message && id === located.id && file === loc?.file) return located;\n const error: LocatedError = new ReportedError(message);\n if (id !== undefined) error.id = id;\n if (loc !== undefined && file !== undefined) error.loc = { ...loc, file };\n return error;\n}\n\n/** A compiled story: its HTML, and its warnings as the plugins report them. */\nexport interface CompiledStory {\n readonly output: string;\n readonly warnings: readonly string[];\n}\n\n/** Files covered by directory-only entry watches, including directory links, without following cycles. */\nfunction* entryFolderFiles(paths: Iterable<string>): Generator<string> {\n const visited = new Set<string>();\n function* walk(path: string, root: boolean): Generator<string> {\n let names: string[];\n try {\n const stat = statSync(path);\n if (!stat.isDirectory()) {\n if (!root && stat.isFile()) yield path;\n return;\n }\n const key = identify(path).key;\n if (visited.has(key)) return;\n visited.add(key);\n names = readdirSync(path);\n } catch (e) {\n const code = e instanceof Error && 'code' in e ? e.code : undefined;\n // A missing target or a link loop supplied no bytes. A searchable directory may still supply a known\n // file when it cannot be listed, so permission and I/O failures must stop output verification.\n if (code === 'ENOENT' || code === 'ENOTDIR' || code === 'ELOOP') return;\n throw new Error(`Cannot inspect entry watch path ${path}: ${e instanceof Error ? e.message : String(e)}`, {\n cause: e,\n });\n }\n for (const name of names) yield* walk(join(path, name), false);\n }\n for (const path of paths) yield* walk(path, true);\n}\n\n/**\n * Compiles the story for a plugin, leaving out what a build writes (`outputs`).\n * `writesStory` is whether the story goes to a file (a build, not the dev server): a story path in `outputs`\n * that holds an authored file of a source folder then fails the compile (`OUTPUT_IS_INPUT`), as a named output\n * does. `entryFiles` are physical inputs (files or watched directories) the story must also never replace.\n * Throws a LocatedError when the compile fails or reports errors.\n */\nexport async function compileStory(\n options: CompileOptions,\n outputs: BuildOutputs,\n cache?: Map<string, FileCacheEntry>,\n writesStory = false,\n entryFiles: Iterable<string> = [],\n): Promise<CompiledStory> {\n const inputs = [...entryFiles].map((path) => ({ role: 'entry' as const, path }));\n // Only the story is protected here; overwriting bundler chunks and assets follows the bundler's policy.\n // Re-read identities after compilation too: awaiting a format may let an output link change targets.\n const checkEntry = (): void => {\n if (!writesStory) return;\n const output = outputPaths({ files: outputs.stories ?? [], dirs: [] }, 'snapshot');\n checkNamedInputs(inputs, output, []);\n for (const path of entryFolderFiles(inputs.map((input) => input.path))) {\n // A watched directory includes prior generated stories too; they remain replaceable, as in source folders.\n if (!output.isFile(path) || isOwnOutput(path) || isPreviousBuild(path)) continue;\n checkNamedInputs([{ role: 'entry', path }], output, []);\n }\n };\n let result: CompileResult;\n try {\n checkEntry();\n result = await compileForOutputFile(\n options,\n writesStory ? outputs : { files: outputs.files, dirs: outputs.dirs },\n cache,\n );\n checkEntry();\n } catch (e) {\n throw fatalError(e);\n }\n return { output: result.output, warnings: splitDiagnostics(result).map(formatDiagnostic) };\n}\n","/**\n * Path helpers for the bundler plugins. Watchers and bundlers spell one file\n * differently: macOS FSEvents reports /private/var/… for a file under /var/…,\n * Vite resolves module ids through symbolic links, Windows keeps a short 8.3\n * folder name (C:\\Users\\RUNNER~1) where another tool gives the long one, and\n * a case-insensitive volume takes any letter case. So the plugins compare\n * files by their identity key (see path-identity.ts), and spell a path they\n * hand a watcher by its canonical (real) path.\n */\nimport { dirname, resolve, sep } from 'node:path';\nimport type { BuildOutputs } from '../filesystem.js';\nimport { identify, isKeyInside } from '../path-identity.js';\n\n/** The real path of `path`, with forward slashes: how the Vite plugin spells a path it hands a watcher. */\nexport function canonicalPath(path: string): string {\n return toPosix(identify(path).canonical);\n}\n\n/** The key a file is compared by: two paths name the same file exactly when their keys are equal. */\nexport function fileKey(path: string): string {\n return identify(path).key;\n}\n\n/** Whether the file with key `key` is one of the folders (or files) with keys `within`, or inside one. */\nexport function keyWithin(key: string, within: readonly string[]): boolean {\n return within.some((outer) => isKeyInside(key, outer, sep));\n}\n\n/** The output settings that say where a bundle is written, as Rollup and Vite pass them to generateBundle. */\nexport interface OutputLocation {\n readonly dir?: string | undefined;\n readonly file?: string | undefined;\n}\n\n/**\n * The absolute path a bundle writes the file it emits as `fileName` to: inside\n * `output.dir`, or next to `output.file`, either resolved against the working\n * directory, as the bundler resolves them. Undefined when the output names\n * neither, as for a bundle only generated in memory.\n */\nexport function emittedFilePath(output: OutputLocation, fileName: string): string | undefined {\n const dir = output.dir ?? (output.file === undefined ? undefined : dirname(output.file));\n return dir === undefined ? undefined : resolve(dir, fileName);\n}\n\n/**\n * The locations a bundler's `output` option names: one output's settings or an\n * array of them, as a config gives them. Outputs that name neither `dir` nor\n * `file`, and anything that isn't an output's settings, are left out.\n */\nexport function outputLocations(option: unknown): OutputLocation[] {\n return (Array.isArray(option) ? option : [option]).flatMap((output: unknown): OutputLocation[] => {\n if (typeof output !== 'object' || output === null) return [];\n const dir: unknown = 'dir' in output ? output.dir : undefined;\n const file: unknown = 'file' in output ? output.file : undefined;\n const location = {\n ...(typeof dir === 'string' ? { dir } : {}),\n ...(typeof file === 'string' ? { file } : {}),\n };\n return location.dir === undefined && location.file === undefined ? [] : [location];\n });\n}\n\n/**\n * Every path the builds of one plugin instance write, gathered from what the\n * bundler reports: each output's location (`output.dir`, `output.file`, the\n * story inside it) and the files of each bundle written there. It is kept across\n * builds, so a compile also leaves out what another output of the same build\n * writes, before or after it, and files an earlier build wrote that the current\n * one doesn't (an old hashed chunk).\n */\nexport interface OutputRecord {\n /** Records an output location: its folder, its file, and the story it writes. */\n addLocation(output: OutputLocation): void;\n /** Records the files a bundle writes to `output`, by output file name. */\n addFiles(output: OutputLocation, fileNames: Iterable<string>): void;\n /** Every path recorded so far: `output.dir` folders as folders, the rest as files, the stories among them marked. */\n outputs(): BuildOutputs;\n}\n\n/** An empty OutputRecord for a plugin that writes its story as `storyFileName`. */\nexport function createOutputRecord(storyFileName: string): OutputRecord {\n const files = new Set<string>();\n const stories = new Set<string>();\n const dirs = new Set<string>();\n const addFiles = (output: OutputLocation, fileNames: Iterable<string>): void => {\n for (const fileName of fileNames) {\n const path = emittedFilePath(output, fileName);\n if (path !== undefined) files.add(path);\n }\n };\n return {\n addLocation(output) {\n if (output.dir !== undefined) dirs.add(resolve(output.dir));\n if (output.file !== undefined) files.add(resolve(output.file));\n addFiles(output, [storyFileName]);\n const story = emittedFilePath(output, storyFileName);\n if (story !== undefined) stories.add(story);\n },\n addFiles,\n outputs: () => ({ files: [...files], stories: [...stories], dirs: [...dirs] }),\n };\n}\n\n/**\n * The path with the platform's separators turned into forward slashes. Only Windows has a backslash separator;\n * on POSIX a backslash is an ordinary filename character and stays one.\n */\nexport function toPosix(path: string): string {\n return sep === '\\\\' ? path.replaceAll('\\\\', '/') : path;\n}\n\n/**\n * Whether `file` is a temporary copy of a Vite config file. Vite writes one next\n * to the config file each time it loads it (when no node_modules folder is\n * above the config, and always under Deno), then deletes it.\n */\nexport function isViteConfigTemp(file: string): boolean {\n return /\\.timestamp-\\d+-[0-9a-f]*\\.mjs$/.test(file);\n}\n","/**\n * The options both bundler plugins take, checked once where the plugin is\n * created and turned into what the plugin works with: the compile options of a\n * build, the files whose changes rebuild the story, and which of them\n * `compileOptions.exclude` leaves out. The Vite and the Rollup plugin share this,\n * so the same options mean the same thing in both.\n */\nimport { isAbsolute, relative, sep } from 'node:path';\nimport type { CompileOptions, InlineSource } from '../types.js';\nimport { TweeTsError } from '../errors.js';\nimport { isExcluded } from '../filesystem.js';\nimport { absolutePathSpelling, identify, isSameOrInside } from '../path-identity.js';\nimport { toPosix } from './paths.js';\nimport { parseVersion } from '../semver.js';\nimport { isRecord } from '../util.js';\nimport { compileOptionErrors } from '../compile-options.js';\n\n/**\n * The compile options a plugin passes on to the compiler. `sources` and\n * `formatId` come from the plugin's own `sources` and `format` options, so they\n * are not accepted here.\n */\nexport type PluginCompileOptions = Omit<Partial<CompileOptions>, 'sources' | 'formatId'>;\n\n/** The options both plugins take. */\nexport interface SharedPluginOptions {\n /**\n * Source directories/files to compile, relative to the working directory. The plugins take paths only: a\n * bundler watches files, so the inline sources `compile()` accepts are not supported here.\n */\n sources: readonly string[];\n /** Story format ID (`formatId` in the compile options). */\n format?: string | undefined;\n /**\n * Output file name, relative to the output folder: names separated by forward\n * slashes, without a `.` or `..` segment. Default: 'index.html'.\n */\n outputFilename?: string | undefined;\n /** Additional compile options. Set `sources` and `format` with the options above, not here. */\n compileOptions?: PluginCompileOptions | undefined;\n}\n\n/** The options the Vite plugin takes on top of the shared ones. */\ninterface EntryOption {\n entry?: string | undefined;\n}\n\n/** Which plugin the options are for, which decides the option names it accepts. */\nexport type PluginKind = 'vite' | 'rollup';\n\n/** The option names each plugin accepts. */\nconst OPTION_NAMES: Readonly<Record<PluginKind, readonly string[]>> = {\n rollup: ['sources', 'format', 'outputFilename', 'compileOptions'],\n vite: ['sources', 'format', 'outputFilename', 'compileOptions', 'entry'],\n};\n\n/** The compile options each plugin sets from an option of its own, by that option's name. */\nconst PLUGIN_SET_COMPILE_OPTIONS: readonly (readonly [string, string])[] = [\n ['sources', 'sources'],\n ['formatId', 'format'],\n];\n\n/** The options, checked and resolved. */\nexport interface ResolvedPluginOptions {\n /** The sources as given: the compiler reads them, and `exclude` globs match against them. */\n readonly sources: readonly string[];\n readonly format: string | undefined;\n readonly outputFilename: string;\n readonly compileOptions: Readonly<PluginCompileOptions>;\n /** The entry, absolute (Vite only). */\n readonly entry: string | undefined;\n /**\n * The paths whose changes rebuild the story, absolute and with forward\n * slashes: the sources, the head file and the modules.\n */\n readonly inputs: readonly string[];\n /** Whether `compileOptions.exclude` leaves a file (absolute, forward slashes) out of the story. */\n readonly excluded: (file: string) => boolean;\n /** The compile options of one build, with `inline` sources after the user's. */\n readonly compile: (inline?: readonly InlineSource[]) => CompileOptions;\n}\n\nfunction fail(kind: PluginKind, message: string): never {\n throw new TweeTsError(`twee-ts ${kind} plugin: ${message}`, [], { code: 'INVALID_OPTIONS' });\n}\n\n/** The oldest Vite the plugin works with (the `vite` peer dependency). */\nconst MINIMUM_VITE_MAJOR = 8;\n\n/**\n * Throws a TweeTsError (`INVALID_OPTIONS`) that names twee-ts and the Vite version when Vite is older than the\n * plugin supports, instead of the obscure failure an older Vite gives (a missing `index.html`, say). A version\n * that is not a SemVer version (a custom build) is accepted.\n */\nexport function checkViteVersion(viteVersion: string): void {\n const parsed = parseVersion(viteVersion);\n if (parsed === null) return;\n if (parsed.major < MINIMUM_VITE_MAJOR) {\n fail(\n 'vite',\n `Vite ${viteVersion} is not supported; the plugin needs Vite ${MINIMUM_VITE_MAJOR} or newer. ` +\n 'Upgrade Vite, or use an older twee-ts release for this Vite.',\n );\n }\n}\n\n/**\n * Characters a file name can't hold on every file system (Windows rejects\n * `<>:\"|?*`, the control characters and `\\`), and those a URL path reads\n * differently from the file name (`#`, `?`, `%`).\n */\nconst UNPORTABLE = /[\\u0000-\\u001f\\u007f<>:\"|?*#%\\\\]/;\n\n/** Names Windows reserves for devices, with or without an extension. */\nconst WINDOWS_DEVICE = /^(con|prn|aux|nul|com[0-9¹²³]|lpt[0-9¹²³])(\\..*)?$/i;\n\n/**\n * Why `name` can't be an output file name, or undefined when it can. It must be\n * a relative path: names separated by forward slashes, none of them empty, `.`\n * or `..`, nor one a file system or a URL would read differently. The bundler\n * writes it inside the output folder, and the dev server serves it at the same\n * path under the base URL.\n */\nexport function outputFilenameProblem(name: string): string | undefined {\n if (name === '') return 'it is empty';\n if (UNPORTABLE.test(name)) return 'it holds a character that is not portable in a file name or URL path';\n if (name.startsWith('/')) return 'it is an absolute path';\n const segments = name.split('/');\n if (segments.includes('')) return 'it has an empty name between slashes, or ends with a slash';\n if (segments.some((segment) => segment === '.' || segment === '..')) return 'it has a \".\" or \"..\" segment';\n if (segments.some((segment) => segment.endsWith('.') || segment.endsWith(' '))) {\n return 'a name in it ends with \".\" or a space, which Windows drops';\n }\n if (segments.some((segment) => WINDOWS_DEVICE.test(segment))) return 'a name in it is reserved on Windows';\n return undefined;\n}\n\nfunction checkString(kind: PluginKind, value: unknown, name: string): void {\n if (value !== undefined && (typeof value !== 'string' || value === '')) {\n fail(kind, `\\`${name}\\` must be a non-empty string.`);\n }\n}\n\nfunction checkStringList(kind: PluginKind, value: unknown, name: string): void {\n if (!Array.isArray(value) || value.some((item) => typeof item !== 'string' || item === '')) {\n fail(kind, `\\`${name}\\` must be an array of non-empty strings.`);\n }\n}\n\n/**\n * Checks the options as a JavaScript caller may pass them, whatever their type\n * says: an object with only the accepted option names, each of the right type.\n */\nfunction checkOptions(kind: PluginKind, options: unknown): void {\n if (!isRecord(options)) fail(kind, 'the options must be an object.');\n const accepted = OPTION_NAMES[kind];\n const unknown = Object.keys(options).filter((key) => !accepted.includes(key));\n if (unknown.length > 0) {\n const names = unknown.map((key) => `\\`${key}\\``).join(', ');\n fail(kind, `unknown option ${names}; the options are ${accepted.join(', ')}.`);\n }\n checkStringList(kind, options['sources'], 'sources');\n for (const name of ['format', 'outputFilename', 'entry']) checkString(kind, options[name], name);\n const outputFilename = options['outputFilename'];\n const problem = typeof outputFilename === 'string' ? outputFilenameProblem(outputFilename) : undefined;\n if (problem !== undefined) {\n fail(kind, `\\`outputFilename\\` ${JSON.stringify(outputFilename)} can't be used: ${problem}.`);\n }\n const compileOptions = options['compileOptions'];\n if (compileOptions === undefined) return;\n if (!isRecord(compileOptions)) fail(kind, '`compileOptions` must be an object.');\n for (const [key, own] of PLUGIN_SET_COMPILE_OPTIONS) {\n if (Object.hasOwn(compileOptions, key)) {\n fail(kind, `\\`compileOptions.${key}\\` is not accepted; set the plugin's \\`${own}\\` option instead.`);\n }\n }\n // The compiler's own check, so a compile option holds the same values here as in compile() and the config file.\n const errors = compileOptionErrors(compileOptions, [], 'compileOptions.');\n if (errors.length > 0) fail(kind, errors.join(' '));\n}\n\n/** Absolute forward-slash path of a path given relative to the working directory. */\nfunction absolute(path: string): string {\n return toPosix(absolutePathSpelling(path));\n}\n\n/**\n * How the compiler spells `file` when it finds it by walking each source it is inside: the source\n * as given, then the file's path below it. A watcher may report the real path of a file the sources\n * (and so the exclude globs) reach through a link, which the globs would otherwise not match.\n */\nfunction spellingsUnderSources(file: string, sources: readonly string[]): string[] {\n const real = identify(file).canonical;\n return sources.flatMap((source) => {\n const below = relative(identify(source).canonical, real);\n const outside = below === '..' || below.startsWith(`..${sep}`) || isAbsolute(below);\n return outside ? [] : [`${absolute(source)}/${toPosix(below)}`];\n });\n}\n\n/**\n * Checks a plugin's options and resolves them. Throws a TweeTsError naming the\n * option for anything outside what the plugin supports: an unknown option, a\n * value of the wrong type, `compileOptions.sources` or `compileOptions.formatId`\n * (the plugin's `sources` and `format` set them), or an output file name that\n * is not a plain relative path.\n */\nexport function resolvePluginOptions(\n kind: PluginKind,\n options: Readonly<SharedPluginOptions & EntryOption>,\n): ResolvedPluginOptions {\n checkOptions(kind, options);\n const { sources, format, entry } = options;\n const compileOptions: Readonly<PluginCompileOptions> = { ...options.compileOptions };\n const { headFile, modules = [], exclude = [] } = compileOptions;\n const notExcludable = [...(headFile === undefined ? [] : [headFile]), ...modules].map(absolute);\n return {\n sources: [...sources],\n format,\n outputFilename: options.outputFilename ?? 'index.html',\n compileOptions,\n entry: entry === undefined ? undefined : absolutePathSpelling(entry),\n inputs: [...sources.map(absolute), ...notExcludable],\n // `exclude` never applies to the head file and the modules.\n excluded: (file) =>\n exclude.length > 0 &&\n [file, ...spellingsUnderSources(file, sources)].some((spelling) => isExcluded(spelling, exclude)) &&\n !notExcludable.some((path) => isSameOrInside(file, path)),\n compile: (inline = []) => ({ ...compileOptions, sources: [...sources, ...inline], formatId: format }),\n };\n}\n","/**\n * What a bundler's watch mode (`rollup --watch`, `vite build --watch`) is told\n * to watch for the story, whose inputs the plugins read outside the module\n * graph. Rollup's watcher and the Rolldown watcher of later Vite 8 releases\n * watch a registered folder recursively; earlier ones see only the folder's own\n * entries. So every path is registered on its own as well.\n */\nimport { existsSync, lstatSync, readdirSync, readlinkSync, statSync } from 'node:fs';\nimport { dirname, isAbsolute, join, parse, sep } from 'node:path';\nimport { absolutePathSpelling } from '../path-identity.js';\nimport { realPathOf, walkedEntry } from '../filesystem.js';\nimport type { OutputPaths } from '../filesystem.js';\nimport { toPosix } from './paths.js';\n\n/**\n * How a target is spelt: as reached from the input (`given`, what Rollup's\n * watcher reports back), or by its real path (`real`, forward slashes), which\n * Vite's watchers report (macOS FSEvents reports a file under /var as under\n * /private/var, its real path).\n */\nexport type TargetSpelling = 'given' | 'real';\n\n/** What walking one path found: the paths to register for it, and whether the path itself is among them. */\ninterface Walked {\n readonly targets: readonly string[];\n readonly whole: boolean;\n}\n\nconst NOTHING: Walked = { targets: [], whole: false };\n\n/** What the build watch is to watch for the inputs: the paths to register, and the links the inputs are reached through. */\nexport interface WatchPlan {\n /** The paths to register with the bundler's watcher (forward slashes). */\n readonly targets: string[];\n /**\n * Every link the inputs are reached through, as authored (platform paths): each hop of a chain of links, the links\n * among the folders above an input and the links below a source folder that source discovery follows. A watcher\n * that follows links watches the end of a chain, and does not report that a link was pointed elsewhere.\n */\n readonly links: string[];\n /**\n * With `given` spelling, the real path of each target (platform paths). A watcher that follows links keeps watching\n * what a target led to when it was registered, also after a link on the way leads elsewhere, so a target whose real\n * path changed is registered by its new real path as well.\n */\n readonly reals: ReadonlyMap<string, string>;\n}\n\n/**\n * The paths to register for the inputs (forward-slash paths): every file under\n * them that source discovery reads, but those `skip` returns true for, and no\n * path the build writes (`outputs`). With `real` spelling, each link an input is reached through is registered as\n * authored too, every hop of a chain of links (see linksOnTheWay), but those that lead to a folder holding an output.\n *\n * A folder is registered, with what it holds, only when watching it reports\n * nothing the story leaves out: nothing below it is skipped (an `exclude`\n * match), is an output or holds one, or is a link to a folder (which source\n * discovery doesn't follow, and which may lead to the output). Of any other\n * folder only what it holds is registered, minus those, so writing the outputs\n * or editing an excluded file starts no build. A file added straight to such a folder is read at the next build\n * something else starts. An input that can't be read is registered as it is\n * (unless it is an output folder), so its creation may start a build; below an\n * input, what can't be read is left out, as source discovery leaves it out.\n */\nexport function watchTargets(\n inputs: readonly string[],\n skip: (file: string) => boolean,\n outputs: OutputPaths,\n spelling: TargetSpelling,\n): string[] {\n return watchPlan(inputs, skip, outputs, spelling).targets;\n}\n\n/** What watchTargets registers for the inputs, and the links they are reached through. */\nexport function watchPlan(\n inputs: readonly string[],\n skip: (file: string) => boolean,\n outputs: OutputPaths,\n spelling: TargetSpelling,\n): WatchPlan {\n const links = new Set<string>();\n /** Every link on the way to `path`, noted; those registered by real path are the ones that lead to no output. */\n const hopsOf = (path: string): string[] => {\n const hops = linksOnTheWay(path);\n for (const hop of hops) links.add(hop);\n return hops.filter((hop) => !outputs.holds(realPathOf(hop))).map(toPosix);\n };\n // By real path, each link a path is reached through is also registered as authored, every hop of a chain: replacing\n // a link changes what the input is, and only its own location sees that. A path below a folder is reached through\n // the links of the input above it, so only the links it is itself are looked for.\n // As given, a path is registered once: Rollup's watcher follows a link, watches what it leads to when the path is\n // first registered, and reports a change by the name it was given. The real path of each is noted, since a path that\n // leads elsewhere later is watched from there again (see WatchPlan.reals).\n const reals = new Map<string, string>();\n const spell = (path: string, real: string, isRoot: boolean): string[] => {\n if (spelling === 'real') return [toPosix(real), ...(isRoot || isLink(path) ? hopsOf(path) : [])];\n // A link found while walking a folder, to a file the build reads, is among the links the inputs are reached\n // through, each hop of its chain: pointing one elsewhere changes the story (#443). Links source discovery leaves\n // out (to a folder, to a file the build writes, to nothing) never get here, and are not watched (#160).\n if (!isRoot && isLink(path)) for (const hop of linksOnTheWay(path)) links.add(hop);\n // Rollup's watcher fails with an error nobody handles for a path that is a loop of links.\n if (isLoop(path)) return [];\n if (!isLoop(real)) reals.set(path, real);\n return [path];\n };\n const walk = (path: string, real: string, isRoot: boolean): Walked => {\n if (outputs.isFile(real) || (!isRoot && outputs.isDir(real))) return NOTHING;\n let entry;\n let names;\n try {\n entry = isRoot ? { stat: statSync(path), real } : walkedEntry(path, real);\n if (entry === undefined || outputs.isFile(entry.real)) return NOTHING;\n if (!entry.stat.isDirectory()) {\n return skip(path) ? NOTHING : { targets: spell(path, entry.real, isRoot), whole: true };\n }\n names = readdirSync(path);\n } catch {\n return isRoot && !outputs.isDir(real) ? { targets: spell(path, real, isRoot), whole: true } : NOTHING;\n }\n const folder = entry.real;\n const children = names.map((name) => walk(`${path}/${name}`, join(folder, name), false));\n const held = children.flatMap((child) => child.targets);\n const whole = !outputs.holds(folder) && children.every((child) => child.whole);\n return whole ? { targets: [...spell(path, folder, isRoot), ...held], whole } : { targets: held, whole };\n };\n const targets = inputs.flatMap((input) => {\n for (const link of linksOnTheWay(input)) links.add(link);\n return [\n ...(spelling === 'real' ? ancestorLinks(input, outputs) : []),\n ...walk(input, realPathOf(input), true).targets,\n ];\n });\n return { targets: [...new Set(targets)], links: [...links], reals };\n}\n\n/**\n * The paths to register, besides the real paths of the files a bundle read, so that the build watch sees what\n * changes how the entry's imports resolve: for each spelling (absolute) of an import that reaches a file through\n * links, every link on the way (see linksOnTheWay), the links a link leads through too (replacing any of them changes\n * the file the import reads); and for a spelling\n * that reaches nothing, the nearest folder that exists, where creating the file shows (a bundle that failed for a\n * missing import). A folder that holds a build output is left out, since the watcher would report what the build\n * writes there and rebuild for ever: a file created straight in it is read with the next build something else starts.\n */\nexport function importWatchTargets(authored: Iterable<string>, outputs: OutputPaths): string[] {\n const targets = new Set<string>();\n const missing: string[] = [];\n for (const spelling of authored) {\n if (existsSync(spelling)) {\n if (toPosix(realPathOf(spelling)) === toPosix(spelling)) continue;\n for (const link of linksOnTheWay(spelling)) if (!outputs.holds(realPathOf(link))) targets.add(toPosix(link));\n continue;\n }\n missing.push(spelling);\n }\n for (const folder of missingImportFolders(missing)) {\n if (!outputs.holds(realPathOf(folder))) targets.add(toPosix(folder));\n }\n return [...targets];\n}\n\n/**\n * The nearest folder that exists, for each of the paths in `authored` that reaches nothing: where creating that\n * file (or the folders above it) shows. Of a path that exists there is none, and neither is the root of a file\n * system (an absolute import such as `/missing.js`, which Vite reads from the project root first), which no watcher\n * is asked to watch whole.\n */\nexport function missingImportFolders(authored: Iterable<string>): string[] {\n const folders = new Set<string>();\n for (const spelling of authored) {\n if (existsSync(spelling)) continue;\n let folder = dirname(spelling);\n while (!existsSync(folder) && dirname(folder) !== folder) folder = dirname(folder);\n if (existsSync(folder) && dirname(folder) !== folder) folders.add(folder);\n }\n return [...folders];\n}\n\n/**\n * The links among the folders above `path`, as authored (forward slashes), every hop of a chain, in the order they are\n * followed. Replacing one of them changes what the input is, and only its own location sees that. A link directly in\n * the root of the file system (`/var` on macOS) is the system's own alias and is left out, as is a link to a folder that\n * holds a build output, since watching it whole would rebuild for what the build writes.\n */\nfunction ancestorLinks(path: string, outputs: OutputPaths): string[] {\n return linksOnTheWay(dirname(path))\n .filter((link) => !outputs.holds(realPathOf(link)))\n .map(toPosix);\n}\n\n/** How many links the file system follows for one path before it gives up (ELOOP on Linux). */\nconst MAX_LINK_HOPS = 40;\n\n/**\n * Every link the file system follows to reach `path`, in the order it follows them: each link along the path, and\n * along the target each one leads to, so every hop of a link to a link (a chain) is there. A link directly in the\n * root of the file system (`/var` on macOS) is the system's own alias and is left out. The walk ends where a name\n * reaches nothing, or after as many hops as the file system follows.\n */\nexport function linksOnTheWay(path: string): string[] {\n const links: string[] = [];\n /** The names of a path or a link's target below its root; `..` is kept for the walk to take. */\n const names = (text: string, root: string): string[] =>\n text\n .slice(root.length)\n .split(sep === '\\\\' ? /[/\\\\]/ : '/')\n .filter((name) => name !== '' && name !== '.');\n const start = absolutePathSpelling(path);\n let reached = parse(start).root;\n let rest = names(start, reached);\n for (let hops = 0; rest.length > 0 && hops <= MAX_LINK_HOPS;) {\n const [name = '', ...more] = rest;\n rest = more;\n if (name === '..') {\n // Up from where the links before it led, as the file system takes it.\n reached = dirname(reached);\n continue;\n }\n const next = join(reached, name);\n let target: string | undefined;\n try {\n target = lstatSync(next).isSymbolicLink() ? readlinkSync(next) : undefined;\n } catch {\n break; // Reaches nothing.\n }\n if (target === undefined) {\n reached = next;\n continue;\n }\n hops += 1;\n if (dirname(next) !== dirname(dirname(next))) links.push(next);\n // A relative target goes on from the folder that holds the link; an absolute one from its root.\n const root = isAbsolute(target) ? parse(target).root : '';\n if (root !== '') reached = root;\n rest = [...names(target, root), ...rest];\n }\n return links;\n}\n\n/** Whether `path` is a loop of links, which the file system gives up following (ELOOP). */\nfunction isLoop(path: string): boolean {\n try {\n statSync(path);\n return false;\n } catch (error) {\n return error instanceof Error && Reflect.get(error, 'code') === 'ELOOP';\n }\n}\n\n/** Whether `path` is a symbolic link (or a Windows junction); a path that can't be read is none. */\nfunction isLink(path: string): boolean {\n try {\n return lstatSync(path).isSymbolicLink();\n } catch {\n return false;\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rohal12/twee-ts",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "TypeScript Twee-to-HTML compiler — a complete reimplementation of Tweego",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Unlicense",
|
|
@@ -118,7 +118,7 @@
|
|
|
118
118
|
"@vitest/eslint-plugin": "^1.6.27",
|
|
119
119
|
"acorn": "^8.19.0",
|
|
120
120
|
"eslint": "^10.12.0",
|
|
121
|
-
"fallow": "3.
|
|
121
|
+
"fallow": "3.34.1",
|
|
122
122
|
"fast-check": "^4.10.2",
|
|
123
123
|
"jscpd": "5.4.1",
|
|
124
124
|
"knip": "^6.41.0",
|