diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..bbe261e --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,71 @@ +# Claude Code Task Management Guide + +## Documentation Available + +📚 **Project Documentation**: Check the documentation files in this directory for project-specific setup instructions and guides. +**Project Tasks**: Check the tasks directory in documentation/tasks for the list of tasks to be completed. Use the CLI commands below to interact with them. + +## MANDATORY Task Management Workflow + +🚨 **YOU MUST FOLLOW THIS EXACT WORKFLOW - NO EXCEPTIONS** 🚨 + +### **STEP 1: DISCOVER TASKS (MANDATORY)** +You MUST start by running this command to see all available tasks: +```bash +task-manager list-tasks +``` + +### **STEP 2: START EACH TASK (MANDATORY)** +Before working on any task, you MUST mark it as started: +```bash +task-manager start-task +``` + +### **STEP 3: COMPLETE EACH TASK (MANDATORY)** +After finishing implementation, you MUST mark the task as completed: +```bash +task-manager complete-task "Brief description of what was implemented" +``` + +## Task Files Location + +📁 **Task Data**: Your tasks are organized in the `documentation/tasks/` directory: +- Task JSON files contain complete task information +- Use ONLY the `task-manager` commands listed above +- Follow the mandatory workflow sequence for each task + +## MANDATORY Task Workflow Sequence + +🔄 **For EACH individual task, you MUST follow this sequence:** + +1. 📋 **DISCOVER**: `task-manager list-tasks` (first time only) +2. 🚀 **START**: `task-manager start-task ` (mark as in progress) +3. 💻 **IMPLEMENT**: Do the actual coding/implementation work +4. ✅ **COMPLETE**: `task-manager complete-task "What was done"` +5. 🔁 **REPEAT**: Go to next task (start from step 2) + +## Task Status Options + +- `pending` - Ready to work on +- `in_progress` - Currently being worked on +- `completed` - Successfully finished +- `blocked` - Cannot proceed (waiting for dependencies) +- `cancelled` - No longer needed + +## CRITICAL WORKFLOW RULES + +❌ **NEVER skip** the `task-manager start-task` command +❌ **NEVER skip** the `task-manager complete-task` command +❌ **NEVER work on multiple tasks simultaneously** +✅ **ALWAYS complete one task fully before starting the next** +✅ **ALWAYS provide completion details in the complete command** +✅ **ALWAYS follow the exact 3-step sequence: list → start → complete** + +## Final Requirements + +🚨 **CRITICAL**: Your work is not complete until you have: +1. ✅ Completed ALL tasks using the mandatory workflow +2. ✅ Committed all changes with comprehensive commit messages +3. ✅ Created a pull request with proper description + +Remember: The task management workflow is MANDATORY, not optional! diff --git a/app/globals.css b/app/globals.css index 0d27128..e8dd7c6 100644 --- a/app/globals.css +++ b/app/globals.css @@ -14,6 +14,42 @@ } } +@keyframes aurora { + from { + background-position: 50% 50%, 50% 50%; + } + to { + background-position: 350% 50%, 350% 50%; + } +} + +@keyframes float { + 0%, 100% { + transform: translateY(0px); + } + 50% { + transform: translateY(-20px); + } +} + +@keyframes glow { + 0%, 100% { + opacity: 0.5; + } + 50% { + opacity: 1; + } +} + +@keyframes pulse-ring { + 0% { + transform: scale(0.33); + } + 80%, 100% { + opacity: 0; + } +} + @layer base { :root { --background: 0 0% 100%; diff --git a/app/page.tsx b/app/page.tsx index e22f95a..8c41ad4 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -5,10 +5,12 @@ import { PlaceholdersAndVanishInput } from '@/components/ui/placeholders-and-van import { useState } from 'react' import { AnalysisResult } from '@/components/analysis-result' import { Button } from '@/components/ui/button' -import { Download, Loader2, X } from 'lucide-react' +import { Download, Loader2, X, Sparkles, Zap, BarChart3, Target, ArrowRight, ChevronDown } from 'lucide-react' import { Alert, AlertDescription } from '@/components/ui/alert' import { useLocalStorage } from 'usehooks-ts' import { formatDistanceToNow } from 'date-fns' +import { motion } from 'framer-motion' +import { Card, CardContent } from '@/components/ui/card' interface Report { url: string @@ -30,7 +32,7 @@ export default function Home() { "Find out how to enhance your website", ] - const handleChange = (e: React.ChangeEvent) => { + const handleChange = () => { if (error) setError(null) } @@ -67,7 +69,7 @@ export default function Home() { timestamp: Date.now() }, ...prevReports]) - } catch (err) { + } catch { setError('Failed to analyze the website. Please try again.') } finally { setIsAnalyzing(false) @@ -110,61 +112,270 @@ export default function Home() { return (
-
-

- Landing Page Content Analyzer -

-

- Get actionable insights to improve your landing page copywriting and layout -

-
+ {/* Hero Section */} +
+ {/* Floating elements */} + + + + + + + + + + + + + {/* Main Hero Content */} + + +

+ Landing Page +

+

+ + Content Analyzer + +

+
+ + + Unlock the secrets of high-converting landing pages with{" "} + + AI-powered insights + + {" "}that transform your content and boost engagement + +
+ + {/* Features Cards */} + + {[ + { icon: Target, title: "Smart Analysis", desc: "AI-driven content evaluation" }, + { icon: Zap, title: "Instant Results", desc: "Get insights in seconds" }, + { icon: BarChart3, title: "Actionable Data", desc: "Clear improvement suggestions" } + ].map((feature, index) => ( + + + +
+ +
+

{feature.title}

+

{feature.desc}

+
+
+
+ ))} +
+ + {/* Input Section */} + -
+ + +

+ + No signup required • Get instant analysis + +

+
+ + {/* Loading State */} {isAnalyzing && ( -
- - Analyzing page... -
+ + + + + + Analyzing your page... + + )} + {/* Error State */} {error && ( - - {error} - + + + + + {error} + + + + )} + + {/* Scroll indicator */} + {reports.length > 0 && ( + + + View your reports + + + )}
{reports.length > 0 && ( -
-
+ +
+ {/* Section Header */} + +

+ Your Analysis Reports +

+

+ Click on any report to view detailed insights and download your analysis +

+
+ + {/* Reports Grid */}
- {reports.map((report) => { + {reports.map((report, index) => { const isExpanded = expandedReports.has(report.timestamp); return ( -
toggleReport(report.timestamp)} + whileHover={{ y: -2 }} + whileTap={{ scale: 0.98 }} > -
+
-
-

- {report.url} -

-

+

+
+
+

+ {report.url} +

+
+

+ {formatDistanceToNow(report.timestamp, { addSuffix: true })}

- {isExpanded && ( -
+ + {isExpanded ? ( + -
+ + ) : ( + + + )}
+ + {!isExpanded && ( +
+ + Click to view analysis +
+ )}
{isExpanded && ( -
-
- + +
+
+ +
-
+ )} -
+ ); })}
-
+ )}
diff --git a/documentation/app_flowchart.md b/documentation/app_flowchart.md new file mode 100644 index 0000000..1dcf26a --- /dev/null +++ b/documentation/app_flowchart.md @@ -0,0 +1,9 @@ +flowchart TD + A[User Opens App] --> B[Clerk Auth Gate] + B --> C[URL Submission Form] + C --> D[POST to api analyze] + D --> E[JinaAI Fetch Content] + E --> F[OpenAI Analyze Content] + F --> G[API Returns Markdown] + G --> H[Render AnalysisResult] + H --> I[Download Markdown Report] \ No newline at end of file diff --git a/documentation/backend_structure_document.md b/documentation/backend_structure_document.md new file mode 100644 index 0000000..f77b253 --- /dev/null +++ b/documentation/backend_structure_document.md @@ -0,0 +1,154 @@ +# Backend Structure Document + +This document outlines the backend setup of the Webpage Analyzer application. It describes the architecture, database management, APIs, hosting, infrastructure components, security, monitoring, and maintenance practices. The goal is to provide a clear, non-technical overview of how the backend works and why certain choices were made. + +## 1. Backend Architecture + +The backend is built using Next.js API Routes. This means we rely on Next.js both for serving pages and for handling server-side logic in dedicated API endpoints. + +• Frameworks and Patterns + - Next.js (App Router) for routing, server-side rendering (SSR), and API routes. + - Separation of concerns: API routes handle business logic, `lib/` modules contain core functions (e.g., content fetching, AI calls), and React components focus on UI. + - Environment variables (`.env`) store API keys and secrets, keeping them out of client code. + +• Scalability, Maintainability, Performance + - Serverless API Routes on Vercel automatically scale in response to traffic spikes. + - Modular code structure (pages, components, lib, utils) eases future feature additions and bug fixes. + - Third-party services (JinaAI, OpenAI) handle heavy processing, keeping our servers lightweight. + +## 2. Database Management + +Although the core analysis flow uses local browser storage for reports, we leverage Supabase (a hosted PostgreSQL service) for user-related data and future storage of analysis history. + +• Database Technology + - Type: SQL + - System: Supabase (managed PostgreSQL) + +• Data Handling + - User accounts and sessions are managed by Clerk, with Supabase storing user profiles and access records. + - In the current setup, analysis reports are saved locally in the browser. We plan to extend Supabase to store reports in the future. + - Supabase uses Row-Level Security (RLS) to ensure users can only access their own data. + +## 3. Database Schema + +Below is a human-readable overview of the proposed SQL schema for storing users and analysis reports. You can run these statements in PostgreSQL via Supabase. + +```sql +-- Table to store user profiles (supplied by Clerk integration) +CREATE TABLE profiles ( + id uuid PRIMARY KEY, + email text UNIQUE NOT NULL, + created_at timestamp with time zone DEFAULT now(), + updated_at timestamp with time zone DEFAULT now() +); + +-- Table to store analysis reports +CREATE TABLE analysis_reports ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + user_id uuid REFERENCES profiles(id) ON DELETE CASCADE, + url text NOT NULL, + fetched_content text NOT NULL, + analysis_markdown text NOT NULL, + created_at timestamp with time zone DEFAULT now(), + updated_at timestamp with time zone DEFAULT now() +); + +-- Index to quickly retrieve reports by user +CREATE INDEX ON analysis_reports (user_id); +``` + +## 4. API Design and Endpoints + +We use RESTful API routes built into Next.js to handle client-backend communication. + +• Main Endpoint + - `POST /api/analyze` + • Purpose: Receive a URL, fetch its content, analyze it via JinaAI and OpenAI, and return the analysis in Markdown format. + • Input: `{ url: string }` + • Output: `{ analysis: string }` (Markdown text) + • Logic: Calls `lib/analyze.ts` methods (`getWebsiteContent`, `analyzeContent`). + +• (Future) Report Management Endpoints + - `GET /api/reports` — List a user’s saved reports + - `POST /api/reports` — Save a new analysis report + - `GET /api/reports/{id}` — Retrieve a specific report + - `DELETE /api/reports/{id}` — Remove a report + +• Authentication + - Clerk middleware protects API routes, ensuring only signed-in users can call protected endpoints. + +## 5. Hosting Solutions + +• Application Hosting + - Vercel: Hosts the Next.js app and API routes. Provides automatic SSL, global CDN, and seamless deployments from the Git repository. + +• Database Hosting + - Supabase: Managed PostgreSQL database with built-in authentication, storage, and edge functions. + +• Authentication Service + - Clerk: Hosted user management service handling sign-up, sign-in, password resets, and session management. + +**Benefits** + - Reliability: Vercel and Supabase offer high uptime SLAs. + - Scalability: Serverless functions on Vercel scale automatically. Supabase scales vertically and horizontally as needed. + - Cost-Effectiveness: Pay-as-you-go model and generous free tiers for early-stage projects. + +## 6. Infrastructure Components + +• Load Balancing & CDN + - Vercel’s global CDN caches static assets and serverless responses close to users, reducing latency. + +• Caching Mechanisms + - Edge caching on Vercel for static assets and ISR (Incremental Static Regeneration) if adopted in future expansions. + +• Networking + - HTTPS enforced by default via Vercel’s SSL certificates. + +• Storage + - LocalStorage: Temporary client-side storage for analysis reports. + - Supabase Storage (optional): For storing larger files or logs in the future. + +## 7. Security Measures + +• Authentication & Authorization + - Clerk manages user identity, issuing secure JSON Web Tokens (JWT) for API access. + - API routes check tokens and enforce user-specific data access with Supabase Row-Level Security. + +• Data Encryption + - In transit: HTTPS/TLS for all network traffic. + - At rest: Supabase encrypts database storage by default. + +• Secrets Management + - API keys (OpenAI, JinaAI, Clerk, Supabase) kept in environment variables on Vercel, never exposed to the client. + +• Rate Limiting & Abuse Prevention (Future) + - Implement rate limiting on `/api/analyze` to avoid excessive AI calls. + +## 8. Monitoring and Maintenance + +• Logging + - Vercel logs serverless function invocations and errors. + - Supabase provides query and performance logs in its dashboard. + +• Metrics and Alerts + - Vercel Analytics: Tracks request volumes, latencies, and error rates. + - Supabase Metrics: Monitors database performance and usage. + +• Error Tracking (Recommended) + - Integrate Sentry or Logflare for centralized error monitoring and alerting. + +• Maintenance Practices + - Automated deployments on Git pushes (continuous deployment). + - Regular dependency updates and security scans. + - Scheduled backups of Supabase database. + +## 9. Conclusion and Overall Backend Summary + +The Webpage Analyzer’s backend leverages modern, serverless technologies to deliver scalable, secure, and maintainable services: + +• Next.js API Routes provide a unified framework for both frontend and backend logic, allowing rapid development and seamless deployment on Vercel. +• Supabase offers a robust PostgreSQL database with built-in authentication, ready to store user profiles and analysis history. +• Clerk handles user management, ensuring secure access to protected features. +• External AI services (JinaAI, OpenAI) perform content fetching and analysis, offloading heavy processing from our servers. + +Together, these components form a cohesive and future-proof backend foundation that aligns with the project’s goals of reliability, performance, and ease of use. As the application grows, additional endpoints, caching strategies, and monitoring tools can be added without major architectural changes, ensuring long-term success. \ No newline at end of file diff --git a/documentation/frontend_guidelines_document.md b/documentation/frontend_guidelines_document.md new file mode 100644 index 0000000..fe29339 --- /dev/null +++ b/documentation/frontend_guidelines_document.md @@ -0,0 +1,135 @@ +# Frontend Guidelines Document + +This document provides an overview of the frontend setup, architecture, design principles, and best practices for the Webpage Analyzer application. It is written in clear, everyday language so that anyone can understand how the frontend is built, maintained, and extended. + +## 1. Frontend Architecture + +### Frameworks and Libraries +- **Next.js 14 (App Router)**: Powers server-side rendering (SSR), routing, and API routes in a single framework. It keeps pages, components, and backend logic organized in one place. +- **React**: Builds interactive user interfaces through reusable components. +- **Tailwind CSS**: A utility-first CSS framework for rapid, consistent styling without leaving your HTML. +- **shadcn/ui + Radix UI**: A collection of accessible, prebuilt UI components layered on Tailwind, speeding up development while ensuring consistency. +- **Framer Motion**: Provides smooth, declarative animations to enhance user experience. +- **Lucide React**: Supplies a set of open-source icons for consistent visual cues. + +### How It Supports Scalability, Maintainability, and Performance +- **Server-Side Rendering** with Next.js ensures fast initial page loads and good SEO. +- **Component-Based Design** in React lets you build, test, and reuse small pieces of UI independently. +- **Utility CSS (Tailwind)** keeps your styles predictable and minimizes custom CSS. +- **Modular API Routes** (e.g., `/api/analyze`) secure API keys on the server, centralize business logic, and simplify client code. +- **Separation of Concerns**: UI components, business logic (in `lib/`), hooks, and utilities are each in their own folders, making it easy to find and update code. + +## 2. Design Principles + +### Key Principles +- **Usability**: Interfaces should be intuitive—forms guide users through URL input, analysis, and report download. +- **Accessibility**: Components follow ARIA best practices, and color choices meet contrast guidelines. +- **Responsiveness**: The layout adapts seamlessly from mobile to desktop using flexible utility classes in Tailwind. +- **Consistency**: Reusable components (buttons, inputs, cards) follow the same styling rules everywhere. + +### Applying the Principles +- Form fields show clear labels and inline validation messages. +- Focus states and keyboard navigation are supported by shadcn/ui and Radix defaults. +- Breakpoints in Tailwind ensure content reorganizes itself on small screens. +- Shared spacing, typography, and color rules keep the visual language unified. + +## 3. Styling and Theming + +### CSS Approach +- **Utility-First (Tailwind CSS)**: Apply small, single-purpose classes directly in JSX (e.g., `px-4 py-2 bg-indigo-600 text-white`). +- **Component Styles**: For complex patterns or theming variants, use Tailwind’s `@apply` directive in a central CSS file. + +### Theming +- A light and dark mode toggle is supported via a context provider. Tailwind’s `dark:` modifier switches colors automatically. +- Core color variables are defined in `tailwind.config.js` for easy theming adjustments. + +### Visual Style +- **Flat & Modern**: Clean surfaces, simple lines, and minimal shadows. +- **Subtle Glassmorphism**: Used sparingly for overlays or modal backgrounds to draw attention without distraction. + +### Color Palette +- **Primary**: Indigo (#4F46E5) +- **Secondary**: Emerald (#10B981) +- **Accent**: Amber (#F59E0B) +- **Neutral Light**: Gray-50 (#F9FAFB) +- **Neutral Dark**: Gray-900 (#111827) + +### Typography +- **Font Family**: Inter, with system-ui fallbacks (`font-family: 'Inter', system-ui, sans-serif`). +- **Sizes**: Scaled using Tailwind (`text-sm`, `text-base`, `text-lg`, `text-xl`). + +## 4. Component Structure + +### Organization +- **`components/`**: All reusable UI pieces live here. Subfolders: + - **`ui/`**: shadcn/ui components (buttons, cards, inputs). + - **`providers/`**: Context providers (e.g., Clerk client provider). +- **`app/`**: Page-level components and API routes in Next.js App Router. +- **`lib/`**: Business logic modules (`analyze.ts` for AI calls). +- **`hooks/`**: Custom React hooks (e.g., `useLocalStorage`). + +### Benefits of Component-Based Architecture +- **Reusability**: Build once, use everywhere (e.g., a Button component with consistent styling). +- **Maintainability**: Fix a bug in one place, and it updates everywhere. +- **Testability**: Isolated components are easier to test in isolation. + +## 5. State Management + +### Approach +- **Local Component State**: Managed with React’s `useState` for simple UI states (e.g., loading spinners). +- **Form State**: Handled by **React Hook Form** and validated with **Zod**, giving instant feedback. +- **Persistent State**: A `useLocalStorage` hook keeps analysis reports in browser storage so users can revisit past results. + +### Sharing State +- Context providers (e.g., Clerk for auth) wrap the app at the top level. +- Hooks and context keep state accessible but scoped to where it’s needed. + +## 6. Routing and Navigation + +### Routing Library +- **Next.js App Router** handles both page routes (in `app/`) and API routes (in `app/api/`). + +### Navigation Structure +- **Landing Page (`/`)**: Shows the URL input form and past reports. +- **Analysis API (`/api/analyze`)**: A backend endpoint that receives URLs, fetches content from JinaAI, sends it to OpenAI, and returns Markdown suggestions. + +### User Flow +1. User signs in (handled by Clerk). +2. User enters URL in `UrlAnalyzer` component. +3. Client posts to `/api/analyze`. +4. Server returns Markdown report. +5. `AnalysisResult` component renders the report and offers a download. + +## 7. Performance Optimization + +### Strategies +- **Code Splitting & Lazy Loading**: Next.js automatically splits code by route. For large components (e.g., Markdown renderer), use `dynamic()` imports. +- **Asset Optimization**: SVG icons from Lucide and optimized images in `public/`. +- **Minimal CSS**: Only load Tailwind utilities that are used, thanks to PurgeCSS built into Next.js. +- **Server-Side Rendering (SSR)**: Critical pages render on the server for faster first paint. + +### Impact on UX +- Faster page loads, smoother transitions. +- Reduced bundle sizes lead to less data transfer. +- Responsive animations without jank, thanks to Framer Motion. + +## 8. Testing and Quality Assurance + +### Unit Tests +- **React Testing Library**: For components like `UrlAnalyzer` and `AnalysisResult`. +- **Jest**: Runs fast, in-memory tests for functions in `lib/analyze.ts`. + +### Integration Tests +- **API Route Tests**: Mock JinaAI and OpenAI calls to ensure `/api/analyze` behaves as expected. + +### End-to-End (E2E) Tests +- **Cypress or Playwright**: Automate user flows—from signing in with Clerk to entering a URL and viewing a report. + +### Tooling +- **ESLint & Prettier**: Enforce code style and catch common errors. +- **TypeScript**: Ensures type safety throughout the codebase. +- **CI Pipeline**: Runs linters, tests, and builds on every push. + +## 9. Conclusion and Overall Frontend Summary + +This Frontend Guidelines Document outlines how the Webpage Analyzer app is built to be fast, scalable, and maintainable. We use Next.js 14 with React for a modern development experience, utility-first styling with Tailwind and shadcn/ui for consistency, and clear patterns for state, routing, and performance. Our design principles of usability, accessibility, and responsiveness ensure everyone has a smooth experience. Robust testing and quality tools keep our code reliable. By following these guidelines, new and existing team members can confidently develop, maintain, and extend the frontend with minimal friction. \ No newline at end of file diff --git a/documentation/project_requirements_document.md b/documentation/project_requirements_document.md new file mode 100644 index 0000000..cc27718 --- /dev/null +++ b/documentation/project_requirements_document.md @@ -0,0 +1,113 @@ +# Project Requirements Document (PRD) + +## 1. Project Overview + +**Paragraph 1:** +Webpage Analyzer is a web application that lets users enter any webpage URL and instantly get actionable copywriting and layout improvement suggestions. Under the hood, it fetches the raw HTML and text of the target site using JinaAI, sends that content to OpenAI for natural language analysis, and then presents a structured report in Markdown format. Users can read the feedback online or download the report for offline use. + +**Paragraph 2:** +This tool is being built to help marketers, copywriters, and designers quickly audit web pages without manual inspection. Key objectives include ease of use (single URL form), secure handling of API keys (all AI calls go through server-side Next.js API routes), and fast turnaround (aiming for report generation under 10 seconds). Success will be measured by user adoption, average response time, and the accuracy/relevance of suggestions as judged by early testers. + +--- + +## 2. In-Scope vs. Out-of-Scope + +**In-Scope (MVP):** +- User sign-up, sign-in, and session management (Clerk) +- Single-page interface with URL submission form (React Hook Form + Zod validation) +- Next.js API route (`/api/analyze`) that: + • Fetches content via JinaAI + • Analyzes text via OpenAI +- Markdown rendering of analysis results (`marked` library) +- Downloadable Markdown report +- Client-side local persistence of past reports (`useLocalStorage` hook) +- Responsive UI with Tailwind CSS, shadcn/ui, Framer Motion, Lucide icons +- Deployment on Vercel with environment-based API keys + +**Out-of-Scope (Phase 2+):** +- Team collaboration features (sharing, commenting) +- Multi-page project management or versioning +- In-app editing of page content +- Additional AI models (e.g., for layout mockups) +- Mobile native or desktop application +- Analytics dashboard with usage metrics +- Multi-language support beyond English + +--- + +## 3. User Flow + +**Paragraph 1:** +A new user lands on the homepage and is prompted to sign up or log in via Clerk’s authentication widgets. After authentication, they’re redirected to the main analyzer page, where they see a simple form at the top—an input field labeled "Enter webpage URL" and a submit button. Input is validated in real time: empty or invalid URLs trigger an inline error message. + +**Paragraph 2:** +When the user hits "Analyze," the form sends a `POST` request to the Next.js `/api/analyze` endpoint. The server fetches and analyzes content, then returns a Markdown report. The front end displays a loading spinner (Framer Motion) until the response arrives. Once ready, the Markdown is rendered in the main content area using the `marked` library. The user can read suggestions, click a "Download .md" button to save the report locally, or view past reports stored in localStorage below the current result. + +--- + +## 4. Core Features + +- **Authentication (Clerk):** Sign-up, login, session management, protected routes +- **URL Submission Form:** React Hook Form + Zod for real-time validation and error handling +- **Server-Side API Layer:** Next.js API route `/api/analyze` to keep AI keys secure +- **Content Fetching (JinaAI):** `getWebsiteContent(url)` helper in `lib/analyze.ts` +- **AI Analysis (OpenAI):** `analyzeContent(text)` helper in `lib/analyze.ts` +- **Markdown Rendering:** Use `marked` to convert Markdown to sanitized HTML +- **Report Download:** Client-side generation of `.md` file and download link +- **Local Persistence:** Custom `useLocalStorage` hook to store and retrieve past reports +- **Responsive UI:** Tailwind CSS + shadcn/ui for design, Framer Motion for animations, Lucide React for icons +- **Deployment Pipeline:** Vercel integration with environment variables for API keys +- **Basic Error Handling & Notifications:** Inline form errors, toast messages for network/AI failures + +--- + +## 5. Tech Stack & Tools + +- Frontend: Next.js 14 (App Router), React 18 +- Styling: Tailwind CSS, shadcn/ui components +- Animations: Framer Motion, Lucide React icons +- Forms & Validation: React Hook Form, Zod +- Auth & User Management: Clerk +- Backend/API: Next.js API Routes (`app/api/analyze/route.ts`) +- AI Services: JinaAI (content fetch), OpenAI (analysis) via `lib/analyze.ts` +- Persistence: Browser localStorage (custom hook), Supabase client setup (future DB integration) +- Markdown Parser: marked +- Deployment: Vercel +- IDE/Plugins (Optional): Cursor.ai, Windsurf for AI-assisted coding and navigation + +--- + +## 6. Non-Functional Requirements + +- **Performance:** 90th percentile response time ≤ 10s for analysis; initial page load ≤ 2s at 3G speeds +- **Security:** All AI API keys stored server-side; enforce HTTPS; sanitize Markdown output to prevent XSS +- **Scalability:** Rate limiting on `/api/analyze`; stateless serverless functions to scale with demand +- **Usability:** WCAG 2.1 AA accessibility; mobile-first responsive design; clear form error messages +- **Reliability:** 99.9% uptime on Vercel; retry logic for AI API calls (up to 2 retries with exponential backoff) +- **Maintainability:** TypeScript across codebase; modular folder structure; JSDoc on key functions + +--- + +## 7. Constraints & Assumptions + +- JinaAI and OpenAI API credentials are available and have sufficient quota +- The environment supports Next.js 14 serverless functions (Vercel) +- LocalStorage capacity (~5MB) is enough for storing text-only reports +- Users will only analyze publicly accessible URLs (no auth-protected pages) +- No on-premise hosting; relies on Vercel’s managed infrastructure +- Supabase is set up but only client initialization is in scope (no database schema changes yet) + +--- + +## 8. Known Issues & Potential Pitfalls + +- **API Rate Limits:** JinaAI/OpenAI quotas may be exhausted; implement monitoring and notify admins +- **Large Page Content:** Fetching very large websites could hit memory/time limits; consider chunking or summary first +- **Markdown Security:** Untrusted HTML injection via Markdown; use a sanitizer like DOMPurify +- **Network Failures:** Flaky connections can cause timeouts; implement retry/backoff logic and user messaging +- **LocalStorage Limits:** Users with many reports could exceed browser storage; warn or prune old entries +- **Edge Cases in URL Validation:** Some valid URLs may fail Zod checks; maintain a whitelist of URL patterns or fallback parsing logic + +--- + +*End of PRD* \ No newline at end of file diff --git a/documentation/security_guideline_document.md b/documentation/security_guideline_document.md new file mode 100644 index 0000000..fc76af2 --- /dev/null +++ b/documentation/security_guideline_document.md @@ -0,0 +1,97 @@ +# Security Guidelines for Webpage Analyzer + +This security guideline document outlines best practices and actionable recommendations to ensure the Webpage Analyzer application is built and operated securely. It is based on core security principles and tailored to the project’s architecture, technology stack, and workflows. + +## 1. Security by Design & Core Principles + +- **Embed Security Early:** Incorporate security considerations during design, development, and deployment phases; update continuously as features evolve. +- **Least Privilege:** Grant only the minimum permissions to users, API credentials, and services. For example, Supabase service roles should have limited access rights. +- **Defense in Depth:** Layer controls (network, API, application, data) so that a single failure does not compromise the system. +- **Fail Securely:** On errors—such as failed AI calls or network timeouts—return generic error messages without exposing stack traces or secrets. +- **Secure Defaults & Simplicity:** Opt for secure out-of-the-box configurations (e.g., HTTPS-only, secure cookies, strict CORS) and avoid complex custom security mechanisms. + +## 2. Authentication & Access Control + +- **Clerk Integration:** + - Enforce strong passwords, multi-factor authentication (MFA), and session timeouts. + - Use Clerk’s server-side sessions and validate them on every API call to `/api/analyze`. +- **Role-Based Access Control (RBAC):** + - Define roles (e.g., `user`, `admin`) in Clerk or Supabase policies. + - Check user roles server-side before initiating analysis or accessing stored reports. +- **Secure Session Management:** + - Configure cookies with `Secure`, `HttpOnly`, and `SameSite=Strict`. + - Regenerate session identifiers on login to prevent fixation. + +## 3. Input Handling & Processing + +- **Server-Side Validation:** + - Validate submitted URLs in `react-hook-form` via Zod and re-validate on the server to prevent open redirects or SSRF. + - Employ a URL allow-list or pattern check to restrict analysis to legitimate domains if needed. +- **Prevent Injection Attacks:** + - Use parameterized queries or Supabase’s prepared statements to avoid SQL injection. + - Sanitize any user-provided data before rendering in components or Markdown conversion. +- **Secure File Downloads:** + - When generating the Markdown report for download, ensure the filename is sanitized to prevent path traversal. + +## 4. Data Protection & Privacy + +- **Environment Variables & Secrets:** + - Store OpenAI, JinaAI, Clerk, and Supabase secrets in a secure vault (e.g., Vercel secrets, HashiCorp Vault) rather than plaintext `.env` files. + - Rotate keys periodically and after personnel changes. +- **Encryption in Transit & At Rest:** + - Enforce TLS 1.2+ for all frontend and API communications. + - Ensure Supabase database enforces encrypted connections. +- **PII Handling:** + - Do not log raw website content or user-submitted URLs in plain logs. + - Mask or redact sensitive data if logs are required for debugging. + +## 5. API & Service Security + +- **HTTPS Enforcement:** + - Redirect all HTTP traffic to HTTPS and set HSTS headers. +- **Rate Limiting & Throttling:** + - Implement rate limits on `/api/analyze` (e.g., 5 requests/minute per user) to prevent abuse and control API costs. +- **CORS Configuration:** + - Restrict origins to your application’s domain only. Avoid `*`. +- **Error Handling & Logging:** + - Return generic HTTP 4xx/5xx responses to clients. + - Log detailed errors (with context but no secrets) to a secure log store (e.g., Datadog, Logflare). + +## 6. Web Application Security Hygiene + +- **Security Headers:** + - `Content-Security-Policy`: Restrict sources for scripts, styles, and frames. + - `X-Content-Type-Options: nosniff` + - `X-Frame-Options: DENY` or `frame-ancestors 'none'` in CSP. + - `Referrer-Policy: strict-origin-when-cross-origin` +- **CSRF Protection:** + - Use Next.js built-in CSRF protection or anti-CSRF tokens for state-changing routes. +- **Secure Cookies:** + - For Clerk cookies: set `HttpOnly`, `Secure`, and `SameSite=Strict`. +- **Client-Side Storage:** + - Store analysis reports in `localStorage` only if they contain no PII or sensitive data. Consider user opt-in or encryption before storage. + +## 7. Infrastructure & Configuration Management + +- **Server Hardening:** + - Disable unused ports and services on deployment servers. + - Regularly apply OS and dependency patches. +- **CI/CD Pipeline:** + - Integrate vulnerability scanning (SCA) for dependencies. + - Fail builds on introduced high-severity CVEs. + - Use environment-specific configurations; disable debug logs in production. +- **TLS Configuration:** + - Use modern cipher suites only; disable SSLv3, TLS 1.0/1.1. + +## 8. Dependency Management + +- **Lockfiles & Audits:** + - Commit `package-lock.json` and run `npm audit` or `yarn audit` during CI. +- **Minimal Footprint:** + - Review and remove unused dependencies (e.g., check if `marked` can be replaced by a lighter Markdown parser). +- **Regular Updates:** + - Schedule periodic dependency upgrades and regression tests. + +--- + +By following these guidelines, the Webpage Analyzer application will maintain a strong security posture, protect user data, and reduce risk exposure throughout its lifecycle. \ No newline at end of file diff --git a/documentation/tasks/design-landing-page-for-it-project_2025-08-08_13-10-49-550Z.json b/documentation/tasks/design-landing-page-for-it-project_2025-08-08_13-10-49-550Z.json new file mode 100644 index 0000000..30f9004 --- /dev/null +++ b/documentation/tasks/design-landing-page-for-it-project_2025-08-08_13-10-49-550Z.json @@ -0,0 +1,77 @@ +[ + { + "title": "Set Up Authentication and User Session Management", + "description": "Implement user sign-up, sign-in, and session management using Clerk, ensuring protected routes and seamless user experience.", + "details": "Integrate Clerk authentication widgets into the Next.js 14 app using the App Router. Configure protected routes so only authenticated users can access the analyzer page. Ensure session persistence and handle redirects after login/signup. Use Clerk's React components for UI consistency. Test with both new and returning users. Document Clerk configuration and environment variables.", + "status": "pending", + "test_strategy": "Test sign-up, login, logout, and session persistence across page reloads. Attempt to access protected routes as unauthenticated user and verify redirection. Use Clerk's test accounts to simulate flows. Check for proper error handling and UI feedback.", + "priority": "high", + "ordinal": 0, + "task_group_id": "96e9b647-188c-4b23-9ebf-a024b3b62098", + "parent_task_id": null, + "id": "bdb71733-073d-44a2-86b4-277228ee9e4d", + "created_at": "2025-08-08T13:10:34.710834Z", + "user_id": "user_2qXKC3eZTjQJhRR30uDzhnVJfMe", + "subtasks": [] + }, + { + "title": "Implement Analyzer Page with URL Submission and Validation", + "description": "Create the main analyzer page with a URL input form, real-time validation, and error handling using React Hook Form and Zod.", + "details": "Build a single-page interface with a form at the top for URL submission. Use React Hook Form for state management and Zod for schema-based validation. Display inline error messages for invalid or empty URLs. Ensure accessibility (WCAG 2.1 AA) and responsive design using Tailwind CSS and shadcn/ui components. Include Framer Motion for form animations and Lucide icons for visual cues.", + "status": "pending", + "test_strategy": "Test form validation with valid, invalid, and empty URLs. Check accessibility with screen readers and keyboard navigation. Verify responsive layout on multiple devices. Confirm error messages appear as expected.", + "priority": "high", + "ordinal": 1, + "task_group_id": "96e9b647-188c-4b23-9ebf-a024b3b62098", + "parent_task_id": null, + "id": "458abb89-f4d4-4ce8-8d9e-c75ba73f9055", + "created_at": "2025-08-08T13:10:34.710841Z", + "user_id": "user_2qXKC3eZTjQJhRR30uDzhnVJfMe", + "subtasks": [] + }, + { + "title": "Develop Server-Side Analysis API Route", + "description": "Create the Next.js API route (/api/analyze) to securely fetch webpage content via JinaAI, analyze it with OpenAI, and return a Markdown report.", + "details": "Implement /api/analyze as a serverless function in Next.js. Use a helper (getWebsiteContent) in lib/analyze.ts to fetch HTML/text from the target URL via JinaAI. Pass the content to analyzeContent (OpenAI) for copy/layout suggestions. Sanitize Markdown output using DOMPurify to prevent XSS. Store API keys securely in environment variables. Add rate limiting and retry logic (up to 2 retries with exponential backoff) for API calls. Handle errors gracefully and return informative messages to the client.", + "status": "pending", + "test_strategy": "Unit test helpers with mock responses. Integration test the API route with real and mock URLs. Simulate API failures and rate limits. Validate Markdown output is sanitized and accurate. Measure response times to ensure performance targets.", + "priority": "high", + "ordinal": 2, + "task_group_id": "96e9b647-188c-4b23-9ebf-a024b3b62098", + "parent_task_id": null, + "id": "ca3d75d0-80a3-4aee-9529-3a5780a7683d", + "created_at": "2025-08-08T13:10:34.710843Z", + "user_id": "user_2qXKC3eZTjQJhRR30uDzhnVJfMe", + "subtasks": [] + }, + { + "title": "Build Frontend Report Rendering, Download, and Local Persistence", + "description": "Display the Markdown analysis report, enable download as .md, and persist past reports in localStorage.", + "details": "Use the marked library to render Markdown as sanitized HTML in the main content area. Implement a 'Download .md' button for client-side report download. Create a custom useLocalStorage hook to save and retrieve past reports, displaying them below the current result. Ensure UI is responsive and animated (Framer Motion). Handle localStorage limits by warning or pruning old entries. Use toast notifications for download and error events.", + "status": "pending", + "test_strategy": "Test Markdown rendering with various report contents. Download reports and verify file integrity. Add, retrieve, and delete past reports in localStorage. Simulate storage limits and check warning/pruning logic. Test UI responsiveness and accessibility.", + "priority": "medium", + "ordinal": 3, + "task_group_id": "96e9b647-188c-4b23-9ebf-a024b3b62098", + "parent_task_id": null, + "id": "80860b04-b019-40be-9217-9f6e742812a5", + "created_at": "2025-08-08T13:10:34.710844Z", + "user_id": "user_2qXKC3eZTjQJhRR30uDzhnVJfMe", + "subtasks": [] + }, + { + "title": "Finalize UI/UX, Error Handling, and Deployment Pipeline", + "description": "Polish the landing and analyzer pages, implement global error handling, and set up Vercel deployment with environment-based API keys.", + "details": "Refine the landing page with branding, animations (Framer Motion), and Lucide icons. Ensure all pages are mobile-first and meet accessibility standards. Implement global error handling for network and AI failures (toast messages, inline errors). Set up Vercel deployment pipeline, configure environment variables for API keys, and enforce HTTPS. Document deployment steps and environment setup. Prepare for Supabase client initialization (future DB integration).", + "status": "pending", + "test_strategy": "Perform end-to-end testing of the user flow from landing to report download. Test error scenarios (network, API, storage). Validate deployment on Vercel, check environment variable handling, and enforce HTTPS. Run accessibility audits and performance checks.", + "priority": "medium", + "ordinal": 4, + "task_group_id": "96e9b647-188c-4b23-9ebf-a024b3b62098", + "parent_task_id": null, + "id": "d00ca695-253d-4002-81c5-98ad0283d947", + "created_at": "2025-08-08T13:10:34.710845Z", + "user_id": "user_2qXKC3eZTjQJhRR30uDzhnVJfMe", + "subtasks": [] + } +] \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index c4b37e4..d3d9fd4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -75,7 +75,7 @@ "prettier": "^3.4.2", "prettier-plugin-tailwindcss": "^0.6.11", "tailwindcss": "^3.4.1", - "typescript": "^5" + "typescript": "5.9.2" } }, "node_modules/@alloc/quick-lru": { @@ -232,10 +232,11 @@ "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", - "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", + "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", "dev": true, + "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.4.3" }, @@ -2193,20 +2194,21 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.21.0.tgz", - "integrity": "sha512-eTH+UOR4I7WbdQnG4Z48ebIA6Bgi7WO8HvFEneeYBxG8qCOYgTOFPSg6ek9ITIDvGjDQzWHcoWHCDO2biByNzA==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.39.0.tgz", + "integrity": "sha512-bhEz6OZeUR+O/6yx9Jk6ohX6H9JSFTaiY0v9/PuKT3oGK0rn0jNplLmyFUGV+a9gfYnVNwGDwS/UkLIuXNb2Rw==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.21.0", - "@typescript-eslint/type-utils": "8.21.0", - "@typescript-eslint/utils": "8.21.0", - "@typescript-eslint/visitor-keys": "8.21.0", + "@typescript-eslint/scope-manager": "8.39.0", + "@typescript-eslint/type-utils": "8.39.0", + "@typescript-eslint/utils": "8.39.0", + "@typescript-eslint/visitor-keys": "8.39.0", "graphemer": "^1.4.0", - "ignore": "^5.3.1", + "ignore": "^7.0.0", "natural-compare": "^1.4.0", - "ts-api-utils": "^2.0.0" + "ts-api-utils": "^2.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2216,21 +2218,32 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "@typescript-eslint/parser": "^8.39.0", "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.8.0" + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.21.0.tgz", - "integrity": "sha512-Wy+/sdEH9kI3w9civgACwabHbKl+qIOu0uFZ9IMKzX3Jpv9og0ZBJrZExGrPpFAY7rWsXuxs5e7CPPP17A4eYA==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.39.0.tgz", + "integrity": "sha512-g3WpVQHngx0aLXn6kfIYCZxM6rRJlWzEkVpqEFLT3SgEDsp9cpCbxxgwnE504q4H+ruSDh/VGS6nqZIDynP+vg==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.21.0", - "@typescript-eslint/types": "8.21.0", - "@typescript-eslint/typescript-estree": "8.21.0", - "@typescript-eslint/visitor-keys": "8.21.0", + "@typescript-eslint/scope-manager": "8.39.0", + "@typescript-eslint/types": "8.39.0", + "@typescript-eslint/typescript-estree": "8.39.0", + "@typescript-eslint/visitor-keys": "8.39.0", "debug": "^4.3.4" }, "engines": { @@ -2242,17 +2255,40 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.8.0" + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.39.0.tgz", + "integrity": "sha512-CTzJqaSq30V/Z2Og9jogzZt8lJRR5TKlAdXmWgdu4hgcC9Kww5flQ+xFvMxIBWVNdxJO7OifgdOK4PokMIWPew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.39.0", + "@typescript-eslint/types": "^8.39.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.21.0.tgz", - "integrity": "sha512-G3IBKz0/0IPfdeGRMbp+4rbjfSSdnGkXsM/pFZA8zM9t9klXDnB/YnKOBQ0GoPmoROa4bCq2NeHgJa5ydsQ4mA==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.39.0.tgz", + "integrity": "sha512-8QOzff9UKxOh6npZQ/4FQu4mjdOCGSdO3p44ww0hk8Vu+IGbg0tB/H1LcTARRDzGCC8pDGbh2rissBuuoPgH8A==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.21.0", - "@typescript-eslint/visitor-keys": "8.21.0" + "@typescript-eslint/types": "8.39.0", + "@typescript-eslint/visitor-keys": "8.39.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2262,16 +2298,35 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.39.0.tgz", + "integrity": "sha512-Fd3/QjmFV2sKmvv3Mrj8r6N8CryYiCS8Wdb/6/rgOXAWGcFuc+VkQuG28uk/4kVNVZBQuuDHEDUpo/pQ32zsIQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.21.0.tgz", - "integrity": "sha512-95OsL6J2BtzoBxHicoXHxgk3z+9P3BEcQTpBKriqiYzLKnM2DeSqs+sndMKdamU8FosiadQFT3D+BSL9EKnAJQ==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.39.0.tgz", + "integrity": "sha512-6B3z0c1DXVT2vYA9+z9axjtc09rqKUPRmijD5m9iv8iQpHBRYRMBcgxSiKTZKm6FwWw1/cI4v6em35OsKCiN5Q==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.21.0", - "@typescript-eslint/utils": "8.21.0", + "@typescript-eslint/types": "8.39.0", + "@typescript-eslint/typescript-estree": "8.39.0", + "@typescript-eslint/utils": "8.39.0", "debug": "^4.3.4", - "ts-api-utils": "^2.0.0" + "ts-api-utils": "^2.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2282,14 +2337,15 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.8.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.21.0.tgz", - "integrity": "sha512-PAL6LUuQwotLW2a8VsySDBwYMm129vFm4tMVlylzdoTybTHaAi0oBp7Ac6LhSrHHOdLM3efH+nAR6hAWoMF89A==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.39.0.tgz", + "integrity": "sha512-ArDdaOllnCj3yn/lzKn9s0pBQYmmyme/v1HbGIGB0GB/knFI3fWMHloC+oYTJW46tVbYnGKTMDK4ah1sC2v0Kg==", "dev": true, + "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -2299,19 +2355,22 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.21.0.tgz", - "integrity": "sha512-x+aeKh/AjAArSauz0GiQZsjT8ciadNMHdkUSwBB9Z6PrKc/4knM4g3UfHml6oDJmKC88a6//cdxnO/+P2LkMcg==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.39.0.tgz", + "integrity": "sha512-ndWdiflRMvfIgQRpckQQLiB5qAKQ7w++V4LlCHwp62eym1HLB/kw7D9f2e8ytONls/jt89TEasgvb+VwnRprsw==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.21.0", - "@typescript-eslint/visitor-keys": "8.21.0", + "@typescript-eslint/project-service": "8.39.0", + "@typescript-eslint/tsconfig-utils": "8.39.0", + "@typescript-eslint/types": "8.39.0", + "@typescript-eslint/visitor-keys": "8.39.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", - "ts-api-utils": "^2.0.0" + "ts-api-utils": "^2.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2321,14 +2380,15 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.8.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -2338,6 +2398,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -2349,15 +2410,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.21.0.tgz", - "integrity": "sha512-xcXBfcq0Kaxgj7dwejMbFyq7IOHgpNMtVuDveK7w3ZGwG9owKzhALVwKpTF2yrZmEwl9SWdetf3fxNzJQaVuxw==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.39.0.tgz", + "integrity": "sha512-4GVSvNA0Vx1Ktwvf4sFE+exxJ3QGUorQG1/A5mRfRNZtkBT2xrA/BCO2H0eALx/PnvCS6/vmYwRdDA41EoffkQ==", "dev": true, + "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.21.0", - "@typescript-eslint/types": "8.21.0", - "@typescript-eslint/typescript-estree": "8.21.0" + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.39.0", + "@typescript-eslint/types": "8.39.0", + "@typescript-eslint/typescript-estree": "8.39.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2368,17 +2430,18 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.8.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.21.0.tgz", - "integrity": "sha512-BkLMNpdV6prozk8LlyK/SOoWLmUFi+ZD+pcqti9ILCbVvHGk1ui1g4jJOc2WDLaeExz2qWwojxlPce5PljcT3w==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.39.0.tgz", + "integrity": "sha512-ldgiJ+VAhQCfIjeOgu8Kj5nSxds0ktPOSO9p4+0VDH2R2pLvQraaM5Oen2d7NxzMCm+Sn/vJT+mv2H5u6b/3fA==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.21.0", - "eslint-visitor-keys": "^4.2.0" + "@typescript-eslint/types": "8.39.0", + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2389,10 +2452,11 @@ } }, "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -8533,10 +8597,11 @@ } }, "node_modules/ts-api-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.0.tgz", - "integrity": "sha512-xCt/TOAc+EOHS1XPnijD3/yzpH6qg2xppZO1YDqGoVsNXfQfzHpOdNuXwrwOU8u4ITXJyDCTyt8w5g1sZv9ynQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=18.12" }, @@ -8665,10 +8730,11 @@ } }, "node_modules/typescript": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", - "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", + "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index 539be43..8f9ce82 100644 --- a/package.json +++ b/package.json @@ -76,6 +76,6 @@ "prettier": "^3.4.2", "prettier-plugin-tailwindcss": "^0.6.11", "tailwindcss": "^3.4.1", - "typescript": "^5" + "typescript": "5.9.2" } }