>;
diff --git a/packages/starpod/cli/template/database/db/data/sponsors.ts b/packages/starpod/cli/template/database/db/data/sponsors.ts
new file mode 100644
index 00000000..84670ed9
--- /dev/null
+++ b/packages/starpod/cli/template/database/db/data/sponsors.ts
@@ -0,0 +1,7 @@
+/**
+ * Sponsors that can appear on episodes. `img` is a filename inside
+ * src/img/sponsors/.
+ */
+export default [
+ // { id: 'acme', name: 'Acme Corp', img: 'acme.svg', url: 'https://acme.com' }
+];
diff --git a/packages/starpod/cli/template/database/db/seed.ts b/packages/starpod/cli/template/database/db/seed.ts
new file mode 100644
index 00000000..51a380c7
--- /dev/null
+++ b/packages/starpod/cli/template/database/db/seed.ts
@@ -0,0 +1,99 @@
+import 'dotenv/config';
+
+import { sql } from 'drizzle-orm';
+
+import { createDb } from 'starpod/db';
+import {
+ Episode,
+ HostOrGuest,
+ Person,
+ Sponsor,
+ SponsorForEpisode
+} from 'starpod/db/schema';
+import { getAllEpisodes } from 'starpod/src/lib/rss';
+
+import starpodConfig from '../starpod.config';
+import people from './data/people';
+import peoplePerEpisode from './data/people-per-episode';
+import sponsors from './data/sponsors';
+import sponsorsPerEpisode from './data/sponsors-per-episode';
+
+const db = createDb(
+ process.env.ASTRO_DB_REMOTE_URL!,
+ process.env.ASTRO_DB_APP_TOKEN!
+);
+
+async function seed() {
+ if (people.length) {
+ await db
+ .insert(Person)
+ .values(people)
+ .onConflictDoUpdate({
+ target: Person.id,
+ set: { name: sql`excluded.name`, img: sql`excluded.img` }
+ });
+ }
+
+ if (sponsors.length) {
+ await db
+ .insert(Sponsor)
+ .values(sponsors)
+ .onConflictDoUpdate({
+ target: Sponsor.id,
+ set: {
+ name: sql`excluded.name`,
+ img: sql`excluded.img`,
+ url: sql`excluded.url`
+ }
+ });
+ }
+
+ const allEpisodes = await getAllEpisodes(starpodConfig);
+ const episodes = allEpisodes.map((episode) => ({
+ episodeSlug: episode.episodeSlug
+ }));
+
+ if (episodes.length) {
+ await db.insert(Episode).values(episodes).onConflictDoNothing();
+ }
+
+ const hostsOrGuestsToInsert = [];
+ const sponsorsForEpisodesToInsert = [];
+ for (const episode of episodes) {
+ for (const person of peoplePerEpisode[episode.episodeSlug] ?? []) {
+ hostsOrGuestsToInsert.push({
+ episodeSlug: episode.episodeSlug,
+ isHost: Boolean(person.isHost),
+ personId: person.id
+ });
+ }
+
+ for (const sponsor of sponsorsPerEpisode[episode.episodeSlug] ?? []) {
+ sponsorsForEpisodesToInsert.push({
+ episodeSlug: episode.episodeSlug,
+ sponsorId: sponsor.id
+ });
+ }
+ }
+
+ if (hostsOrGuestsToInsert.length) {
+ await db
+ .insert(HostOrGuest)
+ .values(hostsOrGuestsToInsert)
+ .onConflictDoNothing();
+ }
+
+ if (sponsorsForEpisodesToInsert.length) {
+ await db
+ .insert(SponsorForEpisode)
+ .values(sponsorsForEpisodesToInsert)
+ .onConflictDoNothing();
+ }
+
+ console.log('Seed complete!');
+}
+
+seed().catch((err) => {
+ console.error('Seed failed:', err);
+ process.exit(1);
+});
diff --git a/packages/starpod/cli/template/database/drizzle.config.ts b/packages/starpod/cli/template/database/drizzle.config.ts
new file mode 100644
index 00000000..43eeee7a
--- /dev/null
+++ b/packages/starpod/cli/template/database/drizzle.config.ts
@@ -0,0 +1,12 @@
+import { defineConfig } from 'drizzle-kit';
+
+export default defineConfig({
+ // The schema ships with the starpod package.
+ schema: './node_modules/starpod/src/db/schema.ts',
+ out: './drizzle',
+ dialect: 'turso',
+ dbCredentials: {
+ url: process.env.ASTRO_DB_REMOTE_URL!,
+ authToken: process.env.ASTRO_DB_APP_TOKEN!
+ }
+});
diff --git a/packages/starpod/package.json b/packages/starpod/package.json
new file mode 100644
index 00000000..f257822c
--- /dev/null
+++ b/packages/starpod/package.json
@@ -0,0 +1,66 @@
+{
+ "name": "starpod",
+ "type": "module",
+ "version": "0.1.0",
+ "description": "Turn an RSS feed into a full podcast website. An Astro integration.",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/shipshapecode/starpod.git",
+ "directory": "packages/starpod"
+ },
+ "license": "MIT",
+ "keywords": [
+ "astro-integration",
+ "astro-component",
+ "withastro",
+ "podcast"
+ ],
+ "bin": {
+ "starpod": "./cli/index.mjs"
+ },
+ "files": ["cli", "src", "tsconfig.json"],
+ "exports": {
+ ".": "./src/index.ts",
+ "./config": "./src/config.ts",
+ "./content": "./src/content.ts",
+ "./db": "./src/db/index.ts",
+ "./db/schema": "./src/db/schema.ts",
+ "./layout": "./src/layouts/Layout.astro",
+ "./components/AdPackageCard": "./src/components/AdPackageCard.astro",
+ "./rss": "./src/lib/rss.ts",
+ "./src/*": "./src/*"
+ },
+ "dependencies": {
+ "@astrojs/sitemap": "^3.7.3",
+ "@bryanguffey/astro-standard-site": "^1.0.3",
+ "@libsql/client": "^0.17.3",
+ "@preact/signals": "^2.9.1",
+ "@tailwindcss/forms": "^0.5.11",
+ "@tailwindcss/typography": "^0.5.19",
+ "@tailwindcss/vite": "^4.3.0",
+ "@vercel/speed-insights": "^1.3.1",
+ "astro-seo-schema": "^5.2.0",
+ "atropos": "^2.0.2",
+ "drizzle-orm": "^0.45.2",
+ "html-to-text": "^9.0.5",
+ "rss-to-json": "^2.1.1",
+ "schema-dts": "^1.1.5",
+ "tailwindcss": "^4.3.0",
+ "valibot": "^1.4.1"
+ },
+ "peerDependencies": {
+ "@astrojs/preact": "^5.0.0",
+ "astro": "^6.0.0",
+ "preact": "^10.0.0"
+ },
+ "devDependencies": {
+ "@astrojs/preact": "^5.1.4",
+ "@types/html-to-text": "^9.0.4",
+ "astro": "6.4.2",
+ "preact": "^10.29.2",
+ "typescript": "^5.9.3"
+ },
+ "engines": {
+ "node": "^22.0.0"
+ }
+}
diff --git a/public/images/apple.svg b/packages/starpod/src/assets/apple.svg
similarity index 100%
rename from public/images/apple.svg
rename to packages/starpod/src/assets/apple.svg
diff --git a/src/img/people/avatar-dark.png b/packages/starpod/src/assets/avatar-dark.png
similarity index 100%
rename from src/img/people/avatar-dark.png
rename to packages/starpod/src/assets/avatar-dark.png
diff --git a/src/img/people/avatar-light.png b/packages/starpod/src/assets/avatar-light.png
similarity index 100%
rename from src/img/people/avatar-light.png
rename to packages/starpod/src/assets/avatar-light.png
diff --git a/public/images/dots-dark.svg b/packages/starpod/src/assets/dots-dark.svg
similarity index 100%
rename from public/images/dots-dark.svg
rename to packages/starpod/src/assets/dots-dark.svg
diff --git a/public/images/dots-light.svg b/packages/starpod/src/assets/dots-light.svg
similarity index 100%
rename from public/images/dots-light.svg
rename to packages/starpod/src/assets/dots-light.svg
diff --git a/public/images/forward-icon.svg b/packages/starpod/src/assets/forward-icon.svg
similarity index 100%
rename from public/images/forward-icon.svg
rename to packages/starpod/src/assets/forward-icon.svg
diff --git a/public/images/mute-icon.svg b/packages/starpod/src/assets/mute-icon.svg
similarity index 100%
rename from public/images/mute-icon.svg
rename to packages/starpod/src/assets/mute-icon.svg
diff --git a/public/images/overcast.svg b/packages/starpod/src/assets/overcast.svg
similarity index 100%
rename from public/images/overcast.svg
rename to packages/starpod/src/assets/overcast.svg
diff --git a/public/images/pocket-casts.svg b/packages/starpod/src/assets/pocket-casts.svg
similarity index 100%
rename from public/images/pocket-casts.svg
rename to packages/starpod/src/assets/pocket-casts.svg
diff --git a/public/images/rewind-icon.svg b/packages/starpod/src/assets/rewind-icon.svg
similarity index 100%
rename from public/images/rewind-icon.svg
rename to packages/starpod/src/assets/rewind-icon.svg
diff --git a/public/images/rocket-dark.svg b/packages/starpod/src/assets/rocket-dark.svg
similarity index 100%
rename from public/images/rocket-dark.svg
rename to packages/starpod/src/assets/rocket-dark.svg
diff --git a/public/images/rocket-light.svg b/packages/starpod/src/assets/rocket-light.svg
similarity index 100%
rename from public/images/rocket-light.svg
rename to packages/starpod/src/assets/rocket-light.svg
diff --git a/public/images/search-icon.svg b/packages/starpod/src/assets/search-icon.svg
similarity index 100%
rename from public/images/search-icon.svg
rename to packages/starpod/src/assets/search-icon.svg
diff --git a/public/images/spotify.svg b/packages/starpod/src/assets/spotify.svg
similarity index 100%
rename from public/images/spotify.svg
rename to packages/starpod/src/assets/spotify.svg
diff --git a/public/images/unmute-icon.svg b/packages/starpod/src/assets/unmute-icon.svg
similarity index 100%
rename from public/images/unmute-icon.svg
rename to packages/starpod/src/assets/unmute-icon.svg
diff --git a/public/images/youtube.svg b/packages/starpod/src/assets/youtube.svg
similarity index 100%
rename from public/images/youtube.svg
rename to packages/starpod/src/assets/youtube.svg
diff --git a/src/components/AdPackageCard.astro b/packages/starpod/src/components/AdPackageCard.astro
similarity index 100%
rename from src/components/AdPackageCard.astro
rename to packages/starpod/src/components/AdPackageCard.astro
diff --git a/src/components/Breadcrumbs.astro b/packages/starpod/src/components/Breadcrumbs.astro
similarity index 100%
rename from src/components/Breadcrumbs.astro
rename to packages/starpod/src/components/Breadcrumbs.astro
diff --git a/src/components/ContactForm.tsx b/packages/starpod/src/components/ContactForm.tsx
similarity index 100%
rename from src/components/ContactForm.tsx
rename to packages/starpod/src/components/ContactForm.tsx
diff --git a/src/components/Dots.astro b/packages/starpod/src/components/Dots.astro
similarity index 100%
rename from src/components/Dots.astro
rename to packages/starpod/src/components/Dots.astro
diff --git a/src/components/EpisodeList.astro b/packages/starpod/src/components/EpisodeList.astro
similarity index 100%
rename from src/components/EpisodeList.astro
rename to packages/starpod/src/components/EpisodeList.astro
diff --git a/src/components/FormattedDate.tsx b/packages/starpod/src/components/FormattedDate.tsx
similarity index 100%
rename from src/components/FormattedDate.tsx
rename to packages/starpod/src/components/FormattedDate.tsx
diff --git a/src/components/FullPlayButton.tsx b/packages/starpod/src/components/FullPlayButton.tsx
similarity index 100%
rename from src/components/FullPlayButton.tsx
rename to packages/starpod/src/components/FullPlayButton.tsx
diff --git a/src/components/Hosts.astro b/packages/starpod/src/components/Hosts.astro
similarity index 67%
rename from src/components/Hosts.astro
rename to packages/starpod/src/components/Hosts.astro
index dbd68b96..fe64fce2 100644
--- a/src/components/Hosts.astro
+++ b/packages/starpod/src/components/Hosts.astro
@@ -2,12 +2,19 @@
import type { ImageMetadata } from 'astro';
import { Image } from 'astro:assets';
-import starpodConfig from '../../starpod.config';
+import starpodConfig from 'virtual:starpod/config';
+
+import avatarLight from '../assets/avatar-light.png';
const { hosts } = starpodConfig;
const images = import.meta.glob<{ default: ImageMetadata }>(
'/src/img/people/*.{jpeg,jpg,png}'
);
+
+// Fall back to the packaged avatar when the site has not provided a photo in
+// src/img/people yet.
+const hostImage = (img: string) =>
+ images[`/src/img/people/${img}`]?.() ?? avatarLight;
---
diff --git a/src/components/LargePlatforms.astro b/packages/starpod/src/components/LargePlatforms.astro
similarity index 98%
rename from src/components/LargePlatforms.astro
rename to packages/starpod/src/components/LargePlatforms.astro
index 631b10f1..d12242ea 100644
--- a/src/components/LargePlatforms.astro
+++ b/packages/starpod/src/components/LargePlatforms.astro
@@ -1,5 +1,5 @@
---
-import starpodConfig from '../../starpod.config';
+import starpodConfig from 'virtual:starpod/config';
import AppleIcon from '../svgs/apple.svg?raw';
import OvercastIcon from '../svgs/overcast.svg?raw';
import PocketCastsIcon from '../svgs/pocket-casts.svg?raw';
diff --git a/src/components/NotFoundContent.astro b/packages/starpod/src/components/NotFoundContent.astro
similarity index 100%
rename from src/components/NotFoundContent.astro
rename to packages/starpod/src/components/NotFoundContent.astro
diff --git a/src/components/Platforms.astro b/packages/starpod/src/components/Platforms.astro
similarity index 83%
rename from src/components/Platforms.astro
rename to packages/starpod/src/components/Platforms.astro
index 972e4299..47c8b7e2 100644
--- a/src/components/Platforms.astro
+++ b/packages/starpod/src/components/Platforms.astro
@@ -1,5 +1,5 @@
---
-import starpodConfig from '../../starpod.config';
+import starpodConfig from 'virtual:starpod/config';
import { getShowInfo } from '../lib/rss';
const { platforms } = starpodConfig;
@@ -61,21 +61,21 @@ const show = await getShowInfo();
diff --git a/src/components/Player.tsx b/packages/starpod/src/components/Player.tsx
similarity index 100%
rename from src/components/Player.tsx
rename to packages/starpod/src/components/Player.tsx
diff --git a/src/components/SearchButton.tsx b/packages/starpod/src/components/SearchButton.tsx
similarity index 100%
rename from src/components/SearchButton.tsx
rename to packages/starpod/src/components/SearchButton.tsx
diff --git a/src/components/SearchDialog.tsx b/packages/starpod/src/components/SearchDialog.tsx
similarity index 100%
rename from src/components/SearchDialog.tsx
rename to packages/starpod/src/components/SearchDialog.tsx
diff --git a/src/components/ShowArtwork.astro b/packages/starpod/src/components/ShowArtwork.astro
similarity index 100%
rename from src/components/ShowArtwork.astro
rename to packages/starpod/src/components/ShowArtwork.astro
diff --git a/src/components/episode/CreatorsAndGuests.astro b/packages/starpod/src/components/episode/CreatorsAndGuests.astro
similarity index 80%
rename from src/components/episode/CreatorsAndGuests.astro
rename to packages/starpod/src/components/episode/CreatorsAndGuests.astro
index 358b6009..8e911493 100644
--- a/src/components/episode/CreatorsAndGuests.astro
+++ b/packages/starpod/src/components/episode/CreatorsAndGuests.astro
@@ -2,6 +2,11 @@
import type { ImageMetadata } from 'astro';
import { Image } from 'astro:assets';
+import starpodConfig from 'virtual:starpod/config';
+
+import avatarDark from '../../assets/avatar-dark.png';
+import avatarLight from '../../assets/avatar-light.png';
+
export interface Props {
hostsAndGuests: Array<{
id: string;
@@ -15,7 +20,9 @@ const { hostsAndGuests } = Astro.props;
const images = import.meta.glob<{ default: ImageMetadata }>(
'/src/img/people/*.{jpeg,jpg,png}'
);
-const priorityNames = ['RobbieTheWagner', 'Charles William Carpenter III', 'Adam Argyle'];
+// The show's configured hosts sort first, in config order; other hosts (e.g.
+// past hosts recorded in the database) follow, then guests alphabetically.
+const priorityNames = starpodConfig.hosts.map((host) => host.name);
---
Creators and Guests
@@ -53,7 +60,7 @@ const priorityNames = ['RobbieTheWagner', 'Charles William Carpenter III', 'Adam
}).map((person) => {
return (
- {person.img ?
+ {person.img && images[`/src/img/people/${person.img}`] ?
}
diff --git a/src/components/episode/MarkdownTranscript.tsx b/packages/starpod/src/components/episode/MarkdownTranscript.tsx
similarity index 100%
rename from src/components/episode/MarkdownTranscript.tsx
rename to packages/starpod/src/components/episode/MarkdownTranscript.tsx
diff --git a/src/components/episode/Sponsors.astro b/packages/starpod/src/components/episode/Sponsors.astro
similarity index 85%
rename from src/components/episode/Sponsors.astro
rename to packages/starpod/src/components/episode/Sponsors.astro
index 66f3a402..7a804167 100644
--- a/src/components/episode/Sponsors.astro
+++ b/packages/starpod/src/components/episode/Sponsors.astro
@@ -24,7 +24,9 @@ const svgs = import.meta.glob('/src/img/sponsors/*.svg', {
diff --git a/src/components/episode/Transcript.tsx b/packages/starpod/src/components/episode/Transcript.tsx
similarity index 100%
rename from src/components/episode/Transcript.tsx
rename to packages/starpod/src/components/episode/Transcript.tsx
diff --git a/src/components/illustrations/404Illustration.astro b/packages/starpod/src/components/illustrations/404Illustration.astro
similarity index 100%
rename from src/components/illustrations/404Illustration.astro
rename to packages/starpod/src/components/illustrations/404Illustration.astro
diff --git a/src/components/illustrations/UFOIllustration.astro b/packages/starpod/src/components/illustrations/UFOIllustration.astro
similarity index 100%
rename from src/components/illustrations/UFOIllustration.astro
rename to packages/starpod/src/components/illustrations/UFOIllustration.astro
diff --git a/src/components/player/ForwardButton/index.tsx b/packages/starpod/src/components/player/ForwardButton/index.tsx
similarity index 100%
rename from src/components/player/ForwardButton/index.tsx
rename to packages/starpod/src/components/player/ForwardButton/index.tsx
diff --git a/packages/starpod/src/components/player/ForwardButton/styles.css b/packages/starpod/src/components/player/ForwardButton/styles.css
new file mode 100644
index 00000000..e823e2d9
--- /dev/null
+++ b/packages/starpod/src/components/player/ForwardButton/styles.css
@@ -0,0 +1,3 @@
+.forward-button {
+ mask-image: url('../../../assets/forward-icon.svg');
+}
diff --git a/src/components/player/MuteButton/index.tsx b/packages/starpod/src/components/player/MuteButton/index.tsx
similarity index 100%
rename from src/components/player/MuteButton/index.tsx
rename to packages/starpod/src/components/player/MuteButton/index.tsx
diff --git a/packages/starpod/src/components/player/MuteButton/styles.css b/packages/starpod/src/components/player/MuteButton/styles.css
new file mode 100644
index 00000000..9c85f9ac
--- /dev/null
+++ b/packages/starpod/src/components/player/MuteButton/styles.css
@@ -0,0 +1,7 @@
+.mute-button {
+ mask-image: url('../../../assets/mute-icon.svg');
+}
+
+.unmute-button {
+ mask-image: url('../../../assets/unmute-icon.svg');
+}
diff --git a/src/components/player/PlayButton.tsx b/packages/starpod/src/components/player/PlayButton.tsx
similarity index 100%
rename from src/components/player/PlayButton.tsx
rename to packages/starpod/src/components/player/PlayButton.tsx
diff --git a/src/components/player/PlaybackRateButton.tsx b/packages/starpod/src/components/player/PlaybackRateButton.tsx
similarity index 100%
rename from src/components/player/PlaybackRateButton.tsx
rename to packages/starpod/src/components/player/PlaybackRateButton.tsx
diff --git a/src/components/player/RewindButton/index.tsx b/packages/starpod/src/components/player/RewindButton/index.tsx
similarity index 100%
rename from src/components/player/RewindButton/index.tsx
rename to packages/starpod/src/components/player/RewindButton/index.tsx
diff --git a/packages/starpod/src/components/player/RewindButton/styles.css b/packages/starpod/src/components/player/RewindButton/styles.css
new file mode 100644
index 00000000..a795fa42
--- /dev/null
+++ b/packages/starpod/src/components/player/RewindButton/styles.css
@@ -0,0 +1,3 @@
+.rewind-button {
+ mask-image: url('../../../assets/rewind-icon.svg');
+}
diff --git a/src/components/player/Slider/index.tsx b/packages/starpod/src/components/player/Slider/index.tsx
similarity index 100%
rename from src/components/player/Slider/index.tsx
rename to packages/starpod/src/components/player/Slider/index.tsx
diff --git a/src/components/player/Slider/styles.css b/packages/starpod/src/components/player/Slider/styles.css
similarity index 91%
rename from src/components/player/Slider/styles.css
rename to packages/starpod/src/components/player/Slider/styles.css
index 790defe9..33ec5caa 100644
--- a/src/components/player/Slider/styles.css
+++ b/packages/starpod/src/components/player/Slider/styles.css
@@ -17,7 +17,7 @@
}
&::-webkit-slider-thumb {
@apply relative -mt-[5px] box-content h-4 w-4 cursor-pointer appearance-none bg-contain bg-no-repeat transition-opacity duration-300 lg:opacity-0;
- background-image: url('/images/rocket-dark.svg');
+ background-image: url('../../../assets/rocket-dark.svg');
background-position: center center;
box-shadow: none;
background-color: #0000;
@@ -33,16 +33,16 @@
}
&::-moz-range-thumb {
@apply h-4 w-4 cursor-pointer appearance-none border-0 bg-transparent bg-contain bg-no-repeat transition-opacity duration-300 outline-none lg:opacity-0;
- background-image: url('/images/rocket-dark.svg');
+ background-image: url('../../../assets/rocket-dark.svg');
background-position: center center;
}
@media (prefers-color-scheme: light) {
&::-webkit-slider-thumb {
- background-image: url('/images/rocket-light.svg');
+ background-image: url('../../../assets/rocket-light.svg');
}
&::-moz-range-thumb {
- background-image: url('/images/rocket-light.svg');
+ background-image: url('../../../assets/rocket-light.svg');
}
}
diff --git a/src/components/state.ts b/packages/starpod/src/components/state.ts
similarity index 100%
rename from src/components/state.ts
rename to packages/starpod/src/components/state.ts
diff --git a/packages/starpod/src/config.ts b/packages/starpod/src/config.ts
new file mode 100644
index 00000000..528530c2
--- /dev/null
+++ b/packages/starpod/src/config.ts
@@ -0,0 +1,7 @@
+export {
+ defineStarpodConfig,
+ validateStarpodConfig,
+ type Host,
+ type NavLink,
+ type StarpodConfig
+} from './utils/config';
diff --git a/packages/starpod/src/content.ts b/packages/starpod/src/content.ts
new file mode 100644
index 00000000..26735502
--- /dev/null
+++ b/packages/starpod/src/content.ts
@@ -0,0 +1,18 @@
+import { glob } from 'astro/loaders';
+
+/**
+ * Loader for episode transcript markdown files, named by episode number
+ * (e.g. `42.md`). Use in the consuming site's `src/content.config.ts`:
+ *
+ * ```ts
+ * import { defineCollection } from 'astro:content';
+ * import { transcriptsLoader } from 'starpod/content';
+ *
+ * export const collections = {
+ * transcripts: defineCollection({ loader: transcriptsLoader() })
+ * };
+ * ```
+ */
+export function transcriptsLoader(base = './src/content/transcripts') {
+ return glob({ pattern: '**/*.{md,mdx}', base });
+}
diff --git a/db/index.ts b/packages/starpod/src/db/index.ts
similarity index 100%
rename from db/index.ts
rename to packages/starpod/src/db/index.ts
diff --git a/db/schema.ts b/packages/starpod/src/db/schema.ts
similarity index 100%
rename from db/schema.ts
rename to packages/starpod/src/db/schema.ts
diff --git a/packages/starpod/src/index.ts b/packages/starpod/src/index.ts
new file mode 100644
index 00000000..8f4f7772
--- /dev/null
+++ b/packages/starpod/src/index.ts
@@ -0,0 +1,285 @@
+import { resolve as resolvePath } from 'node:path';
+import { fileURLToPath } from 'node:url';
+
+import preact from '@astrojs/preact';
+import sitemap from '@astrojs/sitemap';
+import tailwindcss from '@tailwindcss/vite';
+import type { AstroIntegration } from 'astro';
+import { fontProviders } from 'astro/config';
+import type { Plugin as VitePlugin } from 'vite';
+
+import rehypeTranscriptTimestamps from './lib/rehype-transcript-timestamps.mjs';
+import { validateStarpodConfig, type StarpodConfig } from './utils/config';
+import {
+ main as applyVercelMarkdownNegotiation,
+ pagesToMarkdownPaths
+} from './vercel-md-negotiation.mjs';
+
+/**
+ * Built-in components a site may replace via `options.components`. Each maps
+ * to the default implementation shipped with the package; call sites import
+ * them through `virtual:starpod/components/` so an override swaps the
+ * module everywhere at once.
+ */
+const OVERRIDABLE_COMPONENTS = {
+ Dots: './components/Dots.astro',
+ EpisodeList: './components/EpisodeList.astro',
+ Hosts: './components/Hosts.astro',
+ InfoCard: './components/InfoCard.astro',
+ LargePlatforms: './components/LargePlatforms.astro',
+ NotFoundContent: './components/NotFoundContent.astro',
+ Platforms: './components/Platforms.astro',
+ ShowArtwork: './components/ShowArtwork.astro'
+} as const;
+
+export type OverridableComponent = keyof typeof OVERRIDABLE_COMPONENTS;
+
+export interface StarpodOptions {
+ /**
+ * Enable the Turso/Drizzle database for per-episode guests and sponsors.
+ * Requires `ASTRO_DB_REMOTE_URL` and `ASTRO_DB_APP_TOKEN`. When disabled
+ * (the default), episode pages simply render without the guests and
+ * sponsors sections.
+ */
+ database?: boolean;
+ /**
+ * Replace built-in components with your own, e.g.
+ * `{ Hosts: './src/components/MyHosts.astro' }`. Paths are resolved from
+ * the project root.
+ */
+ components?: Partial>;
+ /**
+ * Extra stylesheets loaded after the built-in styles, e.g.
+ * `['./src/styles/theme.css']`. Paths are resolved from the project root.
+ */
+ customCss?: string[];
+}
+
+const VIRTUAL_CONFIG_ID = 'virtual:starpod/config';
+const RESOLVED_VIRTUAL_CONFIG_ID = '\0' + VIRTUAL_CONFIG_ID;
+const VIRTUAL_USER_CSS_ID = 'virtual:starpod/user-css';
+const RESOLVED_VIRTUAL_USER_CSS_ID = '\0' + VIRTUAL_USER_CSS_ID;
+const VIRTUAL_COMPONENT_PREFIX = 'virtual:starpod/components/';
+
+/**
+ * Serves the virtual modules that connect the consuming site to the package:
+ * the validated config (plus feature flags), user CSS, and component
+ * overrides.
+ */
+function starpodVitePlugin(
+ config: StarpodConfig,
+ options: StarpodOptions,
+ root: URL
+): VitePlugin {
+ const rootDir = fileURLToPath(root);
+
+ return {
+ name: 'starpod',
+ resolveId(id) {
+ if (id === VIRTUAL_CONFIG_ID) {
+ return RESOLVED_VIRTUAL_CONFIG_ID;
+ }
+ if (id === VIRTUAL_USER_CSS_ID) {
+ return RESOLVED_VIRTUAL_USER_CSS_ID;
+ }
+ if (id.startsWith(VIRTUAL_COMPONENT_PREFIX)) {
+ const name = id.slice(
+ VIRTUAL_COMPONENT_PREFIX.length
+ ) as OverridableComponent;
+ const defaultPath = OVERRIDABLE_COMPONENTS[name];
+ if (!defaultPath) {
+ throw new Error(
+ `[starpod] Unknown component "${name}". Overridable components: ${Object.keys(OVERRIDABLE_COMPONENTS).join(', ')}`
+ );
+ }
+ const override = options.components?.[name];
+ return override
+ ? resolvePath(rootDir, override)
+ : fileURLToPath(new URL(defaultPath, import.meta.url));
+ }
+ },
+ load(id) {
+ if (id === RESOLVED_VIRTUAL_CONFIG_ID) {
+ return [
+ `export default ${JSON.stringify(config)};`,
+ `export const database = ${options.database === true};`
+ ].join('\n');
+ }
+ if (id === RESOLVED_VIRTUAL_USER_CSS_ID) {
+ const imports = (options.customCss ?? []).map(
+ (css) =>
+ `import ${JSON.stringify(
+ css.startsWith('.') ? resolvePath(rootDir, css) : css
+ )};`
+ );
+ return imports.join('\n') || 'export {};';
+ }
+ }
+ };
+}
+
+/**
+ * Every route the integration injects, mirroring the file-based routes the
+ * pages had when they lived in the consuming site's `src/pages`.
+ */
+const ROUTES: Array<{ pattern: string; entrypoint: string }> = [
+ { pattern: '/', entrypoint: 'index.astro' },
+ { pattern: '/index.html.md', entrypoint: 'index.html.md.ts' },
+ { pattern: '/contact.html.md', entrypoint: 'contact.html.md.ts' },
+ { pattern: '/404', entrypoint: '404.astro' },
+ { pattern: '/[...notFound]', entrypoint: '[...notFound].astro' },
+ { pattern: '/[episode]', entrypoint: '[episode].astro' },
+ { pattern: '/[episode].html.md', entrypoint: '[episode].html.md.ts' },
+ { pattern: '/about', entrypoint: 'about.astro' },
+ { pattern: '/about.html.md', entrypoint: 'about.html.md.ts' },
+ { pattern: '/contact', entrypoint: 'contact.astro' },
+ {
+ pattern: '/episodes-index.html.md',
+ entrypoint: 'episodes-index.html.md.ts'
+ },
+ { pattern: '/for-llms', entrypoint: 'for-llms.astro' },
+ { pattern: '/for-llms.html.md', entrypoint: 'for-llms.html.md.ts' },
+ { pattern: '/llms.txt', entrypoint: 'llms.txt.ts' },
+ { pattern: '/openapi.json', entrypoint: 'openapi.json.ts' },
+ { pattern: '/robots.txt', entrypoint: 'robots.txt.ts' },
+ { pattern: '/api/contact', entrypoint: 'api/contact.ts' },
+ { pattern: '/api/episodes/[page].json', entrypoint: 'api/episodes/[page].json.ts' },
+ {
+ pattern: '/api/episodes/search.json',
+ entrypoint: 'api/episodes/search.json.ts'
+ }
+];
+
+const MISSING_CONFIG_MESSAGE = `[starpod] Missing podcast config.
+
+Create starpod.config.ts at your project root:
+
+ import { defineStarpodConfig } from 'starpod/config';
+
+ export default defineStarpodConfig({
+ blurb: 'A one-line tagline for your show.',
+ description: 'A few sentences about your show.',
+ hosts: [{ name: 'Your Name', bio: 'A short bio.', img: 'your-name.jpg' }],
+ platforms: {},
+ rssFeed: 'https://example.com/feed.xml'
+ });
+
+Then pass it to the integration in astro.config.mjs:
+
+ import starpodConfig from './starpod.config';
+
+ export default defineConfig({
+ integrations: [starpod(starpodConfig)]
+ });
+`;
+
+export default function starpod(
+ config?: StarpodConfig,
+ options: StarpodOptions = {}
+): AstroIntegration {
+ if (!config) {
+ // `astro add starpod` writes `starpod()` with no arguments; fail with
+ // instructions rather than a crash deeper in the build.
+ throw new Error(MISSING_CONFIG_MESSAGE);
+ }
+ // Validated here too so configs that skipped defineStarpodConfig still
+ // get checked.
+ const starpodConfig = validateStarpodConfig(config);
+ let projectRoot: URL;
+
+ return {
+ name: 'starpod',
+ hooks: {
+ 'astro:config:setup': ({ config, injectRoute, updateConfig }) => {
+ projectRoot = config.root;
+
+ for (const route of ROUTES) {
+ injectRoute({
+ pattern: route.pattern,
+ entrypoint: new URL(`./pages/${route.entrypoint}`, import.meta.url)
+ });
+ }
+
+ updateConfig({
+ build: {
+ inlineStylesheets: 'always'
+ },
+ experimental: {
+ clientPrerender: true
+ },
+ fonts: [
+ {
+ provider: fontProviders.google(),
+ name: 'Inter',
+ cssVariable: '--astro-font-inter',
+ formats: ['woff2'],
+ styles: ['normal'],
+ subsets: ['latin'],
+ weights: ['300 900'],
+ options: {
+ experimental: {
+ variableAxis: {
+ opsz: ['14..32']
+ }
+ }
+ }
+ }
+ ],
+ image: {
+ remotePatterns: [{ protocol: 'https' }, { protocol: 'http' }]
+ },
+ integrations: [
+ preact({
+ // The preset's default exclude is /node_modules/, which would
+ // skip this package's own .tsx components when starpod is
+ // installed as a dependency. Exclude everything else but keep
+ // starpod's sources in the Preact JSX transform.
+ exclude: [/node_modules(?!.*[\\/]starpod[\\/])/]
+ }),
+ sitemap({
+ filter: (page) => {
+ const pathname = new URL(page).pathname;
+ // Exclude episode number pages and only include slug pages.
+ return !/^\/\d+\/?$/.test(pathname);
+ }
+ })
+ ],
+ markdown: {
+ // Makes bracketed timestamps in markdown transcripts clickable
+ // for seeking.
+ rehypePlugins: [rehypeTranscriptTimestamps]
+ },
+ prefetch: {
+ prefetchAll: true,
+ defaultStrategy: 'viewport'
+ },
+ trailingSlash: 'never',
+ vite: {
+ plugins: [
+ tailwindcss(),
+ starpodVitePlugin(starpodConfig, options, config.root)
+ ]
+ }
+ });
+ },
+ 'astro:build:done': ({ dir, assets }) => {
+ // Injects `Accept: text/markdown` content-negotiation routes into the
+ // Vercel build output. No-ops for other adapters. The adapter runs
+ // first in astro:build:done (Astro unshifts it), so config.json exists
+ // here β but the static dir is only copied afterwards, so the markdown
+ // twin paths are derived from the build's generated assets, not the
+ // filesystem.
+ const outputBase = fileURLToPath(dir);
+ const generated = [...assets.values()]
+ .flat()
+ .map((url) => fileURLToPath(url).slice(outputBase.length));
+ applyVercelMarkdownNegotiation(
+ fileURLToPath(new URL('./.vercel/output', projectRoot)),
+ pagesToMarkdownPaths(generated)
+ );
+ }
+ }
+ };
+}
+
+export { defineStarpodConfig, type Host, type StarpodConfig } from './utils/config';
diff --git a/src/layouts/Layout.astro b/packages/starpod/src/layouts/Layout.astro
similarity index 92%
rename from src/layouts/Layout.astro
rename to packages/starpod/src/layouts/Layout.astro
index fd7057e5..ba36cc08 100644
--- a/src/layouts/Layout.astro
+++ b/packages/starpod/src/layouts/Layout.astro
@@ -6,19 +6,22 @@ import { Schema } from 'astro-seo-schema';
import SpeedInsights from '@vercel/speed-insights/astro';
import Breadcrumbs from '../components/Breadcrumbs.astro';
-import Dots from '../components/Dots.astro';
-import Hosts from '../components/Hosts.astro';
-import InfoCard from '../components/InfoCard.astro';
-import Platforms from '../components/Platforms.astro';
+import Dots from 'virtual:starpod/components/Dots';
+import Hosts from 'virtual:starpod/components/Hosts';
+import InfoCard from 'virtual:starpod/components/InfoCard';
+import Platforms from 'virtual:starpod/components/Platforms';
import Player from '../components/Player';
import SearchButton from '../components/SearchButton';
import SearchDialog from '../components/SearchDialog';
-import ShowArtwork from '../components/ShowArtwork.astro';
+import ShowArtwork from 'virtual:starpod/components/ShowArtwork';
import { getShowInfo } from '../lib/rss';
-import starpodConfig from 'starpod.config';
+import starpodConfig from 'virtual:starpod/config';
import '../styles/global.css';
+// Site-provided stylesheets from the integration's `customCss` option; loads
+// after the built-in styles so they win the cascade.
+import 'virtual:starpod/user-css';
const show = await getShowInfo();
diff --git a/src/lib/api-errors.ts b/packages/starpod/src/lib/api-errors.ts
similarity index 100%
rename from src/lib/api-errors.ts
rename to packages/starpod/src/lib/api-errors.ts
diff --git a/src/lib/llms.ts b/packages/starpod/src/lib/llms.ts
similarity index 100%
rename from src/lib/llms.ts
rename to packages/starpod/src/lib/llms.ts
diff --git a/src/lib/not-found.ts b/packages/starpod/src/lib/not-found.ts
similarity index 100%
rename from src/lib/not-found.ts
rename to packages/starpod/src/lib/not-found.ts
diff --git a/src/lib/openapi.ts b/packages/starpod/src/lib/openapi.ts
similarity index 100%
rename from src/lib/openapi.ts
rename to packages/starpod/src/lib/openapi.ts
diff --git a/src/lib/optimize-episode-image.ts b/packages/starpod/src/lib/optimize-episode-image.ts
similarity index 100%
rename from src/lib/optimize-episode-image.ts
rename to packages/starpod/src/lib/optimize-episode-image.ts
diff --git a/packages/starpod/src/lib/rehype-transcript-timestamps.d.mts b/packages/starpod/src/lib/rehype-transcript-timestamps.d.mts
new file mode 100644
index 00000000..ebf294af
--- /dev/null
+++ b/packages/starpod/src/lib/rehype-transcript-timestamps.d.mts
@@ -0,0 +1,4 @@
+type RehypeTranscriptTimestamps = () => (tree: unknown) => void;
+
+declare const rehypeTranscriptTimestamps: RehypeTranscriptTimestamps;
+export default rehypeTranscriptTimestamps;
diff --git a/src/lib/rehype-transcript-timestamps.mjs b/packages/starpod/src/lib/rehype-transcript-timestamps.mjs
similarity index 100%
rename from src/lib/rehype-transcript-timestamps.mjs
rename to packages/starpod/src/lib/rehype-transcript-timestamps.mjs
diff --git a/src/lib/rss.ts b/packages/starpod/src/lib/rss.ts
similarity index 77%
rename from src/lib/rss.ts
rename to packages/starpod/src/lib/rss.ts
index e562e615..91670ce4 100644
--- a/src/lib/rss.ts
+++ b/packages/starpod/src/lib/rss.ts
@@ -11,9 +11,32 @@ import {
} from 'valibot';
import { optimizeImage } from './optimize-episode-image';
+import type { StarpodConfig } from '../utils/config';
import { dasherize } from '../utils/dasherize';
import { truncate } from '../utils/truncate';
-import starpodConfig from '../../starpod.config';
+
+// rss-to-json is CJS with `__esModule: true` and both `exports.parse` and
+// `exports.default` pointing at the same function, so what the default import
+// yields depends on whether the bundler externalized it. Normalize both
+// shapes to the parse function.
+type ParseFeedFn = (url: string) => Promise;
+const parseFeedModule: unknown = parseFeed;
+const parseRssFeed: ParseFeedFn =
+ typeof parseFeedModule === 'function'
+ ? (parseFeedModule as ParseFeedFn)
+ : (parseFeedModule as { parse: ParseFeedFn }).parse;
+
+// Inside Astro (dev, build, vitest) the config comes from the integration's
+// virtual module. Standalone scripts (e.g. `db/seed.ts` under tsx) have no
+// Vite, so they must pass their config explicitly and the dynamic import is
+// never reached.
+async function resolveRssFeed(config?: StarpodConfig): Promise {
+ if (config) {
+ return config.rssFeed;
+ }
+ const { default: starpodConfig } = await import('virtual:starpod/config');
+ return starpodConfig.rssFeed;
+}
export interface Show {
title: string;
@@ -75,13 +98,12 @@ function pickTranscript(
let showInfoCache: Show | null = null;
-export async function getShowInfo() {
+export async function getShowInfo(config?: StarpodConfig) {
if (showInfoCache) {
return showInfoCache;
}
- // @ts-expect-error
- const showInfo = (await parseFeed.parse(starpodConfig.rssFeed)) as Show;
+ const showInfo = (await parseRssFeed(await resolveRssFeed(config))) as Show;
showInfo.image = (await optimizeImage(showInfo.image, {
height: 640,
width: 640
@@ -93,7 +115,7 @@ export async function getShowInfo() {
let episodesCache: Array | null = null;
-export async function getAllEpisodes() {
+export async function getAllEpisodes(config?: StarpodConfig) {
if (episodesCache) {
return episodesCache;
}
@@ -124,8 +146,7 @@ export async function getAllEpisodes() {
)
});
- // @ts-expect-error
- let feed = (await parseFeed.parse(starpodConfig.rssFeed)) as Show;
+ let feed = (await parseRssFeed(await resolveRssFeed(config))) as Show;
let items = parse(FeedSchema, feed).items;
let episodes: Array = await Promise.all(
diff --git a/src/lib/standardSite.ts b/packages/starpod/src/lib/standardSite.ts
similarity index 100%
rename from src/lib/standardSite.ts
rename to packages/starpod/src/lib/standardSite.ts
diff --git a/src/lib/transcript.ts b/packages/starpod/src/lib/transcript.ts
similarity index 100%
rename from src/lib/transcript.ts
rename to packages/starpod/src/lib/transcript.ts
diff --git a/src/pages/.well-known/site.standard.publication.ts b/packages/starpod/src/pages/.well-known/site.standard.publication.ts
similarity index 100%
rename from src/pages/.well-known/site.standard.publication.ts
rename to packages/starpod/src/pages/.well-known/site.standard.publication.ts
diff --git a/src/pages/404.astro b/packages/starpod/src/pages/404.astro
similarity index 61%
rename from src/pages/404.astro
rename to packages/starpod/src/pages/404.astro
index 1cadd86c..49fb4289 100644
--- a/src/pages/404.astro
+++ b/packages/starpod/src/pages/404.astro
@@ -1,6 +1,6 @@
---
import Layout from '../layouts/Layout.astro';
-import NotFoundContent from '../components/NotFoundContent.astro';
+import NotFoundContent from 'virtual:starpod/components/NotFoundContent';
---
diff --git a/src/pages/[...notFound].astro b/packages/starpod/src/pages/[...notFound].astro
similarity index 94%
rename from src/pages/[...notFound].astro
rename to packages/starpod/src/pages/[...notFound].astro
index 0170f24b..335c54db 100644
--- a/src/pages/[...notFound].astro
+++ b/packages/starpod/src/pages/[...notFound].astro
@@ -1,6 +1,6 @@
---
import Layout from '../layouts/Layout.astro';
-import NotFoundContent from '../components/NotFoundContent.astro';
+import NotFoundContent from 'virtual:starpod/components/NotFoundContent';
import { jsonError } from '../lib/api-errors';
import { generateNotFoundMarkdown } from '../lib/not-found';
import { getShowInfo } from '../lib/rss';
diff --git a/src/pages/[episode].astro b/packages/starpod/src/pages/[episode].astro
similarity index 87%
rename from src/pages/[episode].astro
rename to packages/starpod/src/pages/[episode].astro
index c00087ea..e70d3396 100644
--- a/src/pages/[episode].astro
+++ b/packages/starpod/src/pages/[episode].astro
@@ -2,14 +2,14 @@
import { getEntry, render } from 'astro:content';
import { eq } from 'drizzle-orm';
-import { createDb } from '../../db';
+import { createDb } from '../db';
import {
Episode as DbEpisode,
HostOrGuest,
Person,
Sponsor,
SponsorForEpisode
-} from '../../db/schema';
+} from '../db/schema';
import { Schema } from 'astro-seo-schema';
@@ -23,6 +23,8 @@ import FullPlayButton from '../components/FullPlayButton';
import UFOIllustration from '../components/illustrations/UFOIllustration.astro';
import { generateDocumentLinkTag } from '@bryanguffey/astro-standard-site';
+import { database } from 'virtual:starpod/config';
+
import Layout from '../layouts/Layout.astro';
import { getAllEpisodes, getShowInfo } from '../lib/rss';
import {
@@ -83,37 +85,45 @@ const playerEpisode = {
const canonicalURL = new URL(`/${episode.episodeSlug}`, Astro.url);
-const db = createDb(
- import.meta.env.ASTRO_DB_REMOTE_URL,
- import.meta.env.ASTRO_DB_APP_TOKEN
-);
-
-const hostsAndGuests = await db
- .select({
- id: Person.id,
- img: Person.img,
- isHost: HostOrGuest.isHost,
- name: Person.name
- })
- .from(HostOrGuest)
- .innerJoin(DbEpisode, eq(HostOrGuest.episodeSlug, DbEpisode.episodeSlug))
- .innerJoin(Person, eq(HostOrGuest.personId, Person.id))
- .where(eq(DbEpisode.episodeSlug, episode.episodeSlug));
-
-const sponsors = await db
- .select({
- id: Sponsor.id,
- img: Sponsor.img,
- name: Sponsor.name,
- url: Sponsor.url
- })
- .from(SponsorForEpisode)
- .innerJoin(
- DbEpisode,
- eq(SponsorForEpisode.episodeSlug, DbEpisode.episodeSlug)
- )
- .innerJoin(Sponsor, eq(SponsorForEpisode.sponsorId, Sponsor.id))
- .where(eq(DbEpisode.episodeSlug, episode.episodeSlug));
+// The guests/sponsors database is opt-in via the integration's `database`
+// option; without it the page renders with those sections absent.
+const db = database
+ ? createDb(
+ import.meta.env.ASTRO_DB_REMOTE_URL,
+ import.meta.env.ASTRO_DB_APP_TOKEN
+ )
+ : null;
+
+const hostsAndGuests = !db
+ ? []
+ : await db
+ .select({
+ id: Person.id,
+ img: Person.img,
+ isHost: HostOrGuest.isHost,
+ name: Person.name
+ })
+ .from(HostOrGuest)
+ .innerJoin(DbEpisode, eq(HostOrGuest.episodeSlug, DbEpisode.episodeSlug))
+ .innerJoin(Person, eq(HostOrGuest.personId, Person.id))
+ .where(eq(DbEpisode.episodeSlug, episode.episodeSlug));
+
+const sponsors = !db
+ ? []
+ : await db
+ .select({
+ id: Sponsor.id,
+ img: Sponsor.img,
+ name: Sponsor.name,
+ url: Sponsor.url
+ })
+ .from(SponsorForEpisode)
+ .innerJoin(
+ DbEpisode,
+ eq(SponsorForEpisode.episodeSlug, DbEpisode.episodeSlug)
+ )
+ .innerJoin(Sponsor, eq(SponsorForEpisode.sponsorId, Sponsor.id))
+ .where(eq(DbEpisode.episodeSlug, episode.episodeSlug));
const title = `${episode.title} - ${show.title} - Episode ${episode.episodeNumber}`;
diff --git a/src/pages/[episode].html.md.ts b/packages/starpod/src/pages/[episode].html.md.ts
similarity index 96%
rename from src/pages/[episode].html.md.ts
rename to packages/starpod/src/pages/[episode].html.md.ts
index bab5450c..0413bef4 100644
--- a/src/pages/[episode].html.md.ts
+++ b/packages/starpod/src/pages/[episode].html.md.ts
@@ -4,7 +4,7 @@ import type { APIRoute } from 'astro';
import { cleanTranscript, generateEpisodeMarkdown } from '../lib/llms';
import { getAllEpisodes, getShowInfo } from '../lib/rss';
import { getRssTranscriptText } from '../lib/transcript';
-import starpodConfig from '../../starpod.config';
+import starpodConfig from 'virtual:starpod/config';
export async function getStaticPaths() {
const allEpisodes = await getAllEpisodes();
diff --git a/src/pages/about.astro b/packages/starpod/src/pages/about.astro
similarity index 84%
rename from src/pages/about.astro
rename to packages/starpod/src/pages/about.astro
index 729658e1..32356e13 100644
--- a/src/pages/about.astro
+++ b/packages/starpod/src/pages/about.astro
@@ -3,13 +3,20 @@ import type { ImageMetadata } from 'astro';
import { Image } from 'astro:assets';
import Layout from '../layouts/Layout.astro';
-import starpodConfig from '../../starpod.config';
-import LargePlatforms from '../components/LargePlatforms.astro';
+import starpodConfig from 'virtual:starpod/config';
+import LargePlatforms from 'virtual:starpod/components/LargePlatforms';
+
+import avatarLight from '../assets/avatar-light.png';
const { hosts } = starpodConfig;
const images = import.meta.glob<{ default: ImageMetadata }>(
'/src/img/people/*.{jpeg,jpg,png}'
);
+
+// Fall back to the packaged avatar when the site has not provided a photo in
+// src/img/people yet.
+const hostImage = (img: string) =>
+ images[`/src/img/people/${img}`]?.() ?? avatarLight;
---
@@ -36,7 +43,7 @@ const images = import.meta.glob<{ default: ImageMetadata }>(
diff --git a/src/pages/about.html.md.ts b/packages/starpod/src/pages/about.html.md.ts
similarity index 88%
rename from src/pages/about.html.md.ts
rename to packages/starpod/src/pages/about.html.md.ts
index 0d51e17d..0e9b3fb8 100644
--- a/src/pages/about.html.md.ts
+++ b/packages/starpod/src/pages/about.html.md.ts
@@ -2,7 +2,7 @@ import type { APIRoute } from 'astro';
import { generateAboutMarkdown } from '../lib/llms';
import { getShowInfo } from '../lib/rss';
-import starpodConfig from '../../starpod.config';
+import starpodConfig from 'virtual:starpod/config';
export const GET: APIRoute = async () => {
const show = await getShowInfo();
diff --git a/src/pages/api/contact.ts b/packages/starpod/src/pages/api/contact.ts
similarity index 100%
rename from src/pages/api/contact.ts
rename to packages/starpod/src/pages/api/contact.ts
diff --git a/src/pages/api/episodes/[page].json.ts b/packages/starpod/src/pages/api/episodes/[page].json.ts
similarity index 100%
rename from src/pages/api/episodes/[page].json.ts
rename to packages/starpod/src/pages/api/episodes/[page].json.ts
diff --git a/src/pages/api/episodes/search.json.ts b/packages/starpod/src/pages/api/episodes/search.json.ts
similarity index 100%
rename from src/pages/api/episodes/search.json.ts
rename to packages/starpod/src/pages/api/episodes/search.json.ts
diff --git a/src/pages/contact.astro b/packages/starpod/src/pages/contact.astro
similarity index 100%
rename from src/pages/contact.astro
rename to packages/starpod/src/pages/contact.astro
diff --git a/src/pages/contact.html.md.ts b/packages/starpod/src/pages/contact.html.md.ts
similarity index 88%
rename from src/pages/contact.html.md.ts
rename to packages/starpod/src/pages/contact.html.md.ts
index ffe564f7..c4372cee 100644
--- a/src/pages/contact.html.md.ts
+++ b/packages/starpod/src/pages/contact.html.md.ts
@@ -2,7 +2,7 @@ import type { APIRoute } from 'astro';
import { generateContactMarkdown } from '../lib/llms';
import { getShowInfo } from '../lib/rss';
-import starpodConfig from '../../starpod.config';
+import starpodConfig from 'virtual:starpod/config';
export const GET: APIRoute = async ({ site }) => {
const show = await getShowInfo();
diff --git a/src/pages/episodes-index.html.md.ts b/packages/starpod/src/pages/episodes-index.html.md.ts
similarity index 100%
rename from src/pages/episodes-index.html.md.ts
rename to packages/starpod/src/pages/episodes-index.html.md.ts
diff --git a/src/pages/for-llms.astro b/packages/starpod/src/pages/for-llms.astro
similarity index 99%
rename from src/pages/for-llms.astro
rename to packages/starpod/src/pages/for-llms.astro
index f825d6c3..09527a52 100644
--- a/src/pages/for-llms.astro
+++ b/packages/starpod/src/pages/for-llms.astro
@@ -2,7 +2,7 @@
import Layout from '../layouts/Layout.astro';
import { getAllEpisodes, getShowInfo } from '../lib/rss';
import { formatDate, formatDuration } from '../lib/llms';
-import starpodConfig from '../../starpod.config';
+import starpodConfig from 'virtual:starpod/config';
const show = await getShowInfo();
const episodes = await getAllEpisodes();
diff --git a/src/pages/for-llms.html.md.ts b/packages/starpod/src/pages/for-llms.html.md.ts
similarity index 90%
rename from src/pages/for-llms.html.md.ts
rename to packages/starpod/src/pages/for-llms.html.md.ts
index a9fedf28..eeef10c1 100644
--- a/src/pages/for-llms.html.md.ts
+++ b/packages/starpod/src/pages/for-llms.html.md.ts
@@ -2,7 +2,7 @@ import type { APIRoute } from 'astro';
import { generateForLlmsMarkdown } from '../lib/llms';
import { getAllEpisodes, getShowInfo } from '../lib/rss';
-import starpodConfig from '../../starpod.config';
+import starpodConfig from 'virtual:starpod/config';
export const GET: APIRoute = async ({ site }) => {
const show = await getShowInfo();
diff --git a/src/pages/index.astro b/packages/starpod/src/pages/index.astro
similarity index 87%
rename from src/pages/index.astro
rename to packages/starpod/src/pages/index.astro
index 6a4f6489..57577192 100644
--- a/src/pages/index.astro
+++ b/packages/starpod/src/pages/index.astro
@@ -1,6 +1,6 @@
---
import Layout from '../layouts/Layout.astro';
-import EpisodeList from '../components/EpisodeList.astro';
+import EpisodeList from 'virtual:starpod/components/EpisodeList';
import { getAllEpisodes, getShowInfo } from '../lib/rss';
const episodes = await getAllEpisodes();
const show = await getShowInfo();
diff --git a/src/pages/index.html.md.ts b/packages/starpod/src/pages/index.html.md.ts
similarity index 90%
rename from src/pages/index.html.md.ts
rename to packages/starpod/src/pages/index.html.md.ts
index 24c8856c..c6b33ae4 100644
--- a/src/pages/index.html.md.ts
+++ b/packages/starpod/src/pages/index.html.md.ts
@@ -2,7 +2,7 @@ import type { APIRoute } from 'astro';
import { generateHomeMarkdown } from '../lib/llms';
import { getAllEpisodes, getShowInfo } from '../lib/rss';
-import starpodConfig from '../../starpod.config';
+import starpodConfig from 'virtual:starpod/config';
export const GET: APIRoute = async ({ site }) => {
const show = await getShowInfo();
diff --git a/src/pages/llms.txt.ts b/packages/starpod/src/pages/llms.txt.ts
similarity index 92%
rename from src/pages/llms.txt.ts
rename to packages/starpod/src/pages/llms.txt.ts
index 9b6767e1..39e1125a 100644
--- a/src/pages/llms.txt.ts
+++ b/packages/starpod/src/pages/llms.txt.ts
@@ -2,7 +2,7 @@ import type { APIRoute } from 'astro';
import { generateLlmsTxt } from '../lib/llms';
import { getAllEpisodes, getShowInfo } from '../lib/rss';
-import starpodConfig from '../../starpod.config';
+import starpodConfig from 'virtual:starpod/config';
export const GET: APIRoute = async ({ site }) => {
const show = await getShowInfo();
diff --git a/src/pages/openapi.json.ts b/packages/starpod/src/pages/openapi.json.ts
similarity index 89%
rename from src/pages/openapi.json.ts
rename to packages/starpod/src/pages/openapi.json.ts
index bf4d506c..34b1e8b4 100644
--- a/src/pages/openapi.json.ts
+++ b/packages/starpod/src/pages/openapi.json.ts
@@ -2,7 +2,7 @@ import type { APIRoute } from 'astro';
import { generateOpenApiSpec } from '../lib/openapi';
import { getShowInfo } from '../lib/rss';
-import starpodConfig from '../../starpod.config';
+import starpodConfig from 'virtual:starpod/config';
export const GET: APIRoute = async ({ site }) => {
const show = await getShowInfo();
diff --git a/src/pages/robots.txt.ts b/packages/starpod/src/pages/robots.txt.ts
similarity index 100%
rename from src/pages/robots.txt.ts
rename to packages/starpod/src/pages/robots.txt.ts
diff --git a/src/styles/buttons.css b/packages/starpod/src/styles/buttons.css
similarity index 100%
rename from src/styles/buttons.css
rename to packages/starpod/src/styles/buttons.css
diff --git a/src/styles/global.css b/packages/starpod/src/styles/global.css
similarity index 100%
rename from src/styles/global.css
rename to packages/starpod/src/styles/global.css
diff --git a/src/styles/gradient-icon.css b/packages/starpod/src/styles/gradient-icon.css
similarity index 100%
rename from src/styles/gradient-icon.css
rename to packages/starpod/src/styles/gradient-icon.css
diff --git a/src/styles/search-icon.css b/packages/starpod/src/styles/search-icon.css
similarity index 72%
rename from src/styles/search-icon.css
rename to packages/starpod/src/styles/search-icon.css
index 33a130b4..b1e8f090 100644
--- a/src/styles/search-icon.css
+++ b/packages/starpod/src/styles/search-icon.css
@@ -1,5 +1,5 @@
.search-icon {
- mask-image: url(/images/search-icon.svg);
+ mask-image: url('../assets/search-icon.svg');
mask-size: contain;
mask-repeat: no-repeat;
mask-position: center;
diff --git a/src/styles/tailwind.css b/packages/starpod/src/styles/tailwind.css
similarity index 82%
rename from src/styles/tailwind.css
rename to packages/starpod/src/styles/tailwind.css
index fdd85d82..dcb26567 100644
--- a/src/styles/tailwind.css
+++ b/packages/starpod/src/styles/tailwind.css
@@ -1,11 +1,20 @@
@import 'tailwindcss';
+/*
+ Tailwind's automatic source detection skips node_modules, so when this
+ package is installed as a dependency its own templates must be registered
+ explicitly. Paths are relative to this stylesheet.
+*/
+@source '../components';
+@source '../layouts';
+@source '../pages';
+
@plugin '@tailwindcss/forms';
@plugin '@tailwindcss/typography';
@theme {
- --background-image-dots-dark: url('/images/dots-dark.svg');
- --background-image-dots-light: url('/images/dots-light.svg');
+ --background-image-dots-dark: url('../assets/dots-dark.svg');
+ --background-image-dots-light: url('../assets/dots-light.svg');
--background-image-gradient-light: background: radial-gradient(
77% 77% at 50% 0%,
#edecfc 0%,
diff --git a/src/svgs/404-dark.svg b/packages/starpod/src/svgs/404-dark.svg
similarity index 100%
rename from src/svgs/404-dark.svg
rename to packages/starpod/src/svgs/404-dark.svg
diff --git a/src/svgs/404-light.svg b/packages/starpod/src/svgs/404-light.svg
similarity index 100%
rename from src/svgs/404-light.svg
rename to packages/starpod/src/svgs/404-light.svg
diff --git a/src/svgs/apple.svg b/packages/starpod/src/svgs/apple.svg
similarity index 100%
rename from src/svgs/apple.svg
rename to packages/starpod/src/svgs/apple.svg
diff --git a/src/svgs/overcast.svg b/packages/starpod/src/svgs/overcast.svg
similarity index 100%
rename from src/svgs/overcast.svg
rename to packages/starpod/src/svgs/overcast.svg
diff --git a/src/svgs/pocket-casts.svg b/packages/starpod/src/svgs/pocket-casts.svg
similarity index 100%
rename from src/svgs/pocket-casts.svg
rename to packages/starpod/src/svgs/pocket-casts.svg
diff --git a/src/svgs/spotify.svg b/packages/starpod/src/svgs/spotify.svg
similarity index 100%
rename from src/svgs/spotify.svg
rename to packages/starpod/src/svgs/spotify.svg
diff --git a/src/svgs/ufo-dark.svg b/packages/starpod/src/svgs/ufo-dark.svg
similarity index 100%
rename from src/svgs/ufo-dark.svg
rename to packages/starpod/src/svgs/ufo-dark.svg
diff --git a/src/svgs/ufo-light.svg b/packages/starpod/src/svgs/ufo-light.svg
similarity index 100%
rename from src/svgs/ufo-light.svg
rename to packages/starpod/src/svgs/ufo-light.svg
diff --git a/src/svgs/youtube.svg b/packages/starpod/src/svgs/youtube.svg
similarity index 100%
rename from src/svgs/youtube.svg
rename to packages/starpod/src/svgs/youtube.svg
diff --git a/packages/starpod/src/utils/config.ts b/packages/starpod/src/utils/config.ts
new file mode 100644
index 00000000..3a4ba681
--- /dev/null
+++ b/packages/starpod/src/utils/config.ts
@@ -0,0 +1,161 @@
+import {
+ array,
+ minLength,
+ nonEmpty,
+ object,
+ optional,
+ pipe,
+ safeParse,
+ string,
+ url,
+ type GenericSchema
+} from 'valibot';
+
+export type Host = {
+ /**
+ * The name of the host
+ */
+ name: string;
+ /**
+ * A bio about the host to display
+ */
+ bio: string;
+ /**
+ * A url to an image to use for the host
+ */
+ img: string;
+ /**
+ * A url to the host's GitHub
+ */
+ github?: string;
+ /**
+ * A url to the host's Twitter
+ */
+ twitter?: string;
+ /**
+ * A url to the host's website
+ */
+ website?: string;
+};
+
+export type NavLink = {
+ /**
+ * Link text, e.g. "Store".
+ */
+ label: string;
+ /**
+ * Destination: an external URL or a local path like "/sponsor" for a
+ * custom page you added to your site's src/pages/.
+ */
+ href: string;
+};
+
+export type StarpodConfig = {
+ /**
+ * A very short tagline for your show. Generally, no more than one sentence. Less is more here.
+ */
+ blurb: string;
+ /**
+ * A somewhat longer description of what your show is about. This should still ideally be fairly short, and should usually be 2-4 sentences.
+ */
+ description: string;
+ /**
+ * A list of your show's hosts and their info.
+ */
+ hosts: Array;
+ /**
+ * Links to the platforms your show is available on.
+ */
+ platforms: {
+ apple?: string;
+ appleIdNumber?: string;
+ overcast?: string;
+ pocketCasts?: string;
+ spotify?: string;
+ youtube?: string;
+ };
+ /**
+ * The url to the RSS feed where your podcast is hosted.
+ */
+ rssFeed: string;
+ /**
+ * Extra navigation links shown after About and Contact β e.g. a merch
+ * store, or custom pages your site adds (like a sponsor page).
+ */
+ links?: Array;
+};
+
+const urlField = (name: string) =>
+ pipe(string(`${name} must be a string`), url(`${name} must be a valid URL`));
+
+const HostSchema: GenericSchema = object({
+ name: pipe(string(), nonEmpty('every host needs a name')),
+ bio: string('every host needs a bio (an empty string is fine)'),
+ img: pipe(
+ string(),
+ nonEmpty(
+ "every host needs an img β a filename inside your site's src/img/people/"
+ )
+ ),
+ github: optional(urlField('host github')),
+ twitter: optional(urlField('host twitter')),
+ website: optional(urlField('host website'))
+});
+
+const NavLinkSchema: GenericSchema = object({
+ label: pipe(string(), nonEmpty('every link needs a label')),
+ href: pipe(string(), nonEmpty('every link needs an href'))
+});
+
+const StarpodConfigSchema: GenericSchema = object({
+ blurb: pipe(
+ string('blurb must be a string'),
+ nonEmpty('blurb is required β a one-line tagline for your show')
+ ),
+ description: pipe(
+ string('description must be a string'),
+ nonEmpty('description is required β a few sentences about your show')
+ ),
+ hosts: pipe(
+ array(HostSchema, 'hosts must be an array'),
+ minLength(1, 'add at least one host')
+ ),
+ platforms: object(
+ {
+ apple: optional(urlField('platforms.apple')),
+ appleIdNumber: optional(string()),
+ overcast: optional(urlField('platforms.overcast')),
+ pocketCasts: optional(urlField('platforms.pocketCasts')),
+ spotify: optional(urlField('platforms.spotify')),
+ youtube: optional(urlField('platforms.youtube'))
+ },
+ 'platforms is required (an empty object is fine)'
+ ),
+ rssFeed: urlField('rssFeed'),
+ links: optional(array(NavLinkSchema, 'links must be an array'))
+});
+
+/**
+ * Validates a Starpod config, throwing a readable error listing every
+ * problem. Runs both from `defineStarpodConfig` (so mistakes surface the
+ * moment the config file loads) and inside the integration (so a config
+ * that skipped the helper is still checked).
+ */
+export function validateStarpodConfig(config: StarpodConfig): StarpodConfig {
+ const result = safeParse(StarpodConfigSchema, config);
+ if (!result.success) {
+ const problems = result.issues
+ .map((issue) => {
+ const path = issue.path?.map((segment) => segment.key).join('.');
+ return ` - ${path ? `${path}: ` : ''}${issue.message}`;
+ })
+ .join('\n');
+ throw new Error(
+ `[starpod] Invalid Starpod config:\n${problems}\n\nSee https://github.com/shipshapecode/starpod#configuration for the full reference.`
+ );
+ }
+ return result.output;
+}
+
+export const defineStarpodConfig = (config: StarpodConfig) =>
+ validateStarpodConfig(config);
diff --git a/src/utils/dasherize.ts b/packages/starpod/src/utils/dasherize.ts
similarity index 100%
rename from src/utils/dasherize.ts
rename to packages/starpod/src/utils/dasherize.ts
diff --git a/src/utils/truncate.ts b/packages/starpod/src/utils/truncate.ts
similarity index 100%
rename from src/utils/truncate.ts
rename to packages/starpod/src/utils/truncate.ts
diff --git a/packages/starpod/src/vercel-md-negotiation.d.mts b/packages/starpod/src/vercel-md-negotiation.d.mts
new file mode 100644
index 00000000..bc6112db
--- /dev/null
+++ b/packages/starpod/src/vercel-md-negotiation.d.mts
@@ -0,0 +1,27 @@
+interface VercelRoute {
+ src?: string;
+ dest?: string;
+ headers?: Record;
+ status?: number;
+ handle?: string;
+ has?: Array<{ type: string; key: string; value: string }>;
+ continue?: boolean;
+}
+
+interface NegotiationRoute extends VercelRoute {
+ src: string;
+}
+
+interface VercelOutputConfig {
+ routes: VercelRoute[];
+ [key: string]: unknown;
+}
+
+export function collectMarkdownPaths(staticDir: string): string[];
+export function pagesToMarkdownPaths(pathnames: string[]): string[];
+export function buildNegotiationRoutes(mdPaths: string[]): NegotiationRoute[];
+export function patchConfig(
+ config: VercelOutputConfig,
+ mdPaths: string[]
+): { config: VercelOutputConfig; inserted: number };
+export function main(outputDir?: string, mdPaths?: string[] | null): void;
diff --git a/scripts/vercel-md-negotiation.mjs b/packages/starpod/src/vercel-md-negotiation.mjs
similarity index 89%
rename from scripts/vercel-md-negotiation.mjs
rename to packages/starpod/src/vercel-md-negotiation.mjs
index ca18f9b3..cf3bac45 100644
--- a/scripts/vercel-md-negotiation.mjs
+++ b/packages/starpod/src/vercel-md-negotiation.mjs
@@ -54,6 +54,20 @@ export function collectMarkdownPaths(staticDir) {
return paths.sort();
}
+/**
+ * Derive negotiated URL paths from Astro's generated page pathnames (as given
+ * to the `astro:build:done` hook), e.g. 'about.html.md' -> '/about'. Used by
+ * the integration, where the static output directory is not yet populated at
+ * hook time.
+ */
+export function pagesToMarkdownPaths(pathnames) {
+ return pathnames
+ .map((p) => p.replace(/^\/+/, '').replace(/\/+$/, ''))
+ .filter((p) => p.endsWith(MD_SUFFIX))
+ .map((p) => '/' + p.slice(0, -MD_SUFFIX.length))
+ .sort();
+}
+
const escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const chunk = (items, size) => {
@@ -171,11 +185,11 @@ export function patchConfig(config, mdPaths) {
return { config: { ...config, routes }, inserted: negotiationRoutes.length };
}
-export function main(outputDir = '.vercel/output') {
+export function main(outputDir = '.vercel/output', mdPaths = null) {
const configPath = join(outputDir, 'config.json');
const staticDir = join(outputDir, 'static');
- if (!existsSync(configPath) || !existsSync(staticDir)) {
+ if (!existsSync(configPath) || (mdPaths === null && !existsSync(staticDir))) {
console.log(
`[md-negotiation] No Vercel build output at ${outputDir}, skipping`
);
@@ -183,7 +197,9 @@ export function main(outputDir = '.vercel/output') {
}
const config = JSON.parse(readFileSync(configPath, 'utf-8'));
- const mdPaths = collectMarkdownPaths(staticDir);
+ if (mdPaths === null) {
+ mdPaths = collectMarkdownPaths(staticDir);
+ }
const { config: patched, inserted } = patchConfig(config, mdPaths);
if (inserted === 0) {
diff --git a/packages/starpod/src/virtual.d.ts b/packages/starpod/src/virtual.d.ts
new file mode 100644
index 00000000..01018735
--- /dev/null
+++ b/packages/starpod/src/virtual.d.ts
@@ -0,0 +1,16 @@
+declare module 'virtual:starpod/config' {
+ const config: import('./utils/config').StarpodConfig;
+ export default config;
+ /** Whether the guests/sponsors database was enabled via integration options. */
+ export const database: boolean;
+}
+
+declare module 'virtual:starpod/user-css' {
+ const noop: Record;
+ export default noop;
+}
+
+declare module 'virtual:starpod/components/*' {
+ const Component: (props: Record) => unknown;
+ export default Component;
+}
diff --git a/packages/starpod/tsconfig.json b/packages/starpod/tsconfig.json
new file mode 100644
index 00000000..4d3cf63a
--- /dev/null
+++ b/packages/starpod/tsconfig.json
@@ -0,0 +1,12 @@
+{
+ "extends": "astro/tsconfigs/strict",
+ "compilerOptions": {
+ "allowSyntheticDefaultImports": true,
+ "esModuleInterop": true,
+ "strictNullChecks": true,
+ "verbatimModuleSyntax": true,
+ "jsx": "react-jsx",
+ "jsxImportSource": "preact"
+ },
+ "include": ["src/**/*"]
+}
diff --git a/playwright.worktree.config.ts b/playwright.worktree.config.ts
new file mode 100644
index 00000000..d01db439
--- /dev/null
+++ b/playwright.worktree.config.ts
@@ -0,0 +1,23 @@
+// Worktree-only override: the user's own dev server occupies :4321 serving
+// the main branch, so e2e here must boot its own server on another port.
+// Not meant to be committed.
+import { defineConfig } from '@playwright/test';
+
+import baseConfig from './playwright.config';
+
+const PORT = 4399;
+
+export default defineConfig({
+ ...baseConfig,
+ reporter: 'list',
+ use: {
+ ...baseConfig.use,
+ baseURL: `http://localhost:${PORT}`
+ },
+ webServer: {
+ command: `pnpm dev --port ${PORT}`,
+ url: `http://localhost:${PORT}`,
+ reuseExistingServer: false,
+ timeout: 180 * 1000
+ }
+});
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 389b06ca..b660fd05 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -16,43 +16,25 @@ importers:
version: 5.1.4(@babel/core@7.29.7)(@types/node@24.12.4)(jiti@2.7.0)(lightningcss@1.32.0)(preact@10.29.2)(rollup@4.60.4)(tsx@4.22.4)(yaml@2.9.0)
'@astrojs/vercel':
specifier: ^10.0.8
- version: 10.0.8(astro@6.4.2(@types/node@24.12.4)(@vercel/functions@3.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.4)(yaml@2.9.0))(react@19.0.0)(rollup@4.60.4)
+ version: 10.0.8(astro@6.4.2(@types/node@24.12.4)(@vercel/functions@3.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.4)(yaml@2.9.0))(encoding@0.1.13)(react@19.0.0)(rollup@4.60.4)
'@bryanguffey/astro-standard-site':
specifier: ^1.0.3
version: 1.0.3(astro@6.4.2(@types/node@24.12.4)(@vercel/functions@3.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.4)(yaml@2.9.0))
- '@libsql/client':
- specifier: ^0.17.3
- version: 0.17.3
- '@preact/signals':
- specifier: ^2.9.1
- version: 2.9.1(preact@10.29.2)
- '@vercel/analytics':
- specifier: ^1.6.1
- version: 1.6.1(react@19.0.0)
- '@vercel/speed-insights':
- specifier: ^1.3.1
- version: 1.3.1(react@19.0.0)
astro:
specifier: 6.4.2
version: 6.4.2(@types/node@24.12.4)(@vercel/functions@3.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.4)(yaml@2.9.0)
- astro-seo-schema:
- specifier: ^5.2.0
- version: 5.2.0(astro@6.4.2(@types/node@24.12.4)(@vercel/functions@3.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.4)(yaml@2.9.0))(schema-dts@1.1.5)
- atropos:
- specifier: ^2.0.2
- version: 2.0.2
drizzle-orm:
specifier: ^0.45.2
version: 0.45.2(@libsql/client@0.17.3)
- preact:
- specifier: ^10.29.2
- version: 10.29.2
+ html-to-text:
+ specifier: ^9.0.5
+ version: 9.0.5
rss-to-json:
specifier: ^2.1.1
version: 2.1.1
- schema-dts:
- specifier: ^1.1.5
- version: 1.1.5
+ starpod:
+ specifier: workspace:*
+ version: link:packages/starpod
valibot:
specifier: ^1.4.1
version: 1.4.1(typescript@5.9.3)
@@ -60,24 +42,12 @@ importers:
'@astrojs/check':
specifier: ^0.9.9
version: 0.9.9(prettier-plugin-astro@0.14.1)(prettier@3.8.3)(typescript@5.9.3)
- '@astrojs/sitemap':
- specifier: ^3.7.3
- version: 3.7.3
'@eslint/js':
specifier: ^9.39.4
version: 9.39.4
'@playwright/test':
specifier: ^1.60.0
version: 1.60.0
- '@tailwindcss/forms':
- specifier: ^0.5.11
- version: 0.5.11(tailwindcss@4.3.0)
- '@tailwindcss/typography':
- specifier: ^0.5.19
- version: 0.5.19(tailwindcss@4.3.0)
- '@tailwindcss/vite':
- specifier: ^4.3.0
- version: 4.3.0(vite@7.3.3(@types/node@24.12.4)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.22.4)(yaml@2.9.0))
'@testing-library/jest-dom':
specifier: ^6.9.1
version: 6.9.1
@@ -111,12 +81,12 @@ importers:
globals:
specifier: ^16.5.0
version: 16.5.0
- html-to-text:
- specifier: ^9.0.5
- version: 9.0.5
jsdom:
specifier: ^27.4.0
version: 27.4.0
+ preact:
+ specifier: ^10.29.2
+ version: 10.29.2
prettier:
specifier: ^3.8.3
version: 3.8.3
@@ -126,6 +96,9 @@ importers:
prettier-plugin-tailwindcss:
specifier: ^0.7.4
version: 0.7.4(prettier-plugin-astro@0.14.1)(prettier@3.8.3)
+ release-plan:
+ specifier: ^0.18.0
+ version: 0.18.0
sharp:
specifier: ^0.34.5
version: 0.34.5
@@ -145,6 +118,73 @@ importers:
specifier: ^4.1.7
version: 4.1.7(@types/node@24.12.4)(jsdom@27.4.0)(vite@7.3.3(@types/node@24.12.4)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.22.4)(yaml@2.9.0))
+ packages/starpod:
+ dependencies:
+ '@astrojs/sitemap':
+ specifier: ^3.7.3
+ version: 3.7.3
+ '@bryanguffey/astro-standard-site':
+ specifier: ^1.0.3
+ version: 1.0.3(astro@6.4.2(@types/node@24.12.4)(@vercel/functions@3.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.4)(yaml@2.9.0))
+ '@libsql/client':
+ specifier: ^0.17.3
+ version: 0.17.3
+ '@preact/signals':
+ specifier: ^2.9.1
+ version: 2.9.1(preact@10.29.2)
+ '@tailwindcss/forms':
+ specifier: ^0.5.11
+ version: 0.5.11(tailwindcss@4.3.0)
+ '@tailwindcss/typography':
+ specifier: ^0.5.19
+ version: 0.5.19(tailwindcss@4.3.0)
+ '@tailwindcss/vite':
+ specifier: ^4.3.0
+ version: 4.3.0(vite@7.3.3(@types/node@24.12.4)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.22.4)(yaml@2.9.0))
+ '@vercel/speed-insights':
+ specifier: ^1.3.1
+ version: 1.3.1(react@19.0.0)
+ astro-seo-schema:
+ specifier: ^5.2.0
+ version: 5.2.0(astro@6.4.2(@types/node@24.12.4)(@vercel/functions@3.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.4)(yaml@2.9.0))(schema-dts@1.1.5)
+ atropos:
+ specifier: ^2.0.2
+ version: 2.0.2
+ drizzle-orm:
+ specifier: ^0.45.2
+ version: 0.45.2(@libsql/client@0.17.3)
+ html-to-text:
+ specifier: ^9.0.5
+ version: 9.0.5
+ rss-to-json:
+ specifier: ^2.1.1
+ version: 2.1.1
+ schema-dts:
+ specifier: ^1.1.5
+ version: 1.1.5
+ tailwindcss:
+ specifier: ^4.3.0
+ version: 4.3.0
+ valibot:
+ specifier: ^1.4.1
+ version: 1.4.1(typescript@5.9.3)
+ devDependencies:
+ '@astrojs/preact':
+ specifier: ^5.1.4
+ version: 5.1.4(@babel/core@7.29.7)(@types/node@24.12.4)(jiti@2.7.0)(lightningcss@1.32.0)(preact@10.29.2)(rollup@4.60.4)(tsx@4.22.4)(yaml@2.9.0)
+ '@types/html-to-text':
+ specifier: ^9.0.4
+ version: 9.0.4
+ astro:
+ specifier: 6.4.2
+ version: 6.4.2(@types/node@24.12.4)(@vercel/functions@3.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.4)(yaml@2.9.0)
+ preact:
+ specifier: ^10.29.2
+ version: 10.29.2
+ typescript:
+ specifier: ^5.9.3
+ version: 5.9.3
+
packages:
'@acemir/cssom@0.9.31':
@@ -1079,6 +1119,9 @@ packages:
'@noble/hashes':
optional: true
+ '@gar/promisify@1.1.3':
+ resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==}
+
'@humanfs/core@0.19.2':
resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==}
engines: {node: '>=18.18.0'}
@@ -1236,6 +1279,10 @@ packages:
cpu: [x64]
os: [win32]
+ '@isaacs/cliui@8.0.2':
+ resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
+ engines: {node: '>=12'}
+
'@isaacs/fs-minipass@4.0.1':
resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==}
engines: {node: '>=18.0.0'}
@@ -1313,6 +1360,18 @@ packages:
cpu: [x64]
os: [win32]
+ '@manypkg/find-root@2.2.3':
+ resolution: {integrity: sha512-jtEZKczWTueJYHjGpxU3KJQ08Gsrf4r6Q2GjmPp/RGk5leeYAA1eyDADSAF+KVCsQ6EwZd/FMcOFCoMhtqdCtQ==}
+ engines: {node: '>=14.18.0'}
+
+ '@manypkg/get-packages@2.2.2':
+ resolution: {integrity: sha512-3+Zd8kLZmsyJFmWTBtY0MAuCErI7yKB2cjMBlujvSVKZ2R/BMXi0kjCXu2dtRlSq/ML86t1FkumT0yreQ3n8OQ==}
+ engines: {node: '>=14.18.0'}
+
+ '@manypkg/tools@1.1.2':
+ resolution: {integrity: sha512-3lBouSuF7CqlseLB+FKES0K4FQ02JrbEoRtJhxnsyB1s5v4AP03gsoohN8jp7DcOImhaR9scYdztq3/sLfk/qQ==}
+ engines: {node: '>=14.18.0'}
+
'@mapbox/node-pre-gyp@2.0.3':
resolution: {integrity: sha512-uwPAhccfFJlsfCxMYTwOdVfOz3xqyj8xYL3zJj8f0pb30tLohnnFPhLuqp4/qoEz8sNxe4SESZedcBojRefIzg==}
engines: {node: '>=18'}
@@ -1333,9 +1392,91 @@ packages:
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
engines: {node: '>= 8'}
+ '@npmcli/fs@1.1.1':
+ resolution: {integrity: sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==}
+
+ '@npmcli/git@6.0.3':
+ resolution: {integrity: sha512-GUYESQlxZRAdhs3UhbB6pVRNUELQOHXwK9ruDkwmCv2aZ5y0SApQzUJCg02p3A7Ue2J5hxvlk1YI53c00NmRyQ==}
+ engines: {node: ^18.17.0 || >=20.5.0}
+
+ '@npmcli/move-file@1.1.2':
+ resolution: {integrity: sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==}
+ engines: {node: '>=10'}
+ deprecated: This functionality has been moved to @npmcli/fs
+
+ '@npmcli/package-json@6.2.0':
+ resolution: {integrity: sha512-rCNLSB/JzNvot0SEyXqWZ7tX2B5dD2a1br2Dp0vSYVo5jh8Z0EZ7lS9TsZ1UtziddB1UfNUaMCc538/HztnJGA==}
+ engines: {node: ^18.17.0 || >=20.5.0}
+
+ '@npmcli/promise-spawn@8.0.3':
+ resolution: {integrity: sha512-Yb00SWaL4F8w+K8YGhQ55+xE4RUNdMHV43WZGsiTM92gS+lC0mGsn7I4hLug7pbao035S6bj3Y3w0cUNGLfmkg==}
+ engines: {node: ^18.17.0 || >=20.5.0}
+
+ '@octokit/auth-token@5.1.2':
+ resolution: {integrity: sha512-JcQDsBdg49Yky2w2ld20IHAlwr8d/d8N6NiOXbtuoPCqzbsiJgF633mVUw3x4mo0H5ypataQIX7SFu3yy44Mpw==}
+ engines: {node: '>= 18'}
+
+ '@octokit/core@6.1.6':
+ resolution: {integrity: sha512-kIU8SLQkYWGp3pVKiYzA5OSaNF5EE03P/R8zEmmrG6XwOg5oBjXyQVVIauQ0dgau4zYhpZEhJrvIYt6oM+zZZA==}
+ engines: {node: '>= 18'}
+
+ '@octokit/endpoint@10.1.4':
+ resolution: {integrity: sha512-OlYOlZIsfEVZm5HCSR8aSg02T2lbUWOsCQoPKfTXJwDzcHQBrVBGdGXb89dv2Kw2ToZaRtudp8O3ZIYoaOjKlA==}
+ engines: {node: '>= 18'}
+
+ '@octokit/graphql@8.2.2':
+ resolution: {integrity: sha512-Yi8hcoqsrXGdt0yObxbebHXFOiUA+2v3n53epuOg1QUgOB6c4XzvisBNVXJSl8RYA5KrDuSL2yq9Qmqe5N0ryA==}
+ engines: {node: '>= 18'}
+
+ '@octokit/openapi-types@24.2.0':
+ resolution: {integrity: sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==}
+
+ '@octokit/openapi-types@25.1.0':
+ resolution: {integrity: sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA==}
+
+ '@octokit/plugin-paginate-rest@11.6.0':
+ resolution: {integrity: sha512-n5KPteiF7pWKgBIBJSk8qzoZWcUkza2O6A0za97pMGVrGfPdltxrfmfF5GucHYvHGZD8BdaZmmHGz5cX/3gdpw==}
+ engines: {node: '>= 18'}
+ peerDependencies:
+ '@octokit/core': '>=6'
+
+ '@octokit/plugin-request-log@5.3.1':
+ resolution: {integrity: sha512-n/lNeCtq+9ofhC15xzmJCNKP2BWTv8Ih2TTy+jatNCCq/gQP/V7rK3fjIfuz0pDWDALO/o/4QY4hyOF6TQQFUw==}
+ engines: {node: '>= 18'}
+ peerDependencies:
+ '@octokit/core': '>=6'
+
+ '@octokit/plugin-rest-endpoint-methods@13.5.0':
+ resolution: {integrity: sha512-9Pas60Iv9ejO3WlAX3maE1+38c5nqbJXV5GrncEfkndIpZrJ/WPMRd2xYDcPPEt5yzpxcjw9fWNoPhsSGzqKqw==}
+ engines: {node: '>= 18'}
+ peerDependencies:
+ '@octokit/core': '>=6'
+
+ '@octokit/request-error@6.1.8':
+ resolution: {integrity: sha512-WEi/R0Jmq+IJKydWlKDmryPcmdYSVjL3ekaiEL1L9eo1sUnqMJ+grqmC9cjk7CA7+b2/T397tO5d8YLOH3qYpQ==}
+ engines: {node: '>= 18'}
+
+ '@octokit/request@9.2.4':
+ resolution: {integrity: sha512-q8ybdytBmxa6KogWlNa818r0k1wlqzNC+yNkcQDECHvQo8Vmstrg18JwqJHdJdUiHD2sjlwBgSm9kHkOKe2iyA==}
+ engines: {node: '>= 18'}
+
+ '@octokit/rest@21.1.1':
+ resolution: {integrity: sha512-sTQV7va0IUVZcntzy1q3QqPm/r8rWtDCqpRAmb8eXXnKkjoQEtFe3Nt5GTVsHft+R6jJoHeSiVLcgcvhtue/rg==}
+ engines: {node: '>= 18'}
+
+ '@octokit/types@13.10.0':
+ resolution: {integrity: sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==}
+
+ '@octokit/types@14.1.0':
+ resolution: {integrity: sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g==}
+
'@oslojs/encoding@1.1.0':
resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==}
+ '@pkgjs/parseargs@0.11.0':
+ resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
+ engines: {node: '>=14'}
+
'@pkgr/core@0.3.6':
resolution: {integrity: sha512-SEeaJLb3qBNF/OaXnaR1NmmBbFYk1zC0ZH/52fATcRPLFg/p791YrcyFFy44Bo9sLaGuSuLp5Q6axbb/O+v/RA==}
engines: {node: ^14.18.0 || >=16.0.0}
@@ -1345,6 +1486,18 @@ packages:
engines: {node: '>=18'}
hasBin: true
+ '@pnpm/config.env-replace@1.1.0':
+ resolution: {integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==}
+ engines: {node: '>=12.22.0'}
+
+ '@pnpm/network.ca-file@1.0.2':
+ resolution: {integrity: sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==}
+ engines: {node: '>=12.22.0'}
+
+ '@pnpm/npm-conf@3.0.3':
+ resolution: {integrity: sha512-//0sR/cow/s4ICQaYoAobOl4aU8cjU6x/V24V7XkKotb9+O+3zySIYp146vpaobYHnxa4pZX8NkV54Z5AwbDKA==}
+ engines: {node: '>=12'}
+
'@preact/preset-vite@2.10.5':
resolution: {integrity: sha512-p0vJpxiVO7KWWazWny3LUZ+saXyZKWv6Ju0bYMWNJRp2YveufRPgSUB1C4MTqGJfz07EehMgfN+AJNwQy+w6Iw==}
peerDependencies:
@@ -1514,6 +1667,9 @@ packages:
cpu: [x64]
os: [win32]
+ '@sec-ant/readable-stream@0.4.1':
+ resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==}
+
'@selderee/plugin-htmlparser2@0.11.0':
resolution: {integrity: sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==}
@@ -1548,6 +1704,10 @@ packages:
'@shikijs/vscode-textmate@10.0.2':
resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==}
+ '@sindresorhus/merge-streams@4.0.0':
+ resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==}
+ engines: {node: '>=18'}
+
'@standard-schema/spec@1.1.0':
resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
@@ -1665,6 +1825,10 @@ packages:
peerDependencies:
preact: '>=10 || ^10.0.0-alpha.0 || ^10.0.0-beta.0'
+ '@tootallnate/once@1.1.2':
+ resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==}
+ engines: {node: '>= 6'}
+
'@types/aria-query@5.0.4':
resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==}
@@ -1905,6 +2069,14 @@ packages:
resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==}
engines: {node: '>= 14'}
+ agentkeepalive@4.6.0:
+ resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==}
+ engines: {node: '>= 8.0.0'}
+
+ aggregate-error@3.1.0:
+ resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==}
+ engines: {node: '>=8'}
+
ajv-draft-04@1.0.0:
resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==}
peerDependencies:
@@ -1923,6 +2095,10 @@ packages:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
+ ansi-regex@6.3.0:
+ resolution: {integrity: sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==}
+ engines: {node: '>=12'}
+
ansi-styles@4.3.0:
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
engines: {node: '>=8'}
@@ -1931,6 +2107,13 @@ packages:
resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==}
engines: {node: '>=10'}
+ ansi-styles@6.2.3:
+ resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==}
+ engines: {node: '>=12'}
+
+ any-promise@1.3.0:
+ resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
+
anymatch@3.1.3:
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
engines: {node: '>= 8'}
@@ -1955,6 +2138,9 @@ packages:
array-iterate@2.0.1:
resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==}
+ assert-never@1.4.0:
+ resolution: {integrity: sha512-5oJg84os6NMQNl27T9LnZkvvqzvAnHu03ShCnoj6bsJwS7L8AO4lf+C/XjK/nvzEqQB744moC6V128RucQd1jA==}
+
assertion-error@2.0.1:
resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
engines: {node: '>=12'}
@@ -2024,6 +2210,9 @@ packages:
engines: {node: '>=6.0.0'}
hasBin: true
+ before-after-hook@3.0.2:
+ resolution: {integrity: sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==}
+
bidi-js@1.0.3:
resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==}
@@ -2036,6 +2225,9 @@ packages:
brace-expansion@1.1.15:
resolution: {integrity: sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==}
+ brace-expansion@2.1.4:
+ resolution: {integrity: sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==}
+
brace-expansion@5.0.6:
resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==}
engines: {node: 18 || 20 || >=22}
@@ -2052,6 +2244,10 @@ packages:
buffer-from@1.1.2:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
+ cacache@15.3.0:
+ resolution: {integrity: sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==}
+ engines: {node: '>= 10'}
+
call-bind-apply-helpers@1.0.2:
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
engines: {node: '>= 0.4'}
@@ -2082,6 +2278,10 @@ packages:
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
engines: {node: '>=10'}
+ chalk@5.6.2:
+ resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==}
+ engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
+
character-entities-html4@2.1.0:
resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==}
@@ -2099,6 +2299,10 @@ packages:
resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==}
engines: {node: '>= 20.19.0'}
+ chownr@2.0.0:
+ resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==}
+ engines: {node: '>=10'}
+
chownr@3.0.0:
resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==}
engines: {node: '>=18'}
@@ -2107,6 +2311,18 @@ packages:
resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==}
engines: {node: '>=8'}
+ clean-stack@2.2.0:
+ resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==}
+ engines: {node: '>=6'}
+
+ cli-highlight@2.1.11:
+ resolution: {integrity: sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==}
+ engines: {node: '>=8.0.0', npm: '>=5.0.0'}
+ hasBin: true
+
+ cliui@7.0.4:
+ resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==}
+
cliui@8.0.1:
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
engines: {node: '>=12'}
@@ -2145,6 +2361,9 @@ packages:
engines: {node: '>=18'}
hasBin: true
+ config-chain@1.1.13:
+ resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==}
+
consola@3.4.2:
resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==}
engines: {node: ^14.18.0 || >=16.10.0}
@@ -2220,6 +2439,10 @@ packages:
resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==}
engines: {node: '>= 0.4'}
+ deep-extend@0.6.0:
+ resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==}
+ engines: {node: '>=4.0.0'}
+
deep-is@0.1.4:
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
@@ -2394,6 +2617,9 @@ packages:
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
engines: {node: '>= 0.4'}
+ eastasianwidth@0.2.0:
+ resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
+
electron-to-chromium@1.5.364:
resolution: {integrity: sha512-G/dYE3+AYhyHwzTwg8UbnXf7zqMERYh7l2jJ3QujhFsH8agSYwtnGAR2aZ7f0AakIKJXd5En/Hre4igIUrdlYw==}
@@ -2403,6 +2629,12 @@ packages:
emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
+ emoji-regex@9.2.2:
+ resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
+
+ encoding@0.1.13:
+ resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==}
+
enhanced-resolve@5.22.1:
resolution: {integrity: sha512-6QEuw3zoX1SJQc7b87aBXke/no+mG2bTBgw29gWMQonLmpEkWoCAVkl+M49e48AZlWzxiDzDZzYdp6kobcyLww==}
engines: {node: '>=10.13.0'}
@@ -2423,6 +2655,9 @@ packages:
resolution: {integrity: sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==}
engines: {node: '>=20.19.0'}
+ err-code@2.0.3:
+ resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==}
+
es-define-property@1.0.1:
resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
engines: {node: '>= 0.4'}
@@ -2508,6 +2743,7 @@ packages:
eslint@9.39.4:
resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options.
hasBin: true
peerDependencies:
jiti: '*'
@@ -2544,6 +2780,14 @@ packages:
eventemitter3@5.0.4:
resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==}
+ execa@5.1.1:
+ resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
+ engines: {node: '>=10'}
+
+ execa@9.6.1:
+ resolution: {integrity: sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==}
+ engines: {node: ^18.19.0 || >=20.5.0}
+
expect-type@1.3.0:
resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==}
engines: {node: '>=12.0.0'}
@@ -2551,6 +2795,9 @@ packages:
extend@3.0.2:
resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
+ fast-content-type-parse@2.0.1:
+ resolution: {integrity: sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q==}
+
fast-deep-equal@3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
@@ -2592,6 +2839,10 @@ packages:
picomatch:
optional: true
+ figures@6.1.0:
+ resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==}
+ engines: {node: '>=18'}
+
file-entry-cache@8.0.0:
resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
engines: {node: '>=16.0.0'}
@@ -2638,10 +2889,25 @@ packages:
resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==}
engines: {node: '>= 0.4'}
+ foreground-child@3.3.1:
+ resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
+ engines: {node: '>=14'}
+
form-data@4.0.5:
resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==}
engines: {node: '>= 6'}
+ fs-extra@11.4.0:
+ resolution: {integrity: sha512-EQsFzMUJkCKGr1ePqlYADkIUmHW1s3ZXr5Yqy6wbGrfUCphpl2maM/kyOIRA2HpP3AaFQTZXD4ldjek+nccddA==}
+ engines: {node: '>=14.14'}
+
+ fs-minipass@2.1.0:
+ resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==}
+ engines: {node: '>= 8'}
+
+ fs.realpath@1.0.0:
+ resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
+
fsevents@2.3.2:
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@@ -2674,6 +2940,14 @@ packages:
resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
engines: {node: '>= 0.4'}
+ get-stream@6.0.1:
+ resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
+ engines: {node: '>=10'}
+
+ get-stream@9.0.1:
+ resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==}
+ engines: {node: '>=18'}
+
get-tsconfig@4.14.0:
resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==}
@@ -2681,6 +2955,11 @@ packages:
resolution: {integrity: sha512-7nF7C9fIPFEMHgEMEfgIlO9wDdZ8CyHw27rWciFZfHvHDReIiPhsYuzPRXsfvBCqFy1l8RRyyWV7QLM+ZhUJsQ==}
engines: {node: '>=20.20.0'}
+ github-changelog@2.1.4:
+ resolution: {integrity: sha512-mZQF/YC9OR8XMGpYlLQqG66RiKwlaQZ7rXTZug28oOYkzOXd0acszuvYHVzPlYmns1aDDSwQkbzFxNOYpWhmig==}
+ engines: {node: 18.* || 20.* || >= 22}
+ hasBin: true
+
github-slugger@2.0.0:
resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==}
@@ -2692,10 +2971,19 @@ packages:
resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
engines: {node: '>=10.13.0'}
+ glob@10.5.0:
+ resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==}
+ deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
+ hasBin: true
+
glob@13.0.6:
resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==}
engines: {node: 18 || 20 || >=22}
+ glob@7.2.3:
+ resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
+ deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
+
globals@14.0.0:
resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==}
engines: {node: '>=18'}
@@ -2708,6 +2996,9 @@ packages:
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
engines: {node: '>= 0.4'}
+ graceful-fs@4.2.10:
+ resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==}
+
graceful-fs@4.2.11:
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
@@ -2771,6 +3062,17 @@ packages:
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
hasBin: true
+ highlight.js@10.7.3:
+ resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==}
+
+ hosted-git-info@4.1.0:
+ resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==}
+ engines: {node: '>=10'}
+
+ hosted-git-info@8.1.0:
+ resolution: {integrity: sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw==}
+ engines: {node: ^18.17.0 || >=20.5.0}
+
html-encoding-sniffer@6.0.0:
resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==}
engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
@@ -2791,6 +3093,10 @@ packages:
http-cache-semantics@4.2.0:
resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==}
+ http-proxy-agent@4.0.1:
+ resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==}
+ engines: {node: '>= 6'}
+
http-proxy-agent@7.0.2:
resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==}
engines: {node: '>= 14'}
@@ -2803,6 +3109,21 @@ packages:
resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==}
engines: {node: '>= 14'}
+ human-signals@2.1.0:
+ resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
+ engines: {node: '>=10.17.0'}
+
+ human-signals@8.0.1:
+ resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==}
+ engines: {node: '>=18.18.0'}
+
+ humanize-ms@1.2.1:
+ resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==}
+
+ iconv-lite@0.6.3:
+ resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
+ engines: {node: '>=0.10.0'}
+
ignore@5.3.2:
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
engines: {node: '>= 4'}
@@ -2819,10 +3140,31 @@ packages:
resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==}
engines: {node: '>=8'}
+ infer-owner@1.0.4:
+ resolution: {integrity: sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==}
+
+ inflight@1.0.6:
+ resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
+ deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
+
+ inherits@2.0.4:
+ resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+
+ ini@1.3.8:
+ resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
+
+ ini@5.0.0:
+ resolution: {integrity: sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==}
+ engines: {node: ^18.17.0 || >=20.5.0}
+
internal-slot@1.1.0:
resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==}
engines: {node: '>= 0.4'}
+ ip-address@10.5.0:
+ resolution: {integrity: sha512-R5SnVLJmgYYvf2F2ZgwSBnelz5G4q5AxIC277GDfUaNbrZKNANcBC7RHqYYePlszf4kBolVkJauG0ZjHHFh55g==}
+ engines: {node: '>= 12'}
+
iron-webcrypto@1.2.1:
resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==}
@@ -2877,6 +3219,9 @@ packages:
engines: {node: '>=14.16'}
hasBin: true
+ is-lambda@1.0.1:
+ resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==}
+
is-map@2.0.3:
resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==}
engines: {node: '>= 0.4'}
@@ -2908,6 +3253,14 @@ packages:
resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==}
engines: {node: '>= 0.4'}
+ is-stream@2.0.1:
+ resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
+ engines: {node: '>=8'}
+
+ is-stream@4.0.1:
+ resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==}
+ engines: {node: '>=18'}
+
is-string@1.1.1:
resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==}
engines: {node: '>= 0.4'}
@@ -2916,6 +3269,10 @@ packages:
resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==}
engines: {node: '>= 0.4'}
+ is-unicode-supported@2.1.0:
+ resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==}
+ engines: {node: '>=18'}
+
is-weakmap@2.0.2:
resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==}
engines: {node: '>= 0.4'}
@@ -2934,13 +3291,23 @@ packages:
isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+ isexe@3.1.5:
+ resolution: {integrity: sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==}
+ engines: {node: '>=18'}
+
iso-datestring-validator@2.2.2:
resolution: {integrity: sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA==}
+ jackspeak@3.4.3:
+ resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
+
jiti@2.7.0:
resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==}
hasBin: true
+ jju@1.4.0:
+ resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==}
+
js-base64@3.7.8:
resolution: {integrity: sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==}
@@ -2968,6 +3335,10 @@ packages:
json-buffer@3.0.1:
resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
+ json-parse-even-better-errors@4.0.0:
+ resolution: {integrity: sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==}
+ engines: {node: ^18.17.0 || >=20.5.0}
+
json-schema-traverse@0.4.1:
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
@@ -2988,6 +3359,9 @@ packages:
jsonc-parser@3.3.1:
resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==}
+ jsonfile@6.2.1:
+ resolution: {integrity: sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==}
+
keyv@4.5.4:
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
@@ -2998,6 +3372,14 @@ packages:
kolorist@1.8.0:
resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==}
+ ky@1.14.3:
+ resolution: {integrity: sha512-9zy9lkjac+TR1c2tG+mkNSVlyOpInnWdSMiue4F+kq8TwJSgv6o8jhLRg8Ho6SnZ9wOYUq/yozts9qQCfk7bIw==}
+ engines: {node: '>=18'}
+
+ latest-version@9.0.0:
+ resolution: {integrity: sha512-7W0vV3rqv5tokqkBAFV1LbR7HPOWzXQDpDgEuib/aJ1jsZZx6x3c2mBI+TJhJzOhkGeaLbCKEHXEXLfirtG2JA==}
+ engines: {node: '>=18'}
+
leac@0.6.0:
resolution: {integrity: sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==}
@@ -3090,6 +3472,9 @@ packages:
longest-streak@3.1.0:
resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
+ lru-cache@10.4.3:
+ resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
+
lru-cache@11.5.1:
resolution: {integrity: sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==}
engines: {node: 20 || >=22}
@@ -3097,6 +3482,10 @@ packages:
lru-cache@5.1.1:
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
+ lru-cache@6.0.0:
+ resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
+ engines: {node: '>=10'}
+
lz-string@1.5.0:
resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==}
hasBin: true
@@ -3107,6 +3496,10 @@ packages:
magicast@0.5.3:
resolution: {integrity: sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==}
+ make-fetch-happen@9.1.0:
+ resolution: {integrity: sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==}
+ engines: {node: '>= 10'}
+
markdown-table@3.0.4:
resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==}
@@ -3159,6 +3552,9 @@ packages:
mdn-data@2.27.1:
resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==}
+ merge-stream@2.0.0:
+ resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
+
merge2@1.4.1:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
engines: {node: '>= 8'}
@@ -3259,6 +3655,10 @@ packages:
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
engines: {node: '>= 0.6'}
+ mimic-fn@2.1.0:
+ resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
+ engines: {node: '>=6'}
+
min-indent@1.0.1:
resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
engines: {node: '>=4'}
@@ -3274,14 +3674,58 @@ packages:
minimatch@3.1.5:
resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==}
+ minimatch@9.0.9:
+ resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ minimist@1.2.8:
+ resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+
+ minipass-collect@1.0.2:
+ resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==}
+ engines: {node: '>= 8'}
+
+ minipass-fetch@1.4.1:
+ resolution: {integrity: sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==}
+ engines: {node: '>=8'}
+
+ minipass-flush@1.0.7:
+ resolution: {integrity: sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA==}
+ engines: {node: '>= 8'}
+
+ minipass-pipeline@1.2.4:
+ resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==}
+ engines: {node: '>=8'}
+
+ minipass-sized@1.0.3:
+ resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==}
+ engines: {node: '>=8'}
+
+ minipass@3.3.6:
+ resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==}
+ engines: {node: '>=8'}
+
+ minipass@5.0.0:
+ resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==}
+ engines: {node: '>=8'}
+
minipass@7.1.3:
resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==}
engines: {node: '>=16 || 14 >=14.17'}
+ minizlib@2.1.2:
+ resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==}
+ engines: {node: '>= 8'}
+
minizlib@3.1.0:
resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==}
engines: {node: '>= 18'}
+ mkdirp@1.0.4:
+ resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==}
+ engines: {node: '>=10'}
+ hasBin: true
+
mrmime@2.0.1:
resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==}
engines: {node: '>=10'}
@@ -3295,6 +3739,9 @@ packages:
multiformats@9.9.0:
resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==}
+ mz@2.7.0:
+ resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
+
nanoid@3.3.12:
resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
@@ -3303,6 +3750,10 @@ packages:
natural-compare@1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
+ negotiator@0.6.4:
+ resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==}
+ engines: {node: '>= 0.6'}
+
neotraverse@0.6.18:
resolution: {integrity: sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==}
engines: {node: '>= 10'}
@@ -3345,9 +3796,37 @@ packages:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'}
+ npm-install-checks@7.1.2:
+ resolution: {integrity: sha512-z9HJBCYw9Zr8BqXcllKIs5nI+QggAImbBdHphOzVYrz2CB4iQ6FzWyKmlqDZua+51nAu7FcemlbTc9VgQN5XDQ==}
+ engines: {node: ^18.17.0 || >=20.5.0}
+
+ npm-normalize-package-bin@4.0.0:
+ resolution: {integrity: sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==}
+ engines: {node: ^18.17.0 || >=20.5.0}
+
+ npm-package-arg@12.0.2:
+ resolution: {integrity: sha512-f1NpFjNI9O4VbKMOlA5QoBq/vSQPORHcTZ2feJpFkTHJ9eQkdlmZEKSjcAhxTGInC7RlEyScT9ui67NaOsjFWA==}
+ engines: {node: ^18.17.0 || >=20.5.0}
+
+ npm-pick-manifest@10.0.0:
+ resolution: {integrity: sha512-r4fFa4FqYY8xaM7fHecQ9Z2nE9hgNfJR+EmoKv0+chvzWkBcORX3r0FpTByP+CbOVJDladMXnPQGVN8PBLGuTQ==}
+ engines: {node: ^18.17.0 || >=20.5.0}
+
+ npm-run-path@4.0.1:
+ resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
+ engines: {node: '>=8'}
+
+ npm-run-path@6.0.0:
+ resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==}
+ engines: {node: '>=18'}
+
nth-check@2.1.1:
resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
+ object-assign@4.1.1:
+ resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
+ engines: {node: '>=0.10.0'}
+
object-inspect@1.13.4:
resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
engines: {node: '>= 0.4'}
@@ -3373,6 +3852,13 @@ packages:
ohash@2.0.11:
resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==}
+ once@1.4.0:
+ resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
+
+ onetime@5.1.2:
+ resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
+ engines: {node: '>=6'}
+
oniguruma-parser@0.12.2:
resolution: {integrity: sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==}
@@ -3395,6 +3881,14 @@ packages:
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
engines: {node: '>=10'}
+ p-map@3.0.0:
+ resolution: {integrity: sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==}
+ engines: {node: '>=8'}
+
+ p-map@4.0.0:
+ resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==}
+ engines: {node: '>=10'}
+
p-queue@9.3.0:
resolution: {integrity: sha512-7NED7xhQ74Ngp4JP/2e0VZHp7vSWfJfqeiR92jPgxsz6m0Se4P03YoTKa9dDXyZ3r6P616gUXttrB6nnHYKang==}
engines: {node: '>=20'}
@@ -3403,6 +3897,13 @@ packages:
resolution: {integrity: sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==}
engines: {node: '>=20'}
+ package-json-from-dist@1.0.1:
+ resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
+
+ package-json@10.0.1:
+ resolution: {integrity: sha512-ua1L4OgXSBdsu1FPb7F3tYH0F48a6kxvod4pLUlGY9COeJAJQNX/sNH2IiEmsxw7lqYiAwrdHMjz1FctOsyDQg==}
+ engines: {node: '>=18'}
+
package-manager-detector@1.6.0:
resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==}
@@ -3410,9 +3911,25 @@ packages:
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
engines: {node: '>=6'}
+ parse-github-repo-url@1.4.1:
+ resolution: {integrity: sha512-bSWyzBKqcSL4RrncTpGsEKoJ7H8a4L3++ifTAbTFeMHyq2wRV+42DGmQcHIrJIvdcacjIOxEuKH/w4tthF17gg==}
+
parse-latin@7.0.0:
resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==}
+ parse-ms@4.0.0:
+ resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==}
+ engines: {node: '>=18'}
+
+ parse5-htmlparser2-tree-adapter@6.0.1:
+ resolution: {integrity: sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==}
+
+ parse5@5.1.1:
+ resolution: {integrity: sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==}
+
+ parse5@6.0.1:
+ resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==}
+
parse5@7.3.0:
resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==}
@@ -3429,10 +3946,22 @@ packages:
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
engines: {node: '>=8'}
+ path-is-absolute@1.0.1:
+ resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
+ engines: {node: '>=0.10.0'}
+
path-key@3.1.1:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
engines: {node: '>=8'}
+ path-key@4.0.0:
+ resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==}
+ engines: {node: '>=12'}
+
+ path-scurry@1.11.1:
+ resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
+ engines: {node: '>=16 || 14 >=14.18'}
+
path-scurry@2.0.2:
resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==}
engines: {node: 18 || 20 || >=22}
@@ -3569,16 +4098,43 @@ packages:
resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+ pretty-ms@9.3.0:
+ resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==}
+ engines: {node: '>=18'}
+
prismjs@1.30.0:
resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==}
engines: {node: '>=6'}
+ proc-log@5.0.0:
+ resolution: {integrity: sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==}
+ engines: {node: ^18.17.0 || >=20.5.0}
+
+ progress@2.0.3:
+ resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==}
+ engines: {node: '>=0.4.0'}
+
+ promise-inflight@1.0.1:
+ resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==}
+ peerDependencies:
+ bluebird: '*'
+ peerDependenciesMeta:
+ bluebird:
+ optional: true
+
promise-limit@2.7.0:
resolution: {integrity: sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw==}
+ promise-retry@2.0.1:
+ resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==}
+ engines: {node: '>=10'}
+
property-information@7.1.0:
resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==}
+ proto-list@1.2.4:
+ resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==}
+
proxy-from-env@2.1.0:
resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==}
engines: {node: '>=10'}
@@ -3593,6 +4149,10 @@ packages:
radix3@1.1.2:
resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==}
+ rc@1.2.8:
+ resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
+ hasBin: true
+
react-is@17.0.2:
resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
@@ -3625,6 +4185,14 @@ packages:
resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==}
engines: {node: '>= 0.4'}
+ registry-auth-token@5.1.1:
+ resolution: {integrity: sha512-P7B4+jq8DeD2nMsAcdfaqHbssgHtZ7Z5+++a5ask90fvmJ8p5je4mOa+wzu+DB4vQ5tdJV/xywY+UnVFeQLV5Q==}
+ engines: {node: '>=14'}
+
+ registry-url@6.0.1:
+ resolution: {integrity: sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==}
+ engines: {node: '>=12'}
+
rehype-parse@9.0.1:
resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==}
@@ -3637,6 +4205,10 @@ packages:
rehype@13.0.2:
resolution: {integrity: sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==}
+ release-plan@0.18.0:
+ resolution: {integrity: sha512-WzP+O+XRF4AqhTDQK84FovY+TxHyC8J7QWoOwxnrvVjyHns417l1FUldboRhBYua5Pej6Yg/2jH1dEH2MRNHeA==}
+ hasBin: true
+
remark-gfm@4.0.1:
resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==}
@@ -3690,10 +4262,19 @@ packages:
retext@9.0.0:
resolution: {integrity: sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==}
+ retry@0.12.0:
+ resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==}
+ engines: {node: '>= 4'}
+
reusify@1.1.0:
resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+ rimraf@3.0.2:
+ resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
+ deprecated: Rimraf versions prior to v4 are no longer supported
+ hasBin: true
+
rollup@4.60.4:
resolution: {integrity: sha512-WHeFSbZYsPu3+bLoNRUuAO+wavNlocOPf3wSHTP7hcFKVnJeWsYlCDbr3mTS14FCizf9ccIxXA8sGL8zKeQN3g==}
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
@@ -3715,6 +4296,9 @@ packages:
resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==}
engines: {node: '>= 0.4'}
+ safer-buffer@2.1.2:
+ resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
+
sass-formatter@0.7.9:
resolution: {integrity: sha512-CWZ8XiSim+fJVG0cFLStwDvft1VI7uvXdCNJYXhDvowiv+DsbD1nXLiQ4zrE5UBvj5DWZJ93cwN0NX5PMsr1Pw==}
@@ -3788,6 +4372,13 @@ packages:
siginfo@2.0.0:
resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
+ signal-exit@3.0.7:
+ resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
+
+ signal-exit@4.1.0:
+ resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
+ engines: {node: '>=14'}
+
simple-code-frame@1.3.0:
resolution: {integrity: sha512-MB4pQmETUBlNs62BBeRjIFGeuy/x6gGKh7+eRUemn1rCFhqo7K+4slPqsyizCbcbYLnaYqaoZ2FWsZ/jN06D8w==}
@@ -3799,10 +4390,22 @@ packages:
engines: {node: '>=20.19.5', npm: '>=10.8.2'}
hasBin: true
+ smart-buffer@4.2.0:
+ resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==}
+ engines: {node: '>= 6.0.0', npm: '>= 3.0.0'}
+
smol-toml@1.6.1:
resolution: {integrity: sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==}
engines: {node: '>= 18'}
+ socks-proxy-agent@6.2.1:
+ resolution: {integrity: sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==}
+ engines: {node: '>= 10'}
+
+ socks@2.8.9:
+ resolution: {integrity: sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw==}
+ engines: {node: '>= 10.0.0', npm: '>= 3.0.0'}
+
source-map-js@1.2.1:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'}
@@ -3821,6 +4424,22 @@ packages:
space-separated-tokens@2.0.2:
resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
+ spdx-correct@3.2.0:
+ resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==}
+
+ spdx-exceptions@2.5.0:
+ resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==}
+
+ spdx-expression-parse@3.0.1:
+ resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==}
+
+ spdx-license-ids@3.0.23:
+ resolution: {integrity: sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==}
+
+ ssri@8.0.1:
+ resolution: {integrity: sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==}
+ engines: {node: '>= 8'}
+
stack-trace@1.0.0:
resolution: {integrity: sha512-H6D7134xi6qONvh7ZHKgviXf+rd3vhGBSvebPZCaUkd8zvQ+7PtDw6CljPTe4cXWNf2IKZGNqw6VJXSb9IgBpA==}
engines: {node: '>=20.0.0'}
@@ -3842,6 +4461,10 @@ packages:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
+ string-width@5.1.2:
+ resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
+ engines: {node: '>=12'}
+
stringify-entities@4.0.4:
resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==}
@@ -3849,10 +4472,26 @@ packages:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
engines: {node: '>=8'}
+ strip-ansi@7.2.0:
+ resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==}
+ engines: {node: '>=12'}
+
+ strip-final-newline@2.0.0:
+ resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
+ engines: {node: '>=6'}
+
+ strip-final-newline@4.0.0:
+ resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==}
+ engines: {node: '>=18'}
+
strip-indent@3.0.0:
resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==}
engines: {node: '>=8'}
+ strip-json-comments@2.0.1:
+ resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==}
+ engines: {node: '>=0.10.0'}
+
strip-json-comments@3.1.1:
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
engines: {node: '>=8'}
@@ -3890,10 +4529,22 @@ packages:
resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==}
engines: {node: '>=6'}
+ tar@6.2.1:
+ resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==}
+ engines: {node: '>=10'}
+ deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
+
tar@7.5.15:
resolution: {integrity: sha512-dzGK0boVlC4W5QFuQN1EFSl3bIDYsk7Tj40U6eIBnK2k/8ml7TZ5agbI5j5+qnoVcAA+rNtBml8SEiLxZpNqRQ==}
engines: {node: '>=18'}
+ thenify-all@1.6.0:
+ resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
+ engines: {node: '>=0.8'}
+
+ thenify@3.3.1:
+ resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
+
tiny-inflate@1.0.3:
resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==}
@@ -3999,12 +4650,22 @@ packages:
unicode-segmenter@0.14.5:
resolution: {integrity: sha512-jHGmj2LUuqDcX3hqY12Ql+uhUTn8huuxNZGq7GvtF6bSybzH3aFgedYu/KTzQStEgt1Ra2F3HxadNXsNjb3m3g==}
+ unicorn-magic@0.3.0:
+ resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==}
+ engines: {node: '>=18'}
+
unified@11.0.5:
resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==}
unifont@0.7.4:
resolution: {integrity: sha512-oHeis4/xl42HUIeHuNZRGEvxj5AaIKR+bHPNegRq5LV1gdc3jundpONbjglKpihmJf+dswygdMJn3eftGIMemg==}
+ unique-filename@1.1.1:
+ resolution: {integrity: sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==}
+
+ unique-slug@2.0.2:
+ resolution: {integrity: sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==}
+
unist-util-find-after@5.0.0:
resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==}
@@ -4032,6 +4693,13 @@ packages:
unist-util-visit@5.1.0:
resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==}
+ universal-user-agent@7.0.3:
+ resolution: {integrity: sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==}
+
+ universalify@2.0.1:
+ resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
+ engines: {node: '>= 10.0.0'}
+
unstorage@1.17.5:
resolution: {integrity: sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg==}
peerDependencies:
@@ -4114,6 +4782,13 @@ packages:
typescript:
optional: true
+ validate-npm-package-license@3.0.4:
+ resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==}
+
+ validate-npm-package-name@6.0.2:
+ resolution: {integrity: sha512-IUoow1YUtvoBBC06dXs8bR8B9vuA3aJfmQNKMoaPG/OFsPmoQvw8xh+6Ye25Gx9DQhoEom3Pcu9MKHerm/NpUQ==}
+ engines: {node: ^18.17.0 || >=20.5.0}
+
vfile-location@5.0.3:
resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==}
@@ -4359,6 +5034,11 @@ packages:
engines: {node: '>= 8'}
hasBin: true
+ which@5.0.0:
+ resolution: {integrity: sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==}
+ engines: {node: ^18.17.0 || >=20.5.0}
+ hasBin: true
+
why-is-node-running@2.3.0:
resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==}
engines: {node: '>=8'}
@@ -4372,6 +5052,13 @@ packages:
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
engines: {node: '>=10'}
+ wrap-ansi@8.1.0:
+ resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
+ engines: {node: '>=12'}
+
+ wrappy@1.0.2:
+ resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
+
ws@8.21.0:
resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==}
engines: {node: '>=10.0.0'}
@@ -4401,6 +5088,9 @@ packages:
yallist@3.1.1:
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
+ yallist@4.0.0:
+ resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
+
yallist@5.0.0:
resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==}
engines: {node: '>=18'}
@@ -4419,6 +5109,10 @@ packages:
engines: {node: '>= 14.6'}
hasBin: true
+ yargs-parser@20.2.9:
+ resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==}
+ engines: {node: '>=10'}
+
yargs-parser@21.1.1:
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
engines: {node: '>=12'}
@@ -4427,6 +5121,10 @@ packages:
resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==}
engines: {node: ^20.19.0 || ^22.12.0 || >=23}
+ yargs@16.2.2:
+ resolution: {integrity: sha512-Nt9ZJjXTv5R8MHbqby/wXQ6Gi0Bb3TcYZkR1bzuL4yB2OxWPkXknz513gEF0GoA6tn00UpbPvERW8rzCuWCA6w==}
+ engines: {node: '>=10'}
+
yargs@17.7.2:
resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
engines: {node: '>=12'}
@@ -4439,6 +5137,10 @@ packages:
resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==}
engines: {node: '>=12.20'}
+ yoctocolors@2.2.0:
+ resolution: {integrity: sha512-xYqdZFUK/VYazNl/oCDYN+3WloWQwMfZxBoiNt6qNyk+xfOdi598muWE42rNZFp1kNOiqW936q5RhUdnpqElSg==}
+ engines: {node: '>=18'}
+
zimmerframe@1.1.4:
resolution: {integrity: sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==}
@@ -4594,12 +5296,12 @@ snapshots:
is-wsl: 3.1.1
which-pm-runs: 1.1.0
- '@astrojs/vercel@10.0.8(astro@6.4.2(@types/node@24.12.4)(@vercel/functions@3.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.4)(yaml@2.9.0))(react@19.0.0)(rollup@4.60.4)':
+ '@astrojs/vercel@10.0.8(astro@6.4.2(@types/node@24.12.4)(@vercel/functions@3.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.4)(yaml@2.9.0))(encoding@0.1.13)(react@19.0.0)(rollup@4.60.4)':
dependencies:
'@astrojs/internal-helpers': 0.10.0
'@vercel/analytics': 1.6.1(react@19.0.0)
'@vercel/functions': 3.6.1
- '@vercel/nft': 1.10.2(rollup@4.60.4)
+ '@vercel/nft': 1.10.2(encoding@0.1.13)(rollup@4.60.4)
'@vercel/routing-utils': 5.3.3
astro: 6.4.2(@types/node@24.12.4)(@vercel/functions@3.6.1)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.4)(yaml@2.9.0)
esbuild: 0.27.7
@@ -5245,6 +5947,8 @@ snapshots:
'@exodus/bytes@1.15.1': {}
+ '@gar/promisify@1.1.3': {}
+
'@humanfs/core@0.19.2':
dependencies:
'@humanfs/types': 0.15.0
@@ -5357,6 +6061,15 @@ snapshots:
'@img/sharp-win32-x64@0.34.5':
optional: true
+ '@isaacs/cliui@8.0.2':
+ dependencies:
+ string-width: 5.1.2
+ string-width-cjs: string-width@4.2.3
+ strip-ansi: 7.2.0
+ strip-ansi-cjs: strip-ansi@6.0.1
+ wrap-ansi: 8.1.0
+ wrap-ansi-cjs: wrap-ansi@7.0.0
+
'@isaacs/fs-minipass@4.0.1':
dependencies:
minipass: 7.1.3
@@ -5438,12 +6151,27 @@ snapshots:
'@libsql/win32-x64-msvc@0.5.29':
optional: true
- '@mapbox/node-pre-gyp@2.0.3':
+ '@manypkg/find-root@2.2.3':
+ dependencies:
+ '@manypkg/tools': 1.1.2
+
+ '@manypkg/get-packages@2.2.2':
+ dependencies:
+ '@manypkg/find-root': 2.2.3
+ '@manypkg/tools': 1.1.2
+
+ '@manypkg/tools@1.1.2':
+ dependencies:
+ fast-glob: 3.3.3
+ jju: 1.4.0
+ js-yaml: 4.1.1
+
+ '@mapbox/node-pre-gyp@2.0.3(encoding@0.1.13)':
dependencies:
consola: 3.4.2
detect-libc: 2.1.2
https-proxy-agent: 7.0.6
- node-fetch: 2.7.0
+ node-fetch: 2.7.0(encoding@0.1.13)
nopt: 8.1.0
semver: 7.8.1
tar: 7.5.15
@@ -5465,14 +6193,132 @@ snapshots:
'@nodelib/fs.scandir': 2.1.5
fastq: 1.20.1
+ '@npmcli/fs@1.1.1':
+ dependencies:
+ '@gar/promisify': 1.1.3
+ semver: 7.8.1
+
+ '@npmcli/git@6.0.3':
+ dependencies:
+ '@npmcli/promise-spawn': 8.0.3
+ ini: 5.0.0
+ lru-cache: 10.4.3
+ npm-pick-manifest: 10.0.0
+ proc-log: 5.0.0
+ promise-retry: 2.0.1
+ semver: 7.8.1
+ which: 5.0.0
+
+ '@npmcli/move-file@1.1.2':
+ dependencies:
+ mkdirp: 1.0.4
+ rimraf: 3.0.2
+
+ '@npmcli/package-json@6.2.0':
+ dependencies:
+ '@npmcli/git': 6.0.3
+ glob: 10.5.0
+ hosted-git-info: 8.1.0
+ json-parse-even-better-errors: 4.0.0
+ proc-log: 5.0.0
+ semver: 7.8.1
+ validate-npm-package-license: 3.0.4
+
+ '@npmcli/promise-spawn@8.0.3':
+ dependencies:
+ which: 5.0.0
+
+ '@octokit/auth-token@5.1.2': {}
+
+ '@octokit/core@6.1.6':
+ dependencies:
+ '@octokit/auth-token': 5.1.2
+ '@octokit/graphql': 8.2.2
+ '@octokit/request': 9.2.4
+ '@octokit/request-error': 6.1.8
+ '@octokit/types': 14.1.0
+ before-after-hook: 3.0.2
+ universal-user-agent: 7.0.3
+
+ '@octokit/endpoint@10.1.4':
+ dependencies:
+ '@octokit/types': 14.1.0
+ universal-user-agent: 7.0.3
+
+ '@octokit/graphql@8.2.2':
+ dependencies:
+ '@octokit/request': 9.2.4
+ '@octokit/types': 14.1.0
+ universal-user-agent: 7.0.3
+
+ '@octokit/openapi-types@24.2.0': {}
+
+ '@octokit/openapi-types@25.1.0': {}
+
+ '@octokit/plugin-paginate-rest@11.6.0(@octokit/core@6.1.6)':
+ dependencies:
+ '@octokit/core': 6.1.6
+ '@octokit/types': 13.10.0
+
+ '@octokit/plugin-request-log@5.3.1(@octokit/core@6.1.6)':
+ dependencies:
+ '@octokit/core': 6.1.6
+
+ '@octokit/plugin-rest-endpoint-methods@13.5.0(@octokit/core@6.1.6)':
+ dependencies:
+ '@octokit/core': 6.1.6
+ '@octokit/types': 13.10.0
+
+ '@octokit/request-error@6.1.8':
+ dependencies:
+ '@octokit/types': 14.1.0
+
+ '@octokit/request@9.2.4':
+ dependencies:
+ '@octokit/endpoint': 10.1.4
+ '@octokit/request-error': 6.1.8
+ '@octokit/types': 14.1.0
+ fast-content-type-parse: 2.0.1
+ universal-user-agent: 7.0.3
+
+ '@octokit/rest@21.1.1':
+ dependencies:
+ '@octokit/core': 6.1.6
+ '@octokit/plugin-paginate-rest': 11.6.0(@octokit/core@6.1.6)
+ '@octokit/plugin-request-log': 5.3.1(@octokit/core@6.1.6)
+ '@octokit/plugin-rest-endpoint-methods': 13.5.0(@octokit/core@6.1.6)
+
+ '@octokit/types@13.10.0':
+ dependencies:
+ '@octokit/openapi-types': 24.2.0
+
+ '@octokit/types@14.1.0':
+ dependencies:
+ '@octokit/openapi-types': 25.1.0
+
'@oslojs/encoding@1.1.0': {}
+ '@pkgjs/parseargs@0.11.0':
+ optional: true
+
'@pkgr/core@0.3.6': {}
'@playwright/test@1.60.0':
dependencies:
playwright: 1.60.0
+ '@pnpm/config.env-replace@1.1.0': {}
+
+ '@pnpm/network.ca-file@1.0.2':
+ dependencies:
+ graceful-fs: 4.2.10
+
+ '@pnpm/npm-conf@3.0.3':
+ dependencies:
+ '@pnpm/config.env-replace': 1.1.0
+ '@pnpm/network.ca-file': 1.0.2
+ config-chain: 1.1.13
+
'@preact/preset-vite@2.10.5(@babel/core@7.29.7)(preact@10.29.2)(rollup@4.60.4)(vite@7.3.3(@types/node@24.12.4)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.22.4)(yaml@2.9.0))':
dependencies:
'@babel/core': 7.29.7
@@ -5607,6 +6453,8 @@ snapshots:
'@rollup/rollup-win32-x64-msvc@4.60.4':
optional: true
+ '@sec-ant/readable-stream@0.4.1': {}
+
'@selderee/plugin-htmlparser2@0.11.0':
dependencies:
domhandler: 5.0.3
@@ -5652,6 +6500,8 @@ snapshots:
'@shikijs/vscode-textmate@10.0.2': {}
+ '@sindresorhus/merge-streams@4.0.0': {}
+
'@standard-schema/spec@1.1.0': {}
'@tailwindcss/forms@0.5.11(tailwindcss@4.3.0)':
@@ -5757,6 +6607,8 @@ snapshots:
'@testing-library/dom': 8.20.1
preact: 10.29.2
+ '@tootallnate/once@1.1.2': {}
+
'@types/aria-query@5.0.4': {}
'@types/chai@5.2.3':
@@ -5868,9 +6720,9 @@ snapshots:
dependencies:
'@vercel/oidc': 3.5.0
- '@vercel/nft@1.10.2(rollup@4.60.4)':
+ '@vercel/nft@1.10.2(encoding@0.1.13)(rollup@4.60.4)':
dependencies:
- '@mapbox/node-pre-gyp': 2.0.3
+ '@mapbox/node-pre-gyp': 2.0.3(encoding@0.1.13)
'@rollup/pluginutils': 5.4.0(rollup@4.60.4)
acorn: 8.16.0
acorn-import-attributes: 1.9.5(acorn@8.16.0)
@@ -6011,6 +6863,15 @@ snapshots:
agent-base@7.1.4: {}
+ agentkeepalive@4.6.0:
+ dependencies:
+ humanize-ms: 1.2.1
+
+ aggregate-error@3.1.0:
+ dependencies:
+ clean-stack: 2.2.0
+ indent-string: 4.0.0
+
ajv-draft-04@1.0.0(ajv@8.20.0):
optionalDependencies:
ajv: 8.20.0
@@ -6031,12 +6892,18 @@ snapshots:
ansi-regex@5.0.1: {}
+ ansi-regex@6.3.0: {}
+
ansi-styles@4.3.0:
dependencies:
color-convert: 2.0.1
ansi-styles@5.2.0: {}
+ ansi-styles@6.2.3: {}
+
+ any-promise@1.3.0: {}
+
anymatch@3.1.3:
dependencies:
normalize-path: 3.0.0
@@ -6059,6 +6926,8 @@ snapshots:
array-iterate@2.0.1: {}
+ assert-never@1.4.0: {}
+
assertion-error@2.0.1: {}
astro-eslint-parser@1.4.0:
@@ -6217,6 +7086,8 @@ snapshots:
baseline-browser-mapping@2.10.33: {}
+ before-after-hook@3.0.2: {}
+
bidi-js@1.0.3:
dependencies:
require-from-string: 2.0.2
@@ -6232,6 +7103,10 @@ snapshots:
balanced-match: 1.0.2
concat-map: 0.0.1
+ brace-expansion@2.1.4:
+ dependencies:
+ balanced-match: 1.0.2
+
brace-expansion@5.0.6:
dependencies:
balanced-match: 4.0.4
@@ -6250,6 +7125,29 @@ snapshots:
buffer-from@1.1.2: {}
+ cacache@15.3.0:
+ dependencies:
+ '@npmcli/fs': 1.1.1
+ '@npmcli/move-file': 1.1.2
+ chownr: 2.0.0
+ fs-minipass: 2.1.0
+ glob: 7.2.3
+ infer-owner: 1.0.4
+ lru-cache: 6.0.0
+ minipass: 3.3.6
+ minipass-collect: 1.0.2
+ minipass-flush: 1.0.7
+ minipass-pipeline: 1.2.4
+ mkdirp: 1.0.4
+ p-map: 4.0.0
+ promise-inflight: 1.0.1
+ rimraf: 3.0.2
+ ssri: 8.0.1
+ tar: 6.2.1
+ unique-filename: 1.1.1
+ transitivePeerDependencies:
+ - bluebird
+
call-bind-apply-helpers@1.0.2:
dependencies:
es-errors: 1.3.0
@@ -6280,6 +7178,8 @@ snapshots:
ansi-styles: 4.3.0
supports-color: 7.2.0
+ chalk@5.6.2: {}
+
character-entities-html4@2.1.0: {}
character-entities-legacy@3.0.0: {}
@@ -6294,10 +7194,29 @@ snapshots:
dependencies:
readdirp: 5.0.0
+ chownr@2.0.0: {}
+
chownr@3.0.0: {}
ci-info@4.4.0: {}
+ clean-stack@2.2.0: {}
+
+ cli-highlight@2.1.11:
+ dependencies:
+ chalk: 4.1.2
+ highlight.js: 10.7.3
+ mz: 2.7.0
+ parse5: 5.1.1
+ parse5-htmlparser2-tree-adapter: 6.0.1
+ yargs: 16.2.2
+
+ cliui@7.0.4:
+ dependencies:
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+ wrap-ansi: 7.0.0
+
cliui@8.0.1:
dependencies:
string-width: 4.2.3
@@ -6333,6 +7252,11 @@ snapshots:
tree-kill: 1.2.2
yargs: 17.7.2
+ config-chain@1.1.13:
+ dependencies:
+ ini: 1.3.8
+ proto-list: 1.2.4
+
consola@3.4.2: {}
convert-source-map@2.0.0: {}
@@ -6422,6 +7346,8 @@ snapshots:
which-collection: 1.0.2
which-typed-array: 1.1.21
+ deep-extend@0.6.0: {}
+
deep-is@0.1.4: {}
deepmerge@4.3.1: {}
@@ -6501,6 +7427,8 @@ snapshots:
es-errors: 1.3.0
gopd: 1.2.0
+ eastasianwidth@0.2.0: {}
+
electron-to-chromium@1.5.364: {}
emmet@2.4.11:
@@ -6510,6 +7438,13 @@ snapshots:
emoji-regex@8.0.0: {}
+ emoji-regex@9.2.2: {}
+
+ encoding@0.1.13:
+ dependencies:
+ iconv-lite: 0.6.3
+ optional: true
+
enhanced-resolve@5.22.1:
dependencies:
graceful-fs: 4.2.11
@@ -6523,6 +7458,8 @@ snapshots:
entities@8.0.0: {}
+ err-code@2.0.3: {}
+
es-define-property@1.0.1: {}
es-errors@1.3.0: {}
@@ -6767,10 +7704,39 @@ snapshots:
eventemitter3@5.0.4: {}
+ execa@5.1.1:
+ dependencies:
+ cross-spawn: 7.0.6
+ get-stream: 6.0.1
+ human-signals: 2.1.0
+ is-stream: 2.0.1
+ merge-stream: 2.0.0
+ npm-run-path: 4.0.1
+ onetime: 5.1.2
+ signal-exit: 3.0.7
+ strip-final-newline: 2.0.0
+
+ execa@9.6.1:
+ dependencies:
+ '@sindresorhus/merge-streams': 4.0.0
+ cross-spawn: 7.0.6
+ figures: 6.1.0
+ get-stream: 9.0.1
+ human-signals: 8.0.1
+ is-plain-obj: 4.1.0
+ is-stream: 4.0.1
+ npm-run-path: 6.0.0
+ pretty-ms: 9.3.0
+ signal-exit: 4.1.0
+ strip-final-newline: 4.0.0
+ yoctocolors: 2.2.0
+
expect-type@1.3.0: {}
extend@3.0.2: {}
+ fast-content-type-parse@2.0.1: {}
+
fast-deep-equal@3.1.3: {}
fast-glob@3.3.3:
@@ -6809,6 +7775,10 @@ snapshots:
optionalDependencies:
picomatch: 4.0.4
+ figures@6.1.0:
+ dependencies:
+ is-unicode-supported: 2.1.0
+
file-entry-cache@8.0.0:
dependencies:
flat-cache: 4.0.1
@@ -6847,6 +7817,11 @@ snapshots:
dependencies:
is-callable: 1.2.7
+ foreground-child@3.3.1:
+ dependencies:
+ cross-spawn: 7.0.6
+ signal-exit: 4.1.0
+
form-data@4.0.5:
dependencies:
asynckit: 0.4.0
@@ -6855,6 +7830,18 @@ snapshots:
hasown: 2.0.4
mime-types: 2.1.35
+ fs-extra@11.4.0:
+ dependencies:
+ graceful-fs: 4.2.11
+ jsonfile: 6.2.1
+ universalify: 2.0.1
+
+ fs-minipass@2.1.0:
+ dependencies:
+ minipass: 3.3.6
+
+ fs.realpath@1.0.0: {}
+
fsevents@2.3.2:
optional: true
@@ -6887,6 +7874,13 @@ snapshots:
dunder-proto: 1.0.1
es-object-atoms: 1.1.2
+ get-stream@6.0.1: {}
+
+ get-stream@9.0.1:
+ dependencies:
+ '@sec-ant/readable-stream': 0.4.1
+ is-stream: 4.0.1
+
get-tsconfig@4.14.0:
dependencies:
resolve-pkg-maps: 1.0.0
@@ -6895,6 +7889,21 @@ snapshots:
dependencies:
resolve-pkg-maps: 1.0.0
+ github-changelog@2.1.4:
+ dependencies:
+ '@manypkg/get-packages': 2.2.2
+ chalk: 4.1.2
+ cli-highlight: 2.1.11
+ execa: 5.1.1
+ hosted-git-info: 4.1.0
+ make-fetch-happen: 9.1.0
+ p-map: 3.0.0
+ progress: 2.0.3
+ yargs: 17.7.2
+ transitivePeerDependencies:
+ - bluebird
+ - supports-color
+
github-slugger@2.0.0: {}
glob-parent@5.1.2:
@@ -6905,18 +7914,38 @@ snapshots:
dependencies:
is-glob: 4.0.3
+ glob@10.5.0:
+ dependencies:
+ foreground-child: 3.3.1
+ jackspeak: 3.4.3
+ minimatch: 9.0.9
+ minipass: 7.1.3
+ package-json-from-dist: 1.0.1
+ path-scurry: 1.11.1
+
glob@13.0.6:
dependencies:
minimatch: 10.2.5
minipass: 7.1.3
path-scurry: 2.0.2
+ glob@7.2.3:
+ dependencies:
+ fs.realpath: 1.0.0
+ inflight: 1.0.6
+ inherits: 2.0.4
+ minimatch: 3.1.5
+ once: 1.4.0
+ path-is-absolute: 1.0.1
+
globals@14.0.0: {}
globals@16.5.0: {}
gopd@1.2.0: {}
+ graceful-fs@4.2.10: {}
+
graceful-fs@4.2.11: {}
h3@1.15.11:
@@ -7038,6 +8067,16 @@ snapshots:
he@1.2.0: {}
+ highlight.js@10.7.3: {}
+
+ hosted-git-info@4.1.0:
+ dependencies:
+ lru-cache: 6.0.0
+
+ hosted-git-info@8.1.0:
+ dependencies:
+ lru-cache: 10.4.3
+
html-encoding-sniffer@6.0.0:
dependencies:
'@exodus/bytes': 1.15.1
@@ -7065,6 +8104,14 @@ snapshots:
http-cache-semantics@4.2.0: {}
+ http-proxy-agent@4.0.1:
+ dependencies:
+ '@tootallnate/once': 1.1.2
+ agent-base: 6.0.2
+ debug: 4.4.3
+ transitivePeerDependencies:
+ - supports-color
+
http-proxy-agent@7.0.2:
dependencies:
agent-base: 7.1.4
@@ -7086,6 +8133,19 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ human-signals@2.1.0: {}
+
+ human-signals@8.0.1: {}
+
+ humanize-ms@1.2.1:
+ dependencies:
+ ms: 2.1.3
+
+ iconv-lite@0.6.3:
+ dependencies:
+ safer-buffer: 2.1.2
+ optional: true
+
ignore@5.3.2: {}
import-fresh@3.3.1:
@@ -7097,12 +8157,27 @@ snapshots:
indent-string@4.0.0: {}
+ infer-owner@1.0.4: {}
+
+ inflight@1.0.6:
+ dependencies:
+ once: 1.4.0
+ wrappy: 1.0.2
+
+ inherits@2.0.4: {}
+
+ ini@1.3.8: {}
+
+ ini@5.0.0: {}
+
internal-slot@1.1.0:
dependencies:
es-errors: 1.3.0
hasown: 2.0.4
side-channel: 1.1.0
+ ip-address@10.5.0: {}
+
iron-webcrypto@1.2.1: {}
is-arguments@1.2.0:
@@ -7148,6 +8223,8 @@ snapshots:
dependencies:
is-docker: 3.0.0
+ is-lambda@1.0.1: {}
+
is-map@2.0.3: {}
is-number-object@1.1.1:
@@ -7174,6 +8251,10 @@ snapshots:
dependencies:
call-bound: 1.0.4
+ is-stream@2.0.1: {}
+
+ is-stream@4.0.1: {}
+
is-string@1.1.1:
dependencies:
call-bound: 1.0.4
@@ -7185,6 +8266,8 @@ snapshots:
has-symbols: 1.1.0
safe-regex-test: 1.1.0
+ is-unicode-supported@2.1.0: {}
+
is-weakmap@2.0.2: {}
is-weakset@2.0.4:
@@ -7200,10 +8283,20 @@ snapshots:
isexe@2.0.0: {}
+ isexe@3.1.5: {}
+
iso-datestring-validator@2.2.2: {}
+ jackspeak@3.4.3:
+ dependencies:
+ '@isaacs/cliui': 8.0.2
+ optionalDependencies:
+ '@pkgjs/parseargs': 0.11.0
+
jiti@2.7.0: {}
+ jju@1.4.0: {}
+
js-base64@3.7.8: {}
js-tokens@4.0.0: {}
@@ -7244,6 +8337,8 @@ snapshots:
json-buffer@3.0.1: {}
+ json-parse-even-better-errors@4.0.0: {}
+
json-schema-traverse@0.4.1: {}
json-schema-traverse@1.0.0: {}
@@ -7256,6 +8351,12 @@ snapshots:
jsonc-parser@3.3.1: {}
+ jsonfile@6.2.1:
+ dependencies:
+ universalify: 2.0.1
+ optionalDependencies:
+ graceful-fs: 4.2.11
+
keyv@4.5.4:
dependencies:
json-buffer: 3.0.1
@@ -7264,6 +8365,12 @@ snapshots:
kolorist@1.8.0: {}
+ ky@1.14.3: {}
+
+ latest-version@9.0.0:
+ dependencies:
+ package-json: 10.0.1
+
leac@0.6.0: {}
levn@0.4.1:
@@ -7343,12 +8450,18 @@ snapshots:
longest-streak@3.1.0: {}
+ lru-cache@10.4.3: {}
+
lru-cache@11.5.1: {}
lru-cache@5.1.1:
dependencies:
yallist: 3.1.1
+ lru-cache@6.0.0:
+ dependencies:
+ yallist: 4.0.0
+
lz-string@1.5.0: {}
magic-string@0.30.21:
@@ -7361,6 +8474,28 @@ snapshots:
'@babel/types': 7.29.7
source-map-js: 1.2.1
+ make-fetch-happen@9.1.0:
+ dependencies:
+ agentkeepalive: 4.6.0
+ cacache: 15.3.0
+ http-cache-semantics: 4.2.0
+ http-proxy-agent: 4.0.1
+ https-proxy-agent: 5.0.1
+ is-lambda: 1.0.1
+ lru-cache: 6.0.0
+ minipass: 3.3.6
+ minipass-collect: 1.0.2
+ minipass-fetch: 1.4.1
+ minipass-flush: 1.0.7
+ minipass-pipeline: 1.2.4
+ negotiator: 0.6.4
+ promise-retry: 2.0.1
+ socks-proxy-agent: 6.2.1
+ ssri: 8.0.1
+ transitivePeerDependencies:
+ - bluebird
+ - supports-color
+
markdown-table@3.0.4: {}
math-intrinsics@1.1.0: {}
@@ -7489,6 +8624,8 @@ snapshots:
mdn-data@2.27.1: {}
+ merge-stream@2.0.0: {}
+
merge2@1.4.1: {}
micromark-core-commonmark@2.0.3:
@@ -7693,6 +8830,8 @@ snapshots:
dependencies:
mime-db: 1.52.0
+ mimic-fn@2.1.0: {}
+
min-indent@1.0.1: {}
mini-svg-data-uri@1.4.4: {}
@@ -7705,12 +8844,55 @@ snapshots:
dependencies:
brace-expansion: 1.1.15
+ minimatch@9.0.9:
+ dependencies:
+ brace-expansion: 2.1.4
+
+ minimist@1.2.8: {}
+
+ minipass-collect@1.0.2:
+ dependencies:
+ minipass: 3.3.6
+
+ minipass-fetch@1.4.1:
+ dependencies:
+ minipass: 3.3.6
+ minipass-sized: 1.0.3
+ minizlib: 2.1.2
+ optionalDependencies:
+ encoding: 0.1.13
+
+ minipass-flush@1.0.7:
+ dependencies:
+ minipass: 3.3.6
+
+ minipass-pipeline@1.2.4:
+ dependencies:
+ minipass: 3.3.6
+
+ minipass-sized@1.0.3:
+ dependencies:
+ minipass: 3.3.6
+
+ minipass@3.3.6:
+ dependencies:
+ yallist: 4.0.0
+
+ minipass@5.0.0: {}
+
minipass@7.1.3: {}
+ minizlib@2.1.2:
+ dependencies:
+ minipass: 3.3.6
+ yallist: 4.0.0
+
minizlib@3.1.0:
dependencies:
minipass: 7.1.3
+ mkdirp@1.0.4: {}
+
mrmime@2.0.1: {}
ms@2.1.3: {}
@@ -7719,10 +8901,18 @@ snapshots:
multiformats@9.9.0: {}
+ mz@2.7.0:
+ dependencies:
+ any-promise: 1.3.0
+ object-assign: 4.1.1
+ thenify-all: 1.6.0
+
nanoid@3.3.12: {}
natural-compare@1.4.0: {}
+ negotiator@0.6.4: {}
+
neotraverse@0.6.18: {}
nlcst-to-string@4.0.0:
@@ -7731,9 +8921,11 @@ snapshots:
node-fetch-native@1.6.7: {}
- node-fetch@2.7.0:
+ node-fetch@2.7.0(encoding@0.1.13):
dependencies:
whatwg-url: 5.0.0
+ optionalDependencies:
+ encoding: 0.1.13
node-gyp-build@4.8.4: {}
@@ -7752,10 +8944,41 @@ snapshots:
normalize-path@3.0.0: {}
+ npm-install-checks@7.1.2:
+ dependencies:
+ semver: 7.8.1
+
+ npm-normalize-package-bin@4.0.0: {}
+
+ npm-package-arg@12.0.2:
+ dependencies:
+ hosted-git-info: 8.1.0
+ proc-log: 5.0.0
+ semver: 7.8.1
+ validate-npm-package-name: 6.0.2
+
+ npm-pick-manifest@10.0.0:
+ dependencies:
+ npm-install-checks: 7.1.2
+ npm-normalize-package-bin: 4.0.0
+ npm-package-arg: 12.0.2
+ semver: 7.8.1
+
+ npm-run-path@4.0.1:
+ dependencies:
+ path-key: 3.1.1
+
+ npm-run-path@6.0.0:
+ dependencies:
+ path-key: 4.0.0
+ unicorn-magic: 0.3.0
+
nth-check@2.1.1:
dependencies:
boolbase: 1.0.0
+ object-assign@4.1.1: {}
+
object-inspect@1.13.4: {}
object-is@1.1.6:
@@ -7784,6 +9007,14 @@ snapshots:
ohash@2.0.11: {}
+ once@1.4.0:
+ dependencies:
+ wrappy: 1.0.2
+
+ onetime@5.1.2:
+ dependencies:
+ mimic-fn: 2.1.0
+
oniguruma-parser@0.12.2: {}
oniguruma-to-es@4.3.6:
@@ -7813,6 +9044,14 @@ snapshots:
dependencies:
p-limit: 3.1.0
+ p-map@3.0.0:
+ dependencies:
+ aggregate-error: 3.1.0
+
+ p-map@4.0.0:
+ dependencies:
+ aggregate-error: 3.1.0
+
p-queue@9.3.0:
dependencies:
eventemitter3: 5.0.4
@@ -7820,12 +9059,23 @@ snapshots:
p-timeout@7.0.1: {}
+ package-json-from-dist@1.0.1: {}
+
+ package-json@10.0.1:
+ dependencies:
+ ky: 1.14.3
+ registry-auth-token: 5.1.1
+ registry-url: 6.0.1
+ semver: 7.8.1
+
package-manager-detector@1.6.0: {}
parent-module@1.0.1:
dependencies:
callsites: 3.1.0
+ parse-github-repo-url@1.4.1: {}
+
parse-latin@7.0.0:
dependencies:
'@types/nlcst': 2.0.3
@@ -7835,6 +9085,16 @@ snapshots:
unist-util-visit-children: 3.0.0
vfile: 6.0.3
+ parse-ms@4.0.0: {}
+
+ parse5-htmlparser2-tree-adapter@6.0.1:
+ dependencies:
+ parse5: 6.0.1
+
+ parse5@5.1.1: {}
+
+ parse5@6.0.1: {}
+
parse5@7.3.0:
dependencies:
entities: 6.0.1
@@ -7852,8 +9112,17 @@ snapshots:
path-exists@4.0.0: {}
+ path-is-absolute@1.0.1: {}
+
path-key@3.1.1: {}
+ path-key@4.0.0: {}
+
+ path-scurry@1.11.1:
+ dependencies:
+ lru-cache: 10.4.3
+ minipass: 7.1.3
+
path-scurry@2.0.2:
dependencies:
lru-cache: 11.5.1
@@ -7929,12 +9198,29 @@ snapshots:
ansi-styles: 5.2.0
react-is: 17.0.2
+ pretty-ms@9.3.0:
+ dependencies:
+ parse-ms: 4.0.0
+
prismjs@1.30.0: {}
+ proc-log@5.0.0: {}
+
+ progress@2.0.3: {}
+
+ promise-inflight@1.0.1: {}
+
promise-limit@2.7.0: {}
+ promise-retry@2.0.1:
+ dependencies:
+ err-code: 2.0.3
+ retry: 0.12.0
+
property-information@7.1.0: {}
+ proto-list@1.2.4: {}
+
proxy-from-env@2.1.0: {}
punycode@2.3.1: {}
@@ -7943,6 +9229,13 @@ snapshots:
radix3@1.1.2: {}
+ rc@1.2.8:
+ dependencies:
+ deep-extend: 0.6.0
+ ini: 1.3.8
+ minimist: 1.2.8
+ strip-json-comments: 2.0.1
+
react-is@17.0.2: {}
react@19.0.0:
@@ -7976,6 +9269,14 @@ snapshots:
gopd: 1.2.0
set-function-name: 2.0.2
+ registry-auth-token@5.1.1:
+ dependencies:
+ '@pnpm/npm-conf': 3.0.3
+
+ registry-url@6.0.1:
+ dependencies:
+ rc: 1.2.8
+
rehype-parse@9.0.1:
dependencies:
'@types/hast': 3.0.4
@@ -8001,6 +9302,26 @@ snapshots:
rehype-stringify: 10.0.1
unified: 11.0.5
+ release-plan@0.18.0:
+ dependencies:
+ '@manypkg/get-packages': 2.2.2
+ '@npmcli/package-json': 6.2.0
+ '@octokit/rest': 21.1.1
+ assert-never: 1.4.0
+ chalk: 5.6.2
+ cli-highlight: 2.1.11
+ execa: 9.6.1
+ fs-extra: 11.4.0
+ github-changelog: 2.1.4
+ js-yaml: 4.1.1
+ latest-version: 9.0.0
+ parse-github-repo-url: 1.4.1
+ semver: 7.8.1
+ yargs: 17.7.2
+ transitivePeerDependencies:
+ - bluebird
+ - supports-color
+
remark-gfm@4.0.1:
dependencies:
'@types/mdast': 4.0.4
@@ -8081,8 +9402,14 @@ snapshots:
retext-stringify: 4.0.0
unified: 11.0.5
+ retry@0.12.0: {}
+
reusify@1.1.0: {}
+ rimraf@3.0.2:
+ dependencies:
+ glob: 7.2.3
+
rollup@4.60.4:
dependencies:
'@types/estree': 1.0.8
@@ -8138,6 +9465,9 @@ snapshots:
es-errors: 1.3.0
is-regex: 1.2.1
+ safer-buffer@2.1.2:
+ optional: true
+
sass-formatter@0.7.9:
dependencies:
suf-log: 2.5.3
@@ -8254,6 +9584,10 @@ snapshots:
siginfo@2.0.0: {}
+ signal-exit@3.0.7: {}
+
+ signal-exit@4.1.0: {}
+
simple-code-frame@1.3.0:
dependencies:
kolorist: 1.8.0
@@ -8267,8 +9601,23 @@ snapshots:
arg: 5.0.2
sax: 1.6.0
+ smart-buffer@4.2.0: {}
+
smol-toml@1.6.1: {}
+ socks-proxy-agent@6.2.1:
+ dependencies:
+ agent-base: 6.0.2
+ debug: 4.4.3
+ socks: 2.8.9
+ transitivePeerDependencies:
+ - supports-color
+
+ socks@2.8.9:
+ dependencies:
+ ip-address: 10.5.0
+ smart-buffer: 4.2.0
+
source-map-js@1.2.1: {}
source-map-support@0.5.21:
@@ -8282,6 +9631,24 @@ snapshots:
space-separated-tokens@2.0.2: {}
+ spdx-correct@3.2.0:
+ dependencies:
+ spdx-expression-parse: 3.0.1
+ spdx-license-ids: 3.0.23
+
+ spdx-exceptions@2.5.0: {}
+
+ spdx-expression-parse@3.0.1:
+ dependencies:
+ spdx-exceptions: 2.5.0
+ spdx-license-ids: 3.0.23
+
+ spdx-license-ids@3.0.23: {}
+
+ ssri@8.0.1:
+ dependencies:
+ minipass: 3.3.6
+
stack-trace@1.0.0: {}
stackback@0.0.2: {}
@@ -8301,6 +9668,12 @@ snapshots:
is-fullwidth-code-point: 3.0.0
strip-ansi: 6.0.1
+ string-width@5.1.2:
+ dependencies:
+ eastasianwidth: 0.2.0
+ emoji-regex: 9.2.2
+ strip-ansi: 7.2.0
+
stringify-entities@4.0.4:
dependencies:
character-entities-html4: 2.1.0
@@ -8310,10 +9683,20 @@ snapshots:
dependencies:
ansi-regex: 5.0.1
+ strip-ansi@7.2.0:
+ dependencies:
+ ansi-regex: 6.3.0
+
+ strip-final-newline@2.0.0: {}
+
+ strip-final-newline@4.0.0: {}
+
strip-indent@3.0.0:
dependencies:
min-indent: 1.0.1
+ strip-json-comments@2.0.1: {}
+
strip-json-comments@3.1.1: {}
strnum@1.1.2: {}
@@ -8350,6 +9733,15 @@ snapshots:
tapable@2.3.3: {}
+ tar@6.2.1:
+ dependencies:
+ chownr: 2.0.0
+ fs-minipass: 2.1.0
+ minipass: 5.0.0
+ minizlib: 2.1.2
+ mkdirp: 1.0.4
+ yallist: 4.0.0
+
tar@7.5.15:
dependencies:
'@isaacs/fs-minipass': 4.0.1
@@ -8358,6 +9750,14 @@ snapshots:
minizlib: 3.1.0
yallist: 5.0.0
+ thenify-all@1.6.0:
+ dependencies:
+ thenify: 3.3.1
+
+ thenify@3.3.1:
+ dependencies:
+ any-promise: 1.3.0
+
tiny-inflate@1.0.3: {}
tinybench@2.9.0: {}
@@ -8439,6 +9839,8 @@ snapshots:
unicode-segmenter@0.14.5: {}
+ unicorn-magic@0.3.0: {}
+
unified@11.0.5:
dependencies:
'@types/unist': 3.0.3
@@ -8455,6 +9857,14 @@ snapshots:
ofetch: 1.5.1
ohash: 2.0.11
+ unique-filename@1.1.1:
+ dependencies:
+ unique-slug: 2.0.2
+
+ unique-slug@2.0.2:
+ dependencies:
+ imurmurhash: 0.1.4
+
unist-util-find-after@5.0.0:
dependencies:
'@types/unist': 3.0.3
@@ -8497,6 +9907,10 @@ snapshots:
unist-util-is: 6.0.1
unist-util-visit-parents: 6.0.2
+ universal-user-agent@7.0.3: {}
+
+ universalify@2.0.1: {}
+
unstorage@1.17.5(@vercel/functions@3.6.1):
dependencies:
anymatch: 3.1.3
@@ -8526,6 +9940,13 @@ snapshots:
optionalDependencies:
typescript: 5.9.3
+ validate-npm-package-license@3.0.4:
+ dependencies:
+ spdx-correct: 3.2.0
+ spdx-expression-parse: 3.0.1
+
+ validate-npm-package-name@6.0.2: {}
+
vfile-location@5.0.3:
dependencies:
'@types/unist': 3.0.3
@@ -8751,6 +10172,10 @@ snapshots:
dependencies:
isexe: 2.0.0
+ which@5.0.0:
+ dependencies:
+ isexe: 3.1.5
+
why-is-node-running@2.3.0:
dependencies:
siginfo: 2.0.0
@@ -8764,6 +10189,14 @@ snapshots:
string-width: 4.2.3
strip-ansi: 6.0.1
+ wrap-ansi@8.1.0:
+ dependencies:
+ ansi-styles: 6.2.3
+ string-width: 5.1.2
+ strip-ansi: 7.2.0
+
+ wrappy@1.0.2: {}
+
ws@8.21.0: {}
xml-name-validator@5.0.0: {}
@@ -8776,6 +10209,8 @@ snapshots:
yallist@3.1.1: {}
+ yallist@4.0.0: {}
+
yallist@5.0.0: {}
yaml-language-server@1.20.0:
@@ -8796,10 +10231,22 @@ snapshots:
yaml@2.9.0: {}
+ yargs-parser@20.2.9: {}
+
yargs-parser@21.1.1: {}
yargs-parser@22.0.0: {}
+ yargs@16.2.2:
+ dependencies:
+ cliui: 7.0.4
+ escalade: 3.2.0
+ get-caller-file: 2.0.5
+ require-directory: 2.1.1
+ string-width: 4.2.3
+ y18n: 5.0.8
+ yargs-parser: 20.2.9
+
yargs@17.7.2:
dependencies:
cliui: 8.0.1
@@ -8814,6 +10261,8 @@ snapshots:
yocto-queue@1.2.2: {}
+ yoctocolors@2.2.0: {}
+
zimmerframe@1.1.4: {}
zod@3.25.76: {}
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
new file mode 100644
index 00000000..924b55f4
--- /dev/null
+++ b/pnpm-workspace.yaml
@@ -0,0 +1,2 @@
+packages:
+ - packages/*
diff --git a/scripts/publish-atproto-episodes.ts b/scripts/publish-atproto-episodes.ts
index 4010972e..c6f47e3b 100644
--- a/scripts/publish-atproto-episodes.ts
+++ b/scripts/publish-atproto-episodes.ts
@@ -26,7 +26,7 @@ import {
} from '@bryanguffey/astro-standard-site';
import starpodConfig from '../starpod.config';
-import { dasherize } from '../src/utils/dasherize';
+import { dasherize } from 'starpod/src/utils/dasherize';
const BACKFILL = process.argv.includes('--backfill');
// Set by the GitHub workflow when it has just triggered a site rebuild:
diff --git a/src/components/player/ForwardButton/styles.css b/src/components/player/ForwardButton/styles.css
deleted file mode 100644
index e220fe05..00000000
--- a/src/components/player/ForwardButton/styles.css
+++ /dev/null
@@ -1,3 +0,0 @@
-.forward-button {
- mask-image: url(/images/forward-icon.svg);
-}
diff --git a/src/components/player/MuteButton/styles.css b/src/components/player/MuteButton/styles.css
deleted file mode 100644
index c78a6361..00000000
--- a/src/components/player/MuteButton/styles.css
+++ /dev/null
@@ -1,7 +0,0 @@
-.mute-button {
- mask-image: url(/images/mute-icon.svg);
-}
-
-.unmute-button {
- mask-image: url(/images/unmute-icon.svg);
-}
diff --git a/src/components/player/RewindButton/styles.css b/src/components/player/RewindButton/styles.css
deleted file mode 100644
index c3794419..00000000
--- a/src/components/player/RewindButton/styles.css
+++ /dev/null
@@ -1,3 +0,0 @@
-.rewind-button {
- mask-image: url(/images/rewind-icon.svg);
-}
diff --git a/src/content.config.ts b/src/content.config.ts
index 6120d914..0e0c7d44 100644
--- a/src/content.config.ts
+++ b/src/content.config.ts
@@ -1,10 +1,10 @@
import { defineCollection } from 'astro:content';
-import { glob } from 'astro/loaders';
+import { transcriptsLoader } from 'starpod/content';
const transcripts = defineCollection({
- loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/transcripts' }),
+ loader: transcriptsLoader()
});
export const collections = {
transcripts
-};
\ No newline at end of file
+};
diff --git a/src/pages/sponsor.astro b/src/pages/sponsor.astro
index e64a560c..9586f80f 100644
--- a/src/pages/sponsor.astro
+++ b/src/pages/sponsor.astro
@@ -1,10 +1,15 @@
---
+// A fully custom page: Starpod injects the core site routes, and anything
+// else lives in your own src/pages/, composed from the package's building
+// blocks. This one is whiskey.fm's sponsorship pitch and doubles as the
+// reference implementation for custom pages.
import type { ImageMetadata } from 'astro';
import { Image } from 'astro:assets';
-import Layout from '../layouts/Layout.astro';
-import AdPackageCard from '../components/AdPackageCard.astro';
-import { getShowInfo } from '../lib/rss';
+import AdPackageCard from 'starpod/components/AdPackageCard';
+import Layout from 'starpod/layout';
+import { getShowInfo } from 'starpod/rss';
+
const show = await getShowInfo();
const title = `${show.title}`;
diff --git a/src/utils/config.ts b/src/utils/config.ts
deleted file mode 100644
index c24c53d0..00000000
--- a/src/utils/config.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-export type Host = {
- /**
- * The name of the host
- */
- name: string;
- /**
- * A bio about the host to display
- */
- bio: string;
- /**
- * A url to an image to use for the host
- */
- img: string;
- /**
- * A url to the host's GitHub
- */
- github?: string;
- /**
- * A url to the host's Twitter
- */
- twitter?: string;
- /**
- * A url to the host's website
- */
- website?: string;
-};
-
-export type StarpodConfig = {
- /**
- * A very short tagline for your show. Generally, no more than one sentence. Less is more here.
- */
- blurb: string;
- /**
- * A somewhat longer description of what your show is about. This should still ideally be fairly short, and should usually be 2-4 sentences.
- */
- description: string;
- /**
- * A list of your show's hosts and their info.
- */
- hosts: Array;
- /**
- * Links to the platforms your show is available on.
- */
- platforms: {
- apple?: string;
- appleIdNumber?: string;
- overcast?: string;
- pocketCasts?: string;
- spotify?: string;
- youtube?: string;
- };
- /**
- * The url to the RSS feed where your podcast is hosted.
- */
- rssFeed: string;
-};
-
-export const defineStarpodConfig = (config: StarpodConfig) => config;
diff --git a/starpod.config.ts b/starpod.config.ts
index 5a38d9ea..7d29a543 100644
--- a/starpod.config.ts
+++ b/starpod.config.ts
@@ -1,4 +1,4 @@
-import { defineStarpodConfig } from 'src/utils/config';
+import { defineStarpodConfig } from 'starpod/config';
export default defineStarpodConfig({
blurb:
@@ -32,5 +32,9 @@ export default defineStarpodConfig({
spotify: 'https://open.spotify.com/show/19jiuHAqzeKnkleQUpZxDf',
youtube: 'https://www.youtube.com/@WhiskeyWebAndWhatnot/'
},
- rssFeed: 'https://rss.flightcast.com/w7bqgc792i30fd43a32uawx0.xml'
+ rssFeed: 'https://rss.flightcast.com/w7bqgc792i30fd43a32uawx0.xml',
+ links: [
+ { label: 'Store', href: 'https://whiskey.fund/' },
+ { label: 'Become a sponsor', href: '/sponsor' }
+ ]
});
diff --git a/tests/unit/ForwardButton.test.tsx b/tests/unit/ForwardButton.test.tsx
index 17591c1e..0a8e7420 100644
--- a/tests/unit/ForwardButton.test.tsx
+++ b/tests/unit/ForwardButton.test.tsx
@@ -1,6 +1,6 @@
import { render, screen, fireEvent } from '@testing-library/preact';
import { beforeEach, describe, expect, it } from 'vitest';
-import ForwardButton from '../../src/components/player/ForwardButton';
+import ForwardButton from 'starpod/src/components/player/ForwardButton';
import { createRef } from 'preact';
// Mock audio element
diff --git a/tests/unit/FullPlayButton.test.tsx b/tests/unit/FullPlayButton.test.tsx
index d4df6799..30b0e746 100644
--- a/tests/unit/FullPlayButton.test.tsx
+++ b/tests/unit/FullPlayButton.test.tsx
@@ -1,7 +1,7 @@
import { render, screen, fireEvent } from '@testing-library/preact';
import { beforeEach, describe, expect, it } from 'vitest';
-import FullPlayButton from '../../src/components/FullPlayButton';
-import { currentEpisode, isPlaying } from '../../src/components/state';
+import FullPlayButton from 'starpod/src/components/FullPlayButton';
+import { currentEpisode, isPlaying } from 'starpod/src/components/state';
const mockEpisode = {
id: 'test-episode-1',
diff --git a/tests/unit/MuteButton.test.tsx b/tests/unit/MuteButton.test.tsx
index 6453fa4a..c458bd27 100644
--- a/tests/unit/MuteButton.test.tsx
+++ b/tests/unit/MuteButton.test.tsx
@@ -1,7 +1,7 @@
import { render, screen, fireEvent } from '@testing-library/preact';
import { beforeEach, describe, expect, it } from 'vitest';
-import MuteButton from '../../src/components/player/MuteButton';
-import { isMuted } from '../../src/components/state';
+import MuteButton from 'starpod/src/components/player/MuteButton';
+import { isMuted } from 'starpod/src/components/state';
describe('MuteButton', () => {
beforeEach(() => {
diff --git a/tests/unit/PlayButton.test.tsx b/tests/unit/PlayButton.test.tsx
index 81d518ad..f736f2b7 100644
--- a/tests/unit/PlayButton.test.tsx
+++ b/tests/unit/PlayButton.test.tsx
@@ -1,7 +1,7 @@
import { render, screen, fireEvent } from '@testing-library/preact';
import { beforeEach, describe, expect, it } from 'vitest';
-import PlayButton from '../../src/components/player/PlayButton';
-import { currentEpisode, isPlaying } from '../../src/components/state';
+import PlayButton from 'starpod/src/components/player/PlayButton';
+import { currentEpisode, isPlaying } from 'starpod/src/components/state';
const mockEpisode = {
id: 'test-episode-1',
diff --git a/tests/unit/PlaybackRateButton.test.tsx b/tests/unit/PlaybackRateButton.test.tsx
index bc23e7c3..c54cda50 100644
--- a/tests/unit/PlaybackRateButton.test.tsx
+++ b/tests/unit/PlaybackRateButton.test.tsx
@@ -1,6 +1,6 @@
import { render, screen, fireEvent } from '@testing-library/preact';
import { beforeEach, describe, expect, it } from 'vitest';
-import PlaybackRateButton from '../../src/components/player/PlaybackRateButton';
+import PlaybackRateButton from 'starpod/src/components/player/PlaybackRateButton';
import { createRef } from 'preact';
// Mock audio element
diff --git a/tests/unit/Player.test.tsx b/tests/unit/Player.test.tsx
index 9b822119..17f5fe23 100644
--- a/tests/unit/Player.test.tsx
+++ b/tests/unit/Player.test.tsx
@@ -1,7 +1,7 @@
import { render, screen } from '@testing-library/preact';
import { beforeEach, describe, expect, it, vi } from 'vitest';
-import Player from '../../src/components/Player';
-import { currentEpisode, isPlaying, isMuted } from '../../src/components/state';
+import Player from 'starpod/src/components/Player';
+import { currentEpisode, isPlaying, isMuted } from 'starpod/src/components/state';
const mockEpisode = {
id: 'test-episode-1',
diff --git a/tests/unit/RewindButton.test.tsx b/tests/unit/RewindButton.test.tsx
index 8d9ec09d..75559327 100644
--- a/tests/unit/RewindButton.test.tsx
+++ b/tests/unit/RewindButton.test.tsx
@@ -1,6 +1,6 @@
import { render, screen, fireEvent } from '@testing-library/preact';
import { beforeEach, describe, expect, it } from 'vitest';
-import RewindButton from '../../src/components/player/RewindButton';
+import RewindButton from 'starpod/src/components/player/RewindButton';
import { createRef } from 'preact';
// Mock audio element
diff --git a/tests/unit/SearchButton.test.tsx b/tests/unit/SearchButton.test.tsx
index 8bb6e2e4..1b65e44c 100644
--- a/tests/unit/SearchButton.test.tsx
+++ b/tests/unit/SearchButton.test.tsx
@@ -1,7 +1,7 @@
import { render, screen, fireEvent } from '@testing-library/preact';
import { beforeEach, describe, expect, it } from 'vitest';
-import SearchButton from '../../src/components/SearchButton';
-import { isSearchOpen } from '../../src/components/state';
+import SearchButton from 'starpod/src/components/SearchButton';
+import { isSearchOpen } from 'starpod/src/components/state';
describe('SearchButton', () => {
beforeEach(() => {
diff --git a/tests/unit/SearchDialog.test.tsx b/tests/unit/SearchDialog.test.tsx
index fd4a7950..d3dec7a7 100644
--- a/tests/unit/SearchDialog.test.tsx
+++ b/tests/unit/SearchDialog.test.tsx
@@ -1,7 +1,7 @@
import { render, screen, fireEvent } from '@testing-library/preact';
import { beforeEach, describe, expect, it, vi, afterEach } from 'vitest';
-import SearchDialog from '../../src/components/SearchDialog';
-import { isSearchOpen } from '../../src/components/state';
+import SearchDialog from 'starpod/src/components/SearchDialog';
+import { isSearchOpen } from 'starpod/src/components/state';
// Mock fetch for episodes
const mockEpisodes = [
diff --git a/tests/unit/Slider.test.tsx b/tests/unit/Slider.test.tsx
index 857c8530..140f7614 100644
--- a/tests/unit/Slider.test.tsx
+++ b/tests/unit/Slider.test.tsx
@@ -1,6 +1,6 @@
import { render, screen, fireEvent } from '@testing-library/preact';
import { beforeEach, describe, expect, it } from 'vitest';
-import Slider from '../../src/components/player/Slider';
+import Slider from 'starpod/src/components/player/Slider';
import { createRef } from 'preact';
// Mock audio element
diff --git a/tests/unit/config.test.ts b/tests/unit/config.test.ts
new file mode 100644
index 00000000..a31af246
--- /dev/null
+++ b/tests/unit/config.test.ts
@@ -0,0 +1,74 @@
+import { describe, expect, it } from 'vitest';
+
+import {
+ defineStarpodConfig,
+ validateStarpodConfig,
+ type StarpodConfig
+} from 'starpod/src/utils/config';
+
+const validConfig: StarpodConfig = {
+ blurb: 'A test show.',
+ description: 'A show for testing Starpod.',
+ hosts: [{ name: 'Test Host', bio: 'Bio.', img: 'test-host.jpg' }],
+ platforms: {},
+ rssFeed: 'https://example.com/feed.xml'
+};
+
+describe('defineStarpodConfig', () => {
+ it('returns a valid config unchanged', () => {
+ expect(defineStarpodConfig(validConfig)).toEqual(validConfig);
+ });
+
+ it('accepts optional links and platform urls', () => {
+ const config = defineStarpodConfig({
+ ...validConfig,
+ platforms: { spotify: 'https://open.spotify.com/show/abc' },
+ links: [{ label: 'Store', href: 'https://example.com/store' }]
+ });
+ expect(config.links).toHaveLength(1);
+ });
+
+ it('rejects a non-URL rssFeed and names the field', () => {
+ expect(() =>
+ validateStarpodConfig({ ...validConfig, rssFeed: 'not a url' })
+ ).toThrow(/rssFeed must be a valid URL/);
+ });
+
+ it('rejects an empty hosts array', () => {
+ expect(() =>
+ validateStarpodConfig({ ...validConfig, hosts: [] })
+ ).toThrow(/at least one host/);
+ });
+
+ it('rejects a missing blurb with the field path', () => {
+ const { blurb: _blurb, ...withoutBlurb } = validConfig;
+ expect(() =>
+ validateStarpodConfig(withoutBlurb as StarpodConfig)
+ ).toThrow(/blurb/);
+ });
+
+ it('reports every problem at once', () => {
+ const broken = {
+ ...validConfig,
+ rssFeed: 'nope',
+ hosts: []
+ } as StarpodConfig;
+ let message = '';
+ try {
+ validateStarpodConfig(broken);
+ } catch (error) {
+ message = (error as Error).message;
+ }
+ expect(message).toMatch(/rssFeed/);
+ expect(message).toMatch(/at least one host/);
+ });
+
+ it('rejects hosts missing an img with a helpful message', () => {
+ expect(() =>
+ validateStarpodConfig({
+ ...validConfig,
+ hosts: [{ name: 'X', bio: '', img: '' }]
+ })
+ ).toThrow(/src\/img\/people/);
+ });
+});
diff --git a/tests/unit/contact-api.test.ts b/tests/unit/contact-api.test.ts
index 46879ecd..5da92711 100644
--- a/tests/unit/contact-api.test.ts
+++ b/tests/unit/contact-api.test.ts
@@ -1,6 +1,6 @@
import { afterEach, describe, expect, it, vi } from 'vitest';
-import { ALL, POST } from '../../src/pages/api/contact';
+import { ALL, POST } from 'starpod/src/pages/api/contact';
type ApiContext = Parameters[0];
diff --git a/tests/unit/llms.test.ts b/tests/unit/llms.test.ts
index de8e476b..44a16ea8 100644
--- a/tests/unit/llms.test.ts
+++ b/tests/unit/llms.test.ts
@@ -14,9 +14,9 @@ import {
generateDeveloperResourcesSection,
generateHomeMarkdown,
generateContactMarkdown
-} from '../../src/lib/llms';
-import type { Episode, Show } from '../../src/lib/rss';
-import type { StarpodConfig } from '../../src/utils/config';
+} from 'starpod/src/lib/llms';
+import type { Episode, Show } from 'starpod/src/lib/rss';
+import type { StarpodConfig } from 'starpod/src/utils/config';
describe('LLM Utilities', () => {
describe('formatDuration', () => {
diff --git a/tests/unit/not-found.test.ts b/tests/unit/not-found.test.ts
index 0655256e..e29746ec 100644
--- a/tests/unit/not-found.test.ts
+++ b/tests/unit/not-found.test.ts
@@ -1,7 +1,7 @@
import { describe, expect, it } from 'vitest';
-import { generateNotFoundMarkdown } from '../../src/lib/not-found';
-import type { Show } from '../../src/lib/rss';
+import { generateNotFoundMarkdown } from 'starpod/src/lib/not-found';
+import type { Show } from 'starpod/src/lib/rss';
describe('generateNotFoundMarkdown', () => {
const mockShow: Show = {
diff --git a/tests/unit/openapi.test.ts b/tests/unit/openapi.test.ts
index 2a498e06..fd7aed14 100644
--- a/tests/unit/openapi.test.ts
+++ b/tests/unit/openapi.test.ts
@@ -1,8 +1,8 @@
import { describe, expect, it } from 'vitest';
-import { generateOpenApiSpec } from '../../src/lib/openapi';
-import type { Show } from '../../src/lib/rss';
-import type { StarpodConfig } from '../../src/utils/config';
+import { generateOpenApiSpec } from 'starpod/src/lib/openapi';
+import type { Show } from 'starpod/src/lib/rss';
+import type { StarpodConfig } from 'starpod/src/utils/config';
const mockShow: Show = {
title: 'Test Podcast',
diff --git a/tests/unit/rehype-transcript-timestamps.test.ts b/tests/unit/rehype-transcript-timestamps.test.ts
index edce73ab..8bb9d13a 100644
--- a/tests/unit/rehype-transcript-timestamps.test.ts
+++ b/tests/unit/rehype-transcript-timestamps.test.ts
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest';
-import rehypeTranscriptTimestamps from '../../src/lib/rehype-transcript-timestamps.mjs';
+import rehypeTranscriptTimestamps from 'starpod/src/lib/rehype-transcript-timestamps.mjs';
type HastNode = {
type: string;
diff --git a/tests/unit/robots.test.ts b/tests/unit/robots.test.ts
index 9ab1d79d..98ac4aa2 100644
--- a/tests/unit/robots.test.ts
+++ b/tests/unit/robots.test.ts
@@ -1,5 +1,5 @@
import { describe, expect, it, beforeEach } from 'vitest';
-import { getRobotsTxt } from '../../src/pages/robots.txt';
+import { getRobotsTxt } from 'starpod/src/pages/robots.txt';
describe('Robots.txt', () => {
let mockSite: URL;
diff --git a/tests/unit/transcript.test.ts b/tests/unit/transcript.test.ts
index 01bee066..413f767d 100644
--- a/tests/unit/transcript.test.ts
+++ b/tests/unit/transcript.test.ts
@@ -3,8 +3,8 @@ import { afterEach, describe, expect, it, vi } from 'vitest';
import {
getRssTranscriptParagraphs,
getRssTranscriptText
-} from '../../src/lib/transcript';
-import type { Episode } from '../../src/lib/rss';
+} from 'starpod/src/lib/transcript';
+import type { Episode } from 'starpod/src/lib/rss';
// Each test uses a unique transcript URL because the module caches parsed
// transcripts by URL β reusing a URL would return a previous test's cached
diff --git a/tests/unit/vercel-md-negotiation.test.ts b/tests/unit/vercel-md-negotiation.test.ts
index b1d7bd51..873ed490 100644
--- a/tests/unit/vercel-md-negotiation.test.ts
+++ b/tests/unit/vercel-md-negotiation.test.ts
@@ -7,7 +7,7 @@ import {
buildNegotiationRoutes,
collectMarkdownPaths,
patchConfig
-} from '../../scripts/vercel-md-negotiation.mjs';
+} from 'starpod/src/vercel-md-negotiation.mjs';
const ACCEPT_MD = [{ type: 'header', key: 'accept', value: '.*text/markdown.*' }];
diff --git a/tsconfig.json b/tsconfig.json
index e3696fbb..6bcf9434 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -3,6 +3,9 @@
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"baseUrl": ".",
+ "paths": {
+ "starpod/src/*": ["./packages/starpod/src/*"]
+ },
"esModuleInterop": true,
"strictNullChecks": true,
"verbatimModuleSyntax": true,
@@ -10,5 +13,5 @@
"jsxImportSource": "preact"
},
"include": [".astro/types.d.ts", "**/*"],
- "exclude": ["dist"]
+ "exclude": ["dist", "packages/starpod/cli/template"]
}
diff --git a/vitest.config.ts b/vitest.config.ts
index 91f56210..e698fa55 100644
--- a/vitest.config.ts
+++ b/vitest.config.ts
@@ -1,3 +1,5 @@
+import { fileURLToPath } from 'node:url';
+
import { defineConfig } from 'vitest/config';
export default defineConfig({
@@ -10,7 +12,17 @@ export default defineConfig({
},
resolve: {
alias: {
- '@': '/src'
+ '@': '/src',
+ // Resolve package-internal imports as filesystem paths so
+ // directory-index imports (e.g. .../player/Slider) work in tests.
+ 'starpod/src': fileURLToPath(
+ new URL('./packages/starpod/src', import.meta.url)
+ ),
+ // Outside Astro there is no integration to provide the virtual config
+ // module, so tests resolve it straight to the site's config file.
+ 'virtual:starpod/config': fileURLToPath(
+ new URL('./starpod.config.ts', import.meta.url)
+ )
}
}
});