diff --git a/TODO.md b/TODO.md
new file mode 100644
index 0000000..ed6ffae
--- /dev/null
+++ b/TODO.md
@@ -0,0 +1,14 @@
+## Providers
+- [ ] google
+- [ ] bunny
+- [ ] fontshare
+- [ ] font-source?
+- [ ] custom
+- [ ] (public)
+
+## Features
+
+- zero-configuration required
+- automatic font metric optimisation powered by https://github.com/unjs/fontaine
+- built-in providers (`google`, `bunny`, `local` and more)
+- custom providers for full control
diff --git a/build.config.ts b/build.config.ts
new file mode 100644
index 0000000..5226c94
--- /dev/null
+++ b/build.config.ts
@@ -0,0 +1,4 @@
+import { defineBuildConfig } from 'unbuild'
+export default defineBuildConfig({
+ externals: ['css-tree', '#types']
+})
diff --git a/package.json b/package.json
index c74f15c..09a4c27 100644
--- a/package.json
+++ b/package.json
@@ -21,7 +21,7 @@
"prepack": "nuxt-module-build",
"dev": "nuxi dev playground",
"dev:build": "nuxi build playground",
- "dev:prepare": "nuxt-module-build --stub && nuxt-module-build prepare && nuxi prepare playground",
+ "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground",
"release": "npm run lint && npm run test && npm run prepack && changelogen --release && npm publish && git push --follow-tags",
"lint": "eslint .",
"test": "vitest run",
@@ -30,7 +30,14 @@
},
"dependencies": {
"@nuxt/kit": "^3.10.2",
- "fontaine": "^0.4.1"
+ "csstree": "^0.0.3",
+ "defu": "^6.1.4",
+ "fontaine": "^0.4.1",
+ "globby": "^14.0.1",
+ "magic-string": "^0.30.7",
+ "pathe": "^1.1.2",
+ "ufo": "^1.4.0",
+ "unplugin": "^1.7.1"
},
"devDependencies": {
"@nuxt/devtools": "latest",
@@ -38,10 +45,12 @@
"@nuxt/module-builder": "^0.5.5",
"@nuxt/schema": "^3.10.2",
"@nuxt/test-utils": "^3.11.0",
+ "@types/css-tree": "^2.3.6",
"@vitest/coverage-v8": "^1.3.0",
"changelogen": "^0.5.5",
"eslint": "^8.56.0",
"typescript": "^5.3.3",
+ "unbuild": "^2.0.0",
"vitest": "^1.3.0",
"vue-tsc": "^1.8.27"
},
diff --git a/playground/app.vue b/playground/app.vue
index bc0bfa7..6947306 100644
--- a/playground/app.vue
+++ b/playground/app.vue
@@ -3,3 +3,12 @@
Nuxt module playground!
+
+
diff --git a/playground/assets/test.css b/playground/assets/test.css
new file mode 100644
index 0000000..71b5f34
--- /dev/null
+++ b/playground/assets/test.css
@@ -0,0 +1,3 @@
+:root {
+ font-family: 'Roboto', sans-serif;
+}
diff --git a/playground/nuxt.config.ts b/playground/nuxt.config.ts
index 5f53c66..46999c6 100644
--- a/playground/nuxt.config.ts
+++ b/playground/nuxt.config.ts
@@ -1,5 +1,29 @@
export default defineNuxtConfig({
devtools: { enabled: true },
- modules: ['@nuxt/fonts'],
- fonts: {},
+ modules: [
+ '@nuxt/fonts',
+ // '@nuxtjs/tailwindcss'
+ ],
+ fonts: {
+ providers: {
+ google: false
+ }
+ // provider: 'google', // sets default provider
+ // families: [
+ // {
+ // name: 'Roboto', // the 'canonical' name of the font used to look it up in a provider database
+ // as: 'custom-roboto-family', // allow registering a font family with a different name
+ // provider: 'local', // you can override the provider on a per-family basis
+ // // provider specific options can be provided
+ // src: '~/public/roboto.woff2', // you can specify a source within your project
+ // // specific configuration will be used to generate `@font-face` definitions
+ // subsets: ['latin', 'greek'],
+ // display: 'swap', // or 'block'7
+ // weight: ['400', '700'],
+ // style: ['normal', 'italic'],
+ // // and produce CSS overrides to reduce layout shift (using fontaine)
+ // fallbacks: ['Arial'],
+ // }
+ // ]
+ }
})
diff --git a/playground/package.json b/playground/package.json
index da7c4bd..af02c36 100644
--- a/playground/package.json
+++ b/playground/package.json
@@ -9,6 +9,7 @@
},
"dependencies": {
"@nuxt/fonts": "latest",
+ "@nuxtjs/tailwindcss": "latest",
"nuxt": "latest",
"vue": "latest"
}
diff --git a/playground/public/roboto.woff2 b/playground/public/roboto.woff2
new file mode 100644
index 0000000..b65a361
Binary files /dev/null and b/playground/public/roboto.woff2 differ
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 8e91907..c691228 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -14,9 +14,30 @@ importers:
'@nuxt/kit':
specifier: ^3.10.2
version: 3.10.2(rollup@3.29.4)
+ csstree:
+ specifier: ^0.0.3
+ version: 0.0.3
+ defu:
+ specifier: ^6.1.4
+ version: 6.1.4
fontaine:
specifier: ^0.4.1
version: 0.4.1
+ globby:
+ specifier: ^14.0.1
+ version: 14.0.1
+ magic-string:
+ specifier: ^0.30.7
+ version: 0.30.7
+ pathe:
+ specifier: ^1.1.2
+ version: 1.1.2
+ ufo:
+ specifier: ^1.4.0
+ version: 1.4.0
+ unplugin:
+ specifier: ^1.7.1
+ version: 1.7.1
devDependencies:
'@nuxt/devtools':
specifier: latest
@@ -33,6 +54,9 @@ importers:
'@nuxt/test-utils':
specifier: ^3.11.0
version: 3.11.0(h3@1.10.1)(rollup@3.29.4)(vite@4.4.2)(vitest@1.3.0)(vue-router@4.2.5)(vue@3.4.19)
+ '@types/css-tree':
+ specifier: ^2.3.6
+ version: 2.3.6
'@vitest/coverage-v8':
specifier: ^1.3.0
version: 1.3.0(vitest@1.3.0)
@@ -45,6 +69,9 @@ importers:
typescript:
specifier: ^5.3.3
version: 5.3.3
+ unbuild:
+ specifier: ^2.0.0
+ version: 2.0.0(typescript@5.3.3)
vitest:
specifier: ^1.3.0
version: 1.3.0
@@ -57,6 +84,9 @@ importers:
'@nuxt/fonts':
specifier: workspace:*
version: link:..
+ '@nuxtjs/tailwindcss':
+ specifier: latest
+ version: 6.11.4(rollup@3.29.4)
nuxt:
specifier: latest
version: 3.10.2(eslint@8.56.0)(rollup@3.29.4)(typescript@5.3.3)(vite@5.1.1)(vue-tsc@1.8.27)
@@ -70,6 +100,11 @@ packages:
resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==}
engines: {node: '>=0.10.0'}
+ /@alloc/quick-lru@5.2.0:
+ resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
+ engines: {node: '>=10'}
+ dev: false
+
/@ampproject/remapping@2.2.1:
resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==}
engines: {node: '>=6.0.0'}
@@ -652,6 +687,49 @@ packages:
dependencies:
mime: 3.0.0
+ /@csstools/cascade-layer-name-parser@1.0.8(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3):
+ resolution: {integrity: sha512-xHxXavWvXB5nAA9IvZtjEzkONM3hPXpxqYK4cEw60LcqPiFjq7ZlEFxOyYFPrG4UdANKtnucNtRVDy7frjq6AA==}
+ engines: {node: ^14 || ^16 || >=18}
+ peerDependencies:
+ '@csstools/css-parser-algorithms': ^2.6.0
+ '@csstools/css-tokenizer': ^2.2.3
+ dependencies:
+ '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3)
+ '@csstools/css-tokenizer': 2.2.3
+ dev: false
+
+ /@csstools/css-parser-algorithms@2.6.0(@csstools/css-tokenizer@2.2.3):
+ resolution: {integrity: sha512-YfEHq0eRH98ffb5/EsrrDspVWAuph6gDggAE74ZtjecsmyyWpW768hOyiONa8zwWGbIWYfa2Xp4tRTrpQQ00CQ==}
+ engines: {node: ^14 || ^16 || >=18}
+ peerDependencies:
+ '@csstools/css-tokenizer': ^2.2.3
+ dependencies:
+ '@csstools/css-tokenizer': 2.2.3
+ dev: false
+
+ /@csstools/css-tokenizer@2.2.3:
+ resolution: {integrity: sha512-pp//EvZ9dUmGuGtG1p+n17gTHEOqu9jO+FiCUjNN3BDmyhdA2Jq9QsVeR7K8/2QCK17HSsioPlTW9ZkzoWb3Lg==}
+ engines: {node: ^14 || ^16 || >=18}
+ dev: false
+
+ /@csstools/selector-specificity@3.0.2(postcss-selector-parser@6.0.15):
+ resolution: {integrity: sha512-RpHaZ1h9LE7aALeQXmXrJkRG84ZxIsctEN2biEUmFyKpzFM3zZ35eUMcIzZFsw/2olQE6v69+esEqU2f1MKycg==}
+ engines: {node: ^14 || ^16 || >=18}
+ peerDependencies:
+ postcss-selector-parser: ^6.0.13
+ dependencies:
+ postcss-selector-parser: 6.0.15
+ dev: false
+
+ /@csstools/utilities@1.0.0(postcss@8.4.35):
+ resolution: {integrity: sha512-tAgvZQe/t2mlvpNosA4+CkMiZ2azISW5WPAcdSalZlEjQvUfghHxfQcrCiK/7/CrfAWVxyM88kGFYO82heIGDg==}
+ engines: {node: ^14 || ^16 || >=18}
+ peerDependencies:
+ postcss: ^8.4
+ dependencies:
+ postcss: 8.4.35
+ dev: false
+
/@esbuild-kit/cjs-loader@2.4.2:
resolution: {integrity: sha512-BDXFbYOJzT/NBEtp71cvsrGPwGAMGRB/349rwKuoxNSiKjPraNNnlK6MIIabViCjqZugu6j+xeMDlEkWdHHJSg==}
dependencies:
@@ -1561,6 +1639,19 @@ packages:
'@jridgewell/resolve-uri': 3.1.0
'@jridgewell/sourcemap-codec': 1.4.14
+ /@koa/router@12.0.1:
+ resolution: {integrity: sha512-ribfPYfHb+Uw3b27Eiw6NPqjhIhTpVFzEWLwyc/1Xp+DCdwRRyIlAUODX+9bPARF6aQtUu1+/PHzdNvRzcs/+Q==}
+ engines: {node: '>= 12'}
+ dependencies:
+ debug: 4.3.4
+ http-errors: 2.0.0
+ koa-compose: 4.1.0
+ methods: 1.1.2
+ path-to-regexp: 6.2.1
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
/@kwsites/file-exists@1.1.1:
resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==}
dependencies:
@@ -1802,7 +1893,7 @@ packages:
execa: 7.1.1
global-dirs: 3.0.1
magicast: 0.2.9
- pathe: 1.1.1
+ pathe: 1.1.2
picocolors: 1.0.0
pkg-types: 1.0.3
prompts: 2.4.2
@@ -1853,7 +1944,7 @@ packages:
nuxt: 3.10.2(eslint@8.56.0)(rollup@3.29.4)(typescript@5.3.3)(vite@4.4.2)(vue-tsc@1.8.27)
nypm: 0.2.2
pacote: 15.2.0
- pathe: 1.1.1
+ pathe: 1.1.2
perfect-debounce: 1.0.0
picocolors: 1.0.0
pkg-types: 1.0.3
@@ -2216,6 +2307,30 @@ packages:
- vti
- vue-tsc
+ /@nuxtjs/tailwindcss@6.11.4(rollup@3.29.4):
+ resolution: {integrity: sha512-09cksgZD4seQj054Z/BeiwFg1bzQTol8KPulLDLGnmMTkEi21vj/z+WlXQRpVbN1GS9+oU9tcSsu2ufXCM3DBg==}
+ dependencies:
+ '@nuxt/kit': 3.10.2(rollup@3.29.4)
+ autoprefixer: 10.4.17(postcss@8.4.35)
+ chokidar: 3.6.0
+ clear-module: 4.1.2
+ consola: 3.2.3
+ defu: 6.1.4
+ h3: 1.10.1
+ micromatch: 4.0.5
+ pathe: 1.1.2
+ postcss: 8.4.35
+ postcss-custom-properties: 13.3.5(postcss@8.4.35)
+ postcss-nesting: 12.0.3(postcss@8.4.35)
+ tailwind-config-viewer: 1.7.3(tailwindcss@3.4.1)
+ tailwindcss: 3.4.1
+ ufo: 1.4.0
+ transitivePeerDependencies:
+ - rollup
+ - supports-color
+ - ts-node
+ dev: false
+
/@parcel/watcher-android-arm64@2.4.0:
resolution: {integrity: sha512-+fPtO/GsbYX1LJnCYCaDVT3EOBjvSFdQN9Mrzh9zWAOOfvidPWyScTrHIZHHfJBvlHzNA0Gy0U3NXFA/M7PHUA==}
engines: {node: '>= 10.0.0'}
@@ -2812,6 +2927,10 @@ packages:
'@tufjs/canonical-json': 2.0.0
minimatch: 9.0.3
+ /@types/css-tree@2.3.6:
+ resolution: {integrity: sha512-TMZiGQ0PzBDlOLQ4qVz8+GGVhVGAPqMAHbXxDkmxjTexB/4rWeeK8N3IvdJXmR3lvio2MYnnn72DzgnHYu9mSA==}
+ dev: true
+
/@types/estree@1.0.1:
resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==}
@@ -3304,6 +3423,14 @@ packages:
resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+ /accepts@1.3.8:
+ resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==}
+ engines: {node: '>= 0.6'}
+ dependencies:
+ mime-types: 2.1.35
+ negotiator: 0.6.3
+ dev: false
+
/acorn-jsx@5.3.2(acorn@8.10.0):
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
peerDependencies:
@@ -3414,6 +3541,10 @@ packages:
resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
engines: {node: '>=12'}
+ /any-promise@1.3.0:
+ resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
+ dev: false
+
/anymatch@3.1.3:
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
engines: {node: '>= 8'}
@@ -3462,6 +3593,10 @@ packages:
readable-stream: 3.6.2
dev: true
+ /arg@5.0.2:
+ resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
+ dev: false
+
/argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
@@ -3522,6 +3657,12 @@ packages:
/async-sema@3.1.1:
resolution: {integrity: sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==}
+ /async@2.6.4:
+ resolution: {integrity: sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==}
+ dependencies:
+ lodash: 4.17.21
+ dev: false
+
/async@3.2.4:
resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==}
@@ -3529,6 +3670,11 @@ packages:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
dev: true
+ /at-least-node@1.0.0:
+ resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==}
+ engines: {node: '>= 4.0.0'}
+ dev: false
+
/autoprefixer@10.4.17(postcss@8.4.35):
resolution: {integrity: sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==}
engines: {node: ^10 || ^12 || >=14}
@@ -3726,13 +3872,13 @@ packages:
resolution: {integrity: sha512-3IP/MuamSVRVw8W8+CHWAz9gKN4gd+voF2zm/Ln6D25C2RhytEZ1ABbC8MjKr4BR9rhoV1JQ7jJA158LDiTkLg==}
dependencies:
chokidar: 3.5.3
- defu: 6.1.2
+ defu: 6.1.4
dotenv: 16.3.1
giget: 1.1.2
jiti: 1.19.1
mlly: 1.4.0
ohash: 1.1.2
- pathe: 1.1.1
+ pathe: 1.1.2
perfect-debounce: 1.0.0
pkg-types: 1.0.3
rc9: 2.1.1
@@ -3796,6 +3942,14 @@ packages:
tar: 6.1.15
unique-filename: 3.0.0
+ /cache-content-type@1.0.1:
+ resolution: {integrity: sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==}
+ engines: {node: '>= 6.0.0'}
+ dependencies:
+ mime-types: 2.1.35
+ ylru: 1.3.2
+ dev: false
+
/call-bind@1.0.2:
resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==}
dependencies:
@@ -3807,6 +3961,11 @@ packages:
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
engines: {node: '>=6'}
+ /camelcase-css@2.0.1:
+ resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
+ engines: {node: '>= 6'}
+ dev: false
+
/camelcase@6.3.0:
resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
engines: {node: '>=10'}
@@ -3876,7 +4035,7 @@ packages:
node-fetch-native: 1.2.0
ofetch: 1.1.1
open: 9.1.0
- pathe: 1.1.1
+ pathe: 1.1.2
pkg-types: 1.0.3
scule: 1.0.0
semver: 7.6.0
@@ -3937,6 +4096,14 @@ packages:
resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==}
engines: {node: '>=6'}
+ /clear-module@4.1.2:
+ resolution: {integrity: sha512-LWAxzHqdHsAZlPlEyJ2Poz6AIs384mPeqLVCru2p0BrP9G/kVGuhNyZYClLO6cXlnuJjzC8xtsJIuMjKqLXoAw==}
+ engines: {node: '>=8'}
+ dependencies:
+ parent-module: 2.0.0
+ resolve-from: 5.0.0
+ dev: false
+
/clear@0.1.0:
resolution: {integrity: sha512-qMjRnoL+JDPJHeLePZJuao6+8orzHMGP04A8CdwCNsKhRbOnKRjefxONR7bwILT3MHecxKBjHkKL/tkZ8r4Uzw==}
@@ -3970,6 +4137,11 @@ packages:
resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==}
engines: {node: '>=0.10.0'}
+ /co@4.6.0:
+ resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==}
+ engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'}
+ dev: false
+
/color-convert@1.9.3:
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
requiresBuild: true
@@ -4010,6 +4182,16 @@ packages:
/commander@2.20.3:
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
+ /commander@4.1.1:
+ resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
+ engines: {node: '>= 6'}
+ dev: false
+
+ /commander@6.2.1:
+ resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==}
+ engines: {node: '>= 6'}
+ dev: false
+
/commander@7.2.0:
resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==}
engines: {node: '>= 10'}
@@ -4043,6 +4225,18 @@ packages:
/console-control-strings@1.1.0:
resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==}
+ /content-disposition@0.5.4:
+ resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==}
+ engines: {node: '>= 0.6'}
+ dependencies:
+ safe-buffer: 5.2.1
+ dev: false
+
+ /content-type@1.0.5:
+ resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==}
+ engines: {node: '>= 0.6'}
+ dev: false
+
/convert-gitmoji@0.1.3:
resolution: {integrity: sha512-t5yxPyI8h8KPvRwrS/sRrfIpT2gJbmBAY0TFokyUBy3PM44RuFRpZwHdACz+GTSPLRLo3s4qsscOMLjHiXBwzw==}
dev: true
@@ -4057,6 +4251,14 @@ packages:
/cookie-es@1.0.0:
resolution: {integrity: sha512-mWYvfOLrfEc996hlKcdABeIiPHUPC6DM2QYZdGGOvhOTbA3tjm2eBwqlJpoFdjC89NI4Qt6h0Pu06Mp+1Pj5OQ==}
+ /cookies@0.9.1:
+ resolution: {integrity: sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==}
+ engines: {node: '>= 0.8'}
+ dependencies:
+ depd: 2.0.0
+ keygrip: 1.1.0
+ dev: false
+
/core-util-is@1.0.3:
resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
@@ -4195,6 +4397,14 @@ packages:
dependencies:
css-tree: 2.2.1
+ /csstree@0.0.3:
+ resolution: {integrity: sha512-xs+bw0WIYtl88NrtDMS8QNTSCxYXmIpuuR9Fq/o/8T+CMm0ONxQIUS7liXcWoqZlCBXiNf4YOXHcXvAXyYVY7g==}
+ engines: {node: '>=0.8'}
+ requiresBuild: true
+ dependencies:
+ string-iterator: 0.0.1
+ dev: false
+
/csstype@3.1.3:
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
@@ -4211,6 +4421,17 @@ packages:
dependencies:
ms: 2.0.0
+ /debug@3.2.7:
+ resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+ dependencies:
+ ms: 2.1.3
+ dev: false
+
/debug@4.3.4:
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
engines: {node: '>=6.0'}
@@ -4282,6 +4503,10 @@ packages:
type-detect: 4.0.8
dev: true
+ /deep-equal@1.0.1:
+ resolution: {integrity: sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==}
+ dev: false
+
/deep-is@0.1.4:
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
@@ -4334,9 +4559,6 @@ packages:
object-keys: 1.1.1
dev: true
- /defu@6.1.2:
- resolution: {integrity: sha512-+uO4+qr7msjNNWKYPHqN/3+Dx3NFkmIzayk2L1MyZQlvgZb/J1A0fo410dpKrN2SnqFjt8n4JL8fDJE0wIgjFQ==}
-
/defu@6.1.4:
resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
@@ -4352,6 +4574,11 @@ packages:
resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==}
engines: {node: '>=0.10'}
+ /depd@1.1.2:
+ resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==}
+ engines: {node: '>= 0.6'}
+ dev: false
+
/depd@2.0.0:
resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
engines: {node: '>= 0.8'}
@@ -4382,6 +4609,10 @@ packages:
resolution: {integrity: sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==}
dev: false
+ /didyoumean@1.2.2:
+ resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
+ dev: false
+
/diff-sequences@29.6.3:
resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -4398,6 +4629,10 @@ packages:
path-type: 4.0.0
dev: true
+ /dlv@1.1.3:
+ resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
+ dev: false
+
/doctrine@3.0.0:
resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
engines: {node: '>=6.0.0'}
@@ -4975,10 +5210,10 @@ packages:
'@capsizecss/metrics': 1.3.0
'@capsizecss/unpack': 1.0.0
magic-regexp: 0.7.0
- magic-string: 0.30.1
- pathe: 1.1.1
- ufo: 1.1.2
- unplugin: 1.3.2
+ magic-string: 0.30.7
+ pathe: 1.1.2
+ ufo: 1.4.0
+ unplugin: 1.7.1
transitivePeerDependencies:
- encoding
dev: false
@@ -5047,6 +5282,16 @@ packages:
jsonfile: 6.1.0
universalify: 2.0.0
+ /fs-extra@9.1.0:
+ resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==}
+ engines: {node: '>=10'}
+ dependencies:
+ at-least-node: 1.0.0
+ graceful-fs: 4.2.11
+ jsonfile: 6.1.0
+ universalify: 2.0.0
+ dev: false
+
/fs-minipass@2.1.0:
resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==}
engines: {node: '>= 8'}
@@ -5155,11 +5400,11 @@ packages:
hasBin: true
dependencies:
colorette: 2.0.20
- defu: 6.1.2
+ defu: 6.1.4
https-proxy-agent: 5.0.1
mri: 1.2.0
node-fetch-native: 1.2.0
- pathe: 1.1.1
+ pathe: 1.1.2
tar: 6.1.15
transitivePeerDependencies:
- supports-color
@@ -5299,7 +5544,7 @@ packages:
dependencies:
'@sindresorhus/merge-streams': 2.2.1
fast-glob: 3.3.2
- ignore: 5.2.4
+ ignore: 5.3.1
path-type: 5.0.0
slash: 5.1.0
unicorn-magic: 0.1.0
@@ -5339,11 +5584,11 @@ packages:
resolution: {integrity: sha512-A9V2NEDNHet7v1gCg7CMwerSigLi0SRbhTy7C3lGb0N4YKIpPmLDjedTUopqp4dnn7COHfqUjjaz3zbtz4QduA==}
dependencies:
cookie-es: 1.0.0
- defu: 6.1.2
+ defu: 6.1.4
destr: 2.0.0
iron-webcrypto: 0.7.1
radix3: 1.0.1
- ufo: 1.1.2
+ ufo: 1.4.0
uncrypto: 0.1.3
dev: true
@@ -5370,14 +5615,12 @@ packages:
/has-symbols@1.0.3:
resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==}
engines: {node: '>= 0.4'}
- dev: true
/has-tostringtag@1.0.0:
resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==}
engines: {node: '>= 0.4'}
dependencies:
has-symbols: 1.0.3
- dev: true
/has-unicode@2.0.1:
resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==}
@@ -5419,9 +5662,38 @@ packages:
resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==}
engines: {node: '>=8'}
+ /http-assert@1.5.0:
+ resolution: {integrity: sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==}
+ engines: {node: '>= 0.8'}
+ dependencies:
+ deep-equal: 1.0.1
+ http-errors: 1.8.1
+ dev: false
+
/http-cache-semantics@4.1.1:
resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==}
+ /http-errors@1.6.3:
+ resolution: {integrity: sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==}
+ engines: {node: '>= 0.6'}
+ dependencies:
+ depd: 1.1.2
+ inherits: 2.0.3
+ setprototypeof: 1.1.0
+ statuses: 1.5.0
+ dev: false
+
+ /http-errors@1.8.1:
+ resolution: {integrity: sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==}
+ engines: {node: '>= 0.6'}
+ dependencies:
+ depd: 1.1.2
+ inherits: 2.0.4
+ setprototypeof: 1.2.0
+ statuses: 1.5.0
+ toidentifier: 1.0.1
+ dev: false
+
/http-errors@2.0.0:
resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==}
engines: {node: '>= 0.8'}
@@ -5568,6 +5840,10 @@ packages:
once: 1.4.0
wrappy: 1.0.2
+ /inherits@2.0.3:
+ resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==}
+ dev: false
+
/inherits@2.0.4:
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
@@ -5662,7 +5938,6 @@ packages:
engines: {node: '>= 0.4'}
dependencies:
has-tostringtag: 1.0.0
- dev: true
/is-glob@4.0.3:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
@@ -5907,6 +6182,13 @@ packages:
resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==}
engines: {'0': node >= 0.2.0}
+ /keygrip@1.1.0:
+ resolution: {integrity: sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==}
+ engines: {node: '>= 0.6'}
+ dependencies:
+ tsscmp: 1.0.6
+ dev: false
+
/kleur@3.0.3:
resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==}
engines: {node: '>=6'}
@@ -5918,6 +6200,70 @@ packages:
/knitwork@1.0.0:
resolution: {integrity: sha512-dWl0Dbjm6Xm+kDxhPQJsCBTxrJzuGl0aP9rhr+TG8D3l+GL90N8O8lYUi7dTSAN2uuDqCtNgb6aEuQH5wsiV8Q==}
+ /koa-compose@4.1.0:
+ resolution: {integrity: sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==}
+ dev: false
+
+ /koa-convert@2.0.0:
+ resolution: {integrity: sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA==}
+ engines: {node: '>= 10'}
+ dependencies:
+ co: 4.6.0
+ koa-compose: 4.1.0
+ dev: false
+
+ /koa-send@5.0.1:
+ resolution: {integrity: sha512-tmcyQ/wXXuxpDxyNXv5yNNkdAMdFRqwtegBXUaowiQzUKqJehttS0x2j0eOZDQAyloAth5w6wwBImnFzkUz3pQ==}
+ engines: {node: '>= 8'}
+ dependencies:
+ debug: 4.3.4
+ http-errors: 1.8.1
+ resolve-path: 1.4.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
+ /koa-static@5.0.0:
+ resolution: {integrity: sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ==}
+ engines: {node: '>= 7.6.0'}
+ dependencies:
+ debug: 3.2.7
+ koa-send: 5.0.1
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
+ /koa@2.15.0:
+ resolution: {integrity: sha512-KEL/vU1knsoUvfP4MC4/GthpQrY/p6dzwaaGI6Rt4NQuFqkw3qrvsdYF5pz3wOfi7IGTvMPHC9aZIcUKYFNxsw==}
+ engines: {node: ^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4}
+ dependencies:
+ accepts: 1.3.8
+ cache-content-type: 1.0.1
+ content-disposition: 0.5.4
+ content-type: 1.0.5
+ cookies: 0.9.1
+ debug: 4.3.4
+ delegates: 1.0.0
+ depd: 2.0.0
+ destroy: 1.2.0
+ encodeurl: 1.0.2
+ escape-html: 1.0.3
+ fresh: 0.5.2
+ http-assert: 1.5.0
+ http-errors: 1.8.1
+ is-generator-function: 1.0.10
+ koa-compose: 4.1.0
+ koa-convert: 2.0.0
+ on-finished: 2.4.1
+ only: 0.0.2
+ parseurl: 1.3.3
+ statuses: 1.5.0
+ type-is: 1.6.18
+ vary: 1.1.2
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
/kolorist@1.8.0:
resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==}
@@ -5947,10 +6293,19 @@ packages:
prelude-ls: 1.2.1
type-check: 0.4.0
+ /lilconfig@2.1.0:
+ resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==}
+ engines: {node: '>=10'}
+ dev: false
+
/lilconfig@3.1.1:
resolution: {integrity: sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==}
engines: {node: '>=14'}
+ /lines-and-columns@1.2.4:
+ resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
+ dev: false
+
/listhen@1.6.0:
resolution: {integrity: sha512-z0RcEXVX5oTpY1bO02SKoTU/kmZSrFSngNNzHRM6KICR17PTq7ANush6AE6ztGJwJD4RLpBrVHd9GnV51J7s3w==}
hasBin: true
@@ -6050,11 +6405,11 @@ packages:
resolution: {integrity: sha512-C9m5/JqFV1/CMrMFDf1PqmvMc8ohrssmlF5bdgea7nUqqn6D9xzKVTa6DIm0LReCqvEPS35o1UElmb7PmoSfHQ==}
dependencies:
estree-walker: 3.0.3
- magic-string: 0.30.1
+ magic-string: 0.30.7
mlly: 1.4.0
type-level-regexp: 0.1.17
- ufo: 1.1.2
- unplugin: 1.3.2
+ ufo: 1.4.0
+ unplugin: 1.7.1
dev: false
/magic-string-ast@0.3.0:
@@ -6063,12 +6418,6 @@ packages:
dependencies:
magic-string: 0.30.7
- /magic-string@0.30.1:
- resolution: {integrity: sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==}
- engines: {node: '>=12'}
- dependencies:
- '@jridgewell/sourcemap-codec': 1.4.15
-
/magic-string@0.30.7:
resolution: {integrity: sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==}
engines: {node: '>=12'}
@@ -6157,6 +6506,11 @@ packages:
/mdn-data@2.0.30:
resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==}
+ /media-typer@0.3.0:
+ resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==}
+ engines: {node: '>= 0.6'}
+ dev: false
+
/merge-stream@2.0.0:
resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
@@ -6164,6 +6518,11 @@ packages:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
engines: {node: '>= 8'}
+ /methods@1.1.2:
+ resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==}
+ engines: {node: '>= 0.6'}
+ dev: false
+
/micromatch@4.0.5:
resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
engines: {node: '>=8.6'}
@@ -6174,14 +6533,12 @@ packages:
/mime-db@1.52.0:
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
engines: {node: '>= 0.6'}
- dev: true
/mime-types@2.1.35:
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
engines: {node: '>= 0.6'}
dependencies:
mime-db: 1.52.0
- dev: true
/mime@1.6.0:
resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==}
@@ -6221,7 +6578,6 @@ packages:
/minimist@1.2.8:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
- dev: true
/minipass-collect@1.0.2:
resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==}
@@ -6291,6 +6647,13 @@ packages:
minipass: 3.3.6
yallist: 4.0.0
+ /mkdirp@0.5.6:
+ resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==}
+ hasBin: true
+ dependencies:
+ minimist: 1.2.8
+ dev: false
+
/mkdirp@1.0.4:
resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==}
engines: {node: '>=10'}
@@ -6328,9 +6691,9 @@ packages:
resolution: {integrity: sha512-ua8PAThnTwpprIaU47EPeZ/bPUVp2QYBbWMphUQpVdBI3Lgqzm5KZQ45Agm3YJedHXaIHl6pBGabaLSUPPSptg==}
dependencies:
acorn: 8.10.0
- pathe: 1.1.1
+ pathe: 1.1.2
pkg-types: 1.0.3
- ufo: 1.1.2
+ ufo: 1.4.0
/mlly@1.5.0:
resolution: {integrity: sha512-NPVQvAY1xr1QoVeG0cy8yUYC7FQcOx6evl/RjT1wL5FvzPnzOysoqB/jmx/DhssT2dYa8nxECLAaFI/+gVLhDQ==}
@@ -6365,6 +6728,14 @@ packages:
/muggle-string@0.3.1:
resolution: {integrity: sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==}
+ /mz@2.7.0:
+ resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
+ dependencies:
+ any-promise: 1.3.0
+ object-assign: 4.1.1
+ thenify-all: 1.6.0
+ dev: false
+
/nanoid@3.3.7:
resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
@@ -6965,6 +7336,11 @@ packages:
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
engines: {node: '>=0.10.0'}
+ /object-hash@3.0.0:
+ resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
+ engines: {node: '>= 6'}
+ dev: false
+
/object-is@1.1.5:
resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==}
engines: {node: '>= 0.4'}
@@ -6983,7 +7359,7 @@ packages:
dependencies:
destr: 2.0.0
node-fetch-native: 1.2.0
- ufo: 1.1.2
+ ufo: 1.4.0
dev: true
/ofetch@1.3.3:
@@ -7024,6 +7400,10 @@ packages:
dependencies:
mimic-fn: 4.0.0
+ /only@0.0.2:
+ resolution: {integrity: sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ==}
+ dev: false
+
/open@10.0.3:
resolution: {integrity: sha512-dtbI5oW7987hwC9qjJTyABldTaa19SuyJse1QboWv3b0qCcrrLNVDqBx1XgELAjh9QTVQaP/C5b1nhQebd1H2A==}
engines: {node: '>=18'}
@@ -7033,6 +7413,14 @@ packages:
is-inside-container: 1.0.0
is-wsl: 3.1.0
+ /open@7.4.2:
+ resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==}
+ engines: {node: '>=8'}
+ dependencies:
+ is-docker: 2.2.1
+ is-wsl: 2.2.0
+ dev: false
+
/open@8.4.2:
resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==}
engines: {node: '>=12'}
@@ -7163,6 +7551,13 @@ packages:
dependencies:
callsites: 3.1.0
+ /parent-module@2.0.0:
+ resolution: {integrity: sha512-uo0Z9JJeWzv8BG+tRcapBKNJ0dro9cLyczGzulS6EfeyAdeC9sbojtW6XwvYxJkEne9En+J2XEl4zyglVeIwFg==}
+ engines: {node: '>=8'}
+ dependencies:
+ callsites: 3.1.0
+ dev: false
+
/parse-git-config@3.0.0:
resolution: {integrity: sha512-wXoQGL1D+2COYWCD35/xbiKma1Z15xvZL8cI25wvxzled58V51SJM04Urt/uznS900iQor7QO04SgdfT/XlbuA==}
engines: {node: '>=8'}
@@ -7220,6 +7615,10 @@ packages:
lru-cache: 10.0.0
minipass: 7.0.4
+ /path-to-regexp@6.2.1:
+ resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==}
+ dev: false
+
/path-type@4.0.0:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'}
@@ -7229,9 +7628,6 @@ packages:
resolution: {integrity: sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==}
engines: {node: '>=12'}
- /pathe@1.1.1:
- resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==}
-
/pathe@1.1.2:
resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==}
@@ -7256,7 +7652,6 @@ packages:
/pify@2.3.0:
resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
engines: {node: '>=0.10.0'}
- dev: true
/pify@3.0.0:
resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==}
@@ -7275,12 +7670,28 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
+ /pirates@4.0.6:
+ resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
+ engines: {node: '>= 6'}
+ dev: false
+
/pkg-types@1.0.3:
resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==}
dependencies:
jsonc-parser: 3.2.0
mlly: 1.4.0
- pathe: 1.1.1
+ pathe: 1.1.2
+
+ /portfinder@1.0.32:
+ resolution: {integrity: sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==}
+ engines: {node: '>= 0.12.0'}
+ dependencies:
+ async: 2.6.4
+ debug: 3.2.7
+ mkdirp: 0.5.6
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
/postcss-calc@9.0.1(postcss@8.4.35):
resolution: {integrity: sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==}
@@ -7314,6 +7725,20 @@ packages:
postcss: 8.4.35
postcss-value-parser: 4.2.0
+ /postcss-custom-properties@13.3.5(postcss@8.4.35):
+ resolution: {integrity: sha512-xHg8DTCMfN2nrqs2CQTF+0m5jgnzKL5zrW5Y05KF6xBRO0uDPxiplBm/xcr1o49SLbyJXkMuaRJKhRzkrquKnQ==}
+ engines: {node: ^14 || ^16 || >=18}
+ peerDependencies:
+ postcss: ^8.4
+ dependencies:
+ '@csstools/cascade-layer-name-parser': 1.0.8(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3)
+ '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3)
+ '@csstools/css-tokenizer': 2.2.3
+ '@csstools/utilities': 1.0.0(postcss@8.4.35)
+ postcss: 8.4.35
+ postcss-value-parser: 4.2.0
+ dev: false
+
/postcss-discard-comments@6.0.1(postcss@8.4.35):
resolution: {integrity: sha512-f1KYNPtqYLUeZGCHQPKzzFtsHaRuECe6jLakf/RjSRqvF5XHLZnM2+fXLhb8Qh/HBFHs3M4cSLb1k3B899RYIg==}
engines: {node: ^14 || ^16 || >=18.0}
@@ -7346,6 +7771,45 @@ packages:
dependencies:
postcss: 8.4.35
+ /postcss-import@15.1.0(postcss@8.4.35):
+ resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ postcss: ^8.0.0
+ dependencies:
+ postcss: 8.4.35
+ postcss-value-parser: 4.2.0
+ read-cache: 1.0.0
+ resolve: 1.22.2
+ dev: false
+
+ /postcss-js@4.0.1(postcss@8.4.35):
+ resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==}
+ engines: {node: ^12 || ^14 || >= 16}
+ peerDependencies:
+ postcss: ^8.4.21
+ dependencies:
+ camelcase-css: 2.0.1
+ postcss: 8.4.35
+ dev: false
+
+ /postcss-load-config@4.0.2(postcss@8.4.35):
+ resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==}
+ engines: {node: '>= 14'}
+ peerDependencies:
+ postcss: '>=8.0.9'
+ ts-node: '>=9.0.0'
+ peerDependenciesMeta:
+ postcss:
+ optional: true
+ ts-node:
+ optional: true
+ dependencies:
+ lilconfig: 3.1.1
+ postcss: 8.4.35
+ yaml: 2.3.4
+ dev: false
+
/postcss-merge-longhand@6.0.2(postcss@8.4.35):
resolution: {integrity: sha512-+yfVB7gEM8SrCo9w2lCApKIEzrTKl5yS1F4yGhV3kSim6JzbfLGJyhR1B6X+6vOT0U33Mgx7iv4X9MVWuaSAfw==}
engines: {node: ^14 || ^16 || >=18.0}
@@ -7416,7 +7880,17 @@ packages:
dependencies:
postcss: 8.4.35
postcss-selector-parser: 6.0.15
- dev: true
+
+ /postcss-nesting@12.0.3(postcss@8.4.35):
+ resolution: {integrity: sha512-yrtMRPFNkfZMv9ikBvZ/Eh3RxhpMBKQ3KzD7LCY8+jYVlgju/Mdcxi4JY8bW2Y7ISXw8GTLuF/o+kFtp+yaVfQ==}
+ engines: {node: ^14 || ^16 || >=18}
+ peerDependencies:
+ postcss: ^8.4
+ dependencies:
+ '@csstools/selector-specificity': 3.0.2(postcss-selector-parser@6.0.15)
+ postcss: 8.4.35
+ postcss-selector-parser: 6.0.15
+ dev: false
/postcss-normalize-charset@6.0.1(postcss@8.4.35):
resolution: {integrity: sha512-aW5LbMNRZ+oDV57PF9K+WI1Z8MPnF+A8qbajg/T8PP126YrGX1f9IQx21GI2OlGz7XFJi/fNi0GTbY948XJtXg==}
@@ -7650,7 +8124,7 @@ packages:
/rc9@2.1.1:
resolution: {integrity: sha512-lNeOl38Ws0eNxpO3+wD1I9rkHGQyj1NU1jlzv4go2CtEnEQEUfqnIvZG7W+bC/aXdJ27n5x/yUjb6RoT9tko+Q==}
dependencies:
- defu: 6.1.2
+ defu: 6.1.4
destr: 2.0.0
flat: 5.0.2
@@ -7658,6 +8132,12 @@ packages:
resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==}
dev: true
+ /read-cache@1.0.0:
+ resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
+ dependencies:
+ pify: 2.3.0
+ dev: false
+
/read-package-json-fast@3.0.2:
resolution: {integrity: sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
@@ -7735,6 +8215,16 @@ packages:
dependencies:
redis-errors: 1.2.0
+ /replace-in-file@6.3.5:
+ resolution: {integrity: sha512-arB9d3ENdKva2fxRnSjwBEXfK1npgyci7ZZuwysgAp7ORjHSyxz6oqIjTEv8R0Ydl4Ll7uOAZXL4vbkhGIizCg==}
+ engines: {node: '>=10'}
+ hasBin: true
+ dependencies:
+ chalk: 4.1.2
+ glob: 7.2.3
+ yargs: 17.7.2
+ dev: false
+
/require-directory@2.1.1:
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
engines: {node: '>=0.10.0'}
@@ -7747,6 +8237,14 @@ packages:
resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
engines: {node: '>=8'}
+ /resolve-path@1.4.0:
+ resolution: {integrity: sha512-i1xevIst/Qa+nA9olDxLWnLk8YZbi8R/7JPbCMcgyWaFR6bKWaexgJgEB5oc2PKMjYdrHynyz0NY+if+H98t1w==}
+ engines: {node: '>= 0.8'}
+ dependencies:
+ http-errors: 1.6.3
+ path-is-absolute: 1.0.1
+ dev: false
+
/resolve-pkg-maps@1.0.0:
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
dev: true
@@ -7965,6 +8463,10 @@ packages:
/set-blocking@2.0.0:
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
+ /setprototypeof@1.1.0:
+ resolution: {integrity: sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==}
+ dev: false
+
/setprototypeof@1.2.0:
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
@@ -8147,6 +8649,11 @@ packages:
/standard-as-callback@2.1.0:
resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==}
+ /statuses@1.5.0:
+ resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==}
+ engines: {node: '>= 0.6'}
+ dev: false
+
/statuses@2.0.1:
resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==}
engines: {node: '>= 0.8'}
@@ -8162,6 +8669,11 @@ packages:
optionalDependencies:
bare-events: 2.2.0
+ /string-iterator@0.0.1:
+ resolution: {integrity: sha512-XCUPs7nuLZ+FblEzY8CsrZ+7oAMPE4sroxEtd/K7mngI34+jJ5bBd2Uilxbt3ivPTNB46nxW9P8Zdff3Vw3/Lw==}
+ engines: {node: '>=0.8'}
+ dev: false
+
/string-width@4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
@@ -8245,6 +8757,20 @@ packages:
postcss: 8.4.35
postcss-selector-parser: 6.0.15
+ /sucrase@3.35.0:
+ resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==}
+ engines: {node: '>=16 || 14 >=14.17'}
+ hasBin: true
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.3
+ commander: 4.1.1
+ glob: 10.3.10
+ lines-and-columns: 1.2.4
+ mz: 2.7.0
+ pirates: 4.0.6
+ ts-interface-checker: 0.1.13
+ dev: false
+
/supports-color@5.5.0:
resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
engines: {node: '>=4'}
@@ -8286,6 +8812,57 @@ packages:
resolution: {integrity: sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA==}
engines: {node: '>=18'}
+ /tailwind-config-viewer@1.7.3(tailwindcss@3.4.1):
+ resolution: {integrity: sha512-rgeFXe9vL4njtaSI1y2uUAD1aRx05RYHbReN72ARAVEVSlNmS0Zf46pj3/ORc3xQwLK/AzbaIs6UFcK7hJSIlA==}
+ engines: {node: '>=8'}
+ hasBin: true
+ peerDependencies:
+ tailwindcss: 1 || 2 || 2.0.1-compat || 3
+ dependencies:
+ '@koa/router': 12.0.1
+ commander: 6.2.1
+ fs-extra: 9.1.0
+ koa: 2.15.0
+ koa-static: 5.0.0
+ open: 7.4.2
+ portfinder: 1.0.32
+ replace-in-file: 6.3.5
+ tailwindcss: 3.4.1
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
+ /tailwindcss@3.4.1:
+ resolution: {integrity: sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==}
+ engines: {node: '>=14.0.0'}
+ hasBin: true
+ dependencies:
+ '@alloc/quick-lru': 5.2.0
+ arg: 5.0.2
+ chokidar: 3.6.0
+ didyoumean: 1.2.2
+ dlv: 1.1.3
+ fast-glob: 3.3.2
+ glob-parent: 6.0.2
+ is-glob: 4.0.3
+ jiti: 1.21.0
+ lilconfig: 2.1.0
+ micromatch: 4.0.5
+ normalize-path: 3.0.0
+ object-hash: 3.0.0
+ picocolors: 1.0.0
+ postcss: 8.4.35
+ postcss-import: 15.1.0(postcss@8.4.35)
+ postcss-js: 4.0.1(postcss@8.4.35)
+ postcss-load-config: 4.0.2(postcss@8.4.35)
+ postcss-nested: 6.0.1(postcss@8.4.35)
+ postcss-selector-parser: 6.0.15
+ resolve: 1.22.2
+ sucrase: 3.35.0
+ transitivePeerDependencies:
+ - ts-node
+ dev: false
+
/tapable@2.2.1:
resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==}
engines: {node: '>=6'}
@@ -8354,6 +8931,19 @@ packages:
/text-table@0.2.0:
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
+ /thenify-all@1.6.0:
+ resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
+ engines: {node: '>=0.8'}
+ dependencies:
+ thenify: 3.3.1
+ dev: false
+
+ /thenify@3.3.1:
+ resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
+ dependencies:
+ any-promise: 1.3.0
+ dev: false
+
/through@2.3.8:
resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
dev: true
@@ -8418,9 +9008,18 @@ packages:
typescript: 5.3.3
dev: true
+ /ts-interface-checker@0.1.13:
+ resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
+ dev: false
+
/tslib@2.6.0:
resolution: {integrity: sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==}
+ /tsscmp@1.0.6:
+ resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==}
+ engines: {node: '>=0.6.x'}
+ dev: false
+
/tsx@3.12.7:
resolution: {integrity: sha512-C2Ip+jPmqKd1GWVQDvz/Eyc6QJbGfE7NrR3fx5BpEHMZsEHoIxHL1j+lKdGobr8ovEyqeNkPLSKp6SCSOt7gmw==}
hasBin: true
@@ -8481,6 +9080,14 @@ packages:
resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==}
engines: {node: '>=14.16'}
+ /type-is@1.6.18:
+ resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==}
+ engines: {node: '>= 0.6'}
+ dependencies:
+ media-typer: 0.3.0
+ mime-types: 2.1.35
+ dev: false
+
/type-level-regexp@0.1.17:
resolution: {integrity: sha512-wTk4DH3cxwk196uGLK/E9pE45aLfeKJacKmcEgEOA/q5dnPGNxXt0cfYdFxb57L+sEpf1oJH4Dnx/pnRcku9jg==}
dev: false
@@ -8490,9 +9097,6 @@ packages:
engines: {node: '>=14.17'}
hasBin: true
- /ufo@1.1.2:
- resolution: {integrity: sha512-TrY6DsjTQQgyS3E3dBaOXf0TpPD8u9FVrVYmKVegJuFw51n/YB9XPt+U6ydzFG5ZIN7+DIjPbNmXoBj9esYhgQ==}
-
/ufo@1.4.0:
resolution: {integrity: sha512-Hhy+BhRBleFjpJ2vchUNN40qgkh0366FWJGqVLYBHev0vpHTrXSA0ryT+74UiW6KWsldNurQMKGqCm1M2zBciQ==}
@@ -8607,13 +9211,13 @@ packages:
escape-string-regexp: 5.0.0
fast-glob: 3.3.0
local-pkg: 0.4.3
- magic-string: 0.30.1
+ magic-string: 0.30.7
mlly: 1.4.0
- pathe: 1.1.1
+ pathe: 1.1.2
pkg-types: 1.0.3
scule: 1.0.0
strip-literal: 1.0.1
- unplugin: 1.3.2
+ unplugin: 1.7.1
transitivePeerDependencies:
- rollup
dev: true
@@ -8698,19 +9302,11 @@ packages:
- rollup
- vue
- /unplugin@1.3.2:
- resolution: {integrity: sha512-Lh7/2SryjXe/IyWqx9K7IKwuKhuOFZEhotiBquOODsv2IVyDkI9lv/XhgfjdXf/xdbv32txmnBNnC/JVTDJlsA==}
- dependencies:
- acorn: 8.10.0
- chokidar: 3.5.3
- webpack-sources: 3.2.3
- webpack-virtual-modules: 0.5.0
-
/unplugin@1.7.1:
resolution: {integrity: sha512-JqzORDAPxxs8ErLV4x+LL7bk5pk3YlcWqpSNsIkAZj972KzFZLClc/ekppahKkOczGkwIG6ElFgdOgOlK4tXZw==}
dependencies:
acorn: 8.11.3
- chokidar: 3.5.3
+ chokidar: 3.6.0
webpack-sources: 3.2.3
webpack-virtual-modules: 0.6.1
@@ -8862,6 +9458,11 @@ packages:
dependencies:
builtins: 5.0.1
+ /vary@1.1.2:
+ resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
+ engines: {node: '>= 0.8'}
+ dev: false
+
/vite-node@1.3.0:
resolution: {integrity: sha512-D/oiDVBw75XMnjAXne/4feCkCEwcbr2SU1bjAhCcfI5Bq3VoOHji8/wCPAfUkDIeohJ5nSZ39fNxM3dNZ6OBOA==}
engines: {node: ^18.0.0 || >=20.0.0}
@@ -9016,7 +9617,7 @@ packages:
'@vue/compiler-dom': 3.3.4
esno: 0.16.3
kolorist: 1.8.0
- magic-string: 0.30.1
+ magic-string: 0.30.7
shell-quote: 1.8.1
vite: 4.4.2
transitivePeerDependencies:
@@ -9327,9 +9928,6 @@ packages:
resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==}
engines: {node: '>=10.13.0'}
- /webpack-virtual-modules@0.5.0:
- resolution: {integrity: sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw==}
-
/webpack-virtual-modules@0.6.1:
resolution: {integrity: sha512-poXpCylU7ExuvZK8z+On3kX+S8o/2dQ/SVYueKA0D4WEMXROXgY8Ez50/bQEUmvoSMMrWcrJqCHuhAbsiwg7Dg==}
@@ -9489,6 +10087,11 @@ packages:
fd-slicer: 1.1.0
dev: true
+ /ylru@1.3.2:
+ resolution: {integrity: sha512-RXRJzMiK6U2ye0BlGGZnmpwJDPgakn6aNQ0A7gHRbD4I0uvK4TW6UqkK1V0pp9jskjJBAXd3dRrbzWkqJ+6cxA==}
+ engines: {node: '>= 4.0.0'}
+ dev: false
+
/yocto-queue@0.1.0:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}
diff --git a/src/module.ts b/src/module.ts
index f449fb3..7f1fdbe 100644
--- a/src/module.ts
+++ b/src/module.ts
@@ -1,7 +1,36 @@
-import { defineNuxtModule } from '@nuxt/kit'
+import { addBuildPlugin, defineNuxtModule, resolveAlias, resolvePath } from '@nuxt/kit'
+
+import google from './providers/google'
+import local from './providers/local'
+
+import { FontFamilyInjectionPlugin } from './plugin'
+import type { FontProvider } from './types'
-// Module options TypeScript interface definition
export interface ModuleOptions {
+ // TODO: support default provider
+ provider?: string
+ providers?: {
+ [key: string]: FontProvider | string | false
+ }
+ /**
+ * An ordered list of providers to check when resolving font families.
+ *
+ * Default behaviour is to check all user providers in the order they were defined, and then all built-in providers.
+ */
+ priority?: string[]
+ // TODO:
+ families?: Array<{
+ name: string
+ as?: string
+ provider?: string
+ src?: string
+ subsets?: Array
+ display?: string
+ weight?: Array
+ style?: Array
+ fallbacks?: Array
+ }>
+ // TODO: allow customising download behaviour with nuxt/assets
}
export default defineNuxtModule({
@@ -10,8 +39,69 @@ export default defineNuxtModule({
configKey: 'fonts'
},
defaults: {
+ providers: {
+ local,
+ google,
+ },
},
async setup (options, nuxt) {
+ // Skip when preparing
+ if (nuxt.options._prepare) return
+
+ const providers = await resolveProviders(options.providers)
+ // Allow registering and disabling providers
+ nuxt.hook('modules:done', async () => {
+ await nuxt.callHook('fonts:providers', providers)
+ const setups: Array> = []
+ for (const key in providers) {
+ if (options.providers?.[key] === false) {
+ delete providers[key]
+ } else if (providers[key].setup) {
+ setups.push(providers[key].setup!(nuxt))
+ }
+ }
+ await Promise.all(setups)
+ })
+
+ addBuildPlugin(FontFamilyInjectionPlugin({
+ dev: nuxt.options.dev,
+ resolveFontFace: (fontFamily) => {
+ // TODO: respect 'none' provider
+ for (const key in providers) {
+ const resolveFontFaces = providers[key].resolveFontFaces
+ console.log(key)
+ if (resolveFontFaces) {
+ const result = resolveFontFaces(fontFamily)
+ if (result) {
+ return result.fonts
+ }
+ }
+ }
+ }
+ }))
}
})
+
+async function resolveProviders (_providers: Record = {}) {
+ const providers = { ..._providers }
+ for (const key in providers) {
+ const value = providers[key]
+ if (value === false) {
+ delete providers[key]
+ }
+ if (typeof value === 'string') {
+ providers[key] = await import(await resolvePath(resolveAlias(value)))
+ }
+ }
+ return providers as Record
+}
+
+export interface ModuleHooks {
+ 'fonts:providers': (providers: FontProvider) => void | Promise
+}
+
+
+declare module '@nuxt/schema' {
+ interface NuxtHooks extends ModuleHooks {}
+}
diff --git a/src/plugin.ts b/src/plugin.ts
new file mode 100644
index 0000000..fdf175e
--- /dev/null
+++ b/src/plugin.ts
@@ -0,0 +1,169 @@
+import { createUnplugin } from 'unplugin'
+import { parse, walk, type Declaration } from 'css-tree'
+import MagicString from 'magic-string'
+import { extname } from 'pathe'
+import { hasProtocol } from 'ufo'
+
+import type { FontFaceData, FontSource } from './types'
+
+interface FontFamilyInjectionPluginOptions {
+ dev: boolean
+ resolveFontFace: (fontFamily: string) => FontFaceData | FontFaceData[] | undefined
+}
+
+export const FontFamilyInjectionPlugin = (options: FontFamilyInjectionPluginOptions) => createUnplugin(() => {
+ return {
+ name: 'nuxt:fonts:font-family-injection',
+ transformInclude (id) {
+ return isCSS(id)
+ },
+ transform (code) {
+ // Early return if no font-family is used in this CSS
+ if (!code.includes('font-family:')) { return }
+
+ const s = new MagicString(code)
+ const processedFontFamilies = new Set()
+ const injectedDeclarations = new Set()
+
+ // TODO: handle these edge cases
+ // 1. existing font-family in this scope
+ // 2. handle CSS custom property
+ walk(parse(code), node => {
+ if (node.type === 'Declaration' && node.property === 'font-family') {
+ for (const fontFamily of extractFontFamilies(node)) {
+ if (processedFontFamilies.has(fontFamily)) continue
+ processedFontFamilies.add(fontFamily)
+
+ const result = options.resolveFontFace(fontFamily)
+ if (!result) continue
+
+ for (const declaration of generateFontFaces(fontFamily, result)) {
+ if (!injectedDeclarations.has(declaration)) {
+ injectedDeclarations.add(declaration)
+ s.prepend(declaration)
+ }
+ }
+ }
+ }
+ })
+
+ if (s.hasChanged()) {
+ return {
+ code: s.toString(),
+ map: s.generateMap({ hires: true })
+ }
+ }
+ },
+ }
+})
+
+// Copied from vue-bundle-renderer utils
+const IS_CSS_RE = /\.(?:css|scss|sass|postcss|pcss|less|stylus|styl)(\?[^.]+)?$/
+
+function isCSS (id: string) {
+ return IS_CSS_RE.test(id)
+}
+
+// https://developer.mozilla.org/en-US/docs/Web/CSS/font-family
+const genericCSSFamilies = new Set([
+ /* A generic family name only */
+ 'serif',
+ 'sans-serif',
+ 'monospace',
+ 'cursive',
+ 'fantasy',
+ 'system-ui',
+ 'ui-serif',
+ 'ui-sans-serif',
+ 'ui-monospace',
+ 'ui-rounded',
+ 'emoji',
+ 'math',
+ 'fangsong',
+
+ /* Global values */
+ 'inherit',
+ 'initial',
+ 'revert',
+ 'revert-layer',
+ 'unset',
+])
+
+function* generateFontFaces (family: string, source: FontFaceData | FontFaceData[]) {
+ const sources = Array.isArray(source) ? source : [source]
+ for (const font of sources) {
+ const src = Array.isArray(font.src) ? font.src : [font.src]
+ const sources = src.map(s => typeof s === 'string' ? parseFont(s) : s)
+
+ yield [
+ '@font-face {',
+ ` font-family: '${family}';`,
+ ` src: ${renderFontSrc(sources)};`,
+ ` unicode-range: ${font.unicodeRange};`,
+ ` font-display: ${font.display || 'swap'};`,
+ font.weight && ` font-weight: ${font.weight};`,
+ font.style && ` font-style: ${font.style};`,
+ font.featureSettings && ` font-feature-settings: ${font.featureSettings};`,
+ font.variationSettings && ` font-variation-settings: ${font.variationSettings};`,
+ `}`
+ ].filter(Boolean).join('\n')
+ }
+}
+
+const formatMap: Record = {
+ otf: 'opentype',
+ woff: 'woff',
+ woff2: 'woff2',
+ ttf: 'truetype',
+ eot: 'embedded-opentype',
+ svg: 'svg',
+}
+
+function parseFont (font: string) {
+ // render as `url("url/to/font") format("woff2")`
+ if (font.startsWith('/') || hasProtocol(font)) {
+ const extension = extname(font).slice(1)
+ const format = formatMap[extension]
+
+ return {
+ url: font,
+ format
+ }
+ }
+
+ // render as `local("Font Name")`
+ return { name: font }
+}
+
+function renderFontSrc (sources: Exclude[]) {
+ return sources.map(src => {
+ if ('url' in src) {
+ let rendered = `url("${src.url}")`
+ for (const key of ['format', 'tech'] as const) {
+ if (key in src) {
+ rendered += ` ${key}(${src[key]})`
+ }
+ }
+ return rendered
+ }
+ return `local("${src.name}")`
+ }).join(', ')
+}
+
+function extractFontFamilies (node: Declaration) {
+ if (node.value.type == 'Raw') {
+ return [node.value.value]
+ }
+
+ const families = [] as string[]
+ for (const child of node.value.children) {
+ if (child.type === 'Identifier' && !genericCSSFamilies.has(child.name)) {
+ families.push(child.name)
+ }
+ if (child.type === 'String') {
+ families.push(child.value)
+ }
+ }
+
+ return families
+}
diff --git a/src/providers/google.ts b/src/providers/google.ts
new file mode 100644
index 0000000..5a4de7c
--- /dev/null
+++ b/src/providers/google.ts
@@ -0,0 +1,27 @@
+import type { FontProvider } from '../types'
+
+const resolvableFontFamilies = new Set([
+ 'Roboto'
+])
+
+
+
+export default {
+ async setup () {},
+ resolveFontFaces (fontFamily) {
+ if (!resolvableFontFamilies.has(fontFamily)) return
+
+ return {
+ fonts: {
+ src: [
+ fontFamily, // resolve to local font if it is installed
+ 'https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4mxKKTU1Kg.woff2',
+ ],
+ unicodeRange: ['U+0000-00FF', 'U+0131', 'U+0152-0153', 'U+02BB-02BC', 'U+02C6', 'U+02DA', 'U+02DC', 'U+0304', 'U+0308', 'U+0329', 'U+2000-206F', 'U+2074', 'U+20AC', 'U+2122', 'U+2191', 'U+2193', 'U+2212', 'U+2215', 'U+FEFF', 'U+FFFD'],
+ display: 'swap',
+ weight: 400,
+ style: 'normal',
+ }
+ }
+ },
+} satisfies FontProvider
diff --git a/src/providers/local.ts b/src/providers/local.ts
new file mode 100644
index 0000000..23ad602
--- /dev/null
+++ b/src/providers/local.ts
@@ -0,0 +1,123 @@
+import { globby } from 'globby'
+import { join, relative, resolve } from 'pathe'
+import { filename } from 'pathe/utils'
+
+import type { FontProvider } from '../types'
+import { withLeadingSlash, withTrailingSlash } from 'ufo'
+
+const providerContext = {
+ rootPaths: [] as string[],
+ registry: {} as Record,
+}
+
+export default {
+ async setup (nuxt) {
+ // Scan for all font files in public directories
+ for (const layer of nuxt.options._layers) {
+ const publicDir = join(layer.config.srcDir || layer.cwd, layer.config.dir?.public || 'public')
+ const possibleFontFiles = await globby('**/*.{ttf,woff,woff2,eot,otf}', {
+ absolute: true,
+ cwd: publicDir
+ })
+ providerContext.rootPaths.push(withTrailingSlash(publicDir))
+ for (const file of possibleFontFiles) {
+ registerFont(file)
+ }
+ }
+
+ // Sort rootPaths so we resolve to most specific path first
+ providerContext.rootPaths = providerContext.rootPaths.sort((a, b) => b.length - a.length)
+
+ // Update registry when files change
+ nuxt.hook('builder:watch', (event, relativePath) => {
+ const path = resolve(nuxt.options.srcDir, relativePath)
+ if (event === 'add' && isFontFile(path)) {
+ registerFont(path)
+ }
+ if (event === 'unlink' && isFontFile(path)) {
+ unregisterFont(path)
+ }
+ })
+ },
+ resolveFontFaces (fontFamily) {
+ const weights = {
+ regular: 400,
+ bold: 700,
+ }
+ const styles = {
+ regular: 'normal',
+ italic: 'italic',
+ }
+ const fonts = []
+ for (const weight in weights) {
+ for (const style in styles) {
+ const resolved = lookupFont(fontFamily + '-' + weight + '-' + style)
+ if (resolved) {
+ fonts.push({
+ src: resolved,
+ weight: weights[weight],
+ style: styles[style],
+ })
+ }
+ }
+ }
+ const resolved = [
+ lookupFont(fontFamily + '-regular'),
+ lookupFont(fontFamily)
+ ]
+ if (resolved) {
+ return {
+ fonts: [
+ { src: resolved }
+ ],
+ }
+ }
+ },
+} satisfies FontProvider
+
+const FONT_RE = /\.(ttf|woff|woff2|eot|otf)(\?[^.]+)?$/
+export const isFontFile = (id: string) => FONT_RE.test(id)
+
+function generateSlugs (path: string) {
+ const name = filename(path)
+ return [...new Set([
+ name.toLowerCase(),
+ // Barlow-das324jasdf => barlow
+ name.replace(/-[\w\d]+$/, '').toLowerCase(),
+ // Barlow.das324jasdf => barlow
+ name.replace(/\.[\w\d]+$/, '').toLowerCase(),
+ // Open+Sans => open-sans
+ name.replace(/\+/g, '-').toLowerCase(),
+ ])]
+}
+
+function registerFont (path: string) {
+ const slugs = generateSlugs(path)
+ for (const slug of slugs) {
+ providerContext.registry[slug] ||= []
+ providerContext.registry[slug]!.push(path)
+ }
+}
+
+function unregisterFont (path: string) {
+ const slugs = generateSlugs(path)
+ for (const slug of slugs) {
+ providerContext.registry[slug] ||= []
+ providerContext.registry[slug] = providerContext.registry[slug]!.filter(p => p !== path)
+ }
+}
+
+function lookupFont (family: string): string[] | undefined {
+ const priority = ['woff2', 'woff', 'ttf', 'otf', 'eot']
+ const scannedFiles = providerContext.registry[family.toLowerCase()]?.map(path => {
+ const base = providerContext.rootPaths.find(root => path.startsWith(root))
+ return base ? withLeadingSlash(relative(base, path)) : path
+ })
+
+ return scannedFiles?.sort((a, b) => {
+ const extA = filename(a).split('.').pop()!
+ const extB = filename(b).split('.').pop()!
+
+ return priority.indexOf(extA) - priority.indexOf(extB)
+ })
+}
diff --git a/src/types.ts b/src/types.ts
new file mode 100644
index 0000000..363bb07
--- /dev/null
+++ b/src/types.ts
@@ -0,0 +1,52 @@
+// TODO: Font metric providers
+
+import type { Nuxt } from '@nuxt/schema'
+
+export interface RemoteFontSource {
+ url: string
+ format?: string
+ tech?: string
+}
+
+export interface LocalFontSource {
+ name: string
+}
+
+export type FontSource = string | LocalFontSource | RemoteFontSource | (LocalFontSource & RemoteFontSource)
+
+export interface FontFaceData {
+ src: FontSource | Array
+ /**
+ * The font-display descriptor.
+ * @default 'swap'
+ */
+ display?: 'auto' | 'block' | 'swap' | 'fallback' | 'optional'
+ /** A font-weight value. */
+ weight?: string | number
+ /** A font-style value. */
+ style?: string
+ /** The range of Unicode code points to be used from the font. */
+ unicodeRange?: string | string[]
+ /** Allows control over advanced typographic features in OpenType fonts. */
+ featureSettings?: string
+ /** Allows low-level control over OpenType or TrueType font variations, by specifying the four letter axis names of the features to vary, along with their variation values. */
+ variationSettings?: string
+
+ // TODO: possibly support in future
+ // metrics
+ // ascent-override
+ // descent-override
+ // line-gap-override
+ // size-adjust
+}
+
+export interface FontProvider {
+ setup?: (nuxt: Nuxt) => void | Promise
+ resolveFontFaces?: (fontFamily: string) => void | {
+ /**
+ * Return data used to generate @font-face declarations
+ * @see https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face
+ */
+ fonts: FontFaceData | FontFaceData[]
+ }
+}
diff --git a/tsconfig.json b/tsconfig.json
index 4b34df1..f2e0164 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,3 +1,11 @@
{
- "extends": "./.nuxt/tsconfig.json"
+ "extends": "./.nuxt/tsconfig.json",
+ "compilerOptions": {
+ "noUncheckedIndexedAccess": true,
+ "paths": {
+ "#types": [
+ "./src/runtime/types"
+ ]
+ }
+ }
}