feat(todo): prepare for production deployment

- Fix type-check errors (subtask id, duplicate currentLocale)
- Add complete Astro landing page with Hero, Features, Pricing, CTA
- Add production environment templates (.env.example, .env.production.example)
- Add docker-compose.prod.yml for production deployment
- Add deploy.sh script for server deployment
- Add /health endpoint for web app health checks
- Improve docker-entrypoint.sh with database wait logic
- Remove references to deleted statistics and session-tasks stores

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Till-JS 2026-01-28 14:04:27 +01:00
parent 99fdf1d17f
commit 1dc4f58edb
24 changed files with 1511 additions and 129 deletions

25
apps/todo/.env.example Normal file
View file

@ -0,0 +1,25 @@
# Todo Production Environment Variables
# Copy this file to .env and fill in the values for docker-compose.prod.yml
# =============================================================================
# Backend Configuration
# =============================================================================
# PostgreSQL connection string
DATABASE_URL=postgresql://todo_user:CHANGE_ME@postgres:5432/todo
# Mana Core Auth URL for JWT validation
MANA_CORE_AUTH_URL=https://auth.mana.how
# Allowed CORS origins (comma-separated)
CORS_ORIGINS=https://todo.mana.how
# =============================================================================
# Web Configuration
# =============================================================================
# Backend API URL (as seen from browser)
PUBLIC_BACKEND_URL=https://todo-api.mana.how
# Auth URL (as seen from browser)
PUBLIC_MANA_CORE_AUTH_URL=https://auth.mana.how

View file

@ -0,0 +1,36 @@
# Todo Backend - Production Environment Variables
# Copy this file to .env.production and fill in the values
# =============================================================================
# REQUIRED
# =============================================================================
# Database connection string (PostgreSQL)
DATABASE_URL=postgresql://todo_user:CHANGE_ME@localhost:5432/todo
# Mana Core Auth URL for JWT validation
MANA_CORE_AUTH_URL=https://auth.mana.how
# Allowed CORS origins (comma-separated)
# Include your frontend domains here
CORS_ORIGINS=https://todo.mana.how,https://todo-landing.mana.how
# =============================================================================
# OPTIONAL
# =============================================================================
# Server port (default: 3018)
PORT=3018
# Node environment (MUST be 'production' for security)
NODE_ENV=production
# Logging level (default: info)
LOG_LEVEL=info
# =============================================================================
# SECURITY NOTES
# =============================================================================
# - NEVER set DEV_BYPASS_AUTH=true in production
# - NEVER commit this file with real credentials
# - Use Docker secrets or environment injection for sensitive values

View file

@ -1,8 +1,46 @@
#!/bin/sh
set -e
echo "Starting Todo Backend..."
echo "=========================================="
echo " Todo Backend Startup"
echo "=========================================="
echo "Environment: ${NODE_ENV:-development}"
echo "Port: ${PORT:-3018}"
# Wait for database to be ready
if [ -n "$DATABASE_URL" ]; then
echo "Waiting for database..."
# Extract host and port from DATABASE_URL
DB_HOST=$(echo $DATABASE_URL | sed -n 's/.*@\([^:]*\):.*/\1/p')
DB_PORT=$(echo $DATABASE_URL | sed -n 's/.*:\([0-9]*\)\/.*/\1/p')
# Default port if not found
DB_PORT=${DB_PORT:-5432}
# Wait for database to accept connections
max_attempts=30
attempt=1
while [ $attempt -le $max_attempts ]; do
if pg_isready -h "$DB_HOST" -p "$DB_PORT" > /dev/null 2>&1; then
echo "Database is ready!"
break
fi
echo "Waiting for database... (attempt $attempt/$max_attempts)"
sleep 2
attempt=$((attempt + 1))
done
if [ $attempt -gt $max_attempts ]; then
echo "Warning: Could not connect to database after $max_attempts attempts"
fi
fi
# Push database schema (safe for production - only adds missing tables/columns)
if [ "$RUN_DB_PUSH" = "true" ]; then
echo "Pushing database schema..."
npx drizzle-kit push --force || echo "Warning: db:push failed, continuing anyway..."
fi
echo "Starting application..."
exec "$@"

32
apps/todo/apps/landing/.gitignore vendored Normal file
View file

@ -0,0 +1,32 @@
# build output
dist/
.output/
# generated types
.astro/
# dependencies
node_modules/
# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# environment variables
.env
.env.production
.env.local
# macOS-specific files
.DS_Store
# IDE
.idea/
.vscode/
*.swp
*.swo
# Wrangler
.wrangler/

View file

@ -0,0 +1,15 @@
{
"useTabs": true,
"singleQuote": true,
"trailingComma": "none",
"printWidth": 100,
"plugins": ["prettier-plugin-astro", "prettier-plugin-tailwindcss"],
"overrides": [
{
"files": "*.astro",
"options": {
"parser": "astro"
}
}
]
}

View file

@ -0,0 +1,19 @@
import { defineConfig } from 'astro/config';
import tailwind from '@astrojs/tailwind';
// https://astro.build/config
export default defineConfig({
integrations: [tailwind()],
output: 'static',
build: {
inlineStylesheets: 'auto',
},
vite: {
resolve: {
alias: {
'@components': '/src/components',
'@layouts': '/src/layouts',
},
},
},
});

View file

@ -0,0 +1,34 @@
{
"name": "@todo/landing",
"version": "1.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "astro dev --port 4323",
"start": "astro dev",
"build": "astro check && astro build",
"preview": "astro preview",
"astro": "astro",
"type-check": "astro check",
"format": "prettier --write .",
"clean": "rm -rf dist .astro node_modules"
},
"dependencies": {
"@astrojs/check": "^0.9.0",
"@manacore/shared-landing-ui": "workspace:*",
"astro": "^5.16.0",
"typescript": "^5.9.2"
},
"devDependencies": {
"@astrojs/tailwind": "^6.0.2",
"@tailwindcss/typography": "^0.5.18",
"@types/node": "^20.0.0",
"eslint": "^9.0.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-astro": "^1.0.0",
"prettier": "^3.6.2",
"prettier-plugin-astro": "^0.14.1",
"prettier-plugin-tailwindcss": "^0.6.14",
"tailwindcss": "^3.4.0"
}
}

View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="#10b981" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4" />
</svg>

After

Width:  |  Height:  |  Size: 317 B

View file

@ -0,0 +1,60 @@
---
// Call to Action section
---
<section class="relative overflow-hidden bg-dark-bg">
<!-- Background gradient -->
<div class="absolute inset-0 bg-gradient-to-r from-primary-950/30 via-dark-bg to-primary-950/30">
</div>
<div class="container relative">
<div class="mx-auto max-w-3xl text-center">
<h2 class="mb-6 text-3xl font-bold md:text-4xl lg:text-5xl">
Bereit, produktiver zu werden?
</h2>
<p class="mb-10 text-lg text-gray-400">
Starte kostenlos und erlebe, wie einfach Task-Management sein kann. Keine Kreditkarte
erforderlich.
</p>
<div class="flex flex-col items-center justify-center gap-4 sm:flex-row">
<a href="#" class="btn btn-primary text-lg">
Jetzt kostenlos starten
<svg class="ml-2 h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M17 8l4 4m0 0l-4 4m4-4H3"></path>
</svg>
</a>
<a href="#features" class="btn btn-secondary"> Mehr erfahren </a>
</div>
<!-- Benefits list -->
<div class="mt-12 flex flex-wrap items-center justify-center gap-6 text-sm text-gray-500">
<div class="flex items-center gap-2">
<svg class="h-5 w-5 text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"
></path>
</svg>
<span>Kostenlos starten</span>
</div>
<div class="flex items-center gap-2">
<svg class="h-5 w-5 text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"
></path>
</svg>
<span>Keine Kreditkarte</span>
</div>
<div class="flex items-center gap-2">
<svg class="h-5 w-5 text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"
></path>
</svg>
<span>Jederzeit kündbar</span>
</div>
</div>
</div>
</div>
</section>

View file

@ -0,0 +1,84 @@
---
// Features section for Todo landing page
const features = [
{
icon: `<svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"></path>
</svg>`,
title: 'Projekte & Ordner',
description:
'Organisiere deine Aufgaben in farbcodierten Projekten. Behalte den Überblick über Arbeit, Privates und mehr.',
},
{
icon: `<svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01"></path>
</svg>`,
title: 'Unteraufgaben',
description:
'Teile grosse Aufgaben in handhabbare Schritte auf. Verfolge den Fortschritt mit Checklisten.',
},
{
icon: `<svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 17V7m0 10a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2h2a2 2 0 012 2m0 10a2 2 0 002 2h2a2 2 0 002-2M9 7a2 2 0 012-2h2a2 2 0 012 2m0 10V7m0 10a2 2 0 002 2h2a2 2 0 002-2V7a2 2 0 00-2-2h-2a2 2 0 00-2 2"></path>
</svg>`,
title: 'Kanban-Boards',
description:
'Visualisiere deine Workflows mit Drag-and-Drop Kanban-Boards. Perfekt für agile Arbeitsweisen.',
},
{
icon: `<svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path>
</svg>`,
title: 'Wiederkehrende Tasks',
description:
'Erstelle Tasks, die sich automatisch wiederholen - täglich, wöchentlich, monatlich oder nach deinen Regeln.',
},
{
icon: `<svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"></path>
</svg>`,
title: 'Smarte Erinnerungen',
description:
'Verpasse nie wieder eine Deadline. Push-Benachrichtigungen und E-Mail-Erinnerungen zur rechten Zeit.',
},
{
icon: `<svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z"></path>
</svg>`,
title: 'Labels & Tags',
description:
'Kategorisiere deine Aufgaben mit farbigen Labels. Filtere und finde Tasks blitzschnell.',
},
];
---
<section id="features" class="bg-dark-surface">
<div class="container">
<!-- Section header -->
<div class="mx-auto mb-16 max-w-3xl text-center">
<span class="mb-4 inline-block text-sm font-medium uppercase tracking-wider text-primary-400">
Funktionen
</span>
<h2 class="mb-6 text-3xl font-bold md:text-4xl lg:text-5xl">Alles was du brauchst</h2>
<p class="text-lg text-gray-400">
Todo bietet alle Funktionen, die du für effektives Task-Management benötigst.
</p>
</div>
<!-- Features grid -->
<div class="grid gap-8 md:grid-cols-2 lg:grid-cols-3">
{
features.map((feature) => (
<div class="group rounded-xl border border-dark-border bg-dark-card p-6 transition-all duration-300 hover:border-primary-500/50 hover:bg-dark-card/80">
<div class="mb-4 flex h-12 w-12 items-center justify-center rounded-lg bg-primary-500/10 text-primary-400 transition-colors group-hover:bg-primary-500/20">
<Fragment set:html={feature.icon} />
</div>
<h3 class="mb-3 text-xl font-semibold">{feature.title}</h3>
<p class="text-gray-400">{feature.description}</p>
</div>
))
}
</div>
</div>
</section>

View file

@ -0,0 +1,109 @@
---
// Footer component
const currentYear = new Date().getFullYear();
const links = {
product: [
{ name: 'Funktionen', href: '#features' },
{ name: 'Preise', href: '#pricing' },
{ name: 'Changelog', href: '/changelog' },
{ name: 'Roadmap', href: '/roadmap' },
],
legal: [
{ name: 'Impressum', href: '/impressum' },
{ name: 'Datenschutz', href: '/datenschutz' },
{ name: 'AGB', href: '/agb' },
],
support: [
{ name: 'FAQ', href: '/faq' },
{ name: 'Kontakt', href: '/kontakt' },
{ name: 'Status', href: '/status' },
],
};
---
<footer class="border-t border-dark-border bg-dark-bg py-12">
<div class="container">
<div class="grid gap-8 md:grid-cols-4">
<!-- Brand -->
<div class="md:col-span-1">
<div class="mb-4 flex items-center gap-2">
<svg
class="h-8 w-8 text-primary-500"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"
></path>
</svg>
<span class="text-xl font-bold">Todo</span>
</div>
<p class="text-sm text-gray-500">Smart Task Management für bessere Produktivität.</p>
</div>
<!-- Links -->
<div>
<h4 class="mb-4 font-semibold">Produkt</h4>
<ul class="space-y-2 text-sm text-gray-400">
{
links.product.map((link) => (
<li>
<a href={link.href} class="transition-colors hover:text-white">
{link.name}
</a>
</li>
))
}
</ul>
</div>
<div>
<h4 class="mb-4 font-semibold">Rechtliches</h4>
<ul class="space-y-2 text-sm text-gray-400">
{
links.legal.map((link) => (
<li>
<a href={link.href} class="transition-colors hover:text-white">
{link.name}
</a>
</li>
))
}
</ul>
</div>
<div>
<h4 class="mb-4 font-semibold">Support</h4>
<ul class="space-y-2 text-sm text-gray-400">
{
links.support.map((link) => (
<li>
<a href={link.href} class="transition-colors hover:text-white">
{link.name}
</a>
</li>
))
}
</ul>
</div>
</div>
<!-- Bottom bar -->
<div
class="mt-12 flex flex-col items-center justify-between gap-4 border-t border-dark-border pt-8 md:flex-row"
>
<p class="text-sm text-gray-500">
&copy; {currentYear} Todo. Alle Rechte vorbehalten.
</p>
<p class="text-sm text-gray-500">
Ein <a href="https://manacore.app" class="text-primary-400 hover:underline">Manacore</a> Produkt
</p>
</div>
</div>
</footer>

View file

@ -0,0 +1,146 @@
---
// Hero section for Todo landing page
---
<section class="relative overflow-hidden py-20 md:py-32">
<!-- Background gradient -->
<div class="absolute inset-0 bg-gradient-to-b from-primary-950/30 via-dark-bg to-dark-bg"></div>
<!-- Grid pattern -->
<div class="absolute inset-0 bg-[url('/grid.svg')] bg-center opacity-10"></div>
<div class="container relative">
<div class="mx-auto max-w-4xl text-center">
<!-- Badge -->
<div
class="mb-8 inline-flex items-center gap-2 rounded-full border border-primary-500/30 bg-primary-500/10 px-4 py-2 text-sm text-primary-400"
>
<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"
></path>
</svg>
<span>Smart Task-Management</span>
</div>
<!-- Headline -->
<h1 class="mb-6 text-4xl font-bold leading-tight md:text-6xl lg:text-7xl">
Erledige mehr mit
<span class="gradient-text">weniger Stress</span>
</h1>
<!-- Subheadline -->
<p class="mx-auto mb-10 max-w-2xl text-lg text-gray-400 md:text-xl">
Projekte, Unteraufgaben, Kanban-Boards, wiederkehrende Tasks und smarte Erinnerungen - alles
an einem Ort. Behalte den Überblick über alles, was wichtig ist.
</p>
<!-- CTA Buttons -->
<div class="flex flex-col items-center justify-center gap-4 sm:flex-row">
<a href="#" class="btn btn-primary group text-lg">
Kostenlos starten
<svg
class="ml-2 h-5 w-5 transition-transform group-hover:translate-x-1"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M17 8l4 4m0 0l-4 4m4-4H3"></path>
</svg>
</a>
<a href="#features" class="btn btn-secondary"> Funktionen entdecken </a>
</div>
<!-- Social proof -->
<div class="mt-16 flex flex-col items-center gap-4">
<div class="flex -space-x-2">
{
[1, 2, 3, 4, 5].map((i) => (
<div class="h-10 w-10 rounded-full border-2 border-dark-bg bg-gradient-to-br from-primary-400 to-primary-600" />
))
}
</div>
<p class="text-sm text-gray-500">
<span class="font-semibold text-white">500+</span> Nutzer vertrauen Todo
</p>
</div>
</div>
<!-- Preview mockup -->
<div class="relative mx-auto mt-16 max-w-5xl">
<div
class="absolute -inset-4 rounded-2xl bg-gradient-to-r from-primary-500/20 via-transparent to-primary-500/20 blur-3xl"
>
</div>
<div class="relative rounded-xl border border-dark-border bg-dark-card p-2 shadow-2xl">
<div class="flex gap-2 px-4 py-3">
<div class="h-3 w-3 rounded-full bg-red-500"></div>
<div class="h-3 w-3 rounded-full bg-yellow-500"></div>
<div class="h-3 w-3 rounded-full bg-green-500"></div>
</div>
<div class="aspect-[16/9] overflow-hidden rounded-lg bg-dark-surface">
<!-- Task list preview -->
<div class="p-6">
<div class="mb-4 flex items-center justify-between">
<h3 class="text-xl font-semibold">Heute</h3>
<div class="flex gap-2">
<button class="rounded-lg bg-primary-500 px-3 py-1 text-sm">+ Aufgabe</button>
</div>
</div>
<div class="space-y-3">
{
[
{ title: 'Meeting mit Team vorbereiten', priority: 'high', done: true },
{ title: 'E-Mails beantworten', priority: 'medium', done: false },
{ title: 'Projekt-Dokumentation aktualisieren', priority: 'low', done: false },
{ title: 'Code-Review durchführen', priority: 'high', done: false },
{ title: 'Sprint Planning vorbereiten', priority: 'medium', done: false },
].map((task) => (
<div class="flex items-center gap-3 rounded-lg bg-dark-card p-3">
<div
class={`h-5 w-5 rounded-full border-2 flex items-center justify-center ${
task.done
? 'border-primary-500 bg-primary-500'
: task.priority === 'high'
? 'border-red-500'
: task.priority === 'medium'
? 'border-yellow-500'
: 'border-gray-500'
}`}
>
{task.done && (
<svg
class="h-3 w-3 text-white"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="3"
d="M5 13l4 4L19 7"
/>
</svg>
)}
</div>
<span class={task.done ? 'text-gray-500 line-through' : 'text-white'}>
{task.title}
</span>
</div>
))
}
</div>
</div>
</div>
</div>
</div>
</div>
</section>

View file

@ -0,0 +1,48 @@
---
import '../styles/global.css';
interface Props {
title?: string;
description?: string;
}
const {
title = 'Todo - Smart Task Management',
description = 'Organisiere deine Aufgaben intelligent. Projekte, Unteraufgaben, wiederkehrende Tasks, Kanban-Boards und mehr. Kostenlos starten.',
} = Astro.props;
---
<!doctype html>
<html lang="de" class="scroll-smooth">
<head>
<meta charset="UTF-8" />
<meta name="description" content={description} />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="generator" content={Astro.generator} />
<!-- SEO Meta Tags -->
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:type" content="website" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content={title} />
<meta name="twitter:description" content={description} />
<!-- Preconnect to Google Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
rel="stylesheet"
/>
<!-- Umami Analytics -->
<script defer src="https://stats.mana.how/script.js" data-website-id="todo-landing"></script>
<title>{title}</title>
</head>
<body class="antialiased">
<slot />
</body>
</html>

View file

@ -0,0 +1,253 @@
---
import Layout from '@layouts/Layout.astro';
import Hero from '@components/Hero.astro';
import Features from '@components/Features.astro';
import CTA from '@components/CTA.astro';
import Footer from '@components/Footer.astro';
// Try to import shared components if available
let StepsSection: any = null;
let PricingSection: any = null;
try {
const shared = await import('@manacore/shared-landing-ui/sections/StepsSection.astro');
StepsSection = shared.default;
} catch {
// Shared component not available
}
try {
const shared = await import('@manacore/shared-landing-ui/sections/PricingSection.astro');
PricingSection = shared.default;
} catch {
// Shared component not available
}
// Steps data
const steps = [
{
number: '1',
title: 'Aufgabe erfassen',
description:
'Erstelle Aufgaben mit natürlicher Sprache. Füge Fälligkeiten, Prioritäten und Tags hinzu - alles in einem Schritt.',
image: '/screenshots/quick-add.png',
},
{
number: '2',
title: 'Organisieren',
description:
'Ordne Aufgaben in Projekte ein, füge Unteraufgaben hinzu und nutze das Kanban-Board für visuelle Workflows.',
image: '/screenshots/organize.png',
},
{
number: '3',
title: 'Erledigen',
description:
'Arbeite deine Tasks ab, verfolge deinen Fortschritt in Statistiken und feiere deine Erfolge.',
image: '/screenshots/complete.png',
},
];
// Pricing data
const pricingPlans = [
{
name: 'Free',
price: '0',
period: '/Monat',
description: 'Perfekt für Einzelpersonen',
features: [
{ text: '3 Projekte', included: true },
{ text: 'Unbegrenzte Aufgaben', included: true },
{ text: 'Labels & Tags', included: true },
{ text: 'Web-App Zugang', included: true },
{ text: 'Kanban-Boards', included: false },
{ text: 'Wiederkehrende Tasks', included: false },
],
cta: {
text: 'Kostenlos starten',
href: '#',
},
},
{
name: 'Pro',
price: '4,99',
period: '/Monat',
description: 'Für Power-User',
features: [
{ text: 'Unbegrenzte Projekte', included: true },
{ text: 'Unbegrenzte Aufgaben', included: true },
{ text: 'Kanban-Boards', included: true },
{ text: 'Wiederkehrende Tasks', included: true },
{ text: 'Statistiken & Heatmaps', included: true },
{ text: 'Priority Support', included: true },
],
cta: {
text: 'Pro starten',
href: '#',
},
highlighted: true,
badge: 'Beliebt',
},
{
name: 'Team',
price: '9,99',
period: '/Monat',
description: 'Für Teams & Unternehmen',
features: [
{ text: 'Alles aus Pro', included: true },
{ text: 'Team-Verwaltung', included: true },
{ text: 'Geteilte Projekte', included: true },
{ text: 'API-Zugang', included: true },
{ text: 'Admin-Dashboard', included: true },
{ text: 'SLA Garantie', included: true },
],
cta: {
text: 'Team erstellen',
href: '#',
},
},
];
---
<Layout
title="Todo - Smart Task Management"
description="Organisiere deine Aufgaben intelligent. Projekte, Unteraufgaben, Kanban-Boards, wiederkehrende Tasks und smarte Erinnerungen. Kostenlos starten."
>
<Hero />
<Features />
{
StepsSection && (
<StepsSection
id="how-it-works"
title="So einfach geht's"
subtitle="In drei Schritten zur Produktivität"
steps={steps}
showImages={false}
alternateLayout={true}
class="bg-dark-surface"
/>
)
}
{
!StepsSection && (
<section id="how-it-works" class="bg-dark-surface">
<div class="container">
<div class="mx-auto mb-16 max-w-3xl text-center">
<span class="mb-4 inline-block text-sm font-medium uppercase tracking-wider text-primary-400">
So funktioniert's
</span>
<h2 class="mb-6 text-3xl font-bold md:text-4xl">So einfach geht's</h2>
<p class="text-lg text-gray-400">In drei Schritten zur Produktivität</p>
</div>
<div class="grid gap-8 md:grid-cols-3">
{steps.map((step) => (
<div class="text-center">
<div class="mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-primary-500/20 text-2xl font-bold text-primary-400">
{step.number}
</div>
<h3 class="mb-3 text-xl font-semibold">{step.title}</h3>
<p class="text-gray-400">{step.description}</p>
</div>
))}
</div>
</div>
</section>
)
}
{
PricingSection && (
<PricingSection
id="pricing"
title="Einfache, transparente Preise"
subtitle="Starte kostenlos, upgrade wenn du mehr brauchst"
plans={pricingPlans}
class="bg-dark-bg"
/>
)
}
{
!PricingSection && (
<section id="pricing" class="bg-dark-bg">
<div class="container">
<div class="mx-auto mb-16 max-w-3xl text-center">
<span class="mb-4 inline-block text-sm font-medium uppercase tracking-wider text-primary-400">
Preise
</span>
<h2 class="mb-6 text-3xl font-bold md:text-4xl">Einfache, transparente Preise</h2>
<p class="text-lg text-gray-400">Starte kostenlos, upgrade wenn du mehr brauchst</p>
</div>
<div class="mx-auto grid max-w-5xl gap-8 md:grid-cols-3">
{pricingPlans.map((plan) => (
<div
class={`relative rounded-xl border p-6 ${plan.highlighted ? 'border-primary-500 bg-primary-500/10' : 'border-dark-border bg-dark-card'}`}
>
{plan.badge && (
<div class="absolute -top-3 left-1/2 -translate-x-1/2 rounded-full bg-primary-500 px-3 py-1 text-xs font-medium text-white">
{plan.badge}
</div>
)}
<h3 class="mb-2 text-xl font-semibold">{plan.name}</h3>
<p class="mb-4 text-sm text-gray-400">{plan.description}</p>
<div class="mb-6">
<span class="text-4xl font-bold">{plan.price}&euro;</span>
<span class="text-gray-500">{plan.period}</span>
</div>
<ul class="mb-8 space-y-3">
{plan.features.map((feature) => (
<li
class={`flex items-center gap-2 text-sm ${feature.included ? 'text-white' : 'text-gray-600'}`}
>
{feature.included ? (
<svg
class="h-5 w-5 text-green-500"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M5 13l4 4L19 7"
/>
</svg>
) : (
<svg
class="h-5 w-5 text-gray-600"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M6 18L18 6M6 6l12 12"
/>
</svg>
)}
{feature.text}
</li>
))}
</ul>
<a
href={plan.cta.href}
class={`btn w-full ${plan.highlighted ? 'btn-primary' : 'btn-secondary'}`}
>
{plan.cta.text}
</a>
</div>
))}
</div>
</div>
</section>
)
}
<CTA />
<Footer />
</Layout>

View file

@ -0,0 +1,78 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
:root {
--color-background-page: #0a0a0a;
--color-background-card: #1a1a1a;
--color-background-card-hover: #242424;
--color-text-primary: #ffffff;
--color-text-secondary: #d1d5db;
--color-text-muted: #9ca3af;
--color-border: #262626;
--color-border-hover: #3f3f3f;
--color-primary: #10b981;
--color-primary-hover: #059669;
}
* {
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
@apply bg-dark-bg text-white;
margin: 0;
padding: 0;
overflow-x: hidden;
font-family: 'Inter', system-ui, -apple-system, sans-serif;
}
/* Custom scrollbar */
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
@apply bg-dark-bg;
}
::-webkit-scrollbar-thumb {
@apply bg-dark-border rounded-full;
}
::-webkit-scrollbar-thumb:hover {
@apply bg-gray-600;
}
/* Section padding */
section {
@apply py-16 md:py-24;
}
/* Container */
.container {
@apply mx-auto max-w-7xl px-4 sm:px-6 lg:px-8;
}
/* Gradient text */
.gradient-text {
@apply bg-gradient-to-r from-primary-400 to-primary-600 bg-clip-text text-transparent;
}
/* Button styles */
.btn {
@apply inline-flex items-center justify-center rounded-lg px-6 py-3 font-medium transition-all duration-200;
}
.btn-primary {
@apply bg-primary-500 text-white hover:bg-primary-600;
}
.btn-secondary {
@apply border border-dark-border bg-dark-card text-white hover:bg-dark-surface;
}

View file

@ -0,0 +1,53 @@
/** @type {import('tailwindcss').Config} */
export default {
content: [
'./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}',
'../../packages/shared-landing-ui/src/**/*.{astro,html,js,jsx,ts,tsx}',
],
theme: {
extend: {
colors: {
// Todo app theme - green/teal
primary: {
DEFAULT: '#10b981',
50: '#ecfdf5',
100: '#d1fae5',
200: '#a7f3d0',
300: '#6ee7b7',
400: '#34d399',
500: '#10b981',
600: '#059669',
700: '#047857',
800: '#065f46',
900: '#064e3b',
950: '#022c22',
},
dark: {
bg: '#0a0a0a',
surface: '#111111',
card: '#1a1a1a',
border: '#262626',
},
// CSS variable mappings for shared-landing-ui compatibility
background: {
page: 'var(--color-background-page, #0a0a0a)',
card: 'var(--color-background-card, #1a1a1a)',
'card-hover': 'var(--color-background-card-hover, #242424)',
},
text: {
primary: 'var(--color-text-primary, #ffffff)',
secondary: 'var(--color-text-secondary, #d1d5db)',
muted: 'var(--color-text-muted, #9ca3af)',
},
border: {
DEFAULT: 'var(--color-border, #262626)',
hover: 'var(--color-border-hover, #3f3f3f)',
},
},
fontFamily: {
sans: ['Inter', 'system-ui', '-apple-system', 'sans-serif'],
},
},
},
plugins: [require('@tailwindcss/typography')],
};

View file

@ -0,0 +1,10 @@
{
"extends": "astro/tsconfigs/strict",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@components/*": ["src/components/*"],
"@layouts/*": ["src/layouts/*"]
}
}
}

View file

@ -0,0 +1,3 @@
name = "todo-landing"
compatibility_date = "2024-12-01"
pages_build_output_dir = "dist"

View file

@ -0,0 +1,19 @@
# Todo Web App - Production Environment Variables
# Copy this file to .env.production and fill in the values
# =============================================================================
# REQUIRED
# =============================================================================
# Backend API URL
PUBLIC_BACKEND_URL=https://todo-api.mana.how
# Mana Core Auth URL for authentication
PUBLIC_MANA_CORE_AUTH_URL=https://auth.mana.how
# =============================================================================
# OPTIONAL
# =============================================================================
# Analytics (if using Umami or similar)
# PUBLIC_ANALYTICS_ID=your-analytics-id

View file

@ -11,7 +11,7 @@
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "eslint .",
"format": "prettier --write .",
"type-check": "echo 'Skipping type-check for now'"
"type-check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json"
},
"devDependencies": {
"@sveltejs/adapter-node": "^5.0.0",

View file

@ -4,7 +4,7 @@ import type { RequestHandler } from './$types';
export const GET: RequestHandler = async () => {
return json({
status: 'ok',
service: 'todo-web',
timestamp: new Date().toISOString(),
service: 'todo-web',
});
};

View file

@ -0,0 +1,66 @@
version: '3.8'
services:
# Todo Backend API
todo-backend:
build:
context: ../..
dockerfile: apps/todo/apps/backend/Dockerfile
container_name: todo-backend
restart: unless-stopped
ports:
- "3018:3018"
environment:
- NODE_ENV=production
- PORT=3018
- DATABASE_URL=${DATABASE_URL}
- MANA_CORE_AUTH_URL=${MANA_CORE_AUTH_URL}
- CORS_ORIGINS=${CORS_ORIGINS}
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3018/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
networks:
- todo-network
labels:
- "traefik.enable=true"
- "traefik.http.routers.todo-api.rule=Host(`todo-api.mana.how`)"
- "traefik.http.routers.todo-api.tls=true"
- "traefik.http.routers.todo-api.tls.certresolver=letsencrypt"
- "traefik.http.services.todo-api.loadbalancer.server.port=3018"
# Todo Web App (SvelteKit with Node adapter)
todo-web:
build:
context: ../..
dockerfile: apps/todo/apps/web/Dockerfile
container_name: todo-web
restart: unless-stopped
ports:
- "5188:5188"
environment:
- NODE_ENV=production
- PORT=5188
- PUBLIC_BACKEND_URL=${PUBLIC_BACKEND_URL}
- PUBLIC_MANA_CORE_AUTH_URL=${PUBLIC_MANA_CORE_AUTH_URL}
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:5188"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
networks:
- todo-network
labels:
- "traefik.enable=true"
- "traefik.http.routers.todo-web.rule=Host(`todo.mana.how`)"
- "traefik.http.routers.todo-web.tls=true"
- "traefik.http.routers.todo-web.tls.certresolver=letsencrypt"
- "traefik.http.services.todo-web.loadbalancer.server.port=5188"
networks:
todo-network:
external: true
name: manacore-network

93
apps/todo/scripts/deploy.sh Executable file
View file

@ -0,0 +1,93 @@
#!/bin/bash
# Todo Deployment Script
# Usage: ./scripts/deploy.sh [--build]
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
MONOREPO_ROOT="$(dirname "$(dirname "$PROJECT_DIR")")"
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN} Todo App Deployment${NC}"
echo -e "${GREEN}========================================${NC}"
# Check for .env file
if [ ! -f "$PROJECT_DIR/.env" ]; then
echo -e "${RED}Error: .env file not found!${NC}"
echo -e "${YELLOW}Copy .env.example to .env and configure it:${NC}"
echo " cp $PROJECT_DIR/.env.example $PROJECT_DIR/.env"
exit 1
fi
# Change to project directory
cd "$PROJECT_DIR"
# Build if requested
if [ "$1" == "--build" ]; then
echo -e "\n${YELLOW}Building Docker images...${NC}"
docker compose -f docker-compose.prod.yml build
fi
# Pull latest images (if not building)
if [ "$1" != "--build" ]; then
echo -e "\n${YELLOW}Pulling latest images...${NC}"
docker compose -f docker-compose.prod.yml pull 2>/dev/null || true
fi
# Stop existing containers
echo -e "\n${YELLOW}Stopping existing containers...${NC}"
docker compose -f docker-compose.prod.yml down --remove-orphans
# Start containers
echo -e "\n${YELLOW}Starting containers...${NC}"
docker compose -f docker-compose.prod.yml up -d
# Wait for health checks
echo -e "\n${YELLOW}Waiting for services to be healthy...${NC}"
sleep 10
# Check health
echo -e "\n${YELLOW}Checking service health...${NC}"
check_health() {
local service=$1
local url=$2
local max_attempts=30
local attempt=1
while [ $attempt -le $max_attempts ]; do
if curl -sf "$url" > /dev/null 2>&1; then
echo -e " ${GREEN}$service: healthy${NC}"
return 0
fi
sleep 2
attempt=$((attempt + 1))
done
echo -e " ${RED}$service: unhealthy${NC}"
return 1
}
check_health "Backend" "http://localhost:3018/health"
check_health "Web" "http://localhost:5188"
# Show container status
echo -e "\n${YELLOW}Container status:${NC}"
docker compose -f docker-compose.prod.yml ps
echo -e "\n${GREEN}========================================${NC}"
echo -e "${GREEN} Deployment complete!${NC}"
echo -e "${GREEN}========================================${NC}"
echo ""
echo " Backend API: http://localhost:3018"
echo " Web App: http://localhost:5188"
echo ""
echo "View logs with:"
echo " docker compose -f docker-compose.prod.yml logs -f"

410
pnpm-lock.yaml generated
View file

@ -203,14 +203,14 @@ importers:
version: link:../../../../packages/shared-landing-ui
astro:
specifier: ^5.16.0
version: 5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1)
version: 5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.8.2)(jiti@1.21.7)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1)
typescript:
specifier: ^5.9.2
version: 5.9.3
devDependencies:
'@astrojs/tailwind':
specifier: ^6.0.2
version: 6.0.2(astro@5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1))(tailwindcss@3.4.18(tsx@4.20.6)(yaml@2.8.1))(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.9.3))
version: 6.0.2(astro@5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.8.2)(jiti@1.21.7)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1))(tailwindcss@3.4.18(tsx@4.20.6)(yaml@2.8.1))(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.9.3))
'@tailwindcss/typography':
specifier: ^0.5.18
version: 0.5.19(tailwindcss@3.4.18(tsx@4.20.6)(yaml@2.8.1))
@ -219,13 +219,13 @@ importers:
version: 20.19.25
eslint:
specifier: ^9.0.0
version: 9.39.1(jiti@2.6.1)
version: 9.39.1(jiti@1.21.7)
eslint-config-prettier:
specifier: ^9.1.0
version: 9.1.2(eslint@9.39.1(jiti@2.6.1))
version: 9.1.2(eslint@9.39.1(jiti@1.21.7))
eslint-plugin-astro:
specifier: ^1.0.0
version: 1.5.0(eslint@9.39.1(jiti@2.6.1))
version: 1.5.0(eslint@9.39.1(jiti@1.21.7))
prettier:
specifier: ^3.6.2
version: 3.6.2
@ -585,19 +585,19 @@ importers:
version: 18.3.27
'@typescript-eslint/eslint-plugin':
specifier: ^7.7.0
version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3))(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)
version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)
'@typescript-eslint/parser':
specifier: ^7.7.0
version: 7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)
version: 7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)
dotenv:
specifier: ^16.4.7
version: 16.6.1
eslint:
specifier: ^9.39.1
version: 9.39.1(jiti@1.21.7)
version: 9.39.1(jiti@2.6.1)
eslint-config-universe:
specifier: ^12.0.1
version: 12.1.0(@types/eslint@9.6.1)(eslint@9.39.1(jiti@1.21.7))(prettier@3.6.2)(typescript@5.3.3)
version: 12.1.0(@types/eslint@9.6.1)(eslint@9.39.1(jiti@2.6.1))(prettier@3.6.2)(typescript@5.3.3)
prettier:
specifier: ^3.2.5
version: 3.6.2
@ -3620,6 +3620,52 @@ importers:
specifier: ^5.9.3
version: 5.9.3
apps/todo/apps/landing:
dependencies:
'@astrojs/check':
specifier: ^0.9.0
version: 0.9.5(prettier-plugin-astro@0.14.1)(prettier@3.6.2)(typescript@5.9.3)
'@manacore/shared-landing-ui':
specifier: workspace:*
version: link:../../../../packages/shared-landing-ui
astro:
specifier: ^5.16.0
version: 5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1)
typescript:
specifier: ^5.9.2
version: 5.9.3
devDependencies:
'@astrojs/tailwind':
specifier: ^6.0.2
version: 6.0.2(astro@5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1))(tailwindcss@3.4.18(tsx@4.20.6)(yaml@2.8.1))(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.9.3))
'@tailwindcss/typography':
specifier: ^0.5.18
version: 0.5.19(tailwindcss@3.4.18(tsx@4.20.6)(yaml@2.8.1))
'@types/node':
specifier: ^20.0.0
version: 20.19.25
eslint:
specifier: ^9.0.0
version: 9.39.1(jiti@2.6.1)
eslint-config-prettier:
specifier: ^9.1.0
version: 9.1.2(eslint@9.39.1(jiti@2.6.1))
eslint-plugin-astro:
specifier: ^1.0.0
version: 1.5.0(eslint@9.39.1(jiti@2.6.1))
prettier:
specifier: ^3.6.2
version: 3.6.2
prettier-plugin-astro:
specifier: ^0.14.1
version: 0.14.1
prettier-plugin-tailwindcss:
specifier: ^0.6.14
version: 0.6.14(prettier-plugin-astro@0.14.1)(prettier-plugin-svelte@3.4.0(prettier@3.6.2)(svelte@5.44.0))(prettier@3.6.2)
tailwindcss:
specifier: ^3.4.0
version: 3.4.18(tsx@4.20.6)(yaml@2.8.1)
apps/todo/apps/web:
dependencies:
'@manacore/shared-auth':
@ -4676,9 +4722,6 @@ importers:
'@types/node':
specifier: ^22.10.5
version: 22.19.1
rimraf:
specifier: ^6.0.1
version: 6.1.2
typescript:
specifier: ^5.7.3
version: 5.9.3
@ -7418,7 +7461,7 @@ packages:
'@expo/bunyan@4.0.1':
resolution: {integrity: sha512-+Lla7nYSiHZirgK+U/uYzsLv/X+HaJienbD5AKX1UQZHYfWaP+9uuQluRB4GrEVWF0GZ7vEVp/jzaOT9k/SQlg==}
engines: {node: '>=0.10.0'}
engines: {'0': node >=0.10.0}
'@expo/cli@0.22.26':
resolution: {integrity: sha512-I689wc8Fn/AX7aUGiwrh3HnssiORMJtR2fpksX+JIe8Cj/EDleblYMSwRPd0025wrwOV9UN1KM/RuEt/QjCS3Q==}
@ -21093,6 +21136,16 @@ snapshots:
transitivePeerDependencies:
- ts-node
'@astrojs/tailwind@6.0.2(astro@5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.8.2)(jiti@1.21.7)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1))(tailwindcss@3.4.18(tsx@4.20.6)(yaml@2.8.1))(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.9.3))':
dependencies:
astro: 5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.8.2)(jiti@1.21.7)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1)
autoprefixer: 10.4.22(postcss@8.5.6)
postcss: 8.5.6
postcss-load-config: 4.0.2(postcss@8.5.6)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.9.3))
tailwindcss: 3.4.18(tsx@4.20.6)(yaml@2.8.1)
transitivePeerDependencies:
- ts-node
'@astrojs/tailwind@6.0.2(astro@5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1))(tailwindcss@3.4.18(tsx@4.20.6)(yaml@2.8.1))(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.9.3))':
dependencies:
astro: 5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1)
@ -29903,16 +29956,16 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3))(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)':
'@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)':
dependencies:
'@eslint-community/regexpp': 4.12.2
'@typescript-eslint/parser': 6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)
'@typescript-eslint/parser': 6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)
'@typescript-eslint/scope-manager': 6.21.0
'@typescript-eslint/type-utils': 6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)
'@typescript-eslint/utils': 6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)
'@typescript-eslint/type-utils': 6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)
'@typescript-eslint/utils': 6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)
'@typescript-eslint/visitor-keys': 6.21.0
debug: 4.4.3
eslint: 9.39.1(jiti@1.21.7)
eslint: 9.39.1(jiti@2.6.1)
graphemer: 1.4.0
ignore: 5.3.2
natural-compare: 1.4.0
@ -29961,15 +30014,15 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3))(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)':
'@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)':
dependencies:
'@eslint-community/regexpp': 4.12.2
'@typescript-eslint/parser': 7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)
'@typescript-eslint/parser': 7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)
'@typescript-eslint/scope-manager': 7.18.0
'@typescript-eslint/type-utils': 7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)
'@typescript-eslint/utils': 7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)
'@typescript-eslint/type-utils': 7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)
'@typescript-eslint/utils': 7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)
'@typescript-eslint/visitor-keys': 7.18.0
eslint: 9.39.1(jiti@1.21.7)
eslint: 9.39.1(jiti@2.6.1)
graphemer: 1.4.0
ignore: 5.3.2
natural-compare: 1.4.0
@ -30061,14 +30114,14 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)':
'@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)':
dependencies:
'@typescript-eslint/scope-manager': 6.21.0
'@typescript-eslint/types': 6.21.0
'@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3)
'@typescript-eslint/visitor-keys': 6.21.0
debug: 4.4.3
eslint: 9.39.1(jiti@1.21.7)
eslint: 9.39.1(jiti@2.6.1)
optionalDependencies:
typescript: 5.3.3
transitivePeerDependencies:
@ -30100,14 +30153,14 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/parser@7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)':
'@typescript-eslint/parser@7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)':
dependencies:
'@typescript-eslint/scope-manager': 7.18.0
'@typescript-eslint/types': 7.18.0
'@typescript-eslint/typescript-estree': 7.18.0(typescript@5.3.3)
'@typescript-eslint/visitor-keys': 7.18.0
debug: 4.4.3
eslint: 9.39.1(jiti@1.21.7)
eslint: 9.39.1(jiti@2.6.1)
optionalDependencies:
typescript: 5.3.3
transitivePeerDependencies:
@ -30233,12 +30286,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/type-utils@6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)':
'@typescript-eslint/type-utils@6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)':
dependencies:
'@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3)
'@typescript-eslint/utils': 6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)
'@typescript-eslint/utils': 6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)
debug: 4.4.3
eslint: 9.39.1(jiti@1.21.7)
eslint: 9.39.1(jiti@2.6.1)
ts-api-utils: 1.4.3(typescript@5.3.3)
optionalDependencies:
typescript: 5.3.3
@ -30269,12 +30322,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/type-utils@7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)':
'@typescript-eslint/type-utils@7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)':
dependencies:
'@typescript-eslint/typescript-estree': 7.18.0(typescript@5.3.3)
'@typescript-eslint/utils': 7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)
'@typescript-eslint/utils': 7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)
debug: 4.4.3
eslint: 9.39.1(jiti@1.21.7)
eslint: 9.39.1(jiti@2.6.1)
ts-api-utils: 1.4.3(typescript@5.3.3)
optionalDependencies:
typescript: 5.3.3
@ -30456,15 +30509,15 @@ snapshots:
- supports-color
- typescript
'@typescript-eslint/utils@6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)':
'@typescript-eslint/utils@6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)':
dependencies:
'@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@1.21.7))
'@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@2.6.1))
'@types/json-schema': 7.0.15
'@types/semver': 7.7.1
'@typescript-eslint/scope-manager': 6.21.0
'@typescript-eslint/types': 6.21.0
'@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3)
eslint: 9.39.1(jiti@1.21.7)
eslint: 9.39.1(jiti@2.6.1)
semver: 7.7.3
transitivePeerDependencies:
- supports-color
@ -30495,13 +30548,13 @@ snapshots:
- supports-color
- typescript
'@typescript-eslint/utils@7.18.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)':
'@typescript-eslint/utils@7.18.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)':
dependencies:
'@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@1.21.7))
'@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@2.6.1))
'@typescript-eslint/scope-manager': 7.18.0
'@typescript-eslint/types': 7.18.0
'@typescript-eslint/typescript-estree': 7.18.0(typescript@5.3.3)
eslint: 9.39.1(jiti@1.21.7)
eslint: 9.39.1(jiti@2.6.1)
transitivePeerDependencies:
- supports-color
- typescript
@ -31307,6 +31360,108 @@ snapshots:
transitivePeerDependencies:
- supports-color
astro@5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.8.2)(jiti@1.21.7)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1):
dependencies:
'@astrojs/compiler': 2.13.0
'@astrojs/internal-helpers': 0.7.5
'@astrojs/markdown-remark': 6.3.9
'@astrojs/telemetry': 3.3.0
'@capsizecss/unpack': 3.0.1
'@oslojs/encoding': 1.1.0
'@rollup/pluginutils': 5.3.0(rollup@4.53.3)
acorn: 8.15.0
aria-query: 5.3.2
axobject-query: 4.1.0
boxen: 8.0.1
ci-info: 4.3.1
clsx: 2.1.1
common-ancestor-path: 1.0.1
cookie: 1.1.0
cssesc: 3.0.0
debug: 4.4.3
deterministic-object-hash: 2.0.2
devalue: 5.5.0
diff: 5.2.0
dlv: 1.1.3
dset: 3.1.4
es-module-lexer: 1.7.0
esbuild: 0.25.12
estree-walker: 3.0.3
flattie: 1.1.1
fontace: 0.3.1
github-slugger: 2.0.0
html-escaper: 3.0.3
http-cache-semantics: 4.2.0
import-meta-resolve: 4.2.0
js-yaml: 4.1.1
magic-string: 0.30.21
magicast: 0.5.1
mrmime: 2.0.1
neotraverse: 0.6.18
p-limit: 6.2.0
p-queue: 8.1.1
package-manager-detector: 1.5.0
piccolore: 0.1.3
picomatch: 4.0.3
prompts: 2.4.2
rehype: 13.0.2
semver: 7.7.3
shiki: 3.15.0
smol-toml: 1.5.2
svgo: 4.0.0
tinyexec: 1.0.2
tinyglobby: 0.2.15
tsconfck: 3.1.6(typescript@5.9.3)
ultrahtml: 1.6.0
unifont: 0.6.0
unist-util-visit: 5.0.0
unstorage: 1.17.3(@netlify/blobs@10.4.1)(ioredis@5.8.2)
vfile: 6.0.3
vite: 6.4.1(@types/node@20.19.25)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1)
vitefu: 1.1.1(vite@6.4.1(@types/node@20.19.25)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1))
xxhash-wasm: 1.1.0
yargs-parser: 21.1.1
yocto-spinner: 0.2.3
zod: 3.25.76
zod-to-json-schema: 3.25.0(zod@3.25.76)
zod-to-ts: 1.2.0(typescript@5.9.3)(zod@3.25.76)
optionalDependencies:
sharp: 0.34.5
transitivePeerDependencies:
- '@azure/app-configuration'
- '@azure/cosmos'
- '@azure/data-tables'
- '@azure/identity'
- '@azure/keyvault-secrets'
- '@azure/storage-blob'
- '@capacitor/preferences'
- '@deno/kv'
- '@netlify/blobs'
- '@planetscale/database'
- '@types/node'
- '@upstash/redis'
- '@vercel/blob'
- '@vercel/functions'
- '@vercel/kv'
- aws4fetch
- db0
- idb-keyval
- ioredis
- jiti
- less
- lightningcss
- rollup
- sass
- sass-embedded
- stylus
- sugarss
- supports-color
- terser
- tsx
- typescript
- uploadthing
- yaml
astro@5.16.0(@netlify/blobs@10.4.1)(@types/node@20.19.25)(ioredis@5.8.2)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(terser@5.44.1)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1):
dependencies:
'@astrojs/compiler': 2.13.0
@ -33636,6 +33791,11 @@ snapshots:
escape-string-regexp@5.0.0: {}
eslint-compat-utils@0.6.5(eslint@9.39.1(jiti@1.21.7)):
dependencies:
eslint: 9.39.1(jiti@1.21.7)
semver: 7.7.3
eslint-compat-utils@0.6.5(eslint@9.39.1(jiti@2.6.1)):
dependencies:
eslint: 9.39.1(jiti@2.6.1)
@ -33646,9 +33806,9 @@ snapshots:
'@typescript-eslint/eslint-plugin': 8.48.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/parser': 8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)
eslint: 9.39.1(jiti@2.6.1)
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.1(jiti@2.6.1))
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))
eslint-plugin-expo: 1.0.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1))
eslint-plugin-react: 7.37.5(eslint@9.39.1(jiti@2.6.1))
eslint-plugin-react-hooks: 5.2.0(eslint@9.39.1(jiti@2.6.1))
globals: 16.5.0
@ -33663,9 +33823,9 @@ snapshots:
'@typescript-eslint/eslint-plugin': 8.48.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3)
'@typescript-eslint/parser': 8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3)
eslint: 9.39.1(jiti@2.6.1)
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.1(jiti@2.6.1))
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))
eslint-plugin-expo: 0.1.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3)
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint@9.39.1(jiti@2.6.1))
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1))
eslint-plugin-react: 7.37.5(eslint@9.39.1(jiti@2.6.1))
eslint-plugin-react-hooks: 5.2.0(eslint@9.39.1(jiti@2.6.1))
globals: 16.5.0
@ -33683,14 +33843,14 @@ snapshots:
dependencies:
eslint: 8.57.1
eslint-config-prettier@8.10.2(eslint@9.39.1(jiti@1.21.7)):
dependencies:
eslint: 9.39.1(jiti@1.21.7)
eslint-config-prettier@8.10.2(eslint@9.39.1(jiti@2.6.1)):
dependencies:
eslint: 9.39.1(jiti@2.6.1)
eslint-config-prettier@9.1.2(eslint@9.39.1(jiti@1.21.7)):
dependencies:
eslint: 9.39.1(jiti@1.21.7)
eslint-config-prettier@9.1.2(eslint@9.39.1(jiti@2.6.1)):
dependencies:
eslint: 9.39.1(jiti@2.6.1)
@ -33715,17 +33875,17 @@ snapshots:
- supports-color
- typescript
eslint-config-universe@12.1.0(@types/eslint@9.6.1)(eslint@9.39.1(jiti@1.21.7))(prettier@3.6.2)(typescript@5.3.3):
eslint-config-universe@12.1.0(@types/eslint@9.6.1)(eslint@9.39.1(jiti@2.6.1))(prettier@3.6.2)(typescript@5.3.3):
dependencies:
'@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3))(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)
'@typescript-eslint/parser': 6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)
eslint: 9.39.1(jiti@1.21.7)
eslint-config-prettier: 8.10.2(eslint@9.39.1(jiti@1.21.7))
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3))(eslint@9.39.1(jiti@1.21.7))
eslint-plugin-node: 11.1.0(eslint@9.39.1(jiti@1.21.7))
eslint-plugin-prettier: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@8.10.2(eslint@9.39.1(jiti@1.21.7)))(eslint@9.39.1(jiti@1.21.7))(prettier@3.6.2)
eslint-plugin-react: 7.37.5(eslint@9.39.1(jiti@1.21.7))
eslint-plugin-react-hooks: 4.6.2(eslint@9.39.1(jiti@1.21.7))
'@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)
'@typescript-eslint/parser': 6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)
eslint: 9.39.1(jiti@2.6.1)
eslint-config-prettier: 8.10.2(eslint@9.39.1(jiti@2.6.1))
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3))(eslint@9.39.1(jiti@2.6.1))
eslint-plugin-node: 11.1.0(eslint@9.39.1(jiti@2.6.1))
eslint-plugin-prettier: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@8.10.2(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))(prettier@3.6.2)
eslint-plugin-react: 7.37.5(eslint@9.39.1(jiti@2.6.1))
eslint-plugin-react-hooks: 4.6.2(eslint@9.39.1(jiti@2.6.1))
optionalDependencies:
prettier: 3.6.2
transitivePeerDependencies:
@ -33763,7 +33923,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.1(jiti@2.6.1)):
eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)):
dependencies:
'@nolyfill/is-core-module': 1.0.39
debug: 4.4.3
@ -33774,7 +33934,22 @@ snapshots:
tinyglobby: 0.2.15
unrs-resolver: 1.11.1
optionalDependencies:
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1))
transitivePeerDependencies:
- supports-color
eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)):
dependencies:
'@nolyfill/is-core-module': 1.0.39
debug: 4.4.3
eslint: 9.39.1(jiti@2.6.1)
get-tsconfig: 4.13.0
is-bun-module: 2.0.0
stable-hash: 0.0.5
tinyglobby: 0.2.15
unrs-resolver: 1.11.1
optionalDependencies:
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1))
transitivePeerDependencies:
- supports-color
@ -33788,12 +33963,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint-module-utils@2.12.1(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.1(jiti@1.21.7)):
eslint-module-utils@2.12.1(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.1(jiti@2.6.1)):
dependencies:
debug: 3.2.7
optionalDependencies:
'@typescript-eslint/parser': 6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)
eslint: 9.39.1(jiti@1.21.7)
'@typescript-eslint/parser': 6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)
eslint: 9.39.1(jiti@2.6.1)
eslint-import-resolver-node: 0.3.9
transitivePeerDependencies:
- supports-color
@ -33808,25 +33983,39 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint-module-utils@2.12.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1)):
eslint-module-utils@2.12.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)):
dependencies:
debug: 3.2.7
optionalDependencies:
'@typescript-eslint/parser': 8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3)
eslint: 9.39.1(jiti@2.6.1)
eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.1(jiti@2.6.1))
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))
transitivePeerDependencies:
- supports-color
eslint-module-utils@2.12.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1)):
eslint-module-utils@2.12.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)):
dependencies:
debug: 3.2.7
optionalDependencies:
'@typescript-eslint/parser': 8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)
eslint: 9.39.1(jiti@2.6.1)
eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.1(jiti@2.6.1))
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))
transitivePeerDependencies:
- supports-color
eslint-plugin-astro@1.5.0(eslint@9.39.1(jiti@1.21.7)):
dependencies:
'@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@1.21.7))
'@jridgewell/sourcemap-codec': 1.5.5
'@typescript-eslint/types': 8.48.0
astro-eslint-parser: 1.2.2
eslint: 9.39.1(jiti@1.21.7)
eslint-compat-utils: 0.6.5(eslint@9.39.1(jiti@1.21.7))
globals: 16.5.0
postcss: 8.5.6
postcss-selector-parser: 7.1.0
transitivePeerDependencies:
- supports-color
@ -33850,12 +34039,6 @@ snapshots:
eslint-utils: 2.1.0
regexpp: 3.2.0
eslint-plugin-es@3.0.1(eslint@9.39.1(jiti@1.21.7)):
dependencies:
eslint: 9.39.1(jiti@1.21.7)
eslint-utils: 2.1.0
regexpp: 3.2.0
eslint-plugin-es@3.0.1(eslint@9.39.1(jiti@2.6.1)):
dependencies:
eslint: 9.39.1(jiti@2.6.1)
@ -33909,7 +34092,7 @@ snapshots:
- eslint-import-resolver-webpack
- supports-color
eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3))(eslint@9.39.1(jiti@1.21.7)):
eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3))(eslint@9.39.1(jiti@2.6.1)):
dependencies:
'@rtsao/scc': 1.1.0
array-includes: 3.1.9
@ -33918,9 +34101,9 @@ snapshots:
array.prototype.flatmap: 1.3.3
debug: 3.2.7
doctrine: 2.1.0
eslint: 9.39.1(jiti@1.21.7)
eslint: 9.39.1(jiti@2.6.1)
eslint-import-resolver-node: 0.3.9
eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.1(jiti@1.21.7))
eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.1(jiti@2.6.1))
hasown: 2.0.2
is-core-module: 2.16.1
is-glob: 4.0.3
@ -33932,7 +34115,7 @@ snapshots:
string.prototype.trimend: 1.0.9
tsconfig-paths: 3.15.0
optionalDependencies:
'@typescript-eslint/parser': 6.21.0(eslint@9.39.1(jiti@1.21.7))(typescript@5.3.3)
'@typescript-eslint/parser': 6.21.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.3.3)
transitivePeerDependencies:
- eslint-import-resolver-typescript
- eslint-import-resolver-webpack
@ -33967,7 +34150,7 @@ snapshots:
- eslint-import-resolver-webpack
- supports-color
eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint@9.39.1(jiti@2.6.1)):
eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1)):
dependencies:
'@rtsao/scc': 1.1.0
array-includes: 3.1.9
@ -33978,7 +34161,7 @@ snapshots:
doctrine: 2.1.0
eslint: 9.39.1(jiti@2.6.1)
eslint-import-resolver-node: 0.3.9
eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1))
eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.8.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))
hasown: 2.0.2
is-core-module: 2.16.1
is-glob: 4.0.3
@ -33996,7 +34179,7 @@ snapshots:
- eslint-import-resolver-webpack
- supports-color
eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1)):
eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1)):
dependencies:
'@rtsao/scc': 1.1.0
array-includes: 3.1.9
@ -34007,7 +34190,7 @@ snapshots:
doctrine: 2.1.0
eslint: 9.39.1(jiti@2.6.1)
eslint-import-resolver-node: 0.3.9
eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.1(jiti@2.6.1))
eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.48.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))
hasown: 2.0.2
is-core-module: 2.16.1
is-glob: 4.0.3
@ -34035,16 +34218,6 @@ snapshots:
resolve: 1.22.11
semver: 6.3.1
eslint-plugin-node@11.1.0(eslint@9.39.1(jiti@1.21.7)):
dependencies:
eslint: 9.39.1(jiti@1.21.7)
eslint-plugin-es: 3.0.1(eslint@9.39.1(jiti@1.21.7))
eslint-utils: 2.1.0
ignore: 5.3.2
minimatch: 3.1.2
resolve: 1.22.11
semver: 6.3.1
eslint-plugin-node@11.1.0(eslint@9.39.1(jiti@2.6.1)):
dependencies:
eslint: 9.39.1(jiti@2.6.1)
@ -34075,16 +34248,6 @@ snapshots:
'@types/eslint': 9.6.1
eslint-config-prettier: 8.10.2(eslint@8.57.1)
eslint-plugin-prettier@5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@8.10.2(eslint@9.39.1(jiti@1.21.7)))(eslint@9.39.1(jiti@1.21.7))(prettier@3.6.2):
dependencies:
eslint: 9.39.1(jiti@1.21.7)
prettier: 3.6.2
prettier-linter-helpers: 1.0.0
synckit: 0.11.11
optionalDependencies:
'@types/eslint': 9.6.1
eslint-config-prettier: 8.10.2(eslint@9.39.1(jiti@1.21.7))
eslint-plugin-prettier@5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@8.10.2(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))(prettier@3.6.2):
dependencies:
eslint: 9.39.1(jiti@2.6.1)
@ -34109,10 +34272,6 @@ snapshots:
dependencies:
eslint: 8.57.1
eslint-plugin-react-hooks@4.6.2(eslint@9.39.1(jiti@1.21.7)):
dependencies:
eslint: 9.39.1(jiti@1.21.7)
eslint-plugin-react-hooks@4.6.2(eslint@9.39.1(jiti@2.6.1)):
dependencies:
eslint: 9.39.1(jiti@2.6.1)
@ -34143,28 +34302,6 @@ snapshots:
string.prototype.matchall: 4.0.12
string.prototype.repeat: 1.0.0
eslint-plugin-react@7.37.5(eslint@9.39.1(jiti@1.21.7)):
dependencies:
array-includes: 3.1.9
array.prototype.findlast: 1.2.5
array.prototype.flatmap: 1.3.3
array.prototype.tosorted: 1.1.4
doctrine: 2.1.0
es-iterator-helpers: 1.2.1
eslint: 9.39.1(jiti@1.21.7)
estraverse: 5.3.0
hasown: 2.0.2
jsx-ast-utils: 3.3.5
minimatch: 3.1.2
object.entries: 1.1.9
object.fromentries: 2.0.8
object.values: 1.2.1
prop-types: 15.8.1
resolve: 2.0.0-next.5
semver: 6.3.1
string.prototype.matchall: 4.0.12
string.prototype.repeat: 1.0.0
eslint-plugin-react@7.37.5(eslint@9.39.1(jiti@2.6.1)):
dependencies:
array-includes: 3.1.9
@ -44929,6 +45066,23 @@ snapshots:
lightningcss: 1.30.2
terser: 5.44.1
vite@6.4.1(@types/node@20.19.25)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1):
dependencies:
esbuild: 0.25.12
fdir: 6.5.0(picomatch@4.0.3)
picomatch: 4.0.3
postcss: 8.5.6
rollup: 4.53.3
tinyglobby: 0.2.15
optionalDependencies:
'@types/node': 20.19.25
fsevents: 2.3.3
jiti: 1.21.7
lightningcss: 1.30.2
terser: 5.44.1
tsx: 4.20.6
yaml: 2.8.1
vite@6.4.1(@types/node@20.19.25)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1):
dependencies:
esbuild: 0.25.12
@ -45031,6 +45185,10 @@ snapshots:
tsx: 4.20.6
yaml: 2.8.1
vitefu@1.1.1(vite@6.4.1(@types/node@20.19.25)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1)):
optionalDependencies:
vite: 6.4.1(@types/node@20.19.25)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1)
vitefu@1.1.1(vite@6.4.1(@types/node@20.19.25)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1)):
optionalDependencies:
vite: 6.4.1(@types/node@20.19.25)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1)