@staticbolt/core 1.0.0-beta.11 → 1.0.0-beta.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cli/index.mjs +1 -1
- package/lib/{logger-BfIn1ytK.mjs → common-Bkh8-tjA.mjs} +10 -10
- package/lib/common-Bkh8-tjA.mjs.map +1 -0
- package/lib/index.d.mts +5 -3
- package/lib/index.d.mts.map +1 -1
- package/lib/index.mjs +3 -3
- package/lib/index.mjs.map +1 -1
- package/lib/plugins/index.d.mts +2 -2
- package/lib/plugins/index.mjs +313 -267
- package/lib/plugins/index.mjs.map +1 -1
- package/lib/{utilities-CZmLMi93.mjs → utilities-Bu5rdDC9.mjs} +306 -54
- package/lib/utilities-Bu5rdDC9.mjs.map +1 -0
- package/package.json +5 -4
- package/lib/logger-BfIn1ytK.mjs.map +0 -1
- package/lib/utilities-CZmLMi93.mjs.map +0 -1
- /package/lib/{chunk-C7Uep-_p.mjs → chunk-DXywRVcq.mjs} +0 -0
package/lib/plugins/index.mjs
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { A as
|
|
2
|
-
import { _ as
|
|
1
|
+
import { A as isStyleMetadata, C as filterScriptMetadata, D as isMarkdownMetadata, E as isHtmlMetadata, F as METADATA_TYPES, H as isValidRelativePath, I as Resolver, L as readJsonFile, M as isTextAssetMetadata, N as isWebManifestMetadata, O as isPackageMetadata, P as isScriptType, S as traverse, T as isBinaryAssetMetadata, U as splitHtmlLink, V as valueOrError, W as DependencyTracker, _ as mergeMaps, b as printFmtError, c as downloadContent, d as hashContent, f as humanReadableBytes, h as isURL, j as isSvgMetadata, k as isScriptMetadata, l as escapeHtml, n as bytesToKB, s as cloneObject, w as filterStyleMetadata, x as generator, y as PrintFormattedError, z as safeReadFileSync } from "../utilities-Bu5rdDC9.mjs";
|
|
2
|
+
import { _ as resolve, a as basename, c as isAbsolute, d as matchPath, f as normalize, g as replaceExtension, h as relative, i as createLog, l as isSubpath, n as CUSTOM_ATTRIBUTES, o as dirname, p as parse$2, r as Log, s as extname, t as CONFIG_FILE_NAME, u as join } from "../common-Bkh8-tjA.mjs";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
|
+
import { copyFileSync, cpSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, rmdirSync, unlinkSync, writeFileSync } from "node:fs";
|
|
4
5
|
import nodePath from "node:path";
|
|
5
|
-
import { HTMLElement, NodeType, parse } from "@staticbolt/node-html-parser";
|
|
6
6
|
import c from "chalk";
|
|
7
|
+
import json5 from "json5";
|
|
8
|
+
import { HTMLElement, NodeType, parse } from "@staticbolt/node-html-parser";
|
|
7
9
|
import postcss from "postcss";
|
|
8
10
|
import { common, createEmphasize } from "emphasize";
|
|
9
|
-
import { copyFileSync, cpSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, rmdirSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
10
11
|
import { globSync } from "glob";
|
|
11
12
|
import { minify_sync } from "terser";
|
|
12
13
|
import * as esbuild from "esbuild";
|
|
13
14
|
import * as t from "@babel/types";
|
|
14
15
|
import sharp from "sharp";
|
|
15
|
-
import json5 from "json5";
|
|
16
16
|
import { generateSW } from "workbox-build";
|
|
17
17
|
import { optimize } from "svgo";
|
|
18
18
|
import postcssrc from "postcss-load-config";
|
|
@@ -47,46 +47,10 @@ import Fastify from "fastify";
|
|
|
47
47
|
import { WebSocketServer } from "ws";
|
|
48
48
|
import browserslistFn from "browserslist";
|
|
49
49
|
import chokidar from "chokidar";
|
|
50
|
-
import { ResolverFactory } from "oxc-resolver";
|
|
51
50
|
import ttf2woff2 from "ttf2woff2";
|
|
52
51
|
import * as z from "zod";
|
|
53
52
|
import * as fontKit from "fontkit";
|
|
54
53
|
|
|
55
|
-
//#region src/utilities/html-links.ts
|
|
56
|
-
/**
|
|
57
|
-
* Checks if the link is an HTML link (not a file link)
|
|
58
|
-
*
|
|
59
|
-
* @param source - The link
|
|
60
|
-
* @returns
|
|
61
|
-
*/
|
|
62
|
-
function isHtmlLink(source) {
|
|
63
|
-
return /^(?:#|https?|mailto:|tel:|url\(|ftp:|data:|javascript:)/i.test(source);
|
|
64
|
-
}
|
|
65
|
-
function isValidRelativePath(source) {
|
|
66
|
-
if (!source) return false;
|
|
67
|
-
if (isAbsolute(source)) return false;
|
|
68
|
-
if (isHtmlLink(source)) return false;
|
|
69
|
-
return true;
|
|
70
|
-
}
|
|
71
|
-
function splitHtmlLink(url) {
|
|
72
|
-
const qIndex = url.indexOf("?");
|
|
73
|
-
const hIndex = url.indexOf("#");
|
|
74
|
-
let delimIndex = -1;
|
|
75
|
-
if (qIndex !== -1 && hIndex !== -1) delimIndex = Math.min(qIndex, hIndex);
|
|
76
|
-
else if (qIndex !== -1) delimIndex = qIndex;
|
|
77
|
-
else if (hIndex !== -1) delimIndex = hIndex;
|
|
78
|
-
if (delimIndex !== -1) {
|
|
79
|
-
const pathEnd = url[delimIndex - 1] === "/" ? delimIndex - 1 : delimIndex;
|
|
80
|
-
return [url.slice(0, pathEnd), url.slice(pathEnd)];
|
|
81
|
-
}
|
|
82
|
-
if (url.endsWith("/")) {
|
|
83
|
-
if (url === "/" || url === "./") return [url, ""];
|
|
84
|
-
return [url.slice(0, -1), "/"];
|
|
85
|
-
}
|
|
86
|
-
return [url, ""];
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
//#endregion
|
|
90
54
|
//#region src/helpers/find-deps.ts
|
|
91
55
|
var DepsFinder = class {
|
|
92
56
|
#depsMap = /* @__PURE__ */ new Map();
|
|
@@ -1583,20 +1547,6 @@ async function loadPrettier(filePath) {
|
|
|
1583
1547
|
}
|
|
1584
1548
|
}
|
|
1585
1549
|
|
|
1586
|
-
//#endregion
|
|
1587
|
-
//#region src/utilities/read-json-file.ts
|
|
1588
|
-
/** Read a file and parse it as JSON safely. */
|
|
1589
|
-
function readJsonFile(path, code) {
|
|
1590
|
-
if (!code) {
|
|
1591
|
-
const [fileString, readError] = safeReadFileSync(path, "utf8");
|
|
1592
|
-
if (readError) return [null, readError];
|
|
1593
|
-
code = fileString;
|
|
1594
|
-
}
|
|
1595
|
-
const [parsed, parseError] = valueOrError(json5.parse)(code);
|
|
1596
|
-
if (parseError !== null) return [null, parseError];
|
|
1597
|
-
return [parsed, null];
|
|
1598
|
-
}
|
|
1599
|
-
|
|
1600
1550
|
//#endregion
|
|
1601
1551
|
//#region src/plugins/i18n/get-locales.ts
|
|
1602
1552
|
function getLocals(options) {
|
|
@@ -3067,6 +3017,28 @@ function htmlBuildTimeScript(options = {}) {
|
|
|
3067
3017
|
}
|
|
3068
3018
|
for (const node of metadata.ast.querySelectorAll(query)) node.remove();
|
|
3069
3019
|
}
|
|
3020
|
+
},
|
|
3021
|
+
lspHtmlData() {
|
|
3022
|
+
return {
|
|
3023
|
+
version: 1.1,
|
|
3024
|
+
tags: [{
|
|
3025
|
+
name: "script",
|
|
3026
|
+
attributes: [
|
|
3027
|
+
{
|
|
3028
|
+
name: buildAttribute,
|
|
3029
|
+
description: "This attribute is used to mark the script as build-time script."
|
|
3030
|
+
},
|
|
3031
|
+
{
|
|
3032
|
+
name: fullDomAttribute,
|
|
3033
|
+
description: "Opt into a full DOM context using `jsdom`. When not present, the lighter `@staticbolt/node-html-parser` is used instead."
|
|
3034
|
+
},
|
|
3035
|
+
{
|
|
3036
|
+
name: contextAttribute,
|
|
3037
|
+
description: "Pass global context object as JSON to be available in the script during execution."
|
|
3038
|
+
}
|
|
3039
|
+
]
|
|
3040
|
+
}]
|
|
3041
|
+
};
|
|
3070
3042
|
}
|
|
3071
3043
|
};
|
|
3072
3044
|
}
|
|
@@ -3326,6 +3298,32 @@ function htmlBundleScriptPlugin(options = {}) {
|
|
|
3326
3298
|
node.textContent = "";
|
|
3327
3299
|
this.addMetadata(newScriptMetadata);
|
|
3328
3300
|
}
|
|
3301
|
+
},
|
|
3302
|
+
lspHtmlData() {
|
|
3303
|
+
return {
|
|
3304
|
+
version: 1.1,
|
|
3305
|
+
tags: [{
|
|
3306
|
+
name: "script",
|
|
3307
|
+
attributes: [
|
|
3308
|
+
{
|
|
3309
|
+
name: bundleAttribute,
|
|
3310
|
+
description: "Enable script bundling."
|
|
3311
|
+
},
|
|
3312
|
+
{
|
|
3313
|
+
name: bundleOutAttribute,
|
|
3314
|
+
description: "Specify the output path for bundled scripts relative to the output directory.\nIf the script has a `src` attribute, the output path will default to `{filename}.bundle.js`.\nIf the script has no `src` attribute, the default behavior is to keep the script inline."
|
|
3315
|
+
},
|
|
3316
|
+
{
|
|
3317
|
+
name: externalsAttribute,
|
|
3318
|
+
description: `Glob patterns list to treat as external during bundling. (semicolon-separated)\n\nDefaults to "${defaultExternal.join(";")}".`
|
|
3319
|
+
},
|
|
3320
|
+
{
|
|
3321
|
+
name: externalsExcludeAttribute,
|
|
3322
|
+
description: `Glob patterns that exempt files from being treated as external, even if they match \`externals\`. (semicolon-separated)\n\nDefaults to "${defaultExternalExclude.join(";")}".`
|
|
3323
|
+
}
|
|
3324
|
+
]
|
|
3325
|
+
}]
|
|
3326
|
+
};
|
|
3329
3327
|
}
|
|
3330
3328
|
};
|
|
3331
3329
|
}
|
|
@@ -3395,6 +3393,24 @@ function htmlBundleStylePlugin(options = {}) {
|
|
|
3395
3393
|
continue;
|
|
3396
3394
|
}
|
|
3397
3395
|
}
|
|
3396
|
+
},
|
|
3397
|
+
lspHtmlData() {
|
|
3398
|
+
return {
|
|
3399
|
+
version: 1.1,
|
|
3400
|
+
tags: [{
|
|
3401
|
+
name: "link",
|
|
3402
|
+
attributes: [{
|
|
3403
|
+
name: bundleAttribute,
|
|
3404
|
+
description: "Enable style bundling."
|
|
3405
|
+
}]
|
|
3406
|
+
}, {
|
|
3407
|
+
name: "style",
|
|
3408
|
+
attributes: [{
|
|
3409
|
+
name: bundleAttribute,
|
|
3410
|
+
description: "Enable style bundling."
|
|
3411
|
+
}]
|
|
3412
|
+
}]
|
|
3413
|
+
};
|
|
3398
3414
|
}
|
|
3399
3415
|
};
|
|
3400
3416
|
}
|
|
@@ -3409,6 +3425,16 @@ function htmlFragmentPlugin(options = {}) {
|
|
|
3409
3425
|
if (!isHtmlMetadata(metadata)) return;
|
|
3410
3426
|
const elements = metadata.ast.querySelectorAll(tag);
|
|
3411
3427
|
for (const node of elements) node.replaceWith(node.innerHTML.trim());
|
|
3428
|
+
},
|
|
3429
|
+
lspHtmlData() {
|
|
3430
|
+
return {
|
|
3431
|
+
version: 1.1,
|
|
3432
|
+
tags: [{
|
|
3433
|
+
name: tag,
|
|
3434
|
+
description: "At build time, this tag is replaced with its contents.",
|
|
3435
|
+
attributes: []
|
|
3436
|
+
}]
|
|
3437
|
+
};
|
|
3412
3438
|
}
|
|
3413
3439
|
};
|
|
3414
3440
|
}
|
|
@@ -3504,6 +3530,18 @@ function htmlIifeScriptPlugin(options = {}) {
|
|
|
3504
3530
|
continue;
|
|
3505
3531
|
}
|
|
3506
3532
|
}
|
|
3533
|
+
},
|
|
3534
|
+
lspHtmlData() {
|
|
3535
|
+
return {
|
|
3536
|
+
version: 1.1,
|
|
3537
|
+
tags: [{
|
|
3538
|
+
name: "script",
|
|
3539
|
+
attributes: [{
|
|
3540
|
+
name: iifeAttribute,
|
|
3541
|
+
description: "Enabling this will wrap the script content in an IIFE (Immediately Invoked Function Expression).\n\nWorks only with inline global scripts."
|
|
3542
|
+
}]
|
|
3543
|
+
}]
|
|
3544
|
+
};
|
|
3507
3545
|
}
|
|
3508
3546
|
};
|
|
3509
3547
|
}
|
|
@@ -3550,6 +3588,18 @@ function htmlInlineScriptPlugin(options = {}) {
|
|
|
3550
3588
|
metadata.scriptsMetadataList.set(metadataID, scriptMetadataClone);
|
|
3551
3589
|
scriptTag.removeAttribute("src");
|
|
3552
3590
|
}
|
|
3591
|
+
},
|
|
3592
|
+
lspHtmlData() {
|
|
3593
|
+
return {
|
|
3594
|
+
version: 1.1,
|
|
3595
|
+
tags: [{
|
|
3596
|
+
name: "script",
|
|
3597
|
+
attributes: [{
|
|
3598
|
+
name: inlineAttribute,
|
|
3599
|
+
description: "Enable inlining external scripts directly into the HTML at build time. It supports local files, remote URLs."
|
|
3600
|
+
}]
|
|
3601
|
+
}]
|
|
3602
|
+
};
|
|
3553
3603
|
}
|
|
3554
3604
|
};
|
|
3555
3605
|
}
|
|
@@ -3615,6 +3665,18 @@ function htmlInlineStylePlugin(options = {}) {
|
|
|
3615
3665
|
const attributesString = Object.entries(linkTag.attrs).map(([name, value]) => `${name}="${value}"`).join(" ");
|
|
3616
3666
|
linkTag.replaceWith(`<style ${attributesString}></style>`);
|
|
3617
3667
|
}
|
|
3668
|
+
},
|
|
3669
|
+
lspHtmlData() {
|
|
3670
|
+
return {
|
|
3671
|
+
version: 1.1,
|
|
3672
|
+
tags: [{
|
|
3673
|
+
name: "link",
|
|
3674
|
+
attributes: [{
|
|
3675
|
+
name: inlineAttribute,
|
|
3676
|
+
description: "Enable inlining external stylesheets directly into the HTML at build time. It supports both local files and remote URLs."
|
|
3677
|
+
}]
|
|
3678
|
+
}]
|
|
3679
|
+
};
|
|
3618
3680
|
}
|
|
3619
3681
|
};
|
|
3620
3682
|
}
|
|
@@ -3689,6 +3751,18 @@ function HtmlInlineSvgPlugin(options = {}) {
|
|
|
3689
3751
|
for (const [attribute, value] of Object.entries(node.attrs)) svgElement.setAttribute(attribute, value);
|
|
3690
3752
|
node.replaceWith(svgElement);
|
|
3691
3753
|
}
|
|
3754
|
+
},
|
|
3755
|
+
lspHtmlData() {
|
|
3756
|
+
return {
|
|
3757
|
+
version: 1.1,
|
|
3758
|
+
tags: [{
|
|
3759
|
+
name: "svg",
|
|
3760
|
+
attributes: [{
|
|
3761
|
+
name: inlineAttribute,
|
|
3762
|
+
description: "Enable inlining external SVGs directly into the HTML at build time. It supports both local files and remote URLs."
|
|
3763
|
+
}]
|
|
3764
|
+
}]
|
|
3765
|
+
};
|
|
3692
3766
|
}
|
|
3693
3767
|
};
|
|
3694
3768
|
}
|
|
@@ -3787,6 +3861,22 @@ function htmlInlineTextPlugin(options = {}) {
|
|
|
3787
3861
|
const importers = deps.getImporters(id);
|
|
3788
3862
|
for (const importer of importers) compileSet.add(importer);
|
|
3789
3863
|
}
|
|
3864
|
+
},
|
|
3865
|
+
lspHtmlData() {
|
|
3866
|
+
return {
|
|
3867
|
+
version: 1.1,
|
|
3868
|
+
tags: [{
|
|
3869
|
+
name: tag,
|
|
3870
|
+
description: "At build time, this tag is replaced with the contents of the external text file.",
|
|
3871
|
+
attributes: [{
|
|
3872
|
+
name: sourceAttribute,
|
|
3873
|
+
description: "The path to the external text file."
|
|
3874
|
+
}, {
|
|
3875
|
+
name: noEscapeAttribute,
|
|
3876
|
+
description: "Disable HTML escaping."
|
|
3877
|
+
}]
|
|
3878
|
+
}]
|
|
3879
|
+
};
|
|
3790
3880
|
}
|
|
3791
3881
|
};
|
|
3792
3882
|
}
|
|
@@ -3845,6 +3935,35 @@ function htmlInsertPlugin(options = {}) {
|
|
|
3845
3935
|
filePath: metadata.id
|
|
3846
3936
|
});
|
|
3847
3937
|
}
|
|
3938
|
+
},
|
|
3939
|
+
lspHtmlData() {
|
|
3940
|
+
return {
|
|
3941
|
+
version: 1.1,
|
|
3942
|
+
tags: [{
|
|
3943
|
+
name: tag,
|
|
3944
|
+
description: "At build time, inject HTML content into any target element on the page using a CSS selector at build time.",
|
|
3945
|
+
attributes: [
|
|
3946
|
+
{
|
|
3947
|
+
name: selectorAttribute,
|
|
3948
|
+
description: "The CSS selector of the target element."
|
|
3949
|
+
},
|
|
3950
|
+
{
|
|
3951
|
+
name: replaceAttribute,
|
|
3952
|
+
description: "Replace the target element with the contents of the custom insert element."
|
|
3953
|
+
},
|
|
3954
|
+
{
|
|
3955
|
+
name: whereAttribute,
|
|
3956
|
+
description: "The position of the inserted element.",
|
|
3957
|
+
values: [
|
|
3958
|
+
{ name: "beforebegin" },
|
|
3959
|
+
{ name: "afterbegin" },
|
|
3960
|
+
{ name: "beforeend" },
|
|
3961
|
+
{ name: "afterend" }
|
|
3962
|
+
]
|
|
3963
|
+
}
|
|
3964
|
+
]
|
|
3965
|
+
}]
|
|
3966
|
+
};
|
|
3848
3967
|
}
|
|
3849
3968
|
};
|
|
3850
3969
|
}
|
|
@@ -3892,14 +4011,14 @@ function executeExpression$1(expressionString, data) {
|
|
|
3892
4011
|
//#endregion
|
|
3893
4012
|
//#region src/plugins/html-layout/html-layout-plugin.ts
|
|
3894
4013
|
function htmlLayoutPlugin(options = {}) {
|
|
3895
|
-
const
|
|
4014
|
+
const layoutTags = options.tags ?? ["layout", "part"];
|
|
3896
4015
|
const sourceAttribute = options.layoutSourceAttribute ?? "src";
|
|
3897
4016
|
const dataSourceAttribute = options.dataSourceAttribute ?? "dataSource";
|
|
3898
4017
|
const dataJsonAttribute = options.dataJsonAttribute ?? "dataJson";
|
|
3899
4018
|
const alwaysIncludeAttribute = options.alwaysIncludeAttribute ?? "always-include";
|
|
3900
4019
|
const addAttributeAttribute = options.addAttributeAttribute ?? "add-attr";
|
|
3901
4020
|
const removeAttributeAttribute = options.removeAttributeAttribute ?? "remove-attr";
|
|
3902
|
-
const query =
|
|
4021
|
+
const query = layoutTags.join(",");
|
|
3903
4022
|
const printFmtError = PrintFormattedError.create({ function: htmlLayoutPlugin });
|
|
3904
4023
|
const htmlLayoutMetadataCache = [];
|
|
3905
4024
|
/**
|
|
@@ -3909,12 +4028,12 @@ function htmlLayoutPlugin(options = {}) {
|
|
|
3909
4028
|
const dataSourceCache = /* @__PURE__ */ new Map();
|
|
3910
4029
|
function isLayoutPath(path) {
|
|
3911
4030
|
const fileName = basename(path);
|
|
3912
|
-
return
|
|
4031
|
+
return layoutTags.some((tag) => fileName.endsWith(`.${tag}.html`));
|
|
3913
4032
|
}
|
|
3914
4033
|
return {
|
|
3915
4034
|
name: "html-layout",
|
|
3916
4035
|
load(content, relativePath, { type }) {
|
|
3917
|
-
if (type && !
|
|
4036
|
+
if (type && !layoutTags.includes(type)) return;
|
|
3918
4037
|
if (!isLayoutPath(relativePath)) return;
|
|
3919
4038
|
const textAssetMetadata = {
|
|
3920
4039
|
type: METADATA_TYPES.TextAsset,
|
|
@@ -3953,7 +4072,7 @@ function htmlLayoutPlugin(options = {}) {
|
|
|
3953
4072
|
}
|
|
3954
4073
|
if (isMarkdownMetadata(metadata)) for (const [key, source] of Object.entries(metadata.ast.frontmatter)) {
|
|
3955
4074
|
if (!source) continue;
|
|
3956
|
-
if (
|
|
4075
|
+
if (layoutTags.includes(key) || key === dataSourceAttribute) sources.push({
|
|
3957
4076
|
get source() {
|
|
3958
4077
|
return source;
|
|
3959
4078
|
},
|
|
@@ -4178,7 +4297,7 @@ function htmlLayoutPlugin(options = {}) {
|
|
|
4178
4297
|
return;
|
|
4179
4298
|
}
|
|
4180
4299
|
if (isMarkdownMetadata(metadata)) {
|
|
4181
|
-
const tag = Object.keys(metadata.ast.frontmatter).find((key) =>
|
|
4300
|
+
const tag = Object.keys(metadata.ast.frontmatter).find((key) => layoutTags.includes(key));
|
|
4182
4301
|
if (!tag) return;
|
|
4183
4302
|
let attributesString = "";
|
|
4184
4303
|
for (const [key, value] of Object.entries(metadata.ast.frontmatter)) attributesString += `${key === tag ? sourceAttribute : key}="${value}" `;
|
|
@@ -4190,6 +4309,56 @@ function htmlLayoutPlugin(options = {}) {
|
|
|
4190
4309
|
};
|
|
4191
4310
|
return;
|
|
4192
4311
|
}
|
|
4312
|
+
},
|
|
4313
|
+
lspHtmlData() {
|
|
4314
|
+
const attributes = [
|
|
4315
|
+
{
|
|
4316
|
+
name: sourceAttribute,
|
|
4317
|
+
description: "The path to the layout to use."
|
|
4318
|
+
},
|
|
4319
|
+
{
|
|
4320
|
+
name: dataSourceAttribute,
|
|
4321
|
+
description: "The path for a JSON file containing data for the layout."
|
|
4322
|
+
},
|
|
4323
|
+
{
|
|
4324
|
+
name: dataJsonAttribute,
|
|
4325
|
+
description: "The layout data in JSON format."
|
|
4326
|
+
}
|
|
4327
|
+
];
|
|
4328
|
+
const alwaysInclude = {
|
|
4329
|
+
name: alwaysIncludeAttribute,
|
|
4330
|
+
description: "When using a layout more than once on the same page. Always include this script/style/link[rel='stylesheet'] even if it is already present."
|
|
4331
|
+
};
|
|
4332
|
+
const tags = [
|
|
4333
|
+
{
|
|
4334
|
+
name: "script",
|
|
4335
|
+
attributes: [alwaysInclude]
|
|
4336
|
+
},
|
|
4337
|
+
{
|
|
4338
|
+
name: "link",
|
|
4339
|
+
attributes: [alwaysInclude]
|
|
4340
|
+
},
|
|
4341
|
+
{
|
|
4342
|
+
name: "style",
|
|
4343
|
+
attributes: [alwaysInclude]
|
|
4344
|
+
}
|
|
4345
|
+
];
|
|
4346
|
+
for (const tag of layoutTags) tags.push({
|
|
4347
|
+
name: tag,
|
|
4348
|
+
description: `This tag allows inlining a \`${tag}\` file.`,
|
|
4349
|
+
attributes
|
|
4350
|
+
});
|
|
4351
|
+
return {
|
|
4352
|
+
version: 1.1,
|
|
4353
|
+
tags,
|
|
4354
|
+
globalAttributes: [{
|
|
4355
|
+
name: addAttributeAttribute,
|
|
4356
|
+
description: "Inside a layout file only.Prefix for conditionally adding boolean attributes.Append the target attribute name as a suffix — `add-attr-open`, `add-attr-disabled`, etc. The value is a JS expression evaluated after placeholder resolution; if it is non-empty and not `\"false\"`, the named attribute is added to the element. Multiple `add-attr-*` attributes can appear on the same element."
|
|
4357
|
+
}, {
|
|
4358
|
+
name: removeAttributeAttribute,
|
|
4359
|
+
description: "Inside a layout file only.Prefix for conditionally removing boolean attributes.Append the target attribute name as a suffix — `remove-attr-open`, `remove-attr-disabled`, etc. The value is a JS expression evaluated after placeholder resolution; if it is non-empty and not `\"false\"`, the named attribute is removed from the element. Multiple `remove-attr-*` attributes can appear on the same element."
|
|
4360
|
+
}]
|
|
4361
|
+
};
|
|
4193
4362
|
}
|
|
4194
4363
|
};
|
|
4195
4364
|
}
|
|
@@ -4257,7 +4426,22 @@ function htmlMarkdownPlugin(options = {}) {
|
|
|
4257
4426
|
});
|
|
4258
4427
|
continue;
|
|
4259
4428
|
}
|
|
4260
|
-
|
|
4429
|
+
const asHtmlString = await markdownMetadata.ast.render();
|
|
4430
|
+
const htmlMetadata = await this.load(metadata.filePath, {
|
|
4431
|
+
code: asHtmlString,
|
|
4432
|
+
type: "html"
|
|
4433
|
+
});
|
|
4434
|
+
if (!isHtmlMetadata(htmlMetadata)) {
|
|
4435
|
+
printFmtError("Invalid HTML file:", metadata.filePath, {
|
|
4436
|
+
node,
|
|
4437
|
+
filePath: metadata.id
|
|
4438
|
+
});
|
|
4439
|
+
continue;
|
|
4440
|
+
}
|
|
4441
|
+
const metadataList = await this.resolveAndLoad(htmlMetadata);
|
|
4442
|
+
this.addMetadata(metadataList.slice(1));
|
|
4443
|
+
await this.transformAndSync(metadataList);
|
|
4444
|
+
node.set_content(htmlMetadata.ast.children);
|
|
4261
4445
|
}
|
|
4262
4446
|
const currentSources = /* @__PURE__ */ new Set();
|
|
4263
4447
|
const markdowns = metadata.ast.querySelectorAll(markdownTag);
|
|
@@ -4281,8 +4465,23 @@ function htmlMarkdownPlugin(options = {}) {
|
|
|
4281
4465
|
continue;
|
|
4282
4466
|
}
|
|
4283
4467
|
currentSources.add(sourceRelative);
|
|
4284
|
-
const
|
|
4285
|
-
|
|
4468
|
+
const asHtmlString = await markdownMetadata.ast.render();
|
|
4469
|
+
const htmlMetadata = await this.load(sourceRelative, {
|
|
4470
|
+
code: asHtmlString,
|
|
4471
|
+
type: "html"
|
|
4472
|
+
});
|
|
4473
|
+
if (!isHtmlMetadata(htmlMetadata)) {
|
|
4474
|
+
printFmtError("Invalid HTML file:", sourceRelative, {
|
|
4475
|
+
node,
|
|
4476
|
+
filePath: metadata.id
|
|
4477
|
+
});
|
|
4478
|
+
continue;
|
|
4479
|
+
}
|
|
4480
|
+
const metadataList = await this.resolveAndLoad(htmlMetadata);
|
|
4481
|
+
this.addMetadata(metadataList.slice(1));
|
|
4482
|
+
await this.transformAndSync(metadataList);
|
|
4483
|
+
await this.rebase(htmlMetadata, join(this.root, metadata.filePath));
|
|
4484
|
+
node.replaceWith(...htmlMetadata.ast.children);
|
|
4286
4485
|
}
|
|
4287
4486
|
deps.update(metadata.id, currentSources);
|
|
4288
4487
|
},
|
|
@@ -4295,6 +4494,23 @@ function htmlMarkdownPlugin(options = {}) {
|
|
|
4295
4494
|
const importers = deps.getImporters(id);
|
|
4296
4495
|
for (const importer of importers) compileSet.add(importer);
|
|
4297
4496
|
}
|
|
4497
|
+
},
|
|
4498
|
+
lspHtmlData() {
|
|
4499
|
+
return {
|
|
4500
|
+
version: 1.1,
|
|
4501
|
+
globalAttributes: [{
|
|
4502
|
+
name: mdAttribute,
|
|
4503
|
+
description: "Render the contents of this element as markdown."
|
|
4504
|
+
}],
|
|
4505
|
+
tags: [{
|
|
4506
|
+
name: markdownTag,
|
|
4507
|
+
description: "This tag lets you render Markdown files inside HTML.",
|
|
4508
|
+
attributes: [{
|
|
4509
|
+
name: sourceAttribute,
|
|
4510
|
+
description: "The path to the external markdown file."
|
|
4511
|
+
}]
|
|
4512
|
+
}]
|
|
4513
|
+
};
|
|
4298
4514
|
}
|
|
4299
4515
|
};
|
|
4300
4516
|
}
|
|
@@ -4900,8 +5116,8 @@ function getPreloadInfo(filePath) {
|
|
|
4900
5116
|
//#region src/plugins/html-preload/html-preload-plugin.ts
|
|
4901
5117
|
function htmlPreloadPlugin(options = {}) {
|
|
4902
5118
|
const preloadAttribute = options.preloadAttribute ?? "preload";
|
|
4903
|
-
const includeAttribute = options.includeAttribute ?? "include";
|
|
4904
|
-
const excludeAttribute = options.excludeAttribute ?? "exclude";
|
|
5119
|
+
const includeAttribute = options.includeAttribute ?? "preload-include";
|
|
5120
|
+
const excludeAttribute = options.excludeAttribute ?? "preload-exclude";
|
|
4905
5121
|
const asTypes = [
|
|
4906
5122
|
"script",
|
|
4907
5123
|
"style",
|
|
@@ -4980,6 +5196,37 @@ function htmlPreloadPlugin(options = {}) {
|
|
|
4980
5196
|
head.insertAdjacentHTML("beforeend", linkTags.join("\n"));
|
|
4981
5197
|
}
|
|
4982
5198
|
}
|
|
5199
|
+
},
|
|
5200
|
+
lspHtmlData() {
|
|
5201
|
+
const attributes = [
|
|
5202
|
+
{
|
|
5203
|
+
name: preloadAttribute,
|
|
5204
|
+
description: `Enable preloading.
|
|
5205
|
+
Automatically generates \`<link rel="preload">\` tags for the dependencies of your scripts and stylesheets.
|
|
5206
|
+
This tells the browser to start fetching those files early, before they are discovered through normal parsing.
|
|
5207
|
+
|
|
5208
|
+
You can narrow down the files to preload by specifying a space-separated list of dependency types, additionally you can use the \`${includeAttribute}\` and \`${excludeAttribute}\` attributes.`,
|
|
5209
|
+
values: asTypes.map((type) => ({ name: type }))
|
|
5210
|
+
},
|
|
5211
|
+
{
|
|
5212
|
+
name: includeAttribute,
|
|
5213
|
+
description: `Glob patterns list to include when using the \`${preloadAttribute}\` attribute. (semicolon-separated)`
|
|
5214
|
+
},
|
|
5215
|
+
{
|
|
5216
|
+
name: excludeAttribute,
|
|
5217
|
+
description: `Glob patterns list to exclude when using the \`${preloadAttribute}\` attribute. (semicolon-separated)`
|
|
5218
|
+
}
|
|
5219
|
+
];
|
|
5220
|
+
return {
|
|
5221
|
+
version: 1.1,
|
|
5222
|
+
tags: [{
|
|
5223
|
+
name: "link",
|
|
5224
|
+
attributes
|
|
5225
|
+
}, {
|
|
5226
|
+
name: "script",
|
|
5227
|
+
attributes
|
|
5228
|
+
}]
|
|
5229
|
+
};
|
|
4983
5230
|
}
|
|
4984
5231
|
};
|
|
4985
5232
|
}
|
|
@@ -6257,207 +6504,6 @@ function printExecutionTime(executionTime) {
|
|
|
6257
6504
|
console.log();
|
|
6258
6505
|
}
|
|
6259
6506
|
|
|
6260
|
-
//#endregion
|
|
6261
|
-
//#region src/resolver/get-aliases.ts
|
|
6262
|
-
/** Gets path aliases from `tsconfig.json` */
|
|
6263
|
-
function getPathAliases(root) {
|
|
6264
|
-
const [tsconfig, tsconfigParseError] = readTsconfig(root);
|
|
6265
|
-
if (tsconfigParseError !== null) return [null, tsconfigParseError];
|
|
6266
|
-
const paths = tsconfig.paths ?? {};
|
|
6267
|
-
const alias = {};
|
|
6268
|
-
for (const key in paths) {
|
|
6269
|
-
const aliasName = key.replace(/\*$/, "");
|
|
6270
|
-
alias[aliasName] = paths[key][0].replace(/\*$/, "");
|
|
6271
|
-
}
|
|
6272
|
-
return [alias, null];
|
|
6273
|
-
}
|
|
6274
|
-
function readTsconfig(root) {
|
|
6275
|
-
const [tsconfig, tsconfigParseError] = readJsonFile(join(root, "tsconfig.json"));
|
|
6276
|
-
if (tsconfigParseError !== null) return [null, tsconfigParseError];
|
|
6277
|
-
if (!tsconfig.compilerOptions) return [null, /* @__PURE__ */ new Error("[readTsconfig] No compilerOptions found in tsconfig.json")];
|
|
6278
|
-
return [tsconfig.compilerOptions, null];
|
|
6279
|
-
}
|
|
6280
|
-
|
|
6281
|
-
//#endregion
|
|
6282
|
-
//#region src/resolver/resolver.ts
|
|
6283
|
-
const nodeModulesResolver = new ResolverFactory({
|
|
6284
|
-
conditionNames: [
|
|
6285
|
-
"browser",
|
|
6286
|
-
"import",
|
|
6287
|
-
"default"
|
|
6288
|
-
],
|
|
6289
|
-
extensions: [
|
|
6290
|
-
".js",
|
|
6291
|
-
".json",
|
|
6292
|
-
".node",
|
|
6293
|
-
".css"
|
|
6294
|
-
],
|
|
6295
|
-
symlinks: false
|
|
6296
|
-
});
|
|
6297
|
-
var Resolver = class Resolver {
|
|
6298
|
-
root;
|
|
6299
|
-
aliases = {};
|
|
6300
|
-
notFound = /* @__PURE__ */ new Set();
|
|
6301
|
-
files = /* @__PURE__ */ new Set();
|
|
6302
|
-
directories = /* @__PURE__ */ new Set();
|
|
6303
|
-
static JS_EXTENSIONS = new Set([
|
|
6304
|
-
".js",
|
|
6305
|
-
".mjs",
|
|
6306
|
-
".cjs",
|
|
6307
|
-
".jsx",
|
|
6308
|
-
".ts",
|
|
6309
|
-
".mts",
|
|
6310
|
-
".cts",
|
|
6311
|
-
".tsx"
|
|
6312
|
-
]);
|
|
6313
|
-
static HTML_EXTENSIONS = new Set([".html", ".md"]);
|
|
6314
|
-
constructor(root) {
|
|
6315
|
-
this.root = root;
|
|
6316
|
-
const [aliases] = getPathAliases(root);
|
|
6317
|
-
if (aliases) this.aliases = aliases;
|
|
6318
|
-
}
|
|
6319
|
-
resolve(sourceOrLink, filePath) {
|
|
6320
|
-
if (!isValidRelativePath(sourceOrLink)) return;
|
|
6321
|
-
const absFilePath = isAbsolute(filePath) ? filePath : join(this.root, filePath);
|
|
6322
|
-
const [source, suffix] = splitHtmlLink(sourceOrLink);
|
|
6323
|
-
if (isAbsolute(source)) return;
|
|
6324
|
-
const checkDirectory = suffix === "/";
|
|
6325
|
-
const absSource = join(dirname(absFilePath), source);
|
|
6326
|
-
const foundFile = this.findFile(absSource, checkDirectory);
|
|
6327
|
-
if (foundFile) return {
|
|
6328
|
-
path: foundFile,
|
|
6329
|
-
exists: true,
|
|
6330
|
-
suffix
|
|
6331
|
-
};
|
|
6332
|
-
const sourceForAlias = suffix === "/" ? source + "/" : source;
|
|
6333
|
-
const resolvedPathAlias = Resolver.resolvePathAlias(sourceForAlias, this.aliases);
|
|
6334
|
-
if (resolvedPathAlias) {
|
|
6335
|
-
const absSource = join(this.root, resolvedPathAlias);
|
|
6336
|
-
const foundFile = this.findFile(absSource, checkDirectory);
|
|
6337
|
-
const isFileAlias = sourceForAlias in this.aliases && !sourceForAlias.endsWith("/");
|
|
6338
|
-
if (!foundFile && !this.notFound.has(absSource.replace(/\/$/, ""))) {
|
|
6339
|
-
this.notFound.add(absSource.replace(/\/$/, ""));
|
|
6340
|
-
Log.warn(`[resolver] Source "${sourceOrLink}" found in "${filePath}" was resolved to "${resolvedPathAlias}", but the file is missing.`);
|
|
6341
|
-
}
|
|
6342
|
-
return {
|
|
6343
|
-
path: foundFile ?? absSource,
|
|
6344
|
-
exists: !!foundFile,
|
|
6345
|
-
suffix,
|
|
6346
|
-
isFileAlias,
|
|
6347
|
-
isDirAlias: !isFileAlias
|
|
6348
|
-
};
|
|
6349
|
-
}
|
|
6350
|
-
if (!source.startsWith(".")) {
|
|
6351
|
-
const resolverResult = nodeModulesResolver.sync(this.root, source);
|
|
6352
|
-
if (resolverResult.path) return {
|
|
6353
|
-
path: resolverResult.path,
|
|
6354
|
-
suffix,
|
|
6355
|
-
exists: true,
|
|
6356
|
-
isPackage: true
|
|
6357
|
-
};
|
|
6358
|
-
}
|
|
6359
|
-
if (source.startsWith("./") || source.startsWith("../")) {
|
|
6360
|
-
if (!this.notFound.has(absSource)) {
|
|
6361
|
-
this.notFound.add(absSource);
|
|
6362
|
-
Log.warn(`[resolver] Source "${sourceOrLink}" found in "${filePath}" points to a non-existent file.`);
|
|
6363
|
-
}
|
|
6364
|
-
return {
|
|
6365
|
-
path: absSource,
|
|
6366
|
-
suffix,
|
|
6367
|
-
exists: false
|
|
6368
|
-
};
|
|
6369
|
-
}
|
|
6370
|
-
}
|
|
6371
|
-
resolveAlias(source) {
|
|
6372
|
-
return Resolver.resolvePathAlias(source, this.aliases);
|
|
6373
|
-
}
|
|
6374
|
-
normalize(filePath) {
|
|
6375
|
-
return normalize(filePath);
|
|
6376
|
-
}
|
|
6377
|
-
static isFile(filePath) {
|
|
6378
|
-
try {
|
|
6379
|
-
return statSync(filePath).isFile();
|
|
6380
|
-
} catch (error) {
|
|
6381
|
-
const code = error.code;
|
|
6382
|
-
if (code === "ENOENT" || code === "ENOTDIR") return false;
|
|
6383
|
-
throw error;
|
|
6384
|
-
}
|
|
6385
|
-
}
|
|
6386
|
-
/** Aliased path to path */
|
|
6387
|
-
static resolvePathAlias(filePath, aliases) {
|
|
6388
|
-
for (const [key, value] of Object.entries(aliases)) {
|
|
6389
|
-
if (key.endsWith("/")) {
|
|
6390
|
-
if (!filePath.startsWith(key)) continue;
|
|
6391
|
-
return filePath.replace(key, value);
|
|
6392
|
-
}
|
|
6393
|
-
if (filePath === key) return value;
|
|
6394
|
-
}
|
|
6395
|
-
}
|
|
6396
|
-
/** Path to aliased path */
|
|
6397
|
-
static resolveAliasPath(filePath, aliases) {
|
|
6398
|
-
let shortest;
|
|
6399
|
-
for (const [key, value] of Object.entries(aliases)) {
|
|
6400
|
-
if (key.endsWith("/")) {
|
|
6401
|
-
if (!filePath.startsWith(value)) continue;
|
|
6402
|
-
const aliased = filePath.replace(value, key);
|
|
6403
|
-
if (!shortest || aliased.length < shortest.length) shortest = aliased;
|
|
6404
|
-
continue;
|
|
6405
|
-
}
|
|
6406
|
-
if (filePath === value && (!shortest || key.length < shortest.length)) shortest = key;
|
|
6407
|
-
}
|
|
6408
|
-
return shortest ?? filePath;
|
|
6409
|
-
}
|
|
6410
|
-
/** Path to aliased path */
|
|
6411
|
-
aliasPath(filePath) {
|
|
6412
|
-
return Resolver.resolveAliasPath(filePath, this.aliases);
|
|
6413
|
-
}
|
|
6414
|
-
findFile(filePath, checkDirectory = false) {
|
|
6415
|
-
if (this.files.has(filePath)) return filePath;
|
|
6416
|
-
if (Resolver.isFile(filePath)) {
|
|
6417
|
-
this.files.add(filePath);
|
|
6418
|
-
return filePath;
|
|
6419
|
-
}
|
|
6420
|
-
const extension = extname(filePath);
|
|
6421
|
-
if (!extension) {
|
|
6422
|
-
for (const candidateExtension of [...Resolver.JS_EXTENSIONS, ...Resolver.HTML_EXTENSIONS]) {
|
|
6423
|
-
const candidate = replaceExtension(filePath, candidateExtension);
|
|
6424
|
-
if (this.files.has(candidate)) return candidate;
|
|
6425
|
-
if (Resolver.isFile(candidate)) {
|
|
6426
|
-
this.files.add(candidate);
|
|
6427
|
-
return candidate;
|
|
6428
|
-
}
|
|
6429
|
-
}
|
|
6430
|
-
const withIndex = join(filePath, "index");
|
|
6431
|
-
for (const candidateExtension of Resolver.HTML_EXTENSIONS) {
|
|
6432
|
-
const candidate = replaceExtension(withIndex, candidateExtension);
|
|
6433
|
-
if (this.files.has(candidate)) return candidate;
|
|
6434
|
-
if (Resolver.isFile(candidate)) {
|
|
6435
|
-
this.files.add(candidate);
|
|
6436
|
-
return candidate;
|
|
6437
|
-
}
|
|
6438
|
-
}
|
|
6439
|
-
if (checkDirectory) {
|
|
6440
|
-
if (this.directories.has(filePath)) return filePath;
|
|
6441
|
-
if (existsSync(filePath)) {
|
|
6442
|
-
this.directories.add(filePath);
|
|
6443
|
-
return filePath;
|
|
6444
|
-
}
|
|
6445
|
-
}
|
|
6446
|
-
return;
|
|
6447
|
-
}
|
|
6448
|
-
if (Resolver.JS_EXTENSIONS.has(extension)) {
|
|
6449
|
-
for (const jsExtension of Resolver.JS_EXTENSIONS) {
|
|
6450
|
-
const candidate = replaceExtension(filePath, jsExtension);
|
|
6451
|
-
if (Resolver.isFile(candidate)) {
|
|
6452
|
-
this.files.add(candidate);
|
|
6453
|
-
return candidate;
|
|
6454
|
-
}
|
|
6455
|
-
}
|
|
6456
|
-
return;
|
|
6457
|
-
}
|
|
6458
|
-
}
|
|
6459
|
-
};
|
|
6460
|
-
|
|
6461
6507
|
//#endregion
|
|
6462
6508
|
//#region src/main.ts
|
|
6463
6509
|
var App = class {
|