@staticbolt/core 1.0.0-beta.3 → 1.0.0-beta.5
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/chunk-C7Uep-_p.mjs +20 -0
- package/lib/cli/index.mjs +1 -1
- package/lib/index.d.mts +299 -292
- package/lib/index.d.mts.map +1 -1
- package/lib/index.mjs +3 -3
- package/lib/index.mjs.map +1 -1
- package/lib/{logger-BuxMGhij.mjs → logger-BfIn1ytK.mjs} +29 -9
- package/lib/logger-BfIn1ytK.mjs.map +1 -0
- package/lib/plugins/index.mjs +31 -20
- package/lib/plugins/index.mjs.map +1 -1
- package/lib/{dependency-tracker-BuZfopIj.mjs → utilities-CZmLMi93.mjs} +45 -45
- package/lib/utilities-CZmLMi93.mjs.map +1 -0
- package/package.json +7 -7
- package/lib/dependency-tracker-BuZfopIj.mjs.map +0 -1
- package/lib/logger-BuxMGhij.mjs.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as CUSTOM_ATTRIBUTES, t as Log } from "./logger-BfIn1ytK.mjs";
|
|
2
2
|
import { NodeType } from "@staticbolt/node-html-parser";
|
|
3
3
|
import c from "chalk";
|
|
4
4
|
import { Node as Node$1 } from "postcss";
|
|
@@ -10,6 +10,48 @@ import { readFileSync } from "node:fs";
|
|
|
10
10
|
import { readFile } from "node:fs/promises";
|
|
11
11
|
import { createHash } from "node:crypto";
|
|
12
12
|
|
|
13
|
+
//#region src/helpers/dependency-tracker.ts
|
|
14
|
+
/**
|
|
15
|
+
* Tracks bidirectional dependencies between importers and their sources.\
|
|
16
|
+
* Handles reconciliation when dependencies change, so stale entries are automatically removed when an importer stops referencing
|
|
17
|
+
* a source.
|
|
18
|
+
*/
|
|
19
|
+
var DependencyTracker = class {
|
|
20
|
+
/** Source → Set of importers that depend on it */
|
|
21
|
+
#sourcesToImporters = /* @__PURE__ */ new Map();
|
|
22
|
+
/** Importer → Set of sources it depends on */
|
|
23
|
+
#importerToSources = /* @__PURE__ */ new Map();
|
|
24
|
+
/** Updates the full set of sources for a given importer, reconciling any stale entries from previous calls. */
|
|
25
|
+
update(importer, sources) {
|
|
26
|
+
const nextSources = new Set(sources);
|
|
27
|
+
const previousSources = this.#importerToSources.get(importer) ?? /* @__PURE__ */ new Set();
|
|
28
|
+
for (const source of previousSources) if (!nextSources.has(source)) this.#sourcesToImporters.get(source)?.delete(importer);
|
|
29
|
+
for (const source of nextSources) {
|
|
30
|
+
if (!this.#sourcesToImporters.has(source)) this.#sourcesToImporters.set(source, /* @__PURE__ */ new Set());
|
|
31
|
+
this.#sourcesToImporters.get(source).add(importer);
|
|
32
|
+
}
|
|
33
|
+
this.#importerToSources.set(importer, nextSources);
|
|
34
|
+
}
|
|
35
|
+
/** Deletes all dependency data for a given id, whether it's acting as an importer, a source, or both (e.g. on file unlink). */
|
|
36
|
+
delete(id) {
|
|
37
|
+
this.#sourcesToImporters.delete(id);
|
|
38
|
+
const sources = this.#importerToSources.get(id);
|
|
39
|
+
if (sources) {
|
|
40
|
+
for (const source of sources) this.#sourcesToImporters.get(source)?.delete(id);
|
|
41
|
+
this.#importerToSources.delete(id);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/** Returns all importers that depend on a given source, or an empty set. */
|
|
45
|
+
getImporters(source) {
|
|
46
|
+
return this.#sourcesToImporters.get(source) ?? /* @__PURE__ */ new Set();
|
|
47
|
+
}
|
|
48
|
+
/** Returns all sources that a given importer depends on, or an empty set. */
|
|
49
|
+
getSources(importer) {
|
|
50
|
+
return this.#importerToSources.get(importer) ?? /* @__PURE__ */ new Set();
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
//#endregion
|
|
13
55
|
//#region src/types/metadata.ts
|
|
14
56
|
const METADATA_TYPES = Object.freeze({
|
|
15
57
|
Script: "Script",
|
|
@@ -439,47 +481,5 @@ function escapeHtml(input) {
|
|
|
439
481
|
}
|
|
440
482
|
|
|
441
483
|
//#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
|
|
484
|
+
export { isHtmlMetadata as A, DependencyTracker as B, 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, mergeMaps as _, clamp as a, safeReadFileSync as b, downloadContent as c, hashContent as d, humanReadableBytes as f, kebabToCamelCase as g, isURL as h, capitalize as i, isMarkdownMetadata as j, isBinaryAssetMetadata 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, printFmtError as w, handleError as x, safeReadFile as y, METADATA_TYPES as z };
|
|
485
|
+
//# sourceMappingURL=utilities-CZmLMi93.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utilities-CZmLMi93.mjs","names":["#sourcesToImporters","#importerToSources","chalk","PostcssNode"],"sources":["../src/helpers/dependency-tracker.ts","../src/types/metadata.ts","../src/helpers/is-script-type.ts","../src/utilities/metadata-utilities.ts","../src/helpers/babel-fixed-imports.ts","../src/utilities/highlight-code.ts","../src/utilities/print-formatted-error.ts","../src/utilities/value-or-error.ts","../src/utilities/read-file.ts","../src/utilities/utilities.ts"],"sourcesContent":["/**\n * Tracks bidirectional dependencies between importers and their sources.\\\n * Handles reconciliation when dependencies change, so stale entries are automatically removed when an importer stops referencing\n * a source.\n */\nexport class DependencyTracker {\n /** Source → Set of importers that depend on it */\n readonly #sourcesToImporters = new Map<string, Set<string>>();\n\n /** Importer → Set of sources it depends on */\n readonly #importerToSources = new Map<string, Set<string>>();\n\n /** Updates the full set of sources for a given importer, reconciling any stale entries from previous calls. */\n update(importer: string, sources: Iterable<string>): void {\n const nextSources = new Set(sources);\n const previousSources = this.#importerToSources.get(importer) ?? new Set();\n\n // Remove importer from sources it no longer uses\n for (const source of previousSources) {\n if (!nextSources.has(source)) {\n this.#sourcesToImporters.get(source)?.delete(importer);\n }\n }\n\n // Add importer to newly referenced sources\n for (const source of nextSources) {\n if (!this.#sourcesToImporters.has(source)) {\n this.#sourcesToImporters.set(source, new Set());\n }\n\n this.#sourcesToImporters.get(source)!.add(importer);\n }\n\n this.#importerToSources.set(importer, nextSources);\n }\n\n /** Deletes all dependency data for a given id, whether it's acting as an importer, a source, or both (e.g. on file unlink). */\n delete(id: string): void {\n // id was a source — drop it entirely\n this.#sourcesToImporters.delete(id);\n\n // id was an importer — remove it from all sources it referenced\n const sources = this.#importerToSources.get(id);\n if (sources) {\n for (const source of sources) {\n this.#sourcesToImporters.get(source)?.delete(id);\n }\n\n this.#importerToSources.delete(id);\n }\n }\n\n /** Returns all importers that depend on a given source, or an empty set. */\n getImporters(source: string): ReadonlySet<string> {\n return this.#sourcesToImporters.get(source) ?? new Set();\n }\n\n /** Returns all sources that a given importer depends on, or an empty set. */\n getSources(importer: string): ReadonlySet<string> {\n return this.#importerToSources.get(importer) ?? new Set();\n }\n}\n","import type { BabelAst, PostcssAst, Document, MarkdownAst } from \"@staticbolt/core\";\nimport type { WebAppManifest } from \"web-app-manifest\";\n\nexport const METADATA_TYPES = Object.freeze({\n Script: \"Script\",\n HTML: \"Html\",\n Markdown: \"Markdown\",\n CSS: \"Style\",\n SVG: \"Svg\",\n Package: \"Package\",\n TextAsset: \"TextAsset\",\n BinaryAsset: \"BinaryAsset\",\n WebAppManifest: \"WebAppManifest\",\n});\n\nexport type MetadataTypes = (typeof METADATA_TYPES)[keyof typeof METADATA_TYPES];\n\nexport interface MetadataBase {\n readonly type: `${Capitalize<string>}${string}`;\n\n /**\n * Relative path of the source file.\n *\n * Initially identical to `originalSource` when the metadata is created. During the build process, this value may change (e.g.,\n * if the file is moved to a different location and its links are rebased).\n */\n filePath: string;\n\n /**\n * Original relative path of the source file.\n *\n * Set when the metadata is created and never modified.\n */\n readonly id: string;\n\n readonly directDependencies: Set<string>;\n}\n\nexport interface ScriptMetadata extends MetadataBase {\n readonly type: (typeof METADATA_TYPES)[\"Script\"];\n\n /**\n * The Babel AST for the script.\n *\n * Mutated during the build process and always represents the file's current transformed state.\n */\n ast: BabelAst;\n\n /** Whether the script is a module or global */\n module: boolean;\n}\n\nexport interface StyleMetadata extends MetadataBase {\n readonly type: (typeof METADATA_TYPES)[\"CSS\"];\n\n /**\n * The PostCSS root after transformation\n *\n * Mutated during the build process and always represents the file's current transformed state.\n */\n ast: PostcssAst;\n}\n\nexport interface HtmlMetadata extends MetadataBase {\n type: (typeof METADATA_TYPES)[\"HTML\"];\n\n /**\n * The HTML AST (root element).\n *\n * Mutated during the build process and always represents the file's current transformed state\n */\n ast: Document;\n\n /** The transformed ASTs from script tags. The key is the UUID */\n scriptsMetadataList: Map<string, ScriptMetadata>;\n\n /** The transformed ASTs from script tags. The key is the UUID */\n stylesMetadataList: Map<string, StyleMetadata>;\n}\n\nexport interface SvgMetadata extends MetadataBase {\n type: (typeof METADATA_TYPES)[\"SVG\"];\n\n /**\n * The HTML AST (root element).\n *\n * Mutated during the build process and always represents the file's current transformed state\n */\n ast: Document;\n\n /** The transformed ASTs from script tags. The key is the UUID */\n stylesMetadataList: Map<string, StyleMetadata>;\n}\n\nexport interface MarkdownMetadata extends MetadataBase {\n type: (typeof METADATA_TYPES)[\"Markdown\"];\n\n /**\n * Markdown tokens and frontmatter.\n *\n * Mutated during the build process and always represents the file's current transformed state\n */\n ast: MarkdownAst;\n}\n\nexport interface WebManifestMetadata extends MetadataBase {\n type: (typeof METADATA_TYPES)[\"WebAppManifest\"];\n ast: WebAppManifest;\n}\n\nexport interface PackageMetadata extends MetadataBase {\n type: (typeof METADATA_TYPES)[\"Package\"];\n\n /** Metadata code */\n code: string;\n\n packageName: string;\n}\n\nexport interface TextAssetMetadata extends MetadataBase {\n type: (typeof METADATA_TYPES)[\"TextAsset\"];\n\n /** Metadata code */\n code: string;\n}\n\nexport interface BinaryAssetMetadata extends MetadataBase {\n type: (typeof METADATA_TYPES)[\"BinaryAsset\"];\n\n /** Raw binary content — images, fonts, wasm, etc. */\n data?: Uint8Array;\n}\n","const allowedTypes = new Set([\n \"module\",\n \"text/javascript\",\n \"application/javascript\",\n \"text/ecmascript\",\n \"application/ecmascript\",\n \"application/x-javascript\",\n]);\n\nexport function isScriptType(type: string | null) {\n return !type || allowedTypes.has(type.toLowerCase());\n}\n","import { isScriptType } from \"../helpers/is-script-type.ts\";\nimport { CUSTOM_ATTRIBUTES } from \"../types/common.ts\";\nimport { METADATA_TYPES } from \"../types/metadata.ts\";\n\nimport type {\n TextAssetMetadata,\n HtmlMetadata,\n MarkdownMetadata,\n MetadataBase,\n ScriptMetadata,\n StyleMetadata,\n SvgMetadata,\n WebManifestMetadata,\n BinaryAssetMetadata,\n PackageMetadata,\n HTMLElement,\n} from \"@staticbolt/core\";\n\nexport function isScriptMetadata(metadata: MetadataBase | undefined): metadata is ScriptMetadata {\n return metadata?.type === METADATA_TYPES.Script;\n}\n\nexport function isPackageMetadata(metadata: MetadataBase | undefined): metadata is PackageMetadata {\n return metadata?.type === METADATA_TYPES.Package;\n}\n\nexport function isHtmlMetadata(metadata: MetadataBase | undefined): metadata is HtmlMetadata {\n return metadata?.type === METADATA_TYPES.HTML;\n}\n\nexport function isStyleMetadata(metadata: MetadataBase | undefined): metadata is StyleMetadata {\n return metadata?.type === METADATA_TYPES.CSS;\n}\n\nexport function isSvgMetadata(metadata: MetadataBase | undefined): metadata is SvgMetadata {\n return metadata?.type === METADATA_TYPES.SVG;\n}\n\nexport function isMarkdownMetadata(metadata: MetadataBase | undefined): metadata is MarkdownMetadata {\n return metadata?.type === METADATA_TYPES.Markdown;\n}\n\nexport function isTextAssetMetadata(metadata: MetadataBase | undefined): metadata is TextAssetMetadata {\n return metadata?.type === METADATA_TYPES.TextAsset;\n}\n\nexport function isBinaryAssetMetadata(metadata: MetadataBase | undefined): metadata is BinaryAssetMetadata {\n return metadata?.type === METADATA_TYPES.BinaryAsset;\n}\n\nexport function isWebManifestMetadata(metadata: MetadataBase): metadata is WebManifestMetadata {\n return metadata.type === METADATA_TYPES.WebAppManifest;\n}\n\n/**\n * Returns script-related metadata entries.\n *\n * - If the input is ScriptMetadata, it returns it directly.\n * - If the input is HtmlMetadata, it scans <script> tags in the AST and resolves their associated ScriptMetadata using the metadata\n * ID attribute.\n */\nexport function filterScriptMetadata(metadata: MetadataBase) {\n const result: { metadata: ScriptMetadata; tag?: HTMLElement; htmlMetadata?: HtmlMetadata }[] = [];\n\n if (isScriptMetadata(metadata)) {\n result.push({ metadata });\n return result;\n }\n\n if (isHtmlMetadata(metadata)) {\n const scriptTags = metadata.ast.querySelectorAll(\"script\");\n\n for (const scriptTag of scriptTags) {\n const scriptId = scriptTag.getAttribute(CUSTOM_ATTRIBUTES.MetadataID);\n if (!scriptId) continue;\n\n const scriptType = scriptTag.getAttribute(\"type\");\n if (!isScriptType(scriptType)) {\n continue;\n }\n\n const scriptMetadata = metadata.scriptsMetadataList.get(scriptId);\n if (!scriptMetadata) continue;\n\n result.push({ metadata: scriptMetadata, htmlMetadata: metadata, tag: scriptTag });\n }\n }\n\n return result;\n}\n\n/**\n * Returns style-related metadata entries.\n *\n * - If the input is StyleMetadata, it returns it directly.\n * - If the input is HtmlMetadata, it scans <style> tags in the AST and resolves their associated StyleMetadata using the metadata\n * ID attribute.\n */\nexport function filterStyleMetadata(metadata: MetadataBase) {\n const result: { metadata: StyleMetadata; tag?: HTMLElement; htmlMetadata?: HtmlMetadata }[] = [];\n\n if (isStyleMetadata(metadata)) {\n result.push({ metadata });\n return result;\n }\n\n if (isHtmlMetadata(metadata)) {\n const styleTags = metadata.ast.querySelectorAll(\"style\");\n\n for (const styleTag of styleTags) {\n const styleId = styleTag.getAttribute(CUSTOM_ATTRIBUTES.MetadataID) || \"\";\n const styleMetadata = metadata.stylesMetadataList.get(styleId);\n if (!styleMetadata) continue;\n\n result.push({\n metadata: styleMetadata,\n htmlMetadata: metadata,\n tag: styleTag,\n });\n }\n }\n\n return result;\n}\n","import _generator from \"@babel/generator\";\nimport _traverse from \"@babel/traverse\";\n\nconst generator = typeof _generator === \"function\" ? _generator : _generator.default;\n\nconst traverse = typeof _traverse === \"function\" ? _traverse : _traverse.default;\n\nexport { generator, traverse };\n","import boxen from \"boxen\";\nimport chalk from \"chalk\";\nimport { common, createEmphasize } from \"emphasize\";\n\n/** - Highlight code string for terminal */\nexport function highlightCode(code: string, { lang = \"ts\", maxCodeLength = 170, maxLineLength = 110, boxed = true } = {}) {\n // Limit code length\n const isTruncated = code.length > maxCodeLength;\n if (isTruncated) code = code.slice(0, Math.max(0, maxCodeLength));\n\n // Limit line length and break on words\n const lines = code.split(\"\\n\");\n let withNewLines = \"\";\n for (const line of lines) {\n if (line.length <= maxLineLength) {\n withNewLines += line + \"\\n\";\n continue;\n }\n\n const words = line.split(\" \");\n let currentLine = \"\";\n for (const word of words) {\n if (currentLine.length + word.length <= maxLineLength) {\n currentLine += word + \" \";\n continue;\n }\n withNewLines += currentLine + \"\\n\";\n currentLine = word + \" \";\n }\n withNewLines += currentLine + \"\\n\";\n }\n\n // Highlight\n let highlighted = createEmphasize(common).highlight(lang, withNewLines.trim()).value;\n if (isTruncated) highlighted += \"\\n\" + chalk.inverse(\" ... \");\n\n if (!boxed) return highlighted;\n\n return boxen(highlighted, {\n padding: 0.5,\n borderStyle: \"round\",\n borderColor: \"white\",\n dimBorder: true,\n });\n}\n","import { NodeType } from \"@staticbolt/node-html-parser\";\nimport c from \"chalk\";\nimport { Node as PostcssNode } from \"postcss\";\n\nimport { generator } from \"../helpers/babel-fixed-imports.ts\";\nimport { CUSTOM_ATTRIBUTES } from \"../types/common.ts\";\nimport { highlightCode } from \"./highlight-code.ts\";\nimport { Log } from \"./logger.ts\";\n\nimport type { Node as BabelNode } from \"@babel/types\";\nimport type { HTMLElement, Node as HtmlNode } from \"@staticbolt/node-html-parser\";\n\ntype Node = BabelNode | PostcssNode | HtmlNode;\n\ninterface FormatErrorOptions {\n /** AST node (e.g., from Babel, PostCSS, or HTML) to convert and highlight */\n node?: Node;\n\n /** Source code to highlight (use instead of `node`) */\n code?: string;\n\n /** Language of the provided source code (required if `code` is set) */\n lang?: string;\n\n /** Path of the file where the error occurred */\n filePath?: string;\n\n /** Name of the function where the error originated */\n functionName?: string;\n\n level?: \"error\" | \"warning\";\n\n /** Function reference used to extract the function name */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n function?: (...arguments_: any[]) => any;\n}\n\ntype MessageAndError = (string | Error)[];\n\nexport class PrintFormattedError {\n options: FormatErrorOptions = {};\n\n constructor(options: FormatErrorOptions = {}) {\n Object.assign(this.options, options);\n }\n\n static create(options: FormatErrorOptions = {}) {\n return new PrintFormattedError(options).print;\n }\n\n print = (...messageAndErrorWithOptions: [...MessageAndError] | [...MessageAndError, FormatErrorOptions]) => {\n const options: FormatErrorOptions = { ...this.options };\n\n const messagesArray: string[] = [];\n for (const item of messageAndErrorWithOptions) {\n // Msg\n if (typeof item === \"string\") {\n messagesArray.push(item);\n continue;\n }\n\n // Error\n if (item instanceof Error) {\n messagesArray.push(`\\n${item.message}`);\n continue;\n }\n\n // Options\n Object.assign(options, item);\n }\n\n let message = \"\";\n\n // First file path in one line without anything else to enable vscode link parsing\n if (options.filePath) {\n message += c.italic(options.filePath) + \"\\n\";\n }\n\n // Then the function name before the messages\n const functionName = options.function?.name ?? options.functionName;\n if (functionName) {\n message += c.dim(`[${functionName}] `);\n }\n\n // Then the messages (spaced)\n message += messagesArray.join(\" \");\n\n // Now the code\n const codeFromNode = options.node && nodeToString(options.node);\n const code = options.code ?? codeFromNode?.code;\n const lang = options.lang ?? codeFromNode?.lang;\n const codeBox = code && lang ? highlightCode(code, { lang }) : \"\";\n if (codeBox) {\n message += \"\\n\" + codeBox;\n }\n\n if (options.level === \"warning\") {\n Log.warn(message);\n return;\n }\n\n Log.error(message);\n };\n}\n\nexport const printFmtError = PrintFormattedError.create();\n\nfunction isHtmlNode(node: Node): node is HtmlNode {\n return \"nodeType\" in node && typeof node.nodeType === \"number\";\n}\n\nfunction isPostcssNode(node: Node): node is PostcssNode {\n return node instanceof PostcssNode;\n}\n\nfunction nodeToString(node: Node): { code: string; lang: string } {\n if (isHtmlNode(node)) {\n const clone = node.clone();\n if (clone.nodeType === NodeType.ELEMENT_NODE) {\n (clone as HTMLElement).removeAttribute(CUSTOM_ATTRIBUTES.MetadataID);\n }\n\n return { code: clone.toString(), lang: \"html\" };\n }\n\n if (isPostcssNode(node)) {\n return { code: node.toString(), lang: \"css\" };\n }\n\n return { code: generator(node, { jsescOption: { minimal: true } }).code, lang: \"js\" };\n}\n","export type ValueOrError<T> = [T, null] | [null, Error];\n\nfunction errorsWrapper<T, A extends unknown[]>(function_: (...arguments_: A) => T | Promise<T>) {\n return (...arguments_: A) => {\n try {\n const promiseOrValue = function_(...arguments_);\n if (isPromise<T>(promiseOrValue)) {\n return new Promise(resolve => {\n promiseOrValue\n .then(value => {\n resolve([value, null]);\n })\n .catch((error: unknown) => {\n resolve(handleError(error, function_.name));\n });\n });\n }\n return [promiseOrValue, null];\n } catch (error) {\n return handleError(error, function_.name);\n }\n };\n}\n\nfunction isPromise<T>(value: T | Promise<T>): value is Promise<T> {\n return (\n value &&\n typeof value === \"object\" &&\n \"then\" in value &&\n typeof value.then === \"function\" &&\n \"catch\" in value &&\n typeof value.catch === \"function\"\n );\n}\n\nexport function handleError<T>(error: unknown, functionName = \"\"): ValueOrError<T> {\n if (!error) {\n return [null, new Error(`[${functionName}] Unexpected error`)];\n }\n\n if (typeof error === \"string\") {\n return [null, new Error(error)];\n }\n\n if (error instanceof Error) {\n return [null, error];\n }\n\n // in some cases the error is not an instance of Error but an object\n if (typeof error === \"object\" && \"message\" in error && typeof error.message === \"string\") {\n return [null, new Error(error.message)];\n }\n\n return [null, new Error(`[${functionName}] Unexpected error`)];\n}\n\ninterface goErrorsI {\n <T, A extends unknown[]>(function_: (...arguments_: A) => Promise<T>): (...arguments_: A) => Promise<ValueOrError<T>>;\n <T, A extends unknown[]>(function_: (...arguments_: A) => T): (...arguments_: A) => ValueOrError<T>;\n}\n\nexport const valueOrError = errorsWrapper as unknown as goErrorsI;\n","import type { Abortable } from \"node:events\";\nimport { readFileSync } from \"node:fs\";\nimport type { ObjectEncodingOptions, OpenMode, PathLike, PathOrFileDescriptor } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport type { FileHandle } from \"node:fs/promises\";\n\nimport { handleError } from \"./value-or-error.ts\";\n\nimport type { ValueOrError } from \"./value-or-error.ts\";\n\nexport async function safeReadFile(\n path: PathLike | FileHandle,\n options?:\n | ({\n encoding?: null | undefined;\n flag?: OpenMode | undefined;\n } & Abortable)\n | null\n): Promise<ValueOrError<Buffer>>;\n\nexport async function safeReadFile(\n path: PathLike | FileHandle,\n options:\n | ({\n encoding: BufferEncoding;\n flag?: OpenMode | undefined;\n } & Abortable)\n | BufferEncoding\n): Promise<ValueOrError<string>>;\n\nexport async function safeReadFile(\n path: PathLike | FileHandle,\n options?:\n | (ObjectEncodingOptions &\n Abortable & {\n flag?: OpenMode | undefined;\n })\n | BufferEncoding\n | null\n): Promise<ValueOrError<string | Buffer>>;\n\nexport async function safeReadFile(\n path: PathLike | FileHandle,\n options?:\n | (ObjectEncodingOptions &\n Abortable & {\n flag?: OpenMode | undefined;\n })\n | BufferEncoding\n | null\n): Promise<ValueOrError<string | Buffer>> {\n try {\n const string_ = await readFile(path, options);\n return [string_, null];\n } catch (error) {\n return handleError(error, \"readFile\");\n }\n}\n\nexport function safeReadFileSync(\n path: PathOrFileDescriptor,\n options?: {\n encoding?: null | undefined;\n flag?: string | undefined;\n } | null\n): ValueOrError<NonSharedBuffer>;\n\nexport function safeReadFileSync(\n path: PathOrFileDescriptor,\n options:\n | {\n encoding: BufferEncoding;\n flag?: string | undefined;\n }\n | BufferEncoding\n): ValueOrError<string>;\n\nexport function safeReadFileSync(\n path: PathOrFileDescriptor,\n options?:\n | (ObjectEncodingOptions & {\n flag?: string | undefined;\n })\n | BufferEncoding\n | null\n): ValueOrError<string | NonSharedBuffer>;\n\nexport function safeReadFileSync(\n path: PathOrFileDescriptor,\n options?:\n | (ObjectEncodingOptions & {\n flag?: string | undefined;\n })\n | BufferEncoding\n | null\n): ValueOrError<string | NonSharedBuffer> {\n try {\n const string_ = readFileSync(path, options);\n return [string_, null];\n } catch (error) {\n return handleError(error, \"readFileSync\");\n }\n}\n","import { createHash } from \"node:crypto\";\n\nimport { Log } from \"./logger.ts\";\n\nimport type { ValueOrError } from \"./value-or-error.ts\";\n\n/** `process.stdout.write` */\nexport function print(...input: string[]) {\n process.stdout.write(input.join(\" \"));\n}\n\n/** - Clear the line in the terminal */\nexport function clearLn() {\n if (\"clearLine\" in process.stdout && typeof process.stdout.clearLine === \"function\") {\n process.stdout.clearLine(0);\n process.stdout.cursorTo(0);\n }\n}\n\n/** Used to assign a computed value to a variable */\nexport function assign<T>(function_: () => T): T {\n return function_();\n}\n\n/** Check if the value is an object */\nexport function isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && !Array.isArray(value) && value !== null;\n}\n\nexport function kebabToCamelCase(string_: string): string {\n return string_.replace(/-([a-z])/g, (_, char) => (char as string).toUpperCase());\n}\n\nexport function camelCaseToKebabCase(string_: string): string {\n return string_.replace(/([a-z])([A-Z])/g, \"$1-$2\").toLowerCase();\n}\n\nexport function capitalize(string_: string): string {\n return string_.charAt(0).toUpperCase() + string_.slice(1);\n}\n\n/**\n * - Get line and column number from first match index\n *\n * @param code - Code string\n * @param matchIndex - Matching index\n * @returns - `[line, column]`\n */\nexport function getLineColumn(code: string, matchIndex: number): [number, number] {\n let lineNumber = 1;\n let columnNumber = 1;\n\n for (let index = 0; index < matchIndex; index++) {\n if (code[index] === \"\\n\") {\n lineNumber++;\n columnNumber = 1; // Reset column at each new line\n continue;\n }\n\n columnNumber++;\n }\n\n return [lineNumber, columnNumber];\n}\n\n/** - Human readable bytes, E.g: `1024 => 1KB` */\nexport function humanReadableBytes(bytes: number): string {\n const units = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"];\n let unitIndex = 0;\n while (bytes >= 1024 && unitIndex < units.length - 1) {\n bytes /= 1024;\n unitIndex++;\n }\n return `${bytes.toFixed(2)} ${units[unitIndex]}`;\n}\n\nexport function bytesToKB(bytes: number): number {\n return bytes / 1024;\n}\n\n/** - Clamp a numeric value between min and max values. */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nexport function isDefined<T>(value: T | undefined): value is T {\n return value !== undefined;\n}\n\n/**\n * Merges all entries from `source` into `target`, mutating `target` in place.\n *\n * - Existing keys in `target` are overwritten by `source` values.\n * - Values are **not** cloned — object references are shared between both maps after the merge.\n *\n * @param target - The map to be mutated with new/updated entries.\n * @param source - The map whose entries are read and applied to `target`.\n * @returns The mutated `target` map.\n */\nexport function mergeMaps<K, V>(target: Map<K, V>, source: Map<K, V>): Map<K, V> {\n for (const [key, value] of source) {\n target.set(key, value);\n }\n return target;\n}\n\nconst cached = new Map<string, string>();\n\n/** - Download from CDN */\nexport async function downloadContent(url: string): Promise<ValueOrError<string>> {\n if (cached.has(url)) {\n return [cached.get(url)!, null];\n }\n\n const headers = {\n \"User-Agent\":\n \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36\",\n Accept: \"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\",\n Referer: url,\n };\n\n try {\n Log.info(`Downloading content from \"${url}\"`);\n const response = await fetch(url, { headers });\n const text = await response.text();\n cached.set(url, text);\n return [text, null];\n } catch {\n return [null, new Error(\"Error downloading q: \" + url)];\n }\n}\n\nexport function isURL(url: string): boolean {\n return url.startsWith(\"http://\") || url.startsWith(\"https://\");\n}\n\n/** Creates a shallow clone of an object while preserving its prototype and property descriptors. */\nexport function cloneObject<T extends object>(object: T): T {\n return Object.create(Object.getPrototypeOf(object) as T, Object.getOwnPropertyDescriptors(object)) as T;\n}\n\nexport function hashContent(content: string) {\n return createHash(\"sha1\").update(content).digest(\"hex\"); // full 40 chars\n}\n\nconst matchHtmlRegExp = /[\"'&<>]/;\n\nexport function escapeHtml(input: string) {\n const string = \"\" + input;\n const match = matchHtmlRegExp.exec(string);\n\n if (!match) {\n return string;\n }\n\n let escape;\n let html = \"\";\n // eslint-disable-next-line no-useless-assignment\n let index = 0;\n let lastIndex = 0;\n\n for (index = match.index; index < string.length; index++) {\n switch (string.codePointAt(index)) {\n case 34: // \"\n escape = \""\";\n break;\n case 38: // &\n escape = \"&\";\n break;\n case 39: // '\n escape = \"'\";\n break;\n case 60: // <\n escape = \"<\";\n break;\n case 62: // >\n escape = \">\";\n break;\n default:\n continue;\n }\n\n if (lastIndex !== index) {\n html += string.slice(lastIndex, index);\n }\n\n lastIndex = index + 1;\n html += escape;\n }\n\n return lastIndex === index ? html : html + string.slice(lastIndex, index);\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@staticbolt/core",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.5",
|
|
4
4
|
"description": "Static website builder",
|
|
5
5
|
"private": false,
|
|
6
6
|
"license": "MIT",
|
|
@@ -54,8 +54,8 @@
|
|
|
54
54
|
"chalk": "^5.6.2",
|
|
55
55
|
"chokidar": "^5.0.0",
|
|
56
56
|
"comment-parser": "^1.4.6",
|
|
57
|
-
"cssnano": "^8.0.
|
|
58
|
-
"cssnano-preset-default": "^8.0.
|
|
57
|
+
"cssnano": "^8.0.1",
|
|
58
|
+
"cssnano-preset-default": "^8.0.1",
|
|
59
59
|
"emphasize": "^7.0.0",
|
|
60
60
|
"esbuild": "^0.28.0",
|
|
61
61
|
"fastify": "^5.8.5",
|
|
@@ -84,11 +84,11 @@
|
|
|
84
84
|
"remark-smartypants": "^3.0.2",
|
|
85
85
|
"sharp": "^0.34.5",
|
|
86
86
|
"svgo": "^4.0.1",
|
|
87
|
-
"terser": "^5.
|
|
87
|
+
"terser": "^5.47.1",
|
|
88
88
|
"ttf2woff2": "^8.0.1",
|
|
89
89
|
"workbox-build": "^7.4.1",
|
|
90
|
-
"ws": "^8.20.
|
|
91
|
-
"yaml": "^2.
|
|
90
|
+
"ws": "^8.20.1",
|
|
91
|
+
"yaml": "^2.9.0",
|
|
92
92
|
"zod": "^4.4.3"
|
|
93
93
|
},
|
|
94
94
|
"devDependencies": {
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
"@types/babel__traverse": "^7.28.0",
|
|
99
99
|
"@types/fontkit": "^2.0.9",
|
|
100
100
|
"@types/html-minifier-terser": "^7.0.2",
|
|
101
|
-
"@types/jsdom": "^28.0.
|
|
101
|
+
"@types/jsdom": "^28.0.3",
|
|
102
102
|
"@types/mdast": "^4.0.4",
|
|
103
103
|
"@types/micromatch": "^4.0.10",
|
|
104
104
|
"@types/postcss-import": "^14.0.3",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dependency-tracker-BuZfopIj.mjs","names":["chalk","PostcssNode","#sourcesToImporters","#importerToSources"],"sources":["../src/types/metadata.ts","../src/helpers/is-script-type.ts","../src/utilities/metadata-utilities.ts","../src/helpers/babel-fixed-imports.ts","../src/utilities/highlight-code.ts","../src/utilities/print-formatted-error.ts","../src/utilities/value-or-error.ts","../src/utilities/read-file.ts","../src/utilities/utilities.ts","../src/helpers/dependency-tracker.ts"],"sourcesContent":["import type { BabelAst, PostcssAst, Document, MarkdownAst } from \"@staticbolt/core\";\nimport type { WebAppManifest } from \"web-app-manifest\";\n\nexport const METADATA_TYPES = Object.freeze({\n Script: \"Script\",\n HTML: \"Html\",\n Markdown: \"Markdown\",\n CSS: \"Style\",\n SVG: \"Svg\",\n Package: \"Package\",\n TextAsset: \"TextAsset\",\n BinaryAsset: \"BinaryAsset\",\n WebAppManifest: \"WebAppManifest\",\n});\n\nexport type MetadataTypes = (typeof METADATA_TYPES)[keyof typeof METADATA_TYPES];\n\nexport interface MetadataBase {\n readonly type: `${Capitalize<string>}${string}`;\n\n /**\n * Relative path of the source file.\n *\n * Initially identical to `originalSource` when the metadata is created. During the build process, this value may change (e.g.,\n * if the file is moved to a different location and its links are rebased).\n */\n filePath: string;\n\n /**\n * Original relative path of the source file.\n *\n * Set when the metadata is created and never modified.\n */\n readonly id: string;\n\n readonly directDependencies: Set<string>;\n}\n\nexport interface ScriptMetadata extends MetadataBase {\n readonly type: (typeof METADATA_TYPES)[\"Script\"];\n\n /**\n * The Babel AST for the script.\n *\n * Mutated during the build process and always represents the file's current transformed state.\n */\n ast: BabelAst;\n\n /** Whether the script is a module or global */\n module: boolean;\n}\n\nexport interface StyleMetadata extends MetadataBase {\n readonly type: (typeof METADATA_TYPES)[\"CSS\"];\n\n /**\n * The PostCSS root after transformation\n *\n * Mutated during the build process and always represents the file's current transformed state.\n */\n ast: PostcssAst;\n}\n\nexport interface HtmlMetadata extends MetadataBase {\n type: (typeof METADATA_TYPES)[\"HTML\"];\n\n /**\n * The HTML AST (root element).\n *\n * Mutated during the build process and always represents the file's current transformed state\n */\n ast: Document;\n\n /** The transformed ASTs from script tags. The key is the UUID */\n scriptsMetadataList: Map<string, ScriptMetadata>;\n\n /** The transformed ASTs from script tags. The key is the UUID */\n stylesMetadataList: Map<string, StyleMetadata>;\n}\n\nexport interface SvgMetadata extends MetadataBase {\n type: (typeof METADATA_TYPES)[\"SVG\"];\n\n /**\n * The HTML AST (root element).\n *\n * Mutated during the build process and always represents the file's current transformed state\n */\n ast: Document;\n\n /** The transformed ASTs from script tags. The key is the UUID */\n stylesMetadataList: Map<string, StyleMetadata>;\n}\n\nexport interface MarkdownMetadata extends MetadataBase {\n type: (typeof METADATA_TYPES)[\"Markdown\"];\n\n /**\n * Markdown tokens and frontmatter.\n *\n * Mutated during the build process and always represents the file's current transformed state\n */\n ast: MarkdownAst;\n}\n\nexport interface WebManifestMetadata extends MetadataBase {\n type: (typeof METADATA_TYPES)[\"WebAppManifest\"];\n ast: WebAppManifest;\n}\n\nexport interface PackageMetadata extends MetadataBase {\n type: (typeof METADATA_TYPES)[\"Package\"];\n\n /** Metadata code */\n code: string;\n\n packageName: string;\n}\n\nexport interface TextAssetMetadata extends MetadataBase {\n type: (typeof METADATA_TYPES)[\"TextAsset\"];\n\n /** Metadata code */\n code: string;\n}\n\nexport interface BinaryAssetMetadata extends MetadataBase {\n type: (typeof METADATA_TYPES)[\"BinaryAsset\"];\n\n /** Raw binary content — images, fonts, wasm, etc. */\n data?: Uint8Array;\n}\n","const allowedTypes = new Set([\n \"module\",\n \"text/javascript\",\n \"application/javascript\",\n \"text/ecmascript\",\n \"application/ecmascript\",\n \"application/x-javascript\",\n]);\n\nexport function isScriptType(type: string | null) {\n return !type || allowedTypes.has(type.toLowerCase());\n}\n","import { isScriptType } from \"../helpers/is-script-type.ts\";\nimport { CUSTOM_ATTRIBUTES } from \"../types/common.ts\";\nimport { METADATA_TYPES } from \"../types/metadata.ts\";\n\nimport type {\n TextAssetMetadata,\n HtmlMetadata,\n MarkdownMetadata,\n MetadataBase,\n ScriptMetadata,\n StyleMetadata,\n SvgMetadata,\n WebManifestMetadata,\n BinaryAssetMetadata,\n PackageMetadata,\n HTMLElement,\n} from \"@staticbolt/core\";\n\nexport function isScriptMetadata(metadata: MetadataBase | undefined): metadata is ScriptMetadata {\n return metadata?.type === METADATA_TYPES.Script;\n}\n\nexport function isPackageMetadata(metadata: MetadataBase | undefined): metadata is PackageMetadata {\n return metadata?.type === METADATA_TYPES.Package;\n}\n\nexport function isHtmlMetadata(metadata: MetadataBase | undefined): metadata is HtmlMetadata {\n return metadata?.type === METADATA_TYPES.HTML;\n}\n\nexport function isStyleMetadata(metadata: MetadataBase | undefined): metadata is StyleMetadata {\n return metadata?.type === METADATA_TYPES.CSS;\n}\n\nexport function isSvgMetadata(metadata: MetadataBase | undefined): metadata is SvgMetadata {\n return metadata?.type === METADATA_TYPES.SVG;\n}\n\nexport function isMarkdownMetadata(metadata: MetadataBase | undefined): metadata is MarkdownMetadata {\n return metadata?.type === METADATA_TYPES.Markdown;\n}\n\nexport function isTextAssetMetadata(metadata: MetadataBase | undefined): metadata is TextAssetMetadata {\n return metadata?.type === METADATA_TYPES.TextAsset;\n}\n\nexport function isBinaryAssetMetadata(metadata: MetadataBase | undefined): metadata is BinaryAssetMetadata {\n return metadata?.type === METADATA_TYPES.BinaryAsset;\n}\n\nexport function isWebManifestMetadata(metadata: MetadataBase): metadata is WebManifestMetadata {\n return metadata.type === METADATA_TYPES.WebAppManifest;\n}\n\n/**\n * Returns script-related metadata entries.\n *\n * - If the input is ScriptMetadata, it returns it directly.\n * - If the input is HtmlMetadata, it scans <script> tags in the AST and resolves their associated ScriptMetadata using the metadata\n * ID attribute.\n */\nexport function filterScriptMetadata(metadata: MetadataBase) {\n const result: { metadata: ScriptMetadata; tag?: HTMLElement; htmlMetadata?: HtmlMetadata }[] = [];\n\n if (isScriptMetadata(metadata)) {\n result.push({ metadata });\n return result;\n }\n\n if (isHtmlMetadata(metadata)) {\n const scriptTags = metadata.ast.querySelectorAll(\"script\");\n\n for (const scriptTag of scriptTags) {\n const scriptId = scriptTag.getAttribute(CUSTOM_ATTRIBUTES.MetadataID);\n if (!scriptId) continue;\n\n const scriptType = scriptTag.getAttribute(\"type\");\n if (!isScriptType(scriptType)) {\n continue;\n }\n\n const scriptMetadata = metadata.scriptsMetadataList.get(scriptId);\n if (!scriptMetadata) continue;\n\n result.push({ metadata: scriptMetadata, htmlMetadata: metadata, tag: scriptTag });\n }\n }\n\n return result;\n}\n\n/**\n * Returns style-related metadata entries.\n *\n * - If the input is StyleMetadata, it returns it directly.\n * - If the input is HtmlMetadata, it scans <style> tags in the AST and resolves their associated StyleMetadata using the metadata\n * ID attribute.\n */\nexport function filterStyleMetadata(metadata: MetadataBase) {\n const result: { metadata: StyleMetadata; tag?: HTMLElement; htmlMetadata?: HtmlMetadata }[] = [];\n\n if (isStyleMetadata(metadata)) {\n result.push({ metadata });\n return result;\n }\n\n if (isHtmlMetadata(metadata)) {\n const styleTags = metadata.ast.querySelectorAll(\"style\");\n\n for (const styleTag of styleTags) {\n const styleId = styleTag.getAttribute(CUSTOM_ATTRIBUTES.MetadataID) || \"\";\n const styleMetadata = metadata.stylesMetadataList.get(styleId);\n if (!styleMetadata) continue;\n\n result.push({\n metadata: styleMetadata,\n htmlMetadata: metadata,\n tag: styleTag,\n });\n }\n }\n\n return result;\n}\n","import _generator from \"@babel/generator\";\nimport _traverse from \"@babel/traverse\";\n\nconst generator = typeof _generator === \"function\" ? _generator : _generator.default;\n\nconst traverse = typeof _traverse === \"function\" ? _traverse : _traverse.default;\n\nexport { generator, traverse };\n","import boxen from \"boxen\";\nimport chalk from \"chalk\";\nimport { common, createEmphasize } from \"emphasize\";\n\n/** - Highlight code string for terminal */\nexport function highlightCode(code: string, { lang = \"ts\", maxCodeLength = 170, maxLineLength = 110, boxed = true } = {}) {\n // Limit code length\n const isTruncated = code.length > maxCodeLength;\n if (isTruncated) code = code.slice(0, Math.max(0, maxCodeLength));\n\n // Limit line length and break on words\n const lines = code.split(\"\\n\");\n let withNewLines = \"\";\n for (const line of lines) {\n if (line.length <= maxLineLength) {\n withNewLines += line + \"\\n\";\n continue;\n }\n\n const words = line.split(\" \");\n let currentLine = \"\";\n for (const word of words) {\n if (currentLine.length + word.length <= maxLineLength) {\n currentLine += word + \" \";\n continue;\n }\n withNewLines += currentLine + \"\\n\";\n currentLine = word + \" \";\n }\n withNewLines += currentLine + \"\\n\";\n }\n\n // Highlight\n let highlighted = createEmphasize(common).highlight(lang, withNewLines.trim()).value;\n if (isTruncated) highlighted += \"\\n\" + chalk.inverse(\" ... \");\n\n if (!boxed) return highlighted;\n\n return boxen(highlighted, {\n padding: 0.5,\n borderStyle: \"round\",\n borderColor: \"white\",\n dimBorder: true,\n });\n}\n","import { NodeType } from \"@staticbolt/node-html-parser\";\nimport c from \"chalk\";\nimport { Node as PostcssNode } from \"postcss\";\n\nimport { generator } from \"../helpers/babel-fixed-imports.ts\";\nimport { CUSTOM_ATTRIBUTES } from \"../types/common.ts\";\nimport { highlightCode } from \"./highlight-code.ts\";\nimport { Log } from \"./logger.ts\";\n\nimport type { Node as BabelNode } from \"@babel/types\";\nimport type { HTMLElement, Node as HtmlNode } from \"@staticbolt/node-html-parser\";\n\ntype Node = BabelNode | PostcssNode | HtmlNode;\n\ninterface FormatErrorOptions {\n /** AST node (e.g., from Babel, PostCSS, or HTML) to convert and highlight */\n node?: Node;\n\n /** Source code to highlight (use instead of `node`) */\n code?: string;\n\n /** Language of the provided source code (required if `code` is set) */\n lang?: string;\n\n /** Path of the file where the error occurred */\n filePath?: string;\n\n /** Name of the function where the error originated */\n functionName?: string;\n\n level?: \"error\" | \"warning\";\n\n /** Function reference used to extract the function name */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n function?: (...arguments_: any[]) => any;\n}\n\ntype MessageAndError = (string | Error)[];\n\nexport class PrintFormattedError {\n options: FormatErrorOptions = {};\n\n constructor(options: FormatErrorOptions = {}) {\n Object.assign(this.options, options);\n }\n\n static create(options: FormatErrorOptions = {}) {\n return new PrintFormattedError(options).print;\n }\n\n print = (...messageAndErrorWithOptions: [...MessageAndError] | [...MessageAndError, FormatErrorOptions]) => {\n const options: FormatErrorOptions = { ...this.options };\n\n const messagesArray: string[] = [];\n for (const item of messageAndErrorWithOptions) {\n // Msg\n if (typeof item === \"string\") {\n messagesArray.push(item);\n continue;\n }\n\n // Error\n if (item instanceof Error) {\n messagesArray.push(`\\n${item.message}`);\n continue;\n }\n\n // Options\n Object.assign(options, item);\n }\n\n let message = \"\";\n\n // First file path in one line without anything else to enable vscode link parsing\n if (options.filePath) {\n message += c.italic(options.filePath) + \"\\n\";\n }\n\n // Then the function name before the messages\n const functionName = options.function?.name ?? options.functionName;\n if (functionName) {\n message += c.dim(`[${functionName}] `);\n }\n\n // Then the messages (spaced)\n message += messagesArray.join(\" \");\n\n // Now the code\n const codeFromNode = options.node && nodeToString(options.node);\n const code = options.code ?? codeFromNode?.code;\n const lang = options.lang ?? codeFromNode?.lang;\n const codeBox = code && lang ? highlightCode(code, { lang }) : \"\";\n if (codeBox) {\n message += \"\\n\" + codeBox;\n }\n\n if (options.level === \"warning\") {\n Log.warn(message);\n return;\n }\n\n Log.error(message);\n };\n}\n\nexport const printFmtError = PrintFormattedError.create();\n\nfunction isHtmlNode(node: Node): node is HtmlNode {\n return \"nodeType\" in node && typeof node.nodeType === \"number\";\n}\n\nfunction isPostcssNode(node: Node): node is PostcssNode {\n return node instanceof PostcssNode;\n}\n\nfunction nodeToString(node: Node): { code: string; lang: string } {\n if (isHtmlNode(node)) {\n const clone = node.clone();\n if (clone.nodeType === NodeType.ELEMENT_NODE) {\n (clone as HTMLElement).removeAttribute(CUSTOM_ATTRIBUTES.MetadataID);\n }\n\n return { code: clone.toString(), lang: \"html\" };\n }\n\n if (isPostcssNode(node)) {\n return { code: node.toString(), lang: \"css\" };\n }\n\n return { code: generator(node, { jsescOption: { minimal: true } }).code, lang: \"js\" };\n}\n","export type ValueOrError<T> = [T, null] | [null, Error];\n\nfunction errorsWrapper<T, A extends unknown[]>(function_: (...arguments_: A) => T | Promise<T>) {\n return (...arguments_: A) => {\n try {\n const promiseOrValue = function_(...arguments_);\n if (isPromise<T>(promiseOrValue)) {\n return new Promise(resolve => {\n promiseOrValue\n .then(value => {\n resolve([value, null]);\n })\n .catch((error: unknown) => {\n resolve(handleError(error, function_.name));\n });\n });\n }\n return [promiseOrValue, null];\n } catch (error) {\n return handleError(error, function_.name);\n }\n };\n}\n\nfunction isPromise<T>(value: T | Promise<T>): value is Promise<T> {\n return (\n value &&\n typeof value === \"object\" &&\n \"then\" in value &&\n typeof value.then === \"function\" &&\n \"catch\" in value &&\n typeof value.catch === \"function\"\n );\n}\n\nexport function handleError<T>(error: unknown, functionName = \"\"): ValueOrError<T> {\n if (!error) {\n return [null, new Error(`[${functionName}] Unexpected error`)];\n }\n\n if (typeof error === \"string\") {\n return [null, new Error(error)];\n }\n\n if (error instanceof Error) {\n return [null, error];\n }\n\n // in some cases the error is not an instance of Error but an object\n if (typeof error === \"object\" && \"message\" in error && typeof error.message === \"string\") {\n return [null, new Error(error.message)];\n }\n\n return [null, new Error(`[${functionName}] Unexpected error`)];\n}\n\ninterface goErrorsI {\n <T, A extends unknown[]>(function_: (...arguments_: A) => Promise<T>): (...arguments_: A) => Promise<ValueOrError<T>>;\n <T, A extends unknown[]>(function_: (...arguments_: A) => T): (...arguments_: A) => ValueOrError<T>;\n}\n\nexport const valueOrError = errorsWrapper as unknown as goErrorsI;\n","import type { Abortable } from \"node:events\";\nimport { readFileSync } from \"node:fs\";\nimport type { ObjectEncodingOptions, OpenMode, PathLike, PathOrFileDescriptor } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport type { FileHandle } from \"node:fs/promises\";\n\nimport { handleError } from \"./value-or-error.ts\";\n\nimport type { ValueOrError } from \"./value-or-error.ts\";\n\nexport async function safeReadFile(\n path: PathLike | FileHandle,\n options?:\n | ({\n encoding?: null | undefined;\n flag?: OpenMode | undefined;\n } & Abortable)\n | null\n): Promise<ValueOrError<Buffer>>;\n\nexport async function safeReadFile(\n path: PathLike | FileHandle,\n options:\n | ({\n encoding: BufferEncoding;\n flag?: OpenMode | undefined;\n } & Abortable)\n | BufferEncoding\n): Promise<ValueOrError<string>>;\n\nexport async function safeReadFile(\n path: PathLike | FileHandle,\n options?:\n | (ObjectEncodingOptions &\n Abortable & {\n flag?: OpenMode | undefined;\n })\n | BufferEncoding\n | null\n): Promise<ValueOrError<string | Buffer>>;\n\nexport async function safeReadFile(\n path: PathLike | FileHandle,\n options?:\n | (ObjectEncodingOptions &\n Abortable & {\n flag?: OpenMode | undefined;\n })\n | BufferEncoding\n | null\n): Promise<ValueOrError<string | Buffer>> {\n try {\n const string_ = await readFile(path, options);\n return [string_, null];\n } catch (error) {\n return handleError(error, \"readFile\");\n }\n}\n\nexport function safeReadFileSync(\n path: PathOrFileDescriptor,\n options?: {\n encoding?: null | undefined;\n flag?: string | undefined;\n } | null\n): ValueOrError<NonSharedBuffer>;\n\nexport function safeReadFileSync(\n path: PathOrFileDescriptor,\n options:\n | {\n encoding: BufferEncoding;\n flag?: string | undefined;\n }\n | BufferEncoding\n): ValueOrError<string>;\n\nexport function safeReadFileSync(\n path: PathOrFileDescriptor,\n options?:\n | (ObjectEncodingOptions & {\n flag?: string | undefined;\n })\n | BufferEncoding\n | null\n): ValueOrError<string | NonSharedBuffer>;\n\nexport function safeReadFileSync(\n path: PathOrFileDescriptor,\n options?:\n | (ObjectEncodingOptions & {\n flag?: string | undefined;\n })\n | BufferEncoding\n | null\n): ValueOrError<string | NonSharedBuffer> {\n try {\n const string_ = readFileSync(path, options);\n return [string_, null];\n } catch (error) {\n return handleError(error, \"readFileSync\");\n }\n}\n","import { createHash } from \"node:crypto\";\n\nimport { Log } from \"./logger.ts\";\n\nimport type { ValueOrError } from \"./value-or-error.ts\";\n\n/** `process.stdout.write` */\nexport function print(...input: string[]) {\n process.stdout.write(input.join(\" \"));\n}\n\n/** - Clear the line in the terminal */\nexport function clearLn() {\n if (\"clearLine\" in process.stdout && typeof process.stdout.clearLine === \"function\") {\n process.stdout.clearLine(0);\n process.stdout.cursorTo(0);\n }\n}\n\n/** Used to assign a computed value to a variable */\nexport function assign<T>(function_: () => T): T {\n return function_();\n}\n\n/** Check if the value is an object */\nexport function isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && !Array.isArray(value) && value !== null;\n}\n\nexport function kebabToCamelCase(string_: string): string {\n return string_.replace(/-([a-z])/g, (_, char) => (char as string).toUpperCase());\n}\n\nexport function camelCaseToKebabCase(string_: string): string {\n return string_.replace(/([a-z])([A-Z])/g, \"$1-$2\").toLowerCase();\n}\n\nexport function capitalize(string_: string): string {\n return string_.charAt(0).toUpperCase() + string_.slice(1);\n}\n\n/**\n * - Get line and column number from first match index\n *\n * @param code - Code string\n * @param matchIndex - Matching index\n * @returns - `[line, column]`\n */\nexport function getLineColumn(code: string, matchIndex: number): [number, number] {\n let lineNumber = 1;\n let columnNumber = 1;\n\n for (let index = 0; index < matchIndex; index++) {\n if (code[index] === \"\\n\") {\n lineNumber++;\n columnNumber = 1; // Reset column at each new line\n continue;\n }\n\n columnNumber++;\n }\n\n return [lineNumber, columnNumber];\n}\n\n/** - Human readable bytes, E.g: `1024 => 1KB` */\nexport function humanReadableBytes(bytes: number): string {\n const units = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"];\n let unitIndex = 0;\n while (bytes >= 1024 && unitIndex < units.length - 1) {\n bytes /= 1024;\n unitIndex++;\n }\n return `${bytes.toFixed(2)} ${units[unitIndex]}`;\n}\n\nexport function bytesToKB(bytes: number): number {\n return bytes / 1024;\n}\n\n/** - Clamp a numeric value between min and max values. */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nexport function isDefined<T>(value: T | undefined): value is T {\n return value !== undefined;\n}\n\n/**\n * Merges all entries from `source` into `target`, mutating `target` in place.\n *\n * - Existing keys in `target` are overwritten by `source` values.\n * - Values are **not** cloned — object references are shared between both maps after the merge.\n *\n * @param target - The map to be mutated with new/updated entries.\n * @param source - The map whose entries are read and applied to `target`.\n * @returns The mutated `target` map.\n */\nexport function mergeMaps<K, V>(target: Map<K, V>, source: Map<K, V>): Map<K, V> {\n for (const [key, value] of source) {\n target.set(key, value);\n }\n return target;\n}\n\nconst cached = new Map<string, string>();\n\n/** - Download from CDN */\nexport async function downloadContent(url: string): Promise<ValueOrError<string>> {\n if (cached.has(url)) {\n return [cached.get(url)!, null];\n }\n\n const headers = {\n \"User-Agent\":\n \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36\",\n Accept: \"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\",\n Referer: url,\n };\n\n try {\n Log.info(`Downloading content from \"${url}\"`);\n const response = await fetch(url, { headers });\n const text = await response.text();\n cached.set(url, text);\n return [text, null];\n } catch {\n return [null, new Error(\"Error downloading q: \" + url)];\n }\n}\n\nexport function isURL(url: string): boolean {\n return url.startsWith(\"http://\") || url.startsWith(\"https://\");\n}\n\n/** Creates a shallow clone of an object while preserving its prototype and property descriptors. */\nexport function cloneObject<T extends object>(object: T): T {\n return Object.create(Object.getPrototypeOf(object) as T, Object.getOwnPropertyDescriptors(object)) as T;\n}\n\nexport function hashContent(content: string) {\n return createHash(\"sha1\").update(content).digest(\"hex\"); // full 40 chars\n}\n\nconst matchHtmlRegExp = /[\"'&<>]/;\n\nexport function escapeHtml(input: string) {\n const string = \"\" + input;\n const match = matchHtmlRegExp.exec(string);\n\n if (!match) {\n return string;\n }\n\n let escape;\n let html = \"\";\n // eslint-disable-next-line no-useless-assignment\n let index = 0;\n let lastIndex = 0;\n\n for (index = match.index; index < string.length; index++) {\n switch (string.codePointAt(index)) {\n case 34: // \"\n escape = \""\";\n break;\n case 38: // &\n escape = \"&\";\n break;\n case 39: // '\n escape = \"'\";\n break;\n case 60: // <\n escape = \"<\";\n break;\n case 62: // >\n escape = \">\";\n break;\n default:\n continue;\n }\n\n if (lastIndex !== index) {\n html += string.slice(lastIndex, index);\n }\n\n lastIndex = index + 1;\n html += escape;\n }\n\n return lastIndex === index ? html : html + string.slice(lastIndex, index);\n}\n","/**\n * Tracks bidirectional dependencies between importers and their sources.\\\n * Handles reconciliation when dependencies change, so stale entries are automatically removed when an importer stops referencing\n * a source.\n */\nexport class DependencyTracker {\n /** Source → Set of importers that depend on it */\n readonly #sourcesToImporters = new Map<string, Set<string>>();\n\n /** Importer → Set of sources it depends on */\n readonly #importerToSources = new Map<string, Set<string>>();\n\n /** Updates the full set of sources for a given importer, reconciling any stale entries from previous calls. */\n update(importer: string, sources: Iterable<string>): void {\n const nextSources = new Set(sources);\n const previousSources = this.#importerToSources.get(importer) ?? new Set();\n\n // Remove importer from sources it no longer uses\n for (const source of previousSources) {\n if (!nextSources.has(source)) {\n this.#sourcesToImporters.get(source)?.delete(importer);\n }\n }\n\n // Add importer to newly referenced sources\n for (const source of nextSources) {\n if (!this.#sourcesToImporters.has(source)) {\n this.#sourcesToImporters.set(source, new Set());\n }\n\n this.#sourcesToImporters.get(source)!.add(importer);\n }\n\n this.#importerToSources.set(importer, nextSources);\n }\n\n /** Deletes all dependency data for a given id, whether it's acting as an importer, a source, or both (e.g. on file unlink). */\n delete(id: string): void {\n // id was a source — drop it entirely\n this.#sourcesToImporters.delete(id);\n\n // id was an importer — remove it from all sources it referenced\n const sources = this.#importerToSources.get(id);\n if (sources) {\n for (const source of sources) {\n this.#sourcesToImporters.get(source)?.delete(id);\n }\n\n this.#importerToSources.delete(id);\n }\n }\n\n /** Returns all importers that depend on a given source, or an empty set. */\n getImporters(source: string): ReadonlySet<string> {\n return this.#sourcesToImporters.get(source) ?? new Set();\n }\n\n /** Returns all sources that a given importer depends on, or an empty set. */\n getSources(importer: string): ReadonlySet<string> {\n return this.#importerToSources.get(importer) ?? new Set();\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"logger-BuxMGhij.mjs","names":["chalk"],"sources":["../src/utilities/path.ts","../src/types/common.ts","../src/utilities/logger.ts"],"sourcesContent":["import nodePath from \"node:path\";\nimport micromatch from \"micromatch\";\n\nexport { basename, extname, isAbsolute, parse, resolve } from \"node:path\";\n\n// For ESM and CSS compatibility:\n// - Always use unix separators (except `resolve`, which returns an absolute path)\n// - Relative paths should always start with `./`\n\nconst separatorRe = /\\\\/g;\n\n/** Normalizes a path result to unix separators and ensures relative paths start with `./` */\nfunction unixify(path: string): string {\n const unix = path.replace(separatorRe, \"/\");\n\n // Example: dirname(\"index.html\") => \".\"\n if (unix === \".\") {\n return \"./\";\n }\n\n if (unix === \"/\" || nodePath.isAbsolute(unix)) {\n return unix;\n }\n\n if (unix.startsWith(\"./\") || unix.startsWith(\"../\")) {\n return unix;\n }\n\n return `./${unix}`;\n}\n\nexport const join = (...arguments_: string[]) => unixify(nodePath.join(...arguments_));\n\nexport const relative = (from: string, to: string) => unixify(nodePath.relative(from, to));\n\nexport const dirname = (path: string) => unixify(nodePath.dirname(path));\n\nexport const normalize = (path: string) => unixify(nodePath.normalize(path));\n\n/**\n * Recalculates the relative path for a resource after a file has been moved.\n *\n * @param source - The source found in the `oldPath` file.\n * @param oldPath - Absolute or relative original path of the file.\n * @param newPath - Absolute or relative new path of the file.\n * @returns The updated relative path from the new file's directory to the same resource.\n */\nexport function rebaseRelativePath(source: string, oldPath: string, newPath: string): string {\n return relative(dirname(newPath), join(dirname(oldPath), source));\n}\n\n/**\n * Checks if a path (child) is a subpath of another (parent).\n *\n * Note: both paths must be of the same type — either both absolute or both relative. Mixing them will produce incorrect results.\n *\n * @param parentDirectory - The parent directory.\n * @param childPath - The child path (file or directory).\n */\nexport function isSubpath(parentDirectory: string, childPath: string): boolean {\n if (childPath === \"./\") return false;\n const relativePath = relative(normalize(parentDirectory), normalize(childPath));\n return relativePath === \"\" || (!relativePath.startsWith(\"..\") && !nodePath.isAbsolute(relativePath));\n}\n\ninterface SourceRelativeToRootOptions {\n /** The root directory (absolute or resolvable) */\n root: string;\n /** The file path that contains the source path */\n filePath: string;\n /** The source path */\n sourcePath: string;\n}\n\n/** Calculates the relative path of a source path to the root. */\nexport function sourceRelativeToRoot({ root, filePath, sourcePath }: SourceRelativeToRootOptions): string {\n const absRoot = nodePath.resolve(root);\n return relative(absRoot, nodePath.join(absRoot, dirname(filePath), sourcePath));\n}\n\n/** Replaces the extension of a given path. */\nexport function replaceExtension(filePath: string, extension: string): string {\n const { dir, name } = nodePath.parse(filePath);\n return normalize(nodePath.format({ dir, name, ext: extension }));\n}\n\n/** Appends a forward slash to the end of a path if it doesn't already end with one. */\nexport const appendForwardSlash = (path: string) => (path.endsWith(\"/\") ? path : `${path}/`);\n\n/** Removes the leading `./` from a path. */\nexport const trimDotPrefix = (path: string) => (path.startsWith(\"./\") ? path.slice(2) : path);\n\n/** Returns the first segment of a path. */\nexport function firstPart(path: string): string {\n const cleaned = normalize(path).replace(/\\/$/, \"\");\n return cleaned.split(\"/\")[0] ?? \"\";\n}\n\ninterface MatchPathOptions {\n include: string | string[];\n ignore?: string | string[];\n root: string;\n}\n\n/** Checks if a file path matches a set of patterns. */\nexport function matchPath(filePath: string, { include, ignore, root }: MatchPathOptions): boolean {\n // Case: outside the root directory\n if (filePath.startsWith(\"..\")) {\n const match = micromatch.isMatch(join(root, filePath), include, { ignore });\n return match;\n }\n\n // Case: inside the root dir\n const withoutDotPrefix = filePath.replace(/^\\.\\//, \"\");\n const match = micromatch.isMatch(withoutDotPrefix, include, { cwd: root, ignore });\n\n return match;\n}\n","import type { ParseResult } from \"@babel/parser\";\nimport type { NodePath as NodePathT } from \"@babel/traverse\";\nimport type * as t from \"@babel/types\";\nimport type { Plugin } from \"@staticbolt/core\";\nimport type { Root } from \"mdast\";\nimport type postcss from \"postcss\";\n\nexport type NodePath<T = t.Node | null | undefined> = NodePathT<T>;\n\nexport type BabelAst = ParseResult;\nexport type PostcssAst = postcss.Root;\nexport type { HTMLElement, Document } from \"@staticbolt/node-html-parser\";\n\nexport interface MarkdownAst {\n root: Root;\n frontmatter: Record<string, string>;\n render(): Promise<string>;\n}\n\nexport const CUSTOM_ATTRIBUTES = Object.freeze({\n /** For script and style tags to grab the metadata */\n MetadataID: \"data-metadata-id\",\n});\n\nexport const CONFIG_FILE_NAME = \".staticbolt.ts\";\n\nexport interface AppConfig {\n root?: string;\n plugins?: (Plugin[] | Plugin)[];\n outdir?: string;\n production?: boolean;\n browserslist?: string[];\n}\n","import chalk from \"chalk\";\n\ntype ChalkInstance = typeof chalk;\n\nconst logConfig = {\n verboseEnabled: false,\n verboseFilter: null as null | RegExp,\n titleWidth: 10,\n spacer: \" \",\n style: {\n success: chalk.green,\n error: chalk.red,\n fatal: chalk.red,\n warning: chalk.yellow,\n verbose: chalk.dim,\n info: chalk.blueBright,\n tip: chalk.magenta,\n log: chalk.white,\n spacer: chalk.dim,\n },\n};\n\nexport function createLog(...defaultMessages: string[]) {\n function Log(...messages: unknown[]) {\n console.log(formatLogTitle(\"LOG\", logConfig.style.log), ...defaultMessages, ...messages);\n }\n\n Log.warn = (...messages: string[]) => {\n logFormatter(\"WARNING\", logConfig.style.warning, ...defaultMessages, ...messages);\n };\n\n Log.success = (...messages: string[]) => {\n logFormatter(\"SUCCESS\", logConfig.style.success, ...defaultMessages, ...messages);\n };\n\n Log.error = (...messages: string[]) => {\n logFormatter(\"ERROR\", logConfig.style.error, ...defaultMessages, ...messages);\n };\n\n Log.fatal = (...messages: string[]) => {\n logFormatter(\"FATAL\", logConfig.style.fatal, ...defaultMessages, ...messages);\n\n // eslint-disable-next-line unicorn/no-process-exit\n process.exit(1);\n };\n\n Log.info = (...messages: string[]) => {\n logFormatter(\"INFO\", logConfig.style.info, ...defaultMessages, ...messages);\n };\n\n Log.tip = (...messages: string[]) => {\n logFormatter(\"TIP\", logConfig.style.tip, ...defaultMessages, ...messages);\n };\n\n Log.debug = (...messages: string[]) => {\n if (!logConfig.verboseEnabled) return;\n\n const joined = defaultMessages.concat(messages).join(\" \");\n if (logConfig.verboseFilter && !logConfig.verboseFilter.test(joined)) return;\n\n logFormatter(\"DEBUG\", logConfig.style.verbose, joined);\n };\n\n Log.enableVerbose = (enabled: boolean) => {\n logConfig.verboseEnabled = enabled;\n };\n\n Log.setVerboseFilter = (filter: RegExp) => {\n logConfig.verboseFilter = filter;\n };\n\n return Log;\n}\n\n/**\n * - Prints a styled message to the console.\n *\n * @example\n * Log(\"Hello World!\"); // Prints: | LOG | Hello World! |\n * Log.success(\"Hello World!\"); // Prints: | SUCCESS | Hello World! |\n * Log.info(\"Hello World!\"); // Prints: | INFO | Hello World! |\n * Log.error(\"Hello World!\"); // Prints: | ERROR | Hello World! |\n * Log.fatal(\"Hello World!\"); // Prints: | FATAL | Hello World! |\n * Log.warn(\"Hello World!\"); // Prints: | WARNING | Hello World! |\n */\nexport const Log = createLog();\n\nfunction formatLogTitle(title: string, style: ChalkInstance) {\n const width = logConfig.titleWidth;\n const paddingLength = title.length >= width ? 0 : (width - title.length) / 2;\n const paddingStart = \" \".repeat(paddingLength);\n const paddingEnd = \" \".repeat(paddingLength);\n\n title = paddingStart + title + paddingEnd;\n\n // Ensure that the final string has width length\n title = title.padEnd(width, \" \");\n\n // apply style\n title = style(title + \"|\");\n\n return title;\n}\n\nfunction logFormatter(title: string, style: ChalkInstance, ...messages: string[]) {\n const { prefixNewlines, content, suffixNewlines } = splitOnNewline(messages);\n const formattedTitle = formatLogTitle(title, style);\n\n const splitByNewLines = content.split(\"\\n\");\n\n let message = \"\";\n for (const [index, splitByNewLine] of splitByNewLines.entries()) {\n if (index > 0) {\n const width = logConfig.titleWidth / logConfig.spacer.length;\n const spacer = logConfig.spacer.repeat(width).padEnd(logConfig.titleWidth);\n message += \"\\n\" + style.dim(spacer + \"↪ \");\n }\n\n message += splitByNewLine;\n }\n\n console.log(prefixNewlines + formattedTitle, message, suffixNewlines);\n}\n\nfunction splitOnNewline(input: string[]) {\n const message = input.join(\" \");\n\n // Check for leading newlines\n let newlineStart = 0;\n while (newlineStart < message.length && message[newlineStart] == \"\\n\") {\n newlineStart++;\n }\n\n // Check for trailing newlines\n let newlineEnd = message.length;\n while (newlineEnd > newlineStart && message[newlineEnd - 1] == \"\\n\") {\n newlineEnd--;\n }\n\n const results = {\n prefixNewlines: message.slice(0, Math.max(0, newlineStart)),\n content: message.slice(newlineStart, newlineEnd),\n suffixNewlines: message.slice(Math.max(0, newlineEnd)),\n };\n\n return results;\n}\n"],"mappings":"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"}
|