Explode gulpfile

* Import TypeScript
* Explode gulpfile into smaller files
* Actual CSS and Font (incomplete) file cache buster
This commit is contained in:
Thibault “Adædra” Hamel 2024-06-21 21:17:32 +02:00
parent 9e8d63c868
commit f85d4d562e
15 changed files with 857 additions and 238 deletions

View File

@ -1,223 +1,2 @@
import { src, dest, parallel, watch as _watch } from "gulp"; export * from "./lib/tasks.ts";
import postcss from "gulp-postcss"; export { default } from "./lib/tasks.ts";
import { Transform } from "node:stream";
import pug from "pug";
import asciidoctor from "asciidoctor";
import { basename, dirname, join } from "node:path";
import Vinyl from "vinyl";
import { unified } from "unified";
import rehypeParse from "rehype-parse";
import rehypeStringify from "rehype-stringify";
import rehypePresetMinify from "rehype-preset-minify";
import rehypeExternalLinks from "rehype-external-links";
import rehypePrism from "@mapbox/rehype-prism";
import { DateTime } from "luxon";
import visit from "unist-util-visit";
import { readFileSync, unlinkSync } from "node:fs";
import { env } from "node:process";
import tmp from "tmp";
import { execFile } from "node:child_process";
const PRODUCTION = env.NODE_ENV === "production";
const DEFAULT_DATE = DateTime.fromSeconds(Number(env.SOURCE_DATE_EPOCH)).toUTC();
const FONT_PRESETS = {
mono: { ranges: ["20-7F", "2E22-2E25", "2713", "2717"] },
text: { ranges: ["20-7F", "A0-FF", "2000-206F", "20AC"] },
};
const SITE_TITLE = "Ad\xE6dra's blog";
const SITE_DESCRIPTION = [
"Ad\xE6dra",
"Software Developper in Paris, France",
"Rust, Ruby, Typescript, Linux",
].join(" \u2022 ");
const Asciidoctor = asciidoctor();
const EXTENSION_REGISTRY = Asciidoctor.Extensions.create();
EXTENSION_REGISTRY.inlineMacro("abbr", function () {
this.process((parent, target, attributes) => {
return this.createInline(
parent,
"quoted",
`<abbr title="${attributes["$positional"]}">${target}</abbr>`,
);
});
});
const extractImages = (gulp, file) => () => (tree) => {
visit(tree, "element", (node) => {
if (node.tagName !== "img") {
return;
}
const path = join(dirname(file.path), node.properties.src);
const image = new Vinyl({
path: join(basename(file.path, ".asciidoc"), node.properties.src),
contents: readFileSync(path),
});
gulp.push(image);
});
};
const asset = env.ASSETS_HOSTS
? (path) => new URL(path, env.ASSETS_HOSTS).toString()
: (path) => join("/_assets/", path);
const renderArticle = () => {
const allArticles = [];
const renderLayout = pug.compileFile("src/layout.pug");
const renderArticleLayout = pug.compileFile("src/article.pug");
return new Transform({
readableObjectMode: true,
writableObjectMode: true,
async transform(file, _, callback) {
try {
const slug = basename(file.path, ".asciidoc");
const article = Asciidoctor.load(file.contents, {
extension_registry: EXTENSION_REGISTRY,
});
const date = DateTime.fromISO(article.getAttribute("docdate"), {
zone: "UTC",
});
if (PRODUCTION && date.equals(DEFAULT_DATE)) {
callback(null);
return;
}
allArticles.push([slug, date, article]);
const vfile = await unified()
.use(rehypeParse)
.use(rehypeExternalLinks, { rel: "noopener", target: "_blank" })
.use(extractImages(this, file))
.use(rehypePrism)
.use(rehypePresetMinify)
.use(rehypeStringify)
.process(article.convert());
const content = renderLayout({
SITE_TITLE,
asset,
title: article.getDoctitle(),
meta: {
description: article.getAttribute("description"),
keywords: article.getAttribute("keywords"),
"og:title": article.getDoctitle(),
"og:type": "article",
"og:article:published_time": article.getAttribute("docdate"),
"og:url": `https://adaedra.eu/${slug}/`,
"og:image":
"https://adaedra.blob.core.windows.net/blog-assets/cariboudev.avif",
"og:image:alt": "Ad\xE6dra's mascot",
"og:description": article.getAttribute("description"),
"og:locale": "en_GB",
"og:site_name": SITE_TITLE,
},
render() {
return renderArticleLayout({
asset,
article,
date,
DateTime,
body: vfile.toString(),
});
},
});
file.contents = Buffer.from(content);
file.path = join(slug, "index.html");
file.base = null;
callback(null, file);
} catch (e) {
console.error(e);
callback(e);
}
},
final(callback) {
try {
allArticles.sort(([, a], [, b]) => b.diff(a).toMillis());
const renderIndex = pug.compileFile("src/index.pug");
const contents = renderLayout({
SITE_TITLE,
asset,
meta: {
description: SITE_DESCRIPTION,
"og:title": SITE_TITLE,
"og:type": "website",
"og:url": `https://adaedra.eu/`,
"og:image":
"https://adaedra.blob.core.windows.net/blog-assets/cariboudev.avif",
"og:image:alt": "Ad\xE6dra's mascot",
"og:description": SITE_DESCRIPTION,
"og:locale": "en_GB",
},
render() {
return renderIndex({ articles: allArticles, asset });
},
});
this.push(
new Vinyl({
path: "index.html",
contents: Buffer.from(contents),
}),
);
callback(null);
} catch (e) {
console.error(e);
callback(e);
}
},
});
};
export const articles = () =>
src("articles/**/*.asciidoc").pipe(renderArticle()).pipe(dest("dist/"));
export const images = () => src("src/*.avif", { encoding: false }).pipe(dest("dist/_assets/"));
// SVG use has no way of allowing cross-origin, so we need to keep them with the HTML files.
export const svg = () => src("src/*.svg").pipe(dest("dist/"));
export const css = () => src("src/index.css").pipe(postcss()).pipe(dest("dist/_assets/"));
const compileFont = () =>
new Transform({
readableObjectMode: true,
writableObjectMode: true,
transform(chunk, _, callback) {
const [, variant, weight] = /([A-Z][a-z]+)-(\w+)\.ttf$/.exec(chunk.basename);
const tmpOutput = tmp.fileSync({ discardDescriptor: true });
const unicodes = FONT_PRESETS[variant.toLowerCase()].ranges;
execFile("pyftsubset", [
chunk.path,
`--unicodes=${unicodes.join(",")}`,
`--output-file=${tmpOutput.name}`,
"--layout-features=*",
"--flavor=woff2",
]).once("exit", () => {
const file = new Vinyl({
path: `iosevka-adaedra-${variant.toLowerCase()}-${weight.toLowerCase()}.woff2`,
contents: readFileSync(tmpOutput.name),
});
unlinkSync(tmpOutput.name);
callback(null, file);
});
},
});
export const fonts = () => src("vendor/*.ttf").pipe(compileFont()).pipe(dest("dist/_assets/"));
export default parallel(fonts, articles, images, svg, css);
export const watch = () => {
_watch(["src/*.pug", "articles/**/*.asciidoc"], articles);
_watch("src/*.css", css);
_watch("src/*.avif", images);
_watch("src/*.svg", svg);
};

5
lib/environment.ts Normal file
View File

@ -0,0 +1,5 @@
import { env } from "node:process";
import { DateTime } from "luxon";
export const PRODUCTION = env.NODE_ENV === "production";
export const DEFAULT_DATE = DateTime.fromSeconds(Number(env.SOURCE_DATE_EPOCH)).toUTC();

36
lib/hash.ts Normal file
View File

@ -0,0 +1,36 @@
import { Transform } from "node:stream";
import { createHash } from "node:crypto";
import File from "vinyl";
function fileHash(buffer: Buffer) {
const hash = createHash("sha256");
hash.update(buffer.toString());
return hash.digest("hex");
}
export default function (manifestName: string) {
const mappings: { [path: string]: string } = {};
return new Transform({
readableObjectMode: true,
writableObjectMode: true,
transform(chunk: File, _, callback) {
const hash = fileHash(chunk.contents as Buffer);
const newName = `${chunk.basename.substring(0, chunk.basename.length - chunk.extname.length)}.${hash.substring(0, 8)}${chunk.extname}`;
mappings[chunk.basename] = newName;
chunk.basename = newName;
callback(null, chunk);
},
final(callback) {
const mappingFile = new File({
path: manifestName,
contents: Buffer.from(JSON.stringify(mappings)),
});
this.push(mappingFile);
callback(null);
},
});
}

10
lib/tasks.ts Normal file
View File

@ -0,0 +1,10 @@
import { series } from "gulp";
import { articles } from "./tasks/articles.js";
import { css } from "./tasks/css.js";
import { fonts } from "./tasks/fonts.js";
import { images } from "./tasks/images.js";
import { svg } from "./tasks/svg.js";
import { watch } from "./tasks/watch.js";
export { articles, css, fonts, images, svg, watch };
export default series(fonts, css, images, svg, articles);

178
lib/tasks/articles.ts Normal file
View File

@ -0,0 +1,178 @@
import { compileFile } from "pug";
import { readFileSync } from "node:fs";
import { env } from "node:process";
import { join, basename, dirname } from "node:path";
import { Transform } from "node:stream";
import asciidoctor, { Document } from "asciidoctor";
import File from "vinyl";
import { DateTime } from "luxon";
import { unified } from "unified";
import rehypeParse from "rehype-parse";
import rehypeStringify from "rehype-stringify";
import rehypePresetMinify from "rehype-preset-minify";
import rehypePrism from "@mapbox/rehype-prism";
import { PRODUCTION, DEFAULT_DATE } from "../environment.js";
import rehypeExternalLinks from "rehype-external-links";
import visit from "unist-util-visit";
import { src, dest } from "gulp";
import { globSync } from "glob";
const Asciidoctor = asciidoctor();
const EXTENSION_REGISTRY = Asciidoctor.Extensions.create();
EXTENSION_REGISTRY.inlineMacro("abbr", function () {
this.process(function (parent, target, attributes) {
return this.createInline(
parent,
"quoted",
`<abbr title="${attributes["$positional"]}">${target}</abbr>`,
);
});
});
const SITE_TITLE = "Ad\xE6dra's blog";
const SITE_DESCRIPTION = [
"Ad\xE6dra",
"Software Developper in Paris, France",
"Rust, Ruby, Typescript, Linux",
].join(" \u2022 ");
const SITE_DEFAULT_META = {
"og:image": "https://adaedra.blob.core.windows.net/blog-assets/cariboudev.avif",
"og:image:alt": SITE_DESCRIPTION,
"og:locale": "en_GB",
};
function readAssetManifest(): { [entry: string]: string } {
return Object.assign(
{},
...globSync("dist/_assets/*.manifest").map((path) =>
JSON.parse(readFileSync(path).toString()),
),
);
}
function extractImages(gulp: Transform, file: File) {
return function () {
return function (tree) {
visit(tree, "element", function (node: any) {
if (node.tagName !== "img") {
return;
}
const path = join(dirname(file.path));
const image = new File({
path: join(basename(file.path, ".asciidoc"), node.properties.src),
contents: readFileSync(path),
});
gulp.push(image);
});
};
};
}
function renderArticle() {
const allArticles: [string, DateTime, Document][] = [];
const renderLayout = compileFile("src/layout.pug");
const renderArticleLayout = compileFile("src/article.pug");
const assetManifest = readAssetManifest();
const asset = (path: string) => {
if (assetManifest.hasOwnProperty(path)) {
path = assetManifest[path];
}
return env.ASSETS_HOSTS
? new URL(path, env.ASSETS_HOSTS).toString()
: join("/_assets/", path);
};
return new Transform({
readableObjectMode: true,
writableObjectMode: true,
async transform(file: File, _, callback) {
try {
const slug = basename(file.path, ".asciidoc");
const article = Asciidoctor.load(file.contents.toString(), {
extension_registry: EXTENSION_REGISTRY,
});
const date = DateTime.fromISO(article.getAttribute("docdate"), { zone: "UTC" });
if (PRODUCTION && date.equals(DEFAULT_DATE)) {
callback(null);
return;
}
allArticles.push([slug, date, article]);
const vfile = await unified()
.use(rehypeParse)
.use(rehypeExternalLinks, { rel: "noopener", target: "_blank" })
.use(extractImages(this, file))
.use(rehypePrism)
.use(rehypePresetMinify)
.use(rehypeStringify)
.process(article.convert());
const content = renderLayout({
SITE_TITLE,
asset,
title: article.getDoctitle({}),
meta: Object.assign({}, SITE_DEFAULT_META, {
description: article.getAttribute("description"),
keywords: article.getAttribute("keywords"),
"og:title": article.getDoctitle({}),
"og:type": "article",
"og:article:published_time": article.getAttribute("docdate"),
"og:url": `https://adaedra.eu/${slug}/`,
"og:description": article.getAttribute("description"),
"og:site_name": SITE_TITLE,
}),
render() {
return renderArticleLayout({
asset,
article,
date,
DateTime,
body: vfile.toString(),
});
},
});
file.contents = Buffer.from(content);
file.path = join(slug, "index.html");
file.base = null;
callback(null, file);
} catch (e) {
console.error(e);
callback(e);
}
},
final(callback) {
try {
allArticles.sort(([, a], [, b]) => b.diff(a).toMillis());
const renderIndex = compileFile("src/index.pug");
const contents = renderLayout({
SITE_TITLE,
asset,
meta: Object.assign({}, SITE_DEFAULT_META, {
description: SITE_DESCRIPTION,
"og:title": SITE_TITLE,
"og:type": "website",
"og:url": `https://adaedra.eu`,
}),
render() {
return renderIndex({ articles: allArticles, asset });
},
});
this.push(new File({ path: "index.html", contents: Buffer.from(contents) }));
callback(null);
} catch (e) {
console.error(e);
callback(e);
}
},
});
}
export const articles = () =>
src("articles/**/*.asciidoc").pipe(renderArticle()).pipe(dest("dist/"));

6
lib/tasks/css.ts Normal file
View File

@ -0,0 +1,6 @@
import { src, dest } from "gulp";
import postcss from "gulp-postcss";
import hashPath from "../hash.js";
export const css = () =>
src("src/index.css").pipe(postcss()).pipe(hashPath("css.manifest")).pipe(dest("dist/_assets/"));

44
lib/tasks/fonts.ts Normal file
View File

@ -0,0 +1,44 @@
import { Transform } from "node:stream";
import File from "vinyl";
import tmp from "tmp";
import { execFile } from "node:child_process";
import { readFileSync, unlinkSync } from "node:fs";
import { src, dest } from "gulp";
import hashPaths from "../hash.js";
const FONT_PRESETS = {
mono: { ranges: ["20-7F", "2205", "2E22-2E25", "2713", "2717"] },
text: { ranges: ["20-7F", "A0-FF", "2000-206F", "20AC"] },
};
function compileFont() {
return new Transform({
readableObjectMode: true,
writableObjectMode: true,
async transform(chunk: File, _, callback) {
const [, variant, weight] = /([A-Z][a-z]+)-(\w+)\.ttf$/.exec(chunk.basename);
const tmpOutput = tmp.fileSync({ discardDescriptor: true });
const unicodes = FONT_PRESETS[variant.toLowerCase()].ranges;
execFile("pyftsubset", [
chunk.path,
`--unicodes=${unicodes.join(",")}`,
`--output-file=${tmpOutput.name}`,
"--flavor=woff2",
]).once("exit", () => {
chunk.path = `iosevka-adaedra-${variant.toLowerCase()}-${weight.toLowerCase()}.woff2`;
chunk.contents = readFileSync(tmpOutput.name);
chunk.base = null;
unlinkSync(tmpOutput.name);
callback(null, chunk);
});
},
});
}
export const fonts = () =>
src("vendor/*.ttf")
.pipe(compileFont())
.pipe(hashPaths("fonts.manifest"))
.pipe(dest("dist/_assets"));

3
lib/tasks/images.ts Normal file
View File

@ -0,0 +1,3 @@
import { src, dest } from "gulp";
export const images = () => src("src/*.avif", { encoding: false }).pipe(dest("dist/_assets/"));

4
lib/tasks/svg.ts Normal file
View File

@ -0,0 +1,4 @@
import { src, dest } from "gulp";
// SVG `use` has no way of allowing cross-origin, so we need to keep them with the HTML files.
export const svg = () => src("src/*.svg").pipe(dest("dist/"));

16
lib/tasks/watch.ts Normal file
View File

@ -0,0 +1,16 @@
import gulp from "gulp";
import { articles } from "./articles.js";
import { css } from "./css.js";
import { images } from "./images.js";
import { svg } from "./svg.js";
export const watch = () => {
gulp.watch(["src/*.pug", "articles/**/*.asciidoc"], articles);
gulp.watch("src/*.css", css);
gulp.watch("src/*.avif", images);
gulp.watch("src/*.svg", svg);
gulp.watch("dist/_assets/fonts.manifest", css);
gulp.watch("dist/_assets/css.manifest", articles);
};

3
lib/ts-loader.js Normal file
View File

@ -0,0 +1,3 @@
import { register } from "node:module";
register("ts-node/esm", import.meta.url);

546
package-lock.json generated
View File

@ -11,6 +11,7 @@
"@mapbox/rehype-prism": "^0.9.0", "@mapbox/rehype-prism": "^0.9.0",
"asciidoctor": "^3.0.4", "asciidoctor": "^3.0.4",
"cssnano": "^7.0.2", "cssnano": "^7.0.2",
"glob": "^10.4.2",
"gulp": "^5.0.0", "gulp": "^5.0.0",
"gulp-cli": "^3.0.0", "gulp-cli": "^3.0.0",
"gulp-postcss": "^10.0.0", "gulp-postcss": "^10.0.0",
@ -23,11 +24,14 @@
"rehype-external-links": "^3.0.0", "rehype-external-links": "^3.0.0",
"rehype-preset-minify": "^7.0.0", "rehype-preset-minify": "^7.0.0",
"tmp": "^0.2.3", "tmp": "^0.2.3",
"ts-node": "^10.9.2",
"unified": "^11.0.4" "unified": "^11.0.4"
}, },
"devDependencies": { "devDependencies": {
"@types/express": "^4.17.21", "@types/express": "^4.17.21",
"@types/glob": "^8.1.0",
"@types/gulp": "^4.0.17", "@types/gulp": "^4.0.17",
"@types/gulp-postcss": "^8.0.6",
"@types/luxon": "^3.4.2", "@types/luxon": "^3.4.2",
"@types/pug": "^2.0.10", "@types/pug": "^2.0.10",
"@types/tmp": "^0.2.6", "@types/tmp": "^0.2.6",
@ -78,6 +82,25 @@
"node": ">=16" "node": ">=16"
} }
}, },
"node_modules/@asciidoctor/opal-runtime/node_modules/glob": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
"integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
"deprecated": "Glob versions prior to v9 are no longer supported",
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^5.0.1",
"once": "^1.3.0"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/@babel/helper-string-parser": { "node_modules/@babel/helper-string-parser": {
"version": "7.24.7", "version": "7.24.7",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz",
@ -118,6 +141,17 @@
"node": ">=6.9.0" "node": ">=6.9.0"
} }
}, },
"node_modules/@cspotcode/source-map-support": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
"dependencies": {
"@jridgewell/trace-mapping": "0.3.9"
},
"engines": {
"node": ">=12"
}
},
"node_modules/@csstools/selector-resolve-nested": { "node_modules/@csstools/selector-resolve-nested": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-1.1.0.tgz", "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-1.1.0.tgz",
@ -179,6 +213,117 @@
"node": ">=10.13.0" "node": ">=10.13.0"
} }
}, },
"node_modules/@isaacs/cliui": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
"integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
"dependencies": {
"string-width": "^5.1.2",
"string-width-cjs": "npm:string-width@^4.2.0",
"strip-ansi": "^7.0.1",
"strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
"wrap-ansi": "^8.1.0",
"wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/@isaacs/cliui/node_modules/ansi-regex": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
"integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
}
},
"node_modules/@isaacs/cliui/node_modules/ansi-styles": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/@isaacs/cliui/node_modules/emoji-regex": {
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
},
"node_modules/@isaacs/cliui/node_modules/string-width": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
"dependencies": {
"eastasianwidth": "^0.2.0",
"emoji-regex": "^9.2.2",
"strip-ansi": "^7.0.1"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@isaacs/cliui/node_modules/strip-ansi": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
"dependencies": {
"ansi-regex": "^6.0.1"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
"node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
"dependencies": {
"ansi-styles": "^6.1.0",
"string-width": "^5.0.1",
"strip-ansi": "^7.0.1"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.15",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
"dependencies": {
"@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10"
}
},
"node_modules/@mapbox/rehype-prism": { "node_modules/@mapbox/rehype-prism": {
"version": "0.9.0", "version": "0.9.0",
"resolved": "https://registry.npmjs.org/@mapbox/rehype-prism/-/rehype-prism-0.9.0.tgz", "resolved": "https://registry.npmjs.org/@mapbox/rehype-prism/-/rehype-prism-0.9.0.tgz",
@ -192,6 +337,15 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/@pkgjs/parseargs": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
"integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
"optional": true,
"engines": {
"node": ">=14"
}
},
"node_modules/@trysound/sax": { "node_modules/@trysound/sax": {
"version": "0.2.0", "version": "0.2.0",
"resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
@ -200,6 +354,26 @@
"node": ">=10.13.0" "node": ">=10.13.0"
} }
}, },
"node_modules/@tsconfig/node10": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
"integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw=="
},
"node_modules/@tsconfig/node12": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag=="
},
"node_modules/@tsconfig/node14": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow=="
},
"node_modules/@tsconfig/node16": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA=="
},
"node_modules/@types/body-parser": { "node_modules/@types/body-parser": {
"version": "1.19.5", "version": "1.19.5",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
@ -249,6 +423,16 @@
"@types/send": "*" "@types/send": "*"
} }
}, },
"node_modules/@types/glob": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz",
"integrity": "sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==",
"dev": true,
"dependencies": {
"@types/minimatch": "^5.1.2",
"@types/node": "*"
}
},
"node_modules/@types/glob-stream": { "node_modules/@types/glob-stream": {
"version": "8.0.2", "version": "8.0.2",
"resolved": "https://registry.npmjs.org/@types/glob-stream/-/glob-stream-8.0.2.tgz", "resolved": "https://registry.npmjs.org/@types/glob-stream/-/glob-stream-8.0.2.tgz",
@ -272,6 +456,16 @@
"chokidar": "^3.3.1" "chokidar": "^3.3.1"
} }
}, },
"node_modules/@types/gulp-postcss": {
"version": "8.0.6",
"resolved": "https://registry.npmjs.org/@types/gulp-postcss/-/gulp-postcss-8.0.6.tgz",
"integrity": "sha512-mjGEmTvurqRHFeJQnrgtMC9GtKNkI2+56n92zIzff5UFr2jUfilw1elKRxS7bK0FYRvuEcnMX9JH0AUpCxBrpg==",
"dev": true,
"dependencies": {
"@types/node": "*",
"@types/vinyl": "*"
}
},
"node_modules/@types/hast": { "node_modules/@types/hast": {
"version": "2.3.10", "version": "2.3.10",
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz",
@ -306,11 +500,16 @@
"integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
"dev": true "dev": true
}, },
"node_modules/@types/minimatch": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz",
"integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==",
"dev": true
},
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "20.14.2", "version": "20.14.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz",
"integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==", "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==",
"dev": true,
"dependencies": { "dependencies": {
"undici-types": "~5.26.4" "undici-types": "~5.26.4"
} }
@ -439,6 +638,28 @@
"node": ">=0.4.0" "node": ">=0.4.0"
} }
}, },
"node_modules/acorn-walk": {
"version": "8.3.3",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz",
"integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==",
"dependencies": {
"acorn": "^8.11.0"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/acorn-walk/node_modules/acorn": {
"version": "8.12.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz",
"integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==",
"bin": {
"acorn": "bin/acorn"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/ansi-colors": { "node_modules/ansi-colors": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz",
@ -492,6 +713,11 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/arg": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA=="
},
"node_modules/array-each": { "node_modules/array-each": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz",
@ -1089,6 +1315,38 @@
"node": ">= 10.13.0" "node": ">= 10.13.0"
} }
}, },
"node_modules/create-require": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ=="
},
"node_modules/cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
"which": "^2.0.1"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/cross-spawn/node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dependencies": {
"isexe": "^2.0.0"
},
"bin": {
"node-which": "bin/node-which"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/css-declaration-sorter": { "node_modules/css-declaration-sorter": {
"version": "7.2.0", "version": "7.2.0",
"resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz",
@ -1311,6 +1569,14 @@
"url": "https://github.com/sponsors/wooorm" "url": "https://github.com/sponsors/wooorm"
} }
}, },
"node_modules/diff": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"engines": {
"node": ">=0.3.1"
}
},
"node_modules/direction": { "node_modules/direction": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/direction/-/direction-2.0.1.tgz", "resolved": "https://registry.npmjs.org/direction/-/direction-2.0.1.tgz",
@ -1391,6 +1657,11 @@
"node": ">= 10.13.0" "node": ">= 10.13.0"
} }
}, },
"node_modules/eastasianwidth": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
},
"node_modules/ejs": { "node_modules/ejs": {
"version": "3.1.10", "version": "3.1.10",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
@ -1592,6 +1863,21 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/foreground-child": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz",
"integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==",
"dependencies": {
"cross-spawn": "^7.0.0",
"signal-exit": "^4.0.1"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/fs-mkdirp-stream": { "node_modules/fs-mkdirp-stream": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-2.0.1.tgz", "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-2.0.1.tgz",
@ -1657,19 +1943,22 @@
} }
}, },
"node_modules/glob": { "node_modules/glob": {
"version": "8.1.0", "version": "10.4.2",
"resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz",
"integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==",
"deprecated": "Glob versions prior to v9 are no longer supported",
"dependencies": { "dependencies": {
"fs.realpath": "^1.0.0", "foreground-child": "^3.1.0",
"inflight": "^1.0.4", "jackspeak": "^3.1.2",
"inherits": "2", "minimatch": "^9.0.4",
"minimatch": "^5.0.1", "minipass": "^7.1.2",
"once": "^1.3.0" "package-json-from-dist": "^1.0.0",
"path-scurry": "^1.11.1"
},
"bin": {
"glob": "dist/esm/bin.mjs"
}, },
"engines": { "engines": {
"node": ">=12" "node": ">=16 || 14 >=14.18"
}, },
"funding": { "funding": {
"url": "https://github.com/sponsors/isaacs" "url": "https://github.com/sponsors/isaacs"
@ -1740,6 +2029,20 @@
"node": ">= 10.13.0" "node": ">= 10.13.0"
} }
}, },
"node_modules/glob/node_modules/minimatch": {
"version": "9.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz",
"integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/global-modules": { "node_modules/global-modules": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
@ -2924,6 +3227,23 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/jackspeak": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.0.tgz",
"integrity": "sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==",
"dependencies": {
"@isaacs/cliui": "^8.0.2"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
},
"optionalDependencies": {
"@pkgjs/parseargs": "^0.11.0"
}
},
"node_modules/jake": { "node_modules/jake": {
"version": "10.9.1", "version": "10.9.1",
"resolved": "https://registry.npmjs.org/jake/-/jake-10.9.1.tgz", "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.1.tgz",
@ -3029,6 +3349,14 @@
"resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
"integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ=="
}, },
"node_modules/lru-cache": {
"version": "10.2.2",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz",
"integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==",
"engines": {
"node": "14 || >=16.14"
}
},
"node_modules/luxon": { "node_modules/luxon": {
"version": "3.4.4", "version": "3.4.4",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.4.tgz", "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.4.tgz",
@ -3037,6 +3365,11 @@
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/make-error": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="
},
"node_modules/map-cache": { "node_modules/map-cache": {
"version": "0.2.2", "version": "0.2.2",
"resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
@ -3225,6 +3558,14 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/minipass": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
"engines": {
"node": ">=16 || 14 >=14.17"
}
},
"node_modules/mute-stdout": { "node_modules/mute-stdout": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-2.0.0.tgz", "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-2.0.0.tgz",
@ -3360,6 +3701,11 @@
"wrappy": "1" "wrappy": "1"
} }
}, },
"node_modules/package-json-from-dist": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz",
"integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw=="
},
"node_modules/parse-entities": { "node_modules/parse-entities": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz",
@ -3409,6 +3755,14 @@
"url": "https://github.com/inikulin/parse5?sponsor=1" "url": "https://github.com/inikulin/parse5?sponsor=1"
} }
}, },
"node_modules/path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"engines": {
"node": ">=8"
}
},
"node_modules/path-parse": { "node_modules/path-parse": {
"version": "1.0.7", "version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
@ -3433,6 +3787,21 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/path-scurry": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
"integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
"dependencies": {
"lru-cache": "^10.2.0",
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
},
"engines": {
"node": ">=16 || 14 >=14.18"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/picocolors": { "node_modules/picocolors": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
@ -5800,6 +6169,36 @@
"node": ">= 0.4" "node": ">= 0.4"
} }
}, },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dependencies": {
"shebang-regex": "^3.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/shebang-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"engines": {
"node": ">=8"
}
},
"node_modules/signal-exit": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/source-map": { "node_modules/source-map": {
"version": "0.6.1", "version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@ -5880,6 +6279,20 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/string-width-cjs": {
"name": "string-width",
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/stringify-entities": { "node_modules/stringify-entities": {
"version": "4.0.4", "version": "4.0.4",
"resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz",
@ -5913,6 +6326,18 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/strip-ansi-cjs": {
"name": "strip-ansi",
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dependencies": {
"ansi-regex": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/stylehacks": { "node_modules/stylehacks": {
"version": "7.0.1", "version": "7.0.1",
"resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-7.0.1.tgz", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-7.0.1.tgz",
@ -6067,6 +6492,72 @@
"url": "https://github.com/sponsors/wooorm" "url": "https://github.com/sponsors/wooorm"
} }
}, },
"node_modules/ts-node": {
"version": "10.9.2",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
"dependencies": {
"@cspotcode/source-map-support": "^0.8.0",
"@tsconfig/node10": "^1.0.7",
"@tsconfig/node12": "^1.0.7",
"@tsconfig/node14": "^1.0.0",
"@tsconfig/node16": "^1.0.2",
"acorn": "^8.4.1",
"acorn-walk": "^8.1.1",
"arg": "^4.1.0",
"create-require": "^1.1.0",
"diff": "^4.0.1",
"make-error": "^1.1.1",
"v8-compile-cache-lib": "^3.0.1",
"yn": "3.1.1"
},
"bin": {
"ts-node": "dist/bin.js",
"ts-node-cwd": "dist/bin-cwd.js",
"ts-node-esm": "dist/bin-esm.js",
"ts-node-script": "dist/bin-script.js",
"ts-node-transpile-only": "dist/bin-transpile.js",
"ts-script": "dist/bin-script-deprecated.js"
},
"peerDependencies": {
"@swc/core": ">=1.2.50",
"@swc/wasm": ">=1.2.50",
"@types/node": "*",
"typescript": ">=2.7"
},
"peerDependenciesMeta": {
"@swc/core": {
"optional": true
},
"@swc/wasm": {
"optional": true
}
}
},
"node_modules/ts-node/node_modules/acorn": {
"version": "8.12.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz",
"integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==",
"bin": {
"acorn": "bin/acorn"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/typescript": {
"version": "5.5.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz",
"integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
},
"node_modules/uglify-js": { "node_modules/uglify-js": {
"version": "3.18.0", "version": "3.18.0",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.18.0.tgz", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.18.0.tgz",
@ -6111,8 +6602,7 @@
"node_modules/undici-types": { "node_modules/undici-types": {
"version": "5.26.5", "version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
"dev": true
}, },
"node_modules/unified": { "node_modules/unified": {
"version": "11.0.4", "version": "11.0.4",
@ -6275,6 +6765,11 @@
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
}, },
"node_modules/v8-compile-cache-lib": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg=="
},
"node_modules/v8flags": { "node_modules/v8flags": {
"version": "4.0.1", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/v8flags/-/v8flags-4.0.1.tgz", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-4.0.1.tgz",
@ -6492,6 +6987,23 @@
"url": "https://github.com/chalk/wrap-ansi?sponsor=1" "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
} }
}, },
"node_modules/wrap-ansi-cjs": {
"name": "wrap-ansi",
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"dependencies": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
"node_modules/wrappy": { "node_modules/wrappy": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
@ -6549,6 +7061,14 @@
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/yn": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
"engines": {
"node": ">=6"
}
},
"node_modules/zwitch": { "node_modules/zwitch": {
"version": "2.0.4", "version": "2.0.4",
"resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",

View File

@ -7,6 +7,7 @@
"@mapbox/rehype-prism": "^0.9.0", "@mapbox/rehype-prism": "^0.9.0",
"asciidoctor": "^3.0.4", "asciidoctor": "^3.0.4",
"cssnano": "^7.0.2", "cssnano": "^7.0.2",
"glob": "^10.4.2",
"gulp": "^5.0.0", "gulp": "^5.0.0",
"gulp-cli": "^3.0.0", "gulp-cli": "^3.0.0",
"gulp-postcss": "^10.0.0", "gulp-postcss": "^10.0.0",
@ -19,18 +20,21 @@
"rehype-external-links": "^3.0.0", "rehype-external-links": "^3.0.0",
"rehype-preset-minify": "^7.0.0", "rehype-preset-minify": "^7.0.0",
"tmp": "^0.2.3", "tmp": "^0.2.3",
"ts-node": "^10.9.2",
"unified": "^11.0.4" "unified": "^11.0.4"
}, },
"devDependencies": { "devDependencies": {
"@types/express": "^4.17.21", "@types/express": "^4.17.21",
"@types/glob": "^8.1.0",
"@types/gulp": "^4.0.17", "@types/gulp": "^4.0.17",
"@types/gulp-postcss": "^8.0.6",
"@types/luxon": "^3.4.2", "@types/luxon": "^3.4.2",
"@types/pug": "^2.0.10", "@types/pug": "^2.0.10",
"@types/tmp": "^0.2.6", "@types/tmp": "^0.2.6",
"prettier": "^3.3.1" "prettier": "^3.3.1"
}, },
"scripts": { "scripts": {
"build": "gulp", "build": "env NODE_OPTIONS='--import ./lib/ts-loader.js' gulp",
"watch": "gulp watch", "watch": "gulp watch",
"dev": "python -m http.server -d dist" "dev": "python -m http.server -d dist"
} }

View File

@ -10,6 +10,6 @@ html(lang="en")
meta(name="theme-color" content="#DDCBA3")/ meta(name="theme-color" content="#DDCBA3")/
- for([name, content] of Object.entries(meta)) - for([name, content] of Object.entries(meta))
meta(name=name content=content)/ meta(name=name content=content)/
link(rel="stylesheet" type="text/css" href=`${asset('index.css')}?v2`)/ link(rel="stylesheet" type="text/css" href=asset("index.css"))/
body: .main body: .main
!= render() != render()

11
tsconfig.json Normal file
View File

@ -0,0 +1,11 @@
{
"ts-node": {
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "NodeNext"
}
},
"compilerOptions": {
"esModuleInterop": true,
}
}