diff --git a/.github/workflows/continuous-deployment.yml b/.github/workflows/continuous-deployment.yml index d86b912..6614670 100644 --- a/.github/workflows/continuous-deployment.yml +++ b/.github/workflows/continuous-deployment.yml @@ -50,28 +50,11 @@ jobs: # Configure DocumentDB version (can be overridden by repository variables) echo "DOCUMENTDB_VERSION=${{ vars.DOCUMENTDB_VERSION || 'latest' }}" >> $GITHUB_ENV echo "MULTI_VERSION=${{ vars.MULTI_VERSION || 'true' }}" >> $GITHUB_ENV - - name: Detect package manager - id: detect-package-manager - run: | - if [ -f "${{ github.workspace }}/yarn.lock" ]; then - echo "manager=yarn" >> $GITHUB_OUTPUT - echo "command=install" >> $GITHUB_OUTPUT - echo "runner=yarn" >> $GITHUB_OUTPUT - exit 0 - elif [ -f "${{ github.workspace }}/package.json" ]; then - echo "manager=npm" >> $GITHUB_OUTPUT - echo "command=ci" >> $GITHUB_OUTPUT - echo "runner=npx --no-install" >> $GITHUB_OUTPUT - exit 0 - else - echo "Unable to determine package manager" - exit 1 - fi - name: Setup Node.js uses: actions/setup-node@v5 with: node-version: 24 - cache: ${{ steps.detect-package-manager.outputs.manager }} + cache: npm - name: Restore cache uses: actions/cache@v4 with: @@ -83,11 +66,11 @@ jobs: restore-keys: | ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}- - name: Install dependencies - run: ${{ steps.detect-package-manager.outputs.manager }} ${{ steps.detect-package-manager.outputs.command }} + run: npm ci - name: Build with Next.js env: NEXT_BASE_PATH: ${{ github.event.repository.name }} - run: ${{ steps.detect-package-manager.outputs.runner }} next build + run: npm run build - name: Download DocumentDB packages from latest release run: .github/scripts/download_packages.sh - name: Upload artifact diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index fba2a6f..ee09c25 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -1,12 +1,16 @@ -name: Validate structured content +# Workflow for validating content structure and build integrity +name: Validate site and content on: + # Runs on pushes targeting the default branch push: branches: - main + # Runs on pull requests targeting the default branch pull_request: branches: - main jobs: + # YAML schema validation job yaml-schema-validation: name: Validate YAML files against schemas runs-on: ubuntu-latest @@ -25,3 +29,22 @@ jobs: npx yaml-ls-check .\articles npx yaml-ls-check .\blogs npx yaml-ls-check .\reference + # Build validation job + build-validation: + name: Validate Next.js build + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v5 + - name: Setup Node.js + uses: actions/setup-node@v5 + with: + node-version: 24 + cache: npm + - name: Install dependencies + run: npm ci + - name: Build Next.js site + # Validate that the site builds successfully + # + # Use the built-in NPM script to build the site + run: npm run build diff --git a/.gitignore b/.gitignore index 8180dc6..ab74a61 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,20 @@ # Sourced from https://github.com/github/gitignore/blob/main/Nextjs.gitignore # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. +# Temporary content cloning directory +_tmp/ + +# Reference files +api-reference/ +reference/ + +# Documentation articles +articles/*/ +articles/**/*.md +articles/**/*.yml +!articles/content.yml +!articles/demo.yml + # dependencies /node_modules /.pnp diff --git a/.vscode/settings.json b/.vscode/settings.json index 1b3c4dc..53e0fea 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,14 +6,8 @@ "./schema/reference.content.schema.json": [ "reference/content.{yml,yaml}" ], - "./schema/reference.data.schema.json": [ - "reference/*/**/*.{yml,yaml}" - ], "./schema/articles.content.schema.json": [ "articles/**/content.{yml,yaml}" - ], - "./schema/articles.navigation.schema.json": [ - "articles/**/navigation.{yml,yaml}" ] }, "editor.tabSize": 2, diff --git a/app/components/Breadcrumb.tsx b/app/components/Breadcrumb.tsx index 07f156e..a3199b1 100644 --- a/app/components/Breadcrumb.tsx +++ b/app/components/Breadcrumb.tsx @@ -16,7 +16,7 @@ export default function Breadcrumb({ type, category, name }: { <> / - {capitalCase(pluralize(type))} + {capitalCase(type)} )} diff --git a/app/components/Index.tsx b/app/components/Index.tsx index 20ad186..337b064 100644 --- a/app/components/Index.tsx +++ b/app/components/Index.tsx @@ -1,9 +1,39 @@ -"use client"; +'use client' import Link from 'next/link'; import { usePathname } from 'next/navigation'; -import type { ReferencePage } from '../services/referenceService'; import { capitalCase } from 'change-case'; +import pluralize from 'pluralize'; +import React, { useEffect, useRef } from 'react'; + +type ReferencePage = { + name: string; + description: string; + reference: string; + type: string; + category?: string; +}; + +type NavigationStructure = { + type: string; + displayName: string; + categories: { + category: string; + displayName: string; + items: ReferencePage[]; + }[]; +}[]; + +const icons = { + chevronRight: ( + + ), +}; export default function Index({ groupedReferences @@ -11,45 +41,149 @@ export default function Index({ groupedReferences: Record>; }) { const pathname = usePathname(); + const activeItemRef = useRef(null); + const containerRef = useRef(null); + + // Auto-scroll to active item when pathname changes + useEffect(() => { + if (activeItemRef.current && containerRef.current) { + const container = containerRef.current; + const activeItem = activeItemRef.current; + + // Calculate position to scroll within the container + const containerRect = container.getBoundingClientRect(); + const itemRect = activeItem.getBoundingClientRect(); + const scrollOffset = itemRect.top - containerRect.top - (containerRect.height / 2) + (itemRect.height / 2); + + // Instant scroll without animation + container.scrollBy({ + top: scrollOffset, + behavior: 'instant' + }); + } + }, [pathname]); - // Get all types and sort them - const types = Object.keys(groupedReferences).sort(); + // Convert old structure to new structure + const navigationStructure: NavigationStructure = Object.entries(groupedReferences) + .sort(([a], [b]) => a.localeCompare(b)) + .map(([type, categories]) => ({ + type, + displayName: type, + categories: Object.entries(categories) + .sort(([a], [b]) => a.localeCompare(b)) + .map(([category, items]) => ({ + category, + displayName: category, + items: items.sort((a, b) => a.name.localeCompare(b.name)) + })) + })); + + // Parse pathname to determine current location + const pathParts = pathname.split('/').filter(Boolean); + const currentType = pathParts[2]; // /docs/reference/[type] + const currentCategory = pathParts[3]; // /docs/reference/[type]/[category] + const currentName = pathParts[4] ? decodeURIComponent(pathParts[4]) : undefined; // /docs/reference/[type]/[category]/[name] return ( -
+
); } - -function Option({ - target, - display, - className, - currentPath -}: { - target: string; - display: string; - className?: string; - currentPath: string; -}) { - // Determine if this option should be highlighted - // Highlight if: - // 1. Exact match (e.g., on /docs/reference/operator, highlight "Operators") - // 2. Category match (e.g., on /docs/reference/operator/accumulator or /docs/reference/operator/accumulator/avg, highlight "Operators" and "Accumulator") - const isExactMatch = currentPath === target; - const isCategoryMatch = currentPath.startsWith(target + '/'); - const isActive = isExactMatch || isCategoryMatch; - - return ( - - {display} - - ); -} diff --git a/app/components/Markdown.tsx b/app/components/Markdown.tsx index ca70b6e..de0c327 100644 --- a/app/components/Markdown.tsx +++ b/app/components/Markdown.tsx @@ -59,6 +59,16 @@ export default function Markdown({ content }: { content: string }) { function getMarkdownComponents() { return { + // H1 headings (main page title from Markdown content) + h1: ({ children, ...props }: any) => ( + <> +

+ {children} +

+
+ + ), + // Paragraphs p: ({ children, ...props }: any) => (

diff --git a/app/docs/[section]/[[...slug]]/page.tsx b/app/docs/[section]/[[...slug]]/page.tsx index 12d8ebc..ab4780f 100644 --- a/app/docs/[section]/[[...slug]]/page.tsx +++ b/app/docs/[section]/[[...slug]]/page.tsx @@ -1,5 +1,6 @@ import Link from "next/link"; import { notFound } from 'next/navigation'; +import { capitalCase } from 'change-case'; import { getAllArticlePaths, getArticleByPath } from "../../../services/articleService"; import ComingSoon from "../../../components/ComingSoon"; import Markdown from "../../../components/Markdown"; @@ -23,7 +24,7 @@ interface PageProps { export async function generateMetadata({ params }: PageProps) { const { section, slug = [] } = await params; const articleData = getArticleByPath(section, slug); - + if (!articleData) { return { title: 'Documentation - DocumentDB', @@ -33,7 +34,7 @@ export async function generateMetadata({ params }: PageProps) { const { frontmatter, navigation, file } = articleData; const selectedNavItem = navigation.find((item) => item.link.includes(file)); const pageTitle = frontmatter.title || selectedNavItem?.title || section; - + return { title: `${pageTitle} - DocumentDB Documentation`, description: frontmatter.description || undefined, @@ -92,8 +93,12 @@ export default async function ArticlePage({ params }: PageProps) { Back to Documentation -

- {section} +

+ { + capitalCase(section) + .replace(/documentdb/i, 'DocumentDB') + .replace(/api/i, 'API') + }

@@ -106,17 +111,17 @@ export default async function ArticlePage({ params }: PageProps) { // For other files, match the specific file name const itemPath = item.link.replace('/docs/', ''); const currentPath = file === 'index' ? section : `${section}/${file}`; - const isActive = itemPath === currentPath || - (file === 'index' && itemPath === `${section}/index`) || - (item.link.includes(file) && file !== 'index'); - + const isActive = itemPath === currentPath || + (file === 'index' && itemPath === `${section}/index`) || + (item.link.includes(file) && file !== 'index'); + return ( {item.title} @@ -130,13 +135,6 @@ export default async function ArticlePage({ params }: PageProps) { {/* Main Content */}
-
-

- {pageTitle} -

-
-
- {/* Coming Soon Component for coming-soon layout */} {frontmatter.layout === 'coming-soon' && } diff --git a/app/docs/page.tsx b/app/docs/page.tsx index 41d2782..1fabea7 100644 --- a/app/docs/page.tsx +++ b/app/docs/page.tsx @@ -1,2407 +1,8 @@ - -"use client"; -import { useState } from "react"; +import Link from "next/link"; +import { getArticleContent } from "../services/articleService"; export default function Docs() { - const [currentPage, setCurrentPage] = useState("main"); - const [selectedOperator, setSelectedOperator] = useState("Accumulator"); - const [selectedPostgresItem, setSelectedPostgresItem] = - useState("Components"); - const [selectedGettingStartedItem, setSelectedGettingStartedItem] = useState( - "Python Setup Guide", - ); - - const operatorCategories = [ - "Accumulator", - "Aggregation", - "Arithmetic Expression", - "Array Expression", - "Array Query", - "Array Update", - "Bitwise", - "Bitwise Query", - "Bitwise Update", - "Boolean Expression", - "Comparison Query", - "Conditional Expression", - "Date Expression", - "Data Size", - "Element Query", - "Evaluation Query", - "Field Update", - "Geospatial", - "Logical Query", - "Miscellaneous", - "Object Expression", - "Projection", - "Timestamp Expression", - "Set Expression", - "Variable Expression", - "Window" - ]; - - const postgresMenuItems = ["Components", "Functions"]; - - const gettingStartedMenuItems = [ - "Python Setup Guide", - "VS Code Extension Quick Start", - "MongoDB Shell Quick Start" - ]; - - if (currentPage === "postgres-api") { - return ( -
- {/* Background elements */} -
-
-
-
-
- -
- {/* Left Sidebar */} -
- {/* Header */} -
- -

- Postgres Extension API -

-
- - {/* Menu Items */} -
- -
-
- - {/* Main Content */} -
-
-
-

- {selectedPostgresItem} -

-
- {selectedPostgresItem !== "Components" && ( -

- Comprehensive documentation for PostgreSQL extension{" "} - {selectedPostgresItem.toLowerCase()} and their usage - patterns. -

- )} -
- - {/* Content based on selected postgres item */} - {selectedPostgresItem === "Components" ? ( -
- {/* pg_documentdb_core Section */} -
-

- pg_documentdb_core -

-

- pg_documentdb_core is a PostgreSQL extension that - introduces BSON datatype support and operations for native - Postgres. This core component is essential for enabling - document-oriented NoSQL capabilities within a PostgreSQL - environment. It provides the foundational data structures - and functions required to handle BSON data types, which - are crucial for performing CRUD operations on documents. -

- -

- Key Features -

-
    -
  • - -
    - - BSON Datatype Support: - {" "} - Adds BSON (Binary JSON) datatype to PostgreSQL, - allowing for efficient storage and manipulation of - JSON-like documents. -
    -
  • -
  • - -
    - - Native Operations: - {" "} - Implements native PostgreSQL operations for BSON data, - ensuring seamless integration and performance. -
    -
  • -
  • - -
    - - Extensibility: - {" "} - Serves as the core building block for additional - functionalities and extensions within the DocumentDB - ecosystem. -
    -
  • -
-
- - {/* pg_documentdb_api Section */} -
-

- pg_documentdb_api -

-

- pg_documentdb_api is the public API surface for - DocumentDB, providing CRUD functionality on documents - stored in the database. This component leverages the - capabilities of pg_documentdb_core to offer a - comprehensive set of APIs for managing document data - within PostgreSQL. -

- -

- Key Features -

-
    -
  • - -
    - - CRUD Operations: - {" "} - Provides a rich set of APIs for creating, reading, - updating, and deleting documents. -
    -
  • -
  • - -
    - - Advanced Queries: - {" "} - Supports complex queries, including full-text - searches, geospatial queries, and vector embeddings. -
    -
  • -
  • - -
    - - Integration: - {" "} - Works seamlessly with pg_documentdb_core to deliver - robust document management capabilities. -
    -
  • -
- -

- Usage -

-

- To use pg_documentdb_api, you need to have - pg_documentdb_core installed and configured in your - PostgreSQL environment. Once set up, you can leverage the - APIs provided by pg_documentdb_api to perform various - document operations. -

-
-
- ) : selectedPostgresItem === "Functions" ? ( -
- {/* Table of Contents */} -
-

- Table of Contents -

- - {/* CRUD Operations */} -
-

- CRUD Operations -

-
- {[ - "aggregate_cursor_first_page()", - "count_query()", - "cursor_get_more()", - "delete()", - "distinct_query()", - "find_and_modify()", - "find_cursor_first_page()", - "insert()", - "insert_one()", - "list_collections_cursor_first_page()", - "list_indexes_cursor_first_page()", - "update()", - ].map((func) => ( - - {func} - - ))} -
-
- - {/* Collection Management */} -
-

- Collection Management -

-
- {[ - "coll_mod()", - "create_collection()", - "create_collection_view()", - "drop_collection()", - "drop_database()", - "rename_collection()", - "shard_collection()", - ].map((func) => ( - - {func} - - ))} -
-
- - {/* User Management */} -
-

- User Management -

-
- {[ - "create_user()", - "drop_user()", - "update_user()", - "users_info()", - ].map((func) => ( - - {func} - - ))} -
-
- - {/* Utility Functions */} -
-

- Utility Functions -

-
- {["binary_extended_version()", "binary_version()"].map( - (func) => ( - - {func} - - ), - )} -
-
-
-
- ) : ( - /* Sample content for other items */ -
-
-

- Overview -

-

- The {selectedPostgresItem} section provides comprehensive - information about PostgreSQL extension capabilities. These - components are essential for building robust database - applications with document storage features. -

-
-

- Example usage: -

- - SELECT * FROM pg_extension WHERE extname = 'documentdb'; - -
-
-
- )} -
-
-
-
- ); - } - - if (currentPage === "getting-started") { - return ( -
- {/* Background elements */} -
-
-
-
-
- -
- {/* Left Sidebar */} -
- {/* Header */} -
- -

Getting Started

-
- - {/* Menu Items */} -
- -
-
- - {/* Main Content */} -
-
-
-

- {selectedGettingStartedItem} -

-
-

- Quick start guide for{" "} - {selectedGettingStartedItem.toLowerCase()}. -

-
- - {/* Content based on selected getting started item */} - {selectedGettingStartedItem === - "VS Code Extension Quick Start" ? ( -
- {/* Introduction */} -
-

- Get started with DocumentDB using the Visual Studio Code - extension for a seamless development experience. -

-
- - {/* Prerequisites */} -
-

- Prerequisites -

-
    -
  • - - Visual Studio Code installed -
  • -
  • - - Docker Desktop installed and running -
  • -
  • - - Basic familiarity with document databases -
  • -
  • - - Git installed (for cloning the repository) -
  • -
-
- - {/* Installing the Extension */} -
-

- Installing the Extension -

-
    -
  1. - 1. - Open VS Code -
  2. -
  3. - 2. - - Navigate to the Extensions marketplace ( - - Ctrl+Shift+X - {" "} - or{" "} - - Cmd+Shift+X - - ) - -
  4. -
  5. - 3. - Search for "DocumentDB for VS Code" -
  6. -
  7. - 4. - Click Install -
  8. -
  9. - 5. - Reload VS Code if prompted -
  10. -
-
- - {/* Setting Up Your First Database */} -
-

- Setting Up Your First Database -

- -
-
-

- 1. Creating a new DocumentDB instance -

-
-
-                            {`docker pull ghcr.io/microsoft/documentdb/documentdb-local:latest
-docker tag ghcr.io/microsoft/documentdb/documentdb-local:latest documentdb
-docker run -dt -p 10260:10260 --name documentdb-container documentdb --username  --password 
-docker image rm -f ghcr.io/microsoft/documentdb/documentdb-local:latest || echo "No existing documentdb image to remove"`}
-                          
-
-
-

- Note: Replace{" "} - - <YOUR_USERNAME> - {" "} - and{" "} - - <YOUR_PASSWORD> - {" "} - with your desired credentials. You must set these - when creating the container for authentication to - work. -

-
-
-

- Port Note: Port{" "} - - 10260 - {" "} - is used by default in these instructions to avoid - conflicts with other local database services. You - can use port{" "} - - 27017 - {" "} - (the standard MongoDB port) or any other available - port if you prefer. If you do, be sure to update the - port number in both your{" "} - - docker run - {" "} - command and your connection string accordingly. -

-
-
- -
-

- 2. Connecting to your database -

-
    -
  • - - - Click the DocumentDB icon in the VS Code sidebar - -
  • -
  • - - Click "Add New Connection" -
  • -
  • - - - On the navigation bar, click on "Connection - String" - -
  • -
  • - - Paste your connection string: -
  • -
-
- - mongodb://<YOUR_USERNAME>:<YOUR_PASSWORD>@localhost:10260/?tls=true&tlsAllowInvalidCertificates=true&authMechanism=SCRAM-SHA-256 - -
-
- -
-

- 3. Creating your first database and collection -

-
    -
  • - - - Click on the drop-down next to your local - connection and select "Create Database..." - -
  • -
  • - - Enter database name and confirm -
  • -
  • - - - Click on the drop-down next to your created - database and select "Create Collection..." - -
  • -
  • - - Enter collection name and confirm -
  • -
  • - - - Repeat for every database and collection you wish - to create under your connection - -
  • -
-
-
-
- - {/* Working with Documents */} -
-

- Working with Documents -

- -
-
-

- 1. Creating documents -

-
    -
  • - - Use the Table View for quick data entry -
  • -
  • - - - Use the Tree View for hierarchical data - exploration - -
  • -
  • - - - Use the JSON View for detailed document structure - -
  • -
-
-
-                            {`{
-  "name": "Test Document",
-  "type": "example",
-  "created_at": new Date()
-}`}
-                          
-
-
- -
-

- 2. Using the document explorer -

-
    -
  • - - Browse documents in multiple views: -
  • -
-
-
- - - Table View for quick insights -
-
- - - Tree View for hierarchical exploration -
-
- - - JSON View for detailed structure -
-
-
    -
  • - - - Use smooth pagination for large datasets - -
  • -
-
-
-
- - {/* Import and Export */} -
-

- Import and Export -

- -
-
-

- 1. Importing data -

-
    -
  • - - - Click on the "Import" button on each collection - -
  • -
  • - - Choose your JSON file -
  • -
  • - - Confirm import -
  • -
-
- -
-

- 2. Exporting data -

-
    -
  • - - - Export entire collections or query results using - the "Export" button on each collection - -
  • -
-
-
-
-
- ) : selectedGettingStartedItem === "MongoDB Shell Quick Start" ? ( -
- {/* Introduction */} -
-

- Get started with DocumentDB using the MongoDB shell for a - familiar MongoDB-compatible experience. -

-
- - {/* Prerequisites */} -
-

- Prerequisites -

-
    -
  • - - MongoDB Shell (mongosh) installed -
  • -
  • - - Docker Desktop installed and running -
  • -
  • - - Basic MongoDB knowledge -
  • -
  • - - Git installed (for cloning the repository) -
  • -
-
- - {/* Installation */} -
-

- Installation -

- -
-
-

- 1. Setting up DocumentDB locally -

-
-
-                            {`# Pull the latest DocumentDB Docker image
-docker pull ghcr.io/microsoft/documentdb/documentdb-local:latest
-
-# Tag the image for convenience
-docker tag ghcr.io/microsoft/documentdb/documentdb-local:latest documentdb
-
-# Run the container with your chosen username and password
-docker run -dt -p 10260:10260 --name documentdb-container documentdb --username  --password 
-docker image rm -f ghcr.io/microsoft/documentdb/documentdb-local:latest || echo "No existing documentdb image to remove"`}
-                          
-
-
-

- Note: Replace{" "} - - <YOUR_USERNAME> - {" "} - and{" "} - - <YOUR_PASSWORD> - {" "} - with your desired credentials. You must set these - when creating the container for authentication to - work. -

-
-
-

- Port Note: Port{" "} - - 10260 - {" "} - is used by default in these instructions to avoid - conflicts with other local database services. You - can use port{" "} - - 27017 - {" "} - (the standard MongoDB port) or any other available - port if you prefer. If you do, be sure to update the - port number in both your{" "} - - docker run - {" "} - command and your connection string accordingly. -

-
-
- -
-

- 2. Starting the server -

-
-
-                            {`# The server will be available at localhost:10260 (or your chosen port)
-# You can verify the server is running using:
-docker ps`}
-                          
-
-
-
-
- - {/* Connecting to DocumentDB */} -
-

- Connecting to DocumentDB -

-

- Connection string format -

-
-
-                        {`mongosh "mongodb://:@localhost:10260/?tls=true&tlsAllowInvalidCertificates=true"`}
-                      
-
-
- - {/* Basic Operations */} -
-

- Basic Operations -

- -
-
-

- 1. Creating databases and collections -

-
-
-                            {`// Create/switch to a database
-use mydb
-
-// Create a collection
-db.createCollection("users")
-
-// Create another collection
-db.createCollection("logs")`}
-                          
-
-
- -
-

- 2. Inserting documents -

-
-
-                            {`// Insert a single document
-db.users.insertOne({ name: "John Doe", email: "john@example.com", created_at: new Date() })
-
-// Insert multiple documents
-db.users.insertMany([
-  { name: "Jane Smith", email: "jane@example.com" }, 
-  { name: "Bob Johnson", email: "bob@example.com" }
-])`}
-                          
-
-
- -
-

- 3. Querying documents -

-
-
-                            {`// Find all documents
-db.users.find()
-
-// Find with criteria
-db.users.find({ name: "John Doe" })
-
-// Find with projection
-db.users.find({}, { name: 1, email: 1, _id: 0 })
-
-// Complex queries
-db.users.find(
-{ $and: 
-  [{ 
-    created_at: { $gte: new Date("2025-01-01") } 
-   }, 
-   { 
-    email: { $regex: "@example.com$" } 
-   }
-  ] 
-})`}
-                          
-
-
- -
-

- 4. Updating documents -

-
-
-                            {`// Update a single document
-db.users.updateOne({ name: "John Doe" }, { $set: { status: "active" } })
-
-// Update multiple documents
-db.users.updateMany({ email: { $regex: "@example.com$" } }, { $set: { domain: "example.com" } })`}
-                          
-
-
- -
-

- 5. Deleting documents -

-
-
-                            {`// Delete a single document
-db.users.deleteOne({ name: "John Doe" })
-
-// Delete multiple documents
-db.users.deleteMany({ status: "inactive" })`}
-                          
-
-
-
-
- - {/* Working with Indexes */} -
-

- Working with Indexes -

- -
-
-

- 1. Understanding index types -

-
-
-                            {`// Available index types:
-// - Single field
-// - Compound
-// - Multi-key
-// - Text
-// - Geospatial
-// - Vector`}
-                          
-
-
- -
-

- 2. Creating indexes -

-
-
-                            {`// Single field index
-db.users.createIndex({ email: 1 })
-
-// Compound index
-db.users.createIndex({ name: 1, email: 1 })
-`}
-                          
-
-
-
-
- - {/* Monitoring and Management */} -
-

- Monitoring and Management -

- -
-
-

- 1. Database statistics -

-
-
-                            {`// Get database stats
-db.stats()
-
-// Get collection stats
-db.users.stats()`}
-                          
-
-
- -
-

- 2. Collection statistics -

-
-
-                            {`// Get collection size
-db.users.dataSize()
-
-// Get index sizes
-db.users.stats().indexSizes`}
-                          
-
-
-
-
-
- ) : selectedGettingStartedItem === "Python Setup Guide" ? ( -
- {/* Introduction */} -
-

- Learn how to set up and use DocumentDB with Python using the MongoDB Python driver (PyMongo). -

-
- - {/* Prerequisites */} -
-

- Prerequisites -

-
    -
  • - - Python 3.7+ -
  • -
  • - - pip package manager -
  • -
  • - - Docker -
  • -
  • - - Git (for cloning the repository) -
  • -
-
- - {/* Step 1: Install Python */} -
-

- Step 1: Install Python -

- -
-
-                {`pip install pymongo`}
-                      
-
-
- - {/* Step 2: Install optional dependencies */} -
-

- Step 2: Install optional dependencies -

- -
-
-                {`pip install dnspython`}
-                      
-
-
- - {/* Step 3: Setup DocumentDB using Docker */} -
-

- Step 3: Setup DocumentDB using Docker -

- -
-
-                {`# Pull the latest DocumentDB Docker image
-docker pull ghcr.io/microsoft/documentdb/documentdb-local:latest
-
-# Tag the image for convenience
-docker tag ghcr.io/microsoft/documentdb/documentdb-local:latest documentdb
-
-# Run the container with your chosen username and password
-docker run -dt -p 10260:10260 --name documentdb-container documentdb --username  --password 
-docker image rm -f ghcr.io/microsoft/documentdb/documentdb-local:latest || echo "No existing documentdb image to remove"`}
-                      
-
- -
-

- Note: During the transition to the Linux Foundation, Docker images may still be hosted on Microsoft's container registry. These will be migrated to the new DocumentDB organization as the transition completes. -

-
- -
-

- Note: Replace{" "} - - <YOUR_USERNAME> - {" "} - and{" "} - - <YOUR_PASSWORD> - {" "} - with your desired credentials. You must set these when creating the container for authentication to work. -

-
- -
-

- Port Note: Port{" "} - - 10260 - {" "} - is used by default in these instructions to avoid conflicts with other local database services. You can use port{" "} - - 27017 - {" "} - (the standard MongoDB port) or any other available port if you prefer. If you do, be sure to update the port number in both your{" "} - - docker run - {" "} - command and your connection string accordingly. -

-
-
- - {/* Step 4: Initialize the pymongo client */} -
-

- Step 4: Initialize the pymongo client with the credentials from the previous step -

- -
-
-                {`import pymongo
-from pymongo import MongoClient
-
-# Create a MongoDB client and open a connection to DocumentDB
-client = pymongo.MongoClient(
-    'mongodb://:@localhost:10260/?tls=true&tlsAllowInvalidCertificates=true'
-                )`}
-                      
-
-
- - {/* Step 5: Create a database and collection */} -
-

- Step 5: Create a database and collection -

- -
-
-                {`quickStartDatabase = client["quickStartDatabase"]
-quickStartCollection = quickStartDatabase.create_collection("quickStartCollection")`}
-                      
-
-
- - {/* Step 6: Insert documents */} -
-

- Step 6: Insert documents -

- -
-
-                {`# Insert a single document
-quickStartCollection.insert_one({
-       'name': 'John Doe',
-       'email': 'john@email.com',
-       'address': '123 Main St, Anytown, USA',
-       'phone': '555-1234'
-   })
-
-# Insert multiple documents
-quickStartCollection.insert_many([
-    {
-        'name': 'Jane Smith',
-        'email': 'jane@email.com',
-        'address': '456 Elm St, Othertown, USA',
-        'phone': '555-5678'
-    },
-    {
-        'name': 'Alice Johnson',
-        'email': 'alice@email.com',
-        'address': '789 Oak St, Sometown, USA',
-        'phone': '555-8765'
-    }
-])`}
-                      
-
-
- - {/* Step 7: Read documents */} -
-

- Step 7: Read documents -

- -
-
-                {`# Read all documents
-for document in quickStartCollection.find():
-    print(document)
-
-# Read a specific document
-singleDocumentReadResult = quickStartCollection.find_one({'name': 'John Doe'})
-    print(singleDocumentReadResult)`}
-                      
-
-
- - {/* Step 8: Run aggregation pipeline query */} -
-

- Step 8: Run aggregation pipeline query -

- -
-
-                {`pipeline = [
-    {'$match': {'name': 'Alice Johnson'}},
-    {'$project': {
-        '_id': 0,
-        'name': 1,
-        'email': 1
-    }}
-]
-
-results = quickStartCollection.aggregate(pipeline)
-print("Aggregation results:")
-for eachDocument in results:
-    print(eachDocument)`}
-                      
-
-
-
- ): ( - // Keep your existing content for other menu items -
-
-

- Getting Started with {selectedGettingStartedItem} -

-

- Welcome to the {selectedGettingStartedItem} guide. This - section will help you get up and running quickly. -

- -

- Step 1: Installation -

-
- - # Installation instructions for{" "} - {selectedGettingStartedItem} - -
- -

- Step 2: Configuration -

-

- Configure your environment for optimal use with - DocumentDB. -

- -

- Step 3: First Steps -

-

- Start building with DocumentDB using{" "} - {selectedGettingStartedItem}. -

-
-
- )} -
-
-
-
- ); - } - - if (currentPage === "api-reference") { - return ( -
- {/* Background elements */} -
-
-
-
-
- -
- {/* Left Sidebar */} -
- {/* Header */} -
- -

Operator Docs

-
- - {/* Menu Items */} -
- -
-
- - {/* Main Content */} -
-
-
-

- {selectedOperator} -

-
-

- List of supported {selectedOperator} operators. Detailed - usage samples coming soon! -

-
- - {/* Content based on selected operator */} - {selectedOperator === "Accumulator" ? ( -
-

- Accumulator Operators -

-
- {[ - "$avg", - "$bottom", - "$bottomN", - "$count", - "$first", - "$firstN", - "$last", - "$lastN", - "$max", - "$maxN", - "$median", - "$min", - "$minN", - "$stdDevPop", - "$stdDevSamp", - "$sum", - "$top", - "$topN", - ].map((operator) => ( - - ))} -
-
- ) : selectedOperator === "Aggregation" ? ( -
-

- Aggregation Operators -

-
- {[ - "$addFields", - "$bucket", - "$changeStreams", - "$collstats", - "$convert", - "$count", - "$densify", - "documents", - "$facet", - "$fill", - "$geoNear", - "$group", - "$indexStats", - "$isNumber", - "$lookup", - "$match", - "$merge", - "$out", - "$redact", - "$replaceWith", - "$sample", - "$set", - "$skip", - "$sort", - "$sortByCount", - "$toBool", - "$toDate", - "$toDecimal", - "$toDouble", - "$toInt", - "$toLong", - "$toObjectId", - "$toString", - "$unset", - "$unwind"].map( - (operator) => ( - - ), - )} -
-
- ) : selectedOperator === "Arithmetic Expression" ? ( -
-

- Arithmetic Expression Operators -

-
- {[ - "$abs", - "$add", - "$ceil", - "$divide", - "$exp", - "$floor", - "$ln", - "$log", - "$log10", - "$mod", - "$multiply", - "$pow", - "$round", - "$sqrt", - "$subtract", - "$trunc", - ].map((operator) => ( - - ))} -
-
- ) : selectedOperator === "Array Expression" ? ( -
-

- Array Expression Operators -

-
- {[ - "$arrayElemAt", - "$arrayToObject", - "$concatArrays", - "$filter", - "$in", - "$indexOfArray", - "$isArray", - "$objectToArray", - "$reverseArray", - "$map", - "$range", - "$reduce", - "$slice", - "$sortArray", - "$zip", - ].map((operator) => ( - - ))} -
-
- ) : selectedOperator === "Array Query" ? ( -
-

- Array Query Operators -

-
- {["$all", "$elemMatch", "$size"].map((operator) => ( - - ))} -
-
- ) : selectedOperator === "Array Update" ? ( -
-

- Array Update Operators -

-
- {[ - "$addToSet", - "$each", - "$pop", - "$position", - "$", - "[]", - "[]", - "$pull", - "$pullAll", - "$push", - "$slice", - "$sort", - ].map((operator) => ( - - ))} -
-
- ) : selectedOperator === "Bitwise" ? ( -
-

- Bitwise Operators -

-
- {["$bitand", "$bitnot", "$bitor", "$bitxnor"].map( - (operator) => ( - - ), - )} -
-
- ) : selectedOperator === "Bitwise Query" ? ( -
-

- Bitwise Query Operators -

-
- {[ - "$bitsAllClear", - "$bitsAllSet", - "$bitsAnyClear", - "$bitsAnySet", - ].map((operator) => ( - - ))} -
-
- ) : selectedOperator === "Bitwise Update" ? ( -
-

- Bitwise Update Operators -

-
- {["$bit"].map((operator) => ( - - ))} -
-
- ) : selectedOperator === "Boolean Expression" ? ( -
-

- Boolean Expression Operators -

-
- {["$and", "$not", "$or"].map((operator) => ( - - ))} -
-
- ) : selectedOperator === "Comparison Query" ? ( -
-

- Comparison Query Operators -

-
- {[ - "$cmp", - "$eq", - "$gt", - "$gte", - "$in", - "$lt", - "$lte", - "$ne", - "$nin", - ].map((operator) => ( - - ))} -
-
- ) : selectedOperator === "Conditional Expression" ? ( -
-

- Conditional Expression Operators -

-
- {["$cond", "$ifNull", "$switch"].map((operator) => ( - - ))} -
-
- ) : selectedOperator === "Date Expression" ? ( -
-

- Date Expression Operators -

-
- {[ - "$dateAdd", - "$dateDiff", - "$dateFromParts", - "$dateFromString", - "$dateSubtract", - "$dateToParts", - "$dateToString", - "$dayOfMonth", - "$dayOfWeek", - "$dayOfYear", - "$hour", - "$isoDayOfWeek", - "$isoWeek", - "$isoWeekYear", - "$millisecond", - "$minute", - "$month", - "$second", - "$week", - "$year" - ].map((operator) => ( - - ))} -
-
- ) : selectedOperator === "Data Size" ? ( -
-

- Data Size Operators -

-
- {["$binarysize", "$bsonsize"].map((operator) => ( - - ))} -
-
- ) : selectedOperator === "Element Query" ? ( -
-

- Element Query Operators -

-
- {["$exists", "$type"].map((operator) => ( - - ))} -
-
- ) : selectedOperator === "Evaluation Query" ? ( -
-

- Evaluation Query Operators -

-
- {["$expr", "$mod", "$regex", "$text"].map((operator) => ( - - ))} -
-
- ) : selectedOperator === "Field Update" ? ( -
-

- Field Update Operators -

-
- {[ - "$currentDate", - "$inc", - "$max", - "$min", - "$mul", - "$rename", - "$set", - "$setOnInsert", - "$unset" - ].map((operator) => ( - - ))} -
-
- ) : selectedOperator === "Geospatial" ? ( -
-

- Geospatial Operators -

-
- {[ - "$box", - "$center", - "$centerSphere", - "$geoIntersects", - "$geoWithin", - "$geometry", - "$maxDistance", - "$minDistance", - "$near", - "$nearSphere", - "$polygon", - ].map((operator) => ( - - ))} -
-
- ) : selectedOperator === "Literal Expression" ? ( -
-

- Geospatial Operators -

-
- {[ - "$literal", - ].map((operator) => ( - - ))} -
-
- ) : selectedOperator === "Logical Query" ? ( -
-

- Logical Query Operators -

-
- {["$and", "$nor", "$not", "$or"].map((operator) => ( - - ))} -
-
- ) : selectedOperator === "Miscellaneous" ? ( -
-

- Miscellaneous Operators -

-
- {["$getField", "$sampleRate", "$comment", "$natural", "$rand"].map((operator) => ( - - ))} -
-
- ) : selectedOperator === "Object Expression" ? ( -
-

- Object Expression Operators -

-
- {["$mergeObjects", "$objectToArray", "$setField"].map( - (operator) => ( - - ), - )} -
-
- ) : selectedOperator === "Projection" ? ( -
-

- Projection Operators -

-
- {["$elemMatch", "$meta", "$slice"].map((operator) => ( - - ))} -
-
- ) : selectedOperator === "Timestamp Expression" ? ( -
-

- Timestamp Expression Operators -

-
- {["$tsSecond", "$tsIncrement"].map((operator) => ( - - ))} -
-
- ) : selectedOperator === "Set Expression" ? ( -
-

- Set Expression Operators -

-
- {[ - "$allElementsTrue", - "$anyElementTrue", - "$setDifference", - "$setEquals", - "$setIntersection", - "$setIsSubset", - "$setUnion" - ].map((operator) => ( - - ))} -
-
- ) : selectedOperator === "Variable Expression" ? ( -
-

- Variable Expression Operators -

-
- {["$let"].map((operator) => ( - - ))} -
-
- ) : selectedOperator === "Window" ? ( -
-

- Window Operators -

-
- {[ - "$shift", - "$covariancePop", - "covarianceSamp", - "$denseRank", - "$derivative", - "$documentNumber", - "$expMovingAvg", - "$integral", - "$linearFill", - "$locf", - "$rank" - ].map((operator) => ( - - ))} -
-
- ) : ( - /* Sample content for other operators */ -
-
-

- Overview -

-

- The {selectedOperator} category provides powerful - operators for document manipulation and querying. These - operators are essential for building complex database - operations and data transformations. -

-
-

- Example usage: -

- - db.collection.find( - {`{${selectedOperator.toLowerCase()}_operator: value}`}) - -
-
- -
-

- Common Operators -

-
- {[1, 2, 3].map((i) => ( -
-

- Operator {i} -

-

- Description of operator {i} functionality and use - cases. -

-
- - {`{ $operator${i}: { field: "value" } }`} - -
-
- ))} -
-
- -
-

- Best Practices -

-
    -
  • - - - Always validate input parameters before using{" "} - {selectedOperator.toLowerCase()} operators - -
  • -
  • - - - Consider performance implications when chaining - multiple operators - -
  • -
  • - - - Use appropriate indexing strategies to optimize{" "} - {selectedOperator.toLowerCase()} queries - -
  • -
-
-
- )} -
-
-
-
- ); - } - - if (currentPage === "architecture") { - return ( -
- {/* Background elements */} -
-
-
-
-
- -
- {/* Header with back button */} -
-
- -
- - {/* Main Content */} -
-
-

- DocumentDB Technical Architecture -

- - {/* JSON Construction Graphic */} -
- {/* Main container with glow effect */} -
- {/* Background glow */} -
- - {/* JSON Document container */} -
- {/* JSON Content */} -
-
{`{`}
-
- "status":{" "} - "building" - , -
-
- "progress":{" "} - 75 - , -
-
- "architecture":{" "} - {`{`} -
-
- "layers":{" "} - [ -
-
- "DocumentDB API", -
-
- "DocumentDB Core", -
-
- "DocumentDB Gateway" -
-
- ], -
-
- "coming_soon":{" "} - true -
-
- {`}`} - , -
-
- "tools":{" "} - [ - - 🔨 - - - ⚙️ - - - 🔧 - - ] -
-
{`}`}
-
- - {/* Construction helmet on JSON */} -
- 👷‍♂️ -
- - {/* Construction cone */} -
- 🚧 -
- - {/* Blueprints */} -
- 📐 -
- - {/* Floating construction particles */} -
-
-
- - {/* Progress indicator */} -
-
-
-
-
-
-
-
-
-
- -

- We're building something amazing! The technical architecture - documentation is coming soon. -

- -
-
-
-
-
-
-
-
-
-
- ); - } + const articleContent = getArticleContent(); return (
@@ -2439,139 +40,88 @@ for eachDocument in results:
{/* Header */}
-

- Documentation +

+ {articleContent.landing.title}

- Everything you need to build with DocumentDB - from getting started - guides to deep architectural insights + {articleContent.landing.description}

- {/* Documentation Grid - Updated to 2x2 layout with 25% larger blocks */} + {/* Documentation Grid */}
- {/* Getting Started */} -
setCurrentPage("getting-started")} - > -
-
-
-
- - - -
-

- Getting Started with DocumentDB -

-
-
-
- - {/* API Reference */} -
setCurrentPage("api-reference")} - > -
-
-
-
- - - -
-

- API Reference Docs -

-
-
-
- - {/* PostgreSQL Extension API */} -
setCurrentPage("postgres-api")} - > -
-
-
-
- - - -
-

- Postgres Extension API Docs -

-
-
-
- - {/* Architecture */} -
setCurrentPage("architecture")} - > -
-
-
-
- - - -
-

- Architecture under the hood -

-
-
-
+ {articleContent.landing.links.map((item) => { + const isReference = item.link === "/docs/reference"; + + if (isReference) { + return ( + +
+
+
+
+ + + +
+

+ {item.title} +

+
+
+ + ); + } + + return ( + +
+
+
+
+ + + +
+

+ {item.title} +

+
+
+ + ); + })}
); -} +} \ No newline at end of file diff --git a/app/docs/reference/[type]/[category]/[name]/page.tsx b/app/docs/reference/[type]/[category]/[name]/page.tsx index 1cc9eda..a677e77 100644 --- a/app/docs/reference/[type]/[category]/[name]/page.tsx +++ b/app/docs/reference/[type]/[category]/[name]/page.tsx @@ -1,17 +1,25 @@ -import Link from 'next/link'; import { notFound } from 'next/navigation'; -import Code from '../../../../../components/Code'; import Breadcrumb from '../../../../../components/Breadcrumb'; +import Markdown from '../../../../../components/Markdown'; import { getAllReferenceParams, getReferenceByPath } from '../../../../../services/referenceService'; import { getMetadata } from "../../../../../services/metadataService"; -import { kebabCase } from 'change-case'; export async function generateMetadata({ params }: { params: Promise<{ type: string; category: string; name: string }> }) { const { type, category, name } = await params; - const data = getReferenceByPath(type, category, name); + const decodedName = decodeURIComponent(name); + const data = getReferenceByPath(type, category, decodedName); + + if (!data) { + return getMetadata({ + title: 'Reference - DocumentDB MQL Reference', + description: '', + extraKeywords: ['reference', type, category, name] + }); + } + return getMetadata({ - title: `${data?.name || 'Reference'} - DocumentDB MQL Reference`, - description: data?.description || data?.summary || '', + title: `${data.frontmatter.title || name} - DocumentDB MQL Reference`, + description: data.frontmatter.description || '', extraKeywords: ['reference', type, category, name] }); } @@ -22,153 +30,22 @@ export async function generateStaticParams(): Promise<{ type: string; category: export default async function ReferencePage({ params }: { params: Promise<{ type: string; category: string; name: string }> }) { const { type, category, name } = await params; - const data = getReferenceByPath(type, category, name); + const decodedName = decodeURIComponent(name); + const data = getReferenceByPath(type, category, decodedName); if (!data) { notFound(); } + const pageTitle = data.frontmatter.title || name; + const pageDescription = data.frontmatter.description; + return (
- - {/* Header */} -
-

- {data.name} -

-
-

- {data.description} -

- {data.summary && ( -
-

{data.summary}

-
- )} -
- - {/* Syntax Section */} - {data.syntax && data.syntax.length > 0 && ( -
- -

Syntax

-
- -
-
- )} - - {/* Parameters Section */} - {data.parameters && data.parameters.length > 0 && ( -
- -

Parameters

-
- {data.parameters.map((param, index) => ( -
-
- {param.name} - {param.type ? - {param.type} - : <>} - {param.required && ( - - required - - )} -
- {param.description && ( -

{param.description}

- )} -
- ))} -
-
- )} - - {/* Examples Section */} - {data.examples && ( -
- -

Examples

- - {/* Sample Data */} - {data.examples.sample && ( -
- )} - - {/* Example Items */} - {data.examples.items && data.examples.items.length > 0 && ( - - )} -
- )} - - {/* Related Section */} - {data.related && data.related.length > 0 && ( -
- -

Related

-
-
    - {data.related.map((rel, index) => ( -
  • - - - - - {rel.reference} - -
  • - ))} -
-
-
- )} + + + {/* Markdown Content */} +
); -} +} \ No newline at end of file diff --git a/app/docs/reference/[type]/[category]/page.tsx b/app/docs/reference/[type]/[category]/page.tsx index 3f68527..6ec5618 100644 --- a/app/docs/reference/[type]/[category]/page.tsx +++ b/app/docs/reference/[type]/[category]/page.tsx @@ -2,8 +2,9 @@ import Link from 'next/link'; import { notFound } from 'next/navigation'; import ReferenceTable from '../../../../components/Grid'; import Breadcrumb from '../../../../components/Breadcrumb'; +import Markdown from '../../../../components/Markdown'; import { getReferencesByTypeGroupedByCategory, getAllTypeCategoryCombinations, isValidTypeCategoryCombination, getCategoryDescription } from '../../../../services/referenceService'; -import { getMetadata } from "../../../../services/metadataService"; +import { getMetadata, sanitizeMarkdown } from "../../../../services/metadataService"; import pluralize from 'pluralize'; import { capitalCase } from 'change-case'; @@ -17,7 +18,7 @@ export async function generateMetadata({ params }: { params: Promise<{ type: str const description = getCategoryDescription(type, category); return getMetadata({ title: `${title} - DocumentDB MQL Reference`, - description: description || '', + description: await sanitizeMarkdown(description), extraKeywords: ['reference', type, category] }); } @@ -42,9 +43,9 @@ export default async function CommandReferencePage({ params }: { params: Promise
{description && ( -

- {description} -

+
+ +
)}
diff --git a/app/docs/reference/[type]/page.tsx b/app/docs/reference/[type]/page.tsx index d43991b..3cb97e4 100644 --- a/app/docs/reference/[type]/page.tsx +++ b/app/docs/reference/[type]/page.tsx @@ -2,16 +2,17 @@ import Link from 'next/link'; import { notFound } from 'next/navigation'; import ReferenceTable from '../../../components/Grid'; import Breadcrumb from '../../../components/Breadcrumb'; +import Markdown from '../../../components/Markdown'; import { getReferencesByTypeGroupedByCategory, getTypeDescription } from '../../../services/referenceService'; -import { getMetadata } from "../../../services/metadataService"; +import { getMetadata, sanitizeMarkdown } from "../../../services/metadataService"; import pluralize from 'pluralize'; import { capitalCase } from 'change-case'; -const allowed_types = ['operator', 'command']; +const allowed_types = ['operators', 'commands']; export const generateStaticParams = async (): Promise<{ type: string }[]> => [ - { type: 'operator' }, - { type: 'command' } + { type: 'operators' }, + { type: 'commands' } ]; export async function generateMetadata({ params }: { params: Promise<{ type: string }> }) { @@ -20,7 +21,7 @@ export async function generateMetadata({ params }: { params: Promise<{ type: str const description = getTypeDescription(type); return getMetadata({ title: `${title} - DocumentDB MQL Reference`, - description: description || '', + description: await sanitizeMarkdown(description), extraKeywords: ['reference', type] }); } @@ -41,9 +42,9 @@ export default async function CommandReferencePage({ params }: { params: Promise
{description && ( -

- {description} -

+
+ +
)}
{Object.entries(grouped).map(([category, items]) => ( diff --git a/app/docs/reference/layout.tsx b/app/docs/reference/layout.tsx index b54a3a4..679440f 100644 --- a/app/docs/reference/layout.tsx +++ b/app/docs/reference/layout.tsx @@ -5,8 +5,8 @@ import { getReferencesGroupedByTypeAndCategory } from '../../services/referenceS import { getMetadata } from "../../services/metadataService"; export const metadata: Metadata = getMetadata({ - title: 'DocumentDB MQL Reference', - description: 'MongoDB Query Language (MQL) reference for DocumentDB. DocumentDB is a powerful, scalable open-source database solution with MongoDB query compatibility.', + title: 'DocumentDB MQL Reference', + description: 'MongoDB Query Language (MQL) reference for DocumentDB.', extraKeywords: ['reference'] }); @@ -18,7 +18,7 @@ export default function ReferenceLayout({ const groupedReferences = getReferencesGroupedByTypeAndCategory(); return ( -
+
{/* Background elements */}
@@ -28,9 +28,9 @@ export default function ReferenceLayout({ style={{ animationDelay: "1.5s" }} >
-
-
-
+
+
+
-
+
{children}
diff --git a/app/docs/reference/page.tsx b/app/docs/reference/page.tsx index 317feed..3ff1963 100644 --- a/app/docs/reference/page.tsx +++ b/app/docs/reference/page.tsx @@ -1,12 +1,24 @@ import Link from 'next/link'; import ReferenceTable from '../../components/Grid'; import Breadcrumb from '../../components/Breadcrumb'; -import { getReferencesGroupedByTypeAndCategory } from '../../services/referenceService'; +import Markdown from '../../components/Markdown'; +import { getReferencesGroupedByTypeAndCategory, getReferenceDescription } from '../../services/referenceService'; +import { getMetadata, sanitizeMarkdown } from '../../services/metadataService'; import pluralize from 'pluralize'; import { capitalCase } from 'change-case'; +export async function generateMetadata() { + const description = getReferenceDescription(); + return getMetadata({ + title: 'DocumentDB MQL Reference', + description: await sanitizeMarkdown(description), + extraKeywords: ['reference'] + }); +} + export default function Home() { const grouped = getReferencesGroupedByTypeAndCategory(); + const description = getReferenceDescription(); return (
@@ -15,9 +27,11 @@ export default function Home() { MongoDB Query Language (MQL)
-

- Explore the essential MongoDB Query Language (MQL) operators and commands available in this reference. Each entry includes a brief description and usage details to help you build effective queries and manage your database. -

+ {description && ( +
+ +
+ )}
{Object.entries(grouped).map(([type, categories]) => { return ( diff --git a/app/services/articleService.ts b/app/services/articleService.ts index f8a8d78..0da835a 100644 --- a/app/services/articleService.ts +++ b/app/services/articleService.ts @@ -21,7 +21,36 @@ export function getArticleNavigation(section: string): Link[] { } const fileContents = fs.readFileSync(navPath, 'utf8'); - return yaml.load(fileContents) as Link[]; + const rawLinks = yaml.load(fileContents) as Link[]; + + // Transform Markdown file links to published relative URIs + return rawLinks.map(link => { + // Convert .md file references to proper URIs + // e.g., "index.md" -> "/docs/section" + // e.g., "nodejs-setup.md" -> "/docs/section/nodejs-setup" + let transformedLink = link.link; + + if (transformedLink.endsWith('.md')) { + const filename = transformedLink.replace('.md', ''); + if (filename === 'index') { + transformedLink = `/docs/${section}`; + } else { + transformedLink = `/docs/${section}/${filename}`; + } + } + + return { + ...link, + link: transformedLink, + // Recursively transform children if they exist + children: link.children?.map(child => ({ + ...child, + link: child.link.endsWith('.md') + ? `/docs/${section}/${child.link.replace('.md', '')}` + : child.link + })) + }; + }); } export function getMarkdownContent(section: string, file: string = 'index'): string { diff --git a/app/services/metadataService.ts b/app/services/metadataService.ts index f88ed07..b645edf 100644 --- a/app/services/metadataService.ts +++ b/app/services/metadataService.ts @@ -1,4 +1,20 @@ import { Metadata } from "next"; +import { remark } from "remark"; +import strip from "strip-markdown"; + +/** + * Sanitizes Markdown content to plain text for SEO purposes + * Removes Markdown formatting, code blocks, and special characters + */ +export const sanitizeMarkdown = async (markdown: string | undefined): Promise => { + if (!markdown) return ''; + + let processor = remark().use(strip).process(markdown); + + let output: string = String(await processor); + + return output.trim(); +}; export const getMetadata = ({ title, description, extraKeywords = [] }: { title: string, description: string, extraKeywords?: string[] }): Metadata => ({ keywords: [...getBaseKeywords(), ...extraKeywords], diff --git a/app/services/referenceService.ts b/app/services/referenceService.ts index 94418a1..f1785e1 100644 --- a/app/services/referenceService.ts +++ b/app/services/referenceService.ts @@ -1,36 +1,55 @@ import fs from 'fs'; import path from 'path'; -import yaml from 'js-yaml'; -import type { Reference } from '../types/Reference'; +import matter from 'gray-matter'; import type { Page } from '../types/Page'; -import { Content } from '../types/Content'; export type ReferencePage = Page & { type: string; category?: string }; -function getContentMetadata(): Content { - const contentPath = path.join(process.cwd(), 'reference', 'content.yml'); - return yaml.load(fs.readFileSync(contentPath, 'utf8')) as Content; -} +export type ReferenceArticle = { + content: string; + frontmatter: { + title?: string; + description?: string; + type: string; + category: string; + [key: string]: any; + }; + type: string; + category: string; + name: string; +}; function getAllReferences(): ReferencePage[] { const root = path.join(process.cwd(), 'reference'); const files: string[] = []; + function walk(dir: string) { for (const entry of fs.readdirSync(dir, { withFileTypes: true })) { - if (entry.isDirectory()) walk(path.join(dir, entry.name)); - else if (entry.name.endsWith('.yml') && entry.name !== 'content.yml') files.push(path.join(dir, entry.name)); + if (entry.isDirectory()) { + walk(path.join(dir, entry.name)); + } else if (entry.name.endsWith('.md')) { + files.push(path.join(dir, entry.name)); + } } } + walk(root); + return files.map(file => { - const data = yaml.load(fs.readFileSync(file, 'utf8')) as Reference; - const slug = path.relative(root, file).replace(/\\/g, '/').replace(/\.yml$/, ''); + const fileContents = fs.readFileSync(file, 'utf8'); + const { data: frontmatter } = matter(fileContents); + const slug = path.relative(root, file).replace(/\\/g, '/').replace(/\.md$/, ''); + + // Extract filename for the name parameter + const parts = slug.split('/'); + const filename = parts[parts.length - 1]; + return { - name: data.name || slug, - description: data.description || '', + name: frontmatter.title || filename, + description: frontmatter.description || '', reference: slug, - type: data.type, - category: (data as any).category || '', + type: frontmatter.type || '', + category: frontmatter.category || 'Uncategorized', }; }); } @@ -38,34 +57,44 @@ function getAllReferences(): ReferencePage[] { export function getReferencesGroupedByTypeAndCategory() { const refs = getAllReferences(); const grouped: Record> = {}; + for (const ref of refs) { // Skip items with undefined type if (!ref.type) continue; if (!grouped[ref.type]) grouped[ref.type] = {}; - if (!grouped[ref.type][ref.category || 'Uncategorized']) grouped[ref.type][ref.category || 'Uncategorized'] = []; + if (!grouped[ref.type][ref.category || 'Uncategorized']) { + grouped[ref.type][ref.category || 'Uncategorized'] = []; + } grouped[ref.type][ref.category || 'Uncategorized'].push(ref); } + return grouped; } export function getReferencesByTypeGroupedByCategory(type: string) { const refs = getAllReferences().filter(r => r.type === type); const grouped: Record = {}; + for (const ref of refs) { - if (!grouped[ref.category || 'Uncategorized']) grouped[ref.category || 'Uncategorized'] = []; + if (!grouped[ref.category || 'Uncategorized']) { + grouped[ref.category || 'Uncategorized'] = []; + } grouped[ref.category || 'Uncategorized'].push(ref); } + return grouped; } export function getAllTypeCategoryCombinations(): { type: string; category: string }[] { const refs = getAllReferences(); const combinations = new Set(); + for (const ref of refs) { const category = ref.category || 'Uncategorized'; combinations.add(`${ref.type}:${category}`); } + return Array.from(combinations).map(combo => { const [type, category] = combo.split(':'); return { type, category }; @@ -79,6 +108,7 @@ export function isValidTypeCategoryCombination(type: string, category: string): export function getAllReferenceParams(): { type: string; category: string; name: string }[] { const refs = getAllReferences(); + return refs.map(ref => { // Extract just the filename (last part of the path) without extension const parts = ref.reference.split('/'); @@ -87,16 +117,16 @@ export function getAllReferenceParams(): { type: string; category: string; name: return { type: ref.type, category: ref.category || 'Uncategorized', - name: filename // Use the filename, not the name field + name: filename }; }); } -export function getReferenceByPath(type: string, category: string, name: string): Reference | null { +export function getReferenceByPath(type: string, category: string, name: string): ReferenceArticle | null { const root = path.join(process.cwd(), 'reference'); const refs = getAllReferences(); - // Match by type, category, and filename (not name) + // Match by type, category, and filename const matchingRef = refs.find(r => { const parts = r.reference.split('/'); const filename = parts[parts.length - 1]; @@ -108,23 +138,56 @@ export function getReferenceByPath(type: string, category: string, name: string) if (!matchingRef) return null; - const filePath = path.join(root, `${matchingRef.reference}.yml`); + const filePath = path.join(root, `${matchingRef.reference}.md`); if (!fs.existsSync(filePath)) return null; - const data = yaml.load(fs.readFileSync(filePath, 'utf8')) as Reference; - return data; + const fileContents = fs.readFileSync(filePath, 'utf8'); + const { data: frontmatter, content } = matter(fileContents); + + return { + content, + frontmatter: { + title: frontmatter.title, + description: frontmatter.description, + type: frontmatter.type || type, + category: frontmatter.category || category, + ...frontmatter + }, + type: frontmatter.type || type, + category: frontmatter.category || category, + name: name + }; } export function getTypeDescription(type: string): string | undefined { - const content = getContentMetadata(); - const typeEntry = content.find(entry => entry.type === type); - return typeEntry?.description; + const root = path.join(process.cwd(), 'reference'); + const metadataPath = path.join(root, type, '_metadata.description.md'); + + if (fs.existsSync(metadataPath)) { + return fs.readFileSync(metadataPath, 'utf8').trim(); + } + + return undefined; } export function getCategoryDescription(type: string, category: string): string | undefined { - const content = getContentMetadata(); - const typeEntry = content.find(entry => entry.type === type); - if (!typeEntry) return undefined; - const categoryEntry = typeEntry.categories.find(cat => cat.category === category); - return categoryEntry?.description; + const root = path.join(process.cwd(), 'reference'); + const metadataPath = path.join(root, type, category, '_metadata.description.md'); + + if (fs.existsSync(metadataPath)) { + return fs.readFileSync(metadataPath, 'utf8').trim(); + } + + return undefined; } + +export function getReferenceDescription(): string | undefined { + const root = path.join(process.cwd(), 'reference'); + const metadataPath = path.join(root, '_metadata.description.md'); + + if (fs.existsSync(metadataPath)) { + return fs.readFileSync(metadataPath, 'utf8').trim(); + } + + return undefined; +} \ No newline at end of file diff --git a/app/types/Reference.ts b/app/types/Reference.ts deleted file mode 100644 index 4954aa1..0000000 --- a/app/types/Reference.ts +++ /dev/null @@ -1,32 +0,0 @@ -export type Reference = { - type: 'operator' | 'command'; - name: string; - description: string; - summary?: string; - syntax: string; - parameters: Array<{ - name: string; - type: 'object' | 'string' | 'number' | 'pattern'; - required: boolean; - description?: string; - }>; - examples: { - sample?: { - set: 'products' | 'stores' | 'employees'; - filter: string; - }; - items: Array<{ - title: string; - explanation?: string; - description: string; - query: string; - output?: { - devlang?: 'bson' | 'json' | 'plaintext'; - value: string; - }; - }>; - }; - related?: Array<{ - reference: string; - }>; -}; \ No newline at end of file diff --git a/articles/architecture/index.md b/articles/architecture/index.md deleted file mode 100644 index d41b069..0000000 --- a/articles/architecture/index.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Architecture under the hood -description: Deep dive into DocumentDB's internal architecture, data structures, query processing, storage engine design, and distributed systems. -layout: coming-soon ---- - -We're building something amazing! The technical architecture documentation is coming soon. diff --git a/articles/architecture/navigation.yml b/articles/architecture/navigation.yml deleted file mode 100644 index 7c5f20f..0000000 --- a/articles/architecture/navigation.yml +++ /dev/null @@ -1,2 +0,0 @@ -- title: Architecture under the hood - link: /docs/architecture \ No newline at end of file diff --git a/articles/content.yml b/articles/content.yml index 7c126f9..8514350 100644 --- a/articles/content.yml +++ b/articles/content.yml @@ -3,10 +3,12 @@ landing: description: Everything you need to build with DocumentDB - from getting started guides to deep architectural insights links: - title: Getting Started with DocumentDB - link: /docs/quickstart - - title: API Reference Docs + link: /docs/getting-started + - title: API Reference link: /docs/reference - - title: Postgres Extension API Docs - link: /docs/postgresql + - title: Postgres Extension API + link: /docs/postgres-api + - title: DocumentDB Local + link: /docs/documentdb-local - title: Architecture under the hood link: /docs/architecture \ No newline at end of file diff --git a/articles/postgresql/functions.md b/articles/postgresql/functions.md deleted file mode 100644 index 1eb9e37..0000000 --- a/articles/postgresql/functions.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: Functions -description: Complete reference for PostgreSQL extension functions including CRUD operations, collection management, user management, and utilities. ---- - -Comprehensive documentation for PostgreSQL extension functions and their usage patterns. - -## Table of Contents - -### CRUD Operations - -| Function | Documentation | -|----------|---------------| -| `aggregate_cursor_first_page()` | [documentdb/wiki/Functions#aggregate_cursor_first_page](https://github.com/microsoft/documentdb/wiki/Functions#aggregate_cursor_first_page) -| `count_query()` | [documentdb/wiki/Functions#count_query](https://github.com/microsoft/documentdb/wiki/Functions#count_query) -| `cursor_get_more()` | [documentdb/wiki/Functions#cursor_get_more](https://github.com/microsoft/documentdb/wiki/Functions#cursor_get_more) -| `delete()` | [documentdb/wiki/Functions#delete](https://github.com/microsoft/documentdb/wiki/Functions#delete) -| `distinct_query()` | [documentdb/wiki/Functions#distinct_query](https://github.com/microsoft/documentdb/wiki/Functions#distinct_query) -| `find_and_modify()` | [documentdb/wiki/Functions#find_and_modify](https://github.com/microsoft/documentdb/wiki/Functions#find_and_modify) -| `find_cursor_first_page()` | [documentdb/wiki/Functions#find_cursor_first_page](https://github.com/microsoft/documentdb/wiki/Functions#find_cursor_first_page) -| `insert()` | [documentdb/wiki/Functions#insert](https://github.com/microsoft/documentdb/wiki/Functions#insert) -| `insert_one()` | [documentdb/wiki/Functions#insert_one](https://github.com/microsoft/documentdb/wiki/Functions#insert_one) -| `list_collections_cursor_first_page()` | [documentdb/wiki/Functions#list_collections_cursor_first_page](https://github.com/microsoft/documentdb/wiki/Functions#list_collections_cursor_first_page) -| `list_indexes_cursor_first_page()` | [documentdb/wiki/Functions#list_indexes_cursor_first_page](https://github.com/microsoft/documentdb/wiki/Functions#list_indexes_cursor_first_page) -| `update()` | [documentdb/wiki/Functions#update](https://github.com/microsoft/documentdb/wiki/Functions#update) - -### Collection Management - -| | Documentation | -| --- | --- | -| `coll_mod()` | [documentdb/wiki/Functions#coll_mod](https://github.com/microsoft/documentdb/wiki/Functions#coll_mod) -| `create_collection()` | [documentdb/wiki/Functions#create_collection](https://github.com/microsoft/documentdb/wiki/Functions#create_collection) -| `create_collection_view()` | [documentdb/wiki/Functions#create_collection_view](https://github.com/microsoft/documentdb/wiki/Functions#create_collection_view) -| `drop_collection()` | [documentdb/wiki/Functions#drop_collection](https://github.com/microsoft/documentdb/wiki/Functions#drop_collection) -| `drop_database()` | [documentdb/wiki/Functions#drop_database](https://github.com/microsoft/documentdb/wiki/Functions#drop_database) -| `rename_collection()` | [documentdb/wiki/Functions#rename_collection](https://github.com/microsoft/documentdb/wiki/Functions#rename_collection) -| `shard_collection()` | [documentdb/wiki/Functions#shard_collection](https://github.com/microsoft/documentdb/wiki/Functions#shard_collection) - -### User Management - -| | Documentation | -| --- | --- | -| `create_user()` | [documentdb/wiki/Functions#create_user](https://github.com/microsoft/documentdb/wiki/Functions#create_user) -| `drop_user()` | [documentdb/wiki/Functions#drop_user](https://github.com/microsoft/documentdb/wiki/Functions#drop_user) -| `update_user()` | [documentdb/wiki/Functions#update_user](https://github.com/microsoft/documentdb/wiki/Functions#update_user) -| `users_info()` | [documentdb/wiki/Functions#users_info](https://github.com/microsoft/documentdb/wiki/Functions#users_info) - -### Utility Functions - -| Function | Documentation | -| --- | --- | -| `binary_extended_version()` | [documentdb/wiki/Functions#binary_extended_version](https://github.com/microsoft/documentdb/wiki/Functions#binary_extended_version) -| `binary_version()` | [documentdb/wiki/Functions#binary_version](https://github.com/microsoft/documentdb/wiki/Functions#binary_version) - diff --git a/articles/postgresql/index.md b/articles/postgresql/index.md deleted file mode 100644 index fb97c58..0000000 --- a/articles/postgresql/index.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: Components -description: Learn about pg_documentdb_core and pg_documentdb_api PostgreSQL extensions that enable BSON support and document operations in Postgres. ---- - -## pg_documentdb_core - -pg_documentdb_core is a PostgreSQL extension that introduces BSON datatype support and operations for native Postgres. This core component is essential for enabling document-oriented NoSQL capabilities within a PostgreSQL environment. It provides the foundational data structures and functions required to handle BSON data types, which are crucial for performing CRUD operations on documents. - -### Key Features - -- **BSON Datatype Support:** Adds BSON (Binary JSON) datatype to PostgreSQL, allowing for efficient storage and manipulation of JSON-like documents. - -- **Native Operations:** Implements native PostgreSQL operations for BSON data, ensuring seamless integration and performance. - -- **Extensibility:** Serves as the core building block for additional functionalities and extensions within the DocumentDB ecosystem. - -## pg_documentdb_api - -pg_documentdb_api is the public API surface for DocumentDB, providing CRUD functionality on documents stored in the database. This component leverages the capabilities of pg_documentdb_core to offer a comprehensive set of APIs for managing document data within PostgreSQL. - -### Key Features - -- **CRUD Operations:** Provides a rich set of APIs for creating, reading, updating, and deleting documents. - -- **Advanced Queries:** Supports complex queries, including full-text searches, geospatial queries, and vector embeddings. - -- **Integration:** Works seamlessly with pg_documentdb_core to deliver robust document management capabilities. - -### Usage - -To use pg_documentdb_api, you need to have pg_documentdb_core installed and configured in your PostgreSQL environment. Once set up, you can leverage the APIs provided by pg_documentdb_api to perform various document operations. - diff --git a/articles/postgresql/navigation.yml b/articles/postgresql/navigation.yml deleted file mode 100644 index 65d35ca..0000000 --- a/articles/postgresql/navigation.yml +++ /dev/null @@ -1,4 +0,0 @@ -- title: Components - link: /docs/postgresql -- title: Functions - link: /docs/postgresql/functions \ No newline at end of file diff --git a/articles/quickstart/extension.md b/articles/quickstart/extension.md deleted file mode 100644 index 64ba6d6..0000000 --- a/articles/quickstart/extension.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: Visual Studio Code Quick Start -description: Get started with DocumentDB using the VS Code extension. Connect to databases, create collections, and manage documents seamlessly. ---- - -Quick start guide for vs code extension quick start. - -Get started with DocumentDB using the Visual Studio Code extension for a seamless development experience. - -## Prerequisites - -- Visual Studio Code installed -- Docker Desktop installed and running -- Basic familiarity with document databases -- Git installed (for cloning the repository) - -## Installing the Extension - -1. Open VS Code -1. Navigate to the Extensions marketplace (`Ctrl+Shift+X` or `Cmd+Shift+X`) -1. Search for "DocumentDB for VS Code" -1. Click Install -1. Reload VS Code if prompted - -## Setting Up Your First Database - -### 1. Creating a new DocumentDB instance - -```bash -docker pull ghcr.io/microsoft/documentdb/documentdb-local:latest -docker tag ghcr.io/microsoft/documentdb/documentdb-local:latest documentdb -docker run -dt -p 10260:10260 --name documentdb-container documentdb --username --password -docker image rm -f ghcr.io/microsoft/documentdb/documentdb-local:latest || echo "No existing documentdb image to remove" -``` - -> [!NOTE] -> Replace `` and `` with your desired credentials. You must set these when creating the container for authentication to work. - -> [!IMPORTANT] -> Port `10260` is used by default in these instructions to avoid conflicts with other local database services. You can use port `27017` (the standard MongoDB port) or any other available port if you prefer. If you do, be sure to update the port number in both your `docker run` command and your connection string accordingly. - -### 2. Connecting to your database - -- Click the DocumentDB icon in the VS Code sidebar -- Click "Add New Connection" -- On the navigation bar, click on "Connection String" -- Paste your connection string: - -``` -mongodb://:@localhost:10260/?tls=true&tlsAllowInvalidCertificates=true&authMechanism=SCRAM-SHA-256 -``` - -### 3. Creating your first database and collection - -- Click on the drop-down next to your local connection and select "Create Database..." -- Enter database name and confirm -- Click on the drop-down next to your created database and select "Create Collection..." -- Enter collection name and confirm -- Repeat for every database and collection you wish to create under your connection - -## Working with Documents - -### 1. Creating documents - -- Use the Table View for quick data entry -- Use the Tree View for hierarchical data exploration -- Use the JSON View for detailed document structure - -```json -{ - "name": "Test Document", - "type": "example", - "created_at": new Date() -} -``` - -### 2. Using the document explorer - -- Browse documents in multiple views: - - Table View for quick insights - - Tree View for hierarchical exploration - - JSON View for detailed structure -- Use smooth pagination for large datasets - -## Import and Export - -### 1. Importing data - -- Click on the "Import" button on each collection -- Choose your JSON file -- Confirm import - -### 2. Exporting data - -- Export entire collections or query results using the "Export" button on each collection diff --git a/articles/quickstart/index.md b/articles/quickstart/index.md deleted file mode 100644 index 01b28c9..0000000 --- a/articles/quickstart/index.md +++ /dev/null @@ -1,127 +0,0 @@ ---- -title: Python Setup Guide -description: Setup and use DocumentDB with Python using PyMongo. Learn to connect, create databases, insert documents, and run aggregation queries. ---- - -Quick start guide for python setup guide. - -Learn how to set up and use DocumentDB with Python using the MongoDB Python driver (PyMongo). - -## Prerequisites - -- Python 3.7+ -- pip package manager -- Docker -- Git (for cloning the repository) - -## Step 1: Install Python - -```bash -pip install pymongo -``` - -## Step 2: Install optional dependencies - -```bash -pip install dnspython -``` - -## Step 3: Setup DocumentDB using Docker - -```bash -# Pull the latest DocumentDB Docker image -docker pull ghcr.io/microsoft/documentdb/documentdb-local:latest - -# Tag the image for convenience -docker tag ghcr.io/microsoft/documentdb/documentdb-local:latest documentdb - -# Run the container with your chosen username and password -docker run -dt -p 10260:10260 --name documentdb-container documentdb --username --password -docker image rm -f ghcr.io/microsoft/documentdb/documentdb-local:latest || echo "No existing documentdb image to remove" -``` - -> [!WARNING] -> During the transition to the Linux Foundation, Docker images may still be hosted on Microsoft's container registry. These will be migrated to the new DocumentDB organization as the transition completes. - -> [!NOTE] -> Replace `` and `` with your desired credentials. You must set these when creating the container for authentication to work. - -> [!IMPORTANT] -> Port `10260` is used by default in these instructions to avoid conflicts with other local database services. You can use port `27017` (the standard MongoDB port) or any other available port if you prefer. If you do, be sure to update the port number in both your `docker run` command and your connection string accordingly. - -## Step 4: Initialize the pymongo client with the credentials from the previous step - -```python -import pymongo -from pymongo import MongoClient - -# Create a MongoDB client and open a connection to DocumentDB -client = pymongo.MongoClient( - 'mongodb://:@localhost:10260/?tls=true&tlsAllowInvalidCertificates=true' -) -``` - -## Step 5: Create a database and collection - -```python -quickStartDatabase = client["quickStartDatabase"] -quickStartCollection = quickStartDatabase.create_collection("quickStartCollection") -``` - -## Step 6: Insert documents - -```python -# Insert a single document -quickStartCollection.insert_one({ - 'name': 'John Doe', - 'email': 'john@email.com', - 'address': '123 Main St, Anytown, USA', - 'phone': '555-1234' -}) - -# Insert multiple documents -quickStartCollection.insert_many([ - { - 'name': 'Jane Smith', - 'email': 'jane@email.com', - 'address': '456 Elm St, Othertown, USA', - 'phone': '555-5678' - }, - { - 'name': 'Alice Johnson', - 'email': 'alice@email.com', - 'address': '789 Oak St, Sometown, USA', - 'phone': '555-8765' - } -]) -``` - -## Step 7: Read documents - -```python -# Read all documents -for document in quickStartCollection.find(): - print(document) - -# Read a specific document -singleDocumentReadResult = quickStartCollection.find_one({'name': 'John Doe'}) -print(singleDocumentReadResult) -``` - -## Step 8: Run aggregation pipeline query - -```python -pipeline = [ - {'$match': {'name': 'Alice Johnson'}}, - {'$project': { - '_id': 0, - 'name': 1, - 'email': 1 - }} -] - -results = quickStartCollection.aggregate(pipeline) -print("Aggregation results:") -for eachDocument in results: - print(eachDocument) -``` diff --git a/articles/quickstart/mongodb-shell.md b/articles/quickstart/mongodb-shell.md deleted file mode 100644 index e77cc48..0000000 --- a/articles/quickstart/mongodb-shell.md +++ /dev/null @@ -1,172 +0,0 @@ ---- -title: MongoDB Shell Quick Start -description: Connect to DocumentDB using MongoDB shell (mongosh). Learn basic operations, querying, indexing, and database management commands. ---- - -Quick start guide for mongodb shell quick start. - -Get started with DocumentDB using the MongoDB shell for a familiar MongoDB-compatible experience. - -## Prerequisites - -- MongoDB Shell (mongosh) installed -- Docker Desktop installed and running -- Basic MongoDB knowledge -- Git installed (for cloning the repository) - -## Installation - -### 1. Setting up DocumentDB locally - -```bash -# Pull the latest DocumentDB Docker image -docker pull ghcr.io/microsoft/documentdb/documentdb-local:latest - -# Tag the image for convenience -docker tag ghcr.io/microsoft/documentdb/documentdb-local:latest documentdb - -# Run the container with your chosen username and password -docker run -dt -p 10260:10260 --name documentdb-container documentdb --username --password -docker image rm -f ghcr.io/microsoft/documentdb/documentdb-local:latest || echo "No existing documentdb image to remove" -``` - -> [!NOTE] -> Replace `` and `` with your desired credentials. You must set these when creating the container for authentication to work. - -> [!IMPORTANT] -> Port `10260` is used by default in these instructions to avoid conflicts with other local database services. You can use port `27017` (the standard MongoDB port) or any other available port if you prefer. If you do, be sure to update the port number in both your `docker run` command and your connection string accordingly. - -### 2. Starting the server - -```bash -# The server will be available at localhost:10260 (or your chosen port) -# You can verify the server is running using: -docker ps -``` - -## Connecting to DocumentDB - -Connection string format - -```bash -mongosh "mongodb://:@localhost:10260/?tls=true&tlsAllowInvalidCertificates=true" -``` - -## Basic Operations - -### 1. Creating databases and collections - -```javascript -// Create/switch to a database -use mydb - -// Create a collection -db.createCollection("users") - -// Create another collection -db.createCollection("logs") -``` - -### 2. Inserting documents - -```javascript -// Insert a single document -db.users.insertOne({ name: "John Doe", email: "john@example.com", created_at: new Date() }) - -// Insert multiple documents -db.users.insertMany([ - { name: "Jane Smith", email: "jane@example.com" }, - { name: "Bob Johnson", email: "bob@example.com" } -]) -``` - -### 3. Querying documents - -```javascript -// Find all documents -db.users.find() - -// Find with criteria -db.users.find({ name: "John Doe" }) - -// Find with projection -db.users.find({}, { name: 1, email: 1, _id: 0 }) - -// Complex queries -db.users.find( -{ $and: - [{ - created_at: { $gte: new Date("2025-01-01") } - }, - { - email: { $regex: "@example.com$" } - } - ] -}) -``` - -### 4. Updating documents - -```javascript -// Update a single document -db.users.updateOne({ name: "John Doe" }, { $set: { status: "active" } }) - -// Update multiple documents -db.users.updateMany({ email: { $regex: "@example.com$" } }, { $set: { domain: "example.com" } }) -``` - -### 5. Deleting documents - -```javascript -// Delete a single document -db.users.deleteOne({ name: "John Doe" }) - -// Delete multiple documents -db.users.deleteMany({ status: "inactive" }) -``` - -## Working with Indexes - -### 1. Understanding index types - -```javascript -// Available index types: -// - Single field -// - Compound -// - Multi-key -// - Text -// - Geospatial -// - Vector -``` - -### 2. Creating indexes - -```javascript -// Single field index -db.users.createIndex({ email: 1 }) - -// Compound index -db.users.createIndex({ name: 1, email: 1 }) -``` - -## Monitoring and Management - -### 1. Database statistics - -```javascript -// Get database stats -db.stats() - -// Get collection stats -db.users.stats() -``` - -### 2. Collection statistics - -```javascript -// Get collection size -db.users.dataSize() - -// Get index sizes -db.users.stats().indexSizes -``` diff --git a/articles/quickstart/navigation.yml b/articles/quickstart/navigation.yml deleted file mode 100644 index c2a3fed..0000000 --- a/articles/quickstart/navigation.yml +++ /dev/null @@ -1,6 +0,0 @@ -- title: Python Setup Guide - link: /docs/quickstart -- title: VS Code Extension Quick Start - link: /docs/quickstart/extension -- title: MongoDB Shell Quick Start - link: /docs/quickstart/mongodb-shell \ No newline at end of file diff --git a/content.config.json b/content.config.json new file mode 100644 index 0000000..da58990 --- /dev/null +++ b/content.config.json @@ -0,0 +1,37 @@ +{ + "sources": [ + { + "repository": "https://github.com/documentdb/docs", + "branch": "main", + "mappings": [ + { + "source": "api-reference", + "target": "reference" + }, + { + "source": "getting-started", + "target": "articles/getting-started" + }, + { + "source": "postgres-api", + "target": "articles/postgres-api" + }, + { + "source": "architecture", + "target": "articles/architecture" + }, + { + "source": "documentdb-local", + "target": "articles/documentdb-local" + } + ] + } + ], + "include": [ + "**/*.md", + "**/*.yml" + ], + "exclude": [ + "**/{readme,README}.md" + ] +} diff --git a/eslint.config.mjs b/eslint.config.mjs index 49c431f..65fd485 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,10 +1,15 @@ import { defineConfig } from "eslint/config"; +import nextPlugin from '@next/eslint-plugin-next' export default defineConfig([ { + plugins: { + '@next/next': nextPlugin, + }, rules: { semi: "error", "prefer-const": "error", + ...nextPlugin.configs.recommended.rules }, }, ]); diff --git a/package-lock.json b/package-lock.json index 2b31f8b..2c4772a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,29 +11,37 @@ "change-case": "^5.4.4", "gray-matter": "^4.0.3", "handlebars": "^4.7.8", - "js-yaml": "^4.1.0", - "next": "^15.5.4", + "js-yaml": "^4.1.1", + "next": "^15.5.9", "pluralize": "^8.0.0", - "react": "19.1.0", - "react-dom": "19.1.0", + "react": "^19.2.3", + "react-dom": "^19.2.3", "react-markdown": "^10.1.0", "react-syntax-highlighter": "^16.1.0", - "remark-gfm": "^4.0.1" + "remark": "^15.0.1", + "remark-gfm": "^4.0.1", + "strip-markdown": "^6.0.0" }, "devDependencies": { - "@eslint/eslintrc": "^3", - "@tailwindcss/postcss": "^4", + "@eslint/eslintrc": "^3.3.3", + "@next/eslint-plugin-next": "^16.1.1", + "@tailwindcss/postcss": "^4.1.18", "@types/js-yaml": "^4.0.9", - "@types/node": "^20", + "@types/minimatch": "^5.1.2", + "@types/node": "^20.19.27", "@types/pluralize": "^0.0.33", - "@types/react": "^19", - "@types/react-dom": "^19", + "@types/react": "^19.2.7", + "@types/react-dom": "^19.2.3", "@types/react-syntax-highlighter": "^15.5.13", - "autoprefixer": "^10.0.1", - "eslint": "^9", - "eslint-config-next": "15.5.4", - "tailwindcss": "^4", - "typescript": "^5" + "autoprefixer": "^10.4.23", + "eslint": "^9.39.2", + "eslint-config-next": "^15.5.4", + "ink": "^6.6.0", + "minimatch": "^10.1.1", + "serve": "^14.2.5", + "tailwindcss": "^4.1.18", + "tsx": "^4.21.0", + "typescript": "^5.9.3" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -45,6 +53,33 @@ "node": ">=0.10.0" } }, + "node_modules/@alcalzone/ansi-tokenize": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@alcalzone/ansi-tokenize/-/ansi-tokenize-0.2.2.tgz", + "integrity": "sha512-mkOh+Wwawzuf5wa30bvc4nA+Qb6DIrGWgBhRR/Pw4T9nsgYait8izvXkNyU78D6Wcu3Z+KUdwCmLCxlWjEotYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@alcalzone/ansi-tokenize/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/@alloc/quick-lru": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", @@ -99,6 +134,448 @@ "tslib": "^2.4.0" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", + "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz", + "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz", + "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz", + "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz", + "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz", + "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz", + "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz", + "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz", + "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz", + "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz", + "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz", + "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz", + "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz", + "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz", + "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz", + "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz", + "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz", + "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz", + "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz", + "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz", + "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz", + "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz", + "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz", + "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz", + "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz", + "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.9.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", @@ -129,13 +606,13 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", - "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/object-schema": "^2.1.6", + "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", "minimatch": "^3.1.2" }, @@ -143,20 +620,36 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@eslint/config-helpers": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz", - "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", "dev": true, "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/core": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz", - "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==", + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -167,9 +660,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", - "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", + "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", "dev": true, "license": "MIT", "dependencies": { @@ -179,7 +672,7 @@ "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", + "js-yaml": "^4.1.1", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, @@ -190,10 +683,23 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@eslint/js": { - "version": "9.36.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.36.0.tgz", - "integrity": "sha512-uhCbYtYynH30iZErszX78U+nR3pJU3RHGQ57NXy5QupD4SBVwDeU8TNBy+MjMngc1UyIW9noKqsRqfjQTBU2dw==", + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", + "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", "dev": true, "license": "MIT", "engines": { @@ -204,9 +710,9 @@ } }, "node_modules/@eslint/object-schema": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", - "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -214,13 +720,13 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz", - "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.15.2", + "@eslint/core": "^0.17.0", "levn": "^0.4.1" }, "engines": { @@ -706,17 +1212,27 @@ "url": "https://opencollective.com/libvips" } }, - "node_modules/@isaacs/fs-minipass": { + "node_modules/@isaacs/balanced-match": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", - "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", "dev": true, - "license": "ISC", + "license": "MIT", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", + "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "dev": true, + "license": "MIT", "dependencies": { - "minipass": "^7.0.4" + "@isaacs/balanced-match": "^4.0.1" }, "engines": { - "node": ">=18.0.0" + "node": "20 || >=22" } }, "node_modules/@jridgewell/gen-mapping": { @@ -783,15 +1299,15 @@ } }, "node_modules/@next/env": { - "version": "15.5.4", - "resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.4.tgz", - "integrity": "sha512-27SQhYp5QryzIT5uO8hq99C69eLQ7qkzkDPsk3N+GuS2XgOgoYEeOav7Pf8Tn4drECOVDsDg8oj+/DVy8qQL2A==", + "version": "15.5.9", + "resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.9.tgz", + "integrity": "sha512-4GlTZ+EJM7WaW2HEZcyU317tIQDjkQIyENDLxYJfSWlfqguN+dHkZgyQTV/7ykvobU7yEH5gKvreNrH4B6QgIg==", "license": "MIT" }, "node_modules/@next/eslint-plugin-next": { - "version": "15.5.4", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-15.5.4.tgz", - "integrity": "sha512-SR1vhXNNg16T4zffhJ4TS7Xn7eq4NfKfcOsRwea7RIAHrjRpI9ALYbamqIJqkAhowLlERffiwk0FMvTLNdnVtw==", + "version": "16.1.1", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-16.1.1.tgz", + "integrity": "sha512-Ovb/6TuLKbE1UiPcg0p39Ke3puyTCIKN9hGbNItmpQsp+WX3qrjO3WaMVSi6JHr9X1NrmthqIguVHodMJbh/dw==", "dev": true, "license": "MIT", "dependencies": { @@ -799,9 +1315,9 @@ } }, "node_modules/@next/swc-darwin-arm64": { - "version": "15.5.4", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.4.tgz", - "integrity": "sha512-nopqz+Ov6uvorej8ndRX6HlxCYWCO3AHLfKK2TYvxoSB2scETOcfm/HSS3piPqc3A+MUgyHoqE6je4wnkjfrOA==", + "version": "15.5.7", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.7.tgz", + "integrity": "sha512-IZwtxCEpI91HVU/rAUOOobWSZv4P2DeTtNaCdHqLcTJU4wdNXgAySvKa/qJCgR5m6KI8UsKDXtO2B31jcaw1Yw==", "cpu": [ "arm64" ], @@ -815,9 +1331,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "15.5.4", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.4.tgz", - "integrity": "sha512-QOTCFq8b09ghfjRJKfb68kU9k2K+2wsC4A67psOiMn849K9ZXgCSRQr0oVHfmKnoqCbEmQWG1f2h1T2vtJJ9mA==", + "version": "15.5.7", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.7.tgz", + "integrity": "sha512-UP6CaDBcqaCBuiq/gfCEJw7sPEoX1aIjZHnBWN9v9qYHQdMKvCKcAVs4OX1vIjeE+tC5EIuwDTVIoXpUes29lg==", "cpu": [ "x64" ], @@ -831,9 +1347,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "15.5.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.4.tgz", - "integrity": "sha512-eRD5zkts6jS3VfE/J0Kt1VxdFqTnMc3QgO5lFE5GKN3KDI/uUpSyK3CjQHmfEkYR4wCOl0R0XrsjpxfWEA++XA==", + "version": "15.5.7", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.7.tgz", + "integrity": "sha512-NCslw3GrNIw7OgmRBxHtdWFQYhexoUCq+0oS2ccjyYLtcn1SzGzeM54jpTFonIMUjNbHmpKpziXnpxhSWLcmBA==", "cpu": [ "arm64" ], @@ -847,9 +1363,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "15.5.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.4.tgz", - "integrity": "sha512-TOK7iTxmXFc45UrtKqWdZ1shfxuL4tnVAOuuJK4S88rX3oyVV4ZkLjtMT85wQkfBrOOvU55aLty+MV8xmcJR8A==", + "version": "15.5.7", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.7.tgz", + "integrity": "sha512-nfymt+SE5cvtTrG9u1wdoxBr9bVB7mtKTcj0ltRn6gkP/2Nu1zM5ei8rwP9qKQP0Y//umK+TtkKgNtfboBxRrw==", "cpu": [ "arm64" ], @@ -863,9 +1379,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "15.5.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.4.tgz", - "integrity": "sha512-7HKolaj+481FSW/5lL0BcTkA4Ueam9SPYWyN/ib/WGAFZf0DGAN8frNpNZYFHtM4ZstrHZS3LY3vrwlIQfsiMA==", + "version": "15.5.7", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.7.tgz", + "integrity": "sha512-hvXcZvCaaEbCZcVzcY7E1uXN9xWZfFvkNHwbe/n4OkRhFWrs1J1QV+4U1BN06tXLdaS4DazEGXwgqnu/VMcmqw==", "cpu": [ "x64" ], @@ -879,9 +1395,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "15.5.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.4.tgz", - "integrity": "sha512-nlQQ6nfgN0nCO/KuyEUwwOdwQIGjOs4WNMjEUtpIQJPR2NUfmGpW2wkJln1d4nJ7oUzd1g4GivH5GoEPBgfsdw==", + "version": "15.5.7", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.7.tgz", + "integrity": "sha512-4IUO539b8FmF0odY6/SqANJdgwn1xs1GkPO5doZugwZ3ETF6JUdckk7RGmsfSf7ws8Qb2YB5It33mvNL/0acqA==", "cpu": [ "x64" ], @@ -895,9 +1411,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "15.5.4", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.4.tgz", - "integrity": "sha512-PcR2bN7FlM32XM6eumklmyWLLbu2vs+D7nJX8OAIoWy69Kef8mfiN4e8TUv2KohprwifdpFKPzIP1njuCjD0YA==", + "version": "15.5.7", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.7.tgz", + "integrity": "sha512-CpJVTkYI3ZajQkC5vajM7/ApKJUOlm6uP4BknM3XKvJ7VXAvCqSjSLmM0LKdYzn6nBJVSjdclx8nYJSa3xlTgQ==", "cpu": [ "arm64" ], @@ -911,9 +1427,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "15.5.4", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.4.tgz", - "integrity": "sha512-1ur2tSHZj8Px/KMAthmuI9FMp/YFusMMGoRNJaRZMOlSkgvLjzosSdQI0cJAKogdHl3qXUQKL9MGaYvKwA7DXg==", + "version": "15.5.7", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.7.tgz", + "integrity": "sha512-gMzgBX164I6DN+9/PGA+9dQiwmTkE4TloBNx8Kv9UiGARsr9Nba7IpcBRA1iTV9vwlYnrE3Uy6I7Aj6qLjQuqw==", "cpu": [ "x64" ], @@ -998,54 +1514,49 @@ } }, "node_modules/@tailwindcss/node": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.13.tgz", - "integrity": "sha512-eq3ouolC1oEFOAvOMOBAmfCIqZBJuvWvvYWh5h5iOYfe1HFC6+GZ6EIL0JdM3/niGRJmnrOc+8gl9/HGUaaptw==", + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.18.tgz", + "integrity": "sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==", "dev": true, "license": "MIT", "dependencies": { "@jridgewell/remapping": "^2.3.4", "enhanced-resolve": "^5.18.3", - "jiti": "^2.5.1", - "lightningcss": "1.30.1", - "magic-string": "^0.30.18", + "jiti": "^2.6.1", + "lightningcss": "1.30.2", + "magic-string": "^0.30.21", "source-map-js": "^1.2.1", - "tailwindcss": "4.1.13" + "tailwindcss": "4.1.18" } }, "node_modules/@tailwindcss/oxide": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.13.tgz", - "integrity": "sha512-CPgsM1IpGRa880sMbYmG1s4xhAy3xEt1QULgTJGQmZUeNgXFR7s1YxYygmJyBGtou4SyEosGAGEeYqY7R53bIA==", + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.18.tgz", + "integrity": "sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==", "dev": true, - "hasInstallScript": true, "license": "MIT", - "dependencies": { - "detect-libc": "^2.0.4", - "tar": "^7.4.3" - }, "engines": { "node": ">= 10" }, "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.1.13", - "@tailwindcss/oxide-darwin-arm64": "4.1.13", - "@tailwindcss/oxide-darwin-x64": "4.1.13", - "@tailwindcss/oxide-freebsd-x64": "4.1.13", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.13", - "@tailwindcss/oxide-linux-arm64-gnu": "4.1.13", - "@tailwindcss/oxide-linux-arm64-musl": "4.1.13", - "@tailwindcss/oxide-linux-x64-gnu": "4.1.13", - "@tailwindcss/oxide-linux-x64-musl": "4.1.13", - "@tailwindcss/oxide-wasm32-wasi": "4.1.13", - "@tailwindcss/oxide-win32-arm64-msvc": "4.1.13", - "@tailwindcss/oxide-win32-x64-msvc": "4.1.13" + "@tailwindcss/oxide-android-arm64": "4.1.18", + "@tailwindcss/oxide-darwin-arm64": "4.1.18", + "@tailwindcss/oxide-darwin-x64": "4.1.18", + "@tailwindcss/oxide-freebsd-x64": "4.1.18", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.18", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.18", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.18", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.18", + "@tailwindcss/oxide-linux-x64-musl": "4.1.18", + "@tailwindcss/oxide-wasm32-wasi": "4.1.18", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.18", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.18" } }, "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.13.tgz", - "integrity": "sha512-BrpTrVYyejbgGo57yc8ieE+D6VT9GOgnNdmh5Sac6+t0m+v+sKQevpFVpwX3pBrM2qKrQwJ0c5eDbtjouY/+ew==", + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.18.tgz", + "integrity": "sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==", "cpu": [ "arm64" ], @@ -1060,9 +1571,9 @@ } }, "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.13.tgz", - "integrity": "sha512-YP+Jksc4U0KHcu76UhRDHq9bx4qtBftp9ShK/7UGfq0wpaP96YVnnjFnj3ZFrUAjc5iECzODl/Ts0AN7ZPOANQ==", + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.18.tgz", + "integrity": "sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==", "cpu": [ "arm64" ], @@ -1077,9 +1588,9 @@ } }, "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.13.tgz", - "integrity": "sha512-aAJ3bbwrn/PQHDxCto9sxwQfT30PzyYJFG0u/BWZGeVXi5Hx6uuUOQEI2Fa43qvmUjTRQNZnGqe9t0Zntexeuw==", + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.18.tgz", + "integrity": "sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==", "cpu": [ "x64" ], @@ -1094,9 +1605,9 @@ } }, "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.13.tgz", - "integrity": "sha512-Wt8KvASHwSXhKE/dJLCCWcTSVmBj3xhVhp/aF3RpAhGeZ3sVo7+NTfgiN8Vey/Fi8prRClDs6/f0KXPDTZE6nQ==", + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.18.tgz", + "integrity": "sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==", "cpu": [ "x64" ], @@ -1111,9 +1622,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.13.tgz", - "integrity": "sha512-mbVbcAsW3Gkm2MGwA93eLtWrwajz91aXZCNSkGTx/R5eb6KpKD5q8Ueckkh9YNboU8RH7jiv+ol/I7ZyQ9H7Bw==", + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.18.tgz", + "integrity": "sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==", "cpu": [ "arm" ], @@ -1128,9 +1639,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.13.tgz", - "integrity": "sha512-wdtfkmpXiwej/yoAkrCP2DNzRXCALq9NVLgLELgLim1QpSfhQM5+ZxQQF8fkOiEpuNoKLp4nKZ6RC4kmeFH0HQ==", + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.18.tgz", + "integrity": "sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==", "cpu": [ "arm64" ], @@ -1145,9 +1656,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.13.tgz", - "integrity": "sha512-hZQrmtLdhyqzXHB7mkXfq0IYbxegaqTmfa1p9MBj72WPoDD3oNOh1Lnxf6xZLY9C3OV6qiCYkO1i/LrzEdW2mg==", + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.18.tgz", + "integrity": "sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==", "cpu": [ "arm64" ], @@ -1162,9 +1673,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.13.tgz", - "integrity": "sha512-uaZTYWxSXyMWDJZNY1Ul7XkJTCBRFZ5Fo6wtjrgBKzZLoJNrG+WderJwAjPzuNZOnmdrVg260DKwXCFtJ/hWRQ==", + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.18.tgz", + "integrity": "sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==", "cpu": [ "x64" ], @@ -1179,9 +1690,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.13.tgz", - "integrity": "sha512-oXiPj5mi4Hdn50v5RdnuuIms0PVPI/EG4fxAfFiIKQh5TgQgX7oSuDWntHW7WNIi/yVLAiS+CRGW4RkoGSSgVQ==", + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.18.tgz", + "integrity": "sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==", "cpu": [ "x64" ], @@ -1196,9 +1707,9 @@ } }, "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.13.tgz", - "integrity": "sha512-+LC2nNtPovtrDwBc/nqnIKYh/W2+R69FA0hgoeOn64BdCX522u19ryLh3Vf3F8W49XBcMIxSe665kwy21FkhvA==", + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.18.tgz", + "integrity": "sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==", "bundleDependencies": [ "@napi-rs/wasm-runtime", "@emnapi/core", @@ -1214,21 +1725,21 @@ "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "^1.4.5", - "@emnapi/runtime": "^1.4.5", - "@emnapi/wasi-threads": "^1.0.4", - "@napi-rs/wasm-runtime": "^0.2.12", - "@tybys/wasm-util": "^0.10.0", - "tslib": "^2.8.0" + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1", + "@emnapi/wasi-threads": "^1.1.0", + "@napi-rs/wasm-runtime": "^1.1.0", + "@tybys/wasm-util": "^0.10.1", + "tslib": "^2.4.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.13.tgz", - "integrity": "sha512-dziTNeQXtoQ2KBXmrjCxsuPk3F3CQ/yb7ZNZNA+UkNTeiTGgfeh+gH5Pi7mRncVgcPD2xgHvkFCh/MhZWSgyQg==", + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.18.tgz", + "integrity": "sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==", "cpu": [ "arm64" ], @@ -1243,9 +1754,9 @@ } }, "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.13.tgz", - "integrity": "sha512-3+LKesjXydTkHk5zXX01b5KMzLV1xl2mcktBJkje7rhFUpUlYJy7IMOLqjIRQncLTa1WZZiFY/foAeB5nmaiTw==", + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.18.tgz", + "integrity": "sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==", "cpu": [ "x64" ], @@ -1260,17 +1771,17 @@ } }, "node_modules/@tailwindcss/postcss": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.13.tgz", - "integrity": "sha512-HLgx6YSFKJT7rJqh9oJs/TkBFhxuMOfUKSBEPYwV+t78POOBsdQ7crhZLzwcH3T0UyUuOzU/GK5pk5eKr3wCiQ==", + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.18.tgz", + "integrity": "sha512-Ce0GFnzAOuPyfV5SxjXGn0CubwGcuDB0zcdaPuCSzAa/2vII24JTkH+I6jcbXLb1ctjZMZZI6OjDaLPJQL1S0g==", "dev": true, "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", - "@tailwindcss/node": "4.1.13", - "@tailwindcss/oxide": "4.1.13", + "@tailwindcss/node": "4.1.18", + "@tailwindcss/oxide": "4.1.18", "postcss": "^8.4.41", - "tailwindcss": "4.1.13" + "tailwindcss": "4.1.18" } }, "node_modules/@tailwindcss/postcss/node_modules/postcss": { @@ -1376,6 +1887,13 @@ "@types/unist": "*" } }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/ms": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", @@ -1383,12 +1901,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.8.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.10.tgz", - "integrity": "sha512-TlgT8JntpcbmKUFzjhsyhGfP2fsiz1Mv56im6enJ905xG1DAYesxJaeSbGqQmAw8OWPdhyJGhGSQGKRNJ45u9w==", + "version": "20.19.27", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.27.tgz", + "integrity": "sha512-N2clP5pJhB2YnZJ3PIHFk5RkygRX5WO/5f0WC08tp0wd+sv0rsJk3MqWn3CbNmT2J505a5336jaQj4ph1AdMug==", "dev": true, + "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.21.0" } }, "node_modules/@types/pluralize": { @@ -1405,23 +1924,22 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "19.1.16", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.16.tgz", - "integrity": "sha512-WBM/nDbEZmDUORKnh5i1bTnAz6vTohUf9b8esSMu+b24+srbaxa04UbJgWx78CVfNXA20sNu0odEIluZDFdCog==", + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz", + "integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==", "license": "MIT", - "peer": true, "dependencies": { - "csstype": "^3.0.2" + "csstype": "^3.2.2" } }, "node_modules/@types/react-dom": { - "version": "19.1.9", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.9.tgz", - "integrity": "sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ==", + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", "dev": true, "license": "MIT", "peerDependencies": { - "@types/react": "^19.0.0" + "@types/react": "^19.2.0" } }, "node_modules/@types/react-syntax-highlighter": { @@ -1486,7 +2004,6 @@ "integrity": "sha512-TGf22kon8KW+DeKaUmOibKWktRY8b2NSAZNdtWh798COm1NWx8+xJ6iFBtk3IvLdv6+LGLJLRlyhrhEDZWargQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.45.0", "@typescript-eslint/types": "8.45.0", @@ -2017,13 +2534,19 @@ "win32" ] }, + "node_modules/@zeit/schemas": { + "version": "2.36.0", + "resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.36.0.tgz", + "integrity": "sha512-7kjMwcChYEzMKjeex9ZFXkt1AyNov9R5HZtjBKVsmVpw7pa7ZtlCGvCBC2vnnXctaYN+aRI61HjIqeetZW5ROg==", + "dev": true, + "license": "MIT" + }, "node_modules/acorn": { "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2057,6 +2580,100 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-align/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/ansi-align/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-escapes": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.2.0.tgz", + "integrity": "sha512-g6LhBsl+GBPRWGWsBtutpzBYuIIdBkLEvad5C/va/74Db018+5TZiyA26cZJAr3Rft5lprVqOIPxf5Vid6tqAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -2072,6 +2689,34 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/arch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true, + "license": "MIT" + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -2264,10 +2909,23 @@ "node": ">= 0.4" } }, + "node_modules/auto-bind": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-5.0.1.tgz", + "integrity": "sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/autoprefixer": { - "version": "10.4.16", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz", - "integrity": "sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==", + "version": "10.4.23", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.23.tgz", + "integrity": "sha512-YYTXSFulfwytnjAPlw8QHncHJmlvFKtczb8InXaAx9Q0LbfDnfEYDE55omerIJKihhmU61Ft+cAOSzQVaBUmeA==", "dev": true, "funding": [ { @@ -2283,12 +2941,12 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "browserslist": "^4.21.10", - "caniuse-lite": "^1.0.30001538", - "fraction.js": "^4.3.6", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", + "browserslist": "^4.28.1", + "caniuse-lite": "^1.0.30001760", + "fraction.js": "^5.3.4", + "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "bin": { @@ -2353,6 +3011,130 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/baseline-browser-mapping": { + "version": "2.9.11", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.11.tgz", + "integrity": "sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/boxen": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.0.0.tgz", + "integrity": "sha512-j//dBVuyacJbvW+tvZ9HuH03fZ46QcaKvvhZickZqtB271DxJ7SNRSNxrV/dZX0085m7hISRZWbzWlJvx/rHSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^7.0.0", + "chalk": "^5.0.1", + "cli-boxes": "^3.0.0", + "string-width": "^5.1.2", + "type-fest": "^2.13.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.0.1" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/boxen/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/boxen/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/widest-line": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", + "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^5.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/brace-expansion": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", @@ -2378,9 +3160,9 @@ } }, "node_modules/browserslist": { - "version": "4.22.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", - "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", "dev": true, "funding": [ { @@ -2396,12 +3178,13 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001565", - "electron-to-chromium": "^1.4.601", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" @@ -2410,6 +3193,16 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/call-bind": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", @@ -2469,10 +3262,23 @@ "node": ">=6" } }, + "node_modules/camelcase": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", + "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/caniuse-lite": { - "version": "1.0.30001721", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001721.tgz", - "integrity": "sha512-cOuvmUVtKrtEaoKiO0rSc29jcjwMwX5tOHDy4MgVFEWiUXj4uBMJkwI8MDySkgXidpMiHUcviogAvFi4pA2hDQ==", + "version": "1.0.30001762", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001762.tgz", + "integrity": "sha512-PxZwGNvH7Ak8WX5iXzoK1KPZttBXNPuaOvI2ZYU7NrlM+d9Ov+TUvlLOBNGzVXAntMSMMlJPd+jY6ovrVjSmUw==", "funding": [ { "type": "opencollective", @@ -2515,6 +3321,22 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chalk-template": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz", + "integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/chalk-template?sponsor=1" + } + }, "node_modules/change-case": { "version": "5.4.4", "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz", @@ -2551,22 +3373,106 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/chownr": { + "node_modules/cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.1.1.tgz", + "integrity": "sha512-SroPvNHxUnk+vIW/dOSfNqdy1sPEFkrTk6TUtqLCnBlo3N7TNYYkzzN7uSD6+jVjrdO4+p8nH7JzH6cIvUem6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "slice-ansi": "^7.1.0", + "string-width": "^8.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.0.tgz", + "integrity": "sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "license": "MIT" + }, + "node_modules/clipboardy": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", - "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-3.0.0.tgz", + "integrity": "sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg==", + "dev": true, + "license": "MIT", + "dependencies": { + "arch": "^2.2.0", + "execa": "^5.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/code-excerpt": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-4.0.0.tgz", + "integrity": "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==", "dev": true, - "license": "BlueOak-1.0.0", + "license": "MIT", + "dependencies": { + "convert-to-spaces": "^2.0.1" + }, "engines": { - "node": ">=18" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, - "node_modules/client-only": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", - "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", - "license": "MIT" - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -2595,11 +3501,81 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", + "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.1.0", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-to-spaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-2.0.1.tgz", + "integrity": "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } }, "node_modules/cross-spawn": { "version": "7.0.6", @@ -2617,9 +3593,10 @@ } }, "node_modules/csstype": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "license": "MIT" }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -2721,6 +3698,16 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -2822,11 +3809,19 @@ "node": ">= 0.4" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, "node_modules/electron-to-chromium": { - "version": "1.4.616", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.616.tgz", - "integrity": "sha512-1n7zWYh8eS0L9Uy+GskE0lkBUNK83cXTVJI0pU3mGprFsbfSdAc15VTFbo+A+Bq4pwstmL30AVcEU3Fo463lNg==", - "dev": true + "version": "1.5.267", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", + "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", + "dev": true, + "license": "ISC" }, "node_modules/emoji-regex": { "version": "9.2.2", @@ -2836,9 +3831,9 @@ "license": "MIT" }, "node_modules/enhanced-resolve": { - "version": "5.18.3", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", - "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", + "version": "5.18.4", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.4.tgz", + "integrity": "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==", "dev": true, "license": "MIT", "dependencies": { @@ -2849,6 +3844,19 @@ "node": ">=10.13.0" } }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/es-abstract": { "version": "1.24.0", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", @@ -3026,11 +4034,65 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-toolkit": { + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.43.0.tgz", + "integrity": "sha512-SKCT8AsWvYzBBuUqMk4NPwFlSdqLpJwmy6AP322ERn8W2YLIB6JBXnwMI2Qsh2gfphT3q7EKAxKb23cvFHFwKA==", + "dev": true, + "license": "MIT", + "workspaces": [ + "docs", + "benchmarks" + ] + }, + "node_modules/esbuild": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", + "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.2", + "@esbuild/android-arm": "0.27.2", + "@esbuild/android-arm64": "0.27.2", + "@esbuild/android-x64": "0.27.2", + "@esbuild/darwin-arm64": "0.27.2", + "@esbuild/darwin-x64": "0.27.2", + "@esbuild/freebsd-arm64": "0.27.2", + "@esbuild/freebsd-x64": "0.27.2", + "@esbuild/linux-arm": "0.27.2", + "@esbuild/linux-arm64": "0.27.2", + "@esbuild/linux-ia32": "0.27.2", + "@esbuild/linux-loong64": "0.27.2", + "@esbuild/linux-mips64el": "0.27.2", + "@esbuild/linux-ppc64": "0.27.2", + "@esbuild/linux-riscv64": "0.27.2", + "@esbuild/linux-s390x": "0.27.2", + "@esbuild/linux-x64": "0.27.2", + "@esbuild/netbsd-arm64": "0.27.2", + "@esbuild/netbsd-x64": "0.27.2", + "@esbuild/openbsd-arm64": "0.27.2", + "@esbuild/openbsd-x64": "0.27.2", + "@esbuild/openharmony-arm64": "0.27.2", + "@esbuild/sunos-x64": "0.27.2", + "@esbuild/win32-arm64": "0.27.2", + "@esbuild/win32-ia32": "0.27.2", + "@esbuild/win32-x64": "0.27.2" + } + }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -3048,26 +4110,24 @@ } }, "node_modules/eslint": { - "version": "9.36.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.36.0.tgz", - "integrity": "sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==", + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", + "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.0", - "@eslint/config-helpers": "^0.3.1", - "@eslint/core": "^0.15.2", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.36.0", - "@eslint/plugin-kit": "^0.3.5", + "@eslint/js": "9.39.2", + "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", @@ -3137,6 +4197,16 @@ } } }, + "node_modules/eslint-config-next/node_modules/@next/eslint-plugin-next": { + "version": "15.5.4", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-15.5.4.tgz", + "integrity": "sha512-SR1vhXNNg16T4zffhJ4TS7Xn7eq4NfKfcOsRwea7RIAHrjRpI9ALYbamqIJqkAhowLlERffiwk0FMvTLNdnVtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-glob": "3.3.1" + } + }, "node_modules/eslint-import-resolver-node": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", @@ -3250,7 +4320,6 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -3289,6 +4358,19 @@ "ms": "^2.1.1" } }, + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/eslint-plugin-import/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -3329,6 +4411,19 @@ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" } }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/eslint-plugin-react": { "version": "7.37.5", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", @@ -3375,6 +4470,19 @@ "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" } }, + "node_modules/eslint-plugin-react/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/eslint-plugin-react/node_modules/resolve": { "version": "2.0.0-next.5", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", @@ -3445,6 +4553,19 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/espree": { "version": "10.4.0", "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", @@ -3542,6 +4663,30 @@ "node": ">=0.10.0" } }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -3719,18 +4864,34 @@ } }, "node_modules/fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", + "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==", "dev": true, + "license": "MIT", "engines": { "node": "*" }, "funding": { - "type": "patreon", + "type": "github", "url": "https://github.com/sponsors/rawify" } }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -3780,6 +4941,19 @@ "node": ">= 0.4" } }, + "node_modules/get-east-asian-width": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", + "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -3819,6 +4993,19 @@ "node": ">= 0.4" } }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-symbol-description": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", @@ -3944,9 +5131,9 @@ } }, "node_modules/gray-matter/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "license": "MIT", "dependencies": { "argparse": "^1.0.7", @@ -4167,40 +5354,161 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true, "engines": { - "node": ">= 4" + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/ink": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/ink/-/ink-6.6.0.tgz", + "integrity": "sha512-QDt6FgJxgmSxAelcOvOHUvFxbIUjVpCH5bx+Slvc5m7IEcpGt3dYwbz/L+oRnqEGeRvwy1tineKK4ect3nW1vQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alcalzone/ansi-tokenize": "^0.2.1", + "ansi-escapes": "^7.2.0", + "ansi-styles": "^6.2.1", + "auto-bind": "^5.0.1", + "chalk": "^5.6.0", + "cli-boxes": "^3.0.0", + "cli-cursor": "^4.0.0", + "cli-truncate": "^5.1.1", + "code-excerpt": "^4.0.0", + "es-toolkit": "^1.39.10", + "indent-string": "^5.0.0", + "is-in-ci": "^2.0.0", + "patch-console": "^2.0.0", + "react-reconciler": "^0.33.0", + "signal-exit": "^3.0.7", + "slice-ansi": "^7.1.0", + "stack-utils": "^2.0.6", + "string-width": "^8.1.0", + "type-fest": "^4.27.0", + "widest-line": "^5.0.0", + "wrap-ansi": "^9.0.0", + "ws": "^8.18.0", + "yoga-layout": "~3.2.1" + }, + "engines": { + "node": ">=20" + }, + "peerDependencies": { + "@types/react": ">=19.0.0", + "react": ">=19.0.0", + "react-devtools-core": "^6.1.2" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react-devtools-core": { + "optional": true + } + } + }, + "node_modules/ink/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ink/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "node_modules/ink/node_modules/string-width": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.0.tgz", + "integrity": "sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==", "dev": true, + "license": "MIT", "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "get-east-asian-width": "^1.3.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=6" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, "node_modules/inline-style-parser": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz", @@ -4400,6 +5708,22 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", @@ -4434,6 +5758,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-fullwidth-code-point": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-generator-function": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", @@ -4476,6 +5816,22 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/is-in-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-in-ci/-/is-in-ci-2.0.0.tgz", + "integrity": "sha512-cFeerHriAnhrQSbpAxL37W1wcJKUUX07HyLWZCW1URJT/ra3GyUTzBgUnh24TMVfNTV2Hij2HLxkPHFZfOZy5w==", + "dev": true, + "license": "MIT", + "bin": { + "is-in-ci": "cli.js" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-map": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", @@ -4541,6 +5897,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-port-reachable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-port-reachable/-/is-port-reachable-4.0.0.tgz", + "integrity": "sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-regex": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", @@ -4589,6 +5958,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-string": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", @@ -4686,6 +6068,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", @@ -4734,9 +6129,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -4845,9 +6240,9 @@ } }, "node_modules/lightningcss": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", - "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz", + "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==", "dev": true, "license": "MPL-2.0", "dependencies": { @@ -4861,22 +6256,44 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "lightningcss-darwin-arm64": "1.30.1", - "lightningcss-darwin-x64": "1.30.1", - "lightningcss-freebsd-x64": "1.30.1", - "lightningcss-linux-arm-gnueabihf": "1.30.1", - "lightningcss-linux-arm64-gnu": "1.30.1", - "lightningcss-linux-arm64-musl": "1.30.1", - "lightningcss-linux-x64-gnu": "1.30.1", - "lightningcss-linux-x64-musl": "1.30.1", - "lightningcss-win32-arm64-msvc": "1.30.1", - "lightningcss-win32-x64-msvc": "1.30.1" + "lightningcss-android-arm64": "1.30.2", + "lightningcss-darwin-arm64": "1.30.2", + "lightningcss-darwin-x64": "1.30.2", + "lightningcss-freebsd-x64": "1.30.2", + "lightningcss-linux-arm-gnueabihf": "1.30.2", + "lightningcss-linux-arm64-gnu": "1.30.2", + "lightningcss-linux-arm64-musl": "1.30.2", + "lightningcss-linux-x64-gnu": "1.30.2", + "lightningcss-linux-x64-musl": "1.30.2", + "lightningcss-win32-arm64-msvc": "1.30.2", + "lightningcss-win32-x64-msvc": "1.30.2" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz", + "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-darwin-arm64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", - "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz", + "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==", "cpu": [ "arm64" ], @@ -4895,9 +6312,9 @@ } }, "node_modules/lightningcss-darwin-x64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", - "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==", + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz", + "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==", "cpu": [ "x64" ], @@ -4916,9 +6333,9 @@ } }, "node_modules/lightningcss-freebsd-x64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", - "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==", + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz", + "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==", "cpu": [ "x64" ], @@ -4937,9 +6354,9 @@ } }, "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", - "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==", + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz", + "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==", "cpu": [ "arm" ], @@ -4958,9 +6375,9 @@ } }, "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", - "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==", + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz", + "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==", "cpu": [ "arm64" ], @@ -4979,9 +6396,9 @@ } }, "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", - "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==", + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz", + "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==", "cpu": [ "arm64" ], @@ -5000,9 +6417,9 @@ } }, "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", - "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==", + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz", + "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==", "cpu": [ "x64" ], @@ -5021,9 +6438,9 @@ } }, "node_modules/lightningcss-linux-x64-musl": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", - "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==", + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz", + "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==", "cpu": [ "x64" ], @@ -5042,9 +6459,9 @@ } }, "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", - "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==", + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz", + "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==", "cpu": [ "arm64" ], @@ -5063,9 +6480,9 @@ } }, "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", - "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==", + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz", + "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==", "cpu": [ "x64" ], @@ -5142,9 +6559,9 @@ } }, "node_modules/magic-string": { - "version": "0.30.19", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.19.tgz", - "integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==", + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5411,9 +6828,9 @@ } }, "node_modules/mdast-util-to-hast": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", - "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", + "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", @@ -5471,6 +6888,13 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -6058,48 +7482,72 @@ "node": ">=8.6" } }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", "dev": true, + "license": "MIT", "dependencies": { - "brace-expansion": "^1.1.7" + "mime-db": "~1.33.0" }, "engines": { - "node": "*" + "node": ">= 0.6" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "node_modules/mime-types/node_modules/mime-db": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "dev": true, "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">= 0.6" } }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, - "license": "ISC", + "license": "MIT", "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=6" } }, - "node_modules/minizlib": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", - "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", "dev": true, - "license": "MIT", + "license": "BlueOak-1.0.0", "dependencies": { - "minipass": "^7.1.2" + "@isaacs/brace-expansion": "^5.0.0" }, "engines": { - "node": ">= 18" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/ms": { @@ -6147,6 +7595,16 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -6154,12 +7612,12 @@ "license": "MIT" }, "node_modules/next": { - "version": "15.5.4", - "resolved": "https://registry.npmjs.org/next/-/next-15.5.4.tgz", - "integrity": "sha512-xH4Yjhb82sFYQfY3vbkJfgSDgXvBB6a8xPs9i35k6oZJRoQRihZH+4s9Yo2qsWpzBmZ3lPXaJ2KPXLfkvW4LnA==", + "version": "15.5.9", + "resolved": "https://registry.npmjs.org/next/-/next-15.5.9.tgz", + "integrity": "sha512-agNLK89seZEtC5zUHwtut0+tNrc0Xw4FT/Dg+B/VLEo9pAcS9rtTKpek3V6kVcVwsB2YlqMaHdfZL4eLEVYuCg==", "license": "MIT", "dependencies": { - "@next/env": "15.5.4", + "@next/env": "15.5.9", "@swc/helpers": "0.5.15", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", @@ -6172,14 +7630,14 @@ "node": "^18.18.0 || ^19.8.0 || >= 20.0.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "15.5.4", - "@next/swc-darwin-x64": "15.5.4", - "@next/swc-linux-arm64-gnu": "15.5.4", - "@next/swc-linux-arm64-musl": "15.5.4", - "@next/swc-linux-x64-gnu": "15.5.4", - "@next/swc-linux-x64-musl": "15.5.4", - "@next/swc-win32-arm64-msvc": "15.5.4", - "@next/swc-win32-x64-msvc": "15.5.4", + "@next/swc-darwin-arm64": "15.5.7", + "@next/swc-darwin-x64": "15.5.7", + "@next/swc-linux-arm64-gnu": "15.5.7", + "@next/swc-linux-arm64-musl": "15.5.7", + "@next/swc-linux-x64-gnu": "15.5.7", + "@next/swc-linux-x64-musl": "15.5.7", + "@next/swc-win32-arm64-msvc": "15.5.7", + "@next/swc-win32-x64-msvc": "15.5.7", "sharp": "^0.34.3" }, "peerDependencies": { @@ -6206,18 +7664,23 @@ } }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "dev": true, + "license": "MIT" }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/object-assign": { @@ -6342,6 +7805,32 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/on-headers": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -6438,6 +7927,16 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/patch-console": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/patch-console/-/patch-console-2.0.0.tgz", + "integrity": "sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -6447,6 +7946,13 @@ "node": ">=8" } }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", + "dev": true, + "license": "(WTFPL OR MIT)" + }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -6462,6 +7968,13 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "node_modules/path-to-regexp": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz", + "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==", + "dev": true, + "license": "MIT" + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -6518,7 +8031,6 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", @@ -6604,27 +8116,61 @@ ], "license": "MIT" }, + "node_modules/range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/react": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", - "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz", + "integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } }, "node_modules/react-dom": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", - "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==", "license": "MIT", - "peer": true, "dependencies": { - "scheduler": "^0.26.0" + "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^19.1.0" + "react": "^19.2.3" } }, "node_modules/react-is": { @@ -6661,6 +8207,22 @@ "react": ">=18" } }, + "node_modules/react-reconciler": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.33.0.tgz", + "integrity": "sha512-KetWRytFv1epdpJc3J4G75I4WrplZE5jOL7Yq0p34+OVOKF4Se7WrdIdVC45XsSSmUTlht2FM/fM1FZb1mfQeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "react": "^19.2.0" + } + }, "node_modules/react-syntax-highlighter": { "version": "16.1.0", "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-16.1.0.tgz", @@ -6741,6 +8303,46 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/registry-auth-token": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", + "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "rc": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/remark": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/remark/-/remark-15.0.1.tgz", + "integrity": "sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/remark-gfm": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", @@ -6807,6 +8409,16 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -6843,6 +8455,23 @@ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, + "node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", @@ -6898,6 +8527,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/safe-push-apply": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", @@ -6934,9 +8584,9 @@ } }, "node_modules/scheduler": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", - "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", "license": "MIT" }, "node_modules/section-matter": { @@ -6965,6 +8615,108 @@ "node": ">=10" } }, + "node_modules/serve": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/serve/-/serve-14.2.5.tgz", + "integrity": "sha512-Qn/qMkzCcMFVPb60E/hQy+iRLpiU8PamOfOSYoAHmmF+fFFmpPpqa6Oci2iWYpTdOUM3VF+TINud7CfbQnsZbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zeit/schemas": "2.36.0", + "ajv": "8.12.0", + "arg": "5.0.2", + "boxen": "7.0.0", + "chalk": "5.0.1", + "chalk-template": "0.4.0", + "clipboardy": "3.0.0", + "compression": "1.8.1", + "is-port-reachable": "4.0.0", + "serve-handler": "6.1.6", + "update-check": "1.5.4" + }, + "bin": { + "serve": "build/main.js" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/serve-handler": { + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.6.tgz", + "integrity": "sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.0.0", + "content-disposition": "0.5.2", + "mime-types": "2.1.18", + "minimatch": "3.1.2", + "path-is-inside": "1.0.2", + "path-to-regexp": "3.3.0", + "range-parser": "1.2.0" + } + }, + "node_modules/serve-handler/node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serve-handler/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/serve/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/serve/node_modules/chalk": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz", + "integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/serve/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -7154,6 +8906,43 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/slice-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", + "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -7195,6 +8984,29 @@ "dev": true, "license": "MIT" }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/stop-iteration-iterator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", @@ -7209,6 +9021,31 @@ "node": ">= 0.4" } }, + "node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, "node_modules/string.prototype.includes": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", @@ -7336,6 +9173,22 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -7355,6 +9208,16 @@ "node": ">=0.10.0" } }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -7367,6 +9230,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strip-markdown": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-markdown/-/strip-markdown-6.0.0.tgz", + "integrity": "sha512-mSa8FtUoX3ExJYDkjPUTC14xaBAn4Ik5GPQD45G5E2egAmeV3kHgVSTfIoSDggbF6Pk9stahVgqsLCNExv6jHw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/style-to-js": { "version": "1.1.17", "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.17.tgz", @@ -7433,16 +9309,16 @@ } }, "node_modules/tailwindcss": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.13.tgz", - "integrity": "sha512-i+zidfmTqtwquj4hMEwdjshYYgMbOrPzb9a0M3ZgNa0JMoZeFC6bxZvO8yr8ozS6ix2SDz0+mvryPeBs2TFE+w==", + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.18.tgz", + "integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==", "dev": true, "license": "MIT" }, "node_modules/tapable": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.3.tgz", - "integrity": "sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", "dev": true, "license": "MIT", "engines": { @@ -7453,23 +9329,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/tar": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.2.tgz", - "integrity": "sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.1.0", - "yallist": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/tinyglobby": { "version": "0.2.15", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", @@ -7511,7 +9370,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -7584,6 +9442,26 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, + "node_modules/tsx": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.27.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -7596,6 +9474,19 @@ "node": ">= 0.8.0" } }, + "node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/typed-array-buffer": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", @@ -7675,11 +9566,11 @@ } }, "node_modules/typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, - "peer": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -7721,10 +9612,11 @@ } }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" }, "node_modules/unified": { "version": "11.0.5", @@ -7885,9 +9777,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, "funding": [ { @@ -7903,9 +9795,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -7914,6 +9807,17 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/update-check": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.4.tgz", + "integrity": "sha512-5YHsflzHP4t1G+8WGPlvKbJEbAJGCgw+Em+dGR1KmBUbr1J36SJBqlHLjR7oob7sco5hWHGQVcr9B2poIVDDTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "registry-auth-token": "3.3.2", + "registry-url": "3.1.0" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -7923,6 +9827,16 @@ "punycode": "^2.1.0" } }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/vfile": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", @@ -8067,20 +9981,79 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/widest-line": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-5.0.0.tgz", + "integrity": "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", "license": "MIT" }, - "node_modules/yallist": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", - "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", "dev": true, - "license": "BlueOak-1.0.0", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, "engines": { "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, "node_modules/yocto-queue": { @@ -8095,6 +10068,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/yoga-layout": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/yoga-layout/-/yoga-layout-3.2.1.tgz", + "integrity": "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==", + "dev": true, + "license": "MIT" + }, "node_modules/zwitch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", diff --git a/package.json b/package.json index 824151f..2c332ae 100644 --- a/package.json +++ b/package.json @@ -3,37 +3,48 @@ "version": "0.1.0", "private": true, "scripts": { - "dev": "next dev --turbopack", - "build": "next build --turbopack", - "start": "next start", + "dev": "npm run compile && next dev --turbopack", + "build": "npm run compile && next build --turbopack", + "compile": "npm run compile:clean && npm run compile:content", + "compile:content": "tsx scripts/compile-content.tsx", + "compile:clean": "tsx scripts/compile-clean.tsx", + "start": "npx serve out", "lint": "eslint" }, "dependencies": { "change-case": "^5.4.4", "gray-matter": "^4.0.3", "handlebars": "^4.7.8", - "js-yaml": "^4.1.0", - "next": "^15.5.4", + "js-yaml": "^4.1.1", + "next": "^15.5.9", "pluralize": "^8.0.0", - "react": "19.1.0", - "react-dom": "19.1.0", + "react": "^19.2.3", + "react-dom": "^19.2.3", "react-markdown": "^10.1.0", "react-syntax-highlighter": "^16.1.0", - "remark-gfm": "^4.0.1" + "remark": "^15.0.1", + "remark-gfm": "^4.0.1", + "strip-markdown": "^6.0.0" }, "devDependencies": { - "@eslint/eslintrc": "^3", - "@tailwindcss/postcss": "^4", + "@eslint/eslintrc": "^3.3.3", + "@next/eslint-plugin-next": "^16.1.1", + "@tailwindcss/postcss": "^4.1.18", "@types/js-yaml": "^4.0.9", - "@types/node": "^20", + "@types/minimatch": "^5.1.2", + "@types/node": "^20.19.27", "@types/pluralize": "^0.0.33", - "@types/react": "^19", - "@types/react-dom": "^19", + "@types/react": "^19.2.7", + "@types/react-dom": "^19.2.3", "@types/react-syntax-highlighter": "^15.5.13", - "autoprefixer": "^10.0.1", - "eslint": "^9", - "eslint-config-next": "15.5.4", - "tailwindcss": "^4", - "typescript": "^5" + "autoprefixer": "^10.4.23", + "eslint": "^9.39.2", + "eslint-config-next": "^15.5.4", + "ink": "^6.6.0", + "minimatch": "^10.1.1", + "serve": "^14.2.5", + "tailwindcss": "^4.1.18", + "tsx": "^4.21.0", + "typescript": "^5.9.3" } } diff --git a/readme.md b/readme.md index 2493264..422c9e3 100644 --- a/readme.md +++ b/readme.md @@ -1,52 +1,124 @@ -# DocumentDB website and docs +# DocumentDB Website -A concise, modern website prototype for DocumentDB, built with [Next.js](https://nextjs.org/) and [Tailwind CSS](https://tailwindcss.com/). The site features a list of community blog posts and core documentation. Content is managed via YAML and Markdown files for easy editing and extensibility. +A modern website for DocumentDB built with [Next.js](https://nextjs.org/) and [Tailwind CSS](https://tailwindcss.com/). The site features community blog posts and technical documentation, with content automatically pulled from the [documentdb/docs](https://github.com/documentdb/docs) repository during the build process. -## Contributing a Blog Post +## Prerequisites for Development -1. Open `blogs/content.yml` in the repository. +- **[Node.js](https://nodejs.org/)** (*20 or higher*) -1. Add your blog post as a new entry, following the format of existing posts (title, author, date, summary, etc). - - The YAML file is validated against its schema for consistency and editor support. +- **[Git](https://git-scm.com/)** (*for cloning documentation content*) -1. Submit a pull request for review. +You can develop locally on any machine with these prerequisites installed, or use [GitHub Codespaces](#develop-in-github-codespaces) for a pre-configured environment. +## Getting Started -## Contributing a Documentation Article +Get started by cloning and running this repository locally. -1. Navigate to the appropriate folder under `articles/` (e.g., `articles/quickstart/`, `articles/postgresql/`). +1. Clone this repository -1. Add your article as a Markdown file (`.md`). - - Update the corresponding `navigation.yml` to include your new article if needed. - - Ensure your content follows the structure and style of existing articles. +1. Install dependencies: -1. Submit a pull request for review. + ```bash + npm install + ``` -## Contributing Reference Content +1. Start the development server: -1. Open the relevant file in the `reference/` directory (e.g., `reference/content.yml`, or a command/operator YAML file). + ```bash + npm run dev + ``` -1. Add or update entries according to the schema and format used in existing files. - - Reference content is organized by command, operator, and type. Follow the folder structure for new additions. - - Use the schemas in the `schema/` directory for guidance and validation. +1. Observe that the site will be available at http://localhost:3000 -1. Submit a pull request for review. +The first time you run `npm run dev` or `npm run build`, documentation content will be automatically compiled from the [documentdb/docs](https://github.com/documentdb/docs) repository. -## Develop in GitHub Codespaces +## Contributing + +We welcome contributions to improve the DocumentDB website, whether it's blog posts, bug fixes, or enhancements to the site itself. + +### Contributing Blog Posts + +Blog posts are managed locally in this repository. Contribute directly through a pull request to this repository. + +1. Open [blogs/content.yml](blogs/content.yml) + +1. Add your blog post entry following the format of existing posts + +1. Submit a pull request for review + +### Contributing Documentation & Reference Content + +Documentation articles and API reference content are managed in a separate repository. For more information, see [documentdb/docs](https://github.com/documentdb/docs). -You can develop and preview the site in a fully configured environment using GitHub Codespaces: +> [!IMPORTANT] +> Please refer to that repository for instructions on contributing: +> +> - Documentation articles (`getting-started/`, `postgres-api/`, `architecture/`, etc.) +> - API reference content (`api-reference/`) +> -- Launch a devcontainer with all dependencies pre-installed. +## Content Configuration - [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/documentdb/documentdb.github.io) +Documentation content is automatically compiled during builds from external repositories. The mapping is configured in [content.config.json](content.config.json). -- The environment includes Node.js, Next.js, and Tailwind CSS setup for instant development and preview. +```json +{ + "sources": [ + { + "repository": "https://github.com/documentdb/docs", + "branch": "main", + "mappings": [ + { + "source": "api-reference", + "target": "reference" + }, + { + "source": "getting-started", + "target": "articles/getting-started" + } + ] + } + ], + "include": ["**/*.md", "**/*.yml"], + "exclude": ["**/{readme,README}.md"] +} +``` + +### Configuration options + +The `content.config.json` file controls how documentation is compiled from external sources into this site. + +- **sources** - Array of repositories to clone content from. Each source includes: + - **repository** - Git repository URL + - **branch** - Git branch to clone from + - **mappings** - Array of source folder to target folder mappings +- **include** - Array of glob patterns for files to include (opt-in filtering) +- **exclude** - Array of glob patterns for files to exclude + +### Manual content operations + +While content is automatically compiled during builds, you can manually trigger these operations during development: + +```bash +# Clean all target directories +npm run clean:content +``` + +```bash +# Compile content from sources +npm run compile:content +``` + +## Develop in GitHub Codespaces -- Install packages with `npm install` +Launch a pre-configured development environment with all dependencies installed: -- Use `npm run dev` to start the local server and preview changes. +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/documentdb/documentdb.github.io) -- The environment also includes the required Visual Studio Code extensions to edit the Markdown and YAML files with full completion support. +The Codespaces environment includes: +- Node.js 20 +- Git +- Visual Studio Code extensions for Markdown and YAML editing +- All npm dependencies - > [!TIP] - > You can use these same steps if you opt to develop on your local machine. Ensure that you are using at least the latest LTS version of Node.js +Simply run `npm run dev` after the container starts. diff --git a/reference/command/aggregation/count.yml b/reference/command/aggregation/count.yml deleted file mode 100644 index ce92838..0000000 --- a/reference/command/aggregation/count.yml +++ /dev/null @@ -1,99 +0,0 @@ -type: command -category: aggregation -name: count -description: |- - The `count` command is used to count the number of documents in a collection that match specific criteria. -summary: |- - This command is useful for obtaining quick statistics about the data stored in your collections, such as the number of documents that meet certain criteria. -syntax: |- - db.collection.count( - , - - ); -parameters: - - name: query - required: true - description: |- - A document specifying the selection criteria using query operators. - - name: options - required: false - description: |- - A document specifying options including, but not limited to `limit` and `skip`. -examples: - sample: |- - [ - { - "_id": "00000000-0000-0000-0000-000000003001", - "name": "Proseware, Inc. | Home Entertainment Hub - East Linwoodbury", - "promotionEvents": [ - { - "eventName": "Unbeatable Bargain Bash" - }, - { - "eventName": "Steal of a Deal Days" - } - ] - }, - { - "_id": "00000000-0000-0000-0000-000000003002", - "name": "Fabrikam, Inc. | Home Accessory Outlet - West Adele", - "promotionEvents": [ - { - "eventName": "Incredible Discount Days" - }, - { - "eventName": "Steal of a Deal Days" - } - ], - "location": { - "lat": -89.2384, - "lon": -46.4012 - } - }, - { - "_id": "00000000-0000-0000-0000-000000003003", - "name": "Wide World Importers | Fitness Equipment Outlet - Reillyborough", - "promotionEvents": [ - { - "eventName": "Incredible Discount Days" - } - ], - "location": { - "lat": -2.4111, - "lon": 72.1041 - } - } - ] - items: - - title: Counting all documents in a collection - explanation: |- - Use the `count` command with an empty document to count **all** documents in a collection. - description: |- - In this example, all documents in the `stores` collection are counted. - query: |- - db.stores.count({ "_id": "00000000-0000-0000-0000-000000003002" }) - output: - value: |- - 1 - - title: Counting documents that match nested criteria - explanation: |- - The `query` parameter supports nested parameters. - description: |- - In this example, the command counts documents that match the string value `"Incredible Discount Days"` for the `promotionEvents.eventName` field. - query: |- - db.stores.count({ "promotionEvents.eventName": "Incredible Discount Days" }) - output: - value: |- - 2 - - title: Counting documents that match multiple criteria - explanation: |- - The `query` parameter also supports multiple parameters. - description: |- - In this example, the `locationLatitude` and `locationLongitude` parameters are used to count documents that match on these specific values. - query: |- - db.stores.count({ "location.lat": -2.4111, "location.lon": 72.1041 }) - output: - value: |- - 1 -related: - - reference: /operator/evaluation-query/regex diff --git a/reference/content.yml b/reference/content.yml deleted file mode 100644 index e0239a3..0000000 --- a/reference/content.yml +++ /dev/null @@ -1,46 +0,0 @@ -- type: command - description: |- - MongoDB Query Language (MQL) commands are direct instructions for managing and interacting with your database server. They are essential for performing administrative tasks, optimizing performance, and maintaining security. - categories: - - category: aggregation - description: |- - Aggregation operations process data records and return computed results. They group values from multiple documents, perform operations on the grouped data, and return a single result. Common aggregation tasks include calculating averages, sums, and counts. - - category: query-and-write - description: |- - Query and write operations allow you to retrieve, insert, update, and delete documents in your DocumentDB collections. These operations are fundamental for interacting with your data, enabling you to perform CRUD (Create, Read, Update, Delete) tasks efficiently. -- type: operator - description: |- - MongoDB Query Language (MQL) operators enable powerful filtering, comparison, and data manipulation within queries. Mastering these operators helps you write expressive queries to efficiently retrieve and update documents in your collections. - categories: - - category: accumulator - description: |- - Accumulator operators are used in aggregation pipelines to perform calculations on groups of documents. They take multiple input values and return a single output value, such as sums, averages, minimums, and maximums, enabling complex data analysis within your queries. - - category: aggregation - - category: arithmetic-expression - - category: array-expression - - category: array-query - description: |- - Array query operators allow you to perform operations on array fields within your documents. These operators enable you to filter, manipulate, and analyze array data effectively, making it easier to work with complex data structures in your queries. - - category: array-update - - category: bitwise - - category: bitwise-query - - category: bitwise-update - - category: boolean-expression - - category: comparison-query - - category: conditional-expression - - category: date-expression - - category: data-size - - category: element-query - - category: evaluation-query - description: |- - Evaluation query operators are used to evaluate expressions and conditions within your queries. They help you filter documents based on specific criteria, allowing for more precise and dynamic querying capabilities. - - category: field-update - - category: geospatial - - category: logical-query - - category: miscellaneous - - category: object-expression - - category: projection - - category: timestamp-expression - - category: set-expression - - category: variable-expression - - category: window diff --git a/reference/operator/evaluation-query/regex.yml b/reference/operator/evaluation-query/regex.yml deleted file mode 100644 index 262febf..0000000 --- a/reference/operator/evaluation-query/regex.yml +++ /dev/null @@ -1,116 +0,0 @@ -type: operator -category: evaluation-query -name: $regex -description: |- - The `$regex` operator is used to perform pattern matching with regular expressions. -summary: |- - This operator is useful for querying string fields for matches that fit specific patterns. Common use cases include searching for documents where a field contains a substring, starts with a certain prefix, or matches a complex pattern. -syntax: |- - { - "field": { - $regex: /pattern/, - $options: '' - } - } -parameters: - - name: field - type: string - required: true - description: |- - The field in the document to apply the regular expression to. This should be a string field that you want to match against the provided pattern. - - name: $regex - type: pattern - required: true - description: |- - The regular expression pattern to match. - - name: $options - type: string - required: false - description: |- - Flags to modify the behavior of the regex. Common options include, but are not limited to `i` for case-insensitive matching, `m` for multiline matching, etc. -examples: - sample: |- - [ - { - "_id": "00000000-0000-0000-0000-000000003001", - "name": "Proseware, Inc. | Home Entertainment Hub - East Linwoodbury", - "promotionEvents": [ - { - "eventName": "Unbeatable Bargain Bash" - }, - { - "eventName": "Steal of a Deal Days" - } - ] - }, - { - "_id": "00000000-0000-0000-0000-000000003002", - "name": "Fabrikam, Inc. | Home Accessory Outlet - West Adele", - "promotionEvents": [ - { - "eventName": "Incredible Discount Days" - }, - { - "eventName": "Steal of a Deal Days" - } - ], - "location": { - "lat": -89.2384, - "lon": -46.4012 - } - }, - { - "_id": "00000000-0000-0000-0000-000000003003", - "name": "Wide World Importers | Fitness Equipment Outlet - Reillyborough", - "promotionEvents": [ - { - "eventName": "Incredible Discount Days" - } - ], - "location": { - "lat": -2.4111, - "lon": 72.1041 - } - } - ] - items: - - title: Find documents with a specific substring - explanation: |- - Use the `$regex` operator to find all documents that match a specific pattern. - description: |- - In this example, the operator filters to documents that contain the exact phrase `Home` in its name. - query: |- - db.stores.find({ "name": { "$regex": /Home/ }}, { name: 1 }) - output: - value: |- - [ - { - _id: '00000000-0000-0000-0000-000000003001', - name: 'Proseware, Inc. | Home Entertainment Hub - East Linwoodbury' - }, - { - _id: '00000000-0000-0000-0000-000000003002', - name: 'Fabrikam, Inc. | Home Accessory Outlet - West Adele' - } - ] - - title: Find documents using a case-insensitive match - explanation: |- - The `$regex` operator includes options like case-insensitive search. - description: |- - In this example, the operator filters to documents that contain the case-insensitive phrase `outlet` in its name. - query: |- - db.stores.find({ "name": { $regex: /outlet/, $options: "i" }}, { name: 1 }) - output: - value: |- - [ - { - _id: '00000000-0000-0000-0000-000000003002', - name: 'Fabrikam, Inc. | Home Accessory Outlet - West Adele' - }, - { - _id: '00000000-0000-0000-0000-000000003003', - name: 'Wide World Importers | Fitness Equipment Outlet - Reillyborough' - } - ] -related: - - reference: /command/aggregation/count diff --git a/schema/articles.navigation.schema.json b/schema/articles.navigation.schema.json deleted file mode 100644 index 3c08399..0000000 --- a/schema/articles.navigation.schema.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Articles Navigation Configuration", - "description": "Schema for defining the navigation menu structure for article sections. This configuration creates sidebar or hierarchical navigation menus that help users browse through related documentation pages within a specific topic area.", - "type": "array", - "minItems": 1, - "maxItems": 50, - "items": { - "type": "object", - "description": "A single navigation item representing a page or section within the documentation. Each item creates a clickable link in the navigation menu that directs users to specific content.", - "required": ["title", "link"], - "properties": { - "title": { - "type": "string", - "description": "The display text for this navigation item as it appears in the menu. Should be concise yet descriptive enough to clearly indicate the page content. Use consistent terminology and formatting across navigation items for better user experience.", - "minLength": 1, - "maxLength": 100, - "examples": [ - "Python Setup Guide", - "VS Code Extension Quick Start", - "MongoDB Shell Quick Start", - "Architecture under the hood", - "Components", - "Functions", - "Getting Started", - "Configuration Options" - ] - }, - "link": { - "type": "string", - "description": "The URL path where this navigation item links to. For internal documentation pages, use relative paths starting with '/'. The path should correspond to actual page routes in your documentation site structure. External links can use absolute URLs with http:// or https:// protocols.", - "pattern": "^(/|https?://)", - "minLength": 1, - "maxLength": 500, - "examples": [ - "/docs/quickstart", - "/docs/quickstart/extension", - "/docs/quickstart/mongodb-shell", - "/docs/architecture", - "/docs/postgresql", - "/docs/postgresql/functions", - "https://external-resource.example.com" - ] - }, - "description": { - "type": "string", - "description": "Optional brief description or subtitle for this navigation item. Can be used to provide additional context about the page content, displayed as helper text in the navigation menu.", - "minLength": 1, - "maxLength": 200, - "examples": [ - "Learn how to set up your Python development environment", - "Quick installation guide for the VS Code extension", - "Deep dive into the DocumentDB architecture" - ] - }, - "children": { - "type": "array", - "description": "Optional array of nested navigation items that appear as sub-items under this parent item. Use this to create hierarchical navigation structures with collapsible sections. Supports multiple levels of nesting for complex documentation structures.", - "minItems": 1, - "maxItems": 30, - "items": { - "$ref": "#/items" - } - } - }, - "additionalProperties": false - } -} \ No newline at end of file diff --git a/schema/reference.content.schema.json b/schema/reference.content.schema.json deleted file mode 100644 index af9aa43..0000000 --- a/schema/reference.content.schema.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MongoDB Query Language Reference Content", - "type": "array", - "uniqueItems": true, - "items": { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "operator", - "command" - ] - }, - "description": { - "type": "string" - }, - "categories": { - "type": "array", - "uniqueItems": true, - "items": { - "type": "object", - "properties": { - "category": { - "type": "string" - }, - "description": { - "type": "string" - } - }, - "required": [ - "category" - ] - } - } - }, - "required": [ - "type", - "categories" - ] - } -} \ No newline at end of file diff --git a/schema/reference.data.schema.json b/schema/reference.data.schema.json deleted file mode 100644 index a6a9635..0000000 --- a/schema/reference.data.schema.json +++ /dev/null @@ -1,219 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MongoDB Query Language Reference", - "type": "object", - "required": [ - "type", - "category", - "name" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "operator", - "command" - ], - "description": "Specifies whether the reference describes a query operator (such as $regex) or a database command (such as count). This helps categorize the reference for documentation and usage purposes." - }, - "category": { - "type": "string", - "description": "The category of the operator or command, such as query, aggregation, update, etc. This helps organize the reference within the broader context of MongoDB functionalities.", - "allOf": [ - { - "if": { - "properties": { - "type": { - "const": "operator" - } - } - }, - "then": { - "properties": { - "category": { - "enum": [ - "accumulator", - "aggregation", - "arithmetic-expression", - "array-expression", - "array-query", - "array-update", - "bitwise", - "bitwise-query", - "bitwise-update", - "boolean-expression", - "comparison-query", - "conditional-expression", - "date-expression", - "data-size", - "element-query", - "evaluation-query", - "field-update", - "geospatial", - "logical-query", - "miscellaneous", - "object-expression", - "projection", - "timestamp-expression", - "set-expression", - "variable-expression", - "window" - ] - } - } - } - }, - { - "if": { - "properties": { - "type": { - "const": "command" - } - } - }, - "then": { - "properties": { - "category": { - "enum": [ - "aggregation", - "query-and-write" - ] - } - } - } - } - ] - }, - "name": { - "type": "string", - "description": "The official name of the operator or command. This should match the name used in MongoDB queries, such as $regex or count." - }, - "description": { - "type": "string", - "description": "A detailed explanation of the operator or command, including its purpose, typical use cases, and any important nuances. This should help users understand when and why to use it." - }, - "summary": { - "type": "string", - "description": "A concise, one- or two-sentence summary of the operator or command. This is used for quick reference and in listings or previews." - }, - "syntax": { - "type": "string", - "description": "The canonical syntax for using the operator or command in a MongoDB query. This should include example structure and required fields, helping users understand how to construct valid queries." - }, - "parameters": { - "type": "array", - "items": { - "type": "object", - "required": [ - "name", - "required" - ], - "properties": { - "name": { - "type": "string", - "description": "The name of the parameter as used in the query or command." - }, - "type": { - "type": "string", - "enum": [ - "object", - "string", - "number", - "pattern", - "array", - "expression" - ], - "description": "The data type of the parameter, such as string, object, number, or pattern. This helps validate and document expected input." - }, - "required": { - "type": "boolean", - "description": "Indicates whether this parameter is mandatory for the operator or command to function correctly." - }, - "description": { - "type": "string", - "description": "A detailed description of the parameter, including its role, expected values, and any special considerations." - } - }, - "additionalProperties": false - }, - "description": "A list of parameters accepted by the operator or command. Each parameter includes its name, type, whether it is required, and a description to guide correct usage." - }, - "examples": { - "type": "object", - "required": [ - "items" - ], - "properties": { - "sample": { - "type": "string", - "description": "A sample dataset or document structure that is used in the example queries. This helps users understand the context and expected input/output." - }, - "items": { - "type": "array", - "items": { - "type": "object", - "required": [ - "title", - "description", - "query" - ], - "properties": { - "title": { - "type": "string", - "description": "A short, descriptive title for the example, summarizing what it demonstrates." - }, - "explanation": { - "type": "string", - "description": "A step-by-step explanation of how the example works and why it is useful." - }, - "description": { - "type": "string", - "description": "A brief description of the example, including its purpose and what it illustrates about the operator or command." - }, - "query": { - "type": "string", - "description": "The actual MongoDB query or command used in the example. This should be copy-pasteable and demonstrate correct usage." - }, - "output": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "string", - "description": "The output produced by the query or command, shown in the specified format." - } - }, - "additionalProperties": false, - "description": "The expected output of the example query, including its format and value." - } - }, - "additionalProperties": false - } - } - }, - "additionalProperties": false, - "description": "A set of practical examples demonstrating how to use the operator or command. Each example includes a sample dataset, query, output, and explanations to help users understand real-world usage." - }, - "related": { - "type": "array", - "maxItems": 4, - "items": { - "type": "object", - "required": [ - "reference" - ], - "properties": { - "reference": { - "type": "string", - "description": "A reference to a related operator or command, typically as a path or identifier. This helps users discover additional relevant documentation." - } - }, - "additionalProperties": false - }, - "description": "A list of up to four related operators or commands, providing links to additional documentation for further exploration." - } - }, - "additionalProperties": false -} \ No newline at end of file diff --git a/scripts/compile-clean.tsx b/scripts/compile-clean.tsx new file mode 100644 index 0000000..904f7f1 --- /dev/null +++ b/scripts/compile-clean.tsx @@ -0,0 +1,240 @@ +#!/usr/bin/env tsx + +import fs from 'fs'; +import path from 'path'; +import React from 'react'; +import { render, Box, Text } from 'ink'; + +/** + * Configuration structure for content cleaning + */ +interface ContentSource { + readonly repository: string; + readonly branch: string; + readonly mappings: ReadonlyArray<{ + readonly source: string; + readonly target: string; + }>; +} + +interface ContentConfig { + readonly sources: ReadonlyArray; + readonly include: ReadonlyArray; + readonly exclude: ReadonlyArray; +} + +interface RmOptions { + readonly recursive: boolean; + readonly force: boolean; +} + +interface CleanedDirectory { + readonly path: string; + readonly repository: string; +} + +/** + * Cleans a directory by removing it if it exists + */ +function cleanDirectory(dirPath: string): boolean { + if (fs.existsSync(dirPath)) { + fs.rmSync(dirPath, { recursive: true, force: true } as RmOptions); + return true; + } + return false; +} + +/** + * Cleans target directories based on configuration mappings + */ +async function cleanContent( + config: ContentConfig, + onProgress?: (cleaned: CleanedDirectory) => void +): Promise<{ + success: boolean; + cleanedDirectories?: ReadonlyArray; + message?: string; +}> { + try { + const cleaned: CleanedDirectory[] = []; + + // Process each source repository + for (const source of config.sources) { + // Process each mapping and clean target directories + for (const mapping of source.mappings) { + const targetDir = path.join(process.cwd(), mapping.target); + + if (cleanDirectory(targetDir)) { + const cleanedDir: CleanedDirectory = { + path: mapping.target, + repository: source.repository + }; + cleaned.push(cleanedDir); + + if (onProgress) { + onProgress(cleanedDir); + } + } + } + } + + return { + success: true, + cleanedDirectories: cleaned + }; + } catch (error: unknown) { + return { + success: false, + message: error instanceof Error ? error.message : 'Unknown error occurred' + }; + } +} + +/** + * Main Console component for Ink rendering + */ +const Console: React.FC = () => { + const [status, setStatus] = React.useState<'loading' | 'cleaning' | 'success' | 'error'>('loading'); + const [errorMessage, setErrorMessage] = React.useState(''); + const [cleanedDirectories, setCleanedDirectories] = React.useState>([]); + const [cleanCount, setCleanCount] = React.useState(0); + const [config, setConfig] = React.useState(null); + + React.useEffect(() => { + const run = async () => { + try { + // Load configuration + const configPath = path.join(process.cwd(), 'content.config.json'); + if (!fs.existsSync(configPath)) { + throw new Error('content.config.json not found'); + } + + const loadedConfig = JSON.parse(fs.readFileSync(configPath, 'utf8')) as ContentConfig; + + // Validate configuration + if (!loadedConfig.sources || loadedConfig.sources.length === 0) { + throw new Error('content.config.json must include at least one source'); + } + + setConfig(loadedConfig); + setStatus('cleaning'); + + // Clean content + const result = await cleanContent(loadedConfig, (cleaned) => { + setCleanCount(prev => prev + 1); + }); + + if (result.success) { + setStatus('success'); + setCleanedDirectories(result.cleanedDirectories || []); + } else { + setStatus('error'); + setErrorMessage(result.message || 'Unknown error'); + } + + // Exit after a brief delay + setTimeout(() => { + process.exit(result.success ? 0 : 1); + }, 100); + } catch (error: unknown) { + setStatus('error'); + setErrorMessage(error instanceof Error ? error.message : 'Unknown error'); + setTimeout(() => { + process.exit(1); + }, 100); + } + }; + + run(); + }, []); + + /** + * Truncates a string to a maximum length with ellipsis + */ + const truncate = (str: string, maxLength: number): string => { + if (str.length <= maxLength) return str; + return str.slice(0, maxLength - 3) + '...'; + }; + + /** + * Groups directories by repository + */ + const groupByRepository = (dirs: ReadonlyArray): Map => { + const grouped = new Map(); + for (const dir of dirs) { + const existing = grouped.get(dir.repository) || []; + existing.push(dir); + grouped.set(dir.repository, existing); + } + return grouped; + }; + + return ( + + + 🧹 Cleaning Content Directories + + + {status === 'loading' && ( + + Loading configuration... + + )} + + {status === 'cleaning' && ( + + + {cleanCount} director{cleanCount !== 1 ? 'ies' : 'y'} cleaned... + + + )} + + {status === 'success' && ( + + {cleanedDirectories.length > 0 ? ( + <> + + ✅ Successfully cleaned {cleanedDirectories.length} director{cleanedDirectories.length === 1 ? 'y' : 'ies'}! + + + + {Array.from(groupByRepository(cleanedDirectories)).map(([repo, dirs], idx) => ( + + + {truncate(repo, 70)} + ({dirs.length} director{dirs.length === 1 ? 'y' : 'ies'}) + + + {dirs.map((dir, dirIdx) => ( + + → {dir.path} + + ))} + + + ))} + + + ) : ( + + No directories needed cleaning (all targets already clean) + + )} + + )} + + {status === 'error' && ( + + + ❌ Error cleaning content: + + + {errorMessage} + + + )} + + ); +}; + +render(); diff --git a/scripts/compile-content.tsx b/scripts/compile-content.tsx new file mode 100644 index 0000000..91676ea --- /dev/null +++ b/scripts/compile-content.tsx @@ -0,0 +1,384 @@ +import fs from 'fs'; +import path from 'path'; +import { execSync } from 'child_process'; +import React from 'react'; +import { render, Box, Text } from 'ink'; +import { minimatch } from 'minimatch'; + +/** + * Configuration structure for content cloning + */ +interface ContentSource { + readonly repository: string; + readonly branch: string; + readonly mappings: ReadonlyArray<{ + readonly source: string; + readonly target: string; + }>; +} + +interface ContentConfig { + readonly sources: ReadonlyArray; + readonly include: ReadonlyArray; + readonly exclude: ReadonlyArray; +} + +interface RmOptions { + readonly recursive: boolean; + readonly force: boolean; +} + +interface CopyOptions { + readonly recursive: boolean; +} + +interface CopiedFile { + readonly from: string; + readonly to: string; + readonly repository: string; +} + +/** + * Tracks file paths that have been copied + */ +class FileTracker { + private readonly copiedFiles: CopiedFile[] = []; + private readonly onProgress?: (count: number, repository: string) => void; + + constructor(onProgress?: (count: number, repository: string) => void) { + this.onProgress = onProgress; + } + + /** + * Records a file being copied + */ + recordFile(relativePath: string, sourcePath: string, repository: string): void { + this.copiedFiles.push({ + from: sourcePath, + to: relativePath, + repository + }); + + if (this.onProgress) { + this.onProgress(this.copiedFiles.length, repository); + } + } + + /** + * Get all copied files with source and destination paths + */ + getCopiedFiles(): ReadonlyArray { + return this.copiedFiles; + } +} + +/** + * Cleans a directory by removing it if it exists + */ +function cleanDirectory(dirPath: string): void { + if (fs.existsSync(dirPath)) { + fs.rmSync(dirPath, { recursive: true, force: true } as RmOptions); + } +} + +/** + * Ensures a directory exists + */ +function ensureDirectory(dirPath: string): void { + if (!fs.existsSync(dirPath)) { + fs.mkdirSync(dirPath, { recursive: true } as CopyOptions); + } +} + +/** + * Checks if a file should be included based on include patterns + */ +function shouldInclude(relativePath: string, includePatterns: ReadonlyArray): boolean { + return includePatterns.some(pattern => + minimatch(relativePath, pattern, { nocase: true, matchBase: true }) + ); +} + +/** + * Checks if a file should be excluded based on exclude patterns + */ +function shouldExclude(relativePath: string, excludePatterns: ReadonlyArray): boolean { + return excludePatterns.some(pattern => + minimatch(relativePath, pattern, { nocase: true, matchBase: true }) + ); +} + +/** + * Recursively copies files from source to destination with filtering + */ +function copyFilesRecursive( + sourceBase: string, + targetBase: string, + includePatterns: ReadonlyArray, + excludePatterns: ReadonlyArray, + tracker: FileTracker, + repository: string, + currentPath: string = '' +): void { + const fullSourcePath = path.join(sourceBase, currentPath); + const fullTargetPath = path.join(targetBase, currentPath); + + if (!fs.existsSync(fullSourcePath)) { + return; + } + + const items = fs.readdirSync(fullSourcePath); + + for (const item of items) { + const itemSourcePath = path.join(fullSourcePath, item); + const itemTargetPath = path.join(fullTargetPath, item); + const itemRelativePath = path.join(currentPath, item).replace(/\\/g, '/'); + const stats = fs.statSync(itemSourcePath); + + if (stats.isDirectory()) { + copyFilesRecursive( + sourceBase, + targetBase, + includePatterns, + excludePatterns, + tracker, + repository, + itemRelativePath + ); + } else { + // Check if file should be included and not excluded + if (shouldInclude(itemRelativePath, includePatterns) && !shouldExclude(itemRelativePath, excludePatterns)) { + ensureDirectory(path.dirname(itemTargetPath)); + fs.copyFileSync(itemSourcePath, itemTargetPath); + tracker.recordFile(itemRelativePath, itemSourcePath, repository); + } + } + } +} + +/** + * Clones content from repositories + */ +async function cloneContent( + config: ContentConfig, + onProgress?: (count: number, repository: string) => void +): Promise<{ + success: boolean; + copiedFiles?: ReadonlyArray; + message?: string; +}> { + const TEMP_DIR = path.join(process.cwd(), '_tmp'); + const tracker = new FileTracker(onProgress); + + try { + // Clean temp directory + cleanDirectory(TEMP_DIR); + ensureDirectory(TEMP_DIR); + + // Process each source repository + for (const source of config.sources) { + const repoName = source.repository.split('/').pop() || 'repo'; + const cloneDir = path.join(TEMP_DIR, repoName); + + // Clone the repository + execSync( + `git clone --depth 1 --branch ${source.branch} ${source.repository} "${cloneDir}"`, + { stdio: 'pipe' } + ); + + // Process each mapping + for (const mapping of source.mappings) { + const sourceDir = path.join(cloneDir, mapping.source); + const targetDir = path.join(process.cwd(), mapping.target); + + // Clean target directory + cleanDirectory(targetDir); + ensureDirectory(targetDir); + + // Copy files with filtering + copyFilesRecursive( + sourceDir, + targetDir, + config.include, + config.exclude, + tracker, + source.repository + ); + } + } + + // Clean up temp directory + cleanDirectory(TEMP_DIR); + + return { + success: true, + copiedFiles: tracker.getCopiedFiles() + }; + } catch (error: unknown) { + // Clean up on error + cleanDirectory(TEMP_DIR); + + return { + success: false, + message: error instanceof Error ? error.message : 'Unknown error occurred' + }; + } +} + +/** + * Main Console component for Ink rendering + */ +const Console: React.FC = () => { + const [status, setStatus] = React.useState<'loading' | 'compiling' | 'success' | 'error'>('loading'); + const [errorMessage, setErrorMessage] = React.useState(''); + const [copiedFiles, setCopiedFiles] = React.useState>([]); + const [fileCount, setFileCount] = React.useState(0); + const [currentRepo, setCurrentRepo] = React.useState(''); + const [config, setConfig] = React.useState(null); + + React.useEffect(() => { + const run = async () => { + try { + // Load configuration + const configPath = path.join(process.cwd(), 'content.config.json'); + if (!fs.existsSync(configPath)) { + throw new Error('content.config.json not found'); + } + + const loadedConfig = JSON.parse(fs.readFileSync(configPath, 'utf8')) as ContentConfig; + + // Validate configuration + if (!loadedConfig.sources || loadedConfig.sources.length === 0) { + throw new Error('content.config.json must include at least one source'); + } + + setConfig(loadedConfig); + setStatus('compiling'); + + // Compile content + const result = await cloneContent(loadedConfig, (count, repo) => { + setFileCount(count); + setCurrentRepo(repo); + }); + + if (result.success) { + setStatus('success'); + setCopiedFiles(result.copiedFiles || []); + } else { + setStatus('error'); + setErrorMessage(result.message || 'Unknown error'); + } + + // Exit after a brief delay + setTimeout(() => { + process.exit(result.success ? 0 : 1); + }, 100); + } catch (error: unknown) { + setStatus('error'); + setErrorMessage(error instanceof Error ? error.message : 'Unknown error'); + setTimeout(() => { + process.exit(1); + }, 100); + } + }; + + run(); + }, []); + + /** + * Truncates a string to a maximum length with ellipsis + */ + const truncate = (str: string, maxLength: number): string => { + if (str.length <= maxLength) return str; + return str.slice(0, maxLength - 3) + '...'; + }; + + /** + * Groups files by repository + */ + const groupByRepository = (files: ReadonlyArray): Map => { + const grouped = new Map(); + for (const file of files) { + const existing = grouped.get(file.repository) || []; + existing.push(file); + grouped.set(file.repository, existing); + } + return grouped; + }; + + return ( + + + 📦 Compiling Documentation Content + + + {status === 'loading' && ( + + Loading configuration... + + )} + + {status === 'compiling' && ( + + + {fileCount} file{fileCount !== 1 ? 's' : ''} copied... + + {currentRepo && ( + + From: {truncate(currentRepo, 60)} + + )} + + )} + + {status === 'success' && ( + + {config && ( + + ✅ Successfully compiled content from {config.sources.length} repositor{config.sources.length === 1 ? 'y' : 'ies'}! + Total files copied: {copiedFiles.length} + + )} + + {copiedFiles.length > 0 && ( + + {Array.from(groupByRepository(copiedFiles)).map(([repo, files], idx) => ( + + + {truncate(repo, 70)} + ({files.length} files) + + + {files.slice(0, 5).map((file, fileIdx) => ( + + → {truncate(file.to, 65)} + + ))} + {files.length > 5 && ( + + ... and {files.length - 5} more files + + )} + + + ))} + + )} + + )} + + {status === 'error' && ( + + + ❌ Error cloning content: + + + {errorMessage} + + + )} + + ); +}; + +render(); diff --git a/scripts/package.json b/scripts/package.json new file mode 100644 index 0000000..aead43d --- /dev/null +++ b/scripts/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} \ No newline at end of file