@staticbolt/core 1.0.0-beta.3 → 1.0.0-beta.30
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/lib/cli/index.d.mts +1 -1
- package/lib/cli/index.mjs +51 -40
- package/lib/cli/index.mjs.map +1 -1
- package/lib/{logger-BuxMGhij.mjs → common-DUFKS3lW.mjs} +91 -32
- package/lib/common-DUFKS3lW.mjs.map +1 -0
- package/lib/deferred-DTj91vEg.mjs +218 -0
- package/lib/deferred-DTj91vEg.mjs.map +1 -0
- package/lib/deferred.d.mts +79 -0
- package/lib/deferred.d.mts.map +1 -0
- package/lib/deferred.mjs +3 -0
- package/lib/index.d.mts +565 -340
- package/lib/index.d.mts.map +1 -1
- package/lib/index.mjs +9 -3
- package/lib/index.mjs.map +1 -1
- package/lib/load-config-D-FtbUws.mjs +57 -0
- package/lib/load-config-D-FtbUws.mjs.map +1 -0
- package/lib/plugins/index.d.mts +639 -35
- package/lib/plugins/index.d.mts.map +1 -1
- package/lib/plugins/index.mjs +2973 -1229
- package/lib/plugins/index.mjs.map +1 -1
- package/lib/plugins/write-files/deferred-worker.d.mts +15 -0
- package/lib/plugins/write-files/deferred-worker.d.mts.map +1 -0
- package/lib/plugins/write-files/deferred-worker.mjs +35 -0
- package/lib/plugins/write-files/deferred-worker.mjs.map +1 -0
- package/lib/rolldown-runtime-DXywRVcq.mjs +20 -0
- package/lib/{dependency-tracker-BuZfopIj.mjs → utilities-D0KXIZ-B.mjs} +373 -113
- package/lib/utilities-D0KXIZ-B.mjs.map +1 -0
- package/package.json +70 -65
- package/lib/dependency-tracker-BuZfopIj.mjs.map +0 -1
- package/lib/logger-BuxMGhij.mjs.map +0 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { DeferredPass } from "@staticbolt/core";
|
|
2
|
+
//#region src/plugins/write-files/deferred-worker.d.ts
|
|
3
|
+
/** A written file and the pass a plugin handed over instead of running. */
|
|
4
|
+
interface DeferredJob {
|
|
5
|
+
/** Absolute path of the file to run the pass over, in place. */
|
|
6
|
+
path: string;
|
|
7
|
+
pass: DeferredPass;
|
|
8
|
+
}
|
|
9
|
+
/** Sent back once the file is done, whether or not the pass went through. A worker is only ever given one job at a time. */
|
|
10
|
+
interface DeferredJobResult {
|
|
11
|
+
error?: string;
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { DeferredJob, DeferredJobResult };
|
|
15
|
+
//# sourceMappingURL=deferred-worker.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deferred-worker.d.mts","names":[],"sources":["../../../src/plugins/write-files/deferred-worker.ts"],"mappings":";;;UAMiB;;EAEf;EAEA,MAAM;;;UAIS;EACf"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { parentPort } from "node:worker_threads";
|
|
3
|
+
|
|
4
|
+
//#region src/plugins/write-files/deferred-worker.ts
|
|
5
|
+
/** Passes are looked up once and kept: a worker is handed the same kind of file over and over. */
|
|
6
|
+
const handlers = /* @__PURE__ */ new Map();
|
|
7
|
+
async function resolveHandler({ module, export: exportName }) {
|
|
8
|
+
const key = `${module}#${exportName}`;
|
|
9
|
+
const cached = handlers.get(key);
|
|
10
|
+
if (cached) return cached;
|
|
11
|
+
const handler = (await import(module))[exportName];
|
|
12
|
+
if (typeof handler !== "function") throw new TypeError(`"${module}" does not export "${exportName}"`);
|
|
13
|
+
handlers.set(key, handler);
|
|
14
|
+
return handler;
|
|
15
|
+
}
|
|
16
|
+
/** Reads the file, runs the pass the plugin named over its contents, and writes the result back over it. */
|
|
17
|
+
async function applyPass({ path, pass }) {
|
|
18
|
+
const handler = await resolveHandler(pass);
|
|
19
|
+
const code = readFileSync(path, "utf8");
|
|
20
|
+
writeFileSync(path, await handler(code, pass.payload), "utf8");
|
|
21
|
+
}
|
|
22
|
+
const port = parentPort;
|
|
23
|
+
if (port) port.on("message", async (job) => {
|
|
24
|
+
const result = {};
|
|
25
|
+
try {
|
|
26
|
+
await applyPass(job);
|
|
27
|
+
} catch (error) {
|
|
28
|
+
result.error = error instanceof Error ? error.message : String(error);
|
|
29
|
+
}
|
|
30
|
+
port.postMessage(result);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
//#endregion
|
|
34
|
+
export { };
|
|
35
|
+
//# sourceMappingURL=deferred-worker.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deferred-worker.mjs","names":[],"sources":["../../../src/plugins/write-files/deferred-worker.ts"],"sourcesContent":["import { readFileSync, writeFileSync } from \"node:fs\";\nimport { parentPort } from \"node:worker_threads\";\n\nimport type { DeferredPass, DeferredPassHandler } from \"@staticbolt/core\";\n\n/** A written file and the pass a plugin handed over instead of running. */\nexport interface DeferredJob {\n /** Absolute path of the file to run the pass over, in place. */\n path: string;\n\n pass: DeferredPass;\n}\n\n/** Sent back once the file is done, whether or not the pass went through. A worker is only ever given one job at a time. */\nexport interface DeferredJobResult {\n error?: string;\n}\n\n/** Passes are looked up once and kept: a worker is handed the same kind of file over and over. */\nconst handlers = new Map<string, DeferredPassHandler<unknown>>();\n\nasync function resolveHandler({ module, export: exportName }: DeferredPass): Promise<DeferredPassHandler<unknown>> {\n const key = `${module}#${exportName}`;\n\n const cached = handlers.get(key);\n if (cached) {\n return cached;\n }\n\n const namespace = (await import(module)) as Record<string, unknown>;\n const handler = namespace[exportName];\n\n if (typeof handler !== \"function\") {\n throw new TypeError(`\"${module}\" does not export \"${exportName}\"`);\n }\n\n handlers.set(key, handler as DeferredPassHandler<unknown>);\n\n return handler as DeferredPassHandler<unknown>;\n}\n\n/** Reads the file, runs the pass the plugin named over its contents, and writes the result back over it. */\nasync function applyPass({ path, pass }: DeferredJob): Promise<void> {\n const handler = await resolveHandler(pass);\n const code = readFileSync(path, \"utf8\");\n\n writeFileSync(path, await handler(code, pass.payload), \"utf8\");\n}\n\nconst port = parentPort;\n\nif (port) {\n port.on(\"message\", async (job: DeferredJob) => {\n const result: DeferredJobResult = {};\n\n try {\n await applyPass(job);\n } catch (error) {\n result.error = error instanceof Error ? error.message : String(error);\n }\n\n port.postMessage(result);\n });\n}\n"],"mappings":";;;;;AAmBA,MAAM,2BAAW,IAAI,IAA0C;AAE/D,eAAe,eAAe,EAAE,QAAQ,QAAQ,cAAmE;CACjH,MAAM,MAAM,GAAG,OAAO,GAAG;CAEzB,MAAM,SAAS,SAAS,IAAI,GAAG;CAC/B,IAAI,QACF,OAAO;CAIT,MAAM,WAAU,MADS,OAAO,QACP,CAAC;CAE1B,IAAI,OAAO,YAAY,YACrB,MAAM,IAAI,UAAU,IAAI,OAAO,qBAAqB,WAAW,EAAE;CAGnE,SAAS,IAAI,KAAK,OAAuC;CAEzD,OAAO;AACT;;AAGA,eAAe,UAAU,EAAE,MAAM,QAAoC;CACnE,MAAM,UAAU,MAAM,eAAe,IAAI;CACzC,MAAM,OAAO,aAAa,MAAM,MAAM;CAEtC,cAAc,MAAM,MAAM,QAAQ,MAAM,KAAK,OAAO,GAAG,MAAM;AAC/D;AAEA,MAAM,OAAO;AAEb,IAAI,MACF,KAAK,GAAG,WAAW,OAAO,QAAqB;CAC7C,MAAM,SAA4B,CAAC;CAEnC,IAAI;EACF,MAAM,UAAU,GAAG;CACrB,SAAS,OAAO;EACd,OAAO,QAAQ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;CACtE;CAEA,KAAK,YAAY,MAAM;AACzB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
|
|
3
|
+
//#region \0rolldown/runtime.js
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __exportAll = (all, no_symbols) => {
|
|
6
|
+
let target = {};
|
|
7
|
+
for (var name in all) {
|
|
8
|
+
__defProp(target, name, {
|
|
9
|
+
get: all[name],
|
|
10
|
+
enumerable: true
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
if (!no_symbols) {
|
|
14
|
+
__defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
15
|
+
}
|
|
16
|
+
return target;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
//#endregion
|
|
20
|
+
export { __exportAll as t };
|
|
@@ -1,15 +1,369 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as replaceExtension, c as isAbsolute, d as join, f as normalize, n as CUSTOM_ATTRIBUTES, o as dirname, r as Log, s as extname } from "./common-DUFKS3lW.mjs";
|
|
2
|
+
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
3
|
+
import { ResolverFactory } from "oxc-resolver";
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
import json5 from "json5";
|
|
6
|
+
import { readFile } from "node:fs/promises";
|
|
7
|
+
import _generator from "@babel/generator";
|
|
2
8
|
import { NodeType } from "@staticbolt/node-html-parser";
|
|
3
|
-
import c from "chalk";
|
|
4
9
|
import { Node as Node$1 } from "postcss";
|
|
5
|
-
import _generator from "@babel/generator";
|
|
6
|
-
import _traverse from "@babel/traverse";
|
|
7
10
|
import boxen from "boxen";
|
|
8
11
|
import { common, createEmphasize } from "emphasize";
|
|
9
|
-
import { readFileSync } from "node:fs";
|
|
10
|
-
import { readFile } from "node:fs/promises";
|
|
11
12
|
import { createHash } from "node:crypto";
|
|
12
13
|
|
|
14
|
+
//#region src/helpers/dependency-tracker.ts
|
|
15
|
+
/**
|
|
16
|
+
* Tracks bidirectional dependencies between importers and their sources.\
|
|
17
|
+
* Handles reconciliation when dependencies change, so stale entries are automatically removed when an importer stops referencing
|
|
18
|
+
* a source.
|
|
19
|
+
*/
|
|
20
|
+
var DependencyTracker = class {
|
|
21
|
+
/** Source → Set of importers that depend on it */
|
|
22
|
+
#sourcesToImporters = /* @__PURE__ */ new Map();
|
|
23
|
+
/** Importer → Set of sources it depends on */
|
|
24
|
+
#importerToSources = /* @__PURE__ */ new Map();
|
|
25
|
+
/** Updates the full set of sources for a given importer, reconciling any stale entries from previous calls. */
|
|
26
|
+
update(importer, sources) {
|
|
27
|
+
const nextSources = new Set(sources);
|
|
28
|
+
const previousSources = this.#importerToSources.get(importer) ?? /* @__PURE__ */ new Set();
|
|
29
|
+
for (const source of previousSources) if (!nextSources.has(source)) this.#sourcesToImporters.get(source)?.delete(importer);
|
|
30
|
+
for (const source of nextSources) {
|
|
31
|
+
if (!this.#sourcesToImporters.has(source)) this.#sourcesToImporters.set(source, /* @__PURE__ */ new Set());
|
|
32
|
+
this.#sourcesToImporters.get(source).add(importer);
|
|
33
|
+
}
|
|
34
|
+
this.#importerToSources.set(importer, nextSources);
|
|
35
|
+
}
|
|
36
|
+
/** Deletes all dependency data for a given id, whether it's acting as an importer, a source, or both (e.g. on file unlink). */
|
|
37
|
+
delete(id) {
|
|
38
|
+
this.#sourcesToImporters.delete(id);
|
|
39
|
+
const sources = this.#importerToSources.get(id);
|
|
40
|
+
if (sources) {
|
|
41
|
+
for (const source of sources) this.#sourcesToImporters.get(source)?.delete(id);
|
|
42
|
+
this.#importerToSources.delete(id);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/** Returns all importers that depend on a given source, or an empty set. */
|
|
46
|
+
getImporters(source) {
|
|
47
|
+
return this.#sourcesToImporters.get(source) ?? /* @__PURE__ */ new Set();
|
|
48
|
+
}
|
|
49
|
+
/** Returns all sources that a given importer depends on, or an empty set. */
|
|
50
|
+
getSources(importer) {
|
|
51
|
+
return this.#importerToSources.get(importer) ?? /* @__PURE__ */ new Set();
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region src/utilities/html-links.ts
|
|
57
|
+
/**
|
|
58
|
+
* Checks if the link is an HTML link (not a file link)
|
|
59
|
+
*
|
|
60
|
+
* @param source - The link
|
|
61
|
+
* @returns
|
|
62
|
+
*/
|
|
63
|
+
function isHtmlLink(source) {
|
|
64
|
+
return /^(?:#|https?|mailto:|tel:|url\(|ftp:|data:|javascript:)/i.test(source);
|
|
65
|
+
}
|
|
66
|
+
function isValidRelativePath(source) {
|
|
67
|
+
if (!source) return false;
|
|
68
|
+
if (isAbsolute(source)) return false;
|
|
69
|
+
return !isHtmlLink(source);
|
|
70
|
+
}
|
|
71
|
+
function splitHtmlLink(url) {
|
|
72
|
+
const qIndex = url.indexOf("?");
|
|
73
|
+
const hIndex = url.indexOf("#");
|
|
74
|
+
let delimIndex = -1;
|
|
75
|
+
if (qIndex !== -1 && hIndex !== -1) delimIndex = Math.min(qIndex, hIndex);
|
|
76
|
+
else if (qIndex !== -1) delimIndex = qIndex;
|
|
77
|
+
else if (hIndex !== -1) delimIndex = hIndex;
|
|
78
|
+
if (delimIndex !== -1) {
|
|
79
|
+
const pathEnd = url[delimIndex - 1] === "/" ? delimIndex - 1 : delimIndex;
|
|
80
|
+
return [url.slice(0, pathEnd), url.slice(pathEnd)];
|
|
81
|
+
}
|
|
82
|
+
if (url.endsWith("/")) {
|
|
83
|
+
if (url === "/" || url === "./") return [url, ""];
|
|
84
|
+
return [url.slice(0, -1), "/"];
|
|
85
|
+
}
|
|
86
|
+
return [url, ""];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
//#endregion
|
|
90
|
+
//#region src/utilities/value-or-error.ts
|
|
91
|
+
function errorsWrapper(function_) {
|
|
92
|
+
return (...arguments_) => {
|
|
93
|
+
try {
|
|
94
|
+
const promiseOrValue = function_(...arguments_);
|
|
95
|
+
if (isPromise(promiseOrValue)) return new Promise((resolve) => {
|
|
96
|
+
promiseOrValue.then((value) => {
|
|
97
|
+
resolve([value, null]);
|
|
98
|
+
}).catch((error) => {
|
|
99
|
+
resolve(handleError(error, function_.name));
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
return [promiseOrValue, null];
|
|
103
|
+
} catch (error) {
|
|
104
|
+
return handleError(error, function_.name);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function isPromise(value) {
|
|
109
|
+
return value && typeof value === "object" && "then" in value && typeof value.then === "function" && "catch" in value && typeof value.catch === "function";
|
|
110
|
+
}
|
|
111
|
+
function handleError(error, functionName = "") {
|
|
112
|
+
if (!error) return [null, /* @__PURE__ */ new Error(`[${functionName}] Unexpected error`)];
|
|
113
|
+
if (typeof error === "string") return [null, new Error(error)];
|
|
114
|
+
if (error instanceof Error) return [null, error];
|
|
115
|
+
if (typeof error === "object" && "message" in error && typeof error.message === "string") return [null, new Error(error.message)];
|
|
116
|
+
return [null, /* @__PURE__ */ new Error(`[${functionName}] Unexpected error`)];
|
|
117
|
+
}
|
|
118
|
+
const valueOrError = errorsWrapper;
|
|
119
|
+
|
|
120
|
+
//#endregion
|
|
121
|
+
//#region src/utilities/read-file.ts
|
|
122
|
+
async function safeReadFile(path, options) {
|
|
123
|
+
try {
|
|
124
|
+
return [await readFile(path, options), null];
|
|
125
|
+
} catch (error) {
|
|
126
|
+
return handleError(error, "readFile");
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function safeReadFileSync(path, options) {
|
|
130
|
+
try {
|
|
131
|
+
return [readFileSync(path, options), null];
|
|
132
|
+
} catch (error) {
|
|
133
|
+
return handleError(error, "readFileSync");
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
//#endregion
|
|
138
|
+
//#region src/utilities/read-json-file.ts
|
|
139
|
+
/** Read a file and parse it as JSON safely. */
|
|
140
|
+
function readJsonFile(path, code) {
|
|
141
|
+
if (!code) {
|
|
142
|
+
const [fileString, readError] = safeReadFileSync(path, "utf8");
|
|
143
|
+
if (readError) return [null, readError];
|
|
144
|
+
code = fileString;
|
|
145
|
+
}
|
|
146
|
+
const [parsed, parseError] = valueOrError(json5.parse)(code);
|
|
147
|
+
if (parseError !== null) return [null, parseError];
|
|
148
|
+
return [parsed, null];
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
//#endregion
|
|
152
|
+
//#region src/resolver/get-aliases.ts
|
|
153
|
+
/** Gets path aliases from `tsconfig.json` */
|
|
154
|
+
function getPathAliases(root) {
|
|
155
|
+
const [tsconfig, tsconfigParseError] = readTsconfig(root);
|
|
156
|
+
if (tsconfigParseError !== null) return [null, tsconfigParseError];
|
|
157
|
+
const paths = tsconfig.paths ?? {};
|
|
158
|
+
const alias = {};
|
|
159
|
+
for (const key in paths) {
|
|
160
|
+
const aliasName = key.replace(/\*$/, "");
|
|
161
|
+
alias[aliasName] = paths[key][0].replace(/\*$/, "");
|
|
162
|
+
}
|
|
163
|
+
return [alias, null];
|
|
164
|
+
}
|
|
165
|
+
function readTsconfig(root) {
|
|
166
|
+
const tsconfigPath = join(root, "tsconfig.json");
|
|
167
|
+
const [tsconfig, tsconfigParseError] = readJsonFile(tsconfigPath);
|
|
168
|
+
if (tsconfigParseError !== null) return [null, tsconfigParseError];
|
|
169
|
+
if (!tsconfig.compilerOptions) return [null, /* @__PURE__ */ new Error("[readTsconfig] No compilerOptions found in tsconfig.json")];
|
|
170
|
+
return [tsconfig.compilerOptions, null];
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
//#endregion
|
|
174
|
+
//#region src/resolver/resolver.ts
|
|
175
|
+
const nodeModulesResolver = new ResolverFactory({
|
|
176
|
+
conditionNames: [
|
|
177
|
+
"browser",
|
|
178
|
+
"import",
|
|
179
|
+
"default"
|
|
180
|
+
],
|
|
181
|
+
extensions: [
|
|
182
|
+
".js",
|
|
183
|
+
".json",
|
|
184
|
+
".node",
|
|
185
|
+
".css"
|
|
186
|
+
],
|
|
187
|
+
symlinks: false
|
|
188
|
+
});
|
|
189
|
+
var Resolver = class Resolver {
|
|
190
|
+
root;
|
|
191
|
+
isProduction;
|
|
192
|
+
aliases = {};
|
|
193
|
+
notFound = /* @__PURE__ */ new Set();
|
|
194
|
+
files = /* @__PURE__ */ new Set();
|
|
195
|
+
directories = /* @__PURE__ */ new Set();
|
|
196
|
+
misses = /* @__PURE__ */ new Set();
|
|
197
|
+
static JS_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
198
|
+
".js",
|
|
199
|
+
".mjs",
|
|
200
|
+
".cjs",
|
|
201
|
+
".jsx",
|
|
202
|
+
".ts",
|
|
203
|
+
".mts",
|
|
204
|
+
".cts",
|
|
205
|
+
".tsx"
|
|
206
|
+
]);
|
|
207
|
+
static HTML_EXTENSIONS = /* @__PURE__ */ new Set([".html", ".md"]);
|
|
208
|
+
constructor(root, isProduction = false, configAliases = {}) {
|
|
209
|
+
this.root = root;
|
|
210
|
+
this.isProduction = isProduction;
|
|
211
|
+
const [aliases] = getPathAliases(root);
|
|
212
|
+
this.aliases = {
|
|
213
|
+
...aliases,
|
|
214
|
+
...configAliases
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
resolve(sourceOrLink, filePath) {
|
|
218
|
+
if (!isValidRelativePath(sourceOrLink)) return;
|
|
219
|
+
const absFilePath = isAbsolute(filePath) ? filePath : join(this.root, filePath);
|
|
220
|
+
const [source, suffix] = splitHtmlLink(sourceOrLink);
|
|
221
|
+
if (isAbsolute(source)) return;
|
|
222
|
+
const isDirectory = suffix === "/";
|
|
223
|
+
const absSource = join(dirname(absFilePath), source);
|
|
224
|
+
const foundFile = this.findFile(absSource, isDirectory);
|
|
225
|
+
if (foundFile) return {
|
|
226
|
+
path: foundFile,
|
|
227
|
+
exists: true,
|
|
228
|
+
suffix
|
|
229
|
+
};
|
|
230
|
+
const sourceForAlias = suffix === "/" ? source + "/" : source;
|
|
231
|
+
const resolvedPathAlias = Resolver.resolvePathAlias(sourceForAlias, this.aliases);
|
|
232
|
+
if (resolvedPathAlias) {
|
|
233
|
+
const absSource = join(this.root, resolvedPathAlias);
|
|
234
|
+
const foundFile = this.findFile(absSource, isDirectory);
|
|
235
|
+
const isFileAlias = Object.hasOwn(this.aliases, sourceForAlias) && !sourceForAlias.endsWith("/");
|
|
236
|
+
if (!foundFile && !this.notFound.has(absSource.replace(/\/$/, ""))) {
|
|
237
|
+
this.notFound.add(absSource.replace(/\/$/, ""));
|
|
238
|
+
Log.warn(`[resolver] Source "${sourceOrLink}" found in "${filePath}" was resolved to "${resolvedPathAlias}", but the file is missing.`);
|
|
239
|
+
}
|
|
240
|
+
return {
|
|
241
|
+
path: foundFile ?? absSource,
|
|
242
|
+
exists: !!foundFile,
|
|
243
|
+
suffix,
|
|
244
|
+
isFileAlias,
|
|
245
|
+
isDirAlias: !isFileAlias
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
if (!source.startsWith(".")) {
|
|
249
|
+
const resolverResult = nodeModulesResolver.sync(this.root, source);
|
|
250
|
+
if (resolverResult.path) return {
|
|
251
|
+
path: resolverResult.path,
|
|
252
|
+
suffix,
|
|
253
|
+
exists: true,
|
|
254
|
+
isPackage: true
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
if (source.startsWith("./") || source.startsWith("../")) {
|
|
258
|
+
if (!this.notFound.has(absSource)) {
|
|
259
|
+
this.notFound.add(absSource);
|
|
260
|
+
Log.warn(`[resolver] Source "${sourceOrLink}" found in "${filePath}" points to a non-existent file.`);
|
|
261
|
+
}
|
|
262
|
+
return {
|
|
263
|
+
path: absSource,
|
|
264
|
+
suffix,
|
|
265
|
+
exists: false
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
resolveAlias(source) {
|
|
270
|
+
return Resolver.resolvePathAlias(source, this.aliases);
|
|
271
|
+
}
|
|
272
|
+
normalize(filePath) {
|
|
273
|
+
return normalize(filePath);
|
|
274
|
+
}
|
|
275
|
+
static isFile(filePath) {
|
|
276
|
+
try {
|
|
277
|
+
return statSync(filePath).isFile();
|
|
278
|
+
} catch (error) {
|
|
279
|
+
const code = error.code;
|
|
280
|
+
if (code === "ENOENT" || code === "ENOTDIR") return false;
|
|
281
|
+
throw error;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
/** Aliased path to path */
|
|
285
|
+
static resolvePathAlias(filePath, aliases) {
|
|
286
|
+
for (const [key, value] of Object.entries(aliases)) {
|
|
287
|
+
if (key.endsWith("/")) {
|
|
288
|
+
if (!filePath.startsWith(key)) continue;
|
|
289
|
+
return filePath.replace(key, () => value);
|
|
290
|
+
}
|
|
291
|
+
if (filePath === key) return value;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
/** Path to aliased path */
|
|
295
|
+
static resolveAliasPath(filePath, aliases) {
|
|
296
|
+
let shortest;
|
|
297
|
+
for (const [key, value] of Object.entries(aliases)) {
|
|
298
|
+
if (key.endsWith("/")) {
|
|
299
|
+
if (!filePath.startsWith(value)) continue;
|
|
300
|
+
const aliased = filePath.replace(value, () => key);
|
|
301
|
+
if (!shortest || aliased.length < shortest.length) shortest = aliased;
|
|
302
|
+
continue;
|
|
303
|
+
}
|
|
304
|
+
if (filePath === value && (!shortest || key.length < shortest.length)) shortest = key;
|
|
305
|
+
}
|
|
306
|
+
return shortest ?? filePath;
|
|
307
|
+
}
|
|
308
|
+
/** Path to aliased path */
|
|
309
|
+
aliasPath(filePath) {
|
|
310
|
+
return Resolver.resolveAliasPath(filePath, this.aliases);
|
|
311
|
+
}
|
|
312
|
+
findFile(filePath, shouldCheckDirectory = false) {
|
|
313
|
+
const missKey = (shouldCheckDirectory ? "d:" : "f:") + filePath;
|
|
314
|
+
if (this.isProduction && this.misses.has(missKey)) return;
|
|
315
|
+
const found = this.#findFileUncached(filePath, shouldCheckDirectory);
|
|
316
|
+
if (found === void 0 && this.isProduction) this.misses.add(missKey);
|
|
317
|
+
return found;
|
|
318
|
+
}
|
|
319
|
+
#findFileUncached(filePath, shouldCheckDirectory) {
|
|
320
|
+
if (this.files.has(filePath)) return filePath;
|
|
321
|
+
if (Resolver.isFile(filePath)) {
|
|
322
|
+
this.files.add(filePath);
|
|
323
|
+
return filePath;
|
|
324
|
+
}
|
|
325
|
+
const extension = extname(filePath);
|
|
326
|
+
if (!extension) {
|
|
327
|
+
for (const candidateExtension of [...Resolver.JS_EXTENSIONS, ...Resolver.HTML_EXTENSIONS]) {
|
|
328
|
+
const candidate = replaceExtension(filePath, candidateExtension);
|
|
329
|
+
if (this.files.has(candidate)) return candidate;
|
|
330
|
+
if (Resolver.isFile(candidate)) {
|
|
331
|
+
this.files.add(candidate);
|
|
332
|
+
return candidate;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
const withIndex = join(filePath, "index");
|
|
336
|
+
for (const candidateExtension of Resolver.HTML_EXTENSIONS) {
|
|
337
|
+
const candidate = replaceExtension(withIndex, candidateExtension);
|
|
338
|
+
if (this.files.has(candidate)) return candidate;
|
|
339
|
+
if (Resolver.isFile(candidate)) {
|
|
340
|
+
this.files.add(candidate);
|
|
341
|
+
return candidate;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
if (shouldCheckDirectory) {
|
|
345
|
+
if (this.directories.has(filePath)) return filePath;
|
|
346
|
+
if (existsSync(filePath)) {
|
|
347
|
+
this.directories.add(filePath);
|
|
348
|
+
return filePath;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
if (Resolver.JS_EXTENSIONS.has(extension)) {
|
|
354
|
+
for (const jsExtension of Resolver.JS_EXTENSIONS) {
|
|
355
|
+
const candidate = replaceExtension(filePath, jsExtension);
|
|
356
|
+
if (Resolver.isFile(candidate)) {
|
|
357
|
+
this.files.add(candidate);
|
|
358
|
+
return candidate;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
//#endregion
|
|
13
367
|
//#region src/types/metadata.ts
|
|
14
368
|
const METADATA_TYPES = Object.freeze({
|
|
15
369
|
Script: "Script",
|
|
@@ -25,7 +379,7 @@ const METADATA_TYPES = Object.freeze({
|
|
|
25
379
|
|
|
26
380
|
//#endregion
|
|
27
381
|
//#region src/helpers/is-script-type.ts
|
|
28
|
-
const allowedTypes = new Set([
|
|
382
|
+
const allowedTypes = /* @__PURE__ */ new Set([
|
|
29
383
|
"module",
|
|
30
384
|
"text/javascript",
|
|
31
385
|
"application/javascript",
|
|
@@ -84,7 +438,8 @@ function filterScriptMetadata(metadata) {
|
|
|
84
438
|
for (const scriptTag of scriptTags) {
|
|
85
439
|
const scriptId = scriptTag.getAttribute(CUSTOM_ATTRIBUTES.MetadataID);
|
|
86
440
|
if (!scriptId) continue;
|
|
87
|
-
|
|
441
|
+
const scriptType = scriptTag.getAttribute("type");
|
|
442
|
+
if (!isScriptType(scriptType)) continue;
|
|
88
443
|
const scriptMetadata = metadata.scriptsMetadataList.get(scriptId);
|
|
89
444
|
if (!scriptMetadata) continue;
|
|
90
445
|
result.push({
|
|
@@ -125,11 +480,6 @@ function filterStyleMetadata(metadata) {
|
|
|
125
480
|
return result;
|
|
126
481
|
}
|
|
127
482
|
|
|
128
|
-
//#endregion
|
|
129
|
-
//#region src/helpers/babel-fixed-imports.ts
|
|
130
|
-
const generator = typeof _generator === "function" ? _generator : _generator.default;
|
|
131
|
-
const traverse = typeof _traverse === "function" ? _traverse : _traverse.default;
|
|
132
|
-
|
|
133
483
|
//#endregion
|
|
134
484
|
//#region src/utilities/highlight-code.ts
|
|
135
485
|
/** - Highlight code string for terminal */
|
|
@@ -156,7 +506,7 @@ function highlightCode(code, { lang = "ts", maxCodeLength = 170, maxLineLength =
|
|
|
156
506
|
withNewLines += currentLine + "\n";
|
|
157
507
|
}
|
|
158
508
|
let highlighted = createEmphasize(common).highlight(lang, withNewLines.trim()).value;
|
|
159
|
-
if (isTruncated) highlighted += "\n" +
|
|
509
|
+
if (isTruncated) highlighted += "\n" + chalk.inverse(" ... ");
|
|
160
510
|
if (!boxed) return highlighted;
|
|
161
511
|
return boxen(highlighted, {
|
|
162
512
|
padding: .5,
|
|
@@ -168,6 +518,7 @@ function highlightCode(code, { lang = "ts", maxCodeLength = 170, maxLineLength =
|
|
|
168
518
|
|
|
169
519
|
//#endregion
|
|
170
520
|
//#region src/utilities/print-formatted-error.ts
|
|
521
|
+
const generator = typeof _generator === "function" ? _generator : _generator.default;
|
|
171
522
|
var PrintFormattedError = class PrintFormattedError {
|
|
172
523
|
options = {};
|
|
173
524
|
constructor(options = {}) {
|
|
@@ -191,9 +542,9 @@ var PrintFormattedError = class PrintFormattedError {
|
|
|
191
542
|
Object.assign(options, item);
|
|
192
543
|
}
|
|
193
544
|
let message = "";
|
|
194
|
-
if (options.filePath) message +=
|
|
545
|
+
if (options.filePath) message += chalk.italic(options.filePath) + "\n";
|
|
195
546
|
const functionName = options.function?.name ?? options.functionName;
|
|
196
|
-
if (functionName) message +=
|
|
547
|
+
if (functionName) message += chalk.dim(`[${functionName}] `);
|
|
197
548
|
message += messagesArray.join(" ");
|
|
198
549
|
const codeFromNode = options.node && nodeToString(options.node);
|
|
199
550
|
const code = options.code ?? codeFromNode?.code;
|
|
@@ -233,54 +584,6 @@ function nodeToString(node) {
|
|
|
233
584
|
};
|
|
234
585
|
}
|
|
235
586
|
|
|
236
|
-
//#endregion
|
|
237
|
-
//#region src/utilities/value-or-error.ts
|
|
238
|
-
function errorsWrapper(function_) {
|
|
239
|
-
return (...arguments_) => {
|
|
240
|
-
try {
|
|
241
|
-
const promiseOrValue = function_(...arguments_);
|
|
242
|
-
if (isPromise(promiseOrValue)) return new Promise((resolve) => {
|
|
243
|
-
promiseOrValue.then((value) => {
|
|
244
|
-
resolve([value, null]);
|
|
245
|
-
}).catch((error) => {
|
|
246
|
-
resolve(handleError(error, function_.name));
|
|
247
|
-
});
|
|
248
|
-
});
|
|
249
|
-
return [promiseOrValue, null];
|
|
250
|
-
} catch (error) {
|
|
251
|
-
return handleError(error, function_.name);
|
|
252
|
-
}
|
|
253
|
-
};
|
|
254
|
-
}
|
|
255
|
-
function isPromise(value) {
|
|
256
|
-
return value && typeof value === "object" && "then" in value && typeof value.then === "function" && "catch" in value && typeof value.catch === "function";
|
|
257
|
-
}
|
|
258
|
-
function handleError(error, functionName = "") {
|
|
259
|
-
if (!error) return [null, /* @__PURE__ */ new Error(`[${functionName}] Unexpected error`)];
|
|
260
|
-
if (typeof error === "string") return [null, new Error(error)];
|
|
261
|
-
if (error instanceof Error) return [null, error];
|
|
262
|
-
if (typeof error === "object" && "message" in error && typeof error.message === "string") return [null, new Error(error.message)];
|
|
263
|
-
return [null, /* @__PURE__ */ new Error(`[${functionName}] Unexpected error`)];
|
|
264
|
-
}
|
|
265
|
-
const valueOrError = errorsWrapper;
|
|
266
|
-
|
|
267
|
-
//#endregion
|
|
268
|
-
//#region src/utilities/read-file.ts
|
|
269
|
-
async function safeReadFile(path, options) {
|
|
270
|
-
try {
|
|
271
|
-
return [await readFile(path, options), null];
|
|
272
|
-
} catch (error) {
|
|
273
|
-
return handleError(error, "readFile");
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
function safeReadFileSync(path, options) {
|
|
277
|
-
try {
|
|
278
|
-
return [readFileSync(path, options), null];
|
|
279
|
-
} catch (error) {
|
|
280
|
-
return handleError(error, "readFileSync");
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
587
|
//#endregion
|
|
285
588
|
//#region src/utilities/utilities.ts
|
|
286
589
|
/** `process.stdout.write` */
|
|
@@ -289,10 +592,9 @@ function print(...input) {
|
|
|
289
592
|
}
|
|
290
593
|
/** - Clear the line in the terminal */
|
|
291
594
|
function clearLn() {
|
|
292
|
-
if ("clearLine" in process.stdout && typeof process.stdout.clearLine === "function")
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
}
|
|
595
|
+
if (!("clearLine" in process.stdout && typeof process.stdout.clearLine === "function")) return;
|
|
596
|
+
process.stdout.clearLine(0);
|
|
597
|
+
process.stdout.cursorTo(0);
|
|
296
598
|
}
|
|
297
599
|
/** Used to assign a computed value to a variable */
|
|
298
600
|
function assign(function_) {
|
|
@@ -405,7 +707,7 @@ function hashContent(content) {
|
|
|
405
707
|
}
|
|
406
708
|
const matchHtmlRegExp = /["'&<>]/;
|
|
407
709
|
function escapeHtml(input) {
|
|
408
|
-
const string =
|
|
710
|
+
const string = input;
|
|
409
711
|
const match = matchHtmlRegExp.exec(string);
|
|
410
712
|
if (!match) return string;
|
|
411
713
|
let escape;
|
|
@@ -439,47 +741,5 @@ function escapeHtml(input) {
|
|
|
439
741
|
}
|
|
440
742
|
|
|
441
743
|
//#endregion
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
* Tracks bidirectional dependencies between importers and their sources.\
|
|
445
|
-
* Handles reconciliation when dependencies change, so stale entries are automatically removed when an importer stops referencing
|
|
446
|
-
* a source.
|
|
447
|
-
*/
|
|
448
|
-
var DependencyTracker = class {
|
|
449
|
-
/** Source → Set of importers that depend on it */
|
|
450
|
-
#sourcesToImporters = /* @__PURE__ */ new Map();
|
|
451
|
-
/** Importer → Set of sources it depends on */
|
|
452
|
-
#importerToSources = /* @__PURE__ */ new Map();
|
|
453
|
-
/** Updates the full set of sources for a given importer, reconciling any stale entries from previous calls. */
|
|
454
|
-
update(importer, sources) {
|
|
455
|
-
const nextSources = new Set(sources);
|
|
456
|
-
const previousSources = this.#importerToSources.get(importer) ?? /* @__PURE__ */ new Set();
|
|
457
|
-
for (const source of previousSources) if (!nextSources.has(source)) this.#sourcesToImporters.get(source)?.delete(importer);
|
|
458
|
-
for (const source of nextSources) {
|
|
459
|
-
if (!this.#sourcesToImporters.has(source)) this.#sourcesToImporters.set(source, /* @__PURE__ */ new Set());
|
|
460
|
-
this.#sourcesToImporters.get(source).add(importer);
|
|
461
|
-
}
|
|
462
|
-
this.#importerToSources.set(importer, nextSources);
|
|
463
|
-
}
|
|
464
|
-
/** Deletes all dependency data for a given id, whether it's acting as an importer, a source, or both (e.g. on file unlink). */
|
|
465
|
-
delete(id) {
|
|
466
|
-
this.#sourcesToImporters.delete(id);
|
|
467
|
-
const sources = this.#importerToSources.get(id);
|
|
468
|
-
if (sources) {
|
|
469
|
-
for (const source of sources) this.#sourcesToImporters.get(source)?.delete(id);
|
|
470
|
-
this.#importerToSources.delete(id);
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
/** Returns all importers that depend on a given source, or an empty set. */
|
|
474
|
-
getImporters(source) {
|
|
475
|
-
return this.#sourcesToImporters.get(source) ?? /* @__PURE__ */ new Set();
|
|
476
|
-
}
|
|
477
|
-
/** Returns all sources that a given importer depends on, or an empty set. */
|
|
478
|
-
getSources(importer) {
|
|
479
|
-
return this.#importerToSources.get(importer) ?? /* @__PURE__ */ new Set();
|
|
480
|
-
}
|
|
481
|
-
};
|
|
482
|
-
|
|
483
|
-
//#endregion
|
|
484
|
-
export { isHtmlMetadata as A, PrintFormattedError as C, filterScriptMetadata as D, traverse as E, isSvgMetadata as F, isTextAssetMetadata as I, isWebManifestMetadata as L, isPackageMetadata as M, isScriptMetadata as N, filterStyleMetadata as O, isStyleMetadata as P, isScriptType as R, valueOrError as S, generator as T, kebabToCamelCase as _, capitalize as a, safeReadFile as b, cloneObject as c, getLineColumn as d, hashContent as f, isURL as g, isObject as h, camelCaseToKebabCase as i, isMarkdownMetadata as j, isBinaryAssetMetadata as k, downloadContent as l, isDefined as m, assign as n, clamp as o, humanReadableBytes as p, bytesToKB as r, clearLn as s, DependencyTracker as t, escapeHtml as u, mergeMaps as v, printFmtError as w, safeReadFileSync as x, print as y, METADATA_TYPES as z };
|
|
485
|
-
//# sourceMappingURL=dependency-tracker-BuZfopIj.mjs.map
|
|
744
|
+
export { isTextAssetMetadata as A, isHtmlLink as B, isBinaryAssetMetadata as C, isScriptMetadata as D, isPackageMetadata as E, readJsonFile as F, splitHtmlLink as H, safeReadFile as I, safeReadFileSync as L, isScriptType as M, METADATA_TYPES as N, isStyleMetadata as O, Resolver as P, handleError as R, filterStyleMetadata as S, isMarkdownMetadata as T, DependencyTracker as U, isValidRelativePath as V, mergeMaps as _, clamp as a, printFmtError as b, downloadContent as c, hashContent as d, humanReadableBytes as f, kebabToCamelCase as g, isURL as h, capitalize as i, isWebManifestMetadata as j, isSvgMetadata as k, escapeHtml as l, isObject as m, bytesToKB as n, clearLn as o, isDefined as p, camelCaseToKebabCase as r, cloneObject as s, assign as t, getLineColumn as u, print as v, isHtmlMetadata as w, filterScriptMetadata as x, PrintFormattedError as y, valueOrError as z };
|
|
745
|
+
//# sourceMappingURL=utilities-D0KXIZ-B.mjs.map
|