From a5d5e5817dbdef12e28e795aa87093a841e40591 Mon Sep 17 00:00:00 2001 From: stephansama Date: Tue, 21 Apr 2026 09:21:46 -0400 Subject: [PATCH 1/8] chore(cspell): add cleye to cspell and update .gitignore --- .config/.cspell.json | 1 + .config/lefthook.yml | 15 + .gitignore | 3 +- .husky/commit-msg | 3 - .husky/pre-commit | 5 - .husky/prepare-commit-msg | 3 - README.md | 86 --- core/single-file/README.md | 27 + core/single-file/cli.mjs | 10 + core/single-file/package.json | 61 ++ core/single-file/src/index.ts | 323 +++++++++ core/single-file/tsconfig.json | 4 + core/single-file/tsdown.config.ts | 11 + core/single-file/typedoc.json | 12 + package.json | 4 +- pnpm-lock.yaml | 1107 +++++++++++++++++++++++------ pnpm-workspace.yaml | 119 ++-- tsconfig.base.json | 39 +- 18 files changed, 1444 insertions(+), 389 deletions(-) create mode 100644 .config/lefthook.yml delete mode 100644 .husky/commit-msg delete mode 100644 .husky/pre-commit delete mode 100644 .husky/prepare-commit-msg create mode 100644 core/single-file/README.md create mode 100644 core/single-file/cli.mjs create mode 100644 core/single-file/package.json create mode 100644 core/single-file/src/index.ts create mode 100644 core/single-file/tsconfig.json create mode 100644 core/single-file/tsdown.config.ts create mode 100644 core/single-file/typedoc.json diff --git a/.config/.cspell.json b/.config/.cspell.json index d9082118..5bffaacd 100644 --- a/.config/.cspell.json +++ b/.config/.cspell.json @@ -13,6 +13,7 @@ "barhandles", "bluwy", "catppuccin", + "cleye", "commitlint", "dotenvx", "esbuild", diff --git a/.config/lefthook.yml b/.config/lefthook.yml new file mode 100644 index 00000000..9037e6d7 --- /dev/null +++ b/.config/lefthook.yml @@ -0,0 +1,15 @@ +prepare-commit-msg: + jobs: + - run: ai-commit-msg -o {1} +commit-msg: + jobs: + - run: pnpm dlx commitlint --config .config/.commitlintrc.ts --edit {1} +pre-commit: + parallel: true + jobs: + - run: auto-readme -vg + name: Update README + - run: lint-staged -v + name: Lint staged + - run: pnpm --workspace-root run scripts:lint-examples + name: Lint examples diff --git a/.gitignore b/.gitignore index 35db97d6..6403776d 100644 --- a/.gitignore +++ b/.gitignore @@ -9,8 +9,8 @@ .config/www/public/* .env** .next -.react-router .publish +.react-router .svelte-kit .turbo .wrangler @@ -22,4 +22,5 @@ core/types-lhci/config dist*/ examples/catppuccin-xsl/vanilla/public/**/* node_modules +single-file.html storybook-static diff --git a/.husky/commit-msg b/.husky/commit-msg deleted file mode 100644 index f5d44c79..00000000 --- a/.husky/commit-msg +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -pnpm dlx commitlint --config .config/.commitlintrc.ts --edit "$1" diff --git a/.husky/pre-commit b/.husky/pre-commit deleted file mode 100644 index 00f78934..00000000 --- a/.husky/pre-commit +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -auto-readme -g -lint-staged -v -pnpm --workspace-root run scripts:lint-examples diff --git a/.husky/prepare-commit-msg b/.husky/prepare-commit-msg deleted file mode 100644 index e932fce7..00000000 --- a/.husky/prepare-commit-msg +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -ai-commit-msg -o "$1" diff --git a/README.md b/README.md index 4d704125..e69de29b 100644 --- a/README.md +++ b/README.md @@ -1,86 +0,0 @@ -
- -# [`@stephansama`](https://github.com/stephansama/packages) packages - -[![PNPM](https://img.shields.io/badge/PNPM-10.9-F69220.svg?logo=pnpm&logoColor=white&labelColor=F69220)](https://github.com/search?q=repo%3Astephansama%2Fnvim%20language%3Alua&type=code) -[![TypeScript](https://img.shields.io/badge/TypeScript-5.8.3-3178C6.svg?logo=typescript&logoColor=white&labelColor=3178C6)](https://github.com/search?q=repo%3Astephansama%2Fnvim%20language%3ATypeScript&type=code) -[![Turborepo](https://img.shields.io/badge/Turborepo-2.5.4-FF1E56.svg?logo=turborepo&logoColor=white&labelColor=FF1E56)](https://turborepo.com/) - -[![codecov](https://codecov.io/github/stephansama/packages/graph/badge.svg)](https://codecov.io/github/stephansama/packages) -[![🦋 Changesets Release](https://github.com/stephansama/packages/actions/workflows/release.yml/badge.svg)](https://github.com/stephansama/packages/actions/workflows/release.yml) -[![CodeQL](https://github.com/stephansama/packages/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/stephansama/packages/actions/workflows/github-code-scanning/codeql) - -Collection of open-source [npm](https://www.npmx.dev/) packages - -
- -##### Table of contents - -
Open Table of contents - -- [Introduction](#introduction) -- [📦 Packages](#-packages) - - [☂️ Codecov coverage graph](#️-codecov-coverage-graph) - - [⭐ Stargazers](#-stargazers) -- [Related repositories](#related-repositories) - -
- -## Introduction - -view examples here 👉 [![packages](https://pkg.pr.new/badge/stephansama/packages?style=flat&color=000&logoSize=auto)](https://pkg.pr.new/~/stephansama/packages) - -or install an example with [`create-stephansama-example`](https://github.com/stephansama/packages/tree/main/core/example) -via `pnpm create stephansama-example` - -## 📦 Packages - -All packages are packaged underneath the `@stephansama` scope (for example: `@stephansama/remark-asciinema`) - - - -### 🏭 workspace - -| 🏷️ Name | Version | 📥 Downloads | 📝 Description | -| ------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | -| [ai-commit-msg](core/ai-commit-msg/README.md) | ![npm version image](https://img.shields.io/npm/v/%40stephansama%2Fai-commit-msg?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/@stephansama/ai-commit-msg?labelColor=211F1F) | generate commit messages using ai | -| [alfred-kaomoji](core/alfred-kaomoji/README.md) | ![npm version image](https://img.shields.io/npm/v/%40stephansama%2Falfred-kaomoji?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/@stephansama/alfred-kaomoji?labelColor=211F1F) | Alfred Kaomoji Picker | -| [astro-iconify-svgmap](core/astro-iconify-svgmap/README.md) | ![npm version image](https://img.shields.io/npm/v/%40stephansama%2Fastro-iconify-svgmap?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/@stephansama/astro-iconify-svgmap?labelColor=211F1F) | Astro integration for generating iconify svgmaps for ssg sites | -| [auto-readme](core/auto-readme/README.md) | ![npm version image](https://img.shields.io/npm/v/%40stephansama%2Fauto-readme?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/@stephansama/auto-readme?labelColor=211F1F) | Generate lists and tables for your README automagically based on your repository and comments | -| [catppuccin-jsonresume-theme](core/catppuccin-jsonresume-theme/README.md) | ![npm version image](https://img.shields.io/npm/v/%40stephansama%2Fcatppuccin-jsonresume-theme?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/@stephansama/catppuccin-jsonresume-theme?labelColor=211F1F) | theme for resume cli website | -| [catppuccin-opml](core/catppuccin-opml/README.md) | ![npm version image](https://img.shields.io/npm/v/%40stephansama%2Fcatppuccin-opml?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/@stephansama/catppuccin-opml?labelColor=211F1F) | Catppuccin styled opml stylesheet | -| [catppuccin-rss](core/catppuccin-rss/README.md) | ![npm version image](https://img.shields.io/npm/v/%40stephansama%2Fcatppuccin-rss?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/@stephansama/catppuccin-rss?labelColor=211F1F) | Catppuccin x Pretty-feed-v3 | -| [catppuccin-typedoc](core/catppuccin-typedoc/README.md) | ![npm version image](https://img.shields.io/npm/v/%40stephansama%2Fcatppuccin-typedoc?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/@stephansama/catppuccin-typedoc?labelColor=211F1F) | Catppuccin css variable theme for typedoc | -| [catppuccin-xsl](core/catppuccin-xsl/README.md) | ![npm version image](https://img.shields.io/npm/v/%40stephansama%2Fcatppuccin-xsl?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/@stephansama/catppuccin-xsl?labelColor=211F1F) | Catppuccin styles for various xsl formats | -| [create-stephansama-example](core/example/README.md) | ![npm version image](https://img.shields.io/npm/v/create-stephansama-example?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/create-stephansama-example?labelColor=211F1F) | Download an example from the @stephansama/packages examples | -| [find-makefile-targets](core/find-makefile-targets/README.md) | ![npm version image](https://img.shields.io/npm/v/%40stephansama%2Ffind-makefile-targets?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/@stephansama/find-makefile-targets?labelColor=211F1F) | Find makefile targets used to pipe into fzf | -| [github-env](core/github-env/README.md) | ![npm version image](https://img.shields.io/npm/v/%40stephansama%2Fgithub-env?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/@stephansama/github-env?labelColor=211F1F) | \[Deprecated] Additional environment variable types for GitHub CI | -| [multipublish](core/multipublish/README.md) | ![npm version image](https://img.shields.io/npm/v/%40stephansama%2Fmultipublish?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/@stephansama/multipublish?labelColor=211F1F) | Publish packages to multiple providers easily | -| [prettier-plugin-handlebars](core/prettier-plugin-handlebars/README.md) | ![npm version image](https://img.shields.io/npm/v/%40stephansama%2Fprettier-plugin-handlebars?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/@stephansama/prettier-plugin-handlebars?labelColor=211F1F) | Prettier plugin that automatically assigns the default parser for various handlebars files | -| [remark-asciinema](core/remark-asciinema/README.md) | ![npm version image](https://img.shields.io/npm/v/%40stephansama%2Fremark-asciinema?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/@stephansama/remark-asciinema?labelColor=211F1F) | A remark plugin that transforms Asciinema links into embedded players or screenshots. | -| [svelte-social-share-links](core/svelte-social-share-links/README.md) | ![npm version image](https://img.shields.io/npm/v/%40stephansama%2Fsvelte-social-share-links?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/@stephansama/svelte-social-share-links?labelColor=211F1F) | Svelte/Web component to share the current url with various social media providers | -| [typed-env](core/typed-env/README.md) | ![npm version image](https://img.shields.io/npm/v/%40stephansama%2Ftyped-env?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/@stephansama/typed-env?labelColor=211F1F) | standard schema compatible environment validator | -| [typed-events](core/typed-events/README.md) | ![npm version image](https://img.shields.io/npm/v/%40stephansama%2Ftyped-events?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/@stephansama/typed-events?labelColor=211F1F) | Typed events store using standard schema | -| [typed-nocodb-api](core/typed-nocodb-api/README.md) | ![npm version image](https://img.shields.io/npm/v/%40stephansama%2Ftyped-nocodb-api?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/@stephansama/typed-nocodb-api?labelColor=211F1F) | Typed API client for NocoDB using Zod | -| [typed-templates](core/typed-templates/README.md) | ![npm version image](https://img.shields.io/npm/v/%40stephansama%2Ftyped-templates?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/@stephansama/typed-templates?labelColor=211F1F) | Use standard schema to validate and use handlebar template directories | -| [types-github-action-env](core/types-github-action-env/README.md) | ![npm version image](https://img.shields.io/npm/v/%40stephansama%2Ftypes-github-action-env?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/@stephansama/types-github-action-env?labelColor=211F1F) | environment variable types for GitHub Action environment | -| [types-lhci](core/types-lhci/README.md) | ![npm version image](https://img.shields.io/npm/v/%40stephansama%2Ftypes-lhci?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F) | ![npm downloads](https://img.shields.io/npm/dw/@stephansama/types-lhci?labelColor=211F1F) | types for lhci configuration | - - - -
- -### ☂️ Codecov coverage graph - -![graph](https://codecov.io/github/stephansama/packages/graphs/tree.svg) - -### ⭐ Stargazers - -[![Stargazers repo roster for @stephansama/packages](https://reporoster.com/stars/stephansama/packages)](https://github.com/stephansama/packages/stargazers) - -
- -## Related repositories - -- [stow.nvim](https://github.com/stephansama/stow.nvim) -- [@stephansama/actions](https://github.com/stephansama/actions) diff --git a/core/single-file/README.md b/core/single-file/README.md new file mode 100644 index 00000000..86b27552 --- /dev/null +++ b/core/single-file/README.md @@ -0,0 +1,27 @@ +# @stephansama/single-file + +[![Source code](https://img.shields.io/badge/Source-666666?style=flat&logo=github&label=Github&labelColor=211F1F)](https://github.com/stephansama/packages/tree/main/core/single-file) +[![Documentation](https://img.shields.io/badge/Documentation-211F1F?style=flat&logo=Wikibooks&labelColor=211F1F)](https://packages.stephansama.info/api/@stephansama/single-file) +[![NPM Version](https://img.shields.io/npm/v/%40stephansama%2Fsingle-file?logo=npm&logoColor=red&color=211F1F&labelColor=211F1F)](https://www.npmx.dev/package/@stephansama/single-file) +[![JSR](https://jsr.io/badges/@stephansama/single-file)](https://jsr.io/@stephansama/single-file) +[![socket.dev](https://badge.socket.dev/npm/package/@stephansama/single-file)](https://socket.dev/npm/package/@stephansama/single-file/overview) +[![npm downloads](https://img.shields.io/npm/dw/@stephansama/single-file?labelColor=211F1F)](https://www.npmx.dev/package/@stephansama/single-file) + +create a single html file from a website url + +##### Table of contents + +
Open Table of contents + +- [Installation](#installation) +- [Usage](#usage) + +
+ +## Installation + +```sh +pnpm install @stephansama/single-file +``` + +## Usage diff --git a/core/single-file/cli.mjs b/core/single-file/cli.mjs new file mode 100644 index 00000000..e9c8ad75 --- /dev/null +++ b/core/single-file/cli.mjs @@ -0,0 +1,10 @@ +#!/usr/bin/env node + +"use strict"; + +import("./dist/index.js") + .then((mod) => mod.run()) + .catch((error) => { + console.error(error); + process.exit(1); + }); diff --git a/core/single-file/package.json b/core/single-file/package.json new file mode 100644 index 00000000..93d7c500 --- /dev/null +++ b/core/single-file/package.json @@ -0,0 +1,61 @@ +{ + "name": "@stephansama/single-file", + "version": "0.0.0", + "description": "create a single html file from a website url", + "keywords": [ + "single-file" + ], + "homepage": "https://packages.stephansama.info/api/@stephansama/single-file", + "repository": { + "type": "git", + "url": "git+https://github.com/stephansama/packages.git", + "directory": "core/single-file" + }, + "license": "MIT", + "author": { + "name": "Stephan Randle", + "email": "stephanrandle.dev@gmail.com", + "url": "https://stephansama.info" + }, + "type": "module", + "exports": { + ".": { + "import": "./dist/index.js", + "require": "./dist/index.cjs" + }, + "./package.json": "./package.json" + }, + "main": "./dist/index.cjs", + "module": "./dist/index.js", + "types": "./dist/index.d.cts", + "bin": "./cli.mjs", + "files": [ + "cli.mjs", + "dist" + ], + "scripts": { + "build": "tsdown", + "dev": "tsdown --watch", + "lint": "eslint ./ --pass-on-no-patterns --no-error-on-unmatched-pattern", + "lint:fix": "eslint ./ --fix" + }, + "dependencies": { + "cheerio": "catalog:", + "dedent": "catalog:", + "he": "catalog:", + "ky": "catalog:", + "obug": "catalog:cli", + "oxc-parser": "catalog:", + "svg-sprite-loader": "catalog:" + }, + "devDependencies": { + "@types/he": "catalog:", + "cleye": "catalog:cli", + "tsdown": "catalog:" + }, + "publishConfig": { + "access": "public", + "provenance": true + }, + "readme": "./README.md" +} diff --git a/core/single-file/src/index.ts b/core/single-file/src/index.ts new file mode 100644 index 00000000..b6eab523 --- /dev/null +++ b/core/single-file/src/index.ts @@ -0,0 +1,323 @@ +import * as cheerio from "cheerio"; +import { cli } from "cleye"; +import dedent from "dedent"; +import he from "he"; +import ky, { type KyResponse } from "ky"; +import * as fs from "node:fs"; +import * as path from "node:path"; +import { createDebug, enable } from "obug"; +import * as oxc from "oxc-parser"; + +const html = dedent; + +const BASE_DEBUG_NAMESPACE = "single-file" as const; +const DEBUG_NAMESPACES = ["info", "warn", "error"] as const; +type DEBUG_NAMESPACE = (typeof DEBUG_NAMESPACES)[number]; +type DEBUG_SCOPE = `${typeof BASE_DEBUG_NAMESPACE}:${DEBUG_NAMESPACE}`; + +const debug = createDebug(BASE_DEBUG_NAMESPACE, { + color: 2, + log: console.info, + useColors: true, +}); + +const [debugInfo, debugWarn, debugError] = DEBUG_NAMESPACES.map((namespace) => { + return debug.extend(namespace); +}); + +export async function run() { + const argv = cli({ + flags: { + output: { + alias: "o", + default: "single-file.html", + description: "output path for single html file", + type: String, + }, + verbose: { + alias: "v", + default: false, + description: "Verbose output", + type: Boolean, + }, + }, + name: "single-file", + parameters: [``], + }); + + enableDebug("single-file:warn"); + enableDebug("single-file:error"); + + if (argv.flags.verbose) { + enableDebug("single-file:info"); + debugInfo.log("enabled debug info"); + } + + const pageResponse = await ky.get(argv._.url); + + debugInfo.log(`loading ${argv._.url}`); + + if (!pageResponse?.headers?.get("Content-Type")?.includes("text/html")) { + throw new Error( + `requested url \`${argv._.url}\` must be an html page.`, + ); + } + + const page = await pageResponse.text(); + + const $ = cheerio.load(page); + + for (const svgUse of $("use[href]")) { + debugInfo.log(`loading \`svg>use\` ${svgUse.attribs.href}`); + + const src = isUrl(svgUse.attribs.href, argv._.url); + if (!src) continue; + + const response = await ky.get(src); + const svgMap = await response.text(); + const $$ = cheerio.load(svgMap, { xmlMode: true }); + const [_, hash] = svgUse.attribs.href.split("#"); + if (!hash) return null; + + const symbol = $$(`symbol#${hash}`); + const viewBox = symbol.attr("viewBox") || "0 0 24 24"; + const inner = symbol.html(); + if (!inner) { + throw new Error("unable to parse parent"); + } + + $(svgUse).parent().attr("viewBox", viewBox); + $(svgUse).replaceWith(inner); + } + + for (const img of $("img[src]")) { + debugInfo.log(`loading \`img\` ${img.attribs.src}`); + + const src = isUrl(img.attribs.src, argv._.url); + if (!src) continue; + + const response = await ky.get(src); + const extension = img.attribs.src + .split(".") + .at(-1) + ?.replace(/#.*/, "") + .replace(/\?.*/, ""); + + switch (extension) { + case "svg": { + if (img.attribs.src.includes("#")) { + const svgMap = await response.text(); + const $$ = cheerio.load(svgMap, { xmlMode: true }); + const [_, hash] = img.attribs.src.split("#"); + if (!hash) return null; + + const symbol = $$(`symbol#${hash}`); + const viewBox = symbol.attr("viewBox") || "0 0 24 24"; + const inner = symbol.html(); + const svg = html` + + ${inner} + + `.trim(); + + const encoded = encodeURIComponent(svg) + .replace(/'/g, "%27") + .replace(/"/g, "%22"); + + $(img).attr("src", `data:image/svg+xml,${encoded}`); + } else { + const dataUri = await bufferToDataUri(response); + $(img).attr("src", dataUri); + } + break; + } + default: { + const dataUri = await bufferToDataUri(response); + $(img).attr("src", dataUri); + } + } + } + + for (const link of $("link[href]")) { + debugInfo.log(`loading \`link\` ${link.attribs.href}`); + + const src = isUrl(link.attribs.href, argv._.url); + if (!src) continue; + + const response = await ky.get(src); + + switch (link.attribs.rel) { + case "apple-touch-icon": + case "icon": + case "shortcut icon": { + const dataUri = await bufferToDataUri(response); + $(link).attr("href", dataUri); + break; + } + + case "stylesheet": { + const linkSrc = await response.text(); + $(link).replaceWith( + html``, + ); + + break; + } + } + } + + const imported = []; + + for (const script of $("script[src]")) { + debugInfo.log(`loading \`script\` ${script.attribs.src}`); + const src = isUrl(script.attribs.src, argv._.url); + if (!src) continue; + + let scriptSrc = await ky.get(src).text(); + const result = await oxc.parse(src, scriptSrc); + const dynamicImports = result.module.dynamicImports.map( + (i) => i.moduleRequest, + ); + const staticImports = result.module.staticImports.map( + (i) => i.moduleRequest, + ); + const imports = [...staticImports]; + + const dirname = path.posix.dirname(new URL(src).pathname); + const allImports = imports + .filter((i) => i) + .map((i) => ({ key: i.value, value: dirname + "/" + i.value })); + + imported.push(...allImports); + + for (const current of imports) { + const escaped = current.value.replace( + /[.*+?^${}()|[\]\\]/g, + "\\$&", + ); + + const importRegex = new RegExp(`import\\s*['"]${escaped}['"]`, "g"); + const fromRegex = new RegExp(`from\\s*['"]${escaped}['"]`, "g"); + + scriptSrc = scriptSrc.replaceAll( + importRegex, + `await import(window.registry["${current.value}"])`, + ); + + scriptSrc = scriptSrc.replaceAll( + fromRegex, + `= await import(window.registry["${current.value}"])`, + ); + } + + // Move this OUTSIDE and BEFORE the for loop + scriptSrc = scriptSrc.replace(/\bimport(?!\s*\()/g, "const"); + + debugInfo.log( + `has imports: ${JSON.stringify(allImports, undefined, 2)}`, + ); + + $(script).removeAttr("src"); + $(script).text(scriptSrc); + } + + const setImports = new Set(imported); + const importSources: Record = {}; + + debugInfo.log( + `found imports ${JSON.stringify([...setImports], undefined, 2)}`, + ); + + for (const current of setImports) { + if (!current.key) continue; + + importSources[current.key] = await ky + .get(new URL(current.value, argv._.url)) + .text(); + } + + const registryString = Object.entries(importSources) + .map(([file, source]) => { + const escaped = escapeScript(source); + return ( + '"' + + file + + '": URL.createObjectURL(new Blob([`' + + escaped + + "`], {type: 'text/javascript'}))" + ); + }) + .join(",\n"); + + const registryScript = ``; + + const updatedContent = $.html() + ?.replace("", `${registryScript}`) + .replace( + /]*\bsrc\b)[^>]*)>([\s\S]*?)<\/script>/g, + (match, attrs, content) => { + if (attrs.includes("application/ld+json")) return match; + if (content.includes("window.registry")) return match; + const decoded = he.decode(content); + return `${decoded}`; + }, + ); + + if (!updatedContent) { + throw new Error("unable to generate head content"); + } + + await fs.promises.writeFile(argv.flags.output, updatedContent, "utf8"); +} + +async function bufferToDataUri(res: KyResponse) { + const buffer = await res.arrayBuffer(); + const mime = res.headers.get("content-type") || "image/png"; + const base64 = Buffer.from(buffer).toString("base64"); + return `data:${mime};base64,${base64}`; +} + +function enableDebug(debugScope: DEBUG_SCOPE) { + enable(debugScope); +} + +function escapeScript(script: string) { + return script + .replaceAll("\\", "\\\\") + .replaceAll("`", "\\`") + .replaceAll("${", "\\${") + .replaceAll("", "<\\/script>") + .replaceAll("\n", "\\n") // ← add this + .replaceAll("\r", ""); +} + +function isProbablyUrl(str: string) { + if (!str) return false; + + // reject obvious non-URLs + if (str.includes("\n") || str.includes("{") || str.includes("function")) { + return false; + } + + // allow: + // - absolute URLs + // - root-relative (/foo.js) + // - relative (./foo.js, foo.js) + return /^(https?:\/\/|\/|\.\/|\.\.\/|[a-zA-Z0-9_\-./]+$)/.test(str); +} + +function isUrl(url: string, base: string) { + if (!isProbablyUrl(url)) return false; + try { + return new URL(url, base).href; + } catch (error) { + console.error(`${url} is not a URL\n${error}`); + return false; + } +} diff --git a/core/single-file/tsconfig.json b/core/single-file/tsconfig.json new file mode 100644 index 00000000..0edb9472 --- /dev/null +++ b/core/single-file/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": ["../../tsconfig.base.json"], + "include": ["./src/*"] +} diff --git a/core/single-file/tsdown.config.ts b/core/single-file/tsdown.config.ts new file mode 100644 index 00000000..a1058fc6 --- /dev/null +++ b/core/single-file/tsdown.config.ts @@ -0,0 +1,11 @@ +import { defineConfig } from "tsdown"; + +export default defineConfig({ + attw: true, + dts: true, + entry: ["src/index.ts"], + exports: true, + format: ["esm", "cjs"], + publint: true, + target: "esnext", +}); diff --git a/core/single-file/typedoc.json b/core/single-file/typedoc.json new file mode 100644 index 00000000..57eeff2c --- /dev/null +++ b/core/single-file/typedoc.json @@ -0,0 +1,12 @@ +{ + "entryPoints": ["src/*"], + "tsconfig": "./tsconfig.json", + "exclude": [ + "**/tests/**", + "**/*.test.ts", + "**/*.spec.ts", + "node_modules", + "**/{node_modules,test,book,doc,dist}/**/*", + "**/{pages,components}/**" + ] +} diff --git a/package.json b/package.json index cdaf884c..3ce2afa7 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "fmt:write": "prettier . --write", "knip": "knip --config ./.config/knip.ts", "lint": "turbo lint", - "prepare": "husky", + "prepare": "[ \"$CI\" = \"true\" ] || lefthook install", "publish": "changeset publish", "scripts:generate-examples": "node ./scripts/generate-examples.js", "scripts:lint-examples": "node ./scripts/lint-examples.js", @@ -68,7 +68,6 @@ "eslint-plugin-testing-library": "catalog:eslint", "eslint-plugin-zod": "catalog:eslint", "globals": "catalog:eslint", - "husky": "^9.1.7", "jsdom": "^27.4.0", "jsonc-eslint-parser": "catalog:eslint", "knip": "^5.83.1", @@ -91,6 +90,7 @@ }, "devDependencies": { "actions-up": "catalog:", + "lefthook": "catalog:", "node-plop": "catalog:", "taze": "catalog:" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index de5ac01c..26b8af8b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,6 +6,9 @@ settings: catalogs: cli: + cleye: + specifier: ^2.6.0 + version: 2.6.0 cosmiconfig: specifier: 9.0.0 version: 9.0.0 @@ -62,6 +65,9 @@ catalogs: '@types/handlebars-helpers': specifier: 0.5.6 version: 0.5.6 + '@types/he': + specifier: ^1.2.3 + version: 1.2.3 '@types/mdast': specifier: 4.0.4 version: 4.0.4 @@ -83,6 +89,12 @@ catalogs: astro: specifier: 5.9.3 version: 5.9.3 + cheerio: + specifier: ^1.2.0 + version: 1.2.0 + dedent: + specifier: ^1.7.2 + version: 1.7.2 deepmerge: specifier: 4.3.1 version: 4.3.1 @@ -98,12 +110,21 @@ catalogs: happy-dom: specifier: 20.6.1 version: 20.6.1 + he: + specifier: ^1.2.0 + version: 1.2.0 json-schema-to-typescript: specifier: 15.0.4 version: 15.0.4 jsr: specifier: 0.13.5 version: 0.13.5 + ky: + specifier: ^2.0.1 + version: 2.0.1 + lefthook: + specifier: ^2.1.6 + version: 2.1.6 mdast: specifier: 3.0.0 version: 3.0.0 @@ -113,9 +134,15 @@ catalogs: node-plop: specifier: 0.32.3 version: 0.32.3 + oxc-parser: + specifier: ^0.127.0 + version: 0.127.0 remark: specifier: 15.0.1 version: 15.0.1 + svg-sprite-loader: + specifier: ^6.0.11 + version: 6.0.11 tailwind-scrollbar: specifier: 4.0.2 version: 4.0.2 @@ -403,9 +430,6 @@ importers: globals: specifier: catalog:eslint version: 16.5.0 - husky: - specifier: ^9.1.7 - version: 9.1.7 jsdom: specifier: ^27.4.0 version: 27.4.0(@noble/hashes@1.8.0) @@ -467,6 +491,9 @@ importers: actions-up: specifier: 'catalog:' version: 1.11.0 + lefthook: + specifier: 'catalog:' + version: 2.1.6 node-plop: specifier: 'catalog:' version: 0.32.3(@types/node@24.10.13) @@ -829,6 +856,40 @@ importers: specifier: 'catalog:' version: 5.1.0 + core/single-file: + dependencies: + cheerio: + specifier: 'catalog:' + version: 1.2.0 + dedent: + specifier: 'catalog:' + version: 1.7.2 + he: + specifier: 'catalog:' + version: 1.2.0 + ky: + specifier: 'catalog:' + version: 2.0.1 + obug: + specifier: catalog:cli + version: 2.1.1 + oxc-parser: + specifier: 'catalog:' + version: 0.127.0 + svg-sprite-loader: + specifier: 'catalog:' + version: 6.0.11 + devDependencies: + '@types/he': + specifier: 'catalog:' + version: 1.2.3 + cleye: + specifier: catalog:cli + version: 2.6.0 + tsdown: + specifier: 'catalog:' + version: 0.15.12(@arethetypeswrong/core@0.18.2)(oxc-resolver@11.17.1)(publint@0.3.18)(typescript@5.9.3)(vue-tsc@2.2.12(typescript@5.9.3)) + core/svelte-social-share-links: devDependencies: '@chromatic-com/storybook': @@ -1843,12 +1904,21 @@ packages: '@emnapi/core@1.7.1': resolution: {integrity: sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==} + '@emnapi/core@1.9.2': + resolution: {integrity: sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==} + '@emnapi/runtime@1.7.1': resolution: {integrity: sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==} + '@emnapi/runtime@1.9.2': + resolution: {integrity: sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==} + '@emnapi/wasi-threads@1.1.0': resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} + '@emnapi/wasi-threads@1.2.1': + resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + '@esbuild/aix-ppc64@0.21.5': resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} engines: {node: '>=12'} @@ -3179,6 +3249,12 @@ packages: '@napi-rs/wasm-runtime@1.1.1': resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} + '@napi-rs/wasm-runtime@1.1.4': + resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==} + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 + '@neoconfetti/react@1.0.0': resolution: {integrity: sha512-klcSooChXXOzIm+SE5IISIAn3bYzYfPjbX7D7HoqZL84oAfgREeSg5vSIaSFH+DaGzzvImTyWe1OyrJ67vik4A==} @@ -3269,6 +3345,136 @@ packages: '@oslojs/encoding@1.1.0': resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==} + '@oxc-parser/binding-android-arm-eabi@0.127.0': + resolution: {integrity: sha512-0LC7ye4hvqbIKxAzThzvswgHLFu2AURKzYLeSVvLdu2TBOYWQDmHnTqPLeA597BcUCxiLqLsS4CJ5uoI5WYWCQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@oxc-parser/binding-android-arm64@0.127.0': + resolution: {integrity: sha512-b5jtVTH6AU5CJXHNdj7Jj9IEiR9yVjjnwHzPJhGyHGPdcsZSzBCkS9GBbV33niRMvKthDwQRFRJfI4a+k4PvYg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@oxc-parser/binding-darwin-arm64@0.127.0': + resolution: {integrity: sha512-obCE8B7ISKkJidjlhv9xRGJPOSDG2Yu6PRga9Ruaz35uintHxbp1Ki/Yc71wx4rj3Edrm0a1kzG1TAwit0wFpg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@oxc-parser/binding-darwin-x64@0.127.0': + resolution: {integrity: sha512-JL6Xb5IwPQT8rUzlpsX7E+AgfcdNklXNPFp8pjCQQ5MQOQo5rtEB2ui+3Hgg9Sn7Y9Egj6YOLLiHhLpdAe12Aw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@oxc-parser/binding-freebsd-x64@0.127.0': + resolution: {integrity: sha512-SDQ/3MQFw58fqQz3Z1PhSKFF3JoCF4gmlNjziDm8X02tTahCw0qJbd7FGPDKw1i4VTBZene9JPyC3mHtSvi+wA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@oxc-parser/binding-linux-arm-gnueabihf@0.127.0': + resolution: {integrity: sha512-Av+D1MIqzV0YMGPT9we2SIZaMKD7Cxs4CvXSx/yxaWHewZjYEjScpOf5igc8IILASViw4WTnjlwUdI1KzVtDHQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-parser/binding-linux-arm-musleabihf@0.127.0': + resolution: {integrity: sha512-Cs2fdJ8cPpFdeebj6p4dag8A4+56hPvZ0AhQQzlaLswGz1tz7bXt1nETLeorrM9+AMcWFFkqxcXwDGfTVidY8g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-parser/binding-linux-arm64-gnu@0.127.0': + resolution: {integrity: sha512-qdOfTcT6SY8gsJrrV92uyEUyjqMGPpIB5JZUG6QN5dukYd+7/j0kX6MwK1DgQj39jtUYixxPiaRUiEN1+0CXgQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-arm64-musl@0.127.0': + resolution: {integrity: sha512-EoTCZneNFU/P2qrpEM+RHmQwt+CvDkyGESG6qhr7KaegXLZwePfbrkCDfAk8/rhxbDUVGsZILX+2tqPzFtoFWA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxc-parser/binding-linux-ppc64-gnu@0.127.0': + resolution: {integrity: sha512-zALjmZYgxFLHjXeudcDF0xFGNydTAtkAeXAr2EuC17ywCyFxcmQra4w0BMde0Yi/re4Bi4iwEoEXtYN7l6eBLQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-riscv64-gnu@0.127.0': + resolution: {integrity: sha512-fPP8M6zQLS7Jz7o9d5ArUSuAuSK3e+WCYVrCpdzeCOejidtZExJ9tjhDrAd3HEPqARBCPmdpqxESPFqy44vkBQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-riscv64-musl@0.127.0': + resolution: {integrity: sha512-7IcC4Ao02oGpfnjt+X/oF4U2mllo2qoSkw5xxiXNKL9MCTsTiAC6616beOuehdxGcnz1bRoPC1RQ2f1GQDdN+g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@oxc-parser/binding-linux-s390x-gnu@0.127.0': + resolution: {integrity: sha512-pbXIhiNFHoqWeqDNLiJ9JkpHz1IM9k4DXa66x+1GTWMG7iLxtkXgE53iiuKSXwmk3zIYmaPVfBvgcAhS583K4Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-x64-gnu@0.127.0': + resolution: {integrity: sha512-MYCguB9RvBvlSd6gbuNI7QwiLoCCAlGnlRJFPrzLI6U1/9wkC/WK6LtBAUln55H1Ctqw45PWmqrobKoMhsYQzQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-x64-musl@0.127.0': + resolution: {integrity: sha512-5eY0B/bxf1xIUxb4NOTvOI3KWtBQfPWYyKAzgcrCt0mDibSZygVpO1Pz8bkeiSZ5Jj9+M09dkggG3H8I5d0Uyg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxc-parser/binding-openharmony-arm64@0.127.0': + resolution: {integrity: sha512-Gld0ajrFTUXNtdw20fVBuTQx66FA75nIVg+//pPfR3sXkuABB4mTBhl3r9JNzrJpgW//qiwxf0nWXUWGJSL3UQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxc-parser/binding-wasm32-wasi@0.127.0': + resolution: {integrity: sha512-T6KVD7rhLzFlwGRXMnxUFfkCZD8FHnb968wVXW1mXzgRFc5RNXOBY2mPPDZ77x5Ln76ltLMgtPg0cOkU1NSrEQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + + '@oxc-parser/binding-win32-arm64-msvc@0.127.0': + resolution: {integrity: sha512-Ujvw4X+LD1CCGULcsQcvb4YNVoBGqt+JHgNNzGGaCImELiZLk477ifUH53gIbE7EKd933NdTi25JWEr9K2HwXw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@oxc-parser/binding-win32-ia32-msvc@0.127.0': + resolution: {integrity: sha512-0cwxKO7KHQQQfo4Uf4B2SQrhgm+cJaP9OvFFhx52Tkg4bezsacu83GB2/In5bC415Ueeym+kXdnge/57rbSfTw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@oxc-parser/binding-win32-x64-msvc@0.127.0': + resolution: {integrity: sha512-rOrnSQSCbhI2kowr9XxE7m9a8oQXnBHjnS6j95LxxAnEZ0+Fz20WlRXG4ondQb+ejjt2KOsa65sE6++L6kUd+w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@oxc-project/types@0.127.0': + resolution: {integrity: sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ==} + '@oxc-project/types@0.95.0': resolution: {integrity: sha512-vACy7vhpMPhjEJhULNxrdR0D943TkA/MigMpJCHmBHvMXxRStRi/dPtTlfQ3uDwWSzRpT8z+7ImjZVf8JWBocQ==} @@ -3786,27 +3992,18 @@ packages: '@shikijs/core@2.5.0': resolution: {integrity: sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg==} - '@shikijs/core@3.19.0': - resolution: {integrity: sha512-L7SrRibU7ZoYi1/TrZsJOFAnnHyLTE1SwHG1yNWjZIVCqjOEmCSuK2ZO9thnRbJG6TOkPp+Z963JmpCNw5nzvA==} - '@shikijs/core@3.22.0': resolution: {integrity: sha512-iAlTtSDDbJiRpvgL5ugKEATDtHdUVkqgHDm/gbD2ZS9c88mx7G1zSYjjOxp5Qa0eaW0MAQosFRmJSk354PRoQA==} '@shikijs/engine-javascript@2.5.0': resolution: {integrity: sha512-VjnOpnQf8WuCEZtNUdjjwGUbtAVKuZkVQ/5cHy/tojVVRIRtlWMYVjyWhxOmIq05AlSOv72z7hRNRGVBgQOl0w==} - '@shikijs/engine-javascript@3.19.0': - resolution: {integrity: sha512-ZfWJNm2VMhKkQIKT9qXbs76RRcT0SF/CAvEz0+RkpUDAoDaCx0uFdCGzSRiD9gSlhm6AHkjdieOBJMaO2eC1rQ==} - '@shikijs/engine-javascript@3.22.0': resolution: {integrity: sha512-jdKhfgW9CRtj3Tor0L7+yPwdG3CgP7W+ZEqSsojrMzCjD1e0IxIbwUMDDpYlVBlC08TACg4puwFGkZfLS+56Tw==} '@shikijs/engine-oniguruma@2.5.0': resolution: {integrity: sha512-pGd1wRATzbo/uatrCIILlAdFVKdxImWJGQ5rFiB5VZi2ve5xj3Ax9jny8QvkaV93btQEwR/rSz5ERFpC5mKNIw==} - '@shikijs/engine-oniguruma@3.19.0': - resolution: {integrity: sha512-1hRxtYIJfJSZeM5ivbUXv9hcJP3PWRo5prG/V2sWwiubUKTa+7P62d2qxCW8jiVFX4pgRHhnHNp+qeR7Xl+6kg==} - '@shikijs/engine-oniguruma@3.22.0': resolution: {integrity: sha512-DyXsOG0vGtNtl7ygvabHd7Mt5EY8gCNqR9Y7Lpbbd/PbJvgWrqaKzH1JW6H6qFkuUa8aCxoiYVv8/YfFljiQxA==} @@ -3816,9 +4013,6 @@ packages: '@shikijs/langs@2.5.0': resolution: {integrity: sha512-Qfrrt5OsNH5R+5tJ/3uYBBZv3SuGmnRPejV9IlIbFH3HTGLDlkqgHymAlzklVmKBjAaVmkPkyikAV/sQ1wSL+w==} - '@shikijs/langs@3.19.0': - resolution: {integrity: sha512-dBMFzzg1QiXqCVQ5ONc0z2ebyoi5BKz+MtfByLm0o5/nbUu3Iz8uaTCa5uzGiscQKm7lVShfZHU1+OG3t5hgwg==} - '@shikijs/langs@3.22.0': resolution: {integrity: sha512-x/42TfhWmp6H00T6uwVrdTJGKgNdFbrEdhaDwSR5fd5zhQ1Q46bHq9EO61SCEWJR0HY7z2HNDMaBZp8JRmKiIA==} @@ -3828,9 +4022,6 @@ packages: '@shikijs/themes@2.5.0': resolution: {integrity: sha512-wGrk+R8tJnO0VMzmUExHR+QdSaPUl/NKs+a4cQQRWyoc3YFbUzuLEi/KWK1hj+8BfHRKm2jNhhJck1dfstJpiw==} - '@shikijs/themes@3.19.0': - resolution: {integrity: sha512-H36qw+oh91Y0s6OlFfdSuQ0Ld+5CgB/VE6gNPK+Hk4VRbVG/XQgkjnt4KzfnnoO6tZPtKJKHPjwebOCfjd6F8A==} - '@shikijs/themes@3.22.0': resolution: {integrity: sha512-o+tlOKqsr6FE4+mYJG08tfCFDS+3CG20HbldXeVoyP+cYSUxDhrFf3GPjE60U55iOkkjbpY2uC3It/eeja35/g==} @@ -3843,9 +4034,6 @@ packages: '@shikijs/types@2.5.0': resolution: {integrity: sha512-ygl5yhxki9ZLNuNpPitBWvcy9fsSKKaRuO4BAlMyagszQidxcpLAr0qiW/q43DtSIDxO6hEbtYLiFZNXO/hdGw==} - '@shikijs/types@3.19.0': - resolution: {integrity: sha512-Z2hdeEQlzuntf/BZpFG8a+Fsw9UVXdML7w0o3TgSXV3yNESGon+bs9ITkQb3Ki7zxoXOOu5oJWqZ2uto06V9iQ==} - '@shikijs/types@3.22.0': resolution: {integrity: sha512-491iAekgKDBFE67z70Ok5a8KBMsQ2IJwOWw3us/7ffQkIBCyOQfm/aNwVMBUriP02QshIfgHCBSIYAl3u2eWjg==} @@ -4393,6 +4581,9 @@ packages: '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + '@types/he@1.2.3': + resolution: {integrity: sha512-q67/qwlxblDzEDvzHhVkwc1gzVWxaNxeyHUBF4xElrvjL11O+Ytze+1fGpBHlr/H9myiBUaUXNnNPmBHxxfAcA==} + '@types/html-minifier-terser@7.0.2': resolution: {integrity: sha512-mm2HqV22l8lFQh4r2oSsOEVea+m0qqxEmwpc9kC1p/XzmjLWrReR9D/GRs8Pex2NX/imyEH9c5IU/7tMBQCHOA==} @@ -5246,6 +5437,9 @@ packages: resolution: {integrity: sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==} engines: {node: '>=0.6'} + big.js@5.2.2: + resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} + binary-searching@2.0.5: resolution: {integrity: sha512-v4N2l3RxL+m4zDxyxz3Ne2aTmiPn8ZUpKFpdPtO+ItW1NcTCXA7JeHG5GMBSvoKSkQZ9ycS+EouDVxYB9ufKWA==} @@ -5264,6 +5458,9 @@ packages: blob-to-buffer@1.2.9: resolution: {integrity: sha512-BF033y5fN6OCofD3vgHmNtwZWRcq9NLyyxyILx9hfMy1sXYy4ojFl765hJ2lP0YaN2fuxPaLO2Vzzoxy0FLFFA==} + bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + body-parser@1.20.3: resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} @@ -5430,6 +5627,13 @@ packages: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} engines: {node: '>= 16'} + cheerio-select@2.1.0: + resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} + + cheerio@1.2.0: + resolution: {integrity: sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==} + engines: {node: '>=20.18.1'} + chokidar@4.0.3: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} @@ -5473,6 +5677,9 @@ packages: resolution: {integrity: sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==} engines: {node: '>=14.16'} + cleye@2.6.0: + resolution: {integrity: sha512-u0SQCsega/ox+2GSuUlG6wvA9c2FtH8sPmv9G9Q3JRTs7FK6+LtaziRAQgx7lrJ1J7bOd3palhwgZKMg8R6JbQ==} + cli-boxes@3.0.0: resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} engines: {node: '>=10'} @@ -5831,6 +6038,14 @@ packages: babel-plugin-macros: optional: true + dedent@1.7.2: + resolution: {integrity: sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + deep-eql@5.0.2: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} @@ -5842,6 +6057,10 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + deepmerge@1.3.2: + resolution: {integrity: sha512-qjMjTrk+RKv/sp4RPDpV5CnKhxjFI9p+GkLBOls5A8EEElldYWCWA9zceAkmfd0xIo2aU1nxiaLFoiya2sb6Cg==} + engines: {node: '>=0.10.0'} + deepmerge@4.3.1: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} @@ -5934,9 +6153,6 @@ packages: resolution: {integrity: sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ==} engines: {node: '>=18'} - devalue@5.5.0: - resolution: {integrity: sha512-69sM5yrHfFLJt0AZ9QqZXGCPfJ7fQjvpln3Rq5+PS03LD32Ost1Q9N+eEnaQwGRIriKkMImXD56ocjQmfjbV3w==} - devalue@5.6.2: resolution: {integrity: sha512-nPRkjWzzDQlsejL1WVifk5rvcFi/y1onBRxjaFMjZeR9mFpqu2gmAZ9xUB9/IEanEP/vBtGeGganC/GO1fmufg==} @@ -5967,16 +6183,31 @@ packages: dom-accessibility-api@0.6.3: resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + dom-serializer@0.2.2: + resolution: {integrity: sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==} + dom-serializer@2.0.0: resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + domelementtype@1.3.1: + resolution: {integrity: sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==} + domelementtype@2.3.0: resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + domhandler@2.4.2: + resolution: {integrity: sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==} + domhandler@5.0.3: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} + domready@1.0.8: + resolution: {integrity: sha512-uIzsOJUNk+AdGE9a6VDeessoMCzF8RrZvJCX/W8QtyfgdR6Uofn/MvRonih3OtCO79b2VDzDOymuiABrQ4z3XA==} + + domutils@1.7.0: + resolution: {integrity: sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==} + domutils@3.2.2: resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} @@ -6048,6 +6279,10 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + emojis-list@3.0.0: + resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} + engines: {node: '>= 4'} + empathic@2.0.0: resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==} engines: {node: '>=14'} @@ -6060,6 +6295,9 @@ packages: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} + encoding-sniffer@0.2.1: + resolution: {integrity: sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==} + enhanced-resolve@5.20.0: resolution: {integrity: sha512-/ce7+jQ1PQ6rVXwe+jKEg5hW5ciicHwIQUagZkp6IufBoY3YDgdTTY1azVs0qoRgVmvsNB+rbjLJxDAeHHtwsQ==} engines: {node: '>=10.13.0'} @@ -6072,6 +6310,12 @@ packages: resolution: {integrity: sha512-kKvD1tO6BM+oK9HzCPpUdRb4vKFQY/FPTFmurMvh6LlN68VMrdj77w8yp51/kDbpkFOS9J8w5W6zIzgM2H8/hw==} engines: {node: '>= 0.4'} + entities@1.1.2: + resolution: {integrity: sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==} + + entities@2.2.0: + resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} + entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -6775,9 +7019,6 @@ packages: resolution: {integrity: sha512-lh9HLdb53sC7XIZOYzTXM4lFuXElv3EVkSDhsd7DoJBj7hm+Ni7D3qYbb+Rr8DuM8nRanBvkVO9d7askreXGnQ==} deprecated: Removed event-stream from gulp-header - h3@1.15.4: - resolution: {integrity: sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==} - h3@1.15.5: resolution: {integrity: sha512-xEyq3rSl+dhGX2Lm0+eFQIAzlDN6Fs0EcC4f7BNUmzaRX/PTzeuM+Tr2lHB8FoXggsQIeXLj8EDVgs5ywxyxmg==} @@ -6810,6 +7051,10 @@ packages: resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} engines: {node: '>= 0.4'} + has-flag@1.0.0: + resolution: {integrity: sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==} + engines: {node: '>=0.10.0'} + has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} @@ -6951,6 +7196,12 @@ packages: html-void-elements@3.0.0: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + htmlparser2@10.1.0: + resolution: {integrity: sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==} + + htmlparser2@3.10.1: + resolution: {integrity: sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==} + http-cache-semantics@4.2.0: resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} @@ -6982,15 +7233,14 @@ packages: resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==} engines: {node: '>=18.18.0'} - husky@9.1.7: - resolution: {integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==} - engines: {node: '>=18'} - hasBin: true - iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + iconv-lite@0.7.0: resolution: {integrity: sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==} engines: {node: '>=0.10.0'} @@ -7006,6 +7256,11 @@ packages: resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} engines: {node: '>= 4'} + image-size@0.5.5: + resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==} + engines: {node: '>=0.10.0'} + hasBin: true + import-fresh@3.3.1: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} @@ -7256,6 +7511,10 @@ packages: resolution: {integrity: sha512-qhsCR/Esx4U4hg/9I19OVUAJkGWtjRYHMRgUMZE2TDdj+Ag+kttZanLupfddNyglzz50cUlmWzUaI37GDfNx/g==} engines: {node: '>=0.10.0'} + is-plain-obj@1.1.0: + resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} + engines: {node: '>=0.10.0'} + is-plain-obj@3.0.0: resolution: {integrity: sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==} engines: {node: '>=10'} @@ -7433,6 +7692,9 @@ packages: jju@1.4.0: resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} + js-base64@2.6.4: + resolution: {integrity: sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==} + js-tokens@10.0.0: resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} @@ -7492,6 +7754,10 @@ packages: json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} @@ -7563,6 +7829,10 @@ packages: kolorist@1.8.0: resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + ky@2.0.1: + resolution: {integrity: sha512-HJPEjEpQPZQ5M3G5eu90/LWZDwysCnvqcfbLvq9FUvfizBZRi58WEixswyyI32LOLcFQd43w7kcfgkCPFxDt/Q==} + engines: {node: '>=22'} + language-subtag-registry@0.3.23: resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} @@ -7581,6 +7851,60 @@ packages: resolution: {integrity: sha512-7vp2Acd2+Kz4XkzxGxaB1FWOi8KjWIWsgdfD5MCb86DWvlLqhRPM+d6Pro3iNEL5VT9mstz5hKAlcd+QR6H3aA==} engines: {node: '>=0.10.0'} + lefthook-darwin-arm64@2.1.6: + resolution: {integrity: sha512-hyB7eeiX78BS66f70byTJacDLC/xV1vgMv9n+idFUsrM7J3Udd/ag9Ag5NP3t0eN0EqQqAtrNnt35EH01lxnRQ==} + cpu: [arm64] + os: [darwin] + + lefthook-darwin-x64@2.1.6: + resolution: {integrity: sha512-5Ka6cFxiH83krt+OMRQtmS6zqoZR5SLXSudLjTbZA1c3ZqF0+dqkeb4XcB6plx6WR0GFizabuc6Bi3iXPIe1eQ==} + cpu: [x64] + os: [darwin] + + lefthook-freebsd-arm64@2.1.6: + resolution: {integrity: sha512-VswyOg5CVN3rMaOJ2HtnkltiMKgFHW/wouWxXsV8RxSa4tgWOKxM0EmSXi8qc2jX+LRga6B0uOY6toXS01zWxA==} + cpu: [arm64] + os: [freebsd] + + lefthook-freebsd-x64@2.1.6: + resolution: {integrity: sha512-vXsCUFYuVwrVWwcypB7Zt2Hf+5pl1V1la7ZfvGYZaTRURu0zF/XUnMF/nOz/PebGv0f4x/iOWXWwP7E42xRWsg==} + cpu: [x64] + os: [freebsd] + + lefthook-linux-arm64@2.1.6: + resolution: {integrity: sha512-WDJiQhJdZOvKORZd+kF/ms2l6NSsXzdA9ahflyr65V90AC4jES223W8VtEMbGPUtHuGWMEZ/v/XvwlWv0Ioz9g==} + cpu: [arm64] + os: [linux] + + lefthook-linux-x64@2.1.6: + resolution: {integrity: sha512-C18nCd7nTX1AVL4TcvwMmLAO1VI1OuGluIOTjiPkBQ746Ls1HhL5rl//jMPACmT28YmxIQJ2ZcLPNmhvEVBZvw==} + cpu: [x64] + os: [linux] + + lefthook-openbsd-arm64@2.1.6: + resolution: {integrity: sha512-mZOMxM8HiPxVFXDO3PtCUbH4GB8rkveXhsgXF27oAZTYVzQ3gO9vT6r/pxit6msqRXz3fvcwimLVJgb8eRsa8A==} + cpu: [arm64] + os: [openbsd] + + lefthook-openbsd-x64@2.1.6: + resolution: {integrity: sha512-sG9ALLZSnnMOfXu+B7SmxFhJhuoAh4bqi5En5aaHJET48TqrLOcWWZuH+7ArFM6gr/U5KfSUvdmHFmY8WqCcIg==} + cpu: [x64] + os: [openbsd] + + lefthook-windows-arm64@2.1.6: + resolution: {integrity: sha512-lD8yFWY4Csuljd0Rqs7EQaySC0VvDf7V3rN1FhRMUISTRDHutebIom1Loc8ckQPvKYGC6mftT9k0GvipsS+Brw==} + cpu: [arm64] + os: [win32] + + lefthook-windows-x64@2.1.6: + resolution: {integrity: sha512-q4z2n3xucLscoWiyMwFViEj3N8MDSkPulMwcJYuCYFHoPhP1h+icqNu7QRLGYj6AnVrCQweiUJY3Tb2X+GbD/A==} + cpu: [x64] + os: [win32] + + lefthook@2.1.6: + resolution: {integrity: sha512-w9sBoR0mdN+kJc3SB85VzpiAAl451/rxdCRcZlwW71QLjkeH3EBQFgc4VMj5apePychYDHAlqEWTB8J8JK/j1Q==} + hasBin: true + levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -7764,6 +8088,10 @@ packages: resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + loader-utils@1.4.2: + resolution: {integrity: sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==} + engines: {node: '>=4.0.0'} + local-pkg@1.1.1: resolution: {integrity: sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==} engines: {node: '>=14'} @@ -8043,6 +8371,10 @@ packages: merge-descriptors@1.0.3: resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + merge-options@1.0.1: + resolution: {integrity: sha512-iuPV41VWKWBIOpBsjoxjDZw8/GbSfZ2mk7N1453bwMrfzdrIk7EzBd+8UVR6rkw67th7xnk9Dytl3J+lHPdxvg==} + engines: {node: '>=4'} + merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -8162,6 +8494,10 @@ packages: micromark@4.0.2: resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + micromatch@3.1.0: + resolution: {integrity: sha512-3StSelAE+hnRvMs8IdVW7Uhk8CVed5tp+kLLGlBP6WiRAXS21GPGu/Nat4WNPXj2Eoc24B02SaeoyozPMfj0/g==} + engines: {node: '>=0.10.0'} + micromatch@3.1.10: resolution: {integrity: sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==} engines: {node: '>=0.10.0'} @@ -8243,6 +8579,9 @@ packages: minisearch@7.2.0: resolution: {integrity: sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==} + mitt@1.1.2: + resolution: {integrity: sha512-3btxP0O9iGADGWAkteQ8mzDtEspZqu4I32y4GZYCV5BrwtzdcRpF4dQgNdJadCrbBx7Lu6Sq9AVrerMHR0Hkmw==} + mitt@3.0.1: resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} @@ -8372,9 +8711,6 @@ packages: encoding: optional: true - node-mock-http@1.0.3: - resolution: {integrity: sha512-jN8dK25fsfnMrVsEhluUTPkBFY+6ybu7jSB1n+ri/vOGjJxU8J9CZhpSGkHXSkFjtUhbmoncG/YG9ta5Ludqog==} - node-mock-http@1.0.4: resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==} @@ -8552,6 +8888,10 @@ packages: resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} engines: {node: '>= 0.4'} + oxc-parser@0.127.0: + resolution: {integrity: sha512-bkgD4qHlN7WxLdX8bLXdaU54TtQtAIg/ZBAfm0aje/mo3MRDo3P0hZSgr4U7O3xfX+fQmR5AP04JS/TGcZLcFA==} + engines: {node: ^20.19.0 || >=22.12.0} + oxc-resolver@11.17.1: resolution: {integrity: sha512-pyRXK9kH81zKlirHufkFhOFBZRks8iAMLwPH8gU7lvKFiuzUH9L8MxDEllazwOb8fjXMcWjY1PMDfMJ2/yh5cw==} @@ -8638,9 +8978,6 @@ packages: package-manager-detector@0.2.11: resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==} - package-manager-detector@1.5.0: - resolution: {integrity: sha512-uBj69dVlYe/+wxj8JOpr97XfsxH/eumMt6HqjNTmJDf/6NO9s+0uxeOneIz3AsPt2m6y9PqzDzd3ATcU17MNfw==} - package-manager-detector@1.6.0: resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} @@ -8676,6 +9013,12 @@ packages: resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} engines: {node: '>=18'} + parse5-htmlparser2-tree-adapter@7.1.0: + resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==} + + parse5-parser-stream@7.1.2: + resolution: {integrity: sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==} + parse5@7.3.0: resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} @@ -8840,10 +9183,19 @@ packages: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} + postcss-prefix-selector@1.16.1: + resolution: {integrity: sha512-Umxu+FvKMwlY6TyDzGFoSUnzW+NOfMBLyC1tAkIjgX+Z/qGspJeRjVC903D7mx7TuBpJlwti2ibXtWuA7fKMeQ==} + peerDependencies: + postcss: '>4 <9' + postcss-selector-parser@7.1.0: resolution: {integrity: sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==} engines: {node: '>=4'} + postcss@5.2.18: + resolution: {integrity: sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==} + engines: {node: '>=0.12'} + postcss@8.5.6: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} @@ -8852,6 +9204,23 @@ packages: resolution: {integrity: sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==} engines: {node: ^10 || ^12 || >=14} + posthtml-parser@0.2.1: + resolution: {integrity: sha512-nPC53YMqJnc/+1x4fRYFfm81KV2V+G9NZY+hTohpYg64Ay7NemWWcV4UWuy/SgMupqQ3kJ88M/iRfZmSnxT+pw==} + + posthtml-rename-id@1.0.12: + resolution: {integrity: sha512-UKXf9OF/no8WZo9edRzvuMenb6AD5hDLzIepJW+a4oJT+T/Lx7vfMYWT4aWlGNQh0WMhnUx1ipN9OkZ9q+ddEw==} + + posthtml-render@1.4.0: + resolution: {integrity: sha512-W1779iVHGfq0Fvh2PROhCe2QhB8mEErgqzo1wpIt36tCgChafP+hbXIhLDOM8ePJrZcFs0vkNEtdibEWVqChqw==} + engines: {node: '>=10'} + + posthtml-svg-mode@1.0.3: + resolution: {integrity: sha512-hEqw9NHZ9YgJ2/0G7CECOeuLQKZi8HjWLkBaSVtOWjygQ9ZD8P7tqeowYs7WrFdKsWEKG7o+IlsPY8jrr0CJpQ==} + + posthtml@0.9.2: + resolution: {integrity: sha512-spBB5sgC4cv2YcW03f/IAUN1pgDJWNWD8FzkyY4mArLUMJW+KlQhlmUdKAHQuPfb00Jl5xIfImeOsf6YL8QK7Q==} + engines: {node: '>=0.10.0'} + powershell-utils@0.1.0: resolution: {integrity: sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==} engines: {node: '>=20'} @@ -9060,6 +9429,10 @@ packages: resolution: {integrity: sha512-M9RxRITi2mHMVPU5zysNjctUT8bAPx6ltEXo/ir9+qmiM47Y7f0Ir3+OxUO5OjYAWdicBQRew7RtHtqUXydqlg==} engines: {node: '>=20'} + query-string@4.3.4: + resolution: {integrity: sha512-O2XLNDBIg1DnTOa+2XrIwSiXEV8h2KImXUnjhhn2+UsvZ+Es2uyd5CCRTNQlDGbzUQOW3aYCBx9rVA6dzsiY7Q==} + engines: {node: '>=0.10.0'} + query-string@9.2.0: resolution: {integrity: sha512-YIRhrHujoQxhexwRLxfy3VSjOXmvZRd2nyw1PwL1UUqZ/ys1dEZd1+NSgXkne2l/4X/7OXkigEAuhTX0g/ivJQ==} engines: {node: '>=18'} @@ -9568,9 +9941,6 @@ packages: shiki@2.5.0: resolution: {integrity: sha512-mI//trrsaiCIPsja5CNfsyNOqgAZUb6VpJA+340toL42UpzQlXpwRV9nch69X6gaUxrr9kaOOa6e3y3uAkGFxQ==} - shiki@3.19.0: - resolution: {integrity: sha512-77VJr3OR/VUZzPiStyRhADmO2jApMM0V2b1qf0RpfWya8Zr1PeZev5AEpPGAAKWdiYUtcZGBE4F5QvJml1PvWA==} - shiki@3.22.0: resolution: {integrity: sha512-LBnhsoYEe0Eou4e1VgJACes+O6S6QC0w71fCSp5Oya79inkwkm15gQ1UF6VtQ8j/taMDh79hAB49WUk8ALQW3g==} @@ -9758,6 +10128,10 @@ packages: stream-replace-string@2.0.0: resolution: {integrity: sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==} + strict-uri-encode@1.1.0: + resolution: {integrity: sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==} + engines: {node: '>=0.10.0'} + string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} @@ -9900,6 +10274,10 @@ packages: resolution: {integrity: sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==} engines: {node: '>=0.8.0'} + supports-color@3.2.3: + resolution: {integrity: sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==} + engines: {node: '>=0.8.0'} + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -9932,6 +10310,16 @@ packages: resolution: {integrity: sha512-AqApqNOxVS97V4Ko9UHTHeSuDJrwauJhZpLDs1gYD8Jk48ntCSWD7NxKje+fnGn5Ja1O3u2FzQZHPdifQjXe3w==} engines: {node: '>=18'} + svg-baker-runtime@1.4.7: + resolution: {integrity: sha512-Zorfwwj5+lWjk/oxwSMsRdS2sPQQdTmmsvaSpzU+i9ZWi3zugHLt6VckWfnswphQP0LmOel3nggpF5nETbt6xw==} + + svg-baker@1.7.0: + resolution: {integrity: sha512-nibslMbkXOIkqKVrfcncwha45f97fGuAOn1G99YwnwTj8kF9YiM6XexPcUso97NxOm6GsP0SIvYVIosBis1xLg==} + + svg-sprite-loader@6.0.11: + resolution: {integrity: sha512-TedsTf8wsHH6HgdwKjUveDZRC6q5gPloYV8A8/zZaRWP929J7x6TzQ6MvZFl+YYDJuJ0Akyuu/vNVJ+fbPuYXg==} + engines: {node: '>=6'} + svgo@4.0.0: resolution: {integrity: sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw==} engines: {node: '>=16'} @@ -9971,6 +10359,9 @@ packages: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} engines: {node: '>=8'} + terminal-columns@2.0.0: + resolution: {integrity: sha512-6IByuUjyNZJXUtwDNm+OIe62zgwwaRbH+WMNTcx05O2G5V9WhvluAAHJY8OvUdwmzMPpqAD/7EUpGdI6ae1aiQ==} + terser@5.42.0: resolution: {integrity: sha512-UYCvU9YQW2f/Vwl+P0GfhxJxbUGLwd+5QrrGgLajzWAtC/23AX0vcise32kkP7Eu0Wu9VlzzHAXkLObgjQfFlQ==} engines: {node: '>=10'} @@ -10094,6 +10485,10 @@ packages: resolution: {integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==} engines: {node: '>=20'} + traverse@0.6.11: + resolution: {integrity: sha512-vxXDZg8/+p3gblxB6BhhG5yWVn1kGRlaL8O78UDXc3wRnPizB5g83dcvWV1jpDMIPnjZjOFuxlMmE82XJ4407w==} + engines: {node: '>= 0.4'} + tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true @@ -10193,6 +10588,9 @@ packages: resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} + type-flag@4.2.0: + resolution: {integrity: sha512-6h6QpSh5glA+BrMCq8FINo4o/BqSHNQdfIPpeSBt0s/6mynPaQWWZL+RHaYm95htTbid/spUbJer1yOCsA6ezQ==} + type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} @@ -10213,6 +10611,10 @@ packages: resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} + typedarray.prototype.slice@1.0.5: + resolution: {integrity: sha512-q7QNVDGTdl702bVFiI5eY4l/HkgCM6at9KhcFbgUAzezHFbOVy4+0O/lCjsABEQwbZPravVfBIiBVGo89yzHFg==} + engines: {node: '>= 0.4'} + typedoc-plugin-markdown@4.11.0: resolution: {integrity: sha512-2iunh2ALyfyh204OF7h2u0kuQ84xB3jFZtFyUr01nThJkLvR8oGGSSDlyt2gyO4kXhvUxDcVbO0y43+qX+wFbw==} engines: {node: '>= 18'} @@ -10323,6 +10725,10 @@ packages: resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} engines: {node: '>=18'} + unidecode@0.1.8: + resolution: {integrity: sha512-SdoZNxCWpN2tXTCrGkPF/0rL2HEq+i2gwRG1ReBvx8/0yTzC3enHfugOf8A9JBShVwwrRIkLX0YcDUGbzjbVCA==} + engines: {node: '>= 0.4.12'} + unified@11.0.5: resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} @@ -10407,8 +10813,8 @@ packages: resolution: {integrity: sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==} engines: {node: '>=0.10.0'} - unstorage@1.17.3: - resolution: {integrity: sha512-i+JYyy0DoKmQ3FximTHbGadmIYb8JEpq7lxUjnjeB702bCPum0vzo6oy5Mfu0lpqISw7hCyMW2yj4nWC8bqJ3Q==} + unstorage@1.17.4: + resolution: {integrity: sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw==} peerDependencies: '@azure/app-configuration': ^1.8.0 '@azure/cosmos': ^4.2.0 @@ -10416,76 +10822,14 @@ packages: '@azure/identity': ^4.6.0 '@azure/keyvault-secrets': ^4.9.0 '@azure/storage-blob': ^12.26.0 - '@capacitor/preferences': ^6.0.3 || ^7.0.0 + '@capacitor/preferences': ^6 || ^7 || ^8 '@deno/kv': '>=0.9.0' '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 '@planetscale/database': ^1.19.0 '@upstash/redis': ^1.34.3 '@vercel/blob': '>=0.27.1' '@vercel/functions': ^2.2.12 || ^3.0.0 - '@vercel/kv': ^1.0.1 - aws4fetch: ^1.0.20 - db0: '>=0.2.1' - idb-keyval: ^6.2.1 - ioredis: ^5.4.2 - uploadthing: ^7.4.4 - peerDependenciesMeta: - '@azure/app-configuration': - optional: true - '@azure/cosmos': - optional: true - '@azure/data-tables': - optional: true - '@azure/identity': - optional: true - '@azure/keyvault-secrets': - optional: true - '@azure/storage-blob': - optional: true - '@capacitor/preferences': - optional: true - '@deno/kv': - optional: true - '@netlify/blobs': - optional: true - '@planetscale/database': - optional: true - '@upstash/redis': - optional: true - '@vercel/blob': - optional: true - '@vercel/functions': - optional: true - '@vercel/kv': - optional: true - aws4fetch: - optional: true - db0: - optional: true - idb-keyval: - optional: true - ioredis: - optional: true - uploadthing: - optional: true - - unstorage@1.17.4: - resolution: {integrity: sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw==} - peerDependencies: - '@azure/app-configuration': ^1.8.0 - '@azure/cosmos': ^4.2.0 - '@azure/data-tables': ^13.3.0 - '@azure/identity': ^4.6.0 - '@azure/keyvault-secrets': ^4.9.0 - '@azure/storage-blob': ^12.26.0 - '@capacitor/preferences': ^6 || ^7 || ^8 - '@deno/kv': '>=0.9.0' - '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 - '@planetscale/database': ^1.19.0 - '@upstash/redis': ^1.34.3 - '@vercel/blob': '>=0.27.1' - '@vercel/functions': ^2.2.12 || ^3.0.0 - '@vercel/kv': ^1 || ^2 || ^3 + '@vercel/kv': ^1 || ^2 || ^3 aws4fetch: ^1.0.20 db0: '>=0.2.1' idb-keyval: ^6.2.1 @@ -10560,6 +10904,9 @@ packages: resolution: {integrity: sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA==} engines: {node: '>=0.10.0'} + url-slug@2.0.0: + resolution: {integrity: sha512-aiNmSsVgrjCiJ2+KWPferjT46YFKoE8i0YX04BlMVDue022Xwhg/zYlnZ6V9/mP3p8Wj7LEp0myiTkC/p6sxew==} + use-sync-external-store@1.6.0: resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} peerDependencies: @@ -10972,6 +11319,11 @@ packages: webpack-virtual-modules@0.6.2: resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + whatwg-encoding@3.1.1: + resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} + engines: {node: '>=18'} + deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation + whatwg-mimetype@3.0.0: resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} engines: {node: '>=12'} @@ -11235,11 +11587,6 @@ packages: resolution: {integrity: sha512-RvEsa3W/NCqEBMtnoE09GRVelA3IqRcKaijEiM6CEGsD19qLurf0HjrYMHwOqImOszlLL0ja63DPJeeU4pm7oQ==} engines: {node: '>=20'} - zod-to-json-schema@3.25.0: - resolution: {integrity: sha512-HvWtU2UG41LALjajJrML6uQejQhNJx+JBO9IflpSja4R03iNWfKXrj6W2h7ljuLyc1nKS+9yDyL/9tD1U/yBnQ==} - peerDependencies: - zod: ^3.25 || ^4 - zod-to-json-schema@3.25.1: resolution: {integrity: sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==} peerDependencies: @@ -11589,8 +11936,8 @@ snapshots: remark-parse: 11.0.0 remark-rehype: 11.1.2 remark-smartypants: 3.0.2 - shiki: 3.19.0 - smol-toml: 1.5.2 + shiki: 3.22.0 + smol-toml: 1.6.0 unified: 11.0.5 unist-util-remove-position: 5.0.0 unist-util-visit: 5.1.0 @@ -11615,7 +11962,7 @@ snapshots: remark-parse: 11.0.0 remark-rehype: 11.1.2 remark-smartypants: 3.0.2 - shiki: 3.19.0 + shiki: 3.22.0 smol-toml: 1.5.2 unified: 11.0.5 unist-util-remove-position: 5.0.0 @@ -11758,7 +12105,7 @@ snapshots: '@babel/helper-member-expression-to-functions@7.28.5': dependencies: '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color @@ -11780,7 +12127,7 @@ snapshots: '@babel/helper-optimise-call-expression@7.27.1': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 '@babel/helper-plugin-utils@7.27.1': {} @@ -12326,16 +12673,32 @@ snapshots: tslib: 2.8.1 optional: true + '@emnapi/core@1.9.2': + dependencies: + '@emnapi/wasi-threads': 1.2.1 + tslib: 2.8.1 + optional: true + '@emnapi/runtime@1.7.1': dependencies: tslib: 2.8.1 optional: true + '@emnapi/runtime@1.9.2': + dependencies: + tslib: 2.8.1 + optional: true + '@emnapi/wasi-threads@1.1.0': dependencies: tslib: 2.8.1 optional: true + '@emnapi/wasi-threads@1.2.1': + dependencies: + tslib: 2.8.1 + optional: true + '@esbuild/aix-ppc64@0.21.5': optional: true @@ -13259,6 +13622,13 @@ snapshots: '@tybys/wasm-util': 0.10.1 optional: true + '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)': + dependencies: + '@emnapi/core': 1.9.2 + '@emnapi/runtime': 1.9.2 + '@tybys/wasm-util': 0.10.1 + optional: true + '@neoconfetti/react@1.0.0': {} '@noble/ciphers@1.3.0': {} @@ -13357,6 +13727,72 @@ snapshots: '@oslojs/encoding@1.1.0': {} + '@oxc-parser/binding-android-arm-eabi@0.127.0': + optional: true + + '@oxc-parser/binding-android-arm64@0.127.0': + optional: true + + '@oxc-parser/binding-darwin-arm64@0.127.0': + optional: true + + '@oxc-parser/binding-darwin-x64@0.127.0': + optional: true + + '@oxc-parser/binding-freebsd-x64@0.127.0': + optional: true + + '@oxc-parser/binding-linux-arm-gnueabihf@0.127.0': + optional: true + + '@oxc-parser/binding-linux-arm-musleabihf@0.127.0': + optional: true + + '@oxc-parser/binding-linux-arm64-gnu@0.127.0': + optional: true + + '@oxc-parser/binding-linux-arm64-musl@0.127.0': + optional: true + + '@oxc-parser/binding-linux-ppc64-gnu@0.127.0': + optional: true + + '@oxc-parser/binding-linux-riscv64-gnu@0.127.0': + optional: true + + '@oxc-parser/binding-linux-riscv64-musl@0.127.0': + optional: true + + '@oxc-parser/binding-linux-s390x-gnu@0.127.0': + optional: true + + '@oxc-parser/binding-linux-x64-gnu@0.127.0': + optional: true + + '@oxc-parser/binding-linux-x64-musl@0.127.0': + optional: true + + '@oxc-parser/binding-openharmony-arm64@0.127.0': + optional: true + + '@oxc-parser/binding-wasm32-wasi@0.127.0': + dependencies: + '@emnapi/core': 1.9.2 + '@emnapi/runtime': 1.9.2 + '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + optional: true + + '@oxc-parser/binding-win32-arm64-msvc@0.127.0': + optional: true + + '@oxc-parser/binding-win32-ia32-msvc@0.127.0': + optional: true + + '@oxc-parser/binding-win32-x64-msvc@0.127.0': + optional: true + + '@oxc-project/types@0.127.0': {} + '@oxc-project/types@0.95.0': {} '@oxc-resolver/binding-android-arm-eabi@11.17.1': @@ -13729,13 +14165,6 @@ snapshots: '@types/hast': 3.0.4 hast-util-to-html: 9.0.5 - '@shikijs/core@3.19.0': - dependencies: - '@shikijs/types': 3.19.0 - '@shikijs/vscode-textmate': 10.0.2 - '@types/hast': 3.0.4 - hast-util-to-html: 9.0.5 - '@shikijs/core@3.22.0': dependencies: '@shikijs/types': 3.22.0 @@ -13749,12 +14178,6 @@ snapshots: '@shikijs/vscode-textmate': 10.0.2 oniguruma-to-es: 3.1.1 - '@shikijs/engine-javascript@3.19.0': - dependencies: - '@shikijs/types': 3.19.0 - '@shikijs/vscode-textmate': 10.0.2 - oniguruma-to-es: 4.3.4 - '@shikijs/engine-javascript@3.22.0': dependencies: '@shikijs/types': 3.22.0 @@ -13766,11 +14189,6 @@ snapshots: '@shikijs/types': 2.5.0 '@shikijs/vscode-textmate': 10.0.2 - '@shikijs/engine-oniguruma@3.19.0': - dependencies: - '@shikijs/types': 3.19.0 - '@shikijs/vscode-textmate': 10.0.2 - '@shikijs/engine-oniguruma@3.22.0': dependencies: '@shikijs/types': 3.22.0 @@ -13785,10 +14203,6 @@ snapshots: dependencies: '@shikijs/types': 2.5.0 - '@shikijs/langs@3.19.0': - dependencies: - '@shikijs/types': 3.19.0 - '@shikijs/langs@3.22.0': dependencies: '@shikijs/types': 3.22.0 @@ -13801,10 +14215,6 @@ snapshots: dependencies: '@shikijs/types': 2.5.0 - '@shikijs/themes@3.19.0': - dependencies: - '@shikijs/types': 3.19.0 - '@shikijs/themes@3.22.0': dependencies: '@shikijs/types': 3.22.0 @@ -13823,11 +14233,6 @@ snapshots: '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 - '@shikijs/types@3.19.0': - dependencies: - '@shikijs/vscode-textmate': 10.0.2 - '@types/hast': 3.0.4 - '@shikijs/types@3.22.0': dependencies: '@shikijs/vscode-textmate': 10.0.2 @@ -14375,6 +14780,8 @@ snapshots: dependencies: '@types/unist': 3.0.3 + '@types/he@1.2.3': {} + '@types/html-minifier-terser@7.0.2': {} '@types/http-cache-semantics@4.0.4': {} @@ -15273,7 +15680,7 @@ snapshots: ast-kit@2.1.3: dependencies: - '@babel/parser': 7.28.5 + '@babel/parser': 7.29.2 pathe: 2.0.3 ast-types-flow@0.0.8: {} @@ -15418,7 +15825,7 @@ snapshots: '@capsizecss/unpack': 2.4.0 '@oslojs/encoding': 1.1.0 '@rollup/pluginutils': 5.3.0(rollup@4.52.5) - acorn: 8.15.0 + acorn: 8.16.0 aria-query: 5.3.2 axobject-query: 4.1.0 boxen: 8.0.1 @@ -15429,7 +15836,7 @@ snapshots: cssesc: 3.0.0 debug: 4.4.3 deterministic-object-hash: 2.0.2 - devalue: 5.5.0 + devalue: 5.6.2 diff: 5.2.0 dlv: 1.1.3 dset: 3.1.4 @@ -15450,19 +15857,19 @@ snapshots: neotraverse: 0.6.18 p-limit: 6.2.0 p-queue: 8.1.1 - package-manager-detector: 1.5.0 + package-manager-detector: 1.6.0 picomatch: 4.0.3 prompts: 2.4.2 rehype: 13.0.2 - semver: 7.7.3 - shiki: 3.19.0 + semver: 7.7.4 + shiki: 3.22.0 tinyexec: 0.3.2 tinyglobby: 0.2.15 tsconfck: 3.1.6(typescript@5.9.3) ultrahtml: 1.6.0 unifont: 0.5.0 - unist-util-visit: 5.0.0 - unstorage: 1.17.3 + unist-util-visit: 5.1.0 + unstorage: 1.17.4 vfile: 6.0.3 vite: 6.4.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.42.0)(tsx@4.21.0)(yaml@2.8.2) vitefu: 1.1.1(vite@6.4.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.42.0)(tsx@4.21.0)(yaml@2.8.2)) @@ -15470,7 +15877,7 @@ snapshots: yargs-parser: 21.1.1 yocto-spinner: 0.2.3 zod: 3.25.76 - zod-to-json-schema: 3.25.0(zod@3.25.76) + zod-to-json-schema: 3.25.1(zod@3.25.76) zod-to-ts: 1.2.0(typescript@5.9.3)(zod@3.25.76) optionalDependencies: sharp: 0.33.5 @@ -15588,6 +15995,8 @@ snapshots: big-integer@1.6.52: {} + big.js@5.2.2: {} + binary-searching@2.0.5: {} birpc@2.6.1: {} @@ -15605,6 +16014,8 @@ snapshots: blob-to-buffer@1.2.9: {} + bluebird@3.7.2: {} + body-parser@1.20.3: dependencies: bytes: 3.1.2 @@ -15816,6 +16227,29 @@ snapshots: check-error@2.1.1: {} + cheerio-select@2.1.0: + dependencies: + boolbase: 1.0.0 + css-select: 5.2.2 + css-what: 6.2.2 + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + + cheerio@1.2.0: + dependencies: + cheerio-select: 2.1.0 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + domutils: 3.2.2 + encoding-sniffer: 0.2.1 + htmlparser2: 10.1.0 + parse5: 7.3.0 + parse5-htmlparser2-tree-adapter: 7.1.0 + parse5-parser-stream: 7.1.2 + undici: 7.22.0 + whatwg-mimetype: 4.0.0 + chokidar@4.0.3: dependencies: readdirp: 4.1.2 @@ -15848,6 +16282,11 @@ snapshots: dependencies: escape-string-regexp: 5.0.0 + cleye@2.6.0: + dependencies: + terminal-columns: 2.0.0 + type-flag: 4.2.0 + cli-boxes@3.0.0: {} cli-cursor@3.1.0: @@ -16193,12 +16632,16 @@ snapshots: dedent@1.7.1: {} + dedent@1.7.2: {} + deep-eql@5.0.2: {} deep-extend@0.6.0: {} deep-is@0.1.4: {} + deepmerge@1.3.2: {} + deepmerge@4.3.1: {} default-browser-id@5.0.0: {} @@ -16279,8 +16722,6 @@ snapshots: dependencies: base-64: 1.0.0 - devalue@5.5.0: {} - devalue@5.6.2: {} devlop@1.1.0: @@ -16303,18 +16744,36 @@ snapshots: dom-accessibility-api@0.6.3: {} + dom-serializer@0.2.2: + dependencies: + domelementtype: 2.3.0 + entities: 2.2.0 + dom-serializer@2.0.0: dependencies: domelementtype: 2.3.0 domhandler: 5.0.3 entities: 4.5.0 + domelementtype@1.3.1: {} + domelementtype@2.3.0: {} + domhandler@2.4.2: + dependencies: + domelementtype: 1.3.1 + domhandler@5.0.3: dependencies: domelementtype: 2.3.0 + domready@1.0.8: {} + + domutils@1.7.0: + dependencies: + dom-serializer: 0.2.2 + domelementtype: 1.3.1 + domutils@3.2.2: dependencies: dom-serializer: 2.0.0 @@ -16382,12 +16841,19 @@ snapshots: emoji-regex@9.2.2: {} + emojis-list@3.0.0: {} + empathic@2.0.0: {} encodeurl@1.0.2: {} encodeurl@2.0.0: {} + encoding-sniffer@0.2.1: + dependencies: + iconv-lite: 0.6.3 + whatwg-encoding: 3.1.1 + enhanced-resolve@5.20.0: dependencies: graceful-fs: 4.2.11 @@ -16405,6 +16871,10 @@ snapshots: punycode: 1.4.1 safe-regex-test: 1.1.0 + entities@1.1.2: {} + + entities@2.2.0: {} + entities@4.5.0: {} entities@6.0.1: {} @@ -17435,18 +17905,6 @@ snapshots: lodash.template: 4.5.0 through2: 2.0.5 - h3@1.15.4: - dependencies: - cookie-es: 1.2.2 - crossws: 0.3.5 - defu: 6.1.4 - destr: 2.0.5 - iron-webcrypto: 1.2.1 - node-mock-http: 1.0.3 - radix3: 1.1.2 - ufo: 1.6.1 - uncrypto: 0.1.3 - h3@1.15.5: dependencies: cookie-es: 1.2.2 @@ -17529,6 +17987,8 @@ snapshots: has-bigints@1.1.0: {} + has-flag@1.0.0: {} + has-flag@4.0.0: {} has-property-descriptors@1.0.2: @@ -17696,8 +18156,7 @@ snapshots: property-information: 7.1.0 space-separated-tokens: 2.0.2 - he@1.2.0: - optional: true + he@1.2.0: {} helper-date@1.0.1: dependencies: @@ -17767,6 +18226,22 @@ snapshots: html-void-elements@3.0.0: {} + htmlparser2@10.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + entities: 7.0.1 + + htmlparser2@3.10.1: + dependencies: + domelementtype: 1.3.1 + domhandler: 2.4.2 + domutils: 1.7.0 + entities: 1.1.2 + inherits: 2.0.4 + readable-stream: 3.6.2 + http-cache-semantics@4.2.0: {} http-errors@2.0.0: @@ -17802,12 +18277,14 @@ snapshots: human-signals@8.0.1: {} - husky@9.1.7: {} - iconv-lite@0.4.24: dependencies: safer-buffer: 2.1.2 + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + iconv-lite@0.7.0: dependencies: safer-buffer: 2.1.2 @@ -17818,6 +18295,8 @@ snapshots: ignore@7.0.5: {} + image-size@0.5.5: {} + import-fresh@3.3.1: dependencies: parent-module: 1.0.1 @@ -18041,6 +18520,8 @@ snapshots: dependencies: path-is-inside: 1.0.2 + is-plain-obj@1.1.0: {} + is-plain-obj@3.0.0: {} is-plain-obj@4.1.0: {} @@ -18177,6 +18658,8 @@ snapshots: jju@1.4.0: {} + js-base64@2.6.4: {} + js-tokens@10.0.0: {} js-tokens@4.0.0: {} @@ -18248,6 +18731,10 @@ snapshots: json-stable-stringify-without-jsonify@1.0.1: {} + json5@1.0.2: + dependencies: + minimist: 1.2.8 + json5@2.2.3: {} jsonc-eslint-parser@2.4.2: @@ -18324,6 +18811,8 @@ snapshots: kolorist@1.8.0: {} + ky@2.0.1: {} + language-subtag-registry@0.3.23: {} language-tags@1.0.9: @@ -18343,6 +18832,49 @@ snapshots: dependencies: set-getter: 0.1.1 + lefthook-darwin-arm64@2.1.6: + optional: true + + lefthook-darwin-x64@2.1.6: + optional: true + + lefthook-freebsd-arm64@2.1.6: + optional: true + + lefthook-freebsd-x64@2.1.6: + optional: true + + lefthook-linux-arm64@2.1.6: + optional: true + + lefthook-linux-x64@2.1.6: + optional: true + + lefthook-openbsd-arm64@2.1.6: + optional: true + + lefthook-openbsd-x64@2.1.6: + optional: true + + lefthook-windows-arm64@2.1.6: + optional: true + + lefthook-windows-x64@2.1.6: + optional: true + + lefthook@2.1.6: + optionalDependencies: + lefthook-darwin-arm64: 2.1.6 + lefthook-darwin-x64: 2.1.6 + lefthook-freebsd-arm64: 2.1.6 + lefthook-freebsd-x64: 2.1.6 + lefthook-linux-arm64: 2.1.6 + lefthook-linux-x64: 2.1.6 + lefthook-openbsd-arm64: 2.1.6 + lefthook-openbsd-x64: 2.1.6 + lefthook-windows-arm64: 2.1.6 + lefthook-windows-x64: 2.1.6 + levn@0.4.1: dependencies: prelude-ls: 1.2.1 @@ -18492,6 +19024,12 @@ snapshots: load-tsconfig@0.2.5: {} + loader-utils@1.4.2: + dependencies: + big.js: 5.2.2 + emojis-list: 3.0.0 + json5: 1.0.2 + local-pkg@1.1.1: dependencies: mlly: 1.8.2 @@ -18628,8 +19166,8 @@ snapshots: magicast@0.3.5: dependencies: - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 source-map-js: 1.2.1 magicast@0.5.1: @@ -18921,6 +19459,10 @@ snapshots: merge-descriptors@1.0.3: {} + merge-options@1.0.1: + dependencies: + is-plain-obj: 1.1.0 + merge-stream@2.0.0: {} merge2@1.4.1: {} @@ -19198,6 +19740,24 @@ snapshots: transitivePeerDependencies: - supports-color + micromatch@3.1.0: + dependencies: + arr-diff: 4.0.0 + array-unique: 0.3.2 + braces: 2.3.2 + define-property: 1.0.0 + extend-shallow: 2.0.1 + extglob: 2.0.4 + fragment-cache: 0.2.1 + kind-of: 5.1.0 + nanomatch: 1.2.13 + object.pick: 1.3.0 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + micromatch@3.1.10: dependencies: arr-diff: 4.0.0 @@ -19277,7 +19837,7 @@ snapshots: esbuild: 0.25.12 find-up: 7.0.0 html-minifier-terser: 7.2.0 - lightningcss: 1.30.2 + lightningcss: 1.31.1 montag: 1.2.1 readjson: 2.2.2 simport: 1.2.0 @@ -19304,6 +19864,8 @@ snapshots: minisearch@7.2.0: {} + mitt@1.1.2: {} + mitt@3.0.1: {} mixin-deep@1.3.2: @@ -19420,8 +19982,6 @@ snapshots: dependencies: whatwg-url: 5.0.0 - node-mock-http@1.0.3: {} - node-mock-http@1.0.4: {} node-modules-inspector@1.4.2: @@ -19701,6 +20261,31 @@ snapshots: object-keys: 1.1.1 safe-push-apply: 1.0.0 + oxc-parser@0.127.0: + dependencies: + '@oxc-project/types': 0.127.0 + optionalDependencies: + '@oxc-parser/binding-android-arm-eabi': 0.127.0 + '@oxc-parser/binding-android-arm64': 0.127.0 + '@oxc-parser/binding-darwin-arm64': 0.127.0 + '@oxc-parser/binding-darwin-x64': 0.127.0 + '@oxc-parser/binding-freebsd-x64': 0.127.0 + '@oxc-parser/binding-linux-arm-gnueabihf': 0.127.0 + '@oxc-parser/binding-linux-arm-musleabihf': 0.127.0 + '@oxc-parser/binding-linux-arm64-gnu': 0.127.0 + '@oxc-parser/binding-linux-arm64-musl': 0.127.0 + '@oxc-parser/binding-linux-ppc64-gnu': 0.127.0 + '@oxc-parser/binding-linux-riscv64-gnu': 0.127.0 + '@oxc-parser/binding-linux-riscv64-musl': 0.127.0 + '@oxc-parser/binding-linux-s390x-gnu': 0.127.0 + '@oxc-parser/binding-linux-x64-gnu': 0.127.0 + '@oxc-parser/binding-linux-x64-musl': 0.127.0 + '@oxc-parser/binding-openharmony-arm64': 0.127.0 + '@oxc-parser/binding-wasm32-wasi': 0.127.0 + '@oxc-parser/binding-win32-arm64-msvc': 0.127.0 + '@oxc-parser/binding-win32-ia32-msvc': 0.127.0 + '@oxc-parser/binding-win32-x64-msvc': 0.127.0 + oxc-resolver@11.17.1: optionalDependencies: '@oxc-resolver/binding-android-arm-eabi': 11.17.1 @@ -19798,8 +20383,6 @@ snapshots: dependencies: quansync: 0.2.10 - package-manager-detector@1.5.0: {} - package-manager-detector@1.6.0: {} pako@0.2.9: {} @@ -19851,6 +20434,15 @@ snapshots: parse-ms@4.0.0: {} + parse5-htmlparser2-tree-adapter@7.1.0: + dependencies: + domhandler: 5.0.3 + parse5: 7.3.0 + + parse5-parser-stream@7.1.2: + dependencies: + parse5: 7.3.0 + parse5@7.3.0: dependencies: entities: 6.0.1 @@ -19988,11 +20580,22 @@ snapshots: possible-typed-array-names@1.1.0: {} + postcss-prefix-selector@1.16.1(postcss@5.2.18): + dependencies: + postcss: 5.2.18 + postcss-selector-parser@7.1.0: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 + postcss@5.2.18: + dependencies: + chalk: 1.1.3 + js-base64: 2.6.4 + source-map: 0.5.7 + supports-color: 3.2.3 + postcss@8.5.6: dependencies: nanoid: 3.3.11 @@ -20005,6 +20608,29 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + posthtml-parser@0.2.1: + dependencies: + htmlparser2: 3.10.1 + isobject: 2.1.0 + + posthtml-rename-id@1.0.12: + dependencies: + escape-string-regexp: 1.0.5 + + posthtml-render@1.4.0: {} + + posthtml-svg-mode@1.0.3: + dependencies: + merge-options: 1.0.1 + posthtml: 0.9.2 + posthtml-parser: 0.2.1 + posthtml-render: 1.4.0 + + posthtml@0.9.2: + dependencies: + posthtml-parser: 0.2.1 + posthtml-render: 1.4.0 + powershell-utils@0.1.0: {} preact@10.29.1: {} @@ -20147,6 +20773,11 @@ snapshots: zod: 3.25.76 zod-package-json: 1.1.0 + query-string@4.3.4: + dependencies: + object-assign: 4.1.1 + strict-uri-encode: 1.1.0 + query-string@9.2.0: dependencies: decode-uri-component: 0.4.1 @@ -20583,8 +21214,8 @@ snapshots: rolldown-plugin-dts@0.17.3(oxc-resolver@11.17.1)(rolldown@1.0.0-beta.45)(typescript@5.9.3)(vue-tsc@2.2.12(typescript@5.9.3)): dependencies: '@babel/generator': 7.28.5 - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 ast-kit: 2.1.3 birpc: 2.6.1 debug: 4.4.3 @@ -20879,17 +21510,6 @@ snapshots: '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 - shiki@3.19.0: - dependencies: - '@shikijs/core': 3.19.0 - '@shikijs/engine-javascript': 3.19.0 - '@shikijs/engine-oniguruma': 3.19.0 - '@shikijs/langs': 3.19.0 - '@shikijs/themes': 3.19.0 - '@shikijs/types': 3.19.0 - '@shikijs/vscode-textmate': 10.0.2 - '@types/hast': 3.0.4 - shiki@3.22.0: dependencies: '@shikijs/core': 3.22.0 @@ -21108,6 +21728,8 @@ snapshots: stream-replace-string@2.0.0: {} + strict-uri-encode@1.1.0: {} + string-argv@0.3.2: {} string-width@4.2.3: @@ -21250,6 +21872,10 @@ snapshots: supports-color@2.0.0: {} + supports-color@3.2.3: + dependencies: + has-flag: 1.0.0 + supports-color@7.2.0: dependencies: has-flag: 4.0.0 @@ -21300,6 +21926,45 @@ snapshots: magic-string: 0.30.21 zimmerframe: 1.1.4 + svg-baker-runtime@1.4.7: + dependencies: + deepmerge: 1.3.2 + mitt: 1.1.2 + svg-baker: 1.7.0 + transitivePeerDependencies: + - supports-color + + svg-baker@1.7.0: + dependencies: + bluebird: 3.7.2 + clone: 2.1.2 + he: 1.2.0 + image-size: 0.5.5 + loader-utils: 1.4.2 + merge-options: 1.0.1 + micromatch: 3.1.0 + postcss: 5.2.18 + postcss-prefix-selector: 1.16.1(postcss@5.2.18) + posthtml-rename-id: 1.0.12 + posthtml-svg-mode: 1.0.3 + query-string: 4.3.4 + traverse: 0.6.11 + transitivePeerDependencies: + - supports-color + + svg-sprite-loader@6.0.11: + dependencies: + bluebird: 3.7.2 + deepmerge: 1.3.2 + domready: 1.0.8 + escape-string-regexp: 1.0.5 + loader-utils: 1.4.2 + svg-baker: 1.7.0 + svg-baker-runtime: 1.4.7 + url-slug: 2.0.0 + transitivePeerDependencies: + - supports-color + svgo@4.0.0: dependencies: commander: 11.1.0 @@ -21348,10 +22013,12 @@ snapshots: term-size@2.2.1: {} + terminal-columns@2.0.0: {} + terser@5.42.0: dependencies: '@jridgewell/source-map': 0.3.6 - acorn: 8.15.0 + acorn: 8.16.0 commander: 2.20.3 source-map-support: 0.5.21 @@ -21453,6 +22120,12 @@ snapshots: dependencies: punycode: 2.3.1 + traverse@0.6.11: + dependencies: + gopd: 1.2.0 + typedarray.prototype.slice: 1.0.5 + which-typed-array: 1.1.19 + tree-kill@1.2.2: {} trim-lines@3.0.1: {} @@ -21532,6 +22205,8 @@ snapshots: type-fest@4.41.0: {} + type-flag@4.2.0: {} + type-is@1.6.18: dependencies: media-typer: 0.3.0 @@ -21570,6 +22245,17 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 + typedarray.prototype.slice@1.0.5: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + get-proto: 1.0.1 + math-intrinsics: 1.1.0 + typed-array-buffer: 1.0.3 + typed-array-byte-offset: 1.0.4 + typedoc-plugin-markdown@4.11.0(typedoc@0.28.18(typescript@5.9.3)): dependencies: typedoc: 0.28.18(typescript@5.9.3) @@ -21679,6 +22365,8 @@ snapshots: unicorn-magic@0.3.0: {} + unidecode@0.1.8: {} + unified@11.0.5: dependencies: '@types/unist': 3.0.3 @@ -21804,17 +22492,6 @@ snapshots: has-value: 0.3.1 isobject: 3.0.1 - unstorage@1.17.3: - dependencies: - anymatch: 3.1.3 - chokidar: 4.0.3 - destr: 2.0.5 - h3: 1.15.4 - lru-cache: 10.4.3 - node-fetch-native: 1.6.7 - ofetch: 1.5.1 - ufo: 1.6.1 - unstorage@1.17.4: dependencies: anymatch: 3.1.3 @@ -21848,6 +22525,10 @@ snapshots: dependencies: prepend-http: 1.0.4 + url-slug@2.0.0: + dependencies: + unidecode: 0.1.8 + use-sync-external-store@1.6.0(react@19.2.1): dependencies: react: 19.2.1 @@ -21965,7 +22646,7 @@ snapshots: esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 - postcss: 8.5.6 + postcss: 8.5.9 rollup: 4.52.5 tinyglobby: 0.2.15 optionalDependencies: @@ -21982,7 +22663,7 @@ snapshots: esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 - postcss: 8.5.6 + postcss: 8.5.9 rollup: 4.52.5 tinyglobby: 0.2.15 optionalDependencies: @@ -22283,6 +22964,10 @@ snapshots: webpack-virtual-modules@0.6.2: {} + whatwg-encoding@3.1.1: + dependencies: + iconv-lite: 0.6.3 + whatwg-mimetype@3.0.0: {} whatwg-mimetype@4.0.0: {} @@ -22551,10 +23236,6 @@ snapshots: dependencies: zod: 3.25.76 - zod-to-json-schema@3.25.0(zod@3.25.76): - dependencies: - zod: 3.25.76 - zod-to-json-schema@3.25.1(zod@3.25.76): dependencies: zod: 3.25.76 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 9dfd498d..80604fc3 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -4,23 +4,21 @@ packages: - examples/** - scripts -autoInstallPeers: true - -# Shared version expressions (yaml anchors). -# This is a yaml feature and is not interpreted by pnpm directly. __versions: - - &codecov 1.9.1 - - &commitlint 19.8.1 - - &eslint 9.39.4 - - &manypkg 3.1.0 - - &react 19.2.1 - - &react_router 7.10.1 - - &storybook 10.2.8 - - &tailwindcss 4.2.2 - - &turbo 2.8.20 - - &typescript_eslint 8.57.0 - - &vite 7.3.1 - - &vitest 4.0.18 + - 1.9.1 + - 19.8.1 + - 9.39.4 + - 3.1.0 + - 19.2.1 + - 7.10.1 + - 10.2.8 + - 4.2.2 + - 2.8.20 + - 8.57.0 + - 7.3.1 + - 4.0.18 + +autoInstallPeers: true catalog: '@catppuccin/palette': 1.7.1 @@ -28,13 +26,14 @@ catalog: '@dotenvx/dotenvx': 1.52.0 '@iconify/types': 2.0.0 '@iconify/utils': 2.3.0 - '@manypkg/find-root': *manypkg - '@manypkg/get-packages': *manypkg + '@manypkg/find-root': 3.1.0 + '@manypkg/get-packages': 3.1.0 '@tailwindcss/cli': 4.2.1 '@testing-library/jest-dom': 6.9.1 '@testing-library/react': 16.3.2 '@types/debug': 4.1.12 '@types/handlebars-helpers': 0.5.6 + '@types/he': ^1.2.3 '@types/mdast': 4.0.4 '@types/minify': 9.1.4 '@types/react': 19.2.14 @@ -42,18 +41,25 @@ catalog: '@types/yargs': 17.0.35 actions-up: 1.11.0 astro: 5.9.3 + cheerio: ^1.2.0 + dedent: ^1.7.2 deepmerge: 4.3.1 es-toolkit: 1.43.0 handlebars: 4.7.8 handlebars-helpers: 0.10.0 happy-dom: 20.6.1 + he: ^1.2.0 json-schema-to-typescript: 15.0.4 jsr: 0.13.5 + ky: ^2.0.1 + lefthook: ^2.1.6 mdast: 3.0.0 minify: 14.0.0 node-plop: 0.32.3 + oxc-parser: ^0.127.0 react: 19.2.0 remark: 15.0.1 + svg-sprite-loader: ^6.0.11 tailwind-scrollbar: 4.0.2 tailwindcss: 4.1.18 taze: 19.9.2 @@ -71,42 +77,43 @@ catalogMode: strict catalogs: cli: + cleye: ^2.6.0 cosmiconfig: 9.0.0 obug: 2.1.1 yargs: 18.0.0 commitlint: - '@commitlint/cli': *commitlint - '@commitlint/config-conventional': *commitlint - '@commitlint/types': *commitlint + '@commitlint/cli': 19.8.1 + '@commitlint/config-conventional': 19.8.1 + '@commitlint/types': 19.8.1 eslint: - '@typescript-eslint/parser': '^8.55.0' - '@eslint/js': '^9.39.2' - '@eslint/json': '^0.14.0' - 'eslint': '^9.39.2' - 'eslint-config-flat-gitignore': '^2.1.0' - 'eslint-config-prettier': '^10.1.8' - 'eslint-plugin-astro': '^1.6.0' - 'eslint-plugin-baseline-js': '^0.4.2' - 'eslint-plugin-jsx-a11y': '^6.10.2' - 'eslint-plugin-perfectionist': '^4.15.1' - 'eslint-plugin-pnpm': '^1.5.0' - 'eslint-plugin-react-hooks': '^7.0.1' - 'eslint-plugin-storybook': '^10.2.8' - 'eslint-plugin-testing-library': '^7.15.4' - 'eslint-plugin-zod': '^3.1.0' - 'globals': '^16.5.0' - 'jsonc-eslint-parser': '^2.4.2' - 'typescript-eslint': '^8.55.0' - 'yaml-eslint-parser': '^1.3.2' + '@eslint/js': ^9.39.2 + '@eslint/json': ^0.14.0 + '@typescript-eslint/parser': ^8.55.0 + eslint: ^9.39.2 + eslint-config-flat-gitignore: ^2.1.0 + eslint-config-prettier: ^10.1.8 + eslint-plugin-astro: ^1.6.0 + eslint-plugin-baseline-js: ^0.4.2 + eslint-plugin-jsx-a11y: ^6.10.2 + eslint-plugin-perfectionist: ^4.15.1 + eslint-plugin-pnpm: ^1.5.0 + eslint-plugin-react-hooks: ^7.0.1 + eslint-plugin-storybook: ^10.2.8 + eslint-plugin-testing-library: ^7.15.4 + eslint-plugin-zod: ^3.1.0 + globals: ^16.5.0 + jsonc-eslint-parser: ^2.4.2 + typescript-eslint: ^8.55.0 + yaml-eslint-parser: ^1.3.2 prettier: - prettier-plugin-astro-organize-imports: '0.4.11' - prettier-plugin-astro: '0.14.1' - prettier-plugin-jsdoc: '1.8.0' - prettier-plugin-organize-imports: '4.3.0' - prettier-plugin-packagejson: '2.5.22' - prettier-plugin-svelte: '3.4.1' - prettier-plugin-tailwindcss: 0.7.2 prettier: 3.8.1 + prettier-plugin-astro: 0.14.1 + prettier-plugin-astro-organize-imports: 0.4.11 + prettier-plugin-jsdoc: 1.8.0 + prettier-plugin-organize-imports: 4.3.0 + prettier-plugin-packagejson: 2.5.22 + prettier-plugin-svelte: 3.4.1 + prettier-plugin-tailwindcss: 0.7.2 schema: '@standard-schema/spec': 1.1.0 arktype: 2.1.29 @@ -114,11 +121,11 @@ catalogs: zod: 4.2.1 storybook: '@chromatic-com/storybook': 4.1.3 - '@storybook/addon-a11y': *storybook - '@storybook/addon-docs': *storybook + '@storybook/addon-a11y': 10.2.8 + '@storybook/addon-docs': 10.2.8 '@storybook/addon-svelte-csf': 5.0.11 - '@storybook/svelte-vite': *storybook - storybook: *storybook + '@storybook/svelte-vite': 10.2.8 + storybook: 10.2.8 svelte: '@sveltejs/package': 2.5.7 '@sveltejs/vite-plugin-svelte': 6.2.4 @@ -126,12 +133,12 @@ catalogs: svelte: 5.51.2 svelte-check: 4.4.0 turbo: - turbo: *turbo - '@turbo/gen': *turbo + '@turbo/gen': 2.8.20 + turbo: 2.8.20 vitest: - '@vitest/coverage-v8': *vitest - '@vitest/ui': *vitest - vitest: *vitest + '@vitest/coverage-v8': 4.0.18 + '@vitest/ui': 4.0.18 + vitest: 4.0.18 cleanupUnusedCatalogs: true diff --git a/tsconfig.base.json b/tsconfig.base.json index a49c55ae..c9c1bb22 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -1,22 +1,21 @@ { - "extends": "@tsconfig/recommended/tsconfig.json", - "exclude": ["node_modules", "dist"], - "include": ["./**/*"], - "compilerOptions": { - "allowImportingTsExtensions": true, - "allowJs": true, - "baseUrl": ".", - "isolatedModules": true, - "lib": ["ESNext"], - "module": "ESNext", - "moduleResolution": "Bundler", - "noEmit": true, - "resolveJsonModule": true, - "skipLibCheck": true, - "strict": true, - "strictNullChecks": true, - "target": "esnext", - "useDefineForClassFields": true, - "verbatimModuleSyntax": true - } + "extends": "@tsconfig/recommended/tsconfig.json", + "exclude": ["node_modules", "dist"], + "include": ["./**/*"], + "compilerOptions": { + "allowImportingTsExtensions": true, + "allowJs": true, + "isolatedModules": true, + "lib": ["ESNext"], + "module": "ESNext", + "moduleResolution": "Bundler", + "noEmit": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "strict": true, + "strictNullChecks": true, + "target": "esnext", + "useDefineForClassFields": true, + "verbatimModuleSyntax": true + } } From 3b02cba94ee777b1afe84fc522447c2c6e789596 Mon Sep 17 00:00:00 2001 From: stephansama Date: Tue, 21 Apr 2026 21:33:19 -0400 Subject: [PATCH 2/8] refactor(core): remove debug logic and use log module --- core/single-file/package.json | 3 +- core/single-file/src/import-map.ts | 34 +++ core/single-file/src/index.ts | 214 ++----------------- core/single-file/src/inline.ts | 133 ++++++++++++ core/single-file/src/log.ts | 34 +++ core/single-file/src/utilities.ts | 51 +++++ pnpm-lock.yaml | 330 ----------------------------- pnpm-workspace.yaml | 1 - 8 files changed, 274 insertions(+), 526 deletions(-) create mode 100644 core/single-file/src/import-map.ts create mode 100644 core/single-file/src/inline.ts create mode 100644 core/single-file/src/log.ts create mode 100644 core/single-file/src/utilities.ts diff --git a/core/single-file/package.json b/core/single-file/package.json index 93d7c500..7d3b0a93 100644 --- a/core/single-file/package.json +++ b/core/single-file/package.json @@ -45,8 +45,7 @@ "he": "catalog:", "ky": "catalog:", "obug": "catalog:cli", - "oxc-parser": "catalog:", - "svg-sprite-loader": "catalog:" + "oxc-parser": "catalog:" }, "devDependencies": { "@types/he": "catalog:", diff --git a/core/single-file/src/import-map.ts b/core/single-file/src/import-map.ts new file mode 100644 index 00000000..45eb10f4 --- /dev/null +++ b/core/single-file/src/import-map.ts @@ -0,0 +1,34 @@ +import ky from "ky"; +import path from "node:path"; + +export const WINDOW_KEY = "imports" as const; + +export const importTypes = ["css", "font", "js", "unknown"] as const; +export type ImportType = (typeof importTypes)[number]; + +export const imports = new Map< + string, + { + contentType: null | string; + data: string; + path?: string; + type: ImportType; + } +>(); + +export async function loadImport(file: string, dirname?: string) { + const loaded = imports.get(file); + if (loaded) return loaded.data; + + const resolvedFile = dirname ? path.join(dirname, file) : file; + const response = await ky.get(resolvedFile); + const data = await response.text(); + + imports.set(file, { + contentType: response.headers.get("Content-Type"), + data, + type: "unknown", + }); + + return data; +} diff --git a/core/single-file/src/index.ts b/core/single-file/src/index.ts index b6eab523..fa33be61 100644 --- a/core/single-file/src/index.ts +++ b/core/single-file/src/index.ts @@ -1,29 +1,14 @@ import * as cheerio from "cheerio"; import { cli } from "cleye"; -import dedent from "dedent"; import he from "he"; -import ky, { type KyResponse } from "ky"; +import ky from "ky"; import * as fs from "node:fs"; -import * as path from "node:path"; -import { createDebug, enable } from "obug"; +import path from "node:path"; import * as oxc from "oxc-parser"; -const html = dedent; - -const BASE_DEBUG_NAMESPACE = "single-file" as const; -const DEBUG_NAMESPACES = ["info", "warn", "error"] as const; -type DEBUG_NAMESPACE = (typeof DEBUG_NAMESPACES)[number]; -type DEBUG_SCOPE = `${typeof BASE_DEBUG_NAMESPACE}:${DEBUG_NAMESPACE}`; - -const debug = createDebug(BASE_DEBUG_NAMESPACE, { - color: 2, - log: console.info, - useColors: true, -}); - -const [debugInfo, debugWarn, debugError] = DEBUG_NAMESPACES.map((namespace) => { - return debug.extend(namespace); -}); +import * as inline from "./inline"; +import * as log from "./log"; +import * as utilities from "./utilities"; export async function run() { const argv = cli({ @@ -45,17 +30,11 @@ export async function run() { parameters: [``], }); - enableDebug("single-file:warn"); - enableDebug("single-file:error"); - - if (argv.flags.verbose) { - enableDebug("single-file:info"); - debugInfo.log("enabled debug info"); - } + log.enable(argv.flags.verbose); const pageResponse = await ky.get(argv._.url); - debugInfo.log(`loading ${argv._.url}`); + log.info(`loading ${argv._.url}`); if (!pageResponse?.headers?.get("Content-Type")?.includes("text/html")) { throw new Error( @@ -67,131 +46,31 @@ export async function run() { const $ = cheerio.load(page); - for (const svgUse of $("use[href]")) { - debugInfo.log(`loading \`svg>use\` ${svgUse.attribs.href}`); - - const src = isUrl(svgUse.attribs.href, argv._.url); - if (!src) continue; - - const response = await ky.get(src); - const svgMap = await response.text(); - const $$ = cheerio.load(svgMap, { xmlMode: true }); - const [_, hash] = svgUse.attribs.href.split("#"); - if (!hash) return null; - - const symbol = $$(`symbol#${hash}`); - const viewBox = symbol.attr("viewBox") || "0 0 24 24"; - const inner = symbol.html(); - if (!inner) { - throw new Error("unable to parse parent"); - } - - $(svgUse).parent().attr("viewBox", viewBox); - $(svgUse).replaceWith(inner); - } - - for (const img of $("img[src]")) { - debugInfo.log(`loading \`img\` ${img.attribs.src}`); - - const src = isUrl(img.attribs.src, argv._.url); - if (!src) continue; - - const response = await ky.get(src); - const extension = img.attribs.src - .split(".") - .at(-1) - ?.replace(/#.*/, "") - .replace(/\?.*/, ""); - - switch (extension) { - case "svg": { - if (img.attribs.src.includes("#")) { - const svgMap = await response.text(); - const $$ = cheerio.load(svgMap, { xmlMode: true }); - const [_, hash] = img.attribs.src.split("#"); - if (!hash) return null; - - const symbol = $$(`symbol#${hash}`); - const viewBox = symbol.attr("viewBox") || "0 0 24 24"; - const inner = symbol.html(); - const svg = html` - - ${inner} - - `.trim(); - - const encoded = encodeURIComponent(svg) - .replace(/'/g, "%27") - .replace(/"/g, "%22"); - - $(img).attr("src", `data:image/svg+xml,${encoded}`); - } else { - const dataUri = await bufferToDataUri(response); - $(img).attr("src", dataUri); - } - break; - } - default: { - const dataUri = await bufferToDataUri(response); - $(img).attr("src", dataUri); - } - } - } - - for (const link of $("link[href]")) { - debugInfo.log(`loading \`link\` ${link.attribs.href}`); - - const src = isUrl(link.attribs.href, argv._.url); - if (!src) continue; - - const response = await ky.get(src); - - switch (link.attribs.rel) { - case "apple-touch-icon": - case "icon": - case "shortcut icon": { - const dataUri = await bufferToDataUri(response); - $(link).attr("href", dataUri); - break; - } - - case "stylesheet": { - const linkSrc = await response.text(); - $(link).replaceWith( - html``, - ); - - break; - } - } + for (const inlineCallback of Object.values(inline)) { + await inlineCallback($, argv._.url); } const imported = []; for (const script of $("script[src]")) { - debugInfo.log(`loading \`script\` ${script.attribs.src}`); - const src = isUrl(script.attribs.src, argv._.url); + log.info(`loading \`script\` ${script.attribs.src}`); + const src = utilities.isUrl(script.attribs.src, argv._.url); if (!src) continue; let scriptSrc = await ky.get(src).text(); const result = await oxc.parse(src, scriptSrc); - const dynamicImports = result.module.dynamicImports.map( - (i) => i.moduleRequest, - ); - const staticImports = result.module.staticImports.map( - (i) => i.moduleRequest, - ); + const dynamicImports = result.module.dynamicImports.map((current) => { + return current.moduleRequest; + }); + const staticImports = result.module.staticImports.map((current) => { + return current.moduleRequest; + }); const imports = [...staticImports]; const dirname = path.posix.dirname(new URL(src).pathname); const allImports = imports .filter((i) => i) - .map((i) => ({ key: i.value, value: dirname + "/" + i.value })); + .map((i) => ({ key: i.value, value: path.join(dirname, i.value) })); imported.push(...allImports); @@ -218,9 +97,7 @@ export async function run() { // Move this OUTSIDE and BEFORE the for loop scriptSrc = scriptSrc.replace(/\bimport(?!\s*\()/g, "const"); - debugInfo.log( - `has imports: ${JSON.stringify(allImports, undefined, 2)}`, - ); + log.info(`has imports: ${JSON.stringify(allImports, undefined, 2)}`); $(script).removeAttr("src"); $(script).text(scriptSrc); @@ -229,9 +106,7 @@ export async function run() { const setImports = new Set(imported); const importSources: Record = {}; - debugInfo.log( - `found imports ${JSON.stringify([...setImports], undefined, 2)}`, - ); + log.info(`found imports ${JSON.stringify([...setImports], undefined, 2)}`); for (const current of setImports) { if (!current.key) continue; @@ -243,7 +118,7 @@ export async function run() { const registryString = Object.entries(importSources) .map(([file, source]) => { - const escaped = escapeScript(source); + const escaped = utilities.escapeScript(source); return ( '"' + file + @@ -274,50 +149,3 @@ export async function run() { await fs.promises.writeFile(argv.flags.output, updatedContent, "utf8"); } - -async function bufferToDataUri(res: KyResponse) { - const buffer = await res.arrayBuffer(); - const mime = res.headers.get("content-type") || "image/png"; - const base64 = Buffer.from(buffer).toString("base64"); - return `data:${mime};base64,${base64}`; -} - -function enableDebug(debugScope: DEBUG_SCOPE) { - enable(debugScope); -} - -function escapeScript(script: string) { - return script - .replaceAll("\\", "\\\\") - .replaceAll("`", "\\`") - .replaceAll("${", "\\${") - .replaceAll("", "<\\/script>") - .replaceAll("\n", "\\n") // ← add this - .replaceAll("\r", ""); -} - -function isProbablyUrl(str: string) { - if (!str) return false; - - // reject obvious non-URLs - if (str.includes("\n") || str.includes("{") || str.includes("function")) { - return false; - } - - // allow: - // - absolute URLs - // - root-relative (/foo.js) - // - relative (./foo.js, foo.js) - return /^(https?:\/\/|\/|\.\/|\.\.\/|[a-zA-Z0-9_\-./]+$)/.test(str); -} - -function isUrl(url: string, base: string) { - if (!isProbablyUrl(url)) return false; - try { - return new URL(url, base).href; - } catch (error) { - console.error(`${url} is not a URL\n${error}`); - return false; - } -} diff --git a/core/single-file/src/inline.ts b/core/single-file/src/inline.ts new file mode 100644 index 00000000..c21a687a --- /dev/null +++ b/core/single-file/src/inline.ts @@ -0,0 +1,133 @@ +import * as cheerio from "cheerio"; +import { default as html } from "dedent"; + +import * as importMap from "./import-map"; +import * as log from "./log"; +import * as utilities from "./utilities"; + +export type InlineFunction = ( + $: cheerio.CheerioAPI, + baseUrl: string, +) => Promise; + +export const img: InlineFunction = async ($, baseUrl) => { + for (const img of $("img[src]")) { + log.info(`loading \`img\` ${img.attribs.src}`); + + const src = utilities.isUrl(img.attribs.src, baseUrl); + if (!src) continue; + + const importedImage = await importMap.loadImport(src); + const extension = img.attribs.src + .split(".") + .at(-1) + ?.replace(/#.*/, "") + .replace(/\?.*/, ""); + + switch (extension) { + case "svg": { + if (img.attribs.src.includes("#")) { + const $$ = cheerio.load(importedImage, { xmlMode: true }); + const [_, hash] = img.attribs.src.split("#"); + if (!hash) continue; + + const symbol = $$(`symbol#${hash}`); + const viewBox = symbol.attr("viewBox") || "0 0 24 24"; + const inner = symbol.html(); + const svg = html` + + ${inner} + + `.trim(); + + const encoded = encodeURIComponent(svg) + .replace(/'/g, "%27") + .replace(/"/g, "%22"); + + $(img).attr("src", `data:image/svg+xml,${encoded}`); + break; + } else { + const dataUri = await utilities.bufferToDataUri( + utilities.str2ab(importedImage), + importMap.imports.get(src)?.contentType, + ); + $(img).attr("src", dataUri); + } + break; + } + default: { + const dataUri = await utilities.bufferToDataUri( + utilities.str2ab(importedImage), + importMap.imports.get(src)?.contentType, + ); + $(img).attr("src", dataUri); + } + } + } +}; + +export async function link($: cheerio.CheerioAPI, baseUrl: string) { + for (const link of $("link[href]")) { + log.info(`loading \`link\` ${link.attribs.href}`); + + const src = utilities.isUrl(link.attribs.href, baseUrl); + if (!src) continue; + + const linkSrc = await importMap.loadImport(src); + + switch (link.attribs.rel) { + case "apple-touch-icon": + case "icon": + case "shortcut icon": { + const buffer = utilities.str2ab(linkSrc); + const mime = importMap.imports.get(src)?.contentType; + const dataUri = await utilities.bufferToDataUri(buffer, mime); + $(link).attr("href", dataUri); + break; + } + + case "stylesheet": { + $(link).replaceWith( + html``, + ); + break; + } + } + } +} + +export async function svgUse($: cheerio.CheerioAPI, baseUrl: string) { + for (const svgUse of $("use[href]")) { + const [url, hash] = svgUse.attribs.href.split("#"); + if (!hash) { + log.warn(`no hash found for use element ${svgUse.attribs.href}`); + continue; + } + + log.info(`loading \`svg>use\` ${url}#${hash}`); + + const src = utilities.isUrl(url, baseUrl); + if (!src) { + log.error(`unable to load source for use element`); + continue; + } + + const svgMap = await importMap.loadImport(src); + const $$ = cheerio.load(svgMap, { xmlMode: true }); + + const symbol = $$(`symbol#${hash}`); + const viewBox = symbol.attr("viewBox") || "0 0 24 24"; + const inner = symbol.html(); + if (!inner) { + throw new Error("unable to parse parent"); + } + + $(svgUse).parent().attr("viewBox", viewBox); + $(svgUse).replaceWith(inner); + } +} diff --git a/core/single-file/src/log.ts b/core/single-file/src/log.ts new file mode 100644 index 00000000..6400291b --- /dev/null +++ b/core/single-file/src/log.ts @@ -0,0 +1,34 @@ +import * as obug from "obug"; + +export const BASE_DEBUG_NAMESPACE = "single-file" as const; +export const DEBUG_NAMESPACES = ["error", "info", "warn"] as const; +export type DEBUG_NAMESPACE = (typeof DEBUG_NAMESPACES)[number]; +export type DEBUG_SCOPE = `${typeof BASE_DEBUG_NAMESPACE}:${DEBUG_NAMESPACE}`; + +export const VERBOSE_SCOPE = "info" satisfies DEBUG_NAMESPACE; + +export const commonDebugOptions = { + log: console.info, + useColors: true, +} satisfies obug.DebugOptions; + +export const debug = obug.createDebug(BASE_DEBUG_NAMESPACE, commonDebugOptions); + +export const [error, info, warn] = DEBUG_NAMESPACES.map((namespace, index) => { + const currentDebugger = obug.createDebug(BASE_DEBUG_NAMESPACE, { + ...commonDebugOptions, + color: index + 1, + }); + const extend = debug.extend.bind(currentDebugger); + return extend(namespace); +}); + +export function enable(isVerbose: boolean) { + const enabledScopes = DEBUG_NAMESPACES.filter((scope) => { + return scope !== VERBOSE_SCOPE || isVerbose; + }) + .map((scope) => `${BASE_DEBUG_NAMESPACE}:${scope}`) + .join(","); + + obug.enable(enabledScopes); +} diff --git a/core/single-file/src/utilities.ts b/core/single-file/src/utilities.ts new file mode 100644 index 00000000..0290d237 --- /dev/null +++ b/core/single-file/src/utilities.ts @@ -0,0 +1,51 @@ +export async function bufferToDataUri( + buffer: ArrayBuffer, + mime?: null | string, +) { + const base64 = Buffer.from(buffer).toString("base64"); + return `data:${mime || "image/png"};base64,${base64}`; +} + +export function escapeScript(script: string) { + return script + .replaceAll("\\", "\\\\") + .replaceAll("`", "\\`") + .replaceAll("${", "\\${") + .replaceAll("", "<\\/script>") + .replaceAll("\n", "\\n") + .replaceAll("\r", ""); +} + +export function isProbablyUrl(str: string) { + if (!str) return false; + + // reject obvious non-URLs + if (str.includes("\n") || str.includes("{") || str.includes("function")) { + return false; + } + + // allow: + // - absolute URLs + // - root-relative (/foo.js) + // - relative (./foo.js, foo.js) + return /^(https?:\/\/|\/|\.\/|\.\.\/|[a-zA-Z0-9_\-./]+$)/.test(str); +} + +export function isUrl(url: string, base: string) { + if (!isProbablyUrl(url)) return false; + try { + return new URL(url, base).href; + } catch (error) { + console.error(`${url} is not a URL\n${error}`); + return false; + } +} + +export function str2ab(str: string) { + const array = new Uint8Array(str.length); + for (let i = 0; i < str.length; i++) { + array[i] = str.charCodeAt(i); + } + return array.buffer; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 26b8af8b..b3912a92 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -140,9 +140,6 @@ catalogs: remark: specifier: 15.0.1 version: 15.0.1 - svg-sprite-loader: - specifier: ^6.0.11 - version: 6.0.11 tailwind-scrollbar: specifier: 4.0.2 version: 4.0.2 @@ -876,9 +873,6 @@ importers: oxc-parser: specifier: 'catalog:' version: 0.127.0 - svg-sprite-loader: - specifier: 'catalog:' - version: 6.0.11 devDependencies: '@types/he': specifier: 'catalog:' @@ -5437,9 +5431,6 @@ packages: resolution: {integrity: sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==} engines: {node: '>=0.6'} - big.js@5.2.2: - resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} - binary-searching@2.0.5: resolution: {integrity: sha512-v4N2l3RxL+m4zDxyxz3Ne2aTmiPn8ZUpKFpdPtO+ItW1NcTCXA7JeHG5GMBSvoKSkQZ9ycS+EouDVxYB9ufKWA==} @@ -5458,9 +5449,6 @@ packages: blob-to-buffer@1.2.9: resolution: {integrity: sha512-BF033y5fN6OCofD3vgHmNtwZWRcq9NLyyxyILx9hfMy1sXYy4ojFl765hJ2lP0YaN2fuxPaLO2Vzzoxy0FLFFA==} - bluebird@3.7.2: - resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} - body-parser@1.20.3: resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} @@ -6057,10 +6045,6 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - deepmerge@1.3.2: - resolution: {integrity: sha512-qjMjTrk+RKv/sp4RPDpV5CnKhxjFI9p+GkLBOls5A8EEElldYWCWA9zceAkmfd0xIo2aU1nxiaLFoiya2sb6Cg==} - engines: {node: '>=0.10.0'} - deepmerge@4.3.1: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} @@ -6183,31 +6167,16 @@ packages: dom-accessibility-api@0.6.3: resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} - dom-serializer@0.2.2: - resolution: {integrity: sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==} - dom-serializer@2.0.0: resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} - domelementtype@1.3.1: - resolution: {integrity: sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==} - domelementtype@2.3.0: resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} - domhandler@2.4.2: - resolution: {integrity: sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==} - domhandler@5.0.3: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} - domready@1.0.8: - resolution: {integrity: sha512-uIzsOJUNk+AdGE9a6VDeessoMCzF8RrZvJCX/W8QtyfgdR6Uofn/MvRonih3OtCO79b2VDzDOymuiABrQ4z3XA==} - - domutils@1.7.0: - resolution: {integrity: sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==} - domutils@3.2.2: resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} @@ -6279,10 +6248,6 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - emojis-list@3.0.0: - resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} - engines: {node: '>= 4'} - empathic@2.0.0: resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==} engines: {node: '>=14'} @@ -6310,12 +6275,6 @@ packages: resolution: {integrity: sha512-kKvD1tO6BM+oK9HzCPpUdRb4vKFQY/FPTFmurMvh6LlN68VMrdj77w8yp51/kDbpkFOS9J8w5W6zIzgM2H8/hw==} engines: {node: '>= 0.4'} - entities@1.1.2: - resolution: {integrity: sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==} - - entities@2.2.0: - resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} - entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -7051,10 +7010,6 @@ packages: resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} engines: {node: '>= 0.4'} - has-flag@1.0.0: - resolution: {integrity: sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==} - engines: {node: '>=0.10.0'} - has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} @@ -7199,9 +7154,6 @@ packages: htmlparser2@10.1.0: resolution: {integrity: sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==} - htmlparser2@3.10.1: - resolution: {integrity: sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==} - http-cache-semantics@4.2.0: resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} @@ -7256,11 +7208,6 @@ packages: resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} engines: {node: '>= 4'} - image-size@0.5.5: - resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==} - engines: {node: '>=0.10.0'} - hasBin: true - import-fresh@3.3.1: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} @@ -7511,10 +7458,6 @@ packages: resolution: {integrity: sha512-qhsCR/Esx4U4hg/9I19OVUAJkGWtjRYHMRgUMZE2TDdj+Ag+kttZanLupfddNyglzz50cUlmWzUaI37GDfNx/g==} engines: {node: '>=0.10.0'} - is-plain-obj@1.1.0: - resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} - engines: {node: '>=0.10.0'} - is-plain-obj@3.0.0: resolution: {integrity: sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==} engines: {node: '>=10'} @@ -7692,9 +7635,6 @@ packages: jju@1.4.0: resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} - js-base64@2.6.4: - resolution: {integrity: sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==} - js-tokens@10.0.0: resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} @@ -7754,10 +7694,6 @@ packages: json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - json5@1.0.2: - resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} - hasBin: true - json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} @@ -8088,10 +8024,6 @@ packages: resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - loader-utils@1.4.2: - resolution: {integrity: sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==} - engines: {node: '>=4.0.0'} - local-pkg@1.1.1: resolution: {integrity: sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==} engines: {node: '>=14'} @@ -8371,10 +8303,6 @@ packages: merge-descriptors@1.0.3: resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} - merge-options@1.0.1: - resolution: {integrity: sha512-iuPV41VWKWBIOpBsjoxjDZw8/GbSfZ2mk7N1453bwMrfzdrIk7EzBd+8UVR6rkw67th7xnk9Dytl3J+lHPdxvg==} - engines: {node: '>=4'} - merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -8494,10 +8422,6 @@ packages: micromark@4.0.2: resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} - micromatch@3.1.0: - resolution: {integrity: sha512-3StSelAE+hnRvMs8IdVW7Uhk8CVed5tp+kLLGlBP6WiRAXS21GPGu/Nat4WNPXj2Eoc24B02SaeoyozPMfj0/g==} - engines: {node: '>=0.10.0'} - micromatch@3.1.10: resolution: {integrity: sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==} engines: {node: '>=0.10.0'} @@ -8579,9 +8503,6 @@ packages: minisearch@7.2.0: resolution: {integrity: sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==} - mitt@1.1.2: - resolution: {integrity: sha512-3btxP0O9iGADGWAkteQ8mzDtEspZqu4I32y4GZYCV5BrwtzdcRpF4dQgNdJadCrbBx7Lu6Sq9AVrerMHR0Hkmw==} - mitt@3.0.1: resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} @@ -9183,19 +9104,10 @@ packages: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} - postcss-prefix-selector@1.16.1: - resolution: {integrity: sha512-Umxu+FvKMwlY6TyDzGFoSUnzW+NOfMBLyC1tAkIjgX+Z/qGspJeRjVC903D7mx7TuBpJlwti2ibXtWuA7fKMeQ==} - peerDependencies: - postcss: '>4 <9' - postcss-selector-parser@7.1.0: resolution: {integrity: sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==} engines: {node: '>=4'} - postcss@5.2.18: - resolution: {integrity: sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==} - engines: {node: '>=0.12'} - postcss@8.5.6: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} @@ -9204,23 +9116,6 @@ packages: resolution: {integrity: sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==} engines: {node: ^10 || ^12 || >=14} - posthtml-parser@0.2.1: - resolution: {integrity: sha512-nPC53YMqJnc/+1x4fRYFfm81KV2V+G9NZY+hTohpYg64Ay7NemWWcV4UWuy/SgMupqQ3kJ88M/iRfZmSnxT+pw==} - - posthtml-rename-id@1.0.12: - resolution: {integrity: sha512-UKXf9OF/no8WZo9edRzvuMenb6AD5hDLzIepJW+a4oJT+T/Lx7vfMYWT4aWlGNQh0WMhnUx1ipN9OkZ9q+ddEw==} - - posthtml-render@1.4.0: - resolution: {integrity: sha512-W1779iVHGfq0Fvh2PROhCe2QhB8mEErgqzo1wpIt36tCgChafP+hbXIhLDOM8ePJrZcFs0vkNEtdibEWVqChqw==} - engines: {node: '>=10'} - - posthtml-svg-mode@1.0.3: - resolution: {integrity: sha512-hEqw9NHZ9YgJ2/0G7CECOeuLQKZi8HjWLkBaSVtOWjygQ9ZD8P7tqeowYs7WrFdKsWEKG7o+IlsPY8jrr0CJpQ==} - - posthtml@0.9.2: - resolution: {integrity: sha512-spBB5sgC4cv2YcW03f/IAUN1pgDJWNWD8FzkyY4mArLUMJW+KlQhlmUdKAHQuPfb00Jl5xIfImeOsf6YL8QK7Q==} - engines: {node: '>=0.10.0'} - powershell-utils@0.1.0: resolution: {integrity: sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==} engines: {node: '>=20'} @@ -9429,10 +9324,6 @@ packages: resolution: {integrity: sha512-M9RxRITi2mHMVPU5zysNjctUT8bAPx6ltEXo/ir9+qmiM47Y7f0Ir3+OxUO5OjYAWdicBQRew7RtHtqUXydqlg==} engines: {node: '>=20'} - query-string@4.3.4: - resolution: {integrity: sha512-O2XLNDBIg1DnTOa+2XrIwSiXEV8h2KImXUnjhhn2+UsvZ+Es2uyd5CCRTNQlDGbzUQOW3aYCBx9rVA6dzsiY7Q==} - engines: {node: '>=0.10.0'} - query-string@9.2.0: resolution: {integrity: sha512-YIRhrHujoQxhexwRLxfy3VSjOXmvZRd2nyw1PwL1UUqZ/ys1dEZd1+NSgXkne2l/4X/7OXkigEAuhTX0g/ivJQ==} engines: {node: '>=18'} @@ -10128,10 +10019,6 @@ packages: stream-replace-string@2.0.0: resolution: {integrity: sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==} - strict-uri-encode@1.1.0: - resolution: {integrity: sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==} - engines: {node: '>=0.10.0'} - string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} @@ -10274,10 +10161,6 @@ packages: resolution: {integrity: sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==} engines: {node: '>=0.8.0'} - supports-color@3.2.3: - resolution: {integrity: sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==} - engines: {node: '>=0.8.0'} - supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -10310,16 +10193,6 @@ packages: resolution: {integrity: sha512-AqApqNOxVS97V4Ko9UHTHeSuDJrwauJhZpLDs1gYD8Jk48ntCSWD7NxKje+fnGn5Ja1O3u2FzQZHPdifQjXe3w==} engines: {node: '>=18'} - svg-baker-runtime@1.4.7: - resolution: {integrity: sha512-Zorfwwj5+lWjk/oxwSMsRdS2sPQQdTmmsvaSpzU+i9ZWi3zugHLt6VckWfnswphQP0LmOel3nggpF5nETbt6xw==} - - svg-baker@1.7.0: - resolution: {integrity: sha512-nibslMbkXOIkqKVrfcncwha45f97fGuAOn1G99YwnwTj8kF9YiM6XexPcUso97NxOm6GsP0SIvYVIosBis1xLg==} - - svg-sprite-loader@6.0.11: - resolution: {integrity: sha512-TedsTf8wsHH6HgdwKjUveDZRC6q5gPloYV8A8/zZaRWP929J7x6TzQ6MvZFl+YYDJuJ0Akyuu/vNVJ+fbPuYXg==} - engines: {node: '>=6'} - svgo@4.0.0: resolution: {integrity: sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw==} engines: {node: '>=16'} @@ -10485,10 +10358,6 @@ packages: resolution: {integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==} engines: {node: '>=20'} - traverse@0.6.11: - resolution: {integrity: sha512-vxXDZg8/+p3gblxB6BhhG5yWVn1kGRlaL8O78UDXc3wRnPizB5g83dcvWV1jpDMIPnjZjOFuxlMmE82XJ4407w==} - engines: {node: '>= 0.4'} - tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true @@ -10611,10 +10480,6 @@ packages: resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} - typedarray.prototype.slice@1.0.5: - resolution: {integrity: sha512-q7QNVDGTdl702bVFiI5eY4l/HkgCM6at9KhcFbgUAzezHFbOVy4+0O/lCjsABEQwbZPravVfBIiBVGo89yzHFg==} - engines: {node: '>= 0.4'} - typedoc-plugin-markdown@4.11.0: resolution: {integrity: sha512-2iunh2ALyfyh204OF7h2u0kuQ84xB3jFZtFyUr01nThJkLvR8oGGSSDlyt2gyO4kXhvUxDcVbO0y43+qX+wFbw==} engines: {node: '>= 18'} @@ -10725,10 +10590,6 @@ packages: resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} engines: {node: '>=18'} - unidecode@0.1.8: - resolution: {integrity: sha512-SdoZNxCWpN2tXTCrGkPF/0rL2HEq+i2gwRG1ReBvx8/0yTzC3enHfugOf8A9JBShVwwrRIkLX0YcDUGbzjbVCA==} - engines: {node: '>= 0.4.12'} - unified@11.0.5: resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} @@ -10904,9 +10765,6 @@ packages: resolution: {integrity: sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA==} engines: {node: '>=0.10.0'} - url-slug@2.0.0: - resolution: {integrity: sha512-aiNmSsVgrjCiJ2+KWPferjT46YFKoE8i0YX04BlMVDue022Xwhg/zYlnZ6V9/mP3p8Wj7LEp0myiTkC/p6sxew==} - use-sync-external-store@1.6.0: resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} peerDependencies: @@ -15995,8 +15853,6 @@ snapshots: big-integer@1.6.52: {} - big.js@5.2.2: {} - binary-searching@2.0.5: {} birpc@2.6.1: {} @@ -16014,8 +15870,6 @@ snapshots: blob-to-buffer@1.2.9: {} - bluebird@3.7.2: {} - body-parser@1.20.3: dependencies: bytes: 3.1.2 @@ -16640,8 +16494,6 @@ snapshots: deep-is@0.1.4: {} - deepmerge@1.3.2: {} - deepmerge@4.3.1: {} default-browser-id@5.0.0: {} @@ -16744,36 +16596,18 @@ snapshots: dom-accessibility-api@0.6.3: {} - dom-serializer@0.2.2: - dependencies: - domelementtype: 2.3.0 - entities: 2.2.0 - dom-serializer@2.0.0: dependencies: domelementtype: 2.3.0 domhandler: 5.0.3 entities: 4.5.0 - domelementtype@1.3.1: {} - domelementtype@2.3.0: {} - domhandler@2.4.2: - dependencies: - domelementtype: 1.3.1 - domhandler@5.0.3: dependencies: domelementtype: 2.3.0 - domready@1.0.8: {} - - domutils@1.7.0: - dependencies: - dom-serializer: 0.2.2 - domelementtype: 1.3.1 - domutils@3.2.2: dependencies: dom-serializer: 2.0.0 @@ -16841,8 +16675,6 @@ snapshots: emoji-regex@9.2.2: {} - emojis-list@3.0.0: {} - empathic@2.0.0: {} encodeurl@1.0.2: {} @@ -16871,10 +16703,6 @@ snapshots: punycode: 1.4.1 safe-regex-test: 1.1.0 - entities@1.1.2: {} - - entities@2.2.0: {} - entities@4.5.0: {} entities@6.0.1: {} @@ -17987,8 +17815,6 @@ snapshots: has-bigints@1.1.0: {} - has-flag@1.0.0: {} - has-flag@4.0.0: {} has-property-descriptors@1.0.2: @@ -18233,15 +18059,6 @@ snapshots: domutils: 3.2.2 entities: 7.0.1 - htmlparser2@3.10.1: - dependencies: - domelementtype: 1.3.1 - domhandler: 2.4.2 - domutils: 1.7.0 - entities: 1.1.2 - inherits: 2.0.4 - readable-stream: 3.6.2 - http-cache-semantics@4.2.0: {} http-errors@2.0.0: @@ -18295,8 +18112,6 @@ snapshots: ignore@7.0.5: {} - image-size@0.5.5: {} - import-fresh@3.3.1: dependencies: parent-module: 1.0.1 @@ -18520,8 +18335,6 @@ snapshots: dependencies: path-is-inside: 1.0.2 - is-plain-obj@1.1.0: {} - is-plain-obj@3.0.0: {} is-plain-obj@4.1.0: {} @@ -18658,8 +18471,6 @@ snapshots: jju@1.4.0: {} - js-base64@2.6.4: {} - js-tokens@10.0.0: {} js-tokens@4.0.0: {} @@ -18731,10 +18542,6 @@ snapshots: json-stable-stringify-without-jsonify@1.0.1: {} - json5@1.0.2: - dependencies: - minimist: 1.2.8 - json5@2.2.3: {} jsonc-eslint-parser@2.4.2: @@ -19024,12 +18831,6 @@ snapshots: load-tsconfig@0.2.5: {} - loader-utils@1.4.2: - dependencies: - big.js: 5.2.2 - emojis-list: 3.0.0 - json5: 1.0.2 - local-pkg@1.1.1: dependencies: mlly: 1.8.2 @@ -19459,10 +19260,6 @@ snapshots: merge-descriptors@1.0.3: {} - merge-options@1.0.1: - dependencies: - is-plain-obj: 1.1.0 - merge-stream@2.0.0: {} merge2@1.4.1: {} @@ -19740,24 +19537,6 @@ snapshots: transitivePeerDependencies: - supports-color - micromatch@3.1.0: - dependencies: - arr-diff: 4.0.0 - array-unique: 0.3.2 - braces: 2.3.2 - define-property: 1.0.0 - extend-shallow: 2.0.1 - extglob: 2.0.4 - fragment-cache: 0.2.1 - kind-of: 5.1.0 - nanomatch: 1.2.13 - object.pick: 1.3.0 - regex-not: 1.0.2 - snapdragon: 0.8.2 - to-regex: 3.0.2 - transitivePeerDependencies: - - supports-color - micromatch@3.1.10: dependencies: arr-diff: 4.0.0 @@ -19864,8 +19643,6 @@ snapshots: minisearch@7.2.0: {} - mitt@1.1.2: {} - mitt@3.0.1: {} mixin-deep@1.3.2: @@ -20580,22 +20357,11 @@ snapshots: possible-typed-array-names@1.1.0: {} - postcss-prefix-selector@1.16.1(postcss@5.2.18): - dependencies: - postcss: 5.2.18 - postcss-selector-parser@7.1.0: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss@5.2.18: - dependencies: - chalk: 1.1.3 - js-base64: 2.6.4 - source-map: 0.5.7 - supports-color: 3.2.3 - postcss@8.5.6: dependencies: nanoid: 3.3.11 @@ -20608,29 +20374,6 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 - posthtml-parser@0.2.1: - dependencies: - htmlparser2: 3.10.1 - isobject: 2.1.0 - - posthtml-rename-id@1.0.12: - dependencies: - escape-string-regexp: 1.0.5 - - posthtml-render@1.4.0: {} - - posthtml-svg-mode@1.0.3: - dependencies: - merge-options: 1.0.1 - posthtml: 0.9.2 - posthtml-parser: 0.2.1 - posthtml-render: 1.4.0 - - posthtml@0.9.2: - dependencies: - posthtml-parser: 0.2.1 - posthtml-render: 1.4.0 - powershell-utils@0.1.0: {} preact@10.29.1: {} @@ -20773,11 +20516,6 @@ snapshots: zod: 3.25.76 zod-package-json: 1.1.0 - query-string@4.3.4: - dependencies: - object-assign: 4.1.1 - strict-uri-encode: 1.1.0 - query-string@9.2.0: dependencies: decode-uri-component: 0.4.1 @@ -21728,8 +21466,6 @@ snapshots: stream-replace-string@2.0.0: {} - strict-uri-encode@1.1.0: {} - string-argv@0.3.2: {} string-width@4.2.3: @@ -21872,10 +21608,6 @@ snapshots: supports-color@2.0.0: {} - supports-color@3.2.3: - dependencies: - has-flag: 1.0.0 - supports-color@7.2.0: dependencies: has-flag: 4.0.0 @@ -21926,45 +21658,6 @@ snapshots: magic-string: 0.30.21 zimmerframe: 1.1.4 - svg-baker-runtime@1.4.7: - dependencies: - deepmerge: 1.3.2 - mitt: 1.1.2 - svg-baker: 1.7.0 - transitivePeerDependencies: - - supports-color - - svg-baker@1.7.0: - dependencies: - bluebird: 3.7.2 - clone: 2.1.2 - he: 1.2.0 - image-size: 0.5.5 - loader-utils: 1.4.2 - merge-options: 1.0.1 - micromatch: 3.1.0 - postcss: 5.2.18 - postcss-prefix-selector: 1.16.1(postcss@5.2.18) - posthtml-rename-id: 1.0.12 - posthtml-svg-mode: 1.0.3 - query-string: 4.3.4 - traverse: 0.6.11 - transitivePeerDependencies: - - supports-color - - svg-sprite-loader@6.0.11: - dependencies: - bluebird: 3.7.2 - deepmerge: 1.3.2 - domready: 1.0.8 - escape-string-regexp: 1.0.5 - loader-utils: 1.4.2 - svg-baker: 1.7.0 - svg-baker-runtime: 1.4.7 - url-slug: 2.0.0 - transitivePeerDependencies: - - supports-color - svgo@4.0.0: dependencies: commander: 11.1.0 @@ -22120,12 +21813,6 @@ snapshots: dependencies: punycode: 2.3.1 - traverse@0.6.11: - dependencies: - gopd: 1.2.0 - typedarray.prototype.slice: 1.0.5 - which-typed-array: 1.1.19 - tree-kill@1.2.2: {} trim-lines@3.0.1: {} @@ -22245,17 +21932,6 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - typedarray.prototype.slice@1.0.5: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - get-proto: 1.0.1 - math-intrinsics: 1.1.0 - typed-array-buffer: 1.0.3 - typed-array-byte-offset: 1.0.4 - typedoc-plugin-markdown@4.11.0(typedoc@0.28.18(typescript@5.9.3)): dependencies: typedoc: 0.28.18(typescript@5.9.3) @@ -22365,8 +22041,6 @@ snapshots: unicorn-magic@0.3.0: {} - unidecode@0.1.8: {} - unified@11.0.5: dependencies: '@types/unist': 3.0.3 @@ -22525,10 +22199,6 @@ snapshots: dependencies: prepend-http: 1.0.4 - url-slug@2.0.0: - dependencies: - unidecode: 0.1.8 - use-sync-external-store@1.6.0(react@19.2.1): dependencies: react: 19.2.1 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 80604fc3..f1b7958d 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -59,7 +59,6 @@ catalog: oxc-parser: ^0.127.0 react: 19.2.0 remark: 15.0.1 - svg-sprite-loader: ^6.0.11 tailwind-scrollbar: 4.0.2 tailwindcss: 4.1.18 taze: 19.9.2 From a06085d81c02a74b9bc8251a5ae90e3fcff01980 Mon Sep 17 00:00:00 2001 From: stephansama Date: Tue, 21 Apr 2026 21:59:15 -0400 Subject: [PATCH 3/8] refactor(core): rename debug namespace constant --- core/single-file/src/inline.ts | 24 +++++++++++++++--------- core/single-file/src/log.ts | 10 +++++----- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/core/single-file/src/inline.ts b/core/single-file/src/inline.ts index c21a687a..4065fd2a 100644 --- a/core/single-file/src/inline.ts +++ b/core/single-file/src/inline.ts @@ -69,7 +69,7 @@ export const img: InlineFunction = async ($, baseUrl) => { } }; -export async function link($: cheerio.CheerioAPI, baseUrl: string) { +export const link: InlineFunction = async ($, baseUrl) => { for (const link of $("link[href]")) { log.info(`loading \`link\` ${link.attribs.href}`); @@ -99,13 +99,19 @@ export async function link($: cheerio.CheerioAPI, baseUrl: string) { } } } -} +}; -export async function svgUse($: cheerio.CheerioAPI, baseUrl: string) { - for (const svgUse of $("use[href]")) { - const [url, hash] = svgUse.attribs.href.split("#"); +export const script: InlineFunction = async ($, baseUrl) => { + for (const current of $("script")) { + // + } +}; + +export const svgUse: InlineFunction = async ($, baseUrl) => { + for (const current of $("use[href]")) { + const [url, hash] = current.attribs.href.split("#"); if (!hash) { - log.warn(`no hash found for use element ${svgUse.attribs.href}`); + log.warn(`no hash found for use element ${current.attribs.href}`); continue; } @@ -127,7 +133,7 @@ export async function svgUse($: cheerio.CheerioAPI, baseUrl: string) { throw new Error("unable to parse parent"); } - $(svgUse).parent().attr("viewBox", viewBox); - $(svgUse).replaceWith(inner); + $(current).parent().attr("viewBox", viewBox); + $(current).replaceWith(inner); } -} +}; diff --git a/core/single-file/src/log.ts b/core/single-file/src/log.ts index 6400291b..f5d885f7 100644 --- a/core/single-file/src/log.ts +++ b/core/single-file/src/log.ts @@ -1,9 +1,9 @@ import * as obug from "obug"; -export const BASE_DEBUG_NAMESPACE = "single-file" as const; +export const DEBUG_BASE_NAMESPACE = "single-file" as const; export const DEBUG_NAMESPACES = ["error", "info", "warn"] as const; export type DEBUG_NAMESPACE = (typeof DEBUG_NAMESPACES)[number]; -export type DEBUG_SCOPE = `${typeof BASE_DEBUG_NAMESPACE}:${DEBUG_NAMESPACE}`; +export type DEBUG_SCOPE = `${typeof DEBUG_BASE_NAMESPACE}:${DEBUG_NAMESPACE}`; export const VERBOSE_SCOPE = "info" satisfies DEBUG_NAMESPACE; @@ -12,10 +12,10 @@ export const commonDebugOptions = { useColors: true, } satisfies obug.DebugOptions; -export const debug = obug.createDebug(BASE_DEBUG_NAMESPACE, commonDebugOptions); +export const debug = obug.createDebug(DEBUG_BASE_NAMESPACE, commonDebugOptions); export const [error, info, warn] = DEBUG_NAMESPACES.map((namespace, index) => { - const currentDebugger = obug.createDebug(BASE_DEBUG_NAMESPACE, { + const currentDebugger = obug.createDebug(DEBUG_BASE_NAMESPACE, { ...commonDebugOptions, color: index + 1, }); @@ -27,7 +27,7 @@ export function enable(isVerbose: boolean) { const enabledScopes = DEBUG_NAMESPACES.filter((scope) => { return scope !== VERBOSE_SCOPE || isVerbose; }) - .map((scope) => `${BASE_DEBUG_NAMESPACE}:${scope}`) + .map((scope) => `${DEBUG_BASE_NAMESPACE}:${scope}`) .join(","); obug.enable(enabledScopes); From 627698781a24a2871692db67d34fa015fc4ab153 Mon Sep 17 00:00:00 2001 From: stephansama Date: Sun, 26 Apr 2026 16:12:09 -0400 Subject: [PATCH 4/8] feat(single-file): add support for binary imports and improved import mapping --- .changeset/smooth-bars-relate.md | 5 ++ core/single-file/src/import-map.ts | 85 ++++++++++++++++++++--- core/single-file/src/index.ts | 104 ++--------------------------- core/single-file/src/inline.ts | 67 ++++++++++++++++--- core/single-file/src/log.ts | 8 +-- core/single-file/src/utilities.ts | 15 +---- 6 files changed, 144 insertions(+), 140 deletions(-) create mode 100644 .changeset/smooth-bars-relate.md diff --git a/.changeset/smooth-bars-relate.md b/.changeset/smooth-bars-relate.md new file mode 100644 index 00000000..d7255e73 --- /dev/null +++ b/.changeset/smooth-bars-relate.md @@ -0,0 +1,5 @@ +--- +"@stephansama/single-file": major +--- + +created single file cli package diff --git a/core/single-file/src/import-map.ts b/core/single-file/src/import-map.ts index 45eb10f4..c028030d 100644 --- a/core/single-file/src/import-map.ts +++ b/core/single-file/src/import-map.ts @@ -1,34 +1,97 @@ import ky from "ky"; import path from "node:path"; +import * as utilities from "./utilities"; + export const WINDOW_KEY = "imports" as const; -export const importTypes = ["css", "font", "js", "unknown"] as const; +export const importTypes = ["css", "font", "js", "binary", "unknown"] as const; export type ImportType = (typeof importTypes)[number]; export const imports = new Map< string, { contentType: null | string; - data: string; + data: ArrayBuffer | string; path?: string; type: ImportType; } >(); -export async function loadImport(file: string, dirname?: string) { +export type LoadImportArgs = { dirname?: string; file: string }; + +export function determineImportType(contentType?: null | string): ImportType { + switch (contentType) { + case "application/ecmascript": + case "application/javascript": + case "text/ecmascript": + case "text/javascript": + return "js"; + default: + return "unknown"; + } +} + +export async function loadImport( + args: LoadImportArgs & { isBinary: true }, +): Promise; +export async function loadImport( + args: LoadImportArgs & { isBinary?: false }, +): Promise; + +export async function loadImport({ + dirname, + file, + isBinary, +}: { + dirname?: string; + file: string; + isBinary?: boolean; +}): Promise { const loaded = imports.get(file); - if (loaded) return loaded.data; + if (loaded) { + if (isBinary && loaded.data instanceof ArrayBuffer) return loaded.data; + if (!isBinary && typeof loaded.data === "string") return loaded.data; + } const resolvedFile = dirname ? path.join(dirname, file) : file; const response = await ky.get(resolvedFile); - const data = await response.text(); + const contentType = response.headers.get("Content-Type"); + + if (isBinary) { + const buffer = await response.arrayBuffer(); + imports.set(file, { contentType, data: buffer, type: "binary" }); + return buffer; + } + + const text = await response.text(); + const importType = determineImportType(contentType); + imports.set(file, { contentType, data: text, type: importType }); + return text; +} + +export async function writeImportMap() { + const registryImports = imports + .entries() + .filter(([_, entry]) => entry.type === "js") + .map(([file, source]) => { + if (typeof source.data !== "string") { + throw new Error( + `source is not of type string (shouldn't happen)`, + ); + } + + const escaped = utilities.escapeScript(source.data); + return ( + '"' + + file + + '": URL.createObjectURL(new Blob([`' + + escaped + + "`], {type: 'text/javascript'}))" + ); + }); - imports.set(file, { - contentType: response.headers.get("Content-Type"), - data, - type: "unknown", - }); + const registryString = Array.from(registryImports).join("\n"); - return data; + return ``; } diff --git a/core/single-file/src/index.ts b/core/single-file/src/index.ts index fa33be61..b90302b5 100644 --- a/core/single-file/src/index.ts +++ b/core/single-file/src/index.ts @@ -1,14 +1,11 @@ import * as cheerio from "cheerio"; import { cli } from "cleye"; -import he from "he"; import ky from "ky"; import * as fs from "node:fs"; -import path from "node:path"; -import * as oxc from "oxc-parser"; +import { writeImportMap } from "./import-map"; import * as inline from "./inline"; import * as log from "./log"; -import * as utilities from "./utilities"; export async function run() { const argv = cli({ @@ -50,102 +47,9 @@ export async function run() { await inlineCallback($, argv._.url); } - const imported = []; + const registryScript = await writeImportMap(); - for (const script of $("script[src]")) { - log.info(`loading \`script\` ${script.attribs.src}`); - const src = utilities.isUrl(script.attribs.src, argv._.url); - if (!src) continue; + $("head").prepend(registryScript); - let scriptSrc = await ky.get(src).text(); - const result = await oxc.parse(src, scriptSrc); - const dynamicImports = result.module.dynamicImports.map((current) => { - return current.moduleRequest; - }); - const staticImports = result.module.staticImports.map((current) => { - return current.moduleRequest; - }); - const imports = [...staticImports]; - - const dirname = path.posix.dirname(new URL(src).pathname); - const allImports = imports - .filter((i) => i) - .map((i) => ({ key: i.value, value: path.join(dirname, i.value) })); - - imported.push(...allImports); - - for (const current of imports) { - const escaped = current.value.replace( - /[.*+?^${}()|[\]\\]/g, - "\\$&", - ); - - const importRegex = new RegExp(`import\\s*['"]${escaped}['"]`, "g"); - const fromRegex = new RegExp(`from\\s*['"]${escaped}['"]`, "g"); - - scriptSrc = scriptSrc.replaceAll( - importRegex, - `await import(window.registry["${current.value}"])`, - ); - - scriptSrc = scriptSrc.replaceAll( - fromRegex, - `= await import(window.registry["${current.value}"])`, - ); - } - - // Move this OUTSIDE and BEFORE the for loop - scriptSrc = scriptSrc.replace(/\bimport(?!\s*\()/g, "const"); - - log.info(`has imports: ${JSON.stringify(allImports, undefined, 2)}`); - - $(script).removeAttr("src"); - $(script).text(scriptSrc); - } - - const setImports = new Set(imported); - const importSources: Record = {}; - - log.info(`found imports ${JSON.stringify([...setImports], undefined, 2)}`); - - for (const current of setImports) { - if (!current.key) continue; - - importSources[current.key] = await ky - .get(new URL(current.value, argv._.url)) - .text(); - } - - const registryString = Object.entries(importSources) - .map(([file, source]) => { - const escaped = utilities.escapeScript(source); - return ( - '"' + - file + - '": URL.createObjectURL(new Blob([`' + - escaped + - "`], {type: 'text/javascript'}))" - ); - }) - .join(",\n"); - - const registryScript = ``; - - const updatedContent = $.html() - ?.replace("", `${registryScript}`) - .replace( - /]*\bsrc\b)[^>]*)>([\s\S]*?)<\/script>/g, - (match, attrs, content) => { - if (attrs.includes("application/ld+json")) return match; - if (content.includes("window.registry")) return match; - const decoded = he.decode(content); - return `${decoded}`; - }, - ); - - if (!updatedContent) { - throw new Error("unable to generate head content"); - } - - await fs.promises.writeFile(argv.flags.output, updatedContent, "utf8"); + await fs.promises.writeFile(argv.flags.output, $.html(), "utf8"); } diff --git a/core/single-file/src/inline.ts b/core/single-file/src/inline.ts index 4065fd2a..4d545781 100644 --- a/core/single-file/src/inline.ts +++ b/core/single-file/src/inline.ts @@ -1,5 +1,7 @@ import * as cheerio from "cheerio"; -import { default as html } from "dedent"; +import { default as html, default as js } from "dedent"; +import path from "node:path"; +import * as oxc from "oxc-parser"; import * as importMap from "./import-map"; import * as log from "./log"; @@ -17,7 +19,10 @@ export const img: InlineFunction = async ($, baseUrl) => { const src = utilities.isUrl(img.attribs.src, baseUrl); if (!src) continue; - const importedImage = await importMap.loadImport(src); + const importedImage = await importMap.loadImport({ + file: src, + isBinary: true, + }); const extension = img.attribs.src .split(".") .at(-1) @@ -27,7 +32,9 @@ export const img: InlineFunction = async ($, baseUrl) => { switch (extension) { case "svg": { if (img.attribs.src.includes("#")) { - const $$ = cheerio.load(importedImage, { xmlMode: true }); + const $$ = cheerio.load(Buffer.from(importedImage), { + xmlMode: true, + }); const [_, hash] = img.attribs.src.split("#"); if (!hash) continue; @@ -51,7 +58,7 @@ export const img: InlineFunction = async ($, baseUrl) => { break; } else { const dataUri = await utilities.bufferToDataUri( - utilities.str2ab(importedImage), + importedImage, importMap.imports.get(src)?.contentType, ); $(img).attr("src", dataUri); @@ -60,7 +67,7 @@ export const img: InlineFunction = async ($, baseUrl) => { } default: { const dataUri = await utilities.bufferToDataUri( - utilities.str2ab(importedImage), + importedImage, importMap.imports.get(src)?.contentType, ); $(img).attr("src", dataUri); @@ -76,13 +83,14 @@ export const link: InlineFunction = async ($, baseUrl) => { const src = utilities.isUrl(link.attribs.href, baseUrl); if (!src) continue; - const linkSrc = await importMap.loadImport(src); - switch (link.attribs.rel) { case "apple-touch-icon": case "icon": case "shortcut icon": { - const buffer = utilities.str2ab(linkSrc); + const buffer = await importMap.loadImport({ + file: src, + isBinary: true, + }); const mime = importMap.imports.get(src)?.contentType; const dataUri = await utilities.bufferToDataUri(buffer, mime); $(link).attr("href", dataUri); @@ -90,6 +98,8 @@ export const link: InlineFunction = async ($, baseUrl) => { } case "stylesheet": { + const linkSrc = await importMap.loadImport({ file: src }); + $(link).replaceWith( html`