From 61970ce89f1019a56a95e9a9d7d414de7d6d1ebd Mon Sep 17 00:00:00 2001 From: saberzero1 Date: Mon, 9 Feb 2026 12:38:53 +0100 Subject: [PATCH] feat: migrate to shared utility library - Remove plugin template code - Add path utilities (simplifySlug, joinSegments, etc.) - Add DOM utilities (removeAllChildren, registerEscapeHandler) - Add lang utilities (classNames) - Update package.json for @quartz-community/utils - Add tests for path utilities --- README.md | 206 ++-- package-lock.json | 1257 +--------------------- package.json | 56 +- src/components/ExampleComponent.tsx | 32 - src/components/index.ts | 2 - src/components/scripts.d.ts | 4 - src/components/scripts/example.inline.ts | 3 - src/components/styles.d.ts | 4 - src/components/styles/example.scss | 8 - src/dom.ts | 59 + src/emitter.ts | 88 -- src/filter.ts | 55 - src/i18n/index.ts | 9 - src/i18n/locales/en-US.ts | 7 - src/index.ts | 36 +- src/lang.ts | 3 + src/path.ts | 214 ++++ src/transformer.ts | 104 -- src/types.ts | 54 - src/util/lang.ts | 5 - test/emitter.test.ts | 45 - test/filter.test.ts | 21 - test/helpers.ts | 38 - test/path.test.ts | 107 ++ test/transformer.test.ts | 22 - tsup.config.ts | 33 +- types/quartz-compat.d.ts | 150 --- 27 files changed, 522 insertions(+), 2100 deletions(-) delete mode 100644 src/components/ExampleComponent.tsx delete mode 100644 src/components/index.ts delete mode 100644 src/components/scripts.d.ts delete mode 100644 src/components/scripts/example.inline.ts delete mode 100644 src/components/styles.d.ts delete mode 100644 src/components/styles/example.scss create mode 100644 src/dom.ts delete mode 100644 src/emitter.ts delete mode 100644 src/filter.ts delete mode 100644 src/i18n/index.ts delete mode 100644 src/i18n/locales/en-US.ts create mode 100644 src/lang.ts create mode 100644 src/path.ts delete mode 100644 src/transformer.ts delete mode 100644 src/types.ts delete mode 100644 src/util/lang.ts delete mode 100644 test/emitter.test.ts delete mode 100644 test/filter.test.ts delete mode 100644 test/helpers.ts create mode 100644 test/path.test.ts delete mode 100644 test/transformer.test.ts delete mode 100644 types/quartz-compat.d.ts diff --git a/README.md b/README.md index 34d004a..56690b2 100644 --- a/README.md +++ b/README.md @@ -1,166 +1,82 @@ -# Quartz Community Plugin Template +# @quartz-community/utils -Production-ready template for building, testing, and publishing Quartz community plugins. It mirrors -Quartz's native plugin patterns and uses a factory-function API similar to Astro integrations: -plugins are created by functions that return objects with `name` and lifecycle hooks. +Shared utility functions for Quartz community plugins. -## Highlights - -- ✅ Quartz-compatible transformer/filter/emitter examples -- ✅ TypeScript-first with exported types for consumers -- ✅ `tsup` bundling + declaration output -- ✅ Vitest testing setup with example tests -- ✅ Linting/formatting with ESLint + Prettier -- ✅ CI workflow for checks and npm publishing -- ✅ Demonstrates CSS/JS resource injection and remark/rehype usage - -## Getting started +## Installation ```bash -npm install -npm run build +npm install @quartz-community/utils ``` -## Usage in Quartz +Or using GitHub: -Install your plugin into a Quartz site and register it in `quartz.config.ts`: +```bash +npm install github:quartz-community/utils +``` + +## Usage ```ts import { - ExampleTransformer, - ExampleFilter, - ExampleEmitter, -} from "@quartz-community/plugin-template"; + simplifySlug, + getFullSlug, + joinSegments, + removeAllChildren, + classNames, +} from "@quartz-community/utils"; -export default { - configuration: { - pageTitle: "My Garden", - }, - plugins: { - transformers: [ExampleTransformer({ highlightToken: "==" })], - filters: [ExampleFilter({ allowDrafts: false })], - emitters: [ExampleEmitter({ manifestSlug: "plugin-manifest" })], - }, -}; +// Path utilities +const slug = simplifySlug("folder/index"); // "folder/" +const currentSlug = getFullSlug(window); // e.g., "blog/my-post" +const path = joinSegments("a", "b", "c"); // "a/b/c" + +// DOM utilities +removeAllChildren(document.getElementById("container")!); + +// Language utilities +const classes = classNames("btn", isActive && "active", null); // "btn active" ``` -## Plugin factory pattern (Astro-style) +## Modules -Quartz plugins are factory functions that return an object with a `name` and hook implementations. -This mirrors Astro's integration pattern (a function returning an object of hooks), which makes -composition and configuration explicit and predictable. +### Path (`@quartz-community/utils/path`) + +Path manipulation utilities for Quartz slugs: + +- `simplifySlug(slug)` - Remove `/index` suffix from slugs +- `getFullSlug(window)` - Get current page slug from document body dataset +- `getFullSlugFromUrl()` - Get current page slug from URL pathname +- `joinSegments(...segments)` - Join path segments with proper slash handling +- `resolvePath(path)` - Ensure path starts with `/` +- `endsWith(str, suffix)` - Check if path ends with suffix +- `trimSuffix(str, suffix)` - Remove suffix from path +- `stripSlashes(str, onlyPrefix?)` - Remove leading/trailing slashes +- `getFileExtension(path)` - Get file extension +- `isFolderPath(path)` - Check if path represents a folder +- `getAllSegmentPrefixes(path)` - Get all path prefixes + +### DOM (`@quartz-community/utils/dom`) + +DOM manipulation utilities: + +- `removeAllChildren(element)` - Remove all child nodes from an element +- `registerEscapeHandler(container, callback)` - Register Escape key and click-outside handlers +- `normalizeRelativeURLs(document, baseUrl)` - Convert relative URLs to absolute + +### Lang (`@quartz-community/utils/lang`) + +Language/general utilities: + +- `classNames(...classes)` - Combine CSS class names, filtering falsy values + +## Types + +The package exports TypeScript types for type-safe slug handling: ```ts -import type { QuartzTransformerPlugin } from "@jackyzha0/quartz/plugins/types"; - -export const MyTransformer: QuartzTransformerPlugin<{ enabled: boolean }> = (opts) => { - return { - name: "MyTransformer", - markdownPlugins() { - return []; - }, - }; -}; +import type { FullSlug, SimpleSlug, RelativeURL } from "@quartz-community/utils"; ``` -## Examples included - -### Transformer - -`ExampleTransformer` shows how to: - -- apply a custom remark plugin -- run a rehype plugin -- inject CSS/JS resources -- perform a text transform hook - -```ts -import { ExampleTransformer } from "@quartz-community/plugin-template"; - -ExampleTransformer({ - highlightToken: "==", - headingClass: "example-plugin-heading", - enableGfm: true, - addHeadingSlugs: true, -}); -``` - -The transformer uses a custom remark plugin to convert `==highlight==` into bold text and a rehype -plugin to attach a class to all headings. It also injects a small inline CSS/JS snippet. - -### Filter - -`ExampleFilter` demonstrates frontmatter-driven filtering: - -```ts -ExampleFilter({ - allowDrafts: false, - excludeTags: ["private", "wip"], - excludePathPrefixes: ["_drafts/", "_private/"], -}); -``` - -### Emitter - -`ExampleEmitter` emits a JSON manifest of all pages: - -```ts -ExampleEmitter({ - manifestSlug: "plugin-manifest", - includeFrontmatter: true, - metadata: { project: "My Garden" }, - transformManifest: (json) => json.replace("My Garden", "Quartz"), -}); -``` - -## API reference - -### `ExampleTransformer(options)` - -| Option | Type | Default | Description | -| ----------------- | --------- | -------------------------- | ----------------------------- | -| `highlightToken` | `string` | `"=="` | Token used to highlight text. | -| `headingClass` | `string` | `"example-plugin-heading"` | Class added to headings. | -| `enableGfm` | `boolean` | `true` | Enables `remark-gfm`. | -| `addHeadingSlugs` | `boolean` | `true` | Enables `rehype-slug`. | - -### `ExampleFilter(options)` - -| Option | Type | Default | Description | -| --------------------- | ---------- | --------------------------- | ------------------------- | -| `allowDrafts` | `boolean` | `false` | Publish draft pages. | -| `excludeTags` | `string[]` | `["private"]` | Tags to exclude. | -| `excludePathPrefixes` | `string[]` | `["_drafts/", "_private/"]` | Path prefixes to exclude. | - -### `ExampleEmitter(options)` - -| Option | Type | Default | Description | -| --------------------- | -------------------------- | ----------------------------------------- | ----------------------------------------- | -| `manifestSlug` | `string` | `"plugin-manifest"` | Output filename (without extension). | -| `includeFrontmatter` | `boolean` | `true` | Include frontmatter in output. | -| `metadata` | `Record` | `{ generator: "Quartz Plugin Template" }` | Extra metadata in manifest. | -| `transformManifest` | `(json: string) => string` | `undefined` | Custom transformer for emitted JSON. | -| `manifestScriptClass` | `string` | `undefined` | Optional CSS class if rendered into HTML. | - -## Testing - -```bash -npm test -``` - -## Build and lint - -```bash -npm run build -npm run lint -npm run format -``` - -## Publishing - -Tags matching `v*` trigger the GitHub Actions publish workflow. Ensure `NPM_TOKEN` is set in the -repository secrets. - ## License MIT diff --git a/package-lock.json b/package-lock.json index b01f178..d3e17ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,33 +1,19 @@ { - "name": "@quartz-community/plugin-template", + "name": "@quartz-community/utils", "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "@quartz-community/plugin-template", + "name": "@quartz-community/utils", "version": "0.1.0", "license": "MIT", - "dependencies": { - "@quartz-community/types": "github:quartz-community/types", - "mdast-util-find-and-replace": "^3.0.1", - "rehype-slug": "^6.0.0", - "remark-gfm": "^4.0.1", - "remark-parse": "^11.0.0", - "remark-stringify": "^11.0.0", - "unified": "^11.0.5", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.3" - }, "devDependencies": { - "@types/hast": "^3.0.4", - "@types/mdast": "^4.0.4", "@types/node": "^24.10.0", "@typescript-eslint/eslint-plugin": "^7.18.0", "@typescript-eslint/parser": "^7.18.0", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", - "preact": "^10.28.2", "prettier": "^3.6.2", "tsup": "^8.5.0", "typescript": "^5.9.3", @@ -36,18 +22,6 @@ "engines": { "node": ">=22", "npm": ">=10.9.2" - }, - "peerDependencies": { - "@jackyzha0/quartz": "^4.5.2", - "preact": "^10.0.0" - }, - "peerDependenciesMeta": { - "@jackyzha0/quartz": { - "optional": true - }, - "preact": { - "optional": false - } } }, "node_modules/@esbuild/aix-ppc64": { @@ -718,15 +692,6 @@ "node": ">= 8" } }, - "node_modules/@quartz-community/types": { - "version": "0.1.0", - "resolved": "git+ssh://git@github.com/quartz-community/types.git#a342579c845f6dfd74c2aed861b4662a69c5e328", - "license": "MIT", - "engines": { - "node": ">=22", - "npm": ">=10.9.2" - } - }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.57.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.57.1.tgz", @@ -1077,15 +1042,6 @@ "win32" ] }, - "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", - "license": "MIT", - "dependencies": { - "@types/ms": "*" - } - }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", @@ -1093,34 +1049,10 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/hast": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", - "license": "MIT" - }, "node_modules/@types/node": { - "version": "24.10.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.11.tgz", - "integrity": "sha512-/Af7O8r1frCVgOz0I62jWUtMohJ0/ZQU/ZoketltOJPZpnb17yoNc9BSoVuV9qlaIXJiPNOpsfq4ByFajSArNQ==", + "version": "24.10.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.12.tgz", + "integrity": "sha512-68e+T28EbdmLSTkPgs3+UacC6rzmqrcWFPQs1C8mwJhI/r5Uxr0yEuQotczNRROd1gq30NGxee+fo0rSIxpyAw==", "dev": true, "license": "MIT", "peer": true, @@ -1128,12 +1060,6 @@ "undici-types": "~7.16.0" } }, - "node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", - "license": "MIT" - }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "7.18.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", @@ -1563,16 +1489,6 @@ "node": ">=12" } }, - "node_modules/bail": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", - "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -1639,16 +1555,6 @@ "node": ">=6" } }, - "node_modules/ccount": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", - "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/chai": { "version": "5.3.3", "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", @@ -1683,16 +1589,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/character-entities": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/check-error": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", @@ -1792,6 +1688,7 @@ "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -1805,19 +1702,6 @@ } } }, - "node_modules/decode-named-character-reference": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", - "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", - "license": "MIT", - "dependencies": { - "character-entities": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/deep-eql": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", @@ -1835,28 +1719,6 @@ "dev": true, "license": "MIT" }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/devlop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", - "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", - "license": "MIT", - "dependencies": { - "dequal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -2155,12 +2017,6 @@ "node": ">=12.0.0" } }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "license": "MIT" - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -2222,24 +2078,6 @@ "reusify": "^1.0.4" } }, - "node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -2339,12 +2177,6 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/github-slugger": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", - "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", - "license": "ISC" - }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -2458,32 +2290,6 @@ "node": ">=8" } }, - "node_modules/hast-util-heading-rank": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-heading-rank/-/hast-util-heading-rank-3.0.0.tgz", - "integrity": "sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-string": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-3.0.1.tgz", - "integrity": "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -2583,18 +2389,6 @@ "node": ">=8" } }, - "node_modules/is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -2723,16 +2517,6 @@ "dev": true, "license": "MIT" }, - "node_modules/longest-streak": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", - "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/loupe": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", @@ -2750,217 +2534,6 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, - "node_modules/markdown-table": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", - "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/mdast-util-find-and-replace": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", - "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "escape-string-regexp": "^5.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mdast-util-from-markdown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", - "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", - "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", - "license": "MIT", - "dependencies": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-gfm-autolink-literal": "^2.0.0", - "mdast-util-gfm-footnote": "^2.0.0", - "mdast-util-gfm-strikethrough": "^2.0.0", - "mdast-util-gfm-table": "^2.0.0", - "mdast-util-gfm-task-list-item": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-autolink-literal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", - "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "ccount": "^2.0.0", - "devlop": "^1.0.0", - "mdast-util-find-and-replace": "^3.0.0", - "micromark-util-character": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-footnote": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", - "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-strikethrough": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", - "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "markdown-table": "^3.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-task-list-item": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", - "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-phrasing": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", - "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-markdown": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", - "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "longest-streak": "^3.0.0", - "mdast-util-phrasing": "^4.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "unist-util-visit": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -2971,569 +2544,6 @@ "node": ">= 8" } }, - "node_modules/micromark": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", - "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", - "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", - "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", - "license": "MIT", - "dependencies": { - "micromark-extension-gfm-autolink-literal": "^2.0.0", - "micromark-extension-gfm-footnote": "^2.0.0", - "micromark-extension-gfm-strikethrough": "^2.0.0", - "micromark-extension-gfm-table": "^2.0.0", - "micromark-extension-gfm-tagfilter": "^2.0.0", - "micromark-extension-gfm-task-list-item": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", - "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-footnote": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", - "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-strikethrough": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", - "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-table": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", - "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-tagfilter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", - "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-task-list-item": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", - "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-factory-destination": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", - "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-label": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", - "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", - "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", - "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-chunked": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", - "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-classify-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", - "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-combine-extensions": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", - "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", - "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-string": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", - "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-encode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", - "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-html-tag-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", - "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-normalize-identifier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", - "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-resolve-all": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", - "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", - "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-subtokenize": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", - "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", - "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -3548,19 +2558,6 @@ "node": ">=8.6" } }, - "node_modules/micromatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/minimatch": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", @@ -3594,6 +2591,7 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, "license": "MIT" }, "node_modules/mz": { @@ -3782,14 +2780,13 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "license": "MIT", - "peer": true, "engines": { - "node": ">=12" + "node": ">=8.6" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" @@ -3890,17 +2887,6 @@ } } }, - "node_modules/preact": { - "version": "10.28.3", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.28.3.tgz", - "integrity": "sha512-tCmoRkPQLpBeWzpmbhryairGnhW9tKV6c6gr/w+RhoRoKEJwsjzipwp//1oCpGPOchvSLaAPlpcJi9MwMmoPyA==", - "dev": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/preact" - } - }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -3972,72 +2958,6 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/rehype-slug": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/rehype-slug/-/rehype-slug-6.0.0.tgz", - "integrity": "sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "github-slugger": "^2.0.0", - "hast-util-heading-rank": "^3.0.0", - "hast-util-to-string": "^3.0.0", - "unist-util-visit": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-gfm": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", - "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-gfm": "^3.0.0", - "micromark-extension-gfm": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-stringify": "^11.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-parse": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", - "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-stringify": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", - "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-to-markdown": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -4355,6 +3275,38 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/tinypool": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", @@ -4408,16 +3360,6 @@ "tree-kill": "cli.js" } }, - "node_modules/trough": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", - "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/ts-api-utils": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", @@ -4556,80 +3498,6 @@ "dev": true, "license": "MIT" }, - "node_modules/unified": { - "version": "11.0.5", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", - "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-is": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", - "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", - "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit-parents": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", - "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -4640,41 +3508,12 @@ "punycode": "^2.1.0" } }, - "node_modules/vfile": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", - "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-message": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", - "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/vite": { "version": "5.4.21", "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", @@ -5324,16 +4163,6 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } - }, - "node_modules/zwitch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } } } } diff --git a/package.json b/package.json index 4c507b6..e95d8b4 100644 --- a/package.json +++ b/package.json @@ -1,23 +1,21 @@ { - "name": "@quartz-community/plugin-template", + "name": "@quartz-community/utils", "version": "0.1.0", - "description": "Template repository for Quartz community plugins.", + "description": "Shared utility functions for Quartz community plugins.", "type": "module", "license": "MIT", "author": "Quartz Community", "homepage": "https://quartz.jzhao.xyz", "repository": { "type": "git", - "url": "https://github.com/quartz-community/plugin-template" + "url": "https://github.com/quartz-community/utils" }, "keywords": [ "quartz", "quartz-plugin", - "plugin-template", - "remark", - "rehype", - "mdast", - "hast" + "utilities", + "path", + "dom" ], "files": [ "dist", @@ -30,13 +28,17 @@ "types": "./dist/index.d.ts", "import": "./dist/index.js" }, - "./types": { - "types": "./dist/types.d.ts", - "import": "./dist/types.js" + "./path": { + "types": "./dist/path.d.ts", + "import": "./dist/path.js" }, - "./components": { - "types": "./dist/components/index.d.ts", - "import": "./dist/components/index.js" + "./dom": { + "types": "./dist/dom.d.ts", + "import": "./dist/dom.js" + }, + "./lang": { + "types": "./dist/lang.d.ts", + "import": "./dist/lang.js" }, "./package.json": "./package.json" }, @@ -53,38 +55,12 @@ "typecheck": "tsc --noEmit", "check": "npm run typecheck && npm run lint && npm run format && npm run test" }, - "peerDependencies": { - "@jackyzha0/quartz": "^4.5.2", - "preact": "^10.0.0" - }, - "peerDependenciesMeta": { - "@jackyzha0/quartz": { - "optional": true - }, - "preact": { - "optional": false - } - }, - "dependencies": { - "@quartz-community/types": "github:quartz-community/types", - "mdast-util-find-and-replace": "^3.0.1", - "rehype-slug": "^6.0.0", - "remark-gfm": "^4.0.1", - "remark-parse": "^11.0.0", - "remark-stringify": "^11.0.0", - "unified": "^11.0.5", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.3" - }, "devDependencies": { - "@types/hast": "^3.0.4", - "@types/mdast": "^4.0.4", "@types/node": "^24.10.0", "@typescript-eslint/eslint-plugin": "^7.18.0", "@typescript-eslint/parser": "^7.18.0", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", - "preact": "^10.28.2", "prettier": "^3.6.2", "tsup": "^8.5.0", "typescript": "^5.9.3", diff --git a/src/components/ExampleComponent.tsx b/src/components/ExampleComponent.tsx deleted file mode 100644 index 28e5ab7..0000000 --- a/src/components/ExampleComponent.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import type { - QuartzComponent, - QuartzComponentProps, - QuartzComponentConstructor, -} from "@quartz-community/types"; -import { classNames } from "../util/lang"; -import { i18n } from "../i18n"; -import style from "./styles/example.scss"; -// @ts-ignore -import script from "./scripts/example.inline.ts"; - -export interface ExampleComponentOptions { - prefix?: string; - suffix?: string; - className?: string; -} - -export default ((opts?: ExampleComponentOptions) => { - const { prefix = "", suffix = "", className = "example-component" } = opts ?? {}; - - const Component: QuartzComponent = (props: QuartzComponentProps) => { - const title = props.fileData?.frontmatter?.title ?? "Untitled"; - const fullText = `${prefix}${title}${suffix}`; - - return
{fullText}
; - }; - - Component.css = style; - Component.afterDOMLoaded = script; - - return Component; -}) satisfies QuartzComponentConstructor; diff --git a/src/components/index.ts b/src/components/index.ts deleted file mode 100644 index f2ca23a..0000000 --- a/src/components/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default as ExampleComponent } from "./ExampleComponent"; -export type { ExampleComponentOptions } from "./ExampleComponent"; diff --git a/src/components/scripts.d.ts b/src/components/scripts.d.ts deleted file mode 100644 index 89df165..0000000 --- a/src/components/scripts.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare module "*.inline.ts" { - const content: string; - export default content; -} diff --git a/src/components/scripts/example.inline.ts b/src/components/scripts/example.inline.ts deleted file mode 100644 index 36f9022..0000000 --- a/src/components/scripts/example.inline.ts +++ /dev/null @@ -1,3 +0,0 @@ -document.addEventListener('nav', () => { - console.log('ExampleComponent: page navigation occurred'); -}); diff --git a/src/components/styles.d.ts b/src/components/styles.d.ts deleted file mode 100644 index 0a31e5e..0000000 --- a/src/components/styles.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare module "*.scss" { - const content: string; - export default content; -} diff --git a/src/components/styles/example.scss b/src/components/styles/example.scss deleted file mode 100644 index 49b4379..0000000 --- a/src/components/styles/example.scss +++ /dev/null @@ -1,8 +0,0 @@ -.example-component { - padding: 8px 16px; - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - color: white; - border-radius: 4px; - font-weight: 600; - display: inline-block; -} diff --git a/src/dom.ts b/src/dom.ts new file mode 100644 index 0000000..5ca99c6 --- /dev/null +++ b/src/dom.ts @@ -0,0 +1,59 @@ +export function removeAllChildren(el: HTMLElement): void { + while (el.firstChild) { + el.removeChild(el.firstChild); + } +} + +export function registerEscapeHandler( + outsideContainer: HTMLElement | null, + onEscape: () => void, +): () => void { + if (!outsideContainer) return () => {}; + + const onKeydown = (e: KeyboardEvent) => { + if (e.key === "Escape") { + e.preventDefault(); + onEscape(); + } + }; + + const onClick = (e: MouseEvent) => { + if (e.target instanceof Node && !outsideContainer.contains(e.target)) { + onEscape(); + } + }; + + document.addEventListener("keydown", onKeydown); + document.addEventListener("click", onClick); + + return () => { + document.removeEventListener("keydown", onKeydown); + document.removeEventListener("click", onClick); + }; +} + +export function normalizeRelativeURLs(html: Document, baseUrl: string): void { + const elements = html.querySelectorAll("[src], [href]"); + for (const el of Array.from(elements)) { + const attr = el.hasAttribute("href") ? "href" : "src"; + const val = el.getAttribute(attr); + if (!val) continue; + if ( + val.startsWith("http://") || + val.startsWith("https://") || + val.startsWith("mailto:") || + val.startsWith("tel:") || + val.startsWith("#") || + val.startsWith("/") || + val.startsWith("data:") + ) { + continue; + } + try { + const normalized = new URL(val, baseUrl).toString(); + el.setAttribute(attr, normalized); + } catch { + continue; + } + } +} diff --git a/src/emitter.ts b/src/emitter.ts deleted file mode 100644 index 702523c..0000000 --- a/src/emitter.ts +++ /dev/null @@ -1,88 +0,0 @@ -import path from "node:path"; -import fs from "node:fs/promises"; -import type { QuartzEmitterPlugin } from "@jackyzha0/quartz/plugins/types"; -import type { ProcessedContent } from "@jackyzha0/quartz/plugins/vfile"; -import type { BuildCtx } from "@jackyzha0/quartz/util/ctx"; -import type { FilePath, FullSlug } from "@jackyzha0/quartz/util/path"; -import type { ExampleEmitterOptions } from "./types"; - -const defaultOptions: ExampleEmitterOptions = { - manifestSlug: "plugin-manifest", - includeFrontmatter: true, - metadata: { - generator: "Quartz Plugin Template", - }, -}; - -const joinSegments = (...segments: string[]) => - segments - .filter((segment) => segment.length > 0) - .join("/") - .replace(/\/+/g, "/") as FilePath; - -const writeFile = async ( - outputDir: string, - slug: FullSlug, - ext: `.${string}` | "", - content: string, -) => { - const outputPath = joinSegments(outputDir, `${slug}${ext}`) as FilePath; - await fs.mkdir(path.dirname(outputPath), { recursive: true }); - await fs.writeFile(outputPath, content); - return outputPath; -}; - -/** - * Example emitter that writes a JSON manifest of content metadata. - */ -export const ExampleEmitter: QuartzEmitterPlugin> = ( - userOptions?: Partial, -) => { - const options = { ...defaultOptions, ...userOptions }; - const emitManifest = async (ctx: BuildCtx, content: ProcessedContent[]) => { - const manifest = { - ...options.metadata, - generatedAt: new Date().toISOString(), - pages: content.map(([_tree, vfile]) => { - const frontmatter = (vfile.data?.frontmatter ?? {}) as { - title?: string; - tags?: string[]; - [key: string]: unknown; - }; - return { - slug: vfile.data?.slug ?? null, - title: frontmatter.title ?? null, - tags: frontmatter.tags ?? null, - filePath: vfile.data?.filePath ?? null, - frontmatter: options.includeFrontmatter ? frontmatter : undefined, - }; - }), - }; - - let json = `${JSON.stringify(manifest, null, 2)}\n`; - if (options.transformManifest) { - json = options.transformManifest(json); - } - - const output = await writeFile( - ctx.argv.output, - options.manifestSlug as FullSlug, - ".json", - json, - ); - return [output]; - }; - - return { - name: "ExampleEmitter", - async emit(ctx, content, _resources) { - return emitManifest(ctx, content); - }, - async *partialEmit(ctx, content, _resources, _changeEvents) { - const outputPaths = await emitManifest(ctx, content); - for (const outputPath of outputPaths) { - yield outputPath; - } - }, - }; -}; diff --git a/src/filter.ts b/src/filter.ts deleted file mode 100644 index 38c4d8a..0000000 --- a/src/filter.ts +++ /dev/null @@ -1,55 +0,0 @@ -import type { QuartzFilterPlugin } from "@jackyzha0/quartz/plugins/types"; -import type { ProcessedContent } from "@jackyzha0/quartz/plugins/vfile"; -import type { BuildCtx } from "@jackyzha0/quartz/util/ctx"; -import type { ExampleFilterOptions } from "./types"; - -const defaultOptions: ExampleFilterOptions = { - allowDrafts: false, - excludeTags: ["private"], - excludePathPrefixes: ["_drafts/", "_private/"], -}; - -const normalizeTag = (tag: unknown) => (typeof tag === "string" ? tag.trim().toLowerCase() : ""); - -const includesTag = (tags: unknown, excludedTags: string[]) => { - if (!Array.isArray(tags)) { - return false; - } - - const normalizedExcluded = excludedTags.map((tag) => tag.toLowerCase()); - return tags.some((tag) => normalizedExcluded.includes(normalizeTag(tag))); -}; - -/** - * Example filter that removes drafts, tagged pages, and excluded path prefixes. - */ -export const ExampleFilter: QuartzFilterPlugin> = ( - userOptions?: Partial, -) => { - const options = { ...defaultOptions, ...userOptions }; - return { - name: "ExampleFilter", - shouldPublish(_ctx: BuildCtx, [_tree, vfile]: ProcessedContent) { - const frontmatter = (vfile.data?.frontmatter ?? {}) as { - draft?: boolean | string; - tags?: string[]; - }; - const isDraft = frontmatter.draft === true || frontmatter.draft === "true"; - if (isDraft && !options.allowDrafts) { - return false; - } - - if (includesTag(frontmatter.tags, options.excludeTags)) { - return false; - } - - const filePath = typeof vfile.data?.filePath === "string" ? vfile.data.filePath : ""; - const normalizedPath = filePath.replace(/\\/g, "/"); - if (options.excludePathPrefixes.some((prefix) => normalizedPath.startsWith(prefix))) { - return false; - } - - return true; - }, - }; -}; diff --git a/src/i18n/index.ts b/src/i18n/index.ts deleted file mode 100644 index 8ad01cf..0000000 --- a/src/i18n/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -import enUS from "./locales/en-US"; - -const locales: Record = { - "en-US": enUS, -}; - -export function i18n(locale: string) { - return locales[locale] || enUS; -} diff --git a/src/i18n/locales/en-US.ts b/src/i18n/locales/en-US.ts deleted file mode 100644 index 001f5c2..0000000 --- a/src/i18n/locales/en-US.ts +++ /dev/null @@ -1,7 +0,0 @@ -export default { - components: { - example: { - title: "Example", - }, - }, -}; diff --git a/src/index.ts b/src/index.ts index d80cf22..7220991 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,23 +1,19 @@ -export { ExampleTransformer } from "./transformer"; -export { ExampleFilter } from "./filter"; -export { ExampleEmitter } from "./emitter"; -export { default as ExampleComponent } from "./components/ExampleComponent"; +export { + simplifySlug, + getFullSlug, + getFullSlugFromUrl, + joinSegments, + resolvePath, + endsWith, + trimSuffix, + stripSlashes, + getFileExtension, + isFolderPath, + getAllSegmentPrefixes, +} from "./path.js"; -export type { - ExampleTransformerOptions, - ExampleFilterOptions, - ExampleEmitterOptions, -} from "./types"; +export type { FullSlug, SimpleSlug, RelativeURL } from "./path.js"; -export type { ExampleComponentOptions } from "./components/ExampleComponent"; +export { removeAllChildren, registerEscapeHandler, normalizeRelativeURLs } from "./dom.js"; -// Re-export shared types from @quartz-community/types -export type { - QuartzComponent, - QuartzComponentProps, - QuartzComponentConstructor, - StringResource, - QuartzTransformerPlugin, - QuartzFilterPlugin, - QuartzEmitterPlugin, -} from "@quartz-community/types"; +export { classNames } from "./lang.js"; diff --git a/src/lang.ts b/src/lang.ts new file mode 100644 index 0000000..5610168 --- /dev/null +++ b/src/lang.ts @@ -0,0 +1,3 @@ +export function classNames(...classes: (string | undefined | null | false)[]): string { + return classes.filter(Boolean).join(" "); +} diff --git a/src/path.ts b/src/path.ts new file mode 100644 index 0000000..514d579 --- /dev/null +++ b/src/path.ts @@ -0,0 +1,214 @@ +/** + * Path utilities for Quartz plugins. + * These functions are isomorphic and work in both Node.js and browser environments. + */ + +/** + * Branded string types for type-safe slug handling. + */ +type SlugLike = string & { __brand: T }; + +/** Full slug - cannot be relative, may not have leading/trailing slashes, can have 'index' as last segment */ +export type FullSlug = SlugLike<"full">; + +/** Simple slug - no '/index' ending, no file extension, can have trailing slash for folders */ +export type SimpleSlug = SlugLike<"simple">; + +/** Relative URL - starts with './' or '../', used for navigation */ +export type RelativeURL = SlugLike<"relative">; + +/** + * Simplifies a full slug by removing the '/index' suffix. + * @param fp - The full slug to simplify + * @returns The simplified slug, or "/" if the result would be empty + * + * @example + * simplifySlug("folder/index") // "folder/" + * simplifySlug("page") // "page" + * simplifySlug("index") // "/" + */ +export function simplifySlug(fp: FullSlug | string): SimpleSlug { + const res = stripSlashes(trimSuffix(fp, "index"), true); + return (res.length === 0 ? "/" : res) as SimpleSlug; +} + +/** + * Gets the current page's full slug from the window location. + * @param window - The window object (for browser environments) + * @returns The full slug of the current page + * + * @example + * // On page /blog/my-post + * getFullSlug(window) // "blog/my-post" + */ +export function getFullSlug(window: Window): FullSlug { + const res = window.document.body.dataset.slug! as FullSlug; + return res; +} + +/** + * Gets the current page's full slug from window.location.pathname. + * Use this when document.body.dataset.slug is not available (e.g., in inline scripts). + * @returns The full slug derived from the URL pathname + * + * @example + * // On URL /blog/my-post/ + * getFullSlugFromUrl() // "blog/my-post" + */ +export function getFullSlugFromUrl(): FullSlug { + let rawSlug = window.location.pathname; + if (rawSlug.endsWith("/")) rawSlug = rawSlug.slice(0, -1); + if (rawSlug.startsWith("/")) rawSlug = rawSlug.slice(1); + return rawSlug as FullSlug; +} + +/** + * Joins path segments together, handling slashes properly. + * @param args - Path segments to join + * @returns The joined path + * + * @example + * joinSegments("a", "b", "c") // "a/b/c" + * joinSegments("/a/", "/b/", "c") // "/a/b/c" + * joinSegments("a", "", "c") // "a/c" + */ +export function joinSegments(...args: string[]): string { + if (args.length === 0) { + return ""; + } + + let joined = args + .filter((segment) => segment !== "" && segment !== "/") + .map((segment) => stripSlashes(segment)) + .join("/"); + + const first = args[0]; + const last = args[args.length - 1]; + + if (first?.startsWith("/")) { + joined = "/" + joined; + } + + if (last?.endsWith("/")) { + joined = joined + "/"; + } + + return joined; +} + +/** + * Resolves a path, ensuring it starts with a slash for absolute navigation. + * @param to - The target path + * @returns The resolved absolute path + * + * @example + * resolvePath("blog/post") // "/blog/post" + * resolvePath("/already-absolute") // "/already-absolute" + */ +export function resolvePath(to: string): string { + if (to.startsWith("/")) return to; + return "/" + to; +} + +/** + * Checks if a string ends with a given suffix, accounting for path separators. + * @param s - The string to check + * @param suffix - The suffix to look for + * @returns True if the string ends with the suffix + * + * @example + * endsWith("folder/index", "index") // true + * endsWith("index", "index") // true + * endsWith("myindex", "index") // false + */ +export function endsWith(s: string, suffix: string): boolean { + return s === suffix || s.endsWith("/" + suffix); +} + +/** + * Removes a suffix from a string if it ends with that suffix (respecting path separators). + * @param s - The string to trim + * @param suffix - The suffix to remove + * @returns The trimmed string + * + * @example + * trimSuffix("folder/index", "index") // "folder/" + * trimSuffix("page", "index") // "page" + */ +export function trimSuffix(s: string, suffix: string): string { + if (endsWith(s, suffix)) { + s = s.slice(0, -suffix.length); + } + return s; +} + +/** + * Strips leading and/or trailing slashes from a string. + * @param s - The string to strip + * @param onlyStripPrefix - If true, only strip leading slash + * @returns The stripped string + * + * @example + * stripSlashes("/path/to/file/") // "path/to/file" + * stripSlashes("/path/", true) // "path/" + */ +export function stripSlashes(s: string, onlyStripPrefix?: boolean): string { + if (s.startsWith("/")) { + s = s.substring(1); + } + + if (!onlyStripPrefix && s.endsWith("/")) { + s = s.slice(0, -1); + } + + return s; +} + +/** + * Gets the file extension from a path. + * @param s - The path string + * @returns The file extension including the dot, or undefined if none + * + * @example + * getFileExtension("file.md") // ".md" + * getFileExtension("file") // undefined + */ +export function getFileExtension(s: string): string | undefined { + return s.match(/\.[A-Za-z0-9]+$/)?.[0]; +} + +/** + * Checks if a path represents a folder (ends with /, index, index.md, or index.html). + * @param fplike - The path-like string to check + * @returns True if the path represents a folder + * + * @example + * isFolderPath("folder/") // true + * isFolderPath("folder/index") // true + * isFolderPath("file.md") // false + */ +export function isFolderPath(fplike: string): boolean { + return ( + fplike.endsWith("/") || + endsWith(fplike, "index") || + endsWith(fplike, "index.md") || + endsWith(fplike, "index.html") + ); +} + +/** + * Gets all segment prefixes for a path (useful for tags/breadcrumbs). + * @param path - The path string (e.g., "a/b/c") + * @returns Array of all prefixes (e.g., ["a", "a/b", "a/b/c"]) + * + * @example + * getAllSegmentPrefixes("programming/web/react") // ["programming", "programming/web", "programming/web/react"] + */ +export function getAllSegmentPrefixes(path: string): string[] { + const segments = path.split("/"); + const results: string[] = []; + for (let i = 0; i < segments.length; i++) { + results.push(segments.slice(0, i + 1).join("/")); + } + return results; +} diff --git a/src/transformer.ts b/src/transformer.ts deleted file mode 100644 index 4fb8207..0000000 --- a/src/transformer.ts +++ /dev/null @@ -1,104 +0,0 @@ -import type { PluggableList, Plugin } from "unified"; -import type { Root as MdastRoot } from "mdast"; -import type { Root as HastRoot, Element } from "hast"; -import type { VFile } from "vfile"; -import remarkGfm from "remark-gfm"; -import rehypeSlug from "rehype-slug"; -import { findAndReplace } from "mdast-util-find-and-replace"; -import { visit } from "unist-util-visit"; -import type { QuartzTransformerPlugin } from "@jackyzha0/quartz/plugins/types"; -import type { BuildCtx } from "@jackyzha0/quartz/util/ctx"; -import type { ExampleTransformerOptions } from "./types"; - -const defaultOptions: ExampleTransformerOptions = { - highlightToken: "==", - headingClass: "example-plugin-heading", - enableGfm: true, - addHeadingSlugs: true, -}; - -const escapeRegExp = (value: string) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); - -const remarkHighlightToken = (token: string): Plugin<[], MdastRoot> => { - const escapedToken = escapeRegExp(token); - const pattern = new RegExp(`${escapedToken}([^\n]+?)${escapedToken}`, "g"); - return () => (tree: MdastRoot, _file: VFile) => { - findAndReplace(tree, [ - [ - pattern, - (_match: string, value: string) => ({ - type: "strong", - children: [{ type: "text", value }], - }), - ], - ]); - }; -}; - -const rehypeHeadingClass = (className: string): Plugin<[], HastRoot> => { - return () => (tree: HastRoot, _file: VFile) => { - visit(tree, "element", (node: Element) => { - if (!/^h[1-6]$/.test(node.tagName)) { - return; - } - - const existing = node.properties?.className; - const classes: string[] = Array.isArray(existing) - ? existing.filter((value): value is string => typeof value === "string") - : typeof existing === "string" - ? [existing] - : []; - node.properties = { - ...node.properties, - className: [...classes, className], - }; - }); - }; -}; - -/** - * Example transformer showing remark/rehype usage and resource injection. - */ -export const ExampleTransformer: QuartzTransformerPlugin> = ( - userOptions?: Partial, -) => { - const options = { ...defaultOptions, ...userOptions }; - return { - name: "ExampleTransformer", - textTransform(_ctx: BuildCtx, src: string) { - return src.endsWith("\n") ? src : `${src}\n`; - }, - markdownPlugins(): PluggableList { - const plugins: PluggableList = [remarkHighlightToken(options.highlightToken)]; - if (options.enableGfm) { - plugins.unshift(remarkGfm); - } - return plugins; - }, - htmlPlugins(): PluggableList { - const plugins: PluggableList = [rehypeHeadingClass(options.headingClass)]; - if (options.addHeadingSlugs) { - plugins.unshift(rehypeSlug); - } - return plugins; - }, - externalResources() { - return { - css: [ - { - content: `.${options.headingClass} { letter-spacing: 0.02em; }`, - inline: true, - }, - ], - js: [ - { - contentType: "inline", - loadTime: "afterDOMReady", - script: "document.documentElement.dataset.exampleTransformer = 'true'", - }, - ], - additionalHead: [], - }; - }, - }; -}; diff --git a/src/types.ts b/src/types.ts deleted file mode 100644 index f20f880..0000000 --- a/src/types.ts +++ /dev/null @@ -1,54 +0,0 @@ -export type { - ChangeEvent, - QuartzEmitterPlugin, - QuartzEmitterPluginInstance, - QuartzFilterPlugin, - QuartzFilterPluginInstance, - QuartzTransformerPlugin, - QuartzTransformerPluginInstance, -} from "@jackyzha0/quartz/plugins/types"; -export type { ProcessedContent, QuartzPluginData } from "@jackyzha0/quartz/plugins/vfile"; -export type { BuildCtx } from "@jackyzha0/quartz/util/ctx"; -export type { CSSResource, JSResource, StaticResources } from "@jackyzha0/quartz/util/resources"; - -export interface ExampleTransformerOptions { - /** Token used to highlight text, defaults to ==highlight== */ - highlightToken: string; - /** Add a CSS class to all headings in the rendered HTML. */ - headingClass: string; - /** Enable remark-gfm for tables/task lists. */ - enableGfm: boolean; - /** Enable adding slug IDs to headings. */ - addHeadingSlugs: boolean; -} - -export interface ExampleFilterOptions { - /** Allow pages marked draft: true to publish. */ - allowDrafts: boolean; - /** Exclude pages that contain any of these frontmatter tags. */ - excludeTags: string[]; - /** Exclude paths that start with any of these prefixes (relative to content root). */ - excludePathPrefixes: string[]; -} - -export interface ExampleEmitterOptions { - /** Filename to emit at the site root. */ - manifestSlug: string; - /** Whether to include the frontmatter block in the manifest. */ - includeFrontmatter: boolean; - /** Extra metadata to write at the top level of the manifest. */ - metadata: Record; - /** Optional hook to transform the emitted manifest JSON string. */ - transformManifest?: (json: string) => string; - /** Add a custom class to the emitted manifest