chore(deps): upgrade development tools (#14040)

Co-authored-by: alexanderniebuhr <45965090+alexanderniebuhr@users.noreply.github.com>
This commit is contained in:
Emanuele Stoppa
2025-07-24 07:31:23 -04:00
committed by GitHub
parent 9362743424
commit c2a347d8a6
84 changed files with 965 additions and 542 deletions

View File

@@ -29,3 +29,4 @@ pnpm-lock.yaml
**/*.jsx
**/*.mjs
**/*.cjs
**/*.css

View File

@@ -15,7 +15,7 @@
"editor.defaultFormatter": "biomejs.biome"
},
"editor.codeActionsOnSave": {
"quickFix.biome": "explicit",
"source.fixAll.biome": "explicit"
}
"quickFix.biome": "explicit",
"source.fixAll.biome": "explicit"
}
}

View File

@@ -259,7 +259,6 @@ The Astro project has five levels of priority to issues, where `p5` is the highe
- `p5`: the bug impacts the majority of Astro projects, it doesn't have a workaround and makes Astro unusable/unstable.
Some examples:
- the dev server crashes;
- the build breaks and doesn't complete;
- huge regressions in terms of performance;

View File

@@ -4,6 +4,5 @@
* previous artifacts here before generating files.
* @param {URL} projectDir
*/
// biome-ignore lint/correctness/noUnusedVariables: parameters here are template placeholders
// biome-ignore lint/correctness/noUnusedFunctionParameters: (same as above)
export async function run(projectDir) {}

View File

@@ -1,18 +1,7 @@
{
"$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
"$schema": "https://biomejs.dev/schemas/2.1.2/schema.json",
"files": {
"includes": [
"**/test/**",
"**/e2e/**",
"**/packages/**",
"**/scripts/**",
"**/benchmark/**",
"**/biome.jsonc",
"!**/smoke/**",
"!**/fixtures/**",
"!**/_temp-fixtures/**",
"!**/vendor/**"
]
"includes": ["**", "!**/smoke/**", "!**/fixtures/**", "!**/_temp-fixtures/**", "!**/vendor/**"]
},
"vcs": {
"enabled": true,
@@ -23,9 +12,16 @@
"indentStyle": "tab",
"indentWidth": 2,
"lineWidth": 100,
"includes": ["**", "!**/.changeset", "!**/pnpm-lock.yaml", "!**/*.astro"]
"includes": ["**", "!**/.changeset", "!**/pnpm-lock.yaml", "!**/*.astro"],
"expand": "auto"
},
"assist": {
"actions": {
"source": {
"organizeImports": "on"
}
}
},
"assist": { "actions": { "source": { "organizeImports": "on" } } },
"linter": {
"enabled": true,
"rules": {
@@ -37,7 +33,12 @@
},
"suspicious": {
// This one is specific to catch `console.log`. The rest of logs are permitted
"noConsole": { "level": "warn", "options": { "allow": ["error", "warn", "info", "debug"] } }
"noConsole": {
"level": "warn",
"options": {
"allow": ["error", "warn", "info", "debug"]
}
}
},
"correctness": {
"noUnusedVariables": {
@@ -74,7 +75,21 @@
"includes": ["**/package.json"],
"json": {
"formatter": {
"lineWidth": 1
"expand": "always"
}
}
},
{
"includes": ["**/*.astro", "**/*.vue", "**/*.svelte"],
"formatter": {
"enabled": false
},
"linter": {
"rules": {
"correctness": {
"noUnusedVariables": "off",
"noUnusedImports": "off"
}
}
}
},

View File

@@ -1,10 +1,9 @@
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import tseslint from 'typescript-eslint';
// plugins
import regexpEslint from 'eslint-plugin-regexp';
import tseslint from 'typescript-eslint';
const typescriptEslint = tseslint.plugin;
// parsers

View File

@@ -1,7 +1,8 @@
// @ts-check
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import sitemap from '@astrojs/sitemap';
import { defineConfig } from 'astro/config';
// https://astro.build/config
export default defineConfig({

View File

@@ -2,9 +2,9 @@
// Import the global.css file here so that it is included on
// all pages through the use of the <BaseHead /> component.
import '../styles/global.css';
import { SITE_TITLE } from '../consts';
import FallbackImage from '../assets/blog-placeholder-1.jpg';
import type { ImageMetadata } from 'astro';
import FallbackImage from '../assets/blog-placeholder-1.jpg';
import { SITE_TITLE } from '../consts';
interface Props {
title: string;

View File

@@ -1,6 +1,6 @@
---
import HeaderLink from './HeaderLink.astro';
import { SITE_TITLE } from '../consts';
import HeaderLink from './HeaderLink.astro';
---
<header>

View File

@@ -1,18 +1,19 @@
import { glob } from 'astro/loaders';
import { defineCollection, z } from 'astro:content';
import { glob } from 'astro/loaders';
const blog = defineCollection({
// Load Markdown and MDX files in the `src/content/blog/` directory.
loader: glob({ base: './src/content/blog', pattern: '**/*.{md,mdx}' }),
// Type-check frontmatter using a schema
schema: ({ image }) => z.object({
title: z.string(),
description: z.string(),
// Transform string to Date object
pubDate: z.coerce.date(),
updatedDate: z.coerce.date().optional(),
heroImage: image().optional(),
}),
schema: ({ image }) =>
z.object({
title: z.string(),
description: z.string(),
// Transform string to Date object
pubDate: z.coerce.date(),
updatedDate: z.coerce.date().optional(),
heroImage: image().optional(),
}),
});
export const collections = { blog };

View File

@@ -1,10 +1,10 @@
---
import { Image } from 'astro:assets';
import type { CollectionEntry } from 'astro:content';
import BaseHead from '../components/BaseHead.astro';
import Header from '../components/Header.astro';
import Footer from '../components/Footer.astro';
import FormattedDate from '../components/FormattedDate.astro';
import { Image } from 'astro:assets';
import Header from '../components/Header.astro';
type Props = CollectionEntry<'blog'>['data'];

View File

@@ -1,6 +1,6 @@
---
import Layout from '../layouts/BlogPost.astro';
import AboutHeroImage from '../assets/blog-placeholder-about.jpg';
import Layout from '../layouts/BlogPost.astro';
---
<Layout

View File

@@ -1,7 +1,6 @@
---
import { type CollectionEntry, getCollection } from 'astro:content';
import { type CollectionEntry, getCollection, render } from 'astro:content';
import BlogPost from '../../layouts/BlogPost.astro';
import { render } from 'astro:content';
export async function getStaticPaths() {
const posts = await getCollection('blog');

View File

@@ -1,11 +1,11 @@
---
import BaseHead from '../../components/BaseHead.astro';
import Header from '../../components/Header.astro';
import Footer from '../../components/Footer.astro';
import { SITE_TITLE, SITE_DESCRIPTION } from '../../consts';
import { getCollection } from 'astro:content';
import FormattedDate from '../../components/FormattedDate.astro';
import { Image } from 'astro:assets';
import { getCollection } from 'astro:content';
import BaseHead from '../../components/BaseHead.astro';
import Footer from '../../components/Footer.astro';
import FormattedDate from '../../components/FormattedDate.astro';
import Header from '../../components/Header.astro';
import { SITE_DESCRIPTION, SITE_TITLE } from '../../consts';
const posts = (await getCollection('blog')).sort(
(a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf(),

View File

@@ -1,8 +1,8 @@
---
import BaseHead from '../components/BaseHead.astro';
import Header from '../components/Header.astro';
import Footer from '../components/Footer.astro';
import { SITE_TITLE, SITE_DESCRIPTION } from '../consts';
import Header from '../components/Header.astro';
import { SITE_DESCRIPTION, SITE_TITLE } from '../consts';
---
<!doctype html>

View File

@@ -1,6 +1,6 @@
import rss from '@astrojs/rss';
import { getCollection } from 'astro:content';
import { SITE_TITLE, SITE_DESCRIPTION } from '../consts';
import rss from '@astrojs/rss';
import { SITE_DESCRIPTION, SITE_TITLE } from '../consts';
export async function GET(context) {
const posts = await getCollection('blog');

View File

@@ -13,25 +13,25 @@
--gray-dark: 34, 41, 57;
--gray-gradient: rgba(var(--gray-light), 50%), #fff;
--box-shadow:
0 2px 6px rgba(var(--gray), 25%), 0 8px 24px rgba(var(--gray), 33%),
0 16px 32px rgba(var(--gray), 33%);
0 2px 6px rgba(var(--gray), 25%), 0 8px 24px rgba(var(--gray), 33%), 0 16px 32px
rgba(var(--gray), 33%);
}
@font-face {
font-family: 'Atkinson';
src: url('/fonts/atkinson-regular.woff') format('woff');
font-family: "Atkinson";
src: url("/fonts/atkinson-regular.woff") format("woff");
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Atkinson';
src: url('/fonts/atkinson-bold.woff') format('woff');
font-family: "Atkinson";
src: url("/fonts/atkinson-bold.woff") format("woff");
font-weight: 700;
font-style: normal;
font-display: swap;
}
body {
font-family: 'Atkinson', sans-serif;
font-family: "Atkinson", sans-serif;
margin: 0;
padding: 0;
text-align: left;

View File

@@ -1,7 +1,7 @@
import react from '@astrojs/react';
import { defineConfig } from 'astro/config';
import react from "@astrojs/react"
// https://astro.build/config
export default defineConfig({
integrations: [react()]
integrations: [react()],
});

View File

@@ -1,6 +1,6 @@
import { useState } from 'react';
export default function({ initialCount }) {
export default function ({ initialCount }) {
const [count, setCount] = useState(initialCount || 0);
return (
<div className="rounded-t-lg overflow-hidden border-t border-l border-r border-gray-400 text-center p-4">
@@ -8,7 +8,10 @@ export default function({ initialCount }) {
<h3 className="font-medium text-lg">Count: {count}</h3>
<button
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
onClick={() => setCount(count + 1)}>Increment</button>
onClick={() => setCount(count + 1)}
>
Increment
</button>
</div>
)
);
}

View File

@@ -1,6 +1,7 @@
// @ts-check
import { defineConfig } from 'astro/config';
import alpine from '@astrojs/alpinejs';
import { defineConfig } from 'astro/config';
// https://astro.build/config
export default defineConfig({

View File

@@ -1,10 +1,11 @@
// @ts-check
import { defineConfig } from 'astro/config';
import preact from '@astrojs/preact';
import react from '@astrojs/react';
import solid from '@astrojs/solid-js';
import svelte from '@astrojs/svelte';
import vue from '@astrojs/vue';
import solid from '@astrojs/solid-js';
import { defineConfig } from 'astro/config';
// https://astro.build/config
export default defineConfig({

View File

@@ -1,7 +1,7 @@
/** @jsxImportSource preact */
import { useState } from 'preact/hooks';
import type { ComponentChildren } from 'preact';
import { useState } from 'preact/hooks';
/** A counter written with Preact */
export function PreactCounter({ children }: { children?: ComponentChildren }) {

View File

@@ -1,6 +1,6 @@
/** @jsxImportSource react */
import { useState, type ReactNode } from 'react';
import { type ReactNode, useState } from 'react';
/** A counter written with React */
export function Counter({ children }: { children?: ReactNode }) {

View File

@@ -2,14 +2,13 @@
// Style Imports
import '../styles/global.css';
import { PreactCounter } from '../components/preact/PreactCounter';
// Component Imports
// For JSX components, all the common ways of exporting (under a namespace, specific export, default export etc) are supported!
import * as react from '../components/react/ReactCounter';
import { PreactCounter } from '../components/preact/PreactCounter';
import SolidCounter from '../components/solid/SolidCounter';
import VueCounter from '../components/vue/VueCounter.vue';
import SvelteCounter from '../components/svelte/SvelteCounter.svelte';
import VueCounter from '../components/vue/VueCounter.vue';
// Full Astro Component Syntax:
// https://docs.astro.build/basics/astro-components/

View File

@@ -1,6 +1,7 @@
// @ts-check
import { defineConfig } from 'astro/config';
import preact from '@astrojs/preact';
import { defineConfig } from 'astro/config';
// https://astro.build/config
export default defineConfig({

View File

@@ -1,5 +1,5 @@
import type { ComponentChildren } from 'preact';
import type { Signal } from '@preact/signals';
import type { ComponentChildren } from 'preact';
import { lazy, Suspense } from 'preact/compat';
import './Counter.css';

View File

@@ -1,9 +1,8 @@
---
import { signal } from '@preact/signals';
// Component Imports
import Counter from '../components/Counter';
import { signal } from '@preact/signals';
// Full Astro Component Syntax:
// https://docs.astro.build/basics/astro-components/

View File

@@ -1,6 +1,7 @@
// @ts-check
import { defineConfig } from 'astro/config';
import react from '@astrojs/react';
import { defineConfig } from 'astro/config';
// https://astro.build/config
export default defineConfig({

View File

@@ -1,6 +1,7 @@
---
// Component Imports
import Counter from '../components/Counter';
const someProps = {
count: 0,
};

View File

@@ -1,6 +1,7 @@
// @ts-check
import { defineConfig } from 'astro/config';
import solid from '@astrojs/solid-js';
import { defineConfig } from 'astro/config';
// https://astro.build/config
export default defineConfig({

View File

@@ -1,6 +1,7 @@
// @ts-check
import { defineConfig } from 'astro/config';
import svelte from '@astrojs/svelte';
import { defineConfig } from 'astro/config';
// https://astro.build/config
export default defineConfig({

View File

@@ -1,6 +1,7 @@
// @ts-check
import { defineConfig } from 'astro/config';
import vue from '@astrojs/vue';
import { defineConfig } from 'astro/config';
// https://astro.build/config
export default defineConfig({

View File

@@ -1,6 +1,7 @@
// @ts-check
import { defineConfig } from 'astro/config';
import node from '@astrojs/node';
import { defineConfig } from 'astro/config';
// https://astro.build/config
export default defineConfig({

View File

@@ -1,5 +1,6 @@
---
import Icon from './Icon.astro';
const currentYear = new Date().getFullYear();
---

View File

@@ -1,7 +1,7 @@
---
import Icon from './Icon.astro';
import ThemeToggle from './ThemeToggle.astro';
import type { iconPaths } from './IconPaths';
import ThemeToggle from './ThemeToggle.astro';
/** Main menu items */
const textLinks: { label: string; href: string }[] = [

View File

@@ -1,10 +1,10 @@
import { glob } from 'astro/loaders';
import { defineCollection, z } from 'astro:content';
import { glob } from 'astro/loaders';
export const collections = {
work: defineCollection({
// Load Markdown files in the src/content/work directory.
loader: glob({ base: './src/content/work', pattern: '**/*.md', }),
loader: glob({ base: './src/content/work', pattern: '**/*.md' }),
schema: z.object({
title: z.string(),
description: z.string(),

View File

@@ -2,10 +2,10 @@
// Learn about using Astro layouts:
// https://docs.astro.build/en/core-concepts/layouts/
import Footer from '../components/Footer.astro';
// Component Imports
import MainHead from '../components/MainHead.astro';
import Nav from '../components/Nav.astro';
import Footer from '../components/Footer.astro';
interface Props {
title?: string | undefined;

View File

@@ -1,8 +1,7 @@
---
import BaseLayout from '../layouts/BaseLayout.astro';
import ContactCTA from '../components/ContactCTA.astro';
import Hero from '../components/Hero.astro';
import BaseLayout from '../layouts/BaseLayout.astro';
---
<BaseLayout title="About | Jeanine White" description="About Jeanine White Lorem Ipsum">

View File

@@ -1,20 +1,17 @@
---
import { getCollection } from 'astro:content';
// Layout import — provides basic page elements: <head>, <nav>, <footer> etc.
import BaseLayout from '../layouts/BaseLayout.astro';
// Component Imports
import CallToAction from '../components/CallToAction.astro';
// Page section components
import ContactCTA from '../components/ContactCTA.astro';
import Grid from '../components/Grid.astro';
import Hero from '../components/Hero.astro';
import Icon from '../components/Icon.astro';
import Pill from '../components/Pill.astro';
import PortfolioPreview from '../components/PortfolioPreview.astro';
// Page section components
import ContactCTA from '../components/ContactCTA.astro';
import Skills from '../components/Skills.astro';
// Layout import — provides basic page elements: <head>, <nav>, <footer> etc.
import BaseLayout from '../layouts/BaseLayout.astro';
// Content Fetching: List four most recent work projects
const projects = (await getCollection('work'))

View File

@@ -1,12 +1,10 @@
---
import { getCollection } from 'astro:content';
import BaseLayout from '../layouts/BaseLayout.astro';
import ContactCTA from '../components/ContactCTA.astro';
import PortfolioPreview from '../components/PortfolioPreview.astro';
import Hero from '../components/Hero.astro';
import Grid from '../components/Grid.astro';
import Hero from '../components/Hero.astro';
import PortfolioPreview from '../components/PortfolioPreview.astro';
import BaseLayout from '../layouts/BaseLayout.astro';
const projects = (await getCollection('work')).sort(
(a, b) => b.data.publishDate.valueOf() - a.data.publishDate.valueOf(),

View File

@@ -1,13 +1,11 @@
---
import { type CollectionEntry, getCollection } from 'astro:content';
import BaseLayout from '../../layouts/BaseLayout.astro';
import { type CollectionEntry, getCollection, render } from 'astro:content';
import ContactCTA from '../../components/ContactCTA.astro';
import Hero from '../../components/Hero.astro';
import Icon from '../../components/Icon.astro';
import Pill from '../../components/Pill.astro';
import { render } from 'astro:content';
import BaseLayout from '../../layouts/BaseLayout.astro';
interface Props {
entry: CollectionEntry<'work'>;

View File

@@ -68,9 +68,9 @@
/* Fonts */
--font-system:
system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell,
'Open Sans', 'Helvetica Neue', sans-serif;
--font-body: 'Public Sans', var(--font-system);
system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell,
"Open Sans", "Helvetica Neue", sans-serif;
--font-body: "Public Sans", var(--font-system);
--font-brand: Rubik, var(--font-system);
/* Transitions */

View File

@@ -1,7 +1,8 @@
// @ts-check
import { defineConfig } from 'astro/config';
import svelte from '@astrojs/svelte';
import node from '@astrojs/node';
import svelte from '@astrojs/svelte';
import { defineConfig } from 'astro/config';
// https://astro.build/config
export default defineConfig({

View File

@@ -17,10 +17,7 @@ interface Cart {
}>;
}
async function getJson<T>(
incomingReq: Request,
endpoint: string,
): Promise<T> {
async function getJson<T>(incomingReq: Request, endpoint: string): Promise<T> {
const origin = new URL(incomingReq.url).origin;
try {
const response = await fetch(`${origin}${endpoint}`, {

View File

@@ -1,5 +1,6 @@
<script>
import { addToUserCart } from '../api';
let { id, name } = $props()
function notifyCartItem(id) {

View File

@@ -1,7 +1,7 @@
---
import TextDecorationSkip from './TextDecorationSkip.astro';
import Cart from './Cart.svelte';
import { getCart } from '../api';
import Cart from './Cart.svelte';
import TextDecorationSkip from './TextDecorationSkip.astro';
const cart = await getCart(Astro.request);
const cartCount = cart.items.reduce((sum, item) => sum + item.count, 0);

View File

@@ -1,5 +1,5 @@
import { productMap } from '../../../models/db';
import type { APIContext } from 'astro';
import { productMap } from '../../../models/db';
export function GET({ params }: APIContext) {
const id = Number(params.id);

View File

@@ -1,7 +1,7 @@
---
import Header from '../components/Header.astro';
import Container from '../components/Container.astro';
import { getCart } from '../api';
import Container from '../components/Container.astro';
import Header from '../components/Header.astro';
if (!Astro.cookies.get('user-id')) {
return Astro.redirect('/');

View File

@@ -1,8 +1,8 @@
---
import Header from '../components/Header.astro';
import Container from '../components/Container.astro';
import ProductListing from '../components/ProductListing.astro';
import { getProducts } from '../api';
import Container from '../components/Container.astro';
import Header from '../components/Header.astro';
import ProductListing from '../components/ProductListing.astro';
import '../styles/common.css';
const products = await getProducts(Astro.request);

View File

@@ -1,6 +1,6 @@
---
import Header from '../components/Header.astro';
import Container from '../components/Container.astro';
import Header from '../components/Header.astro';
---
<html lang="en">

View File

@@ -1,8 +1,8 @@
---
import Header from '../../components/Header.astro';
import Container from '../../components/Container.astro';
import AddToCart from '../../components/AddToCart.svelte';
import { getProduct } from '../../api';
import AddToCart from '../../components/AddToCart.svelte';
import Container from '../../components/Container.astro';
import Header from '../../components/Header.astro';
import '../../styles/common.css';
const id = Number(Astro.params.id);

View File

@@ -1,3 +1,3 @@
body {
font-family: 'GT America Standard', 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-family: "GT America Standard", "Helvetica Neue", Helvetica, Arial, sans-serif;
}

View File

@@ -1,7 +1,7 @@
---
import { ClientRouter } from 'astro:transitions';
import { SiteDescription, SiteTitle } from '../consts';
import SEO, { type Props as SEOProps } from './SEO.astro';
import { SiteTitle, SiteDescription } from '../consts';
export type Props = Partial<SEOProps>;
const { title = SiteTitle, name = SiteTitle, description = SiteDescription, ...seo } = Astro.props;

View File

@@ -1,5 +1,6 @@
---
import type { ImageMetadata } from 'astro';
type Image = {
src: string | ImageMetadata;
alt: string;

View File

@@ -1,5 +1,5 @@
import { glob } from 'astro/loaders';
import { defineCollection, z } from 'astro:content';
import { glob } from 'astro/loaders';
const releases = defineCollection({
// Load Markdown files in the src/content/releases directory.

View File

@@ -1,7 +1,7 @@
---
import BaseHead, { type Props as HeadProps } from '../components/BaseHead.astro';
import Header from '../components/Header.astro';
import Footer from '../components/Footer.astro';
import Header from '../components/Header.astro';
type Props = HeadProps;

View File

@@ -1,9 +1,9 @@
---
import type { CollectionEntry } from 'astro:content';
import BaseHead from '../components/BaseHead.astro';
import Footer from '../components/Footer.astro';
import FormattedDate from '../components/FormattedDate.astro';
import Header from '../components/Header.astro';
import Footer from '../components/Footer.astro';
type Props = {
release: CollectionEntry<'releases'>;

View File

@@ -7,10 +7,10 @@ export default {
hooks: {
'astro:config:setup': ({ addDevToolbarApp }) => {
addDevToolbarApp({
id: "my-toolbar-app",
name: "My Toolbar App",
icon: "🚀",
entrypoint: fileURLToPath(new URL('./app.js', import.meta.url))
id: 'my-toolbar-app',
name: 'My Toolbar App',
icon: '🚀',
entrypoint: fileURLToPath(new URL('./app.js', import.meta.url)),
});
},
},

View File

@@ -1,6 +1,7 @@
// @ts-check
import { defineConfig } from 'astro/config';
import markdoc from '@astrojs/markdoc';
import { defineConfig } from 'astro/config';
// https://astro.build/config
export default defineConfig({

View File

@@ -1,4 +1,4 @@
import { defineMarkdocConfig, component } from '@astrojs/markdoc/config';
import { component, defineMarkdocConfig } from '@astrojs/markdoc/config';
export default defineMarkdocConfig({
tags: {

View File

@@ -1,7 +1,8 @@
// @ts-check
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import preact from '@astrojs/preact';
import { defineConfig } from 'astro/config';
// https://astro.build/config
export default defineConfig({

View File

@@ -1,6 +1,7 @@
// @ts-check
import { defineConfig } from 'astro/config';
import preact from '@astrojs/preact';
import { defineConfig } from 'astro/config';
// https://astro.build/config
export default defineConfig({

View File

@@ -1,6 +1,6 @@
import { isCartOpen, addCartItem } from '../cartStore';
import type { CartItemDisplayInfo } from '../cartStore';
import type { ComponentChildren } from 'preact';
import type { CartItemDisplayInfo } from '../cartStore';
import { addCartItem, isCartOpen } from '../cartStore';
type Props = {
item: CartItemDisplayInfo;

View File

@@ -1,8 +1,8 @@
---
import type { CartItemDisplayInfo } from '../cartStore';
import Layout from '../layouts/Layout.astro';
import AddToCartForm from '../components/AddToCartForm';
import FigurineDescription from '../components/FigurineDescription.astro';
import Layout from '../layouts/Layout.astro';
import { withBase } from '../utils';
const item: CartItemDisplayInfo = {

View File

@@ -1,10 +1,11 @@
// @ts-check
import { defineConfig } from 'astro/config';
import tailwindcss from '@tailwindcss/vite';
import { defineConfig } from 'astro/config';
// https://astro.build/config
export default defineConfig({
vite: {
plugins: [tailwindcss()]
}
plugins: [tailwindcss()],
},
});

View File

@@ -1 +1 @@
@import 'tailwindcss';
@import "tailwindcss";

View File

@@ -55,22 +55,22 @@
},
"devDependencies": {
"@astrojs/check": "^0.9.4",
"@biomejs/biome": "2.0.0",
"@biomejs/biome": "2.1.2",
"@changesets/changelog-github": "^0.5.1",
"@changesets/cli": "^2.28.1",
"@types/node": "^18.19.50",
"esbuild": "^0.25.0",
"eslint": "^9.24.0",
"eslint-plugin-regexp": "^2.7.0",
"knip": "5.50.5",
"@changesets/cli": "^2.29.5",
"@types/node": "^18.19.115",
"esbuild": "0.25.5",
"eslint": "^9.30.1",
"eslint-plugin-regexp": "^2.9.0",
"knip": "5.61.3",
"only-allow": "^1.2.1",
"prettier": "^3.5.3",
"prettier": "^3.6.2",
"prettier-plugin-astro": "^0.14.1",
"publint": "^0.3.10",
"tinyglobby": "^0.2.12",
"turbo": "^2.5.0",
"publint": "^0.3.12",
"tinyglobby": "^0.2.14",
"turbo": "^2.5.4",
"typescript": "~5.8.3",
"typescript-eslint": "^8.29.0"
"typescript-eslint": "^8.35.1"
},
"pnpm": {
"peerDependencyRules": {

View File

@@ -3,9 +3,9 @@
object-position: var(--pos);
height: auto;
}
:where([data-astro-image='full-width']) {
:where([data-astro-image="full-width"]) {
width: 100%;
}
:where([data-astro-image='constrained']) {
:where([data-astro-image="constrained"]) {
max-width: 100%;
}

View File

@@ -1,6 +1,5 @@
import type { RehypePlugin } from '@astrojs/markdown-remark';
import type { RootContent } from 'hast';
// biome-ignore lint/correctness/noUnusedImports: This import includes ambient types for hast to include mdx nodes
import type {} from 'mdast-util-mdx';
import type {
MdxJsxAttribute,

View File

@@ -14,7 +14,6 @@ import {
/** @returns {string} */
// used while generating the virtual module
// biome-ignore lint/correctness/noUnusedFunctionParameters: `key` is used by the generated code
// biome-ignore lint/correctness/noUnusedVariables: `key` is used by the generated code
const getEnv = (key) => {
// @@GET_ENV@@
};

View File

@@ -2,7 +2,6 @@ import type { RehypePlugin } from '@astrojs/markdown-remark';
import { SKIP, visit } from 'estree-util-visit';
import type { Element, RootContent, RootContentMap } from 'hast';
import { toHtml } from 'hast-util-to-html';
// biome-ignore lint/correctness/noUnusedImports: This import includes ambient types for hast to include mdx nodes
import type {} from 'mdast-util-mdx';
import type { MdxJsxFlowElementHast, MdxJsxTextElementHast } from 'mdast-util-mdx-jsx';

View File

@@ -637,7 +637,6 @@
The Vercel adapter has a file-tracer it uses to detect which files should be moved over to the `dist/` folder. When it's done, it prints warnings for things that it detected that maybe should be moved.
This change expands how we do ignores so that:
- Ignores happen within dot folders like `.pnpm`.
- `@libsql/client` is ignored, a package we know is not bundled.
@@ -860,7 +859,6 @@
### Patch Changes
- [#8348](https://github.com/withastro/astro/pull/8348) [`5f2c55bb5`](https://github.com/withastro/astro/commit/5f2c55bb54bb66693d278b7cd705c198aecc0331) Thanks [@ematipico](https://github.com/ematipico)! - - Cache result during bundling, to speed up the process of multiple functions;
- Avoid creating multiple symbolic links of the dependencies when building the project with `functionPerRoute` enabled;
- [#8354](https://github.com/withastro/astro/pull/8354) [`0eb09dbab`](https://github.com/withastro/astro/commit/0eb09dbab1674a57d23ac97950a527d2e5a9c9fb) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Fix unnecessary warning about Sharp showing while building
@@ -1720,7 +1718,6 @@
- [#4015](https://github.com/withastro/astro/pull/4015) [`6fd161d76`](https://github.com/withastro/astro/commit/6fd161d7691cbf9d3ffa4646e46059dfd0940010) Thanks [@matthewp](https://github.com/matthewp)! - New `output` configuration option
This change introduces a new "output target" configuration option (`output`). Setting the output target lets you decide the format of your final build, either:
- `"static"` (default): A static site. Your final build will be a collection of static assets (HTML, CSS, JS) that you can deploy to any static site host.
- `"server"`: A dynamic server application. Your final build will be an application that will run in a hosted server environment, generating HTML dynamically for different requests.
@@ -1798,13 +1795,11 @@
### Minor Changes
- [#3216](https://github.com/withastro/astro/pull/3216) [`114bf63e`](https://github.com/withastro/astro/commit/114bf63e11f28299b13178ef1a412eed37ab7909) Thanks [@JuanM04](https://github.com/JuanM04)! - **[BREAKING]** Now with Build Output API (v3)! [See the README to get started](https://github.com/withastro/astro/tree/main/packages/integrations/vercel#readme).
- `trailingSlash` redirects works without a `vercel.json` file: just configure them inside your `astro.config.mjs`
- Multiple deploy targets: `edge`, `serverless` and `static`!
- When building to `serverless`, your code isn't transpiled to CJS anymore.
**Migrate from v0.1**
1. Change the import inside `astro.config.mjs`:
```diff
- import vercel from '@astrojs/vercel';

View File

@@ -50,7 +50,7 @@
"dependencies": {
"@astrojs/internal-helpers": "workspace:*",
"@vercel/analytics": "^1.5.0",
"@vercel/edge": "^1.2.1",
"@vercel/functions": "^2.2.2",
"@vercel/nft": "^0.29.2",
"@vercel/routing-utils": "^5.0.4",
"esbuild": "^0.25.0",

View File

@@ -64,19 +64,36 @@ const ISR_PATH = `/_isr?${ASTRO_PATH_PARAM}=$0`;
// https://vercel.com/docs/concepts/functions/serverless-functions/runtimes/node-js#node.js-version
const SUPPORTED_NODE_VERSIONS: Record<
string,
| { status: 'default' }
| { status: 'available' }
| { status: 'beta' }
| { status: 'retiring'; removal: Date | string; warnDate: Date }
| { status: 'deprecated'; removal: Date }
| {
status: 'default';
}
| {
status: 'available';
}
| {
status: 'beta';
}
| {
status: 'retiring';
removal: Date | string;
warnDate: Date;
}
| {
status: 'deprecated';
removal: Date;
}
> = {
18: {
status: 'retiring',
removal: new Date('September 1 2025'),
warnDate: new Date('October 1 2024'),
},
20: { status: 'available' },
22: { status: 'default' },
20: {
status: 'available',
},
22: {
status: 'default',
},
};
function getAdapter({
@@ -96,7 +113,10 @@ function getAdapter({
name: PACKAGE_NAME,
serverEntrypoint: `${PACKAGE_NAME}/entrypoint`,
exports: ['default'],
args: { middlewareSecret, skewProtection },
args: {
middlewareSecret,
skewProtection,
},
adapterFeatures: {
edgeMiddleware,
buildOutput,
@@ -196,10 +216,14 @@ export default function vercelAdapter({
}: VercelServerlessConfig = {}): AstroIntegration {
if (maxDuration) {
if (typeof maxDuration !== 'number') {
throw new TypeError(`maxDuration must be a number`, { cause: maxDuration });
throw new TypeError(`maxDuration must be a number`, {
cause: maxDuration,
});
}
if (maxDuration <= 0) {
throw new TypeError(`maxDuration must be a positive number`, { cause: maxDuration });
throw new TypeError(`maxDuration must be a positive number`, {
cause: maxDuration,
});
}
}
@@ -452,7 +476,10 @@ export default function vercelAdapter({
const dest = _middlewareEntryPoint ? MIDDLEWARE_PATH : NODE_PATH;
for (const route of expandedExclusions) {
// vercel interprets src as a regex pattern, so we need to escape it
routeDefinitions.push({ src: escapeRegex(route), dest });
routeDefinitions.push({
src: escapeRegex(route),
dest,
});
}
}
await builder.buildISRFolder(entryFile, '_isr', isrConfig, _config.root);
@@ -472,7 +499,11 @@ export default function vercelAdapter({
src.startsWith('^\\/_image') || src.startsWith('^\\/_server-islands')
? NODE_PATH
: ISR_PATH;
if (!route.isPrerendered) routeDefinitions.push({ src, dest });
if (!route.isPrerendered)
routeDefinitions.push({
src,
dest,
});
}
}
} else {
@@ -480,7 +511,10 @@ export default function vercelAdapter({
const dest = _middlewareEntryPoint ? MIDDLEWARE_PATH : NODE_PATH;
for (const route of routes) {
if (!route.isPrerendered)
routeDefinitions.push({ src: route.patternRegex.source, dest });
routeDefinitions.push({
src: route.patternRegex.source,
dest,
});
}
}
}
@@ -497,7 +531,9 @@ export default function vercelAdapter({
const finalRoutes: Route[] = [
{
src: `^/${_config.build.assets}/(.*)$`,
headers: { 'cache-control': 'public, max-age=31536000, immutable' },
headers: {
'cache-control': 'public, max-age=31536000, immutable',
},
continue: true,
},
];
@@ -652,7 +688,9 @@ class VercelBuilder {
// Enable ESM
// https://aws.amazon.com/blogs/compute/using-node-js-es-modules-and-top-level-await-in-aws-lambda/
await writeJson(packageJson, { type: 'module' });
await writeJson(packageJson, {
type: 'module',
});
// Serverless function config
// https://vercel.com/docs/build-output-api/v3#vercel-primitives/serverless-functions/configuration
@@ -730,9 +768,9 @@ function getRuntime(process: NodeJS.Process, logger: AstroIntegrationLogger): Ru
return `nodejs${major}.x`;
}
if (support.status === 'deprecated') {
const removeDate = new Intl.DateTimeFormat(undefined, { dateStyle: 'long' }).format(
support.removal,
);
const removeDate = new Intl.DateTimeFormat(undefined, {
dateStyle: 'long',
}).format(support.removal);
logger.warn(
`\n` +
`\tYour project is being built for Node.js ${major} as the runtime.\n` +

View File

@@ -23,7 +23,9 @@ export async function copyDependenciesToFunction(
},
// we want to pass the caching by reference, and not by value
cache: object,
): Promise<{ handler: string }> {
): Promise<{
handler: string;
}> {
const entryPath = fileURLToPath(entry);
logger.info(`Bundling function ${relativePath(fileURLToPath(outDir), entryPath)}`);

View File

@@ -25,7 +25,9 @@ const ROOT_FILES = [
function tryStatSync(file: string): fs.Stats | undefined {
try {
// The "throwIfNoEntry" is a performance optimization for cases where the file does not exist
return fs.statSync(file, { throwIfNoEntry: false });
return fs.statSync(file, {
throwIfNoEntry: false,
});
} catch {
// Ignore errors
}

View File

@@ -15,7 +15,13 @@ setGetEnv((key) => process.env[key]);
export const createExports = (
manifest: SSRManifest,
{ middlewareSecret, skewProtection }: { middlewareSecret: string; skewProtection: boolean },
{
middlewareSecret,
skewProtection,
}: {
middlewareSecret: string;
skewProtection: boolean;
},
) => {
const app = new NodeApp(manifest);
const handler = async (req: IncomingMessage, res: ServerResponse) => {
@@ -46,11 +52,17 @@ export const createExports = (
req.headers['x-deployment-id'] = process.env.VERCEL_DEPLOYMENT_ID;
}
const webResponse = await app.render(req, { addCookieHeader: true, clientAddress, locals });
const webResponse = await app.render(req, {
addCookieHeader: true,
clientAddress,
locals,
});
await NodeApp.writeResponse(webResponse, res);
};
return { default: handler };
return {
default: handler,
};
};
// HACK: prevent warning

View File

@@ -65,7 +65,15 @@ export async function generateEdgeMiddleware(
name: 'esbuild-namespace-node-built-in-modules',
setup(build) {
const filter = new RegExp(builtinModules.map((mod) => `(^${mod}$)`).join('|'));
build.onResolve({ filter }, (args) => ({ path: 'node:' + args.path, external: true }));
build.onResolve(
{
filter,
},
(args) => ({
path: 'node:' + args.path,
external: true,
}),
);
},
},
],

View File

@@ -43,14 +43,19 @@ describe('Static Assets', () => {
describe('static adapter', () => {
it('has cache control', async () => {
const { default: vercel } = await import('@astrojs/vercel');
await build({ adapter: vercel() });
await build({
adapter: vercel(),
});
await checkValidCacheControl();
});
it('has cache control other assets', async () => {
const { default: vercel } = await import('@astrojs/vercel');
const assets = '_foo';
await build({ adapter: vercel(), assets });
await build({
adapter: vercel(),
assets,
});
await checkValidCacheControl(assets);
});
});
@@ -58,14 +63,21 @@ describe('Static Assets', () => {
describe('serverless adapter', () => {
it('has cache control', async () => {
const { default: vercel } = await import('@astrojs/vercel');
await build({ output: 'server', adapter: vercel() });
await build({
output: 'server',
adapter: vercel(),
});
await checkValidCacheControl();
});
it('has cache control other assets', async () => {
const { default: vercel } = await import('@astrojs/vercel');
const assets = '_foo';
await build({ output: 'server', adapter: vercel(), assets });
await build({
output: 'server',
adapter: vercel(),
assets,
});
await checkValidCacheControl(assets);
});
});

View File

@@ -6,7 +6,9 @@ describe('Static headers', () => {
let fixture;
before(async () => {
fixture = await loadFixture({ root: './fixtures/static-headers' });
fixture = await loadFixture({
root: './fixtures/static-headers',
});
await fixture.build();
});

View File

@@ -1,5 +1,9 @@
import { waitUntil } from '@vercel/functions';
export interface EdgeLocals {
vercel: {
edge: import('@vercel/edge').RequestContext;
edge: {
waitUntil: typeof waitUntil;
};
};
}

905
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -14,4 +14,4 @@
"noUnusedLocals": true,
"noUnusedParameters": true
}
}
}

View File

@@ -1,67 +1,48 @@
{
"$schema": "https://turborepo.org/schema.json",
"tasks": {
"build": {
"dependsOn": [
"^build"
],
"inputs": [
"**/*",
"!test/**/*",
"!e2e/**/*",
"!performance/**/*",
"!.astro/**/*",
"!.cache/**/*",
"!mod.js",
"!mod.js.map"
],
"outputs": [
"dist/**/*",
"!vendor/**",
"mod.js",
"mod.js.map"
],
"outputLogs": "new-only"
},
"build:ci": {
"dependsOn": [
"^build:ci"
],
"inputs": [
"**/*",
"!test/**/*",
"!e2e/**/*",
"!performance/**/*",
"!.astro/**/*",
"!.cache/**/*",
"!mod.js",
"!mod.js.map"
],
"outputs": [
"dist/**/*",
"!vendor/**",
"mod.js",
"mod.js.map"
],
"outputLogs": "new-only"
},
"dev": {
"cache": false,
"persistent": true
},
"test": {
"dependsOn": [
"^test"
],
"env": [
"RUNNER_OS",
"NODE_VERSION"
],
"outputLogs": "new-only"
},
"test:hosted": {
"cache": false,
"outputLogs": "new-only"
}
}
"$schema": "https://turborepo.org/schema.json",
"tasks": {
"build": {
"dependsOn": ["^build"],
"inputs": [
"**/*",
"!test/**/*",
"!e2e/**/*",
"!performance/**/*",
"!.astro/**/*",
"!.cache/**/*",
"!mod.js",
"!mod.js.map"
],
"outputs": ["dist/**/*", "!vendor/**", "mod.js", "mod.js.map"],
"outputLogs": "new-only"
},
"build:ci": {
"dependsOn": ["^build:ci"],
"inputs": [
"**/*",
"!test/**/*",
"!e2e/**/*",
"!performance/**/*",
"!.astro/**/*",
"!.cache/**/*",
"!mod.js",
"!mod.js.map"
],
"outputs": ["dist/**/*", "!vendor/**", "mod.js", "mod.js.map"],
"outputLogs": "new-only"
},
"dev": {
"cache": false,
"persistent": true
},
"test": {
"dependsOn": ["^test"],
"env": ["RUNNER_OS", "NODE_VERSION"],
"outputLogs": "new-only"
},
"test:hosted": {
"cache": false,
"outputLogs": "new-only"
}
}
}