@staticbolt/core 1.0.0-beta.3 → 1.0.0-beta.31
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/README.md +2 -1
- package/lib/cli/index.d.mts +1 -1
- package/lib/cli/index.mjs +78 -44
- package/lib/cli/index.mjs.map +1 -1
- package/lib/{logger-BuxMGhij.mjs → common-D1QTZ8ra.mjs} +92 -33
- package/lib/common-D1QTZ8ra.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 +713 -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-CsbiJ01A.mjs +57 -0
- package/lib/load-config-CsbiJ01A.mjs.map +1 -0
- package/lib/plugins/index.d.mts +652 -39
- package/lib/plugins/index.d.mts.map +1 -1
- package/lib/plugins/index.mjs +3621 -1344
- 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-jK4uUZBV.mjs} +444 -125
- package/lib/utilities-jK4uUZBV.mjs.map +1 -0
- package/package.json +74 -65
- package/lib/dependency-tracker-BuZfopIj.mjs.map +0 -1
- package/lib/logger-BuxMGhij.mjs.map +0 -1
|
@@ -1,32 +1,101 @@
|
|
|
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-D1QTZ8ra.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
|
|
|
13
|
-
//#region src/
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
+
}
|
|
25
88
|
|
|
26
89
|
//#endregion
|
|
27
90
|
//#region src/helpers/is-script-type.ts
|
|
28
|
-
|
|
91
|
+
/**
|
|
92
|
+
* The `type` that marks a script as TypeScript for the editor: Prettier formats it as such, the editor's own script support
|
|
93
|
+
* leaves it alone, and the build drops it from the output.
|
|
94
|
+
*/
|
|
95
|
+
const TYPESCRIPT_TYPE = "application/x-typescript";
|
|
96
|
+
const allowedTypes = /* @__PURE__ */ new Set([
|
|
29
97
|
"module",
|
|
98
|
+
TYPESCRIPT_TYPE,
|
|
30
99
|
"text/javascript",
|
|
31
100
|
"application/javascript",
|
|
32
101
|
"text/ecmascript",
|
|
@@ -37,6 +106,350 @@ function isScriptType(type) {
|
|
|
37
106
|
return !type || allowedTypes.has(type.toLowerCase());
|
|
38
107
|
}
|
|
39
108
|
|
|
109
|
+
//#endregion
|
|
110
|
+
//#region src/helpers/lsp-checks.ts
|
|
111
|
+
/** The placeholder syntaxes a plugin or a runtime may fill in: `{{ }}`, `[[ ]]`, `${ }`, `<% %>`, `{% %}` and `%name%`. */
|
|
112
|
+
const PLACEHOLDER = /\{\{[\s\S]*?\}\}|\[\[[\s\S]*?\]\]|\$\{[\s\S]*?\}|<%[\s\S]*?%>|\{%[\s\S]*?%\}|%[\w.-]+%/;
|
|
113
|
+
/** Whether an attribute value is only known later: it holds a placeholder something else fills in. */
|
|
114
|
+
function isDynamic(value) {
|
|
115
|
+
return PLACEHOLDER.test(value);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Reports an attribute whose value is a path to a file that is not there. A URL, an absolute link or a value with a placeholder
|
|
119
|
+
* is left alone.
|
|
120
|
+
*/
|
|
121
|
+
function checkFileExists(attribute, document, report) {
|
|
122
|
+
if (!attribute.value) return;
|
|
123
|
+
if (isDynamic(attribute.value)) return;
|
|
124
|
+
if (!isValidRelativePath(attribute.value)) return;
|
|
125
|
+
if (document.resolve(attribute.value)?.exists) return;
|
|
126
|
+
report.error(attribute, `"${attribute.value}" does not exist`);
|
|
127
|
+
}
|
|
128
|
+
/** Reports an attribute whose value is not the JSON of an object. A value with a placeholder is left alone. */
|
|
129
|
+
function checkJsonObject(attribute, report) {
|
|
130
|
+
if (!attribute.value) return;
|
|
131
|
+
if (isDynamic(attribute.value)) return;
|
|
132
|
+
if (isJsonObject(attribute.value)) return;
|
|
133
|
+
report.error(attribute, `"${attribute.name}" must be a JSON object`);
|
|
134
|
+
}
|
|
135
|
+
/** Whether a string is the JSON of an object. */
|
|
136
|
+
function isJsonObject(text) {
|
|
137
|
+
try {
|
|
138
|
+
const parsed = JSON.parse(text);
|
|
139
|
+
return typeof parsed === "object" && parsed !== null && !Array.isArray(parsed);
|
|
140
|
+
} catch {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/** Whether a script element holds JavaScript, going by its `type`: the build leaves any other kind of script alone. */
|
|
145
|
+
function isJavaScript(script) {
|
|
146
|
+
return isScriptType(script.attribute("type")?.value ?? null);
|
|
147
|
+
}
|
|
148
|
+
/** Whether a `<script>` is marked as TypeScript for the editor, which also keeps the editor's own script support out. */
|
|
149
|
+
function isTypeScriptScript(script) {
|
|
150
|
+
return script.attribute("type")?.value?.toLowerCase() === TYPESCRIPT_TYPE;
|
|
151
|
+
}
|
|
152
|
+
/** Whether an element has nothing but whitespace between its tags. */
|
|
153
|
+
function isEmptyElement(element, document) {
|
|
154
|
+
if (!element.contentRange) return true;
|
|
155
|
+
return document.textOf(element.contentRange).trim() === "";
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
//#endregion
|
|
159
|
+
//#region src/utilities/value-or-error.ts
|
|
160
|
+
function errorsWrapper(function_) {
|
|
161
|
+
return (...arguments_) => {
|
|
162
|
+
try {
|
|
163
|
+
const promiseOrValue = function_(...arguments_);
|
|
164
|
+
if (isPromise(promiseOrValue)) return new Promise((resolve) => {
|
|
165
|
+
promiseOrValue.then((value) => {
|
|
166
|
+
resolve([value, null]);
|
|
167
|
+
}).catch((error) => {
|
|
168
|
+
resolve(handleError(error, function_.name));
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
return [promiseOrValue, null];
|
|
172
|
+
} catch (error) {
|
|
173
|
+
return handleError(error, function_.name);
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
function isPromise(value) {
|
|
178
|
+
return value && typeof value === "object" && "then" in value && typeof value.then === "function" && "catch" in value && typeof value.catch === "function";
|
|
179
|
+
}
|
|
180
|
+
function handleError(error, functionName = "") {
|
|
181
|
+
if (!error) return [null, /* @__PURE__ */ new Error(`[${functionName}] Unexpected error`)];
|
|
182
|
+
if (typeof error === "string") return [null, new Error(error)];
|
|
183
|
+
if (error instanceof Error) return [null, error];
|
|
184
|
+
if (typeof error === "object" && "message" in error && typeof error.message === "string") return [null, new Error(error.message)];
|
|
185
|
+
return [null, /* @__PURE__ */ new Error(`[${functionName}] Unexpected error`)];
|
|
186
|
+
}
|
|
187
|
+
const valueOrError = errorsWrapper;
|
|
188
|
+
|
|
189
|
+
//#endregion
|
|
190
|
+
//#region src/utilities/read-file.ts
|
|
191
|
+
async function safeReadFile(path, options) {
|
|
192
|
+
try {
|
|
193
|
+
return [await readFile(path, options), null];
|
|
194
|
+
} catch (error) {
|
|
195
|
+
return handleError(error, "readFile");
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
function safeReadFileSync(path, options) {
|
|
199
|
+
try {
|
|
200
|
+
return [readFileSync(path, options), null];
|
|
201
|
+
} catch (error) {
|
|
202
|
+
return handleError(error, "readFileSync");
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
//#endregion
|
|
207
|
+
//#region src/utilities/read-json-file.ts
|
|
208
|
+
/** Read a file and parse it as JSON safely. */
|
|
209
|
+
function readJsonFile(path, code) {
|
|
210
|
+
if (!code) {
|
|
211
|
+
const [fileString, readError] = safeReadFileSync(path, "utf8");
|
|
212
|
+
if (readError) return [null, readError];
|
|
213
|
+
code = fileString;
|
|
214
|
+
}
|
|
215
|
+
const [parsed, parseError] = valueOrError(json5.parse)(code);
|
|
216
|
+
if (parseError !== null) return [null, parseError];
|
|
217
|
+
return [parsed, null];
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
//#endregion
|
|
221
|
+
//#region src/resolver/get-aliases.ts
|
|
222
|
+
/** Gets path aliases from `tsconfig.json` */
|
|
223
|
+
function getPathAliases(root) {
|
|
224
|
+
const [tsconfig, tsconfigParseError] = readTsconfig(root);
|
|
225
|
+
if (tsconfigParseError !== null) return [null, tsconfigParseError];
|
|
226
|
+
const paths = tsconfig.paths ?? {};
|
|
227
|
+
const alias = {};
|
|
228
|
+
for (const key in paths) {
|
|
229
|
+
const aliasName = key.replace(/\*$/, "");
|
|
230
|
+
alias[aliasName] = paths[key][0].replace(/\*$/, "");
|
|
231
|
+
}
|
|
232
|
+
return [alias, null];
|
|
233
|
+
}
|
|
234
|
+
function readTsconfig(root) {
|
|
235
|
+
const tsconfigPath = join(root, "tsconfig.json");
|
|
236
|
+
const [tsconfig, tsconfigParseError] = readJsonFile(tsconfigPath);
|
|
237
|
+
if (tsconfigParseError !== null) return [null, tsconfigParseError];
|
|
238
|
+
if (!tsconfig.compilerOptions) return [null, /* @__PURE__ */ new Error("[readTsconfig] No compilerOptions found in tsconfig.json")];
|
|
239
|
+
return [tsconfig.compilerOptions, null];
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
//#endregion
|
|
243
|
+
//#region src/resolver/resolver.ts
|
|
244
|
+
const nodeModulesResolver = new ResolverFactory({
|
|
245
|
+
conditionNames: [
|
|
246
|
+
"browser",
|
|
247
|
+
"import",
|
|
248
|
+
"default"
|
|
249
|
+
],
|
|
250
|
+
extensions: [
|
|
251
|
+
".js",
|
|
252
|
+
".json",
|
|
253
|
+
".node",
|
|
254
|
+
".css"
|
|
255
|
+
],
|
|
256
|
+
symlinks: false
|
|
257
|
+
});
|
|
258
|
+
var Resolver = class Resolver {
|
|
259
|
+
root;
|
|
260
|
+
isProduction;
|
|
261
|
+
aliases = {};
|
|
262
|
+
notFound = /* @__PURE__ */ new Set();
|
|
263
|
+
files = /* @__PURE__ */ new Set();
|
|
264
|
+
directories = /* @__PURE__ */ new Set();
|
|
265
|
+
misses = /* @__PURE__ */ new Set();
|
|
266
|
+
/** Whether a source that resolves to a missing file is logged, once. The result says so either way. */
|
|
267
|
+
shouldWarnOnMissing;
|
|
268
|
+
static JS_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
269
|
+
".js",
|
|
270
|
+
".mjs",
|
|
271
|
+
".cjs",
|
|
272
|
+
".jsx",
|
|
273
|
+
".ts",
|
|
274
|
+
".mts",
|
|
275
|
+
".cts",
|
|
276
|
+
".tsx"
|
|
277
|
+
]);
|
|
278
|
+
static HTML_EXTENSIONS = /* @__PURE__ */ new Set([".html", ".md"]);
|
|
279
|
+
constructor(root, isProduction = false, configAliases = {}, shouldWarnOnMissing = true) {
|
|
280
|
+
this.root = root;
|
|
281
|
+
this.isProduction = isProduction;
|
|
282
|
+
this.shouldWarnOnMissing = shouldWarnOnMissing;
|
|
283
|
+
const [aliases] = getPathAliases(root);
|
|
284
|
+
this.aliases = {
|
|
285
|
+
...aliases,
|
|
286
|
+
...configAliases
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
resolve(sourceOrLink, filePath) {
|
|
290
|
+
if (!isValidRelativePath(sourceOrLink)) return;
|
|
291
|
+
const absFilePath = isAbsolute(filePath) ? filePath : join(this.root, filePath);
|
|
292
|
+
const [source, suffix] = splitHtmlLink(sourceOrLink);
|
|
293
|
+
if (isAbsolute(source)) return;
|
|
294
|
+
const isDirectory = suffix === "/";
|
|
295
|
+
const absSource = join(dirname(absFilePath), source);
|
|
296
|
+
const foundFile = this.findFile(absSource, isDirectory);
|
|
297
|
+
if (foundFile) return {
|
|
298
|
+
path: foundFile,
|
|
299
|
+
exists: true,
|
|
300
|
+
suffix
|
|
301
|
+
};
|
|
302
|
+
const sourceForAlias = suffix === "/" ? source + "/" : source;
|
|
303
|
+
const resolvedPathAlias = Resolver.resolvePathAlias(sourceForAlias, this.aliases);
|
|
304
|
+
if (resolvedPathAlias) {
|
|
305
|
+
const absSource = join(this.root, resolvedPathAlias);
|
|
306
|
+
const foundFile = this.findFile(absSource, isDirectory);
|
|
307
|
+
const isFileAlias = Object.hasOwn(this.aliases, sourceForAlias) && !sourceForAlias.endsWith("/");
|
|
308
|
+
if (!foundFile) this.#warnMissing(absSource.replace(/\/$/, ""), `[resolver] Source "${sourceOrLink}" found in "${filePath}" was resolved to "${resolvedPathAlias}", but the file is missing.`);
|
|
309
|
+
return {
|
|
310
|
+
path: foundFile ?? absSource,
|
|
311
|
+
exists: !!foundFile,
|
|
312
|
+
suffix,
|
|
313
|
+
isFileAlias,
|
|
314
|
+
isDirAlias: !isFileAlias
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
if (!source.startsWith(".")) {
|
|
318
|
+
const resolverResult = nodeModulesResolver.sync(this.root, source);
|
|
319
|
+
if (resolverResult.path) return {
|
|
320
|
+
path: resolverResult.path,
|
|
321
|
+
suffix,
|
|
322
|
+
exists: true,
|
|
323
|
+
isPackage: true
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
if (source.startsWith("./") || source.startsWith("../")) {
|
|
327
|
+
this.#warnMissing(absSource, `[resolver] Source "${sourceOrLink}" found in "${filePath}" points to a non-existent file.`);
|
|
328
|
+
return {
|
|
329
|
+
path: absSource,
|
|
330
|
+
suffix,
|
|
331
|
+
exists: false
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
/** Logs a missing file the first time it is resolved to, when the resolver is set to. */
|
|
336
|
+
#warnMissing(absSource, message) {
|
|
337
|
+
if (!this.shouldWarnOnMissing) return;
|
|
338
|
+
if (this.notFound.has(absSource)) return;
|
|
339
|
+
this.notFound.add(absSource);
|
|
340
|
+
Log.warn(message);
|
|
341
|
+
}
|
|
342
|
+
resolveAlias(source) {
|
|
343
|
+
return Resolver.resolvePathAlias(source, this.aliases);
|
|
344
|
+
}
|
|
345
|
+
normalize(filePath) {
|
|
346
|
+
return normalize(filePath);
|
|
347
|
+
}
|
|
348
|
+
static isFile(filePath) {
|
|
349
|
+
try {
|
|
350
|
+
return statSync(filePath).isFile();
|
|
351
|
+
} catch (error) {
|
|
352
|
+
const code = error.code;
|
|
353
|
+
if (code === "ENOENT" || code === "ENOTDIR") return false;
|
|
354
|
+
throw error;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
/** Aliased path to path */
|
|
358
|
+
static resolvePathAlias(filePath, aliases) {
|
|
359
|
+
for (const [key, value] of Object.entries(aliases)) {
|
|
360
|
+
if (key.endsWith("/")) {
|
|
361
|
+
if (!filePath.startsWith(key)) continue;
|
|
362
|
+
return filePath.replace(key, () => value);
|
|
363
|
+
}
|
|
364
|
+
if (filePath === key) return value;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
/** Path to aliased path */
|
|
368
|
+
static resolveAliasPath(filePath, aliases) {
|
|
369
|
+
let shortest;
|
|
370
|
+
for (const [key, value] of Object.entries(aliases)) {
|
|
371
|
+
if (key.endsWith("/")) {
|
|
372
|
+
if (!filePath.startsWith(value)) continue;
|
|
373
|
+
const aliased = filePath.replace(value, () => key);
|
|
374
|
+
if (!shortest || aliased.length < shortest.length) shortest = aliased;
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
377
|
+
if (filePath === value && (!shortest || key.length < shortest.length)) shortest = key;
|
|
378
|
+
}
|
|
379
|
+
return shortest ?? filePath;
|
|
380
|
+
}
|
|
381
|
+
/** Path to aliased path */
|
|
382
|
+
aliasPath(filePath) {
|
|
383
|
+
return Resolver.resolveAliasPath(filePath, this.aliases);
|
|
384
|
+
}
|
|
385
|
+
findFile(filePath, shouldCheckDirectory = false) {
|
|
386
|
+
const missKey = (shouldCheckDirectory ? "d:" : "f:") + filePath;
|
|
387
|
+
if (this.isProduction && this.misses.has(missKey)) return;
|
|
388
|
+
const found = this.#findFileUncached(filePath, shouldCheckDirectory);
|
|
389
|
+
if (found === void 0 && this.isProduction) this.misses.add(missKey);
|
|
390
|
+
return found;
|
|
391
|
+
}
|
|
392
|
+
#findFileUncached(filePath, shouldCheckDirectory) {
|
|
393
|
+
if (this.files.has(filePath)) return filePath;
|
|
394
|
+
if (Resolver.isFile(filePath)) {
|
|
395
|
+
this.files.add(filePath);
|
|
396
|
+
return filePath;
|
|
397
|
+
}
|
|
398
|
+
const extension = extname(filePath);
|
|
399
|
+
if (!extension) {
|
|
400
|
+
for (const candidateExtension of [...Resolver.JS_EXTENSIONS, ...Resolver.HTML_EXTENSIONS]) {
|
|
401
|
+
const candidate = replaceExtension(filePath, candidateExtension);
|
|
402
|
+
if (this.files.has(candidate)) return candidate;
|
|
403
|
+
if (Resolver.isFile(candidate)) {
|
|
404
|
+
this.files.add(candidate);
|
|
405
|
+
return candidate;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
const withIndex = join(filePath, "index");
|
|
409
|
+
for (const candidateExtension of Resolver.HTML_EXTENSIONS) {
|
|
410
|
+
const candidate = replaceExtension(withIndex, candidateExtension);
|
|
411
|
+
if (this.files.has(candidate)) return candidate;
|
|
412
|
+
if (Resolver.isFile(candidate)) {
|
|
413
|
+
this.files.add(candidate);
|
|
414
|
+
return candidate;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
if (shouldCheckDirectory) {
|
|
418
|
+
if (this.directories.has(filePath)) return filePath;
|
|
419
|
+
if (existsSync(filePath)) {
|
|
420
|
+
this.directories.add(filePath);
|
|
421
|
+
return filePath;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
if (Resolver.JS_EXTENSIONS.has(extension)) {
|
|
427
|
+
for (const jsExtension of Resolver.JS_EXTENSIONS) {
|
|
428
|
+
const candidate = replaceExtension(filePath, jsExtension);
|
|
429
|
+
if (Resolver.isFile(candidate)) {
|
|
430
|
+
this.files.add(candidate);
|
|
431
|
+
return candidate;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
//#endregion
|
|
440
|
+
//#region src/types/metadata.ts
|
|
441
|
+
const METADATA_TYPES = Object.freeze({
|
|
442
|
+
Script: "Script",
|
|
443
|
+
HTML: "Html",
|
|
444
|
+
Markdown: "Markdown",
|
|
445
|
+
CSS: "Style",
|
|
446
|
+
SVG: "Svg",
|
|
447
|
+
Package: "Package",
|
|
448
|
+
TextAsset: "TextAsset",
|
|
449
|
+
BinaryAsset: "BinaryAsset",
|
|
450
|
+
WebAppManifest: "WebAppManifest"
|
|
451
|
+
});
|
|
452
|
+
|
|
40
453
|
//#endregion
|
|
41
454
|
//#region src/utilities/metadata-utilities.ts
|
|
42
455
|
function isScriptMetadata(metadata) {
|
|
@@ -84,7 +497,8 @@ function filterScriptMetadata(metadata) {
|
|
|
84
497
|
for (const scriptTag of scriptTags) {
|
|
85
498
|
const scriptId = scriptTag.getAttribute(CUSTOM_ATTRIBUTES.MetadataID);
|
|
86
499
|
if (!scriptId) continue;
|
|
87
|
-
|
|
500
|
+
const scriptType = scriptTag.getAttribute("type");
|
|
501
|
+
if (!isScriptType(scriptType)) continue;
|
|
88
502
|
const scriptMetadata = metadata.scriptsMetadataList.get(scriptId);
|
|
89
503
|
if (!scriptMetadata) continue;
|
|
90
504
|
result.push({
|
|
@@ -125,11 +539,6 @@ function filterStyleMetadata(metadata) {
|
|
|
125
539
|
return result;
|
|
126
540
|
}
|
|
127
541
|
|
|
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
542
|
//#endregion
|
|
134
543
|
//#region src/utilities/highlight-code.ts
|
|
135
544
|
/** - Highlight code string for terminal */
|
|
@@ -156,7 +565,7 @@ function highlightCode(code, { lang = "ts", maxCodeLength = 170, maxLineLength =
|
|
|
156
565
|
withNewLines += currentLine + "\n";
|
|
157
566
|
}
|
|
158
567
|
let highlighted = createEmphasize(common).highlight(lang, withNewLines.trim()).value;
|
|
159
|
-
if (isTruncated) highlighted += "\n" +
|
|
568
|
+
if (isTruncated) highlighted += "\n" + chalk.inverse(" ... ");
|
|
160
569
|
if (!boxed) return highlighted;
|
|
161
570
|
return boxen(highlighted, {
|
|
162
571
|
padding: .5,
|
|
@@ -168,6 +577,7 @@ function highlightCode(code, { lang = "ts", maxCodeLength = 170, maxLineLength =
|
|
|
168
577
|
|
|
169
578
|
//#endregion
|
|
170
579
|
//#region src/utilities/print-formatted-error.ts
|
|
580
|
+
const generator = typeof _generator === "function" ? _generator : _generator.default;
|
|
171
581
|
var PrintFormattedError = class PrintFormattedError {
|
|
172
582
|
options = {};
|
|
173
583
|
constructor(options = {}) {
|
|
@@ -191,9 +601,9 @@ var PrintFormattedError = class PrintFormattedError {
|
|
|
191
601
|
Object.assign(options, item);
|
|
192
602
|
}
|
|
193
603
|
let message = "";
|
|
194
|
-
if (options.filePath) message +=
|
|
604
|
+
if (options.filePath) message += chalk.italic(options.filePath) + "\n";
|
|
195
605
|
const functionName = options.function?.name ?? options.functionName;
|
|
196
|
-
if (functionName) message +=
|
|
606
|
+
if (functionName) message += chalk.dim(`[${functionName}] `);
|
|
197
607
|
message += messagesArray.join(" ");
|
|
198
608
|
const codeFromNode = options.node && nodeToString(options.node);
|
|
199
609
|
const code = options.code ?? codeFromNode?.code;
|
|
@@ -233,54 +643,6 @@ function nodeToString(node) {
|
|
|
233
643
|
};
|
|
234
644
|
}
|
|
235
645
|
|
|
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
646
|
//#endregion
|
|
285
647
|
//#region src/utilities/utilities.ts
|
|
286
648
|
/** `process.stdout.write` */
|
|
@@ -289,10 +651,9 @@ function print(...input) {
|
|
|
289
651
|
}
|
|
290
652
|
/** - Clear the line in the terminal */
|
|
291
653
|
function clearLn() {
|
|
292
|
-
if ("clearLine" in process.stdout && typeof process.stdout.clearLine === "function")
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
}
|
|
654
|
+
if (!("clearLine" in process.stdout && typeof process.stdout.clearLine === "function")) return;
|
|
655
|
+
process.stdout.clearLine(0);
|
|
656
|
+
process.stdout.cursorTo(0);
|
|
296
657
|
}
|
|
297
658
|
/** Used to assign a computed value to a variable */
|
|
298
659
|
function assign(function_) {
|
|
@@ -405,7 +766,7 @@ function hashContent(content) {
|
|
|
405
766
|
}
|
|
406
767
|
const matchHtmlRegExp = /["'&<>]/;
|
|
407
768
|
function escapeHtml(input) {
|
|
408
|
-
const string =
|
|
769
|
+
const string = input;
|
|
409
770
|
const match = matchHtmlRegExp.exec(string);
|
|
410
771
|
if (!match) return string;
|
|
411
772
|
let escape;
|
|
@@ -439,47 +800,5 @@ function escapeHtml(input) {
|
|
|
439
800
|
}
|
|
440
801
|
|
|
441
802
|
//#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
|
|
803
|
+
export { isTextAssetMetadata as A, checkJsonObject as B, isBinaryAssetMetadata as C, isScriptMetadata as D, isPackageMetadata as E, safeReadFile as F, isTypeScriptScript as G, isEmptyElement as H, safeReadFileSync as I, isHtmlLink as J, TYPESCRIPT_TYPE as K, handleError as L, METADATA_TYPES as M, Resolver as N, isStyleMetadata as O, readJsonFile as P, valueOrError as R, filterStyleMetadata as S, isMarkdownMetadata as T, isJavaScript as U, isDynamic as V, isJsonObject as W, splitHtmlLink as X, isValidRelativePath as Y, DependencyTracker as Z, 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, isScriptType as q, camelCaseToKebabCase as r, cloneObject as s, assign as t, getLineColumn as u, print as v, isHtmlMetadata as w, filterScriptMetadata as x, PrintFormattedError as y, checkFileExists as z };
|
|
804
|
+
//# sourceMappingURL=utilities-jK4uUZBV.mjs.map
|